diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f697b5c74b7c..476cb0f837fd 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -192,7 +192,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
192 | /* We requested READDIRPLUS, but the server doesn't grok it */ | 192 | /* We requested READDIRPLUS, but the server doesn't grok it */ |
193 | if (error == -ENOTSUPP && desc->plus) { | 193 | if (error == -ENOTSUPP && desc->plus) { |
194 | NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; | 194 | NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; |
195 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); | 195 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); |
196 | desc->plus = 0; | 196 | desc->plus = 0; |
197 | goto again; | 197 | goto again; |
198 | } | 198 | } |
@@ -537,12 +537,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
537 | 537 | ||
538 | lock_kernel(); | 538 | lock_kernel(); |
539 | 539 | ||
540 | res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping); | ||
541 | if (res < 0) { | ||
542 | unlock_kernel(); | ||
543 | return res; | ||
544 | } | ||
545 | |||
546 | /* | 540 | /* |
547 | * filp->f_pos points to the dirent entry number. | 541 | * filp->f_pos points to the dirent entry number. |
548 | * *desc->dir_cookie has the cookie for the next entry. We have | 542 | * *desc->dir_cookie has the cookie for the next entry. We have |
@@ -564,6 +558,10 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
564 | desc->entry = &my_entry; | 558 | desc->entry = &my_entry; |
565 | 559 | ||
566 | nfs_block_sillyrename(dentry); | 560 | nfs_block_sillyrename(dentry); |
561 | res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping); | ||
562 | if (res < 0) | ||
563 | goto out; | ||
564 | |||
567 | while(!desc->entry->eof) { | 565 | while(!desc->entry->eof) { |
568 | res = readdir_search_pagecache(desc); | 566 | res = readdir_search_pagecache(desc); |
569 | 567 | ||
@@ -579,7 +577,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
579 | break; | 577 | break; |
580 | } | 578 | } |
581 | if (res == -ETOOSMALL && desc->plus) { | 579 | if (res == -ETOOSMALL && desc->plus) { |
582 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); | 580 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); |
583 | nfs_zap_caches(inode); | 581 | nfs_zap_caches(inode); |
584 | desc->plus = 0; | 582 | desc->plus = 0; |
585 | desc->entry->eof = 0; | 583 | desc->entry->eof = 0; |
@@ -594,6 +592,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
594 | break; | 592 | break; |
595 | } | 593 | } |
596 | } | 594 | } |
595 | out: | ||
597 | nfs_unblock_sillyrename(dentry); | 596 | nfs_unblock_sillyrename(dentry); |
598 | unlock_kernel(); | 597 | unlock_kernel(); |
599 | if (res > 0) | 598 | if (res > 0) |
@@ -639,6 +638,21 @@ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) | |||
639 | return 0; | 638 | return 0; |
640 | } | 639 | } |
641 | 640 | ||
641 | /** | ||
642 | * nfs_force_lookup_revalidate - Mark the directory as having changed | ||
643 | * @dir - pointer to directory inode | ||
644 | * | ||
645 | * This forces the revalidation code in nfs_lookup_revalidate() to do a | ||
646 | * full lookup on all child dentries of 'dir' whenever a change occurs | ||
647 | * on the server that might have invalidated our dcache. | ||
648 | * | ||
649 | * The caller should be holding dir->i_lock | ||
650 | */ | ||
651 | void nfs_force_lookup_revalidate(struct inode *dir) | ||
652 | { | ||
653 | NFS_I(dir)->cache_change_attribute = jiffies; | ||
654 | } | ||
655 | |||
642 | /* | 656 | /* |
643 | * A check for whether or not the parent directory has changed. | 657 | * A check for whether or not the parent directory has changed. |
644 | * In the case it has, we assume that the dentries are untrustworthy | 658 | * In the case it has, we assume that the dentries are untrustworthy |
@@ -827,6 +841,10 @@ static int nfs_dentry_delete(struct dentry *dentry) | |||
827 | dentry->d_parent->d_name.name, dentry->d_name.name, | 841 | dentry->d_parent->d_name.name, dentry->d_name.name, |
828 | dentry->d_flags); | 842 | dentry->d_flags); |
829 | 843 | ||
844 | /* Unhash any dentry with a stale inode */ | ||
845 | if (dentry->d_inode != NULL && NFS_STALE(dentry->d_inode)) | ||
846 | return 1; | ||
847 | |||
830 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 848 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
831 | /* Unhash it, so that ->d_iput() would be called */ | 849 | /* Unhash it, so that ->d_iput() would be called */ |
832 | return 1; | 850 | return 1; |
@@ -846,7 +864,6 @@ static int nfs_dentry_delete(struct dentry *dentry) | |||
846 | */ | 864 | */ |
847 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | 865 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) |
848 | { | 866 | { |
849 | nfs_inode_return_delegation(inode); | ||
850 | if (S_ISDIR(inode->i_mode)) | 867 | if (S_ISDIR(inode->i_mode)) |
851 | /* drop any readdir cache as it could easily be old */ | 868 | /* drop any readdir cache as it could easily be old */ |
852 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | 869 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; |
@@ -1268,6 +1285,12 @@ out_err: | |||
1268 | return error; | 1285 | return error; |
1269 | } | 1286 | } |
1270 | 1287 | ||
1288 | static void nfs_dentry_handle_enoent(struct dentry *dentry) | ||
1289 | { | ||
1290 | if (dentry->d_inode != NULL && !d_unhashed(dentry)) | ||
1291 | d_delete(dentry); | ||
1292 | } | ||
1293 | |||
1271 | static int nfs_rmdir(struct inode *dir, struct dentry *dentry) | 1294 | static int nfs_rmdir(struct inode *dir, struct dentry *dentry) |
1272 | { | 1295 | { |
1273 | int error; | 1296 | int error; |
@@ -1280,6 +1303,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1280 | /* Ensure the VFS deletes this inode */ | 1303 | /* Ensure the VFS deletes this inode */ |
1281 | if (error == 0 && dentry->d_inode != NULL) | 1304 | if (error == 0 && dentry->d_inode != NULL) |
1282 | clear_nlink(dentry->d_inode); | 1305 | clear_nlink(dentry->d_inode); |
1306 | else if (error == -ENOENT) | ||
1307 | nfs_dentry_handle_enoent(dentry); | ||
1283 | unlock_kernel(); | 1308 | unlock_kernel(); |
1284 | 1309 | ||
1285 | return error; | 1310 | return error; |
@@ -1386,6 +1411,8 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1386 | nfs_mark_for_revalidate(inode); | 1411 | nfs_mark_for_revalidate(inode); |
1387 | } else | 1412 | } else |
1388 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1413 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
1414 | if (error == -ENOENT) | ||
1415 | nfs_dentry_handle_enoent(dentry); | ||
1389 | out: | 1416 | out: |
1390 | return error; | 1417 | return error; |
1391 | } | 1418 | } |
@@ -1422,7 +1449,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1422 | spin_unlock(&dentry->d_lock); | 1449 | spin_unlock(&dentry->d_lock); |
1423 | spin_unlock(&dcache_lock); | 1450 | spin_unlock(&dcache_lock); |
1424 | error = nfs_safe_remove(dentry); | 1451 | error = nfs_safe_remove(dentry); |
1425 | if (!error) { | 1452 | if (!error || error == -ENOENT) { |
1426 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1453 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1427 | } else if (need_rehash) | 1454 | } else if (need_rehash) |
1428 | d_rehash(dentry); | 1455 | d_rehash(dentry); |
@@ -1635,7 +1662,8 @@ out: | |||
1635 | d_move(old_dentry, new_dentry); | 1662 | d_move(old_dentry, new_dentry); |
1636 | nfs_set_verifier(new_dentry, | 1663 | nfs_set_verifier(new_dentry, |
1637 | nfs_save_change_attribute(new_dir)); | 1664 | nfs_save_change_attribute(new_dir)); |
1638 | } | 1665 | } else if (error == -ENOENT) |
1666 | nfs_dentry_handle_enoent(old_dentry); | ||
1639 | 1667 | ||
1640 | /* new dentry created? */ | 1668 | /* new dentry created? */ |
1641 | if (dentry) | 1669 | if (dentry) |
@@ -1666,13 +1694,19 @@ int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) | |||
1666 | restart: | 1694 | restart: |
1667 | spin_lock(&nfs_access_lru_lock); | 1695 | spin_lock(&nfs_access_lru_lock); |
1668 | 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; | ||
1669 | struct inode *inode; | 1698 | struct inode *inode; |
1670 | 1699 | ||
1671 | if (nr_to_scan-- == 0) | 1700 | if (nr_to_scan-- == 0) |
1672 | break; | 1701 | break; |
1702 | s_umount = &nfsi->vfs_inode.i_sb->s_umount; | ||
1703 | if (!down_read_trylock(s_umount)) | ||
1704 | continue; | ||
1673 | inode = igrab(&nfsi->vfs_inode); | 1705 | inode = igrab(&nfsi->vfs_inode); |
1674 | if (inode == NULL) | 1706 | if (inode == NULL) { |
1707 | up_read(s_umount); | ||
1675 | continue; | 1708 | continue; |
1709 | } | ||
1676 | spin_lock(&inode->i_lock); | 1710 | spin_lock(&inode->i_lock); |
1677 | if (list_empty(&nfsi->access_cache_entry_lru)) | 1711 | if (list_empty(&nfsi->access_cache_entry_lru)) |
1678 | goto remove_lru_entry; | 1712 | goto remove_lru_entry; |
@@ -1691,6 +1725,7 @@ remove_lru_entry: | |||
1691 | spin_unlock(&inode->i_lock); | 1725 | spin_unlock(&inode->i_lock); |
1692 | spin_unlock(&nfs_access_lru_lock); | 1726 | spin_unlock(&nfs_access_lru_lock); |
1693 | iput(inode); | 1727 | iput(inode); |
1728 | up_read(s_umount); | ||
1694 | goto restart; | 1729 | goto restart; |
1695 | } | 1730 | } |
1696 | spin_unlock(&nfs_access_lru_lock); | 1731 | spin_unlock(&nfs_access_lru_lock); |
@@ -1731,7 +1766,7 @@ static void __nfs_access_zap_cache(struct inode *inode) | |||
1731 | void nfs_access_zap_cache(struct inode *inode) | 1766 | void nfs_access_zap_cache(struct inode *inode) |
1732 | { | 1767 | { |
1733 | /* Remove from global LRU init */ | 1768 | /* Remove from global LRU init */ |
1734 | if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) { | 1769 | if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { |
1735 | spin_lock(&nfs_access_lru_lock); | 1770 | spin_lock(&nfs_access_lru_lock); |
1736 | list_del_init(&NFS_I(inode)->access_cache_inode_lru); | 1771 | list_del_init(&NFS_I(inode)->access_cache_inode_lru); |
1737 | spin_unlock(&nfs_access_lru_lock); | 1772 | spin_unlock(&nfs_access_lru_lock); |
@@ -1845,7 +1880,7 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s | |||
1845 | smp_mb__after_atomic_inc(); | 1880 | smp_mb__after_atomic_inc(); |
1846 | 1881 | ||
1847 | /* Add inode to global LRU list */ | 1882 | /* Add inode to global LRU list */ |
1848 | if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) { | 1883 | if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { |
1849 | spin_lock(&nfs_access_lru_lock); | 1884 | spin_lock(&nfs_access_lru_lock); |
1850 | list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list); | 1885 | list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list); |
1851 | spin_unlock(&nfs_access_lru_lock); | 1886 | spin_unlock(&nfs_access_lru_lock); |