aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-05 12:27:44 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-22 23:25:01 -0400
commitfd6840714d9cf6e93f1d42b904860a94df316b85 (patch)
treee72a0ef8bff8f1b6183596dbce3de34570ee6180
parent762d4527c2fc19d821a13d9a3455ccc2d4073731 (diff)
NFS: nfs_lookup - don't hash dentry when optimising away the lookup
If the open intents tell us that a given lookup is going to result in a, exclusive create, we currently optimize away the lookup call itself. The reason is that the lookup would not be atomic with the create RPC call, so why do it in the first place? A problem occurs, however, if the VFS aborts the exclusive create operation after the lookup, but before the call to create the file/directory: in this case we will end up with a hashed negative dentry in the dcache that has never been looked up. Fix this by only actually hashing the dentry once the create operation has been successfully completed. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/dir.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 51328ae640dd..3419c2da9ba9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -904,9 +904,15 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
904 904
905 lock_kernel(); 905 lock_kernel();
906 906
907 /* If we're doing an exclusive create, optimize away the lookup */ 907 /*
908 if (nfs_is_exclusive_create(dir, nd)) 908 * If we're doing an exclusive create, optimize away the lookup
909 goto no_entry; 909 * but don't hash the dentry.
910 */
911 if (nfs_is_exclusive_create(dir, nd)) {
912 d_instantiate(dentry, NULL);
913 res = NULL;
914 goto out_unlock;
915 }
910 916
911 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); 917 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
912 if (error == -ENOENT) 918 if (error == -ENOENT)
@@ -1161,6 +1167,8 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1161 if (IS_ERR(inode)) 1167 if (IS_ERR(inode))
1162 return error; 1168 return error;
1163 d_instantiate(dentry, inode); 1169 d_instantiate(dentry, inode);
1170 if (d_unhashed(dentry))
1171 d_rehash(dentry);
1164 return 0; 1172 return 0;
1165} 1173}
1166 1174