2012-05-10 15:20:37

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 00/14] Clean up mount functions

From: Bryan Schumaker <[email protected]>

I noticed that we had 5 almost identical mount functions in super.c. I
collapsed them all into one common function to make everything easier to
maintain and work with. Patches 1 - 4 are cleanups, 5 - 8 drop us down to
one common mount path, and 9 - 14 are cleanups to remove the nfs4_mount()
function.

These patches also help simplify my modules changes since I no longer have
to split these functions out of the generic code.

Changes in v3
-------------
- Remove the NFS4_MOUNT_UNSHARED flag
- nfs_validate_mount_data() selects between the v2/3 function and the v4 function
- Created a generic function for parsing text mount data

Changes in v2
-------------
- Reword commit message on patch 2: Create a single nfs_get_root()
- Change arguments to nfs_fscache_get_super_cookie() in patch 3
- Introduce a new patch 4 to remove the NFS4_MOUNT_UNSHARED flag

Comments or suggestions are appreciated!

- Bryan

Bryan Schumaker (14):
NFS: Rename nfs4_proc_get_root()
NFS: Create a single nfs_get_root()
NFS: Don't pass mount data to nfs_fscache_get_super_cookie()
NFS: Remove NFS4_MOUNT_UNSHARED
NFS: Create a common fs_mount() function
NFS: Create a common xdev_mount() function
NFS: Use nfs_fs_mount_common() for xdev mounts
NFS: Use nfs_fs_mount_common() for remote referral mounts
NFS: Let mount data parsing set the NFS version
NFS: Create a new nfs_try_mount()
NFS: Create a single function for text mount data
NFS: Create a single nfs_validate_mount_data() function
NFS: Allocate parsed mount data directly to the nfs_mount_info
structure
NFS: Pass mntfh as part of the nfs_mount_info structure

fs/nfs/fscache.c | 15 +-
fs/nfs/fscache.h | 4 +-
fs/nfs/getroot.c | 85 +-----
fs/nfs/internal.h | 1 +
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4proc.c | 30 ++-
fs/nfs/super.c | 745 +++++++++++++++++++----------------------------------
7 files changed, 305 insertions(+), 576 deletions(-)

--
1.7.10.1



2012-05-10 15:20:39

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 05/14] NFS: Create a common fs_mount() function

From: Bryan Schumaker <[email protected]>

The nfs4_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 <[email protected]>
---
fs/nfs/super.c | 185 +++++++++++++++++++++++---------------------------------
1 file changed, 76 insertions(+), 109 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 40d43e0..64a62da 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -277,6 +277,11 @@ static match_table_t nfs_vers_tokens = {
{ Opt_vers_err, NULL }
};

+struct nfs_mount_info {
+ void (*fill_super)(struct super_block *, struct nfs_mount_info *);
+ struct nfs_parsed_mount_data *parsed;
+};
+
static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct dentry *, struct kstatfs *);
static int nfs_show_options(struct seq_file *, struct dentry *);
@@ -2129,8 +2134,9 @@ static inline void nfs_initialise_sb(struct super_block *sb)
* Finish setting up an NFS2/3 superblock
*/
static void nfs_fill_super(struct super_block *sb,
- struct nfs_parsed_mount_data *data)
+ struct nfs_mount_info *mount_info)
{
+ struct nfs_parsed_mount_data *data = mount_info->parsed;
struct nfs_server *server = NFS_SB(sb);

sb->s_blocksize_bits = 0;
@@ -2304,47 +2310,21 @@ static int nfs_bdi_register(struct nfs_server *server)
return bdi_register_dev(&server->backing_dev_info, server->s_dev);
}

-static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *raw_data)
+static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
+ struct nfs_server *server,
+ int flags, const char *dev_name,
+ struct nfs_fh *mntfh,
+ struct nfs_mount_info *mount_info)
{
- struct nfs_server *server = NULL;
struct super_block *s;
- struct nfs_parsed_mount_data *data;
- struct nfs_fh *mntfh;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = {
.mntflags = flags,
+ .server = server,
};
int error;

- data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
- mntfh = nfs_alloc_fhandle();
- if (data == NULL || mntfh == NULL)
- goto out;
-
- /* Validate the mount data */
- error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
- if (error < 0) {
- mntroot = ERR_PTR(error);
- goto out;
- }
-
-#ifdef CONFIG_NFS_V4
- if (data->version == 4) {
- mntroot = nfs4_try_mount(flags, dev_name, data);
- goto out;
- }
-#endif /* CONFIG_NFS_V4 */
-
- /* Get a volume representation */
- server = nfs_create_server(data, mntfh);
- if (IS_ERR(server)) {
- mntroot = ERR_CAST(server);
- goto out;
- }
- sb_mntdata.server = server;
-
if (server->flags & NFS_MOUNT_UNSHARED)
compare_super = NULL;

@@ -2372,23 +2352,21 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,

if (!s->s_root) {
/* initial superblock/root creation */
- nfs_fill_super(s, data);
- nfs_get_cache_cookie(s, data, NULL);
+ mount_info->fill_super(s, mount_info);
+ nfs_get_cache_cookie(s, mount_info->parsed, NULL);
}

mntroot = nfs_get_root(s, mntfh, dev_name);
if (IS_ERR(mntroot))
goto error_splat_super;

- error = security_sb_set_mnt_opts(s, &data->lsm_opts);
+ error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
if (error)
goto error_splat_root;

s->s_flags |= MS_ACTIVE;

out:
- nfs_free_parsed_mount_data(data);
- nfs_free_fhandle(mntfh);
return mntroot;

out_err_nosb:
@@ -2406,6 +2384,52 @@ error_splat_bdi:
goto out;
}

+static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *raw_data)
+{
+ struct nfs_server *server;
+ struct nfs_parsed_mount_data *data = NULL;
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs_fill_super,
+ };
+ struct nfs_fh *mntfh;
+ struct dentry *mntroot = ERR_PTR(-ENOMEM);
+ int error;
+
+ data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
+ mntfh = nfs_alloc_fhandle();
+ if (data == NULL || mntfh == NULL)
+ goto out;
+
+ /* Validate the mount data */
+ error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
+ if (error < 0) {
+ mntroot = ERR_PTR(error);
+ goto out;
+ }
+ mount_info.parsed = data;
+
+#ifdef CONFIG_NFS_V4
+ if (data->version == 4) {
+ mntroot = nfs4_try_mount(flags, dev_name, data);
+ goto out;
+ }
+#endif /* CONFIG_NFS_V4 */
+
+ /* Get a volume representation */
+ server = nfs_create_server(data, mntfh);
+ if (IS_ERR(server)) {
+ mntroot = ERR_CAST(server);
+ goto out;
+ }
+
+ mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mntfh, &mount_info);
+out:
+ nfs_free_parsed_mount_data(data);
+ nfs_free_fhandle(mntfh);
+ return mntroot;
+}
+
/*
* Ensure that we unregister the bdi before kill_anon_super
* releases the device name
@@ -2544,7 +2568,8 @@ static void nfs4_clone_super(struct super_block *sb,
/*
* Set up an NFS4 superblock
*/
-static void nfs4_fill_super(struct super_block *sb)
+static void nfs4_fill_super(struct super_block *sb,
+ struct nfs_mount_info *mount_info)
{
sb->s_time_gran = 1;
sb->s_op = &nfs4_sops;
@@ -2696,89 +2721,31 @@ static struct dentry *
nfs4_remote_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
- struct nfs_parsed_mount_data *data = raw_data;
- struct super_block *s;
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs4_fill_super,
+ .parsed = raw_data,
+ };
struct nfs_server *server;
struct nfs_fh *mntfh;
- struct dentry *mntroot;
- int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
- struct nfs_sb_mountdata sb_mntdata = {
- .mntflags = flags,
- };
- int error = -ENOMEM;
+ struct dentry *mntroot = ERR_PTR(-ENOMEM);

mntfh = nfs_alloc_fhandle();
- if (data == NULL || mntfh == NULL)
+ if (mount_info.parsed == NULL || mntfh == NULL)
goto out;

/* Get a volume representation */
- server = nfs4_create_server(data, mntfh);
+ server = nfs4_create_server(mount_info.parsed, mntfh);
if (IS_ERR(server)) {
- error = PTR_ERR(server);
+ mntroot = ERR_CAST(server);
goto out;
}
- sb_mntdata.server = server;

- if (server->flags & NFS_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_free;
- }
-
- 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);
- nfs_get_cache_cookie(s, data, NULL);
- }
-
- mntroot = nfs_get_root(s, mntfh, dev_name);
- if (IS_ERR(mntroot)) {
- error = PTR_ERR(mntroot);
- goto error_splat_super;
- }
-
- error = security_sb_set_mnt_opts(s, &data->lsm_opts);
- if (error)
- goto error_splat_root;
-
- s->s_flags |= MS_ACTIVE;
-
- nfs_free_fhandle(mntfh);
- return mntroot;
+ mntroot = nfs_fs_mount_common(fs_type, server, flags,
+ dev_name, mntfh, &mount_info);

out:
nfs_free_fhandle(mntfh);
- return ERR_PTR(error);
-
-out_free:
- nfs_free_server(server);
- goto out;
-
-error_splat_root:
- dput(mntroot);
-error_splat_super:
- if (server && !s->s_root)
- bdi_unregister(&server->backing_dev_info);
-error_splat_bdi:
- deactivate_locked_super(s);
- goto out;
+ return mntroot;
}

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,

if (!s->s_root) {
/* initial superblock/root creation */
- nfs4_fill_super(s);
+ nfs4_fill_super(s, NULL);
nfs_get_cache_cookie(s, NULL, data);
}

