diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-01-15 12:21:12 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-01-24 15:58:21 -0500 |
commit | d50e61361c68a05a9cd7d54617522f99f278ac8a (patch) | |
tree | ee0f62664a334349fc18445deef62cca0cd31e3a /fs/nfsd | |
parent | 068c34c0ce8add2e5f01ee6c85710e6fefb832ad (diff) |
nfsd4: decrease nfsd4_encode_fattr stack usage
A struct svc_fh is 320 bytes on x86_64, it'd be better not to have these
on the stack.
kmalloc'ing them probably isn't ideal either, but this is the simplest
thing to do. If it turns out to be a problem in the readdir case then
we could add a svc_fh to nfsd4_readdir and pass that in.
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8198ecf3c03a..63f2395c57ed 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -2058,7 +2058,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
2058 | u32 bmval1 = bmval[1]; | 2058 | u32 bmval1 = bmval[1]; |
2059 | u32 bmval2 = bmval[2]; | 2059 | u32 bmval2 = bmval[2]; |
2060 | struct kstat stat; | 2060 | struct kstat stat; |
2061 | struct svc_fh tempfh; | 2061 | struct svc_fh *tempfh = NULL; |
2062 | struct kstatfs statfs; | 2062 | struct kstatfs statfs; |
2063 | int buflen = count << 2; | 2063 | int buflen = count << 2; |
2064 | __be32 *attrlenp; | 2064 | __be32 *attrlenp; |
@@ -2105,11 +2105,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
2105 | goto out_nfserr; | 2105 | goto out_nfserr; |
2106 | } | 2106 | } |
2107 | if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { | 2107 | if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { |
2108 | fh_init(&tempfh, NFS4_FHSIZE); | 2108 | tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); |
2109 | status = fh_compose(&tempfh, exp, dentry, NULL); | 2109 | status = nfserr_jukebox; |
2110 | if (!tempfh) | ||
2111 | goto out; | ||
2112 | fh_init(tempfh, NFS4_FHSIZE); | ||
2113 | status = fh_compose(tempfh, exp, dentry, NULL); | ||
2110 | if (status) | 2114 | if (status) |
2111 | goto out; | 2115 | goto out; |
2112 | fhp = &tempfh; | 2116 | fhp = tempfh; |
2113 | } | 2117 | } |
2114 | if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | 2118 | if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT |
2115 | | FATTR4_WORD0_SUPPORTED_ATTRS)) { | 2119 | | FATTR4_WORD0_SUPPORTED_ATTRS)) { |
@@ -2495,8 +2499,8 @@ out: | |||
2495 | security_release_secctx(context, contextlen); | 2499 | security_release_secctx(context, contextlen); |
2496 | #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ | 2500 | #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ |
2497 | kfree(acl); | 2501 | kfree(acl); |
2498 | if (fhp == &tempfh) | 2502 | if (tempfh) |
2499 | fh_put(&tempfh); | 2503 | fh_put(tempfh); |
2500 | return status; | 2504 | return status; |
2501 | out_nfserr: | 2505 | out_nfserr: |
2502 | status = nfserrno(err); | 2506 | status = nfserrno(err); |