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. The first few patches are basic cleanups, the last
four drop us down to one common mount path.
These patches also help simplify my modules changes since I no longer have
to split these functions out of the generic code.
Comments or suggestions are appreciated!
- Bryan
Bryan Schumaker (7):
NFS: Rename nfs4_proc_get_root()
NFS: Create a single nfs_get_root()
NFS: Consistent arguments to nfs_fscache_get_super_cookie()
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
fs/nfs/fscache.c | 13 +-
fs/nfs/fscache.h | 2 +-
fs/nfs/getroot.c | 85 +-------
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4proc.c | 30 ++-
fs/nfs/super.c | 622 +++++++++++++----------------------------------------
6 files changed, 192 insertions(+), 561 deletions(-)
--
1.7.10
T24gTW9uLCAyMDEyLTA0LTMwIGF0IDE1OjA3IC0wNDAwLCBKaW0gUmVlcyB3cm90ZToNCj4gYmpz
Y2h1bWFAbmV0YXBwLmNvbSB3cm90ZToNCj4gDQo+ICAgRnJvbTogQnJ5YW4gU2NodW1ha2VyIDxi
anNjaHVtYUBuZXRhcHAuY29tPg0KPiAgIA0KPiAgIFRoaXMgZnVuY3Rpb24gaXMgcmVhbGx5IGdl
dHRpbmcgdGhlIHJvb3QgZmlsZWhhbmRsZSBhbmQgbm90IHRoZSByb290DQo+ICAgZGVudHJ5IG9m
IHRoZSBmaWxlc3lzdGVtLiAgSSBhbHNvIHJlbW92ZWQgdGhlIHJwY19vcHMgbG9va3VwIGZyb20N
Cj4gICBuZnM0X2dldF9yb290ZmgoKSB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IGlmIHdlIHJl
YWNoIHRoaXMgZnVuY3Rpb24NCj4gICB0aGVuIHdlIGFscmVhZHkga25vdyB3ZSBhcmUgdXNpbmcg
TkZTIHY0Lg0KPiANCj4gQW5kIHdoZW4gTkZTdjUgY29tZXMgb3V0Pw0KDQpUaGUgY29tcHV0ZXJz
IHdpbGwgYmUgcHJvZ3JhbW1pbmcgdGhlbXNlbHZlcywgYW5kIHdlJ2xsIGFsbCBiZSBzbGF2aW5n
DQppbiB0aGUgc2FsdCBtaW5lcyBmb3Igb3VyIG1lY2hhbmljYWwgb3ZlcmxvcmRzLi4uDQoNCi0t
IA0KVHJvbmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXINCg0KTmV0QXBw
DQpUcm9uZC5NeWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20NCg0K
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 | 327 +++++++++++++++-----------------------------------------
1 file changed, 86 insertions(+), 241 deletions(-)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index b7a071d..b9ee798 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -325,10 +325,8 @@ 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 struct dentry *nfs4_try_mount(int flags, const char *dev_name,
+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);
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,
@@ -342,7 +340,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,
};
@@ -2125,12 +2123,19 @@ static inline void nfs_initialise_sb(struct super_block *sb)
nfs_super_set_maxbytes(sb, server->maxfilesize);
}
+struct nfs_mount_info {
+ void (*fill_super)(struct super_block *, struct nfs_mount_info *);
+ struct nfs_parsed_mount_data *parsed;
+ unsigned int unshared;
+};
+
/*
* 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;
@@ -2283,13 +2288,13 @@ 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)
+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 = {
@@ -2297,34 +2302,9 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
};
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)
+ if (server->flags & mount_info->unshared)
compare_super = NULL;
/* -o noac implies -o sync */
@@ -2351,23 +2331,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_fscache_get_super_cookie(s, data, NULL);
+ mount_info->fill_super(s, mount_info);
+ nfs_fscache_get_super_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:
@@ -2385,6 +2363,58 @@ 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,
+ .unshared = NFS_MOUNT_UNSHARED,
+ };
+ struct nfs_fh *mntfh;
+ struct dentry *mntroot = ERR_PTR(-ENOMEM);
+ int error;
+
+ if (fs_type == &nfs_fs_type)
+ data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
+#ifdef CONFIG_NFS_V4
+ else
+ data = nfs_alloc_parsed_mount_data(4);
+#endif
+ 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
@@ -2523,7 +2553,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;
@@ -2574,190 +2605,36 @@ static int nfs4_validate_text_mount_data(void *options,
}
/*
- * Validate NFSv4 mount options
- */
-static int nfs4_validate_mount_data(void *options,
- struct nfs_parsed_mount_data *args,
- const char *dev_name)
-{
- struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
- struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
- char *c;
-
- if (data == NULL)
- goto out_no_data;
-
- switch (data->version) {
- case 1:
- if (data->host_addrlen > sizeof(args->nfs_server.address))
- goto out_no_address;
- if (data->host_addrlen == 0)
- goto out_no_address;
- args->nfs_server.addrlen = data->host_addrlen;
- if (copy_from_user(sap, data->host_addr, data->host_addrlen))
- return -EFAULT;
- if (!nfs_verify_server_address(sap))
- goto out_no_address;
-
- if (data->auth_flavourlen) {
- if (data->auth_flavourlen > 1)
- goto out_inval_auth;
- if (copy_from_user(&args->auth_flavors[0],
- data->auth_flavours,
- sizeof(args->auth_flavors[0])))
- return -EFAULT;
- }
-
- c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
- if (IS_ERR(c))
- return PTR_ERR(c);
- args->nfs_server.hostname = c;
-
- c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
- if (IS_ERR(c))
- return PTR_ERR(c);
- args->nfs_server.export_path = c;
- dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
-
- c = strndup_user(data->client_addr.data, 16);
- if (IS_ERR(c))
- return PTR_ERR(c);
- args->client_address = c;
-
- /*
- * Translate to nfs_parsed_mount_data, which nfs4_fill_super
- * can deal with.
- */
-
- args->flags = data->flags & NFS4_MOUNT_FLAGMASK;
- args->rsize = data->rsize;
- args->wsize = data->wsize;
- args->timeo = data->timeo;
- args->retrans = data->retrans;
- args->acregmin = data->acregmin;
- args->acregmax = data->acregmax;
- args->acdirmin = data->acdirmin;
- args->acdirmax = data->acdirmax;
- args->nfs_server.protocol = data->proto;
- nfs_validate_transport_protocol(args);
-
- 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 0;
-
-out_no_data:
- dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");
- return -EINVAL;
-
-out_inval_auth:
- dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",
- data->auth_flavourlen);
- return -EINVAL;
-
-out_no_address:
- dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
- return -EINVAL;
-}
-
-/*
* Get the superblock for the NFS4 root partition
*/
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,
+ .unshared = NFS4_MOUNT_UNSHARED,
+ };
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 & NFS4_MOUNT_UNSHARED)
- compare_super = NULL;
-
- /* -o noac implies -o sync */
- if (server->flags & NFS_MOUNT_NOAC)
- sb_mntdata.mntflags |= MS_SYNCHRONOUS;
-
- /* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
- if (IS_ERR(s)) {
- error = PTR_ERR(s);
- goto out_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_fscache_get_super_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(&nfs4_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,
@@ -2868,7 +2745,7 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
return dentry;
}
-static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
+struct dentry *nfs4_try_mount(int flags, const char *dev_name,
struct nfs_parsed_mount_data *data)
{
char *export_path;
@@ -2891,38 +2768,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(4);
- if (data == NULL)
- goto out;
-
- /* Validate the mount data */
- error = nfs4_validate_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);
@@ -3078,7 +2923,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_fscache_get_super_cookie(s, NULL, data);
}
--
1.7.10
On 04/30/2012 03:07 PM, Jim Rees wrote:
> [email protected] wrote:
>
> 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.
>
> And when NFSv5 comes out?
Well, this function is called "nfs4_get_rootfh()". nfs5_get_rootfh() will probably be something different and also not need an rpc op...
- Bryan
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 the get_super_cookie() function and let
this function decide the best way to handle the situation.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/fscache.c | 13 ++++++++-----
fs/nfs/fscache.h | 2 +-
fs/nfs/super.c | 4 ++--
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index ae65c16..35411f8 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -64,18 +64,21 @@ 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,
+ struct nfs_parsed_mount_data *parsed,
+ struct nfs_clone_mount *cloned)
{
struct nfs_fscache_key *key, *xkey;
struct nfs_server *nfss = NFS_SB(sb);
struct rb_node **p, *parent;
+ char *uniq = NULL;
int diff, ulen;
- if (uniq) {
+ if (parsed && parsed->fscache_uniq) {
+ uniq = parsed->fscache_uniq;
ulen = strlen(uniq);
- } else if (mntdata) {
- struct nfs_server *mnt_s = NFS_SB(mntdata->sb);
+ } 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;
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index b9c572d..0264bd6 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -74,7 +74,7 @@ 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_parsed_mount_data *,
struct nfs_clone_mount *);
extern void nfs_fscache_release_super_cookie(struct super_block *);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 75b1717..b7a071d 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2352,7 +2352,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_fscache_get_super_cookie(s, data, NULL);
}
mntroot = nfs_get_root(s, mntfh, dev_name);
@@ -2724,7 +2724,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_fscache_get_super_cookie(s, data, NULL);
}
mntroot = nfs_get_root(s, mntfh, dev_name);
--
1.7.10
[email protected] wrote:
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.
And when NFSv5 comes out?
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 | 126 ++++++++++++++++----------------------------------------
1 file changed, 35 insertions(+), 91 deletions(-)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index b9ee798..eefb3ed 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2126,6 +2126,7 @@ static inline void nfs_initialise_sb(struct super_block *sb)
struct nfs_mount_info {
void (*fill_super)(struct super_block *, struct nfs_mount_info *);
struct nfs_parsed_mount_data *parsed;
+ struct nfs_clone_mount *cloned;
unsigned int unshared;
};
@@ -2159,8 +2160,9 @@ static void nfs_fill_super(struct super_block *sb,
* Finish setting up a cloned NFS2/3 superblock
*/
static void nfs_clone_super(struct super_block *sb,
- const struct super_block *old_sb)
+ struct nfs_mount_info *mount_info)
{
+ const struct super_block *old_sb = mount_info->cloned->sb;
struct nfs_server *server = NFS_SB(sb);
sb->s_blocksize_bits = old_sb->s_blocksize_bits;
@@ -2439,13 +2441,13 @@ static void nfs_kill_super(struct super_block *s)
}
/*
- * Clone an NFS2/3 server record on xdev traversal (FSID-change)
+ * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
*/
static struct dentry *
-nfs_xdev_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *raw_data)
+nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
+ const char *dev_name, struct nfs_mount_info *mount_info)
{
- struct nfs_clone_mount *data = raw_data;
+ struct nfs_clone_mount *data = mount_info->cloned;
struct super_block *s;
struct nfs_server *server;
struct dentry *mntroot;
@@ -2455,7 +2457,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
};
int error;
- dprintk("--> nfs_xdev_mount()\n");
+ dprintk("--> nfs_xdev_mount_common()\n");
/* create a new volume representation */
server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
@@ -2465,7 +2467,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
}
sb_mntdata.server = server;
- if (server->flags & NFS_MOUNT_UNSHARED)
+ if (server->flags & mount_info->unshared)
compare_super = NULL;
/* -o noac implies -o sync */
@@ -2490,7 +2492,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
if (!s->s_root) {
/* initial superblock/root creation */
- nfs_clone_super(s, data->sb);
+ mount_info->fill_super(s, mount_info);
nfs_fscache_get_super_cookie(s, NULL, data);
}
@@ -2510,13 +2512,13 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
/* clone any lsm security options from the parent to the new sb */
security_sb_clone_mnt_opts(data->sb, s);
- dprintk("<-- nfs_xdev_mount() = 0\n");
+ dprintk("<-- nfs_xdev_mount_common() = 0\n");
return mntroot;
out_err_nosb:
nfs_free_server(server);
out_err_noserver:
- dprintk("<-- nfs_xdev_mount() = %d [error]\n", error);
+ dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error);
return ERR_PTR(error);
error_splat_super:
@@ -2524,18 +2526,34 @@ error_splat_super:
bdi_unregister(&server->backing_dev_info);
error_splat_bdi:
deactivate_locked_super(s);
- dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error);
+ dprintk("<-- nfs_xdev_mount_common() = %d [splat]\n", error);
return ERR_PTR(error);
}
+/*
+ * Clone an NFS2/3 server record on xdev traversal (FSID-change)
+ */
+static struct dentry *
+nfs_xdev_mount(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *raw_data)
+{
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs_clone_super,
+ .cloned = raw_data,
+ .unshared = NFS_MOUNT_UNSHARED,
+ };
+ return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
+}
+
#ifdef CONFIG_NFS_V4
/*
* Finish setting up a cloned NFS4 superblock
*/
static void nfs4_clone_super(struct super_block *sb,
- const struct super_block *old_sb)
+ struct nfs_mount_info *mount_info)
{
+ const struct super_block *old_sb = mount_info->cloned->sb;
sb->s_blocksize_bits = old_sb->s_blocksize_bits;
sb->s_blocksize = old_sb->s_blocksize;
sb->s_maxbytes = old_sb->s_maxbytes;
@@ -2787,86 +2805,12 @@ static struct dentry *
nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
- struct nfs_clone_mount *data = raw_data;
- struct super_block *s;
- struct nfs_server *server;
- struct dentry *mntroot;
- int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
- struct nfs_sb_mountdata sb_mntdata = {
- .mntflags = flags,
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs4_clone_super,
+ .cloned = raw_data,
+ .unshared = NFS4_MOUNT_UNSHARED,
};
- int error;
-
- dprintk("--> nfs4_xdev_mount()\n");
-
- /* create a new volume representation */
- server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
- if (IS_ERR(server)) {
- error = PTR_ERR(server);
- goto out_err_noserver;
- }
- sb_mntdata.server = server;
-
- if (server->flags & NFS4_MOUNT_UNSHARED)
- compare_super = NULL;
-
- /* -o noac implies -o sync */
- if (server->flags & NFS_MOUNT_NOAC)
- sb_mntdata.mntflags |= MS_SYNCHRONOUS;
-
- /* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
- if (IS_ERR(s)) {
- error = PTR_ERR(s);
- goto out_err_nosb;
- }
-
- if (s->s_fs_info != server) {
- nfs_free_server(server);
- server = NULL;
- } else {
- error = nfs_bdi_register(server);
- if (error)
- goto error_splat_bdi;
- }
-
- if (!s->s_root) {
- /* initial superblock/root creation */
- nfs4_clone_super(s, data->sb);
- nfs_fscache_get_super_cookie(s, NULL, data);
- }
-
- mntroot = nfs_get_root(s, data->fh, dev_name);
- if (IS_ERR(mntroot)) {
- error = PTR_ERR(mntroot);
- goto error_splat_super;
- }
- if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
- dput(mntroot);
- error = -ESTALE;
- goto error_splat_super;
- }
-
- s->s_flags |= MS_ACTIVE;
-
- security_sb_clone_mnt_opts(data->sb, s);
-
- dprintk("<-- nfs4_xdev_mount() = 0\n");
- return mntroot;
-
-out_err_nosb:
- nfs_free_server(server);
-out_err_noserver:
- dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error);
- return ERR_PTR(error);
-
-error_splat_super:
- if (server && !s->s_root)
- bdi_unregister(&server->backing_dev_info);
-error_splat_bdi:
- deactivate_locked_super(s);
- dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error);
- return ERR_PTR(error);
+ return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
}
static struct dentry *
--
1.7.10
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 1780391..8182038 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2354,8 +2354,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);
@@ -6570,7 +6570,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
From: Bryan Schumaker <[email protected]>
NFS v4 was doing something slightly different, so the difference can
become the new rpc_ops->getroot() function rather than existing on its
own.
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 8182038..8d62d00 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,
@@ -2372,6 +2373,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
@@ -6570,7 +6596,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
From: Bryan Schumaker <[email protected]>
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/super.c | 90 +++++++++-----------------------------------------------
1 file changed, 14 insertions(+), 76 deletions(-)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9ed670b..21b229c 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2774,95 +2774,33 @@ static struct dentry *
nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
- struct nfs_clone_mount *data = raw_data;
- struct super_block *s;
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs4_fill_super,
+ .set_security = nfs_clone_sb_security,
+ .cloned = raw_data,
+ .unshared = NFS4_MOUNT_UNSHARED,
+ };
struct nfs_server *server;
- struct dentry *mntroot;
+ struct dentry *mntroot = ERR_PTR(-ENOMEM);
struct nfs_fh *mntfh;
- int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
- struct nfs_sb_mountdata sb_mntdata = {
- .mntflags = flags,
- };
- int error = -ENOMEM;
dprintk("--> nfs4_referral_get_sb()\n");
mntfh = nfs_alloc_fhandle();
- if (mntfh == NULL)
- goto out_err_nofh;
+ if (mount_info.cloned == NULL || mntfh == NULL)
+ goto out;
/* create a new volume representation */
- server = nfs4_create_referral_server(data, mntfh);
+ server = nfs4_create_referral_server(mount_info.cloned, mntfh);
if (IS_ERR(server)) {
- error = PTR_ERR(server);
- goto out_err_noserver;
- }
- sb_mntdata.server = server;
-
- if (server->flags & NFS4_MOUNT_UNSHARED)
- compare_super = NULL;
-
- /* -o noac implies -o sync */
- if (server->flags & NFS_MOUNT_NOAC)
- sb_mntdata.mntflags |= MS_SYNCHRONOUS;
-
- /* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
- if (IS_ERR(s)) {
- error = PTR_ERR(s);
- goto out_err_nosb;
- }
-
- if (s->s_fs_info != server) {
- nfs_free_server(server);
- server = NULL;
- } else {
- error = nfs_bdi_register(server);
- if (error)
- goto error_splat_bdi;
- }
-
- if (!s->s_root) {
- /* initial superblock/root creation */
- nfs4_fill_super(s, NULL);
- nfs_fscache_get_super_cookie(s, NULL, data);
- }
-
- mntroot = nfs_get_root(s, mntfh, dev_name);
- if (IS_ERR(mntroot)) {
- error = PTR_ERR(mntroot);
- goto error_splat_super;
- }
- if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
- dput(mntroot);
- error = -ESTALE;
- goto error_splat_super;
+ mntroot = ERR_CAST(server);
+ goto out;
}
- s->s_flags |= MS_ACTIVE;
-
- security_sb_clone_mnt_opts(data->sb, s);
-
+ mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, mntfh, &mount_info);
+out:
nfs_free_fhandle(mntfh);
- dprintk("<-- nfs4_referral_get_sb() = 0\n");
return mntroot;
-
-out_err_nosb:
- nfs_free_server(server);
-out_err_noserver:
- nfs_free_fhandle(mntfh);
-out_err_nofh:
- dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
- return ERR_PTR(error);
-
-error_splat_super:
- if (server && !s->s_root)
- bdi_unregister(&server->backing_dev_info);
-error_splat_bdi:
- deactivate_locked_super(s);
- nfs_free_fhandle(mntfh);
- dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
- return ERR_PTR(error);
}
/*
--
1.7.10
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 eefb3ed..9ed670b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2125,6 +2125,7 @@ static inline void nfs_initialise_sb(struct super_block *sb)
struct nfs_mount_info {
void (*fill_super)(struct super_block *, struct nfs_mount_info *);
+ int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
struct nfs_parsed_mount_data *parsed;
struct nfs_clone_mount *cloned;
unsigned int unshared;
@@ -2290,6 +2291,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;
+}
+
struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
struct nfs_server *server,
int flags, const char *dev_name,
@@ -2334,14 +2351,14 @@ 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_fscache_get_super_cookie(s, mount_info->parsed, NULL);
+ nfs_fscache_get_super_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;
@@ -2372,6 +2389,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,
.unshared = NFS_MOUNT_UNSHARED,
};
struct nfs_fh *mntfh;
@@ -2448,13 +2466,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");
@@ -2463,71 +2476,14 @@ 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 & mount_info->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_fscache_get_super_cookie(s, NULL, data);
- }
-
- mntroot = nfs_get_root(s, data->fh, dev_name);
- if (IS_ERR(mntroot)) {
- error = PTR_ERR(mntroot);
- goto error_splat_super;
- }
- if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
- dput(mntroot);
- error = -ESTALE;
- goto error_splat_super;
+ 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");
+ mount_info->fill_super = nfs_clone_super;
+ mount_info->set_security = nfs_clone_sb_security;
+ 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);
}
/*
@@ -2631,6 +2587,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,
.unshared = NFS4_MOUNT_UNSHARED,
};
--
1.7.10
T24gTW9uLCAyMDEyLTA0LTMwIGF0IDE0OjQwIC0wNDAwLCBianNjaHVtYUBuZXRhcHAuY29tIHdy
b3RlOg0KPiBGcm9tOiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+DQo+IA0K
PiBTaWduZWQtb2ZmLWJ5OiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+DQo+
IC0tLQ0KPiAgZnMvbmZzL3N1cGVyLmMgfCAgIDkwICsrKysrKysrKy0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ICAxIGZpbGUgY2hhbmdlZCwgMTQgaW5z
ZXJ0aW9ucygrKSwgNzYgZGVsZXRpb25zKC0pDQo+IA0KPiBkaWZmIC0tZ2l0IGEvZnMvbmZzL3N1
cGVyLmMgYi9mcy9uZnMvc3VwZXIuYw0KPiBpbmRleCA5ZWQ2NzBiLi4yMWIyMjljIDEwMDY0NA0K
PiAtLS0gYS9mcy9uZnMvc3VwZXIuYw0KPiArKysgYi9mcy9uZnMvc3VwZXIuYw0KPiBAQCAtMjc3
NCw5NSArMjc3NCwzMyBAQCBzdGF0aWMgc3RydWN0IGRlbnRyeSAqDQo+ICBuZnM0X3JlbW90ZV9y
ZWZlcnJhbF9tb3VudChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwgaW50IGZsYWdz
LA0KPiAgCQkJICAgY29uc3QgY2hhciAqZGV2X25hbWUsIHZvaWQgKnJhd19kYXRhKQ0KPiAgew0K
PiAtCXN0cnVjdCBuZnNfY2xvbmVfbW91bnQgKmRhdGEgPSByYXdfZGF0YTsNCj4gLQlzdHJ1Y3Qg
c3VwZXJfYmxvY2sgKnM7DQo+ICsJc3RydWN0IG5mc19tb3VudF9pbmZvIG1vdW50X2luZm8gPSB7
DQo+ICsJCS5maWxsX3N1cGVyID0gbmZzNF9maWxsX3N1cGVyLA0KPiArCQkuc2V0X3NlY3VyaXR5
ID0gbmZzX2Nsb25lX3NiX3NlY3VyaXR5LA0KPiArCQkuY2xvbmVkID0gcmF3X2RhdGEsDQo+ICsJ
CS51bnNoYXJlZCA9IE5GUzRfTU9VTlRfVU5TSEFSRUQsDQoNClRoaXMgc2VlbXMgdG8gYmUgc2V0
dGluZyBhbGwgcmVmZXJyYWwgbW91bnRzIHRvIE5GUzRfTU9VTlRfVU5TSEFSRUQuIFdoeQ0KdGhl
IGNoYW5nZSBpbiBiZWhhdmlvdXI/DQoNCj4gKwl9Ow0KPiAgCXN0cnVjdCBuZnNfc2VydmVyICpz
ZXJ2ZXI7DQo+IC0Jc3RydWN0IGRlbnRyeSAqbW50cm9vdDsNCj4gKwlzdHJ1Y3QgZGVudHJ5ICpt
bnRyb290ID0gRVJSX1BUUigtRU5PTUVNKTsNCj4gIAlzdHJ1Y3QgbmZzX2ZoICptbnRmaDsNCj4g
LQlpbnQgKCpjb21wYXJlX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqKSA9IG5m
c19jb21wYXJlX3N1cGVyOw0KPiAtCXN0cnVjdCBuZnNfc2JfbW91bnRkYXRhIHNiX21udGRhdGEg
PSB7DQo+IC0JCS5tbnRmbGFncyA9IGZsYWdzLA0KPiAtCX07DQo+IC0JaW50IGVycm9yID0gLUVO
T01FTTsNCj4gIA0KPiAgCWRwcmludGsoIi0tPiBuZnM0X3JlZmVycmFsX2dldF9zYigpXG4iKTsN
Cj4gIA0KPiAgCW1udGZoID0gbmZzX2FsbG9jX2ZoYW5kbGUoKTsNCj4gLQlpZiAobW50ZmggPT0g
TlVMTCkNCj4gLQkJZ290byBvdXRfZXJyX25vZmg7DQo+ICsJaWYgKG1vdW50X2luZm8uY2xvbmVk
ID09IE5VTEwgfHwgbW50ZmggPT0gTlVMTCkNCj4gKwkJZ290byBvdXQ7DQo+ICANCj4gIAkvKiBj
cmVhdGUgYSBuZXcgdm9sdW1lIHJlcHJlc2VudGF0aW9uICovDQo+IC0Jc2VydmVyID0gbmZzNF9j
cmVhdGVfcmVmZXJyYWxfc2VydmVyKGRhdGEsIG1udGZoKTsNCj4gKwlzZXJ2ZXIgPSBuZnM0X2Ny
ZWF0ZV9yZWZlcnJhbF9zZXJ2ZXIobW91bnRfaW5mby5jbG9uZWQsIG1udGZoKTsNCj4gIAlpZiAo
SVNfRVJSKHNlcnZlcikpIHsNCj4gLQkJZXJyb3IgPSBQVFJfRVJSKHNlcnZlcik7DQo+IC0JCWdv
dG8gb3V0X2Vycl9ub3NlcnZlcjsNCj4gLQl9DQo+IC0Jc2JfbW50ZGF0YS5zZXJ2ZXIgPSBzZXJ2
ZXI7DQo+IC0NCj4gLQlpZiAoc2VydmVyLT5mbGFncyAmIE5GUzRfTU9VTlRfVU5TSEFSRUQpDQo+
IC0JCWNvbXBhcmVfc3VwZXIgPSBOVUxMOw0KPiAtDQo+IC0JLyogLW8gbm9hYyBpbXBsaWVzIC1v
IHN5bmMgKi8NCj4gLQlpZiAoc2VydmVyLT5mbGFncyAmIE5GU19NT1VOVF9OT0FDKQ0KPiAtCQlz
Yl9tbnRkYXRhLm1udGZsYWdzIHw9IE1TX1NZTkNIUk9OT1VTOw0KPiAtDQo+IC0JLyogR2V0IGEg
c3VwZXJibG9jayAtIG5vdGUgdGhhdCB3ZSBtYXkgZW5kIHVwIHNoYXJpbmcgb25lIHRoYXQgYWxy
ZWFkeSBleGlzdHMgKi8NCj4gLQlzID0gc2dldCgmbmZzNF9mc190eXBlLCBjb21wYXJlX3N1cGVy
LCBuZnNfc2V0X3N1cGVyLCAmc2JfbW50ZGF0YSk7DQo+IC0JaWYgKElTX0VSUihzKSkgew0KPiAt
CQllcnJvciA9IFBUUl9FUlIocyk7DQo+IC0JCWdvdG8gb3V0X2Vycl9ub3NiOw0KPiAtCX0NCj4g
LQ0KPiAtCWlmIChzLT5zX2ZzX2luZm8gIT0gc2VydmVyKSB7DQo+IC0JCW5mc19mcmVlX3NlcnZl
cihzZXJ2ZXIpOw0KPiAtCQlzZXJ2ZXIgPSBOVUxMOw0KPiAtCX0gZWxzZSB7DQo+IC0JCWVycm9y
ID0gbmZzX2JkaV9yZWdpc3RlcihzZXJ2ZXIpOw0KPiAtCQlpZiAoZXJyb3IpDQo+IC0JCQlnb3Rv
IGVycm9yX3NwbGF0X2JkaTsNCj4gLQl9DQo+IC0NCj4gLQlpZiAoIXMtPnNfcm9vdCkgew0KPiAt
CQkvKiBpbml0aWFsIHN1cGVyYmxvY2svcm9vdCBjcmVhdGlvbiAqLw0KPiAtCQluZnM0X2ZpbGxf
c3VwZXIocywgTlVMTCk7DQo+IC0JCW5mc19mc2NhY2hlX2dldF9zdXBlcl9jb29raWUocywgTlVM
TCwgZGF0YSk7DQo+IC0JfQ0KPiAtDQo+IC0JbW50cm9vdCA9IG5mc19nZXRfcm9vdChzLCBtbnRm
aCwgZGV2X25hbWUpOw0KPiAtCWlmIChJU19FUlIobW50cm9vdCkpIHsNCj4gLQkJZXJyb3IgPSBQ
VFJfRVJSKG1udHJvb3QpOw0KPiAtCQlnb3RvIGVycm9yX3NwbGF0X3N1cGVyOw0KPiAtCX0NCj4g
LQlpZiAobW50cm9vdC0+ZF9pbm9kZS0+aV9vcCAhPSBORlNfU0IocyktPm5mc19jbGllbnQtPnJw
Y19vcHMtPmRpcl9pbm9kZV9vcHMpIHsNCj4gLQkJZHB1dChtbnRyb290KTsNCj4gLQkJZXJyb3Ig
PSAtRVNUQUxFOw0KPiAtCQlnb3RvIGVycm9yX3NwbGF0X3N1cGVyOw0KPiArCQltbnRyb290ID0g
RVJSX0NBU1Qoc2VydmVyKTsNCj4gKwkJZ290byBvdXQ7DQo+ICAJfQ0KPiAgDQo+IC0Jcy0+c19m
bGFncyB8PSBNU19BQ1RJVkU7DQo+IC0NCj4gLQlzZWN1cml0eV9zYl9jbG9uZV9tbnRfb3B0cyhk
YXRhLT5zYiwgcyk7DQo+IC0NCj4gKwltbnRyb290ID0gbmZzX2ZzX21vdW50X2NvbW1vbigmbmZz
NF9mc190eXBlLCBzZXJ2ZXIsIGZsYWdzLCBkZXZfbmFtZSwgbW50ZmgsICZtb3VudF9pbmZvKTsN
Cj4gK291dDoNCj4gIAluZnNfZnJlZV9maGFuZGxlKG1udGZoKTsNCj4gLQlkcHJpbnRrKCI8LS0g
bmZzNF9yZWZlcnJhbF9nZXRfc2IoKSA9IDBcbiIpOw0KPiAgCXJldHVybiBtbnRyb290Ow0KPiAt
DQo+IC1vdXRfZXJyX25vc2I6DQo+IC0JbmZzX2ZyZWVfc2VydmVyKHNlcnZlcik7DQo+IC1vdXRf
ZXJyX25vc2VydmVyOg0KPiAtCW5mc19mcmVlX2ZoYW5kbGUobW50ZmgpOw0KPiAtb3V0X2Vycl9u
b2ZoOg0KPiAtCWRwcmludGsoIjwtLSBuZnM0X3JlZmVycmFsX2dldF9zYigpID0gJWQgW2Vycm9y
XVxuIiwgZXJyb3IpOw0KPiAtCXJldHVybiBFUlJfUFRSKGVycm9yKTsNCj4gLQ0KPiAtZXJyb3Jf
c3BsYXRfc3VwZXI6DQo+IC0JaWYgKHNlcnZlciAmJiAhcy0+c19yb290KQ0KPiAtCQliZGlfdW5y
ZWdpc3Rlcigmc2VydmVyLT5iYWNraW5nX2Rldl9pbmZvKTsNCj4gLWVycm9yX3NwbGF0X2JkaToN
Cj4gLQlkZWFjdGl2YXRlX2xvY2tlZF9zdXBlcihzKTsNCj4gLQluZnNfZnJlZV9maGFuZGxlKG1u
dGZoKTsNCj4gLQlkcHJpbnRrKCI8LS0gbmZzNF9yZWZlcnJhbF9nZXRfc2IoKSA9ICVkIFtzcGxh
dF1cbiIsIGVycm9yKTsNCj4gLQlyZXR1cm4gRVJSX1BUUihlcnJvcik7DQo+ICB9DQo+ICANCj4g
IC8qDQoNCi0tIA0KVHJvbmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXIN
Cg0KTmV0QXBwDQpUcm9uZC5NeWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20NCg0K
On 04/30/2012 02:40 PM, [email protected] wrote:
> 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 eefb3ed..9ed670b 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
...
> @@ -2463,71 +2476,14 @@ 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 & mount_info->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_fscache_get_super_cookie(s, NULL, data);
> - }
> -
> - mntroot = nfs_get_root(s, data->fh, dev_name);
> - if (IS_ERR(mntroot)) {
> - error = PTR_ERR(mntroot);
> - goto error_splat_super;
> - }
> - if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
> - dput(mntroot);
> - error = -ESTALE;
> - goto error_splat_super;
> + 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");
> + mount_info->fill_super = nfs_clone_super;
> + mount_info->set_security = nfs_clone_sb_security;
This will overwrite the fill_super function set by nfs4_xdev_mount() to call nfs_clone_super() instead of nfs4_clone_super(). Here is an updated patch:
NFS: Use nfs_fs_mount_common() for xdev mounts
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 eefb3ed..ae82482 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2125,6 +2125,7 @@ static inline void nfs_initialise_sb(struct super_block *sb)
struct nfs_mount_info {
void (*fill_super)(struct super_block *, struct nfs_mount_info *);
+ int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
struct nfs_parsed_mount_data *parsed;
struct nfs_clone_mount *cloned;
unsigned int unshared;
@@ -2290,6 +2291,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;
+}
+
struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
struct nfs_server *server,
int flags, const char *dev_name,
@@ -2334,14 +2351,14 @@ 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_fscache_get_super_cookie(s, mount_info->parsed, NULL);
+ nfs_fscache_get_super_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;
@@ -2372,6 +2389,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,
.unshared = NFS_MOUNT_UNSHARED,
};
struct nfs_fh *mntfh;
@@ -2448,13 +2466,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");
@@ -2463,71 +2476,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 & mount_info->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_fscache_get_super_cookie(s, NULL, data);
- }
-
- mntroot = nfs_get_root(s, data->fh, dev_name);
- if (IS_ERR(mntroot)) {
- error = PTR_ERR(mntroot);
- goto error_splat_super;
- }
- if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
- dput(mntroot);
- error = -ESTALE;
- goto error_splat_super;
+ 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);
}
/*
@@ -2539,6 +2493,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,
.unshared = NFS_MOUNT_UNSHARED,
};
@@ -2631,6 +2586,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,
.unshared = NFS4_MOUNT_UNSHARED,
};
@@ -2807,6 +2763,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,
.unshared = NFS4_MOUNT_UNSHARED,
};
--
1.7.10
> + 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);
> }
>
> /*
> @@ -2631,6 +2587,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,
> .unshared = NFS4_MOUNT_UNSHARED,
> };
T24gTW9uLCAyMDEyLTA0LTMwIGF0IDE0OjQwIC0wNDAwLCBianNjaHVtYUBuZXRhcHAuY29tIHdy
b3RlOg0KPiBGcm9tOiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+DQo+IA0K
PiBJIGludGVuZCBvbiBjcmVhdGluZyBhIHNpbmdsZSBuZnNfZnNfbW91bnQoKSBmdW5jdGlvbiB1
c2VkIGJ5IGFsbCBvdXINCj4gbW91bnQgcGF0aHMuICBUbyBhdm9pZCBjaGVja2luZyBiZXR3ZWVu
IG5ldyBtb3VudHMgYW5kIGNsb25lIG1vdW50cywgSQ0KPiBpbnN0ZWFkIHBhc3MgYm90aCBzdHJ1
Y3R1cmVzIHRvIHRoZSBnZXRfc3VwZXJfY29va2llKCkgZnVuY3Rpb24gYW5kIGxldA0KPiB0aGlz
IGZ1bmN0aW9uIGRlY2lkZSB0aGUgYmVzdCB3YXkgdG8gaGFuZGxlIHRoZSBzaXR1YXRpb24uDQo+
IA0KPiBTaWduZWQtb2ZmLWJ5OiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+
DQo+IC0tLQ0KPiAgZnMvbmZzL2ZzY2FjaGUuYyB8ICAgMTMgKysrKysrKystLS0tLQ0KPiAgZnMv
bmZzL2ZzY2FjaGUuaCB8ICAgIDIgKy0NCj4gIGZzL25mcy9zdXBlci5jICAgfCAgICA0ICsrLS0N
Cj4gIDMgZmlsZXMgY2hhbmdlZCwgMTEgaW5zZXJ0aW9ucygrKSwgOCBkZWxldGlvbnMoLSkNCj4g
DQo+IGRpZmYgLS1naXQgYS9mcy9uZnMvZnNjYWNoZS5jIGIvZnMvbmZzL2ZzY2FjaGUuYw0KPiBp
bmRleCBhZTY1YzE2Li4zNTQxMWY4IDEwMDY0NA0KPiAtLS0gYS9mcy9uZnMvZnNjYWNoZS5jDQo+
ICsrKyBiL2ZzL25mcy9mc2NhY2hlLmMNCj4gQEAgLTY0LDE4ICs2NCwyMSBAQCB2b2lkIG5mc19m
c2NhY2hlX3JlbGVhc2VfY2xpZW50X2Nvb2tpZShzdHJ1Y3QgbmZzX2NsaWVudCAqY2xwKQ0KPiAg
ICogZWl0aGVyIGJ5IHRoZSAnZnNjPXh4eCcgb3B0aW9uIHRvIG1vdW50LCBvciBieSBpbmhlcml0
aW5nIGl0IGZyb20gdGhlIHBhcmVudA0KPiAgICogc3VwZXJibG9jayBhY3Jvc3MgYW4gYXV0b21v
dW50IHBvaW50IG9mIHNvbWUgbmF0dXJlLg0KPiAgICovDQo+IC12b2lkIG5mc19mc2NhY2hlX2dl
dF9zdXBlcl9jb29raWUoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgY29uc3QgY2hhciAqdW5pcSwN
Cj4gLQkJCQkgIHN0cnVjdCBuZnNfY2xvbmVfbW91bnQgKm1udGRhdGEpDQo+ICt2b2lkIG5mc19m
c2NhY2hlX2dldF9zdXBlcl9jb29raWUoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwNCj4gKwkJCQkg
IHN0cnVjdCBuZnNfcGFyc2VkX21vdW50X2RhdGEgKnBhcnNlZCwNCj4gKwkJCQkgIHN0cnVjdCBu
ZnNfY2xvbmVfbW91bnQgKmNsb25lZCkNCj4gIHsNCj4gIAlzdHJ1Y3QgbmZzX2ZzY2FjaGVfa2V5
ICprZXksICp4a2V5Ow0KPiAgCXN0cnVjdCBuZnNfc2VydmVyICpuZnNzID0gTkZTX1NCKHNiKTsN
Cj4gIAlzdHJ1Y3QgcmJfbm9kZSAqKnAsICpwYXJlbnQ7DQo+ICsJY2hhciAqdW5pcSA9IE5VTEw7
DQo+ICAJaW50IGRpZmYsIHVsZW47DQo+ICANCj4gLQlpZiAodW5pcSkgew0KPiArCWlmIChwYXJz
ZWQgJiYgcGFyc2VkLT5mc2NhY2hlX3VuaXEpIHsNCj4gKwkJdW5pcSA9IHBhcnNlZC0+ZnNjYWNo
ZV91bmlxOw0KPiAgCQl1bGVuID0gc3RybGVuKHVuaXEpOw0KPiAtCX0gZWxzZSBpZiAobW50ZGF0
YSkgew0KPiAtCQlzdHJ1Y3QgbmZzX3NlcnZlciAqbW50X3MgPSBORlNfU0IobW50ZGF0YS0+c2Ip
Ow0KPiArCX0gZWxzZSBpZiAoY2xvbmVkKSB7DQo+ICsJCXN0cnVjdCBuZnNfc2VydmVyICptbnRf
cyA9IE5GU19TQihjbG9uZWQtPnNiKTsNCg0KSW5zdGVhZCBvZiBwYXNzaW5nIGluIHRoZSB3aG9s
ZSBuZnNfY2xvbmVfbW91bnQgc3RydWN0dXJlIGhlcmUsIGp1c3QgaW4NCm9yZGVyIHRvIGV4dHJh
Y3QgdGhlIHVuaXF1aWZpZXIsIHdoeSBub3QgcGFzcyBpbiB0aGUgc3RydWN0DQpuZnNfZnNjYWNo
ZV9rZXkgZnJvbSBjbG9uZWQtPnNiPw0KDQoNCg0KLS0gDQpUcm9uZCBNeWtsZWJ1c3QNCkxpbnV4
IE5GUyBjbGllbnQgbWFpbnRhaW5lcg0KDQpOZXRBcHANClRyb25kLk15a2xlYnVzdEBuZXRhcHAu
Y29tDQp3d3cubmV0YXBwLmNvbQ0KDQo=
T24gTW9uLCAyMDEyLTA0LTMwIGF0IDE0OjQwIC0wNDAwLCBianNjaHVtYUBuZXRhcHAuY29tIHdy
b3RlOg0KPiBGcm9tOiBCcnlhbiBTY2h1bWFrZXIgPGJqc2NodW1hQG5ldGFwcC5jb20+DQo+IA0K
PiBUaGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gbmZzX3hkZXZfbW91bnQoKSBhbmQgbmZzNF94
ZGV2X21vdW50KCkgaXMgdGhlDQo+IHVuc2hhcmVkIGZsYWcsIHNvIEkgcGFzcyB0aGlzIGFzIGFu
IG5mc19tb3VudF9pbmZvIHBhcmFtZXRlciBzbyB3ZSBjYW4NCj4gc2hhcmUgbW9yZSBjb2RlLg0K
PiANCj4gU2lnbmVkLW9mZi1ieTogQnJ5YW4gU2NodW1ha2VyIDxianNjaHVtYUBuZXRhcHAuY29t
Pg0KPiAtLS0NCj4gIGZzL25mcy9zdXBlci5jIHwgIDEyNiArKysrKysrKysrKysrKysrLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KPiAgMSBmaWxlIGNoYW5nZWQsIDM1
IGluc2VydGlvbnMoKyksIDkxIGRlbGV0aW9ucygtKQ0KPiANCj4gZGlmZiAtLWdpdCBhL2ZzL25m
cy9zdXBlci5jIGIvZnMvbmZzL3N1cGVyLmMNCj4gaW5kZXggYjllZTc5OC4uZWVmYjNlZCAxMDA2
NDQNCj4gLS0tIGEvZnMvbmZzL3N1cGVyLmMNCj4gKysrIGIvZnMvbmZzL3N1cGVyLmMNCj4gQEAg
LTIxMjYsNiArMjEyNiw3IEBAIHN0YXRpYyBpbmxpbmUgdm9pZCBuZnNfaW5pdGlhbGlzZV9zYihz
dHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQ0KPiAgc3RydWN0IG5mc19tb3VudF9pbmZvIHsNCj4gIAl2
b2lkICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHN0cnVjdCBuZnNfbW91bnRf
aW5mbyAqKTsNCj4gIAlzdHJ1Y3QgbmZzX3BhcnNlZF9tb3VudF9kYXRhICpwYXJzZWQ7DQo+ICsJ
c3RydWN0IG5mc19jbG9uZV9tb3VudCAqY2xvbmVkOw0KPiAgCXVuc2lnbmVkIGludCB1bnNoYXJl
ZDsNCj4gIH07DQo+ICANCj4gQEAgLTIxNTksOCArMjE2MCw5IEBAIHN0YXRpYyB2b2lkIG5mc19m
aWxsX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsDQo+ICAgKiBGaW5pc2ggc2V0dGluZyB1
cCBhIGNsb25lZCBORlMyLzMgc3VwZXJibG9jaw0KPiAgICovDQo+ICBzdGF0aWMgdm9pZCBuZnNf
Y2xvbmVfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwNCj4gLQkJCSAgICBjb25zdCBzdHJ1
Y3Qgc3VwZXJfYmxvY2sgKm9sZF9zYikNCj4gKwkJCSAgICBzdHJ1Y3QgbmZzX21vdW50X2luZm8g
Km1vdW50X2luZm8pDQo+ICB7DQo+ICsJY29uc3Qgc3RydWN0IHN1cGVyX2Jsb2NrICpvbGRfc2Ig
PSBtb3VudF9pbmZvLT5jbG9uZWQtPnNiOw0KPiAgCXN0cnVjdCBuZnNfc2VydmVyICpzZXJ2ZXIg
PSBORlNfU0Ioc2IpOw0KPiAgDQo+ICAJc2ItPnNfYmxvY2tzaXplX2JpdHMgPSBvbGRfc2ItPnNf
YmxvY2tzaXplX2JpdHM7DQo+IEBAIC0yNDM5LDEzICsyNDQxLDEzIEBAIHN0YXRpYyB2b2lkIG5m
c19raWxsX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykNCj4gIH0NCj4gIA0KPiAgLyoNCj4g
LSAqIENsb25lIGFuIE5GUzIvMyBzZXJ2ZXIgcmVjb3JkIG9uIHhkZXYgdHJhdmVyc2FsIChGU0lE
LWNoYW5nZSkNCj4gKyAqIENsb25lIGFuIE5GUzIvMy80IHNlcnZlciByZWNvcmQgb24geGRldiB0
cmF2ZXJzYWwgKEZTSUQtY2hhbmdlKQ0KPiAgICovDQo+ICBzdGF0aWMgc3RydWN0IGRlbnRyeSAq
DQo+IC1uZnNfeGRldl9tb3VudChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwgaW50
IGZsYWdzLA0KPiAtCQljb25zdCBjaGFyICpkZXZfbmFtZSwgdm9pZCAqcmF3X2RhdGEpDQo+ICtu
ZnNfeGRldl9tb3VudF9jb21tb24oc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsIGlu
dCBmbGFncywNCj4gKwkJY29uc3QgY2hhciAqZGV2X25hbWUsIHN0cnVjdCBuZnNfbW91bnRfaW5m
byAqbW91bnRfaW5mbykNCj4gIHsNCj4gLQlzdHJ1Y3QgbmZzX2Nsb25lX21vdW50ICpkYXRhID0g
cmF3X2RhdGE7DQo+ICsJc3RydWN0IG5mc19jbG9uZV9tb3VudCAqZGF0YSA9IG1vdW50X2luZm8t
PmNsb25lZDsNCj4gIAlzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnM7DQo+ICAJc3RydWN0IG5mc19zZXJ2
ZXIgKnNlcnZlcjsNCj4gIAlzdHJ1Y3QgZGVudHJ5ICptbnRyb290Ow0KPiBAQCAtMjQ1NSw3ICsy
NDU3LDcgQEAgbmZzX3hkZXZfbW91bnQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUs
IGludCBmbGFncywNCj4gIAl9Ow0KPiAgCWludCBlcnJvcjsNCj4gIA0KPiAtCWRwcmludGsoIi0t
PiBuZnNfeGRldl9tb3VudCgpXG4iKTsNCj4gKwlkcHJpbnRrKCItLT4gbmZzX3hkZXZfbW91bnRf
Y29tbW9uKClcbiIpOw0KPiAgDQo+ICAJLyogY3JlYXRlIGEgbmV3IHZvbHVtZSByZXByZXNlbnRh
dGlvbiAqLw0KPiAgCXNlcnZlciA9IG5mc19jbG9uZV9zZXJ2ZXIoTkZTX1NCKGRhdGEtPnNiKSwg
ZGF0YS0+ZmgsIGRhdGEtPmZhdHRyLCBkYXRhLT5hdXRoZmxhdm9yKTsNCj4gQEAgLTI0NjUsNyAr
MjQ2Nyw3IEBAIG5mc194ZGV2X21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBl
LCBpbnQgZmxhZ3MsDQo+ICAJfQ0KPiAgCXNiX21udGRhdGEuc2VydmVyID0gc2VydmVyOw0KPiAg
DQo+IC0JaWYgKHNlcnZlci0+ZmxhZ3MgJiBORlNfTU9VTlRfVU5TSEFSRUQpDQo+ICsJaWYgKHNl
cnZlci0+ZmxhZ3MgJiBtb3VudF9pbmZvLT51bnNoYXJlZCkNCj4gIAkJY29tcGFyZV9zdXBlciA9
IE5VTEw7DQo+ICANCj4gIAkvKiAtbyBub2FjIGltcGxpZXMgLW8gc3luYyAqLw0KPiBAQCAtMjQ5
MCw3ICsyNDkyLDcgQEAgbmZzX3hkZXZfbW91bnQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZz
X3R5cGUsIGludCBmbGFncywNCj4gIA0KPiAgCWlmICghcy0+c19yb290KSB7DQo+ICAJCS8qIGlu
aXRpYWwgc3VwZXJibG9jay9yb290IGNyZWF0aW9uICovDQo+IC0JCW5mc19jbG9uZV9zdXBlcihz
LCBkYXRhLT5zYik7DQo+ICsJCW1vdW50X2luZm8tPmZpbGxfc3VwZXIocywgbW91bnRfaW5mbyk7
DQo+ICAJCW5mc19mc2NhY2hlX2dldF9zdXBlcl9jb29raWUocywgTlVMTCwgZGF0YSk7DQo+ICAJ
fQ0KPiAgDQo+IEBAIC0yNTEwLDEzICsyNTEyLDEzIEBAIG5mc194ZGV2X21vdW50KHN0cnVjdCBm
aWxlX3N5c3RlbV90eXBlICpmc190eXBlLCBpbnQgZmxhZ3MsDQo+ICAJLyogY2xvbmUgYW55IGxz
bSBzZWN1cml0eSBvcHRpb25zIGZyb20gdGhlIHBhcmVudCB0byB0aGUgbmV3IHNiICovDQo+ICAJ
c2VjdXJpdHlfc2JfY2xvbmVfbW50X29wdHMoZGF0YS0+c2IsIHMpOw0KPiAgDQo+IC0JZHByaW50
aygiPC0tIG5mc194ZGV2X21vdW50KCkgPSAwXG4iKTsNCj4gKwlkcHJpbnRrKCI8LS0gbmZzX3hk
ZXZfbW91bnRfY29tbW9uKCkgPSAwXG4iKTsNCj4gIAlyZXR1cm4gbW50cm9vdDsNCj4gIA0KPiAg
b3V0X2Vycl9ub3NiOg0KPiAgCW5mc19mcmVlX3NlcnZlcihzZXJ2ZXIpOw0KPiAgb3V0X2Vycl9u
b3NlcnZlcjoNCj4gLQlkcHJpbnRrKCI8LS0gbmZzX3hkZXZfbW91bnQoKSA9ICVkIFtlcnJvcl1c
biIsIGVycm9yKTsNCj4gKwlkcHJpbnRrKCI8LS0gbmZzX3hkZXZfbW91bnRfY29tbW9uKCkgPSAl
ZCBbZXJyb3JdXG4iLCBlcnJvcik7DQo+ICAJcmV0dXJuIEVSUl9QVFIoZXJyb3IpOw0KPiAgDQo+
ICBlcnJvcl9zcGxhdF9zdXBlcjoNCj4gQEAgLTI1MjQsMTggKzI1MjYsMzQgQEAgZXJyb3Jfc3Bs
YXRfc3VwZXI6DQo+ICAJCWJkaV91bnJlZ2lzdGVyKCZzZXJ2ZXItPmJhY2tpbmdfZGV2X2luZm8p
Ow0KPiAgZXJyb3Jfc3BsYXRfYmRpOg0KPiAgCWRlYWN0aXZhdGVfbG9ja2VkX3N1cGVyKHMpOw0K
PiAtCWRwcmludGsoIjwtLSBuZnNfeGRldl9tb3VudCgpID0gJWQgW3NwbGF0XVxuIiwgZXJyb3Ip
Ow0KPiArCWRwcmludGsoIjwtLSBuZnNfeGRldl9tb3VudF9jb21tb24oKSA9ICVkIFtzcGxhdF1c
biIsIGVycm9yKTsNCj4gIAlyZXR1cm4gRVJSX1BUUihlcnJvcik7DQo+ICB9DQo+ICANCj4gKy8q
DQo+ICsgKiBDbG9uZSBhbiBORlMyLzMgc2VydmVyIHJlY29yZCBvbiB4ZGV2IHRyYXZlcnNhbCAo
RlNJRC1jaGFuZ2UpDQo+ICsgKi8NCj4gK3N0YXRpYyBzdHJ1Y3QgZGVudHJ5ICoNCj4gK25mc194
ZGV2X21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLCBpbnQgZmxhZ3MsDQo+
ICsJCWNvbnN0IGNoYXIgKmRldl9uYW1lLCB2b2lkICpyYXdfZGF0YSkNCj4gK3sNCj4gKwlzdHJ1
Y3QgbmZzX21vdW50X2luZm8gbW91bnRfaW5mbyA9IHsNCj4gKwkJLmZpbGxfc3VwZXIgPSBuZnNf
Y2xvbmVfc3VwZXIsDQo+ICsJCS5jbG9uZWQgICA9IHJhd19kYXRhLA0KPiArCQkudW5zaGFyZWQg
PSBORlNfTU9VTlRfVU5TSEFSRUQsDQoNCldoeSB0aGUgY2hhbmdlIGluIHNoYXJlIGJlaGF2aW91
cj8NCg0KPiArCX07DQo+ICsJcmV0dXJuIG5mc194ZGV2X21vdW50X2NvbW1vbigmbmZzX2ZzX3R5
cGUsIGZsYWdzLCBkZXZfbmFtZSwgJm1vdW50X2luZm8pOw0KPiArfQ0KPiArDQo+ICAjaWZkZWYg
Q09ORklHX05GU19WNA0KPiAgDQo+ICAvKg0KPiAgICogRmluaXNoIHNldHRpbmcgdXAgYSBjbG9u
ZWQgTkZTNCBzdXBlcmJsb2NrDQo+ICAgKi8NCj4gIHN0YXRpYyB2b2lkIG5mczRfY2xvbmVfc3Vw
ZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwNCj4gLQkJCSAgICBjb25zdCBzdHJ1Y3Qgc3VwZXJf
YmxvY2sgKm9sZF9zYikNCj4gKwkJCSAgICAgc3RydWN0IG5mc19tb3VudF9pbmZvICptb3VudF9p
bmZvKQ0KPiAgew0KPiArCWNvbnN0IHN0cnVjdCBzdXBlcl9ibG9jayAqb2xkX3NiID0gbW91bnRf
aW5mby0+Y2xvbmVkLT5zYjsNCj4gIAlzYi0+c19ibG9ja3NpemVfYml0cyA9IG9sZF9zYi0+c19i
bG9ja3NpemVfYml0czsNCj4gIAlzYi0+c19ibG9ja3NpemUgPSBvbGRfc2ItPnNfYmxvY2tzaXpl
Ow0KPiAgCXNiLT5zX21heGJ5dGVzID0gb2xkX3NiLT5zX21heGJ5dGVzOw0KPiBAQCAtMjc4Nyw4
NiArMjgwNSwxMiBAQCBzdGF0aWMgc3RydWN0IGRlbnRyeSAqDQo+ICBuZnM0X3hkZXZfbW91bnQo
c3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsIGludCBmbGFncywNCj4gIAkJIGNvbnN0
IGNoYXIgKmRldl9uYW1lLCB2b2lkICpyYXdfZGF0YSkNCj4gIHsNCj4gLQlzdHJ1Y3QgbmZzX2Ns
b25lX21vdW50ICpkYXRhID0gcmF3X2RhdGE7DQo+IC0Jc3RydWN0IHN1cGVyX2Jsb2NrICpzOw0K
PiAtCXN0cnVjdCBuZnNfc2VydmVyICpzZXJ2ZXI7DQo+IC0Jc3RydWN0IGRlbnRyeSAqbW50cm9v
dDsNCj4gLQlpbnQgKCpjb21wYXJlX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAq
KSA9IG5mc19jb21wYXJlX3N1cGVyOw0KPiAtCXN0cnVjdCBuZnNfc2JfbW91bnRkYXRhIHNiX21u
dGRhdGEgPSB7DQo+IC0JCS5tbnRmbGFncyA9IGZsYWdzLA0KPiArCXN0cnVjdCBuZnNfbW91bnRf
aW5mbyBtb3VudF9pbmZvID0gew0KPiArCQkuZmlsbF9zdXBlciA9IG5mczRfY2xvbmVfc3VwZXIs
DQo+ICsJCS5jbG9uZWQgPSByYXdfZGF0YSwNCj4gKwkJLnVuc2hhcmVkID0gTkZTNF9NT1VOVF9V
TlNIQVJFRCwNCj4gIAl9Ow0KPiAtCWludCBlcnJvcjsNCj4gLQ0KPiAtCWRwcmludGsoIi0tPiBu
ZnM0X3hkZXZfbW91bnQoKVxuIik7DQo+IC0NCj4gLQkvKiBjcmVhdGUgYSBuZXcgdm9sdW1lIHJl
cHJlc2VudGF0aW9uICovDQo+IC0Jc2VydmVyID0gbmZzX2Nsb25lX3NlcnZlcihORlNfU0IoZGF0
YS0+c2IpLCBkYXRhLT5maCwgZGF0YS0+ZmF0dHIsIGRhdGEtPmF1dGhmbGF2b3IpOw0KPiAtCWlm
IChJU19FUlIoc2VydmVyKSkgew0KPiAtCQllcnJvciA9IFBUUl9FUlIoc2VydmVyKTsNCj4gLQkJ
Z290byBvdXRfZXJyX25vc2VydmVyOw0KPiAtCX0NCj4gLQlzYl9tbnRkYXRhLnNlcnZlciA9IHNl
cnZlcjsNCj4gLQ0KPiAtCWlmIChzZXJ2ZXItPmZsYWdzICYgTkZTNF9NT1VOVF9VTlNIQVJFRCkN
Cj4gLQkJY29tcGFyZV9zdXBlciA9IE5VTEw7DQo+IC0NCj4gLQkvKiAtbyBub2FjIGltcGxpZXMg
LW8gc3luYyAqLw0KPiAtCWlmIChzZXJ2ZXItPmZsYWdzICYgTkZTX01PVU5UX05PQUMpDQo+IC0J
CXNiX21udGRhdGEubW50ZmxhZ3MgfD0gTVNfU1lOQ0hST05PVVM7DQo+IC0NCj4gLQkvKiBHZXQg
YSBzdXBlcmJsb2NrIC0gbm90ZSB0aGF0IHdlIG1heSBlbmQgdXAgc2hhcmluZyBvbmUgdGhhdCBh
bHJlYWR5IGV4aXN0cyAqLw0KPiAtCXMgPSBzZ2V0KCZuZnM0X2ZzX3R5cGUsIGNvbXBhcmVfc3Vw
ZXIsIG5mc19zZXRfc3VwZXIsICZzYl9tbnRkYXRhKTsNCj4gLQlpZiAoSVNfRVJSKHMpKSB7DQo+
IC0JCWVycm9yID0gUFRSX0VSUihzKTsNCj4gLQkJZ290byBvdXRfZXJyX25vc2I7DQo+IC0JfQ0K
PiAtDQo+IC0JaWYgKHMtPnNfZnNfaW5mbyAhPSBzZXJ2ZXIpIHsNCj4gLQkJbmZzX2ZyZWVfc2Vy
dmVyKHNlcnZlcik7DQo+IC0JCXNlcnZlciA9IE5VTEw7DQo+IC0JfSBlbHNlIHsNCj4gLQkJZXJy
b3IgPSBuZnNfYmRpX3JlZ2lzdGVyKHNlcnZlcik7DQo+IC0JCWlmIChlcnJvcikNCj4gLQkJCWdv
dG8gZXJyb3Jfc3BsYXRfYmRpOw0KPiAtCX0NCj4gLQ0KPiAtCWlmICghcy0+c19yb290KSB7DQo+
IC0JCS8qIGluaXRpYWwgc3VwZXJibG9jay9yb290IGNyZWF0aW9uICovDQo+IC0JCW5mczRfY2xv
bmVfc3VwZXIocywgZGF0YS0+c2IpOw0KPiAtCQluZnNfZnNjYWNoZV9nZXRfc3VwZXJfY29va2ll
KHMsIE5VTEwsIGRhdGEpOw0KPiAtCX0NCj4gLQ0KPiAtCW1udHJvb3QgPSBuZnNfZ2V0X3Jvb3Qo
cywgZGF0YS0+ZmgsIGRldl9uYW1lKTsNCj4gLQlpZiAoSVNfRVJSKG1udHJvb3QpKSB7DQo+IC0J
CWVycm9yID0gUFRSX0VSUihtbnRyb290KTsNCj4gLQkJZ290byBlcnJvcl9zcGxhdF9zdXBlcjsN
Cj4gLQl9DQo+IC0JaWYgKG1udHJvb3QtPmRfaW5vZGUtPmlfb3AgIT0gTkZTX1NCKHMpLT5uZnNf
Y2xpZW50LT5ycGNfb3BzLT5kaXJfaW5vZGVfb3BzKSB7DQo+IC0JCWRwdXQobW50cm9vdCk7DQo+
IC0JCWVycm9yID0gLUVTVEFMRTsNCj4gLQkJZ290byBlcnJvcl9zcGxhdF9zdXBlcjsNCj4gLQl9
DQo+IC0NCj4gLQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsNCj4gLQ0KPiAtCXNlY3VyaXR5X3Ni
X2Nsb25lX21udF9vcHRzKGRhdGEtPnNiLCBzKTsNCj4gLQ0KPiAtCWRwcmludGsoIjwtLSBuZnM0
X3hkZXZfbW91bnQoKSA9IDBcbiIpOw0KPiAtCXJldHVybiBtbnRyb290Ow0KPiAtDQo+IC1vdXRf
ZXJyX25vc2I6DQo+IC0JbmZzX2ZyZWVfc2VydmVyKHNlcnZlcik7DQo+IC1vdXRfZXJyX25vc2Vy
dmVyOg0KPiAtCWRwcmludGsoIjwtLSBuZnM0X3hkZXZfbW91bnQoKSA9ICVkIFtlcnJvcl1cbiIs
IGVycm9yKTsNCj4gLQlyZXR1cm4gRVJSX1BUUihlcnJvcik7DQo+IC0NCj4gLWVycm9yX3NwbGF0
X3N1cGVyOg0KPiAtCWlmIChzZXJ2ZXIgJiYgIXMtPnNfcm9vdCkNCj4gLQkJYmRpX3VucmVnaXN0
ZXIoJnNlcnZlci0+YmFja2luZ19kZXZfaW5mbyk7DQo+IC1lcnJvcl9zcGxhdF9iZGk6DQo+IC0J
ZGVhY3RpdmF0ZV9sb2NrZWRfc3VwZXIocyk7DQo+IC0JZHByaW50aygiPC0tIG5mczRfeGRldl9t
b3VudCgpID0gJWQgW3NwbGF0XVxuIiwgZXJyb3IpOw0KPiAtCXJldHVybiBFUlJfUFRSKGVycm9y
KTsNCj4gKwlyZXR1cm4gbmZzX3hkZXZfbW91bnRfY29tbW9uKCZuZnM0X2ZzX3R5cGUsIGZsYWdz
LCBkZXZfbmFtZSwgJm1vdW50X2luZm8pOw0KPiAgfQ0KPiAgDQo+ICBzdGF0aWMgc3RydWN0IGRl
bnRyeSAqDQoNCi0tIA0KVHJvbmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWlu
ZXINCg0KTmV0QXBwDQpUcm9uZC5NeWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20N
Cg0K