diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-05-10 15:07:35 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-14 20:30:28 -0400 |
commit | 8c958e0c4c52d600bd2ea677eb920fceda8aee49 (patch) | |
tree | 3590ce9504dad5d8dd7eab81429981758de5da8e /fs/nfs/super.c | |
parent | c40f8d1d35a27d81b4af9d5d2f7286fd978ae9b2 (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.c | 122 |
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 = { | |||
280 | struct nfs_mount_info { | 280 | struct 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 | ||
285 | static void nfs_umount_begin(struct super_block *); | 286 | static 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 | */ |
2162 | static void nfs_clone_super(struct super_block *sb, | 2163 | static 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 | */ |
2459 | static struct dentry * | 2461 | static struct dentry * |
2460 | nfs_xdev_mount(struct file_system_type *fs_type, int flags, | 2462 | nfs_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 | ||
2531 | out_err_nosb: | 2533 | out_err_nosb: |
2532 | nfs_free_server(server); | 2534 | nfs_free_server(server); |
2533 | out_err_noserver: | 2535 | out_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 | ||
2537 | error_splat_super: | 2539 | error_splat_super: |
@@ -2539,18 +2541,33 @@ error_splat_super: | |||
2539 | bdi_unregister(&server->backing_dev_info); | 2541 | bdi_unregister(&server->backing_dev_info); |
2540 | error_splat_bdi: | 2542 | error_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 | */ | ||
2551 | static struct dentry * | ||
2552 | nfs_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 | */ |
2551 | static void nfs4_clone_super(struct super_block *sb, | 2567 | static 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 * | |||
2930 | nfs4_xdev_mount(struct file_system_type *fs_type, int flags, | 2947 | nfs4_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 | |||
3000 | out_err_nosb: | ||
3001 | nfs_free_server(server); | ||
3002 | out_err_noserver: | ||
3003 | dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error); | ||
3004 | return ERR_PTR(error); | ||
3005 | |||
3006 | error_splat_super: | ||
3007 | if (server && !s->s_root) | ||
3008 | bdi_unregister(&server->backing_dev_info); | ||
3009 | error_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 | ||
3015 | static struct dentry * | 2957 | static struct dentry * |