aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-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 8ec7fbd8240c..35334539d947 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -562,6 +562,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
562 nfs_fattr_init(&fattr); 562 nfs_fattr_init(&fattr);
563 desc->entry = &my_entry; 563 desc->entry = &my_entry;
564 564
565 nfs_block_sillyrename(dentry);
565 while(!desc->entry->eof) { 566 while(!desc->entry->eof) {
566 res = readdir_search_pagecache(desc); 567 res = readdir_search_pagecache(desc);
567 568
@@ -592,6 +593,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
592 break; 593 break;
593 } 594 }
594 } 595 }
596 nfs_unblock_sillyrename(dentry);
595 unlock_kernel(); 597 unlock_kernel();
596 if (res > 0) 598 if (res > 0)
597 res = 0; 599 res = 0;
@@ -866,6 +868,7 @@ struct dentry_operations nfs_dentry_operations = {
866static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) 868static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
867{ 869{
868 struct dentry *res; 870 struct dentry *res;
871 struct dentry *parent;
869 struct inode *inode = NULL; 872 struct inode *inode = NULL;
870 int error; 873 int error;
871 struct nfs_fh fhandle; 874 struct nfs_fh fhandle;
@@ -894,26 +897,31 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
894 goto out_unlock; 897 goto out_unlock;
895 } 898 }
896 899
900 parent = dentry->d_parent;
901 /* Protect against concurrent sillydeletes */
902 nfs_block_sillyrename(parent);
897 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); 903 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
898 if (error == -ENOENT) 904 if (error == -ENOENT)
899 goto no_entry; 905 goto no_entry;
900 if (error < 0) { 906 if (error < 0) {
901 res = ERR_PTR(error); 907 res = ERR_PTR(error);
902 goto out_unlock; 908 goto out_unblock_sillyrename;
903 } 909 }
904 inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); 910 inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
905 res = (struct dentry *)inode; 911 res = (struct dentry *)inode;
906 if (IS_ERR(res)) 912 if (IS_ERR(res))
907 goto out_unlock; 913 goto out_unblock_sillyrename;
908 914
909no_entry: 915no_entry:
910 res = d_materialise_unique(dentry, inode); 916 res = d_materialise_unique(dentry, inode);
911 if (res != NULL) { 917 if (res != NULL) {
912 if (IS_ERR(res)) 918 if (IS_ERR(res))
913 goto out_unlock; 919 goto out_unblock_sillyrename;
914 dentry = res; 920 dentry = res;
915 } 921 }
916 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 922 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
923out_unblock_sillyrename:
924 nfs_unblock_sillyrename(parent);
917out_unlock: 925out_unlock:
918 unlock_kernel(); 926 unlock_kernel();
919out: 927out: