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.c145
1 files changed, 83 insertions, 62 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index db3ad849a289..ee9a179ebdf3 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -530,9 +530,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
530 nfs_readdir_descriptor_t my_desc, 530 nfs_readdir_descriptor_t my_desc,
531 *desc = &my_desc; 531 *desc = &my_desc;
532 struct nfs_entry my_entry; 532 struct nfs_entry my_entry;
533 struct nfs_fh fh; 533 int res = -ENOMEM;
534 struct nfs_fattr fattr;
535 long res;
536 534
537 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 535 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
538 dentry->d_parent->d_name.name, dentry->d_name.name, 536 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -554,9 +552,11 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
554 552
555 my_entry.cookie = my_entry.prev_cookie = 0; 553 my_entry.cookie = my_entry.prev_cookie = 0;
556 my_entry.eof = 0; 554 my_entry.eof = 0;
557 my_entry.fh = &fh; 555 my_entry.fh = nfs_alloc_fhandle();
558 my_entry.fattr = &fattr; 556 my_entry.fattr = nfs_alloc_fattr();
559 nfs_fattr_init(&fattr); 557 if (my_entry.fh == NULL || my_entry.fattr == NULL)
558 goto out_alloc_failed;
559
560 desc->entry = &my_entry; 560 desc->entry = &my_entry;
561 561
562 nfs_block_sillyrename(dentry); 562 nfs_block_sillyrename(dentry);
@@ -598,7 +598,10 @@ out:
598 nfs_unblock_sillyrename(dentry); 598 nfs_unblock_sillyrename(dentry);
599 if (res > 0) 599 if (res > 0)
600 res = 0; 600 res = 0;
601 dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", 601out_alloc_failed:
602 nfs_free_fattr(my_entry.fattr);
603 nfs_free_fhandle(my_entry.fh);
604 dfprintk(FILE, "NFS: readdir(%s/%s) returns %d\n",
602 dentry->d_parent->d_name.name, dentry->d_name.name, 605 dentry->d_parent->d_name.name, dentry->d_name.name,
603 res); 606 res);
604 return res; 607 return res;
@@ -776,9 +779,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
776 struct inode *dir; 779 struct inode *dir;
777 struct inode *inode; 780 struct inode *inode;
778 struct dentry *parent; 781 struct dentry *parent;
782 struct nfs_fh *fhandle = NULL;
783 struct nfs_fattr *fattr = NULL;
779 int error; 784 int error;
780 struct nfs_fh fhandle;
781 struct nfs_fattr fattr;
782 785
783 parent = dget_parent(dentry); 786 parent = dget_parent(dentry);
784 dir = parent->d_inode; 787 dir = parent->d_inode;
@@ -811,14 +814,22 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
811 if (NFS_STALE(inode)) 814 if (NFS_STALE(inode))
812 goto out_bad; 815 goto out_bad;
813 816
814 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); 817 error = -ENOMEM;
818 fhandle = nfs_alloc_fhandle();
819 fattr = nfs_alloc_fattr();
820 if (fhandle == NULL || fattr == NULL)
821 goto out_error;
822
823 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
815 if (error) 824 if (error)
816 goto out_bad; 825 goto out_bad;
817 if (nfs_compare_fh(NFS_FH(inode), &fhandle)) 826 if (nfs_compare_fh(NFS_FH(inode), fhandle))
818 goto out_bad; 827 goto out_bad;
819 if ((error = nfs_refresh_inode(inode, &fattr)) != 0) 828 if ((error = nfs_refresh_inode(inode, fattr)) != 0)
820 goto out_bad; 829 goto out_bad;
821 830
831 nfs_free_fattr(fattr);
832 nfs_free_fhandle(fhandle);
822out_set_verifier: 833out_set_verifier:
823 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 834 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
824 out_valid: 835 out_valid:
@@ -842,11 +853,21 @@ out_zap_parent:
842 shrink_dcache_parent(dentry); 853 shrink_dcache_parent(dentry);
843 } 854 }
844 d_drop(dentry); 855 d_drop(dentry);
856 nfs_free_fattr(fattr);
857 nfs_free_fhandle(fhandle);
845 dput(parent); 858 dput(parent);
846 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", 859 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n",
847 __func__, dentry->d_parent->d_name.name, 860 __func__, dentry->d_parent->d_name.name,
848 dentry->d_name.name); 861 dentry->d_name.name);
849 return 0; 862 return 0;
863out_error:
864 nfs_free_fattr(fattr);
865 nfs_free_fhandle(fhandle);
866 dput(parent);
867 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n",
868 __func__, dentry->d_parent->d_name.name,
869 dentry->d_name.name, error);
870 return error;
850} 871}
851 872
852/* 873/*
@@ -911,9 +932,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
911 struct dentry *res; 932 struct dentry *res;
912 struct dentry *parent; 933 struct dentry *parent;
913 struct inode *inode = NULL; 934 struct inode *inode = NULL;
935 struct nfs_fh *fhandle = NULL;
936 struct nfs_fattr *fattr = NULL;
914 int error; 937 int error;
915 struct nfs_fh fhandle;
916 struct nfs_fattr fattr;
917 938
918 dfprintk(VFS, "NFS: lookup(%s/%s)\n", 939 dfprintk(VFS, "NFS: lookup(%s/%s)\n",
919 dentry->d_parent->d_name.name, dentry->d_name.name); 940 dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -923,7 +944,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
923 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) 944 if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
924 goto out; 945 goto out;
925 946
926 res = ERR_PTR(-ENOMEM);
927 dentry->d_op = NFS_PROTO(dir)->dentry_ops; 947 dentry->d_op = NFS_PROTO(dir)->dentry_ops;
928 948
929 /* 949 /*
@@ -936,17 +956,23 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
936 goto out; 956 goto out;
937 } 957 }
938 958
959 res = ERR_PTR(-ENOMEM);
960 fhandle = nfs_alloc_fhandle();
961 fattr = nfs_alloc_fattr();
962 if (fhandle == NULL || fattr == NULL)
963 goto out;
964
939 parent = dentry->d_parent; 965 parent = dentry->d_parent;
940 /* Protect against concurrent sillydeletes */ 966 /* Protect against concurrent sillydeletes */
941 nfs_block_sillyrename(parent); 967 nfs_block_sillyrename(parent);
942 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); 968 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
943 if (error == -ENOENT) 969 if (error == -ENOENT)
944 goto no_entry; 970 goto no_entry;
945 if (error < 0) { 971 if (error < 0) {
946 res = ERR_PTR(error); 972 res = ERR_PTR(error);
947 goto out_unblock_sillyrename; 973 goto out_unblock_sillyrename;
948 } 974 }
949 inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); 975 inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
950 res = (struct dentry *)inode; 976 res = (struct dentry *)inode;
951 if (IS_ERR(res)) 977 if (IS_ERR(res))
952 goto out_unblock_sillyrename; 978 goto out_unblock_sillyrename;
@@ -962,6 +988,8 @@ no_entry:
962out_unblock_sillyrename: 988out_unblock_sillyrename:
963 nfs_unblock_sillyrename(parent); 989 nfs_unblock_sillyrename(parent);
964out: 990out:
991 nfs_free_fattr(fattr);
992 nfs_free_fhandle(fhandle);
965 return res; 993 return res;
966} 994}
967 995
@@ -1052,7 +1080,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1052 struct inode *dir; 1080 struct inode *dir;
1053 int openflags, ret = 0; 1081 int openflags, ret = 0;
1054 1082
1055 if (!is_atomic_open(nd)) 1083 if (!is_atomic_open(nd) || d_mountpoint(dentry))
1056 goto no_open; 1084 goto no_open;
1057 parent = dget_parent(dentry); 1085 parent = dget_parent(dentry);
1058 dir = parent->d_inode; 1086 dir = parent->d_inode;
@@ -1669,28 +1697,33 @@ static void nfs_access_free_entry(struct nfs_access_entry *entry)
1669 smp_mb__after_atomic_dec(); 1697 smp_mb__after_atomic_dec();
1670} 1698}
1671 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
1672int 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)
1673{ 1712{
1674 LIST_HEAD(head); 1713 LIST_HEAD(head);
1675 struct nfs_inode *nfsi; 1714 struct nfs_inode *nfsi;
1676 struct nfs_access_entry *cache; 1715 struct nfs_access_entry *cache;
1677 1716
1678restart: 1717 if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
1718 return (nr_to_scan == 0) ? 0 : -1;
1719
1679 spin_lock(&nfs_access_lru_lock); 1720 spin_lock(&nfs_access_lru_lock);
1680 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) { 1721 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
1681 struct rw_semaphore *s_umount;
1682 struct inode *inode; 1722 struct inode *inode;
1683 1723
1684 if (nr_to_scan-- == 0) 1724 if (nr_to_scan-- == 0)
1685 break; 1725 break;
1686 s_umount = &nfsi->vfs_inode.i_sb->s_umount; 1726 inode = &nfsi->vfs_inode;
1687 if (!down_read_trylock(s_umount))
1688 continue;
1689 inode = igrab(&nfsi->vfs_inode);
1690 if (inode == NULL) {
1691 up_read(s_umount);
1692 continue;
1693 }
1694 spin_lock(&inode->i_lock); 1727 spin_lock(&inode->i_lock);
1695 if (list_empty(&nfsi->access_cache_entry_lru)) 1728 if (list_empty(&nfsi->access_cache_entry_lru))
1696 goto remove_lru_entry; 1729 goto remove_lru_entry;
@@ -1704,61 +1737,47 @@ restart:
1704 else { 1737 else {
1705remove_lru_entry: 1738remove_lru_entry:
1706 list_del_init(&nfsi->access_cache_inode_lru); 1739 list_del_init(&nfsi->access_cache_inode_lru);
1740 smp_mb__before_clear_bit();
1707 clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags); 1741 clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
1742 smp_mb__after_clear_bit();
1708 } 1743 }
1709 spin_unlock(&inode->i_lock);
1710 spin_unlock(&nfs_access_lru_lock);
1711 iput(inode);
1712 up_read(s_umount);
1713 goto restart;
1714 } 1744 }
1715 spin_unlock(&nfs_access_lru_lock); 1745 spin_unlock(&nfs_access_lru_lock);
1716 while (!list_empty(&head)) { 1746 nfs_access_free_list(&head);
1717 cache = list_entry(head.next, struct nfs_access_entry, lru);
1718 list_del(&cache->lru);
1719 nfs_access_free_entry(cache);
1720 }
1721 return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure; 1747 return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure;
1722} 1748}
1723 1749
1724static void __nfs_access_zap_cache(struct inode *inode) 1750static void __nfs_access_zap_cache(struct nfs_inode *nfsi, struct list_head *head)
1725{ 1751{
1726 struct nfs_inode *nfsi = NFS_I(inode);
1727 struct rb_root *root_node = &nfsi->access_cache; 1752 struct rb_root *root_node = &nfsi->access_cache;
1728 struct rb_node *n, *dispose = NULL; 1753 struct rb_node *n;
1729 struct nfs_access_entry *entry; 1754 struct nfs_access_entry *entry;
1730 1755
1731 /* Unhook entries from the cache */ 1756 /* Unhook entries from the cache */
1732 while ((n = rb_first(root_node)) != NULL) { 1757 while ((n = rb_first(root_node)) != NULL) {
1733 entry = rb_entry(n, struct nfs_access_entry, rb_node); 1758 entry = rb_entry(n, struct nfs_access_entry, rb_node);
1734 rb_erase(n, root_node); 1759 rb_erase(n, root_node);
1735 list_del(&entry->lru); 1760 list_move(&entry->lru, head);
1736 n->rb_left = dispose;
1737 dispose = n;
1738 } 1761 }
1739 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; 1762 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
1740 spin_unlock(&inode->i_lock);
1741
1742 /* Now kill them all! */
1743 while (dispose != NULL) {
1744 n = dispose;
1745 dispose = n->rb_left;
1746 nfs_access_free_entry(rb_entry(n, struct nfs_access_entry, rb_node));
1747 }
1748} 1763}
1749 1764
1750void nfs_access_zap_cache(struct inode *inode) 1765void nfs_access_zap_cache(struct inode *inode)
1751{ 1766{
1767 LIST_HEAD(head);
1768
1769 if (test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags) == 0)
1770 return;
1752 /* Remove from global LRU init */ 1771 /* Remove from global LRU init */
1753 if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { 1772 spin_lock(&nfs_access_lru_lock);
1754 spin_lock(&nfs_access_lru_lock); 1773 if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
1755 list_del_init(&NFS_I(inode)->access_cache_inode_lru); 1774 list_del_init(&NFS_I(inode)->access_cache_inode_lru);
1756 spin_unlock(&nfs_access_lru_lock);
1757 }
1758 1775
1759 spin_lock(&inode->i_lock); 1776 spin_lock(&inode->i_lock);
1760 /* This will release the spinlock */ 1777 __nfs_access_zap_cache(NFS_I(inode), &head);
1761 __nfs_access_zap_cache(inode); 1778 spin_unlock(&inode->i_lock);
1779 spin_unlock(&nfs_access_lru_lock);
1780 nfs_access_free_list(&head);
1762} 1781}
1763 1782
1764static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) 1783static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
@@ -1809,8 +1828,8 @@ out_stale:
1809 nfs_access_free_entry(cache); 1828 nfs_access_free_entry(cache);
1810 return -ENOENT; 1829 return -ENOENT;
1811out_zap: 1830out_zap:
1812 /* This will release the spinlock */ 1831 spin_unlock(&inode->i_lock);
1813 __nfs_access_zap_cache(inode); 1832 nfs_access_zap_cache(inode);
1814 return -ENOENT; 1833 return -ENOENT;
1815} 1834}
1816 1835
@@ -1865,9 +1884,11 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
1865 smp_mb__after_atomic_inc(); 1884 smp_mb__after_atomic_inc();
1866 1885
1867 /* Add inode to global LRU list */ 1886 /* Add inode to global LRU list */
1868 if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) { 1887 if (!test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
1869 spin_lock(&nfs_access_lru_lock); 1888 spin_lock(&nfs_access_lru_lock);
1870 list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list); 1889 if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
1890 list_add_tail(&NFS_I(inode)->access_cache_inode_lru,
1891 &nfs_access_lru_list);
1871 spin_unlock(&nfs_access_lru_lock); 1892 spin_unlock(&nfs_access_lru_lock);
1872 } 1893 }
1873} 1894}