diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-05-10 15:07:34 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-14 20:30:27 -0400 |
commit | c40f8d1d35a27d81b4af9d5d2f7286fd978ae9b2 (patch) | |
tree | ec27dc62ab6ce56501db0f02f26387b2518323da /fs | |
parent | 586f95cd4ffda7aa120327ec09865b181c809cdf (diff) |
NFS: Create a common fs_mount() function
The nfs4_remote_mount() function was only slightly different from the
nfs_fs_mount() function used by the generic client. I created a new
nfs_mount_info structure to set different parameters to help combine
these functions.
Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/super.c | 185 |
1 files changed, 76 insertions, 109 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 40d43e05af03..64a62da6612d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -277,6 +277,11 @@ static match_table_t nfs_vers_tokens = { | |||
277 | { Opt_vers_err, NULL } | 277 | { Opt_vers_err, NULL } |
278 | }; | 278 | }; |
279 | 279 | ||
280 | struct nfs_mount_info { | ||
281 | void (*fill_super)(struct super_block *, struct nfs_mount_info *); | ||
282 | struct nfs_parsed_mount_data *parsed; | ||
283 | }; | ||
284 | |||
280 | static void nfs_umount_begin(struct super_block *); | 285 | static void nfs_umount_begin(struct super_block *); |
281 | static int nfs_statfs(struct dentry *, struct kstatfs *); | 286 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
282 | static int nfs_show_options(struct seq_file *, struct dentry *); | 287 | static int nfs_show_options(struct seq_file *, struct dentry *); |
@@ -2129,8 +2134,9 @@ static inline void nfs_initialise_sb(struct super_block *sb) | |||
2129 | * Finish setting up an NFS2/3 superblock | 2134 | * Finish setting up an NFS2/3 superblock |
2130 | */ | 2135 | */ |
2131 | static void nfs_fill_super(struct super_block *sb, | 2136 | static void nfs_fill_super(struct super_block *sb, |
2132 | struct nfs_parsed_mount_data *data) | 2137 | struct nfs_mount_info *mount_info) |
2133 | { | 2138 | { |
2139 | struct nfs_parsed_mount_data *data = mount_info->parsed; | ||
2134 | struct nfs_server *server = NFS_SB(sb); | 2140 | struct nfs_server *server = NFS_SB(sb); |
2135 | 2141 | ||
2136 | sb->s_blocksize_bits = 0; | 2142 | sb->s_blocksize_bits = 0; |
@@ -2304,47 +2310,21 @@ static int nfs_bdi_register(struct nfs_server *server) | |||
2304 | return bdi_register_dev(&server->backing_dev_info, server->s_dev); | 2310 | return bdi_register_dev(&server->backing_dev_info, server->s_dev); |
2305 | } | 2311 | } |
2306 | 2312 | ||
2307 | static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, | 2313 | static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type, |
2308 | int flags, const char *dev_name, void *raw_data) | 2314 | struct nfs_server *server, |
2315 | int flags, const char *dev_name, | ||
2316 | struct nfs_fh *mntfh, | ||
2317 | struct nfs_mount_info *mount_info) | ||
2309 | { | 2318 | { |
2310 | struct nfs_server *server = NULL; | ||
2311 | struct super_block *s; | 2319 | struct super_block *s; |
2312 | struct nfs_parsed_mount_data *data; | ||
2313 | struct nfs_fh *mntfh; | ||
2314 | struct dentry *mntroot = ERR_PTR(-ENOMEM); | 2320 | struct dentry *mntroot = ERR_PTR(-ENOMEM); |
2315 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | 2321 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; |
2316 | struct nfs_sb_mountdata sb_mntdata = { | 2322 | struct nfs_sb_mountdata sb_mntdata = { |
2317 | .mntflags = flags, | 2323 | .mntflags = flags, |
2324 | .server = server, | ||
2318 | }; | 2325 | }; |
2319 | int error; | 2326 | int error; |
2320 | 2327 | ||
2321 | data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); | ||
2322 | mntfh = nfs_alloc_fhandle(); | ||
2323 | if (data == NULL || mntfh == NULL) | ||
2324 | goto out; | ||
2325 | |||
2326 | /* Validate the mount data */ | ||
2327 | error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); | ||
2328 | if (error < 0) { | ||
2329 | mntroot = ERR_PTR(error); | ||
2330 | goto out; | ||
2331 | } | ||
2332 | |||
2333 | #ifdef CONFIG_NFS_V4 | ||
2334 | if (data->version == 4) { | ||
2335 | mntroot = nfs4_try_mount(flags, dev_name, data); | ||
2336 | goto out; | ||
2337 | } | ||
2338 | #endif /* CONFIG_NFS_V4 */ | ||
2339 | |||
2340 | /* Get a volume representation */ | ||
2341 | server = nfs_create_server(data, mntfh); | ||
2342 | if (IS_ERR(server)) { | ||
2343 | mntroot = ERR_CAST(server); | ||
2344 | goto out; | ||
2345 | } | ||
2346 | sb_mntdata.server = server; | ||
2347 | |||
2348 | if (server->flags & NFS_MOUNT_UNSHARED) | 2328 | if (server->flags & NFS_MOUNT_UNSHARED) |
2349 | compare_super = NULL; | 2329 | compare_super = NULL; |
2350 | 2330 | ||
@@ -2372,23 +2352,21 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, | |||
2372 | 2352 | ||
2373 | if (!s->s_root) { | 2353 | if (!s->s_root) { |
2374 | /* initial superblock/root creation */ | 2354 | /* initial superblock/root creation */ |
2375 | nfs_fill_super(s, data); | 2355 | mount_info->fill_super(s, mount_info); |
2376 | nfs_get_cache_cookie(s, data, NULL); | 2356 | nfs_get_cache_cookie(s, mount_info->parsed, NULL); |
2377 | } | 2357 | } |
2378 | 2358 | ||
2379 | mntroot = nfs_get_root(s, mntfh, dev_name); | 2359 | mntroot = nfs_get_root(s, mntfh, dev_name); |
2380 | if (IS_ERR(mntroot)) | 2360 | if (IS_ERR(mntroot)) |
2381 | goto error_splat_super; | 2361 | goto error_splat_super; |
2382 | 2362 | ||
2383 | error = security_sb_set_mnt_opts(s, &data->lsm_opts); | 2363 | error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts); |
2384 | if (error) | 2364 | if (error) |
2385 | goto error_splat_root; | 2365 | goto error_splat_root; |
2386 | 2366 | ||
2387 | s->s_flags |= MS_ACTIVE; | 2367 | s->s_flags |= MS_ACTIVE; |
2388 | 2368 | ||
2389 | out: | 2369 | out: |
2390 | nfs_free_parsed_mount_data(data); | ||
2391 | nfs_free_fhandle(mntfh); | ||
2392 | return mntroot; | 2370 | return mntroot; |
2393 | 2371 | ||
2394 | out_err_nosb: | 2372 | out_err_nosb: |
@@ -2406,6 +2384,52 @@ error_splat_bdi: | |||
2406 | goto out; | 2384 | goto out; |
2407 | } | 2385 | } |
2408 | 2386 | ||
2387 | static struct dentry *nfs_fs_mount(struct file_system_type *fs_type, | ||
2388 | int flags, const char *dev_name, void *raw_data) | ||
2389 | { | ||
2390 | struct nfs_server *server; | ||
2391 | struct nfs_parsed_mount_data *data = NULL; | ||
2392 | struct nfs_mount_info mount_info = { | ||
2393 | .fill_super = nfs_fill_super, | ||
2394 | }; | ||
2395 | struct nfs_fh *mntfh; | ||
2396 | struct dentry *mntroot = ERR_PTR(-ENOMEM); | ||
2397 | int error; | ||
2398 | |||
2399 | data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); | ||
2400 | mntfh = nfs_alloc_fhandle(); | ||
2401 | if (data == NULL || mntfh == NULL) | ||
2402 | goto out; | ||
2403 | |||
2404 | /* Validate the mount data */ | ||
2405 | error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); | ||
2406 | if (error < 0) { | ||
2407 | mntroot = ERR_PTR(error); | ||
2408 | goto out; | ||
2409 | } | ||
2410 | mount_info.parsed = data; | ||
2411 | |||
2412 | #ifdef CONFIG_NFS_V4 | ||
2413 | if (data->version == 4) { | ||
2414 | mntroot = nfs4_try_mount(flags, dev_name, data); | ||
2415 | goto out; | ||
2416 | } | ||
2417 | #endif /* CONFIG_NFS_V4 */ | ||
2418 | |||
2419 | /* Get a volume representation */ | ||
2420 | server = nfs_create_server(data, mntfh); | ||
2421 | if (IS_ERR(server)) { | ||
2422 | mntroot = ERR_CAST(server); | ||
2423 | goto out; | ||
2424 | } | ||
2425 | |||
2426 | mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mntfh, &mount_info); | ||
2427 | out: | ||
2428 | nfs_free_parsed_mount_data(data); | ||
2429 | nfs_free_fhandle(mntfh); | ||
2430 | return mntroot; | ||
2431 | } | ||
2432 | |||
2409 | /* | 2433 | /* |
2410 | * Ensure that we unregister the bdi before kill_anon_super | 2434 | * Ensure that we unregister the bdi before kill_anon_super |
2411 | * releases the device name | 2435 | * releases the device name |
@@ -2544,7 +2568,8 @@ static void nfs4_clone_super(struct super_block *sb, | |||
2544 | /* | 2568 | /* |
2545 | * Set up an NFS4 superblock | 2569 | * Set up an NFS4 superblock |
2546 | */ | 2570 | */ |
2547 | static void nfs4_fill_super(struct super_block *sb) | 2571 | static void nfs4_fill_super(struct super_block *sb, |
2572 | struct nfs_mount_info *mount_info) | ||
2548 | { | 2573 | { |
2549 | sb->s_time_gran = 1; | 2574 | sb->s_time_gran = 1; |
2550 | sb->s_op = &nfs4_sops; | 2575 | sb->s_op = &nfs4_sops; |
@@ -2696,89 +2721,31 @@ static struct dentry * | |||
2696 | nfs4_remote_mount(struct file_system_type *fs_type, int flags, | 2721 | nfs4_remote_mount(struct file_system_type *fs_type, int flags, |
2697 | const char *dev_name, void *raw_data) | 2722 | const char *dev_name, void *raw_data) |
2698 | { | 2723 | { |
2699 | struct nfs_parsed_mount_data *data = raw_data; | 2724 | struct nfs_mount_info mount_info = { |
2700 | struct super_block *s; | 2725 | .fill_super = nfs4_fill_super, |
2726 | .parsed = raw_data, | ||
2727 | }; | ||
2701 | struct nfs_server *server; | 2728 | struct nfs_server *server; |
2702 | struct nfs_fh *mntfh; | 2729 | struct nfs_fh *mntfh; |
2703 | struct dentry *mntroot; | 2730 | struct dentry *mntroot = ERR_PTR(-ENOMEM); |
2704 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
2705 | struct nfs_sb_mountdata sb_mntdata = { | ||
2706 | .mntflags = flags, | ||
2707 | }; | ||
2708 | int error = -ENOMEM; | ||
2709 | 2731 | ||
2710 | mntfh = nfs_alloc_fhandle(); | 2732 | mntfh = nfs_alloc_fhandle(); |
2711 | if (data == NULL || mntfh == NULL) | 2733 | if (mount_info.parsed == NULL || mntfh == NULL) |
2712 | goto out; | 2734 | goto out; |
2713 | 2735 | ||
2714 | /* Get a volume representation */ | 2736 | /* Get a volume representation */ |
2715 | server = nfs4_create_server(data, mntfh); | 2737 | server = nfs4_create_server(mount_info.parsed, mntfh); |
2716 | if (IS_ERR(server)) { | 2738 | if (IS_ERR(server)) { |
2717 | error = PTR_ERR(server); | 2739 | mntroot = ERR_CAST(server); |
2718 | goto out; | 2740 | goto out; |
2719 | } | 2741 | } |
2720 | sb_mntdata.server = server; | ||
2721 | 2742 | ||
2722 | if (server->flags & NFS_MOUNT_UNSHARED) | 2743 | mntroot = nfs_fs_mount_common(fs_type, server, flags, |
2723 | compare_super = NULL; | 2744 | dev_name, mntfh, &mount_info); |
2724 | |||
2725 | /* -o noac implies -o sync */ | ||
2726 | if (server->flags & NFS_MOUNT_NOAC) | ||
2727 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; | ||
2728 | |||
2729 | /* Get a superblock - note that we may end up sharing one that already exists */ | ||
2730 | s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata); | ||
2731 | if (IS_ERR(s)) { | ||
2732 | error = PTR_ERR(s); | ||
2733 | goto out_free; | ||
2734 | } | ||
2735 | |||
2736 | if (s->s_fs_info != server) { | ||
2737 | nfs_free_server(server); | ||
2738 | server = NULL; | ||
2739 | } else { | ||
2740 | error = nfs_bdi_register(server); | ||
2741 | if (error) | ||
2742 | goto error_splat_bdi; | ||
2743 | } | ||
2744 | |||
2745 | if (!s->s_root) { | ||
2746 | /* initial superblock/root creation */ | ||
2747 | nfs4_fill_super(s); | ||
2748 | nfs_get_cache_cookie(s, data, NULL); | ||
2749 | } | ||
2750 | |||
2751 | mntroot = nfs_get_root(s, mntfh, dev_name); | ||
2752 | if (IS_ERR(mntroot)) { | ||
2753 | error = PTR_ERR(mntroot); | ||
2754 | goto error_splat_super; | ||
2755 | } | ||
2756 | |||
2757 | error = security_sb_set_mnt_opts(s, &data->lsm_opts); | ||
2758 | if (error) | ||
2759 | goto error_splat_root; | ||
2760 | |||
2761 | s->s_flags |= MS_ACTIVE; | ||
2762 | |||
2763 | nfs_free_fhandle(mntfh); | ||
2764 | return mntroot; | ||
2765 | 2745 | ||
2766 | out: | 2746 | out: |
2767 | nfs_free_fhandle(mntfh); | 2747 | nfs_free_fhandle(mntfh); |
2768 | return ERR_PTR(error); | 2748 | return mntroot; |
2769 | |||
2770 | out_free: | ||
2771 | nfs_free_server(server); | ||
2772 | goto out; | ||
2773 | |||
2774 | error_splat_root: | ||
2775 | dput(mntroot); | ||
2776 | error_splat_super: | ||
2777 | if (server && !s->s_root) | ||
2778 | bdi_unregister(&server->backing_dev_info); | ||
2779 | error_splat_bdi: | ||
2780 | deactivate_locked_super(s); | ||
2781 | goto out; | ||
2782 | } | 2749 | } |
2783 | 2750 | ||
2784 | static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, | 2751 | static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, |
@@ -3099,7 +3066,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, | |||
3099 | 3066 | ||
3100 | if (!s->s_root) { | 3067 | if (!s->s_root) { |
3101 | /* initial superblock/root creation */ | 3068 | /* initial superblock/root creation */ |
3102 | nfs4_fill_super(s); | 3069 | nfs4_fill_super(s, NULL); |
3103 | nfs_get_cache_cookie(s, NULL, data); | 3070 | nfs_get_cache_cookie(s, NULL, data); |
3104 | } | 3071 | } |
3105 | 3072 | ||