diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7370583b61e5..a1554bead692 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -194,7 +194,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
194 | spin_unlock(&inode->i_lock); | 194 | spin_unlock(&inode->i_lock); |
195 | /* Ensure consistent page alignment of the data. | 195 | /* Ensure consistent page alignment of the data. |
196 | * Note: assumes we have exclusive access to this mapping either | 196 | * Note: assumes we have exclusive access to this mapping either |
197 | * through inode->i_sem or some other mechanism. | 197 | * through inode->i_mutex or some other mechanism. |
198 | */ | 198 | */ |
199 | if (page->index == 0) | 199 | if (page->index == 0) |
200 | invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1); | 200 | invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1); |
@@ -573,7 +573,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
573 | 573 | ||
574 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | 574 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) |
575 | { | 575 | { |
576 | down(&filp->f_dentry->d_inode->i_sem); | 576 | mutex_lock(&filp->f_dentry->d_inode->i_mutex); |
577 | switch (origin) { | 577 | switch (origin) { |
578 | case 1: | 578 | case 1: |
579 | offset += filp->f_pos; | 579 | offset += filp->f_pos; |
@@ -589,7 +589,7 @@ loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | |||
589 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; | 589 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; |
590 | } | 590 | } |
591 | out: | 591 | out: |
592 | up(&filp->f_dentry->d_inode->i_sem); | 592 | mutex_unlock(&filp->f_dentry->d_inode->i_mutex); |
593 | return offset; | 593 | return offset; |
594 | } | 594 | } |
595 | 595 | ||
@@ -1001,7 +1001,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1001 | openflags &= ~(O_CREAT|O_TRUNC); | 1001 | openflags &= ~(O_CREAT|O_TRUNC); |
1002 | 1002 | ||
1003 | /* | 1003 | /* |
1004 | * Note: we're not holding inode->i_sem and so may be racing with | 1004 | * Note: we're not holding inode->i_mutex and so may be racing with |
1005 | * operations that change the directory. We therefore save the | 1005 | * operations that change the directory. We therefore save the |
1006 | * change attribute *before* we do the RPC call. | 1006 | * change attribute *before* we do the RPC call. |
1007 | */ | 1007 | */ |
@@ -1051,7 +1051,7 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) | |||
1051 | return dentry; | 1051 | return dentry; |
1052 | if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) | 1052 | if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) |
1053 | return NULL; | 1053 | return NULL; |
1054 | /* Note: caller is already holding the dir->i_sem! */ | 1054 | /* Note: caller is already holding the dir->i_mutex! */ |
1055 | dentry = d_alloc(parent, &name); | 1055 | dentry = d_alloc(parent, &name); |
1056 | if (dentry == NULL) | 1056 | if (dentry == NULL) |
1057 | return NULL; | 1057 | return NULL; |
@@ -1287,6 +1287,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name); | |||
1287 | nfs_begin_data_update(dentry->d_inode); | 1287 | nfs_begin_data_update(dentry->d_inode); |
1288 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, | 1288 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, |
1289 | dir, &qsilly); | 1289 | dir, &qsilly); |
1290 | nfs_mark_for_revalidate(dentry->d_inode); | ||
1290 | nfs_end_data_update(dentry->d_inode); | 1291 | nfs_end_data_update(dentry->d_inode); |
1291 | } else | 1292 | } else |
1292 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, | 1293 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, |
@@ -1334,6 +1335,7 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1334 | /* The VFS may want to delete this inode */ | 1335 | /* The VFS may want to delete this inode */ |
1335 | if (error == 0) | 1336 | if (error == 0) |
1336 | inode->i_nlink--; | 1337 | inode->i_nlink--; |
1338 | nfs_mark_for_revalidate(inode); | ||
1337 | nfs_end_data_update(inode); | 1339 | nfs_end_data_update(inode); |
1338 | } else | 1340 | } else |
1339 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1341 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
@@ -1548,14 +1550,17 @@ go_ahead: | |||
1548 | } | 1550 | } |
1549 | nfs_inode_return_delegation(old_inode); | 1551 | nfs_inode_return_delegation(old_inode); |
1550 | 1552 | ||
1551 | if (new_inode) | 1553 | if (new_inode != NULL) { |
1554 | nfs_inode_return_delegation(new_inode); | ||
1552 | d_delete(new_dentry); | 1555 | d_delete(new_dentry); |
1556 | } | ||
1553 | 1557 | ||
1554 | nfs_begin_data_update(old_dir); | 1558 | nfs_begin_data_update(old_dir); |
1555 | nfs_begin_data_update(new_dir); | 1559 | nfs_begin_data_update(new_dir); |
1556 | nfs_begin_data_update(old_inode); | 1560 | nfs_begin_data_update(old_inode); |
1557 | error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, | 1561 | error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, |
1558 | new_dir, &new_dentry->d_name); | 1562 | new_dir, &new_dentry->d_name); |
1563 | nfs_mark_for_revalidate(old_inode); | ||
1559 | nfs_end_data_update(old_inode); | 1564 | nfs_end_data_update(old_inode); |
1560 | nfs_end_data_update(new_dir); | 1565 | nfs_end_data_update(new_dir); |
1561 | nfs_end_data_update(old_dir); | 1566 | nfs_end_data_update(old_dir); |