--
1.7.10.1


2012-05-10 15:20:38

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 03/14] NFS: Don't pass mount data to nfs_fscache_get_super_cookie()

From: Bryan Schumaker <[email protected]>

I intend on creating a single nfs_fs_mount() function used by all our
mount paths. To avoid checking between new mounts and clone mounts, I
instead pass both structures to a new function in super.c that finds the
cache key and then looks up the super cookie.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/fscache.c | 15 ++-------------
fs/nfs/fscache.h | 4 +---
fs/nfs/super.c | 31 ++++++++++++++++++++++++++-----
3 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index ae65c16..c817787 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -64,23 +64,12 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp)
* either by the 'fsc=xxx' option to mount, or by inheriting it from the parent
* superblock across an automount point of some nature.
*/
-void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq,
- struct nfs_clone_mount *mntdata)
+void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int ulen)
{
struct nfs_fscache_key *key, *xkey;
struct nfs_server *nfss = NFS_SB(sb);
struct rb_node **p, *parent;
- int diff, ulen;
-
- if (uniq) {
- ulen = strlen(uniq);
- } else if (mntdata) {
- struct nfs_server *mnt_s = NFS_SB(mntdata->sb);
- if (mnt_s->fscache_key) {
- uniq = mnt_s->fscache_key->key.uniquifier;
- ulen = mnt_s->fscache_key->key.uniq_len;
- }
- }
+ int diff;

if (!uniq) {
uniq = "";
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index b9c572d..2a08b91 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -73,9 +73,7 @@ extern void nfs_fscache_unregister(void);
extern void nfs_fscache_get_client_cookie(struct nfs_client *);
extern void nfs_fscache_release_client_cookie(struct nfs_client *);

-extern void nfs_fscache_get_super_cookie(struct super_block *,
- const char *,
- struct nfs_clone_mount *);
+extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
extern void nfs_fscache_release_super_cookie(struct super_block *);

extern void nfs_fscache_init_inode_cookie(struct inode *);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 75b1717..f56fb35 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2278,6 +2278,27 @@ static int nfs_compare_super(struct super_block *sb, void *data)
return nfs_compare_mount_options(sb, server, mntflags);
}

+static void nfs_get_cache_cookie(struct super_block *sb,
+ struct nfs_parsed_mount_data *parsed,
+ struct nfs_clone_mount *cloned)
+{
+ char *uniq = NULL;
+ int ulen = 0;
+
+ if (parsed && parsed->fscache_uniq) {
+ uniq = parsed->fscache_uniq;
+ ulen = strlen(parsed->fscache_uniq);
+ } else if (cloned) {
+ struct nfs_server *mnt_s = NFS_SB(cloned->sb);
+ if (mnt_s->fscache_key) {
+ uniq = mnt_s->fscache_key->key.uniquifier;
+ ulen = mnt_s->fscache_key->key.uniq_len;
+ };
+ }
+
+ nfs_fscache_get_super_cookie(sb, uniq, ulen);
+}
+
static int nfs_bdi_register(struct nfs_server *server)
{
return bdi_register_dev(&server->backing_dev_info, server->s_dev);
@@ -2352,7 +2373,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
nfs_fill_super(s, data);
- nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
+ nfs_get_cache_cookie(s, data, NULL);
}

mntroot = nfs_get_root(s, mntfh, dev_name);
@@ -2461,7 +2482,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);
- nfs_fscache_get_super_cookie(s, NULL, data);
+ nfs_get_cache_cookie(s, NULL, data);
}

mntroot = nfs_get_root(s, data->fh, dev_name);
@@ -2724,7 +2745,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
if (!s->s_root) {
/* initial superblock/root creation */
nfs4_fill_super(s);
- nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
+ nfs_get_cache_cookie(s, data, NULL);
}

mntroot = nfs_get_root(s, mntfh, dev_name);
@@ -2988,7 +3009,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
if (!s->s_root) {
/* initial superblock/root creation */
nfs4_clone_super(s, data->sb);
- nfs_fscache_get_super_cookie(s, NULL, data);
+ nfs_get_cache_cookie(s, NULL, data);
}

mntroot = nfs_get_root(s, data->fh, dev_name);
@@ -3079,7 +3100,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
if (!s->s_root) {
/* initial superblock/root creation */
nfs4_fill_super(s);
- nfs_fscache_get_super_cookie(s, NULL, data);
+ nfs_get_cache_cookie(s, NULL, data);
}

mntroot = nfs_get_root(s, mntfh, dev_name);
--
1.7.10.1


2012-05-10 15:20:38

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 02/14] NFS: Create a single nfs_get_root()

From: Bryan Schumaker <[email protected]>

This patch splits out the NFS v4 specific functionality of
nfs4_get_root() into its own rpc_op called by the generic client, and
leaves nfs4_proc_get_rootfh() as its own stand alone function. This
also allows me to change nfs4_remote_mount(), nfs4_xdev_mount() and
nfs4_remote_referral_mount() to use the generic client's nfs_get_root()
function. Later patches in this series will collapse these functions
into one common function, so using the same get_root() function
everywhere simplifies future changes.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/getroot.c | 83 -----------------------------------------------------
fs/nfs/nfs4proc.c | 28 +++++++++++++++++-
fs/nfs/super.c | 6 ++--
3 files changed, 30 insertions(+), 87 deletions(-)

diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 8a0f33e..8abfb19 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -178,87 +178,4 @@ out:
return ret;
}

-/*
- * get an NFS4 root dentry from the root filehandle
- */
-struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh,
- const char *devname)
-{
- struct nfs_server *server = NFS_SB(sb);
- struct nfs_fattr *fattr = NULL;
- struct dentry *ret;
- struct inode *inode;
- void *name = kstrdup(devname, GFP_KERNEL);
- int error;
-
- dprintk("--> nfs4_get_root()\n");
-
- if (!name)
- return ERR_PTR(-ENOMEM);
-
- /* get the info about the server and filesystem */
- error = nfs4_server_capabilities(server, mntfh);
- if (error < 0) {
- dprintk("nfs_get_root: getcaps error = %d\n",
- -error);
- kfree(name);
- return ERR_PTR(error);
- }
-
- fattr = nfs_alloc_fattr();
- if (fattr == NULL) {
- kfree(name);
- return ERR_PTR(-ENOMEM);
- }
-
- /* get the actual root for this mount */
- error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
- if (error < 0) {
- dprintk("nfs_get_root: getattr error = %d\n", -error);
- ret = ERR_PTR(error);
- goto out;
- }
-
- if (fattr->valid & NFS_ATTR_FATTR_FSID &&
- !nfs_fsid_equal(&server->fsid, &fattr->fsid))
- memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
-
- inode = nfs_fhget(sb, mntfh, fattr);
- if (IS_ERR(inode)) {
- dprintk("nfs_get_root: get root inode failed\n");
- ret = ERR_CAST(inode);
- goto out;
- }
-
- error = nfs_superblock_set_dummy_root(sb, inode);
- if (error != 0) {
- ret = ERR_PTR(error);
- goto out;
- }
-
- /* root dentries normally start off anonymous and get spliced in later
- * if the dentry tree reaches them; however if the dentry already
- * exists, we'll pick it up at this point and use it as the root
- */
- ret = d_obtain_alias(inode);
- if (IS_ERR(ret)) {
- dprintk("nfs_get_root: get root dentry failed\n");
- goto out;
- }
-
- security_d_instantiate(ret, inode);
- spin_lock(&ret->d_lock);
- if (IS_ROOT(ret) && !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
- ret->d_fsdata = name;
- name = NULL;
- }
- spin_unlock(&ret->d_lock);
-out:
- if (name)
- kfree(name);
- nfs_free_fattr(fattr);
- dprintk("<-- nfs4_get_root()\n");
- return ret;
-}
-
#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 69212d2..e6ab15f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -80,6 +80,7 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
+static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *);
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
struct nfs_fattr *fattr, struct iattr *sattr,
@@ -2363,6 +2364,31 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
return nfs4_map_errors(status);
}

