]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] 2.5.6 Fix NFS file creation
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Tue, 12 Mar 2002 06:04:45 +0000 (22:04 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Tue, 12 Mar 2002 06:04:45 +0000 (22:04 -0800)
  The following patch fixes a bug in NFS file creation. Recently (not
sure exactly when), open_namei() was changed so that it expects
vfs_create() to always return a fully instantiated dentry for the new
file.

The following patch ensures this is done in the cases where the RPC
CREATE call does not return valid attributes/filehandles. This is
always the case for NFSv2, and can sometimes be the case for v3...

fs/nfs/dir.c

index 55fddf9d114996d6dc1b40030abbfa2f7b3a477d..4ce6cee33d1c4cdfb7c5fa5fce9b448b695381fb 100644 (file)
@@ -614,6 +614,12 @@ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
        struct inode *inode;
        int error = -EACCES;
 
+       if (fhandle->size == 0 || !(fattr->valid & NFS_ATTR_FATTR)) {
+               struct inode *dir = dentry->d_parent->d_inode;
+               error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
+               if (error)
+                       goto out_err;
+       }
        inode = nfs_fhget(dentry, fhandle, fattr);
        if (inode) {
                d_instantiate(dentry, inode);
@@ -621,6 +627,9 @@ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
                error = 0;
        }
        return error;
+out_err:
+       d_drop(dentry);
+       return error;
 }
 
 /*
@@ -652,9 +661,9 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
        nfs_zap_caches(dir);
        error = NFS_PROTO(dir)->create(dir, &dentry->d_name,
                                         &attr, 0, &fhandle, &fattr);
-       if (!error && fhandle.size != 0)
+       if (!error)
                error = nfs_instantiate(dentry, &fhandle, &fattr);
-       if (error || fhandle.size == 0)
+       else
                d_drop(dentry);
        unlock_kernel();
        return error;
@@ -680,9 +689,9 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
        nfs_zap_caches(dir);
        error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev,
                                        &fhandle, &fattr);
-       if (!error && fhandle.size != 0)
+       if (!error)
                error = nfs_instantiate(dentry, &fhandle, &fattr);
-       if (error || fhandle.size == 0)
+       else
                d_drop(dentry);
        unlock_kernel();
        return error;
@@ -717,9 +726,9 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        nfs_zap_caches(dir);
        error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle,
                                        &fattr);
-       if (!error && fhandle.size != 0)
+       if (!error)
                error = nfs_instantiate(dentry, &fhandle, &fattr);
-       if (error || fhandle.size == 0)
+       else
                d_drop(dentry);
        unlock_kernel();
        return error;
@@ -930,7 +939,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
        nfs_zap_caches(dir);
        error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname,
                                          &attr, &sym_fh, &sym_attr);
-       if (!error && sym_fh.size != 0 && (sym_attr.valid & NFS_ATTR_FATTR)) {
+       if (!error) {
                error = nfs_instantiate(dentry, &sym_fh, &sym_attr);
        } else {
                if (error == -EEXIST)