aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-25 16:38:17 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:06:12 -0500
commit6f23e3872cff238589f9bf39c71db2ea880c9a26 (patch)
tree7b118601dcd65ae2bee7eddbeae6bdd6d64f4423 /fs/nfs/dir.c
parente6f810759505bc86c009854b82cc495ffd8eb020 (diff)
NFS: Fix a potential race between umount and nfs_access_cache_shrinker()
Thanks to Yawei Niu for spotting the race. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5ca762de88bf..476cb0f837fd 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1694,13 +1694,19 @@ int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
1694restart: 1694restart:
1695 spin_lock(&nfs_access_lru_lock); 1695 spin_lock(&nfs_access_lru_lock);
1696 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) { 1696 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
1697 struct rw_semaphore *s_umount;
1697 struct inode *inode; 1698 struct inode *inode;
1698 1699
1699 if (nr_to_scan-- == 0) 1700 if (nr_to_scan-- == 0)
1700 break; 1701 break;
1702 s_umount = &nfsi->vfs_inode.i_sb->s_umount;
1703 if (!down_read_trylock(s_umount))
1704 continue;
1701 inode = igrab(&nfsi->vfs_inode); 1705 inode = igrab(&nfsi->vfs_inode);
1702 if (inode == NULL) 1706 if (inode == NULL) {
1707 up_read(s_umount);
1703 continue; 1708 continue;
1709 }
1704 spin_lock(&inode->i_lock); 1710 spin_lock(&inode->i_lock);
1705 if (list_empty(&nfsi->access_cache_entry_lru)) 1711 if (list_empty(&nfsi->access_cache_entry_lru))
1706 goto remove_lru_entry; 1712 goto remove_lru_entry;
@@ -1719,6 +1725,7 @@ remove_lru_entry:
1719 spin_unlock(&inode->i_lock); 1725 spin_unlock(&inode->i_lock);
1720 spin_unlock(&nfs_access_lru_lock); 1726 spin_unlock(&nfs_access_lru_lock);
1721 iput(inode); 1727 iput(inode);
1728 up_read(s_umount);
1722 goto restart; 1729 goto restart;
1723 } 1730 }
1724 spin_unlock(&nfs_access_lru_lock); 1731 spin_unlock(&nfs_access_lru_lock);