+static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
+ struct nfs_fsinfo *info)
+{
+ int error;
+ struct nfs_fattr *fattr = info->fattr;
+
+ error = nfs4_server_capabilities(server, mntfh);
+ if (error < 0) {
+ dprintk("nfs4_get_root: getcaps error = %d\n", -error);
+ return error;
+ }
+
+ error = nfs4_proc_getattr(server, mntfh, fattr);
+ if (error < 0) {
+ dprintk("nfs4_get_root: getattr error = %d\n", -error);
+ return error;
+ }
+
+ if (fattr->valid & NFS_ATTR_FATTR_FSID &&
+ !nfs_fsid_equal(&server->fsid, &fattr->fsid))
+ memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
+
+ return error;
+}
+
/*
* Get locations and (maybe) other attributes of a referral.
* Note that we'll actually follow the referral later when
@@ -6539,7 +6565,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.dir_inode_ops = &nfs4_dir_inode_operations,
.file_inode_ops = &nfs4_file_inode_operations,
.file_ops = &nfs4_file_operations,
- .getroot = nfs4_proc_get_rootfh,
+ .getroot = nfs4_proc_get_root,
.submount = nfs4_submount,
.getattr = nfs4_proc_getattr,
.setattr = nfs4_proc_setattr,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4ac7fca..75b1717 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2727,7 +2727,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
}

- mntroot = nfs4_get_root(s, mntfh, dev_name);
+ mntroot = nfs_get_root(s, mntfh, dev_name);
if (IS_ERR(mntroot)) {
error = PTR_ERR(mntroot);
goto error_splat_super;
@@ -2991,7 +2991,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
nfs_fscache_get_super_cookie(s, NULL, data);
}

- mntroot = nfs4_get_root(s, data->fh, dev_name);
+ mntroot = nfs_get_root(s, data->fh, dev_name);
if (IS_ERR(mntroot)) {
error = PTR_ERR(mntroot);
goto error_splat_super;
@@ -3082,7 +3082,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
nfs_fscache_get_super_cookie(s, NULL, data);
}

- mntroot = nfs4_get_root(s, mntfh, dev_name);
+ mntroot = nfs_get_root(s, mntfh, dev_name);
if (IS_ERR(mntroot)) {
error = PTR_ERR(mntroot);
goto error_splat_super;
--
1.7.10.1


2012-05-10 15:20:41

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 10/14] NFS: Create a new nfs_try_mount()

From: Bryan Schumaker <[email protected]>

This function returns the same same return type as nfs4_try_mount() so
they two can be more easily substituted.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 46 +++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0c4826e..8ebdd5f 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -290,6 +290,9 @@ static int nfs_show_options(struct seq_file *, struct dentry *);
static int nfs_show_devname(struct seq_file *, struct dentry *);
static int nfs_show_path(struct seq_file *, struct dentry *);
static int nfs_show_stats(struct seq_file *, struct dentry *);
+static struct dentry *nfs_fs_mount_common(struct file_system_type *,
+ struct nfs_server *, int, const char *, struct nfs_fh *,
+ struct nfs_mount_info *);
static struct dentry *nfs_fs_mount(struct file_system_type *,
int, const char *, void *);
static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
@@ -1680,8 +1683,8 @@ static int nfs_walk_authlist(struct nfs_parsed_mount_data *args,
* Use the remote server's MOUNT service to request the NFS file handle
* corresponding to the provided path.
*/
-static int nfs_try_mount(struct nfs_parsed_mount_data *args,
- struct nfs_fh *root_fh)
+static int nfs_request_mount(struct nfs_parsed_mount_data *args,
+ struct nfs_fh *root_fh)
{
rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
@@ -1744,6 +1747,25 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
return nfs_walk_authlist(args, &request);
}

+static struct dentry *nfs_try_mount(int flags, const char *dev_name,
+ struct nfs_fh *mntfh,
+ struct nfs_mount_info *mount_info)
+{
+ int status;
+ struct nfs_server *server;
+
+ status = nfs_request_mount(mount_info->parsed, mntfh);
+ if (status)
+ return ERR_PTR(status);
+
+ /* Get a volume representation */
+ server = nfs_create_server(mount_info->parsed, mntfh);
+ if (IS_ERR(server))
+ return ERR_CAST(server);
+
+ return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mntfh, mount_info);
+}
+
/*
* Split "dev_name" into "hostname:export_path".
*
@@ -1966,11 +1988,6 @@ static int nfs_validate_mount_data(void *options,
PAGE_SIZE,
&args->nfs_server.export_path,
NFS_MAXPATHLEN);
- if (!status)
- status = nfs_try_mount(args, mntfh);
-
- kfree(args->nfs_server.export_path);
- args->nfs_server.export_path = NULL;

if (status)
return status;
@@ -2405,7 +2422,6 @@ error_splat_bdi:
static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data)
{
- struct nfs_server *server;
struct nfs_parsed_mount_data *data = NULL;
struct nfs_mount_info mount_info = {
.fill_super = nfs_fill_super,
@@ -2429,20 +2445,12 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
mount_info.parsed = data;

#ifdef CONFIG_NFS_V4
- if (data->version == 4) {
+ if (data->version == 4)
mntroot = nfs4_try_mount(flags, dev_name, data);
- goto out;
- }
+ else
#endif /* CONFIG_NFS_V4 */
+ mntroot = nfs_try_mount(flags, dev_name, mntfh, &mount_info);

- /* Get a volume representation */
- server = nfs_create_server(data, mntfh);
- if (IS_ERR(server)) {
- mntroot = ERR_CAST(server);
- goto out;
- }
-
- mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mntfh, &mount_info);
out:
nfs_free_parsed_mount_data(data);
nfs_free_fhandle(mntfh);
--
1.7.10.1


2012-05-10 18:44:07

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] NFS: Create a common xdev_mount() function

