On Mon, 2012-04-30 at 14:40 -0400, bjschuma@xxxxxxxxxx wrote: > From: Bryan Schumaker <bjschuma@xxxxxxxxxx> > > Signed-off-by: Bryan Schumaker <bjschuma@xxxxxxxxxx> > --- > fs/nfs/super.c | 90 +++++++++----------------------------------------------- > 1 file changed, 14 insertions(+), 76 deletions(-) > > diff --git a/fs/nfs/super.c b/fs/nfs/super.c > index 9ed670b..21b229c 100644 > --- a/fs/nfs/super.c > +++ b/fs/nfs/super.c > @@ -2774,95 +2774,33 @@ static struct dentry * > nfs4_remote_referral_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_mount_info mount_info = { > + .fill_super = nfs4_fill_super, > + .set_security = nfs_clone_sb_security, > + .cloned = raw_data, > + .unshared = NFS4_MOUNT_UNSHARED, This seems to be setting all referral mounts to NFS4_MOUNT_UNSHARED. Why the change in behaviour? > + }; > struct nfs_server *server; > - struct dentry *mntroot; > + struct dentry *mntroot = ERR_PTR(-ENOMEM); > struct nfs_fh *mntfh; > - int (*compare_super)(struct super_block *, void *) = nfs_compare_super; > - struct nfs_sb_mountdata sb_mntdata = { > - .mntflags = flags, > - }; > - int error = -ENOMEM; > > dprintk("--> nfs4_referral_get_sb()\n"); > > mntfh = nfs_alloc_fhandle(); > - if (mntfh == NULL) > - goto out_err_nofh; > + if (mount_info.cloned == NULL || mntfh == NULL) > + goto out; > > /* create a new volume representation */ > - server = nfs4_create_referral_server(data, mntfh); > + server = nfs4_create_referral_server(mount_info.cloned, mntfh); > 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_fill_super(s, NULL); > - nfs_fscache_get_super_cookie(s, NULL, data); > - } > - > - mntroot = nfs_get_root(s, mntfh, 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; > + mntroot = ERR_CAST(server); > + goto out; > } > > - s->s_flags |= MS_ACTIVE; > - > - security_sb_clone_mnt_opts(data->sb, s); > - > + mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, mntfh, &mount_info); > +out: > nfs_free_fhandle(mntfh); > - dprintk("<-- nfs4_referral_get_sb() = 0\n"); > return mntroot; > - > -out_err_nosb: > - nfs_free_server(server); > -out_err_noserver: > - nfs_free_fhandle(mntfh); > -out_err_nofh: > - dprintk("<-- nfs4_referral_get_sb() = %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); > - nfs_free_fhandle(mntfh); > - dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); > - return ERR_PTR(error); > } > > /* -- 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�����٥