iap->ia_mode = 0;
        iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
 
+       err = nfserr_inval;
+       if (!S_ISREG(type) && !S_ISDIR(type) && !special_file(type)) {
+               printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n",
+                      type);
+               goto out;
+       }
+
+       host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
+       if (host_err)
+               goto out_nfserr;
+
        /*
         * Get the dir op function pointer.
         */
        err = 0;
        switch (type) {
        case S_IFREG:
-               host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
-               if (host_err)
-                       goto out_nfserr;
                host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
                break;
        case S_IFDIR:
-               host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
-               if (host_err)
-                       goto out_nfserr;
                host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
                break;
        case S_IFCHR:
        case S_IFBLK:
        case S_IFIFO:
        case S_IFSOCK:
-               host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
-               if (host_err)
-                       goto out_nfserr;
                host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
                break;
-       default:
-               printk("nfsd: bad file type %o in nfsd_create\n", type);
-               host_err = -EINVAL;
-               goto out_nfserr;
        }
        if (host_err < 0) {
                mnt_drop_write(fhp->fh_export->ex_path.mnt);
                write_inode_now(dchild->d_inode, 1);
        }
 
-
        err2 = nfsd_create_setattr(rqstp, resfhp, iap);
        if (err2)
                err = err2;