T24gVGh1LCAyMDEyLTA1LTEwIGF0IDExOjE5IC0wNDAwLCBianNjaHVtYUBuZXRhcHAuY29tIHdy
b3RlOg0KPiBGcm9tOiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+DQo+IA0K
PiBUaGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gbmZzX3hkZXZfbW91bnQoKSBhbmQgbmZzNF94
ZGV2X21vdW50KCkgaXMgdGhlDQo+IHVuc2hhcmVkIGZsYWcsIHNvIEkgcGFzcyB0aGlzIGFzIGFu
IG5mc19tb3VudF9pbmZvIHBhcmFtZXRlciBzbyB3ZSBjYW4NCj4gc2hhcmUgbW9yZSBjb2RlLg0K
DQpUaGUgY2hhbmdlbG9nIHNlZW1zIG5vdCB0byByZWxhdGUgdG8gdGhlIGFjdHVhbCBwYXRjaDog
eW91IGFyZSBhZGRpbmcgYQ0Kc3RydWN0IG5mc19jbG9uZV9tb3VudCB0byB0aGUgbmZzX21vdW50
X2luZm8sIG5vdCBhbiB1bnNoYXJlZCBmbGFnLg0KDQo+IFNpZ25lZC1vZmYtYnk6IEJyeWFuIFNj
aHVtYWtlciA8YmpzY2h1bWFAbmV0YXBwLmNvbT4NCj4gLS0tDQo+ICBmcy9uZnMvc3VwZXIuYyB8
ICAxMjIgKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0NCj4gIDEgZmlsZSBjaGFuZ2VkLCAzMiBpbnNlcnRpb25zKCspLCA5MCBkZWxldGlvbnMo
LSkNCj4gDQo+IGRpZmYgLS1naXQgYS9mcy9uZnMvc3VwZXIuYyBiL2ZzL25mcy9zdXBlci5jDQo+
IGluZGV4IDY0YTYyZGEuLjcwN2QxZjYgMTAwNjQ0DQo+IC0tLSBhL2ZzL25mcy9zdXBlci5jDQo+
ICsrKyBiL2ZzL25mcy9zdXBlci5jDQo+IEBAIC0yODAsNiArMjgwLDcgQEAgc3RhdGljIG1hdGNo
X3RhYmxlX3QgbmZzX3ZlcnNfdG9rZW5zID0gew0KPiAgc3RydWN0IG5mc19tb3VudF9pbmZvIHsN
Cj4gIAl2b2lkICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHN0cnVjdCBuZnNf
bW91bnRfaW5mbyAqKTsNCj4gIAlzdHJ1Y3QgbmZzX3BhcnNlZF9tb3VudF9kYXRhICpwYXJzZWQ7
DQo+ICsJc3RydWN0IG5mc19jbG9uZV9tb3VudCAqY2xvbmVkOw0KPiAgfTsNCj4gIA0KPiAgc3Rh
dGljIHZvaWQgbmZzX3Vtb3VudF9iZWdpbihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKik7DQo+IEBAIC0y
MTYwLDggKzIxNjEsOSBAQCBzdGF0aWMgdm9pZCBuZnNfZmlsbF9zdXBlcihzdHJ1Y3Qgc3VwZXJf
YmxvY2sgKnNiLA0KPiAgICogRmluaXNoIHNldHRpbmcgdXAgYSBjbG9uZWQgTkZTMi8zIHN1cGVy
YmxvY2sNCj4gICAqLw0KPiAgc3RhdGljIHZvaWQgbmZzX2Nsb25lX3N1cGVyKHN0cnVjdCBzdXBl
cl9ibG9jayAqc2IsDQo+IC0JCQkgICAgY29uc3Qgc3RydWN0IHN1cGVyX2Jsb2NrICpvbGRfc2Ip
DQo+ICsJCQkgICAgc3RydWN0IG5mc19tb3VudF9pbmZvICptb3VudF9pbmZvKQ0KPiAgew0KPiAr
CWNvbnN0IHN0cnVjdCBzdXBlcl9ibG9jayAqb2xkX3NiID0gbW91bnRfaW5mby0+Y2xvbmVkLT5z
YjsNCj4gIAlzdHJ1Y3QgbmZzX3NlcnZlciAqc2VydmVyID0gTkZTX1NCKHNiKTsNCj4gIA0KPiAg
CXNiLT5zX2Jsb2Nrc2l6ZV9iaXRzID0gb2xkX3NiLT5zX2Jsb2Nrc2l6ZV9iaXRzOw0KPiBAQCAt
MjQ1NCwxMyArMjQ1NiwxMyBAQCBzdGF0aWMgdm9pZCBuZnNfa2lsbF9zdXBlcihzdHJ1Y3Qgc3Vw
ZXJfYmxvY2sgKnMpDQo+ICB9DQo+ICANCj4gIC8qDQo+IC0gKiBDbG9uZSBhbiBORlMyLzMgc2Vy
dmVyIHJlY29yZCBvbiB4ZGV2IHRyYXZlcnNhbCAoRlNJRC1jaGFuZ2UpDQo+ICsgKiBDbG9uZSBh
biBORlMyLzMvNCBzZXJ2ZXIgcmVjb3JkIG9uIHhkZXYgdHJhdmVyc2FsIChGU0lELWNoYW5nZSkN
Cj4gICAqLw0KPiAgc3RhdGljIHN0cnVjdCBkZW50cnkgKg0KPiAtbmZzX3hkZXZfbW91bnQoc3Ry
dWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsIGludCBmbGFncywNCj4gLQkJY29uc3QgY2hh
ciAqZGV2X25hbWUsIHZvaWQgKnJhd19kYXRhKQ0KPiArbmZzX3hkZXZfbW91bnRfY29tbW9uKHN0
cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLCBpbnQgZmxhZ3MsDQo+ICsJCWNvbnN0IGNo
YXIgKmRldl9uYW1lLCBzdHJ1Y3QgbmZzX21vdW50X2luZm8gKm1vdW50X2luZm8pDQo+ICB7DQo+
IC0Jc3RydWN0IG5mc19jbG9uZV9tb3VudCAqZGF0YSA9IHJhd19kYXRhOw0KPiArCXN0cnVjdCBu
ZnNfY2xvbmVfbW91bnQgKmRhdGEgPSBtb3VudF9pbmZvLT5jbG9uZWQ7DQo+ICAJc3RydWN0IHN1
cGVyX2Jsb2NrICpzOw0KPiAgCXN0cnVjdCBuZnNfc2VydmVyICpzZXJ2ZXI7DQo+ICAJc3RydWN0
IGRlbnRyeSAqbW50cm9vdDsNCj4gQEAgLTI0NzAsNyArMjQ3Miw3IEBAIG5mc194ZGV2X21vdW50
KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLCBpbnQgZmxhZ3MsDQo+ICAJfTsNCj4g
IAlpbnQgZXJyb3I7DQo+ICANCj4gLQlkcHJpbnRrKCItLT4gbmZzX3hkZXZfbW91bnQoKVxuIik7
DQo+ICsJZHByaW50aygiLS0+IG5mc194ZGV2X21vdW50X2NvbW1vbigpXG4iKTsNCj4gIA0KPiAg
CS8qIGNyZWF0ZSBhIG5ldyB2b2x1bWUgcmVwcmVzZW50YXRpb24gKi8NCj4gIAlzZXJ2ZXIgPSBu
ZnNfY2xvbmVfc2VydmVyKE5GU19TQihkYXRhLT5zYiksIGRhdGEtPmZoLCBkYXRhLT5mYXR0ciwg
ZGF0YS0+YXV0aGZsYXZvcik7DQo+IEBAIC0yNTA1LDcgKzI1MDcsNyBAQCBuZnNfeGRldl9tb3Vu
dChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwgaW50IGZsYWdzLA0KPiAgDQo+ICAJ
aWYgKCFzLT5zX3Jvb3QpIHsNCj4gIAkJLyogaW5pdGlhbCBzdXBlcmJsb2NrL3Jvb3QgY3JlYXRp
b24gKi8NCj4gLQkJbmZzX2Nsb25lX3N1cGVyKHMsIGRhdGEtPnNiKTsNCj4gKwkJbW91bnRfaW5m
by0+ZmlsbF9zdXBlcihzLCBtb3VudF9pbmZvKTsNCj4gIAkJbmZzX2dldF9jYWNoZV9jb29raWUo
cywgTlVMTCwgZGF0YSk7DQo+ICAJfQ0KPiAgDQo+IEBAIC0yNTI1LDEzICsyNTI3LDEzIEBAIG5m
c194ZGV2X21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLCBpbnQgZmxhZ3Ms
DQo+ICAJLyogY2xvbmUgYW55IGxzbSBzZWN1cml0eSBvcHRpb25zIGZyb20gdGhlIHBhcmVudCB0
byB0aGUgbmV3IHNiICovDQo+ICAJc2VjdXJpdHlfc2JfY2xvbmVfbW50X29wdHMoZGF0YS0+c2Is
IHMpOw0KPiAgDQo+IC0JZHByaW50aygiPC0tIG5mc194ZGV2X21vdW50KCkgPSAwXG4iKTsNCj4g
KwlkcHJpbnRrKCI8LS0gbmZzX3hkZXZfbW91bnRfY29tbW9uKCkgPSAwXG4iKTsNCj4gIAlyZXR1
cm4gbW50cm9vdDsNCj4gIA0KPiAgb3V0X2Vycl9ub3NiOg0KPiAgCW5mc19mcmVlX3NlcnZlcihz
ZXJ2ZXIpOw0KPiAgb3V0X2Vycl9ub3NlcnZlcjoNCj4gLQlkcHJpbnRrKCI8LS0gbmZzX3hkZXZf
bW91bnQoKSA9ICVkIFtlcnJvcl1cbiIsIGVycm9yKTsNCj4gKwlkcHJpbnRrKCI8LS0gbmZzX3hk
ZXZfbW91bnRfY29tbW9uKCkgPSAlZCBbZXJyb3JdXG4iLCBlcnJvcik7DQo+ICAJcmV0dXJuIEVS
Ul9QVFIoZXJyb3IpOw0KPiAgDQo+ICBlcnJvcl9zcGxhdF9zdXBlcjoNCj4gQEAgLTI1MzksMTgg
KzI1NDEsMzMgQEAgZXJyb3Jfc3BsYXRfc3VwZXI6DQo+ICAJCWJkaV91bnJlZ2lzdGVyKCZzZXJ2
ZXItPmJhY2tpbmdfZGV2X2luZm8pOw0KPiAgZXJyb3Jfc3BsYXRfYmRpOg0KPiAgCWRlYWN0aXZh
dGVfbG9ja2VkX3N1cGVyKHMpOw0KPiAtCWRwcmludGsoIjwtLSBuZnNfeGRldl9tb3VudCgpID0g
JWQgW3NwbGF0XVxuIiwgZXJyb3IpOw0KPiArCWRwcmludGsoIjwtLSBuZnNfeGRldl9tb3VudF9j
b21tb24oKSA9ICVkIFtzcGxhdF1cbiIsIGVycm9yKTsNCj4gIAlyZXR1cm4gRVJSX1BUUihlcnJv
cik7DQo+ICB9DQo+ICANCj4gKy8qDQo+ICsgKiBDbG9uZSBhbiBORlMyLzMgc2VydmVyIHJlY29y
ZCBvbiB4ZGV2IHRyYXZlcnNhbCAoRlNJRC1jaGFuZ2UpDQo+ICsgKi8NCj4gK3N0YXRpYyBzdHJ1
Y3QgZGVudHJ5ICoNCj4gK25mc194ZGV2X21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpm
c190eXBlLCBpbnQgZmxhZ3MsDQo+ICsJCWNvbnN0IGNoYXIgKmRldl9uYW1lLCB2b2lkICpyYXdf
ZGF0YSkNCj4gK3sNCj4gKwlzdHJ1Y3QgbmZzX21vdW50X2luZm8gbW91bnRfaW5mbyA9IHsNCj4g
KwkJLmZpbGxfc3VwZXIgPSBuZnNfY2xvbmVfc3VwZXIsDQo+ICsJCS5jbG9uZWQgICA9IHJhd19k
YXRhLA0KPiArCX07DQo+ICsJcmV0dXJuIG5mc194ZGV2X21vdW50X2NvbW1vbigmbmZzX2ZzX3R5
cGUsIGZsYWdzLCBkZXZfbmFtZSwgJm1vdW50X2luZm8pOw0KPiArfQ0KPiArDQo+ICAjaWZkZWYg
Q09ORklHX05GU19WNA0KPiAgDQo+ICAvKg0KPiAgICogRmluaXNoIHNldHRpbmcgdXAgYSBjbG9u
ZWQgTkZTNCBzdXBlcmJsb2NrDQo+ICAgKi8NCj4gIHN0YXRpYyB2b2lkIG5mczRfY2xvbmVfc3Vw
ZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwNCj4gLQkJCSAgICBjb25zdCBzdHJ1Y3Qgc3VwZXJf
YmxvY2sgKm9sZF9zYikNCj4gKwkJCSAgICAgc3RydWN0IG5mc19tb3VudF9pbmZvICptb3VudF9p
bmZvKQ0KPiAgew0KPiArCWNvbnN0IHN0cnVjdCBzdXBlcl9ibG9jayAqb2xkX3NiID0gbW91bnRf
aW5mby0+Y2xvbmVkLT5zYjsNCj4gIAlzYi0+c19ibG9ja3NpemVfYml0cyA9IG9sZF9zYi0+c19i
bG9ja3NpemVfYml0czsNCj4gIAlzYi0+c19ibG9ja3NpemUgPSBvbGRfc2ItPnNfYmxvY2tzaXpl
Ow0KPiAgCXNiLT5zX21heGJ5dGVzID0gb2xkX3NiLT5zX21heGJ5dGVzOw0KPiBAQCAtMjkzMCw4
NiArMjk0NywxMSBAQCBzdGF0aWMgc3RydWN0IGRlbnRyeSAqDQo+ICBuZnM0X3hkZXZfbW91bnQo
c3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsIGludCBmbGFncywNCj4gIAkJIGNvbnN0
IGNoYXIgKmRldl9uYW1lLCB2b2lkICpyYXdfZGF0YSkNCj4gIHsNCj4gLQlzdHJ1Y3QgbmZzX2Ns
b25lX21vdW50ICpkYXRhID0gcmF3X2RhdGE7DQo+IC0Jc3RydWN0IHN1cGVyX2Jsb2NrICpzOw0K
PiAtCXN0cnVjdCBuZnNfc2VydmVyICpzZXJ2ZXI7DQo+IC0Jc3RydWN0IGRlbnRyeSAqbW50cm9v
dDsNCj4gLQlpbnQgKCpjb21wYXJlX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAq
KSA9IG5mc19jb21wYXJlX3N1cGVyOw0KPiAtCXN0cnVjdCBuZnNfc2JfbW91bnRkYXRhIHNiX21u
dGRhdGEgPSB7DQo+IC0JCS5tbnRmbGFncyA9IGZsYWdzLA0KPiArCXN0cnVjdCBuZnNfbW91bnRf
aW5mbyBtb3VudF9pbmZvID0gew0KPiArCQkuZmlsbF9zdXBlciA9IG5mczRfY2xvbmVfc3VwZXIs
DQo+ICsJCS5jbG9uZWQgPSByYXdfZGF0YSwNCj4gIAl9Ow0KPiAtCWludCBlcnJvcjsNCj4gLQ0K
PiAtCWRwcmludGsoIi0tPiBuZnM0X3hkZXZfbW91bnQoKVxuIik7DQo+IC0NCj4gLQkvKiBjcmVh
dGUgYSBuZXcgdm9sdW1lIHJlcHJlc2VudGF0aW9uICovDQo+IC0Jc2VydmVyID0gbmZzX2Nsb25l
X3NlcnZlcihORlNfU0IoZGF0YS0+c2IpLCBkYXRhLT5maCwgZGF0YS0+ZmF0dHIsIGRhdGEtPmF1
dGhmbGF2b3IpOw0KPiAtCWlmIChJU19FUlIoc2VydmVyKSkgew0KPiAtCQllcnJvciA9IFBUUl9F
UlIoc2VydmVyKTsNCj4gLQkJZ290byBvdXRfZXJyX25vc2VydmVyOw0KPiAtCX0NCj4gLQlzYl9t
bnRkYXRhLnNlcnZlciA9IHNlcnZlcjsNCj4gLQ0KPiAtCWlmIChzZXJ2ZXItPmZsYWdzICYgTkZT
X01PVU5UX1VOU0hBUkVEKQ0KPiAtCQljb21wYXJlX3N1cGVyID0gTlVMTDsNCj4gLQ0KPiAtCS8q
IC1vIG5vYWMgaW1wbGllcyAtbyBzeW5jICovDQo+IC0JaWYgKHNlcnZlci0+ZmxhZ3MgJiBORlNf
TU9VTlRfTk9BQykNCj4gLQkJc2JfbW50ZGF0YS5tbnRmbGFncyB8PSBNU19TWU5DSFJPTk9VUzsN
Cj4gLQ0KPiAtCS8qIEdldCBhIHN1cGVyYmxvY2sgLSBub3RlIHRoYXQgd2UgbWF5IGVuZCB1cCBz
aGFyaW5nIG9uZSB0aGF0IGFscmVhZHkgZXhpc3RzICovDQo+IC0JcyA9IHNnZXQoJm5mczRfZnNf
dHlwZSwgY29tcGFyZV9zdXBlciwgbmZzX3NldF9zdXBlciwgJnNiX21udGRhdGEpOw0KPiAtCWlm
IChJU19FUlIocykpIHsNCj4gLQkJZXJyb3IgPSBQVFJfRVJSKHMpOw0KPiAtCQlnb3RvIG91dF9l
cnJfbm9zYjsNCj4gLQl9DQo+IC0NCj4gLQlpZiAocy0+c19mc19pbmZvICE9IHNlcnZlcikgew0K
PiAtCQluZnNfZnJlZV9zZXJ2ZXIoc2VydmVyKTsNCj4gLQkJc2VydmVyID0gTlVMTDsNCj4gLQl9
IGVsc2Ugew0KPiAtCQllcnJvciA9IG5mc19iZGlfcmVnaXN0ZXIoc2VydmVyKTsNCj4gLQkJaWYg
KGVycm9yKQ0KPiAtCQkJZ290byBlcnJvcl9zcGxhdF9iZGk7DQo+IC0JfQ0KPiAtDQo+IC0JaWYg
KCFzLT5zX3Jvb3QpIHsNCj4gLQkJLyogaW5pdGlhbCBzdXBlcmJsb2NrL3Jvb3QgY3JlYXRpb24g
Ki8NCj4gLQkJbmZzNF9jbG9uZV9zdXBlcihzLCBkYXRhLT5zYik7DQo+IC0JCW5mc19nZXRfY2Fj
aGVfY29va2llKHMsIE5VTEwsIGRhdGEpOw0KPiAtCX0NCj4gLQ0KPiAtCW1udHJvb3QgPSBuZnNf
Z2V0X3Jvb3QocywgZGF0YS0+ZmgsIGRldl9uYW1lKTsNCj4gLQlpZiAoSVNfRVJSKG1udHJvb3Qp
KSB7DQo+IC0JCWVycm9yID0gUFRSX0VSUihtbnRyb290KTsNCj4gLQkJZ290byBlcnJvcl9zcGxh
dF9zdXBlcjsNCj4gLQl9DQo+IC0JaWYgKG1udHJvb3QtPmRfaW5vZGUtPmlfb3AgIT0gTkZTX1NC
KHMpLT5uZnNfY2xpZW50LT5ycGNfb3BzLT5kaXJfaW5vZGVfb3BzKSB7DQo+IC0JCWRwdXQobW50
cm9vdCk7DQo+IC0JCWVycm9yID0gLUVTVEFMRTsNCj4gLQkJZ290byBlcnJvcl9zcGxhdF9zdXBl
cjsNCj4gLQl9DQo+IC0NCj4gLQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsNCj4gLQ0KPiAtCXNl
Y3VyaXR5X3NiX2Nsb25lX21udF9vcHRzKGRhdGEtPnNiLCBzKTsNCj4gLQ0KPiAtCWRwcmludGso
IjwtLSBuZnM0X3hkZXZfbW91bnQoKSA9IDBcbiIpOw0KPiAtCXJldHVybiBtbnRyb290Ow0KPiAt
DQo+IC1vdXRfZXJyX25vc2I6DQo+IC0JbmZzX2ZyZWVfc2VydmVyKHNlcnZlcik7DQo+IC1vdXRf
ZXJyX25vc2VydmVyOg0KPiAtCWRwcmludGsoIjwtLSBuZnM0X3hkZXZfbW91bnQoKSA9ICVkIFtl
cnJvcl1cbiIsIGVycm9yKTsNCj4gLQlyZXR1cm4gRVJSX1BUUihlcnJvcik7DQo+IC0NCj4gLWVy
cm9yX3NwbGF0X3N1cGVyOg0KPiAtCWlmIChzZXJ2ZXIgJiYgIXMtPnNfcm9vdCkNCj4gLQkJYmRp
X3VucmVnaXN0ZXIoJnNlcnZlci0+YmFja2luZ19kZXZfaW5mbyk7DQo+IC1lcnJvcl9zcGxhdF9i
ZGk6DQo+IC0JZGVhY3RpdmF0ZV9sb2NrZWRfc3VwZXIocyk7DQo+IC0JZHByaW50aygiPC0tIG5m
czRfeGRldl9tb3VudCgpID0gJWQgW3NwbGF0XVxuIiwgZXJyb3IpOw0KPiAtCXJldHVybiBFUlJf
UFRSKGVycm9yKTsNCj4gKwlyZXR1cm4gbmZzX3hkZXZfbW91bnRfY29tbW9uKCZuZnM0X2ZzX3R5
cGUsIGZsYWdzLCBkZXZfbmFtZSwgJm1vdW50X2luZm8pOw0KPiAgfQ0KPiAgDQo+ICBzdGF0aWMg
c3RydWN0IGRlbnRyeSAqDQoNCi0tIA0KVHJvbmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50
IG1haW50YWluZXINCg0KTmV0QXBwDQpUcm9uZC5NeWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5l
dGFwcC5jb20NCg0K

