aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-13 12:51:06 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-14 15:09:35 -0400
commit1a81bb8a1fa62ccb9b2411ac10ce702ca4ed302a (patch)
tree7a4d29a36c2646b8cdd67d50f3b7778636e1dfbe /fs/nfs/dir.c
parent61d5eb2985b3b1d69fd53d7dc9789037c27f8d91 (diff)
NFS: Clean up nfs_access_zap_cache()
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 58b1f744c91e..1c71fc213716 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1697,6 +1697,17 @@ static void nfs_access_free_entry(struct nfs_access_entry *entry)
1697 smp_mb__after_atomic_dec(); 1697 smp_mb__after_atomic_dec();
1698} 1698}
1699 1699
1700static void nfs_access_free_list(struct list_head *head)
1701{
1702 struct nfs_access_entry *cache;
1703
1704 while (!list_empty(head)) {
1705 cache = list_entry(head->next, struct nfs_access_entry, lru);
1706 list_del(&cache->lru);
1707 nfs_access_free_entry(cache);
1708 }
1709}
1710
1700int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) 1711int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
1701{ 1712{
1702 LIST_HEAD(head); 1713 LIST_HEAD(head);
@@ -1743,52 +1754,41 @@ remove_lru_entry:
1743 goto restart; 1754 goto restart;
1744 } 1755 }
1745 spin_unlock(&nfs_access_lru_lock); 1756 spin_unlock(&nfs_access_lru_lock);
1746 while (!list_empty(&head)) { 1757 nfs_access_free_list(&head);
1747 cache = list_entry(head.next, struct nfs_access_entry, lru);
1748 list_del(&cache->lru);
1749 nfs_access_free_entry(cache);
1750 }
1751 return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure; 1758 return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure;
1752} 1759}
1753 1760
1754static void __nfs_access_zap_cache(struct inode *inode) 1761static void __nfs_access_zap_cache(struct nfs_inode *nfsi, struct list_head *head)
1755{ 1762{
1756 struct nfs_inode *nfsi = NFS_I(inode);
1757 struct rb_root *root_node = &nfsi->access_cache; 1763 struct rb_root *root_node = &nfsi->access_cache;
1758 struct rb_node *n, *dispose = NULL; 1764 struct rb_node *n;
1759 struct nfs_access_entry *entry; 1765 struct nfs_access_entry *entry;
1760 1766
1761 /* Unhook entries from the cache */ 1767 /* Unhook entries from the cache */
1762 while ((n = rb_first(root_node)) != NULL) { 1768 while ((n = rb_first(root_node)) != NULL) {
1763 entry = rb_entry(n, struct nfs_access_entry, rb_node); 1769 entry = rb_entry(n, struct nfs_access_entry, rb_node);
1764 rb_erase(n, root_node); 1770 rb_erase(n, root_node);
1765 list_del(&entry->lru); 1771 list_move(&entry->lru, head);
1766 n->rb_left = dispose;
1767 dispose = n;
1768 } 1772 }
1769 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; 1773 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
1770 spin_unlock(&inode->i_lock);
1771
1772 /* Now kill them all! */
1773 while (dispose != NULL) {
1774 n = dispose;
1775 dispose = n->rb_left;
1776 nfs_access_free_entry(rb_entry(n, struct nfs_access_entry, rb_node));
1777 }
1778} 1774}
1779 1775
1780void nfs_access_zap_cache(struct inode *inode) 1776void nfs_access_zap_cache(struct inode *inode)
1781{ 1777{
1778 LIST_HEAD(head);
1779
1780 if (test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags) == 0)
1781 return;
1782 /* Remove from global LRU init */ 1782 /* Remove from global LRU init */
1783 if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { 1783 spin_lock(&nfs_access_lru_lock);
1784 spin_lock(&nfs_access_lru_lock); 1784 if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
1785 list_del_init(&NFS_I(inode)->access_cache_inode_lru); 1785 list_del_init(&NFS_I(inode)->access_cache_inode_lru);
1786 spin_unlock(&nfs_access_lru_lock);
1787 }
1788 1786
1789 spin_lock(&inode->i_lock); 1787 spin_lock(&inode->i_lock);
1790 /* This will release the spinlock */ 1788 __nfs_access_zap_cache(NFS_I(inode), &head);
1791 __nfs_access_zap_cache(inode); 1789 spin_unlock(&inode->i_lock);
1790 spin_unlock(&nfs_access_lru_lock);
1791 nfs_access_free_list(&head);
1792} 1792}
1793 1793
1794static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) 1794static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
@@ -1839,8 +1839,8 @@ out_stale:
1839 nfs_access_free_entry(cache); 1839 nfs_access_free_entry(cache);
1840 return -ENOENT; 1840 return -ENOENT;
1841out_zap: 1841out_zap:
1842 /* This will release the spinlock */ 1842 spin_unlock(&inode->i_lock);
1843 __nfs_access_zap_cache(inode); 1843 nfs_access_zap_cache(inode);
1844 return -ENOENT; 1844 return -ENOENT;
1845} 1845}
1846 1846
@@ -1895,9 +1895,11 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
1895 smp_mb__after_atomic_inc(); 1895 smp_mb__after_atomic_inc();
1896 1896
1897 /* Add inode to global LRU list */ 1897 /* Add inode to global LRU list */
1898 if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { 1898 if (!test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
1899 spin_lock(&nfs_access_lru_lock); 1899 spin_lock(&nfs_access_lru_lock);
1900 list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list); 1900 if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
1901 list_add_tail(&NFS_I(inode)->access_cache_inode_lru,
1902 &nfs_access_lru_list);
1901 spin_unlock(&nfs_access_lru_lock); 1903 spin_unlock(&nfs_access_lru_lock);
1902 } 1904 }
1903} 1905}