diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-04-16 16:22:48 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-05-14 15:09:23 -0400 |
commit | 04ffdbe2e69beb0f1745f921871fbe0f97dc4697 (patch) | |
tree | b977a04f4f9a62bdadfc74e2a8669833d65db714 /fs/nfs/super.c | |
parent | e1fb4d05d5a3265f1f6769bee034175f91ecc2dd (diff) |
NFS: Reduce the stack footprint of nfs_follow_remote_path()
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b4148fc00f9f..fa3111eea29a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2672,38 +2672,44 @@ out_freepage: | |||
2672 | static int nfs_follow_remote_path(struct vfsmount *root_mnt, | 2672 | static int nfs_follow_remote_path(struct vfsmount *root_mnt, |
2673 | const char *export_path, struct vfsmount *mnt_target) | 2673 | const char *export_path, struct vfsmount *mnt_target) |
2674 | { | 2674 | { |
2675 | struct nameidata *nd = NULL; | ||
2675 | struct mnt_namespace *ns_private; | 2676 | struct mnt_namespace *ns_private; |
2676 | struct nameidata nd; | ||
2677 | struct super_block *s; | 2677 | struct super_block *s; |
2678 | int ret; | 2678 | int ret; |
2679 | 2679 | ||
2680 | nd = kmalloc(sizeof(*nd), GFP_KERNEL); | ||
2681 | if (nd == NULL) | ||
2682 | return -ENOMEM; | ||
2683 | |||
2680 | ns_private = create_mnt_ns(root_mnt); | 2684 | ns_private = create_mnt_ns(root_mnt); |
2681 | ret = PTR_ERR(ns_private); | 2685 | ret = PTR_ERR(ns_private); |
2682 | if (IS_ERR(ns_private)) | 2686 | if (IS_ERR(ns_private)) |
2683 | goto out_mntput; | 2687 | goto out_mntput; |
2684 | 2688 | ||
2685 | ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, | 2689 | ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, |
2686 | export_path, LOOKUP_FOLLOW, &nd); | 2690 | export_path, LOOKUP_FOLLOW, nd); |
2687 | 2691 | ||
2688 | put_mnt_ns(ns_private); | 2692 | put_mnt_ns(ns_private); |
2689 | 2693 | ||
2690 | if (ret != 0) | 2694 | if (ret != 0) |
2691 | goto out_err; | 2695 | goto out_err; |
2692 | 2696 | ||
2693 | s = nd.path.mnt->mnt_sb; | 2697 | s = nd->path.mnt->mnt_sb; |
2694 | atomic_inc(&s->s_active); | 2698 | atomic_inc(&s->s_active); |
2695 | mnt_target->mnt_sb = s; | 2699 | mnt_target->mnt_sb = s; |
2696 | mnt_target->mnt_root = dget(nd.path.dentry); | 2700 | mnt_target->mnt_root = dget(nd->path.dentry); |
2697 | 2701 | ||
2698 | /* Correct the device pathname */ | 2702 | /* Correct the device pathname */ |
2699 | nfs_fix_devname(&nd.path, mnt_target); | 2703 | nfs_fix_devname(&nd->path, mnt_target); |
2700 | 2704 | ||
2701 | path_put(&nd.path); | 2705 | path_put(&nd->path); |
2706 | kfree(nd); | ||
2702 | down_write(&s->s_umount); | 2707 | down_write(&s->s_umount); |
2703 | return 0; | 2708 | return 0; |
2704 | out_mntput: | 2709 | out_mntput: |
2705 | mntput(root_mnt); | 2710 | mntput(root_mnt); |
2706 | out_err: | 2711 | out_err: |
2712 | kfree(nd); | ||
2707 | return ret; | 2713 | return ret; |
2708 | } | 2714 | } |
2709 | 2715 | ||