2012-05-10 15:20:39

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 07/14] NFS: Use nfs_fs_mount_common() for xdev mounts

From: Bryan Schumaker <[email protected]>

At this point, there are only a few small differences between these two
functions. I can set a few function pointers in the nfs_mount_info
struct to get around these differences.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 97 ++++++++++++++++----------------------------------------
1 file changed, 27 insertions(+), 70 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 707d1f6..a3bc530 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -279,6 +279,7 @@ static match_table_t nfs_vers_tokens = {

struct nfs_mount_info {
void (*fill_super)(struct super_block *, struct nfs_mount_info *);
+ int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
struct nfs_parsed_mount_data *parsed;
struct nfs_clone_mount *cloned;
};
@@ -2312,6 +2313,22 @@ static int nfs_bdi_register(struct nfs_server *server)
return bdi_register_dev(&server->backing_dev_info, server->s_dev);
}

+static int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
+ struct nfs_mount_info *mount_info)
+{
+ return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
+}
+
+static int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
+ struct nfs_mount_info *mount_info)
+{
+ /* clone any lsm security options from the parent to the new sb */
+ security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
+ if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
+ return -ESTALE;
+ return 0;
+}
+
static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
struct nfs_server *server,
int flags, const char *dev_name,
@@ -2355,14 +2372,14 @@ static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
mount_info->fill_super(s, mount_info);
- nfs_get_cache_cookie(s, mount_info->parsed, NULL);
+ nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned);
}

mntroot = nfs_get_root(s, mntfh, dev_name);
if (IS_ERR(mntroot))
goto error_splat_super;

- error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
+ error = mount_info->set_security(s, mntroot, mount_info);
if (error)
goto error_splat_root;

