mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
NFS: Fix the setting of capabilities when automounting a new filesystem
Capabilities cannot be inherited when we cross into a new filesystem.
They need to be reset to the minimal defaults, and then probed for
again.
Fixes: 54ceac4515 ("NFS: Share NFS superblocks per-protocol per-server per-FSID")
Cc: stable@vger.kernel.org
Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
@@ -682,6 +682,44 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nfs_init_client);
|
EXPORT_SYMBOL_GPL(nfs_init_client);
|
||||||
|
|
||||||
|
static void nfs4_server_set_init_caps(struct nfs_server *server)
|
||||||
|
{
|
||||||
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||||
|
/* Set the basic capabilities */
|
||||||
|
server->caps = server->nfs_client->cl_mvops->init_caps;
|
||||||
|
if (server->flags & NFS_MOUNT_NORDIRPLUS)
|
||||||
|
server->caps &= ~NFS_CAP_READDIRPLUS;
|
||||||
|
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
|
||||||
|
server->caps &= ~NFS_CAP_READ_PLUS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
|
||||||
|
* authentication.
|
||||||
|
*/
|
||||||
|
if (nfs4_disable_idmapping &&
|
||||||
|
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
|
||||||
|
server->caps |= NFS_CAP_UIDGID_NOMAP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs_server_set_init_caps(struct nfs_server *server)
|
||||||
|
{
|
||||||
|
switch (server->nfs_client->rpc_ops->version) {
|
||||||
|
case 2:
|
||||||
|
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
|
||||||
|
if (!(server->flags & NFS_MOUNT_NORDIRPLUS))
|
||||||
|
server->caps |= NFS_CAP_READDIRPLUS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nfs4_server_set_init_caps(server);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nfs_server_set_init_caps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a version 2 or 3 client
|
* Create a version 2 or 3 client
|
||||||
*/
|
*/
|
||||||
@@ -726,7 +764,6 @@ static int nfs_init_server(struct nfs_server *server,
|
|||||||
/* Initialise the client representation from the mount data */
|
/* Initialise the client representation from the mount data */
|
||||||
server->flags = ctx->flags;
|
server->flags = ctx->flags;
|
||||||
server->options = ctx->options;
|
server->options = ctx->options;
|
||||||
server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
|
|
||||||
|
|
||||||
switch (clp->rpc_ops->version) {
|
switch (clp->rpc_ops->version) {
|
||||||
case 2:
|
case 2:
|
||||||
@@ -762,6 +799,8 @@ static int nfs_init_server(struct nfs_server *server,
|
|||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
nfs_server_set_init_caps(server);
|
||||||
|
|
||||||
/* Preserve the values of mount_server-related mount options */
|
/* Preserve the values of mount_server-related mount options */
|
||||||
if (ctx->mount_server.addrlen) {
|
if (ctx->mount_server.addrlen) {
|
||||||
memcpy(&server->mountd_address, &ctx->mount_server.address,
|
memcpy(&server->mountd_address, &ctx->mount_server.address,
|
||||||
@@ -934,7 +973,6 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
|
|||||||
target->acregmax = source->acregmax;
|
target->acregmax = source->acregmax;
|
||||||
target->acdirmin = source->acdirmin;
|
target->acdirmin = source->acdirmin;
|
||||||
target->acdirmax = source->acdirmax;
|
target->acdirmax = source->acdirmax;
|
||||||
target->caps = source->caps;
|
|
||||||
target->options = source->options;
|
target->options = source->options;
|
||||||
target->auth_info = source->auth_info;
|
target->auth_info = source->auth_info;
|
||||||
target->port = source->port;
|
target->port = source->port;
|
||||||
@@ -1169,6 +1207,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
|
|||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto out_free_server;
|
goto out_free_server;
|
||||||
|
|
||||||
|
nfs_server_set_init_caps(server);
|
||||||
|
|
||||||
/* probe the filesystem info for this server filesystem */
|
/* probe the filesystem info for this server filesystem */
|
||||||
error = nfs_probe_server(server, fh);
|
error = nfs_probe_server(server, fh);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ extern struct nfs_client *
|
|||||||
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
||||||
struct nfs4_sessionid *, u32);
|
struct nfs4_sessionid *, u32);
|
||||||
extern struct nfs_server *nfs_create_server(struct fs_context *);
|
extern struct nfs_server *nfs_create_server(struct fs_context *);
|
||||||
extern void nfs4_server_set_init_caps(struct nfs_server *);
|
extern void nfs_server_set_init_caps(struct nfs_server *);
|
||||||
extern struct nfs_server *nfs4_create_server(struct fs_context *);
|
extern struct nfs_server *nfs4_create_server(struct fs_context *);
|
||||||
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
|
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
|
||||||
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
||||||
|
|||||||
@@ -1074,24 +1074,6 @@ static void nfs4_session_limit_xasize(struct nfs_server *server)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfs4_server_set_init_caps(struct nfs_server *server)
|
|
||||||
{
|
|
||||||
/* Set the basic capabilities */
|
|
||||||
server->caps |= server->nfs_client->cl_mvops->init_caps;
|
|
||||||
if (server->flags & NFS_MOUNT_NORDIRPLUS)
|
|
||||||
server->caps &= ~NFS_CAP_READDIRPLUS;
|
|
||||||
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
|
|
||||||
server->caps &= ~NFS_CAP_READ_PLUS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
|
|
||||||
* authentication.
|
|
||||||
*/
|
|
||||||
if (nfs4_disable_idmapping &&
|
|
||||||
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
|
|
||||||
server->caps |= NFS_CAP_UIDGID_NOMAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nfs4_server_common_setup(struct nfs_server *server,
|
static int nfs4_server_common_setup(struct nfs_server *server,
|
||||||
struct nfs_fh *mntfh, bool auth_probe)
|
struct nfs_fh *mntfh, bool auth_probe)
|
||||||
{
|
{
|
||||||
@@ -1110,7 +1092,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
|
|||||||
if (error < 0)
|
if (error < 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
nfs4_server_set_init_caps(server);
|
nfs_server_set_init_caps(server);
|
||||||
|
|
||||||
/* Probe the root fh to retrieve its FSID and filehandle */
|
/* Probe the root fh to retrieve its FSID and filehandle */
|
||||||
error = nfs4_get_rootfh(server, mntfh, auth_probe);
|
error = nfs4_get_rootfh(server, mntfh, auth_probe);
|
||||||
|
|||||||
@@ -4092,7 +4092,7 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
|
|||||||
};
|
};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
nfs4_server_set_init_caps(server);
|
nfs_server_set_init_caps(server);
|
||||||
do {
|
do {
|
||||||
err = nfs4_handle_exception(server,
|
err = nfs4_handle_exception(server,
|
||||||
_nfs4_server_capabilities(server, fhandle),
|
_nfs4_server_capabilities(server, fhandle),
|
||||||
|
|||||||
Reference in New Issue
Block a user