diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-04-16 16:22:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-05-14 15:09:23 -0400 |
commit | e1fb4d05d5a3265f1f6769bee034175f91ecc2dd (patch) | |
tree | b5a1d30b2f57e0b9c1d021ed653030fb5c699147 /fs/nfs/dir.c | |
parent | 364d015e5208e4669a4ae9fab2ab104ff26bc159 (diff) |
NFS: Reduce the stack footprint of nfs_lookup
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index a7bb5c694aa3..1debc09eb55f 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -776,9 +776,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) | |||
776 | struct inode *dir; | 776 | struct inode *dir; |
777 | struct inode *inode; | 777 | struct inode *inode; |
778 | struct dentry *parent; | 778 | struct dentry *parent; |
779 | struct nfs_fh *fhandle = NULL; | ||
780 | struct nfs_fattr *fattr = NULL; | ||
779 | int error; | 781 | int error; |
780 | struct nfs_fh fhandle; | ||
781 | struct nfs_fattr fattr; | ||
782 | 782 | ||
783 | parent = dget_parent(dentry); | 783 | parent = dget_parent(dentry); |
784 | dir = parent->d_inode; | 784 | dir = parent->d_inode; |
@@ -811,14 +811,22 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) | |||
811 | if (NFS_STALE(inode)) | 811 | if (NFS_STALE(inode)) |
812 | goto out_bad; | 812 | goto out_bad; |
813 | 813 | ||
814 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); | 814 | error = -ENOMEM; |
815 | fhandle = nfs_alloc_fhandle(); | ||
816 | fattr = nfs_alloc_fattr(); | ||
817 | if (fhandle == NULL || fattr == NULL) | ||
818 | goto out_error; | ||
819 | |||
820 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); | ||
815 | if (error) | 821 | if (error) |
816 | goto out_bad; | 822 | goto out_bad; |
817 | if (nfs_compare_fh(NFS_FH(inode), &fhandle)) | 823 | if (nfs_compare_fh(NFS_FH(inode), fhandle)) |
818 | goto out_bad; | 824 | goto out_bad; |
819 | if ((error = nfs_refresh_inode(inode, &fattr)) != 0) | 825 | if ((error = nfs_refresh_inode(inode, fattr)) != 0) |
820 | goto out_bad; | 826 | goto out_bad; |
821 | 827 | ||
828 | nfs_free_fattr(fattr); | ||
829 | nfs_free_fhandle(fhandle); | ||
822 | out_set_verifier: | 830 | out_set_verifier: |
823 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 831 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
824 | out_valid: | 832 | out_valid: |
@@ -842,11 +850,21 @@ out_zap_parent: | |||
842 | shrink_dcache_parent(dentry); | 850 | shrink_dcache_parent(dentry); |
843 | } | 851 | } |
844 | d_drop(dentry); | 852 | d_drop(dentry); |
853 | nfs_free_fattr(fattr); | ||
854 | nfs_free_fhandle(fhandle); | ||
845 | dput(parent); | 855 | dput(parent); |
846 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", | 856 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", |
847 | __func__, dentry->d_parent->d_name.name, | 857 | __func__, dentry->d_parent->d_name.name, |
848 | dentry->d_name.name); | 858 | dentry->d_name.name); |
849 | return 0; | 859 | return 0; |
860 | out_error: | ||
861 | nfs_free_fattr(fattr); | ||
862 | nfs_free_fhandle(fhandle); | ||
863 | dput(parent); | ||
864 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", | ||
865 | __func__, dentry->d_parent->d_name.name, | ||
866 | dentry->d_name.name, error); | ||
867 | return error; | ||
850 | } | 868 | } |
851 | 869 | ||
852 | /* | 870 | /* |
@@ -911,9 +929,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
911 | struct dentry *res; | 929 | struct dentry *res; |
912 | struct dentry *parent; | 930 | struct dentry *parent; |
913 | struct inode *inode = NULL; | 931 | struct inode *inode = NULL; |
932 | struct nfs_fh *fhandle = NULL; | ||
933 | struct nfs_fattr *fattr = NULL; | ||
914 | int error; | 934 | int error; |
915 | struct nfs_fh fhandle; | ||
916 | struct nfs_fattr fattr; | ||
917 | 935 | ||
918 | dfprintk(VFS, "NFS: lookup(%s/%s)\n", | 936 | dfprintk(VFS, "NFS: lookup(%s/%s)\n", |
919 | dentry->d_parent->d_name.name, dentry->d_name.name); | 937 | dentry->d_parent->d_name.name, dentry->d_name.name); |
@@ -923,7 +941,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
923 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) | 941 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) |
924 | goto out; | 942 | goto out; |
925 | 943 | ||
926 | res = ERR_PTR(-ENOMEM); | ||
927 | dentry->d_op = NFS_PROTO(dir)->dentry_ops; | 944 | dentry->d_op = NFS_PROTO(dir)->dentry_ops; |
928 | 945 | ||
929 | /* | 946 | /* |
@@ -936,17 +953,23 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
936 | goto out; | 953 | goto out; |
937 | } | 954 | } |
938 | 955 | ||
956 | res = ERR_PTR(-ENOMEM); | ||
957 | fhandle = nfs_alloc_fhandle(); | ||
958 | fattr = nfs_alloc_fattr(); | ||
959 | if (fhandle == NULL || fattr == NULL) | ||
960 | goto out; | ||
961 | |||
939 | parent = dentry->d_parent; | 962 | parent = dentry->d_parent; |
940 | /* Protect against concurrent sillydeletes */ | 963 | /* Protect against concurrent sillydeletes */ |
941 | nfs_block_sillyrename(parent); | 964 | nfs_block_sillyrename(parent); |
942 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); | 965 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); |
943 | if (error == -ENOENT) | 966 | if (error == -ENOENT) |
944 | goto no_entry; | 967 | goto no_entry; |
945 | if (error < 0) { | 968 | if (error < 0) { |
946 | res = ERR_PTR(error); | 969 | res = ERR_PTR(error); |
947 | goto out_unblock_sillyrename; | 970 | goto out_unblock_sillyrename; |
948 | } | 971 | } |
949 | inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); | 972 | inode = nfs_fhget(dentry->d_sb, fhandle, fattr); |
950 | res = (struct dentry *)inode; | 973 | res = (struct dentry *)inode; |
951 | if (IS_ERR(res)) | 974 | if (IS_ERR(res)) |
952 | goto out_unblock_sillyrename; | 975 | goto out_unblock_sillyrename; |
@@ -962,6 +985,8 @@ no_entry: | |||
962 | out_unblock_sillyrename: | 985 | out_unblock_sillyrename: |
963 | nfs_unblock_sillyrename(parent); | 986 | nfs_unblock_sillyrename(parent); |
964 | out: | 987 | out: |
988 | nfs_free_fattr(fattr); | ||
989 | nfs_free_fhandle(fhandle); | ||
965 | return res; | 990 | return res; |
966 | } | 991 | } |
967 | 992 | ||