@@ -2393,6 +2410,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
struct nfs_parsed_mount_data *data = NULL;
struct nfs_mount_info mount_info = {
.fill_super = nfs_fill_super,
+ .set_security = nfs_set_sb_security,
};
struct nfs_fh *mntfh;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
@@ -2463,13 +2481,8 @@ 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 = mount_info->cloned;
- 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 dentry *mntroot = ERR_PTR(-ENOMEM);
int error;

dprintk("--> nfs_xdev_mount_common()\n");
@@ -2478,71 +2491,12 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
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 & NFS_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(&nfs_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 */
- mount_info->fill_super(s, mount_info);
- nfs_get_cache_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;
+ goto out;
}

- s->s_flags |= MS_ACTIVE;
-
- /* clone any lsm security options from the parent to the new sb */
- security_sb_clone_mnt_opts(data->sb, s);
-
- dprintk("<-- nfs_xdev_mount_common() = 0\n");
+ mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, data->fh, mount_info);
+out:
return mntroot;
-
-out_err_nosb:
- nfs_free_server(server);
-out_err_noserver:
- dprintk("<-- nfs_xdev_mount_common() = %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("<-- nfs_xdev_mount_common() = %d [splat]\n", error);
- return ERR_PTR(error);
}

/*
@@ -2554,6 +2508,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
{
struct nfs_mount_info mount_info = {
.fill_super = nfs_clone_super,
+ .set_security = nfs_clone_sb_security,
.cloned = raw_data,
};
return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
@@ -2740,6 +2695,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
{
struct nfs_mount_info mount_info = {
.fill_super = nfs4_fill_super,
+ .set_security = nfs_set_sb_security,
.parsed = raw_data,
};
struct nfs_server *server;
@@ -2949,6 +2905,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
{
struct nfs_mount_info mount_info = {
.fill_super = nfs4_clone_super,
+ .set_security = nfs_clone_sb_security,
.cloned = raw_data,
};
return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
--
1.7.10.1


2012-05-10 15:20:41

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 12/14] NFS: Create a single nfs_validate_mount_data() function

From: Bryan Schumaker <[email protected]>

This new function chooses between the v2/3 parser and the v4 parser by
filesystem type.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2746d11..466b299 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -335,6 +335,8 @@ static const struct super_operations nfs_sops = {

#ifdef CONFIG_NFS_V4
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
+static int nfs4_validate_mount_data(void *options,
+ struct nfs_parsed_mount_data *args, const char *dev_name);
static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
struct nfs_parsed_mount_data *data);
static struct dentry *nfs4_mount(struct file_system_type *fs_type,
@@ -1857,10 +1859,10 @@ out_path:
* + breaking back: trying proto=udp after proto=tcp, v2 after v3,
* mountproto=tcp after mountproto=udp, and so on
*/
-static int nfs_validate_mount_data(void *options,
- struct nfs_parsed_mount_data *args,
- struct nfs_fh *mntfh,
- const char *dev_name)
+static int nfs23_validate_mount_data(void *options,
+ struct nfs_parsed_mount_data *args,
+ struct nfs_fh *mntfh,
+ const char *dev_name)
{
struct nfs_mount_data *data = (struct nfs_mount_data *)options;
struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
@@ -2009,6 +2011,28 @@ out_invalid_fh:
return -EINVAL;
}

+#ifdef CONFIG_NFS_V4
+static int nfs_validate_mount_data(struct file_system_type *fs_type,
+ void *options,
+ struct nfs_parsed_mount_data *args,
+ struct nfs_fh *mntfh,
+ const char *dev_name)
+{
+ if (fs_type == &nfs_fs_type)
+ return nfs23_validate_mount_data(options, args, mntfh, dev_name);
+ return nfs4_validate_mount_data(options, args, dev_name);
+}
+#else
+static int nfs_validate_mount_data(struct file_system_type *fs_type,
+ void *options,
+ struct nfs_parsed_mount_data *args,
+ struct nfs_fh *mntfh,
+ const char *dev_name)
+{
+ return nfs23_validate_mount_data(options, args, mntfh, dev_name);
+}
+#endif
+
static int nfs_validate_text_mount_data(void *options,
struct nfs_parsed_mount_data *args,
const char *dev_name)
@@ -2459,7 +2483,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
goto out;

/* Validate the mount data */
- error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
+ error = nfs_validate_mount_data(fs_type, raw_data, data, mntfh, dev_name);
if (error == NFS_TEXT_DATA)
error = nfs_validate_text_mount_data(raw_data, data, dev_name);
if (error < 0) {
@@ -2861,7 +2885,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
goto out;

/* Validate the mount data */
- error = nfs4_validate_mount_data(raw_data, data, dev_name);
+ error = nfs_validate_mount_data(fs_type, raw_data, data, NULL, dev_name);
if (error == NFS_TEXT_DATA)
error = nfs_validate_text_mount_data(raw_data, data, dev_name);
if (error < 0) {
--
1.7.10.1


2012-05-10 15:20:40

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 09/14] NFS: Let mount data parsing set the NFS version

From: Bryan Schumaker <[email protected]>

This field is unconditionally set while parsing mount data, so there is
no need to fill it in here.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 92bc0a5..0c4826e 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -945,7 +945,7 @@ static void nfs_umount_begin(struct super_block *sb)
rpc_killall_tasks(rpc);
}

-static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
+static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
{
struct nfs_parsed_mount_data *data;

@@ -960,7 +960,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
data->auth_flavors[0] = RPC_AUTH_UNIX;
data->auth_flavor_len = 1;
- data->version = version;
data->minorversion = 0;
data->net = current->nsproxy->net_ns;
security_init_mnt_opts(&data->lsm_opts);
@@ -2416,7 +2415,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
struct dentry *mntroot = ERR_PTR(-ENOMEM);
int error;

- data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
+ data = nfs_alloc_parsed_mount_data();
mntfh = nfs_alloc_fhandle();
if (data == NULL || mntfh == NULL)
goto out;
@@ -2862,7 +2861,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
int error = -ENOMEM;
struct dentry *res = ERR_PTR(-ENOMEM);

- data = nfs_alloc_parsed_mount_data(4);
+ data = nfs_alloc_parsed_mount_data();
if (data == NULL)
goto out;

--
1.7.10.1


2012-05-10 15:20:41

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 11/14] NFS: Create a single function for text mount data

From: Bryan Schumaker <[email protected]>

The v2/3 and v4 cases were very similar, with just a few parameters
changed. This makes it easy to share code.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 1 +
fs/nfs/super.c | 151 +++++++++++++++++++++++++----------------------------
2 files changed, 71 insertions(+), 81 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 4cf76e9..bf64095 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -103,6 +103,7 @@ struct nfs_parsed_mount_data {
unsigned int version;
unsigned int minorversion;
char *fscache_uniq;
+ bool need_mount;

struct {
struct sockaddr_storage address;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 8ebdd5f..2746d11 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -66,6 +66,7 @@
#include "pnfs.h"

#define NFSDBG_FACILITY NFSDBG_VFS
+#define NFS_TEXT_DATA 1

#ifdef CONFIG_NFS_V3
#define NFS_DEFAULT_VERSION 3
@@ -333,8 +334,7 @@ static const struct super_operations nfs_sops = {
};

#ifdef CONFIG_NFS_V4
-static int nfs4_validate_text_mount_data(void *options,
- struct nfs_parsed_mount_data *args, const char *dev_name);
+static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
struct nfs_parsed_mount_data *data);
static struct dentry *nfs4_mount(struct file_system_type *fs_type,
@@ -964,6 +964,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
data->auth_flavors[0] = RPC_AUTH_UNIX;
data->auth_flavor_len = 1;
data->minorversion = 0;
+ data->need_mount = true;
data->net = current->nsproxy->net_ns;
security_init_mnt_opts(&data->lsm_opts);
}
@@ -1754,9 +1755,11 @@ static struct dentry *nfs_try_mount(int flags, const char *dev_name,
int status;
struct nfs_server *server;

- status = nfs_request_mount(mount_info->parsed, mntfh);
- if (status)
- return ERR_PTR(status);
+ if (mount_info->parsed->need_mount) {
+ status = nfs_request_mount(mount_info->parsed, mntfh);
+ if (status)
+ return ERR_PTR(status);
+ }

/* Get a volume representation */
server = nfs_create_server(mount_info->parsed, mntfh);
@@ -1911,6 +1914,7 @@ static int nfs_validate_mount_data(void *options,
args->acregmax = data->acregmax;
args->acdirmin = data->acdirmin;
args->acdirmax = data->acdirmax;
+ args->need_mount = false;

memcpy(sap, &data->addr, sizeof(data->addr));
args->nfs_server.addrlen = sizeof(data->addr);
@@ -1962,38 +1966,8 @@ static int nfs_validate_mount_data(void *options,
}

break;
- default: {
- int status;
-
- if (nfs_parse_mount_options((char *)options, args) == 0)
- return -EINVAL;
-
- if (!nfs_verify_server_address(sap))
- goto out_no_address;
-
- if (args->version == 4)
-#ifdef CONFIG_NFS_V4
- return nfs4_validate_text_mount_data(options,
- args, dev_name);
-#else
- goto out_v4_not_compiled;
-#endif
-
- nfs_set_port(sap, &args->nfs_server.port, 0);
-
- nfs_set_mount_transport_protocol(args);
-
- status = nfs_parse_devname(dev_name,
- &args->nfs_server.hostname,
- PAGE_SIZE,
- &args->nfs_server.export_path,
- NFS_MAXPATHLEN);
-
- if (status)
- return status;
-
- break;
- }
+ default:
+ return NFS_TEXT_DATA;
}

#ifndef CONFIG_NFS_V3
@@ -2022,12 +1996,6 @@ out_v3_not_compiled:
return -EPROTONOSUPPORT;
#endif /* !CONFIG_NFS_V3 */

-#ifndef CONFIG_NFS_V4
-out_v4_not_compiled:
- dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
- return -EPROTONOSUPPORT;
-#endif /* !CONFIG_NFS_V4 */
-
out_nomem:
dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
return -ENOMEM;
@@ -2041,6 +2009,60 @@ out_invalid_fh:
return -EINVAL;
}

+static int nfs_validate_text_mount_data(void *options,
+ struct nfs_parsed_mount_data *args,
+ const char *dev_name)
+{
+ int port = 0;
+ int max_namelen = PAGE_SIZE;
+ int max_pathlen = NFS_MAXPATHLEN;
+ struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
+
+ if (nfs_parse_mount_options((char *)options, args) == 0)
+ return -EINVAL;
+
+ if (!nfs_verify_server_address(sap))
+ goto out_no_address;
+
+ if (args->version == 4) {
+#ifdef CONFIG_NFS_V4
+ port = NFS_PORT;
+ max_namelen = NFS4_MAXNAMLEN;
+ max_pathlen = NFS4_MAXPATHLEN;
+ nfs_validate_transport_protocol(args);
+ nfs4_validate_mount_flags(args);
+#else
+ goto out_v4_not_compiled;
+#endif /* CONFIG_NFS_V4 */
+ } else
+ nfs_set_mount_transport_protocol(args);
+
+ nfs_set_port(sap, &args->nfs_server.port, port);
+
+ if (args->auth_flavor_len > 1)
+ goto out_bad_auth;
+
+ return nfs_parse_devname(dev_name,
+ &args->nfs_server.hostname,
+ max_namelen,
+ &args->nfs_server.export_path,
+ max_pathlen);
+
+#ifndef CONFIG_NFS_V4
+out_v4_not_compiled:
+ dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
+ return -EPROTONOSUPPORT;
+#endif /* !CONFIG_NFS_V4 */
+
+out_no_address:
+ dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
+ return -EINVAL;
+
+out_bad_auth:
+ dfprintk(MOUNT, "NFS: Too many RPC auth flavours specified\n");
+ return -EINVAL;
+}
+
static int
nfs_compare_remount_data(struct nfs_server *nfss,
struct nfs_parsed_mount_data *data)
@@ -2438,6 +2460,8 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,

/* Validate the mount data */
error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
+ if (error == NFS_TEXT_DATA)
+ error = nfs_validate_text_mount_data(raw_data, data, dev_name);
if (error < 0) {
mntroot = ERR_PTR(error);
goto out;
@@ -2567,37 +2591,6 @@ static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL);
}

