aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2012-05-10 15:07:35 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-14 20:30:28 -0400
commit8c958e0c4c52d600bd2ea677eb920fceda8aee49 (patch)
tree3590ce9504dad5d8dd7eab81429981758de5da8e /fs/nfs/super.c
parentc40f8d1d35a27d81b4af9d5d2f7286fd978ae9b2 (diff)
NFS: Create a common xdev_mount() function
The only difference between nfs_xdev_mount() and nfs4_xdev_mount() is the clone_super() function called to clone the super block. I can combine these two functions by using the fill_super field in the mount_info structure. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c122
1 files changed, 32 insertions, 90 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 64a62da6612d..707d1f67fb32 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -280,6 +280,7 @@ static match_table_t nfs_vers_tokens = {
280struct nfs_mount_info { 280struct nfs_mount_info {
281 void (*fill_super)(struct super_block *, struct nfs_mount_info *); 281 void (*fill_super)(struct super_block *, struct nfs_mount_info *);
282 struct nfs_parsed_mount_data *parsed; 282 struct nfs_parsed_mount_data *parsed;
283 struct nfs_clone_mount *cloned;
283}; 284};
284 285
285static void nfs_umount_begin(struct super_block *); 286static void nfs_umount_begin(struct super_block *);
@@ -2160,8 +2161,9 @@ static void nfs_fill_super(struct super_block *sb,
2160 * Finish setting up a cloned NFS2/3 superblock 2161 * Finish setting up a cloned NFS2/3 superblock
2161 */ 2162 */
2162static void nfs_clone_super(struct super_block *sb, 2163static void nfs_clone_super(struct super_block *sb,
2163 const struct super_block *old_sb) 2164 struct nfs_mount_info *mount_info)
2164{ 2165{
2166 const struct super_block *old_sb = mount_info->cloned->sb;
2165 struct nfs_server *server = NFS_SB(sb); 2167 struct nfs_server *server = NFS_SB(sb);
2166 2168
2167 sb->s_blocksize_bits = old_sb->s_blocksize_bits; 2169 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
@@ -2454,13 +2456,13 @@ static void nfs_kill_super(struct super_block *s)
2454} 2456}
2455 2457
2456/* 2458/*
2457 * Clone an NFS2/3 server record on xdev traversal (FSID-change) 2459 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
2458 */ 2460 */
2459static struct dentry * 2461static struct dentry *
2460nfs_xdev_mount(struct file_system_type *fs_type, int flags, 2462nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
2461 const char *dev_name, void *raw_data) 2463 const char *dev_name, struct nfs_mount_info *mount_info)
2462{ 2464{
2463 struct nfs_clone_mount *data = raw_data; 2465 struct nfs_clone_mount *data = mount_info->cloned;
2464 struct super_block *s; 2466 struct super_block *s;
2465 struct nfs_server *server; 2467 struct nfs_server *server;
2466 struct dentry *mntroot; 2468 struct dentry *mntroot;
@@ -2470,7 +2472,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2470 }; 2472 };
2471 int error; 2473 int error;
2472 2474
2473 dprintk("--> nfs_xdev_mount()\n"); 2475 dprintk("--> nfs_xdev_mount_common()\n");
2474 2476
2475 /* create a new volume representation */ 2477 /* create a new volume representation */
2476 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); 2478 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
@@ -2505,7 +2507,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2505 2507
2506 if (!s->s_root) { 2508 if (!s->s_root) {
2507 /* initial superblock/root creation */ 2509 /* initial superblock/root creation */
2508 nfs_clone_super(s, data->sb); 2510 mount_info->fill_super(s, mount_info);
2509 nfs_get_cache_cookie(s, NULL, data); 2511 nfs_get_cache_cookie(s, NULL, data);
2510 } 2512 }
2511 2513
@@ -2525,13 +2527,13 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2525 /* clone any lsm security options from the parent to the new sb */ 2527 /* clone any lsm security options from the parent to the new sb */
2526 security_sb_clone_mnt_opts(data->sb, s); 2528 security_sb_clone_mnt_opts(data->sb, s);
2527 2529
2528 dprintk("<-- nfs_xdev_mount() = 0\n"); 2530 dprintk("<-- nfs_xdev_mount_common() = 0\n");
2529 return mntroot; 2531 return mntroot;
2530 2532
2531out_err_nosb: 2533out_err_nosb:
2532 nfs_free_server(server); 2534 nfs_free_server(server);
2533out_err_noserver: 2535out_err_noserver:
2534 dprintk("<-- nfs_xdev_mount() = %d [error]\n", error); 2536 dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error);
2535 return ERR_PTR(error); 2537 return ERR_PTR(error);
2536 2538
2537error_splat_super: 2539error_splat_super:
@@ -2539,18 +2541,33 @@ error_splat_super:
2539 bdi_unregister(&server->backing_dev_info); 2541 bdi_unregister(&server->backing_dev_info);
2540error_splat_bdi: 2542error_splat_bdi:
2541 deactivate_locked_super(s); 2543 deactivate_locked_super(s);
2542 dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error); 2544 dprintk("<-- nfs_xdev_mount_common() = %d [splat]\n", error);
2543 return ERR_PTR(error); 2545 return ERR_PTR(error);
2544} 2546}
2545 2547
2548/*
2549 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
2550 */
2551static struct dentry *
2552nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2553 const char *dev_name, void *raw_data)
2554{
2555 struct nfs_mount_info mount_info = {
2556 .fill_super = nfs_clone_super,
2557 .cloned = raw_data,
2558 };
2559 return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
2560}
2561
2546#ifdef CONFIG_NFS_V4 2562#ifdef CONFIG_NFS_V4
2547 2563
2548/* 2564/*
2549 * Finish setting up a cloned NFS4 superblock 2565 * Finish setting up a cloned NFS4 superblock
2550 */ 2566 */
2551static void nfs4_clone_super(struct super_block *sb, 2567static void nfs4_clone_super(struct super_block *sb,
2552 const struct super_block *old_sb) 2568 struct nfs_mount_info *mount_info)
2553{ 2569{
2570 const struct super_block *old_sb = mount_info->cloned->sb;
2554 sb->s_blocksize_bits = old_sb->s_blocksize_bits; 2571 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
2555 sb->s_blocksize = old_sb->s_blocksize; 2572 sb->s_blocksize = old_sb->s_blocksize;
2556 sb->s_maxbytes = old_sb->s_maxbytes; 2573 sb->s_maxbytes = old_sb->s_maxbytes;
@@ -2930,86 +2947,11 @@ static struct dentry *
2930nfs4_xdev_mount(struct file_system_type *fs_type, int flags, 2947nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
2931 const char *dev_name, void *raw_data) 2948 const char *dev_name, void *raw_data)
2932{ 2949{
2933 struct nfs_clone_mount *data = raw_data; 2950 struct nfs_mount_info mount_info = {
2934 struct super_block *s; 2951 .fill_super = nfs4_clone_super,
2935 struct nfs_server *server; 2952 .cloned = raw_data,
2936 struct dentry *mntroot;
2937 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
2938 struct nfs_sb_mountdata sb_mntdata = {
2939 .mntflags = flags,
2940 }; 2953 };
2941 int error; 2954 return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
2942
2943 dprintk("--> nfs4_xdev_mount()\n");
2944
2945 /* create a new volume representation */
2946 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
2947 if (IS_ERR(server)) {
2948 error = PTR_ERR(server);
2949 goto out_err_noserver;
2950 }
2951 sb_mntdata.server = server;
2952
2953 if (server->flags & NFS_MOUNT_UNSHARED)
2954 compare_super = NULL;
2955
2956 /* -o noac implies -o sync */
2957 if (server->flags & NFS_MOUNT_NOAC)
2958 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2959
2960 /* Get a superblock - note that we may end up sharing one that already exists */
2961 s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
2962 if (IS_ERR(s)) {
2963 error = PTR_ERR(s);
2964 goto out_err_nosb;
2965 }
2966
2967 if (s->s_fs_info != server) {
2968 nfs_free_server(server);
2969 server = NULL;
2970 } else {
2971 error = nfs_bdi_register(server);
2972 if (error)
2973 goto error_splat_bdi;
2974 }
2975
2976 if (!s->s_root) {
2977 /* initial superblock/root creation */
2978 nfs4_clone_super(s, data->sb);
2979 nfs_get_cache_cookie(s, NULL, data);
2980 }
2981
2982 mntroot = nfs_get_root(s, data->fh, dev_name);
2983 if (IS_ERR(mntroot)) {
2984 error = PTR_ERR(mntroot);
2985 goto error_splat_super;
2986 }
2987 if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
2988 dput(mntroot);
2989 error = -ESTALE;
2990 goto error_splat_super;
2991 }
2992
2993 s->s_flags |= MS_ACTIVE;
2994
2995 security_sb_clone_mnt_opts(data->sb, s);
2996
2997 dprintk("<-- nfs4_xdev_mount() = 0\n");
2998 return mntroot;
2999
3000out_err_nosb:
3001 nfs_free_server(server);
3002out_err_noserver:
3003 dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error);
3004 return ERR_PTR(error);
3005
3006error_splat_super:
3007 if (server && !s->s_root)
3008 bdi_unregister(&server->backing_dev_info);
3009error_splat_bdi:
3010 deactivate_locked_super(s);
3011 dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error);
3012 return ERR_PTR(error);
3013} 2955}
3014 2956
3015static struct dentry * 2957static struct dentry *