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 v4
-------------
- Fix up the commit message on patch 6
- Don't delete the dprintks saying that the nfs_xdev_mount() function is exiting
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
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 | 748 ++++++++++++++++++++---------------------------------
7 files changed, 309 insertions(+), 575 deletions(-)
--
1.7.10.1
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 db0952d..c69c806 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
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
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 5b025b0..fc62701 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
From: Bryan Schumaker <[email protected]>
The only difference between nfs_xdev_mount() and nfs4_xdev_mount() is the
clone_super() function called to clone the super block. I can combine
these two functions by using the fill_super field in the mount_info
structure.
Signed-off-by: Bryan Schumaker <[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
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 c69c806..db636d7 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;
@@ -2572,37 +2596,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
*/
@@ -2673,13 +2666,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;
@@ -2880,6 +2867,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
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 | 96 +++++++++++++++++---------------------------------------
1 file changed, 29 insertions(+), 67 deletions(-)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 707d1f6..e93a6e9 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,17 @@ 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_err;
}
- 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);
-
+ mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, data->fh, mount_info);
dprintk("<-- nfs_xdev_mount_common() = 0\n");
+out:
return mntroot;
-out_err_nosb:
- nfs_free_server(server);
-out_err_noserver:
+out_err:
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);
+ goto out;
}
/*
@@ -2554,6 +2513,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 +2700,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 +2910,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
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 e93a6e9..1157189 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2920,95 +2920,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
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
From: Bryan Schumaker <[email protected]>
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 <[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
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
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 db636d7..5b025b0 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) {
@@ -2866,7 +2890,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
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 fc62701..c3ae819 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_err;
}
- 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);
dprintk("<-- nfs_xdev_mount_common() = 0\n");
out:
return mntroot;
@@ -2712,33 +2709,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;
}
@@ -2851,17 +2840,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;
@@ -2873,40 +2863,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);
@@ -2945,24 +2901,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
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
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 1157189..db0952d 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;
@@ -2867,7 +2866,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