-static int nfs4_validate_text_mount_data(void *options,
- struct nfs_parsed_mount_data *args,
- const char *dev_name)
-{
- struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
-
- nfs_set_port(sap, &args->nfs_server.port, NFS_PORT);
-
- nfs_validate_transport_protocol(args);
-
- nfs4_validate_mount_flags(args);
-
- if (args->version != 4) {
- dfprintk(MOUNT,
- "NFS4: Illegal mount version\n");
- return -EINVAL;
- }
-
- if (args->auth_flavor_len > 1) {
- dfprintk(MOUNT,
- "NFS4: Too many RPC auth flavours specified\n");
- return -EINVAL;
- }
-
- return nfs_parse_devname(dev_name,
- &args->nfs_server.hostname,
- NFS4_MAXNAMLEN,
- &args->nfs_server.export_path,
- NFS4_MAXPATHLEN);
-}
-
/*
* Validate NFSv4 mount options
*/
@@ -2668,13 +2661,7 @@ static int nfs4_validate_mount_data(void *options,

break;
default:
- if (nfs_parse_mount_options((char *)options, args) == 0)
- return -EINVAL;
-
- if (!nfs_verify_server_address(sap))
- return -EINVAL;
-
- return nfs4_validate_text_mount_data(options, args, dev_name);
+ return NFS_TEXT_DATA;
}

return 0;
@@ -2875,6 +2862,8 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,

/* Validate the mount data */
error = nfs4_validate_mount_data(raw_data, data, dev_name);
+ if (error == NFS_TEXT_DATA)
+ error = nfs_validate_text_mount_data(raw_data, data, dev_name);
if (error < 0) {
res = ERR_PTR(error);
goto out;
--
1.7.10.1


2012-05-10 15:20:41

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 13/14] NFS: Allocate parsed mount data directly to the nfs_mount_info structure

From: Bryan Schumaker <[email protected]>

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 466b299..61b47da 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2468,7 +2468,6 @@ error_splat_bdi:
static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data)
{
- struct nfs_parsed_mount_data *data = NULL;
struct nfs_mount_info mount_info = {
.fill_super = nfs_fill_super,
.set_security = nfs_set_sb_security,
@@ -2477,30 +2476,29 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
struct dentry *mntroot = ERR_PTR(-ENOMEM);
int error;

- data = nfs_alloc_parsed_mount_data();
+ mount_info.parsed = nfs_alloc_parsed_mount_data();
mntfh = nfs_alloc_fhandle();
- if (data == NULL || mntfh == NULL)
+ if (mount_info.parsed == NULL || mntfh == NULL)
goto out;

/* Validate the mount data */
- error = nfs_validate_mount_data(fs_type, raw_data, data, mntfh, dev_name);
+ error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mntfh, dev_name);
if (error == NFS_TEXT_DATA)
- error = nfs_validate_text_mount_data(raw_data, data, dev_name);
+ error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name);
if (error < 0) {
mntroot = ERR_PTR(error);
goto out;
}
- mount_info.parsed = data;

#ifdef CONFIG_NFS_V4
- if (data->version == 4)
- mntroot = nfs4_try_mount(flags, dev_name, data);
+ if (mount_info.parsed->version == 4)
+ mntroot = nfs4_try_mount(flags, dev_name, mount_info.parsed);
else
#endif /* CONFIG_NFS_V4 */
mntroot = nfs_try_mount(flags, dev_name, mntfh, &mount_info);

out:
- nfs_free_parsed_mount_data(data);
+ nfs_free_parsed_mount_data(mount_info.parsed);
nfs_free_fhandle(mntfh);
return mntroot;
}
--
1.7.10.1


2012-05-10 15:20:38

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 04/14] NFS: Remove NFS4_MOUNT_UNSHARED

From: Bryan Schumaker <[email protected]>

This flag is numerically equivalent to NFS_MOUNT_UNSHARED, so I can
remove it to make collapsing functions more straightforward.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f56fb35..40d43e0 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2719,7 +2719,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
}
sb_mntdata.server = server;

- if (server->flags & NFS4_MOUNT_UNSHARED)
+ if (server->flags & NFS_MOUNT_UNSHARED)
compare_super = NULL;

/* -o noac implies -o sync */
@@ -2983,7 +2983,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
}
sb_mntdata.server = server;

- if (server->flags & NFS4_MOUNT_UNSHARED)
+ if (server->flags & NFS_MOUNT_UNSHARED)
compare_super = NULL;

/* -o noac implies -o sync */
@@ -3074,7 +3074,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
}
sb_mntdata.server = server;

- if (server->flags & NFS4_MOUNT_UNSHARED)
+ if (server->flags & NFS_MOUNT_UNSHARED)
compare_super = NULL;

/* -o noac implies -o sync */
--
1.7.10.1


2012-05-10 15:20:40

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 08/14] NFS: Use nfs_fs_mount_common() for remote referral mounts

From: Bryan Schumaker <[email protected]>

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 89 +++++++++-----------------------------------------------
1 file changed, 13 insertions(+), 76 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a3bc530..92bc0a5 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2915,95 +2915,32 @@ 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,
+ };
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 & NFS_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_get_cache_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);
}

/*
--
1.7.10.1


2012-05-10 15:20:42

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 14/14] NFS: Pass mntfh as part of the nfs_mount_info structure

From: Bryan Schumaker <[email protected]>

This allows me to use the filehandle allocated in nfs_fs_mount() for nfs
v4 mounts instead of allocating a new one. Rather than change
nfs4_mount() to look almost exactly like nfs_fs_mount(), I instead
remove the function.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 107 ++++++++++++++++----------------------------------------
1 file changed, 31 insertions(+), 76 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 61b47da..fa48c32 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -283,6 +283,7 @@ struct nfs_mount_info {
int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
struct nfs_parsed_mount_data *parsed;
struct nfs_clone_mount *cloned;
+ struct nfs_fh *mntfh;
};

static void nfs_umount_begin(struct super_block *);
@@ -292,8 +293,7 @@ static int nfs_show_devname(struct seq_file *, struct dentry *);
static int nfs_show_path(struct seq_file *, struct dentry *);
static int nfs_show_stats(struct seq_file *, struct dentry *);
static struct dentry *nfs_fs_mount_common(struct file_system_type *,
- struct nfs_server *, int, const char *, struct nfs_fh *,
- struct nfs_mount_info *);
+ struct nfs_server *, int, const char *, struct nfs_mount_info *);
static struct dentry *nfs_fs_mount(struct file_system_type *,
int, const char *, void *);
static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
@@ -338,9 +338,7 @@ static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
static int nfs4_validate_mount_data(void *options,
struct nfs_parsed_mount_data *args, const char *dev_name);
static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
- struct nfs_parsed_mount_data *data);
-static struct dentry *nfs4_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *raw_data);
+ struct nfs_mount_info *mount_info);
static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data);
static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
@@ -354,7 +352,7 @@ static void nfs4_kill_super(struct super_block *sb);
static struct file_system_type nfs4_fs_type = {
.owner = THIS_MODULE,
.name = "nfs4",
- .mount = nfs4_mount,
+ .mount = nfs_fs_mount,
.kill_sb = nfs4_kill_super,
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
};
@@ -1751,24 +1749,23 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
}

static struct dentry *nfs_try_mount(int flags, const char *dev_name,
- struct nfs_fh *mntfh,
struct nfs_mount_info *mount_info)
{
int status;
struct nfs_server *server;

if (mount_info->parsed->need_mount) {
- status = nfs_request_mount(mount_info->parsed, mntfh);
+ status = nfs_request_mount(mount_info->parsed, mount_info->mntfh);
if (status)
return ERR_PTR(status);
}

/* Get a volume representation */
- server = nfs_create_server(mount_info->parsed, mntfh);
+ server = nfs_create_server(mount_info->parsed, mount_info->mntfh);
if (IS_ERR(server))
return ERR_CAST(server);

