On Mon, 2012-04-30 at 14:40 -0400, bjschuma@xxxxxxxxxx wrote:
> From: Bryan Schumaker <bjschuma@xxxxxxxxxx>
>
> The only difference between nfs_xdev_mount() and nfs4_xdev_mount() is the
> unshared flag, so I pass this as an nfs_mount_info parameter so we can
> share more code.
>
> Signed-off-by: Bryan Schumaker <bjschuma@xxxxxxxxxx>
> ---
> fs/nfs/super.c | 126 ++++++++++++++++----------------------------------------
> 1 file changed, 35 insertions(+), 91 deletions(-)
>
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index b9ee798..eefb3ed 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -2126,6 +2126,7 @@ static inline void nfs_initialise_sb(struct super_block *sb)
> struct nfs_mount_info {
> void (*fill_super)(struct super_block *, struct nfs_mount_info *);
> struct nfs_parsed_mount_data *parsed;
> + struct nfs_clone_mount *cloned;
> unsigned int unshared;
> };
>
> @@ -2159,8 +2160,9 @@ static void nfs_fill_super(struct super_block *sb,
> * Finish setting up a cloned NFS2/3 superblock
> */
> static void nfs_clone_super(struct super_block *sb,
> - const struct super_block *old_sb)
> + struct nfs_mount_info *mount_info)
> {
> + const struct super_block *old_sb = mount_info->cloned->sb;
> struct nfs_server *server = NFS_SB(sb);
>
> sb->s_blocksize_bits = old_sb->s_blocksize_bits;
> @@ -2439,13 +2441,13 @@ static void nfs_kill_super(struct super_block *s)
> }
>
> /*
> - * Clone an NFS2/3 server record on xdev traversal (FSID-change)
> + * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
> */
> static struct dentry *
> -nfs_xdev_mount(struct file_system_type *fs_type, int flags,
> - const char *dev_name, void *raw_data)
> +nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
> + const char *dev_name, struct nfs_mount_info *mount_info)
> {
> - struct nfs_clone_mount *data = raw_data;
> + struct nfs_clone_mount *data = mount_info->cloned;
> struct super_block *s;
> struct nfs_server *server;
> struct dentry *mntroot;
> @@ -2455,7 +2457,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
> };
> int error;
>
> - dprintk("--> nfs_xdev_mount()\n");
> + dprintk("--> nfs_xdev_mount_common()\n");
>
> /* create a new volume representation */
> server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
> @@ -2465,7 +2467,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
> }
> sb_mntdata.server = server;
>
> - if (server->flags & NFS_MOUNT_UNSHARED)
> + if (server->flags & mount_info->unshared)
> compare_super = NULL;
>
> /* -o noac implies -o sync */
> @@ -2490,7 +2492,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
>
> if (!s->s_root) {
> /* initial superblock/root creation */
> - nfs_clone_super(s, data->sb);
> + mount_info->fill_super(s, mount_info);
> nfs_fscache_get_super_cookie(s, NULL, data);
> }
>
> @@ -2510,13 +2512,13 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
> /* clone any lsm security options from the parent to the new sb */
> security_sb_clone_mnt_opts(data->sb, s);
>
> - dprintk("<-- nfs_xdev_mount() = 0\n");
> + dprintk("<-- nfs_xdev_mount_common() = 0\n");
> return mntroot;
>
> out_err_nosb:
> nfs_free_server(server);
> out_err_noserver:
> - dprintk("<-- nfs_xdev_mount() = %d [error]\n", error);
> + dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error);
> return ERR_PTR(error);
>
> error_splat_super:
> @@ -2524,18 +2526,34 @@ error_splat_super:
> bdi_unregister(&server->backing_dev_info);
> error_splat_bdi:
> deactivate_locked_super(s);
> - dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error);
> + dprintk("<-- nfs_xdev_mount_common() = %d [splat]\n", error);
> return ERR_PTR(error);
> }
>
> +/*
> + * Clone an NFS2/3 server record on xdev traversal (FSID-change)
> + */
> +static struct dentry *
> +nfs_xdev_mount(struct file_system_type *fs_type, int flags,
> + const char *dev_name, void *raw_data)
> +{
> + struct nfs_mount_info mount_info = {
> + .fill_super = nfs_clone_super,
> + .cloned = raw_data,
> + .unshared = NFS_MOUNT_UNSHARED,
Why the change in share behaviour?
> + };
> + return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
> +}
> +
> #ifdef CONFIG_NFS_V4
>
> /*
> * Finish setting up a cloned NFS4 superblock
> */
> static void nfs4_clone_super(struct super_block *sb,
> - const struct super_block *old_sb)
> + struct nfs_mount_info *mount_info)
> {
> + const struct super_block *old_sb = mount_info->cloned->sb;
> sb->s_blocksize_bits = old_sb->s_blocksize_bits;
> sb->s_blocksize = old_sb->s_blocksize;
> sb->s_maxbytes = old_sb->s_maxbytes;
> @@ -2787,86 +2805,12 @@ static struct dentry *
> nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
> const char *dev_name, void *raw_data)
> {
> - struct nfs_clone_mount *data = raw_data;
> - struct super_block *s;
> - struct nfs_server *server;
> - struct dentry *mntroot;
> - int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
> - struct nfs_sb_mountdata sb_mntdata = {
> - .mntflags = flags,
> + struct nfs_mount_info mount_info = {
> + .fill_super = nfs4_clone_super,
> + .cloned = raw_data,
> + .unshared = NFS4_MOUNT_UNSHARED,
> };
> - int error;
> -
> - dprintk("--> nfs4_xdev_mount()\n");
> -
> - /* create a new volume representation */
> - server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
> - if (IS_ERR(server)) {
> - error = PTR_ERR(server);
> - goto out_err_noserver;
> - }
> - sb_mntdata.server = server;
> -
> - if (server->flags & NFS4_MOUNT_UNSHARED)
> - compare_super = NULL;
> -
> - /* -o noac implies -o sync */
> - if (server->flags & NFS_MOUNT_NOAC)
> - sb_mntdata.mntflags |= MS_SYNCHRONOUS;
> -
> - /* Get a superblock - note that we may end up sharing one that already exists */
> - s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
> - if (IS_ERR(s)) {
> - error = PTR_ERR(s);
> - goto out_err_nosb;
> - }
> -
> - if (s->s_fs_info != server) {
> - nfs_free_server(server);
> - server = NULL;
> - } else {
> - error = nfs_bdi_register(server);
> - if (error)
> - goto error_splat_bdi;
> - }
> -
> - if (!s->s_root) {
> - /* initial superblock/root creation */
> - nfs4_clone_super(s, data->sb);
> - nfs_fscache_get_super_cookie(s, NULL, data);
> - }
> -
> - mntroot = nfs_get_root(s, data->fh, dev_name);
> - if (IS_ERR(mntroot)) {
> - error = PTR_ERR(mntroot);
> - goto error_splat_super;
> - }
> - if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
> - dput(mntroot);
> - error = -ESTALE;
> - goto error_splat_super;
> - }
> -
> - s->s_flags |= MS_ACTIVE;
> -
> - security_sb_clone_mnt_opts(data->sb, s);
> -
> - dprintk("<-- nfs4_xdev_mount() = 0\n");
> - return mntroot;
> -
> -out_err_nosb:
> - nfs_free_server(server);
> -out_err_noserver:
> - dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error);
> - return ERR_PTR(error);
> -
> -error_splat_super:
> - if (server && !s->s_root)
> - bdi_unregister(&server->backing_dev_info);
> -error_splat_bdi:
> - deactivate_locked_super(s);
> - dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error);
> - return ERR_PTR(error);
> + return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
> }
>
> static struct dentry *
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@xxxxxxxxxx
www.netapp.com
��.n��������+%������w��{.n�����{��w���jg��������ݢj����G�������j:+v���w�m������w�������h�����٥
[Linux USB Development]
[Linux Media Development]
[Video for Linux]
[Linux NILFS]
[Linux Audio Users]
[Photo]
[Yosemite Info]
[Yosemite Photos]
[POF Sucks]
[Linux Kernel]
[Linux SCSI]
[XFree86]