diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-04-17 00:22:49 +0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-05-14 23:09:25 +0400 |
commit | aa49b4cf7dbf45438563f0ff6a2d23a68b70a7b9 (patch) | |
tree | 39304ffe1812f5407dc20bc77c6dccfa2d060912 /fs/nfs | |
parent | 011fff7239eb90e33e7bebba48bf596fced06eb9 (diff) | |
download | linux-aa49b4cf7dbf45438563f0ff6a2d23a68b70a7b9.tar.xz |
NFS: Reduce stack footprint of nfs_readdir()
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 13 |
2 files changed, 18 insertions, 12 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1debc09eb55f..18da8abbece8 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) nfs_readdir_descriptor_t my_desc, *desc = &my_desc; struct nfs_entry my_entry; - struct nfs_fh fh; - struct nfs_fattr fattr; - long res; + int res = -ENOMEM; dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 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) my_entry.cookie = my_entry.prev_cookie = 0; my_entry.eof = 0; - my_entry.fh = &fh; - my_entry.fattr = &fattr; - nfs_fattr_init(&fattr); + my_entry.fh = nfs_alloc_fhandle(); + my_entry.fattr = nfs_alloc_fattr(); + if (my_entry.fh == NULL || my_entry.fattr == NULL) + goto out_alloc_failed; + desc->entry = &my_entry; nfs_block_sillyrename(dentry); @@ -598,7 +598,10 @@ out: nfs_unblock_sillyrename(dentry); if (res > 0) res = 0; - dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", +out_alloc_failed: + nfs_free_fattr(my_entry.fattr); + nfs_free_fhandle(my_entry.fh); + dfprintk(FILE, "NFS: readdir(%s/%s) returns %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, res); return res; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index c252fc983a7e..1c5bfb3d6f08 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -597,7 +597,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, u64 cookie, struct page *page, unsigned int count, int plus) { struct inode *dir = dentry->d_inode; - struct nfs_fattr dir_attr; __be32 *verf = NFS_COOKIEVERF(dir); struct nfs3_readdirargs arg = { .fh = NFS_FH(dir), @@ -608,7 +607,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, .pages = &page }; struct nfs3_readdirres res = { - .dir_attr = &dir_attr, .verf = verf, .plus = plus }; @@ -618,7 +616,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, .rpc_resp = &res, .rpc_cred = cred }; - int status; + int status = -ENOMEM; if (plus) msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; @@ -626,12 +624,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, dprintk("NFS call readdir%s %d\n", plus? "plus" : "", (unsigned int) cookie); - nfs_fattr_init(&dir_attr); + res.dir_attr = nfs_alloc_fattr(); + if (res.dir_attr == NULL) + goto out; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_invalidate_atime(dir); + nfs_refresh_inode(dir, res.dir_attr); - nfs_refresh_inode(dir, &dir_attr); + nfs_free_fattr(res.dir_attr); +out: dprintk("NFS reply readdir: %d\n", status); return status; } |