- return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mntfh, mount_info);
+ return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mount_info);
}

/*
@@ -2394,7 +2391,6 @@ static int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
struct nfs_server *server,
int flags, const char *dev_name,
- struct nfs_fh *mntfh,
struct nfs_mount_info *mount_info)
{
struct super_block *s;
@@ -2437,7 +2433,7 @@ static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned);
}

- mntroot = nfs_get_root(s, mntfh, dev_name);
+ mntroot = nfs_get_root(s, mount_info->mntfh, dev_name);
if (IS_ERR(mntroot))
goto error_splat_super;

@@ -2472,17 +2468,16 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
.fill_super = nfs_fill_super,
.set_security = nfs_set_sb_security,
};
- struct nfs_fh *mntfh;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
int error;

mount_info.parsed = nfs_alloc_parsed_mount_data();
- mntfh = nfs_alloc_fhandle();
- if (mount_info.parsed == NULL || mntfh == NULL)
+ mount_info.mntfh = nfs_alloc_fhandle();
+ if (mount_info.parsed == NULL || mount_info.mntfh == NULL)
goto out;

/* Validate the mount data */
- error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mntfh, dev_name);
+ error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mount_info.mntfh, dev_name);
if (error == NFS_TEXT_DATA)
error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name);
if (error < 0) {
@@ -2492,14 +2487,14 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,

#ifdef CONFIG_NFS_V4
if (mount_info.parsed->version == 4)
- mntroot = nfs4_try_mount(flags, dev_name, mount_info.parsed);
+ mntroot = nfs4_try_mount(flags, dev_name, &mount_info);
else
#endif /* CONFIG_NFS_V4 */
- mntroot = nfs_try_mount(flags, dev_name, mntfh, &mount_info);
+ mntroot = nfs_try_mount(flags, dev_name, &mount_info);

out:
nfs_free_parsed_mount_data(mount_info.parsed);
- nfs_free_fhandle(mntfh);
+ nfs_free_fhandle(mount_info.mntfh);
return mntroot;
}

@@ -2540,6 +2535,8 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,

dprintk("--> nfs_xdev_mount_common()\n");

+ mount_info->mntfh = data->fh;
+
/* create a new volume representation */
server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
if (IS_ERR(server)) {
@@ -2547,7 +2544,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
goto out;
}

- mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, data->fh, mount_info);
+ mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);
out:
return mntroot;
}
@@ -2707,33 +2704,25 @@ out_no_address:
*/
static struct dentry *
nfs4_remote_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *raw_data)
+ const char *dev_name, void *info)
{
- struct nfs_mount_info mount_info = {
- .fill_super = nfs4_fill_super,
- .set_security = nfs_set_sb_security,
- .parsed = raw_data,
- };
+ struct nfs_mount_info *mount_info = info;
struct nfs_server *server;
- struct nfs_fh *mntfh;
struct dentry *mntroot = ERR_PTR(-ENOMEM);

- mntfh = nfs_alloc_fhandle();
- if (mount_info.parsed == NULL || mntfh == NULL)
- goto out;
+ mount_info->fill_super = nfs4_fill_super;
+ mount_info->set_security = nfs_set_sb_security;

/* Get a volume representation */
- server = nfs4_create_server(mount_info.parsed, mntfh);
+ server = nfs4_create_server(mount_info->parsed, mount_info->mntfh);
if (IS_ERR(server)) {
mntroot = ERR_CAST(server);
goto out;
}

- mntroot = nfs_fs_mount_common(fs_type, server, flags,
- dev_name, mntfh, &mount_info);
+ mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);

out:
- nfs_free_fhandle(mntfh);
return mntroot;
}

@@ -2846,17 +2835,18 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
}

static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
- struct nfs_parsed_mount_data *data)
+ struct nfs_mount_info *mount_info)
{
char *export_path;
struct vfsmount *root_mnt;
struct dentry *res;
+ struct nfs_parsed_mount_data *data = mount_info->parsed;

dfprintk(MOUNT, "--> nfs4_try_mount()\n");

export_path = data->nfs_server.export_path;
data->nfs_server.export_path = "/";
- root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
+ root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
data->nfs_server.hostname);
data->nfs_server.export_path = export_path;

@@ -2868,40 +2858,6 @@ static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
return res;
}

-/*
- * Get the superblock for an NFS4 mountpoint
- */
-static struct dentry *nfs4_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *raw_data)
-{
- struct nfs_parsed_mount_data *data;
- int error = -ENOMEM;
- struct dentry *res = ERR_PTR(-ENOMEM);
-
- data = nfs_alloc_parsed_mount_data();
- if (data == NULL)
- goto out;
-
- /* Validate the mount data */
- error = nfs_validate_mount_data(fs_type, raw_data, data, NULL, dev_name);
- if (error == NFS_TEXT_DATA)
- error = nfs_validate_text_mount_data(raw_data, data, dev_name);
- if (error < 0) {
- res = ERR_PTR(error);
- goto out;
- }
-
- res = nfs4_try_mount(flags, dev_name, data);
- if (IS_ERR(res))
- error = PTR_ERR(res);
-
-out:
- nfs_free_parsed_mount_data(data);
- dprintk("<-- nfs4_mount() = %d%s\n", error,
- error != 0 ? " [error]" : "");
- return res;
-}
-
static void nfs4_kill_super(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);
@@ -2940,24 +2896,23 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
};
struct nfs_server *server;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
- struct nfs_fh *mntfh;

dprintk("--> nfs4_referral_get_sb()\n");

- mntfh = nfs_alloc_fhandle();
- if (mount_info.cloned == NULL || mntfh == NULL)
+ mount_info.mntfh = nfs_alloc_fhandle();
+ if (mount_info.cloned == NULL || mount_info.mntfh == NULL)
goto out;

/* create a new volume representation */
- server = nfs4_create_referral_server(mount_info.cloned, mntfh);
+ server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh);
if (IS_ERR(server)) {
mntroot = ERR_CAST(server);
goto out;
}

- mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, mntfh, &mount_info);
+ mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info);
out:
- nfs_free_fhandle(mntfh);
+ nfs_free_fhandle(mount_info.mntfh);
return mntroot;
}

--
1.7.10.1


2012-05-10 15:20:37

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 01/14] NFS: Rename nfs4_proc_get_root()

From: Bryan Schumaker <[email protected]>

This function is really getting the root filehandle and not the root
dentry of the filesystem. I also removed the rpc_ops lookup from
nfs4_get_rootfh() under the assumption that if we reach this function
then we already know we are using NFS v4.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/getroot.c | 2 +-
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4proc.c | 6 +++---
3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 4ca6f5c..8a0f33e 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -150,7 +150,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
goto out;

/* Start by getting the root filehandle from the server */
- ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+ ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo);
if (ret < 0) {
dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
goto out;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 97365b0..edeef71 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -214,6 +214,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
/* nfs4proc.c */
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
+extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 98eb48d..69212d2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2345,8 +2345,8 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
/*
* get the file handle for the "/" directory on the server
*/
-static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
- struct nfs_fsinfo *info)
+int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fsinfo *info)
{
int minor_version = server->nfs_client->cl_minorversion;
int status = nfs4_lookup_root(server, fhandle, info);
@@ -6539,7 +6539,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.dir_inode_ops = &nfs4_dir_inode_operations,
.file_inode_ops = &nfs4_file_inode_operations,
.file_ops = &nfs4_file_operations,
- .getroot = nfs4_proc_get_root,
+ .getroot = nfs4_proc_get_rootfh,
.submount = nfs4_submount,
.getattr = nfs4_proc_getattr,
.setattr = nfs4_proc_setattr,
--
1.7.10.1


2012-05-10 15:20:39

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 06/14] NFS: Create a common xdev_mount() function

From: Bryan Schumaker <[email protected]>

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 <[email protected]>
---
fs/nfs/super.c | 122 +++++++++++++++-----------------------------------------
1 file changed, 32 insertions(+), 90 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 64a62da..707d1f6 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -280,6 +280,7 @@ static match_table_t nfs_vers_tokens = {
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;
};

static void nfs_umount_begin(struct super_block *);
@@ -2160,8 +2161,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;
@@ -2454,13 +2456,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;
@@ -2470,7 +2472,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);
@@ -2505,7 +2507,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_get_cache_cookie(s, NULL, data);
}

@@ -2525,13 +2527,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:
@@ -2539,18 +2541,33 @@ 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,
+ };
+ 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;
@@ -2930,86 +2947,11 @@ 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,
};
- 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 & NFS_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_get_cache_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 *
--
1.7.10.1