diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-04-16 16:22:49 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-05-14 15:09:25 -0400 |
commit | aa49b4cf7dbf45438563f0ff6a2d23a68b70a7b9 (patch) | |
tree | 39304ffe1812f5407dc20bc77c6dccfa2d060912 /fs/nfs | |
parent | 011fff7239eb90e33e7bebba48bf596fced06eb9 (diff) |
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) | |||
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", | 601 | out_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; |
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, | |||
597 | u64 cookie, struct page *page, unsigned int count, int plus) | 597 | u64 cookie, struct page *page, unsigned int count, int plus) |
598 | { | 598 | { |
599 | struct inode *dir = dentry->d_inode; | 599 | struct inode *dir = dentry->d_inode; |
600 | struct nfs_fattr dir_attr; | ||
601 | __be32 *verf = NFS_COOKIEVERF(dir); | 600 | __be32 *verf = NFS_COOKIEVERF(dir); |
602 | struct nfs3_readdirargs arg = { | 601 | struct nfs3_readdirargs arg = { |
603 | .fh = NFS_FH(dir), | 602 | .fh = NFS_FH(dir), |
@@ -608,7 +607,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
608 | .pages = &page | 607 | .pages = &page |
609 | }; | 608 | }; |
610 | struct nfs3_readdirres res = { | 609 | struct nfs3_readdirres res = { |
611 | .dir_attr = &dir_attr, | ||
612 | .verf = verf, | 610 | .verf = verf, |
613 | .plus = plus | 611 | .plus = plus |
614 | }; | 612 | }; |
@@ -618,7 +616,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
618 | .rpc_resp = &res, | 616 | .rpc_resp = &res, |
619 | .rpc_cred = cred | 617 | .rpc_cred = cred |
620 | }; | 618 | }; |
621 | int status; | 619 | int status = -ENOMEM; |
622 | 620 | ||
623 | if (plus) | 621 | if (plus) |
624 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; | 622 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; |
@@ -626,12 +624,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
626 | dprintk("NFS call readdir%s %d\n", | 624 | dprintk("NFS call readdir%s %d\n", |
627 | plus? "plus" : "", (unsigned int) cookie); | 625 | plus? "plus" : "", (unsigned int) cookie); |
628 | 626 | ||
629 | nfs_fattr_init(&dir_attr); | 627 | res.dir_attr = nfs_alloc_fattr(); |
628 | if (res.dir_attr == NULL) | ||
629 | goto out; | ||
630 | |||
630 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 631 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
631 | 632 | ||
632 | nfs_invalidate_atime(dir); | 633 | nfs_invalidate_atime(dir); |
634 | nfs_refresh_inode(dir, res.dir_attr); | ||
633 | 635 | ||
634 | nfs_refresh_inode(dir, &dir_attr); | 636 | nfs_free_fattr(res.dir_attr); |
637 | out: | ||
635 | dprintk("NFS reply readdir: %d\n", status); | 638 | dprintk("NFS reply readdir: %d\n", status); |
636 | return status; | 639 | return status; |
637 | } | 640 | } |