Skip to content

Commit b01f21c

Browse files
author
Trond Myklebust
committed
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: 54ceac4 ("NFS: Share NFS superblocks per-protocol per-server per-FSID") Cc: [email protected] Reviewed-by: Benjamin Coddington <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent cc5d590 commit b01f21c

File tree

4 files changed

+45
-23
lines changed

4 files changed

+45
-23
lines changed

fs/nfs/client.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,44 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
682682
}
683683
EXPORT_SYMBOL_GPL(nfs_init_client);
684684

685+
static void nfs4_server_set_init_caps(struct nfs_server *server)
686+
{
687+
#if IS_ENABLED(CONFIG_NFS_V4)
688+
/* Set the basic capabilities */
689+
server->caps = server->nfs_client->cl_mvops->init_caps;
690+
if (server->flags & NFS_MOUNT_NORDIRPLUS)
691+
server->caps &= ~NFS_CAP_READDIRPLUS;
692+
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
693+
server->caps &= ~NFS_CAP_READ_PLUS;
694+
695+
/*
696+
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
697+
* authentication.
698+
*/
699+
if (nfs4_disable_idmapping &&
700+
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
701+
server->caps |= NFS_CAP_UIDGID_NOMAP;
702+
#endif
703+
}
704+
705+
void nfs_server_set_init_caps(struct nfs_server *server)
706+
{
707+
switch (server->nfs_client->rpc_ops->version) {
708+
case 2:
709+
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
710+
break;
711+
case 3:
712+
server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
713+
if (!(server->flags & NFS_MOUNT_NORDIRPLUS))
714+
server->caps |= NFS_CAP_READDIRPLUS;
715+
break;
716+
default:
717+
nfs4_server_set_init_caps(server);
718+
break;
719+
}
720+
}
721+
EXPORT_SYMBOL_GPL(nfs_server_set_init_caps);
722+
685723
/*
686724
* Create a version 2 or 3 client
687725
*/
@@ -726,7 +764,6 @@ static int nfs_init_server(struct nfs_server *server,
726764
/* Initialise the client representation from the mount data */
727765
server->flags = ctx->flags;
728766
server->options = ctx->options;
729-
server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
730767

731768
switch (clp->rpc_ops->version) {
732769
case 2:
@@ -762,6 +799,8 @@ static int nfs_init_server(struct nfs_server *server,
762799
if (error < 0)
763800
goto error;
764801

802+
nfs_server_set_init_caps(server);
803+
765804
/* Preserve the values of mount_server-related mount options */
766805
if (ctx->mount_server.addrlen) {
767806
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
934973
target->acregmax = source->acregmax;
935974
target->acdirmin = source->acdirmin;
936975
target->acdirmax = source->acdirmax;
937-
target->caps = source->caps;
938976
target->options = source->options;
939977
target->auth_info = source->auth_info;
940978
target->port = source->port;
@@ -1169,6 +1207,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
11691207
if (error < 0)
11701208
goto out_free_server;
11711209

1210+
nfs_server_set_init_caps(server);
1211+
11721212
/* probe the filesystem info for this server filesystem */
11731213
error = nfs_probe_server(server, fh);
11741214
if (error < 0)

fs/nfs/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ extern struct nfs_client *
231231
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
232232
struct nfs4_sessionid *, u32);
233233
extern struct nfs_server *nfs_create_server(struct fs_context *);
234-
extern void nfs4_server_set_init_caps(struct nfs_server *);
234+
extern void nfs_server_set_init_caps(struct nfs_server *);
235235
extern struct nfs_server *nfs4_create_server(struct fs_context *);
236236
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
237237
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,

fs/nfs/nfs4client.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,24 +1074,6 @@ static void nfs4_session_limit_xasize(struct nfs_server *server)
10741074
#endif
10751075
}
10761076

1077-
void nfs4_server_set_init_caps(struct nfs_server *server)
1078-
{
1079-
/* Set the basic capabilities */
1080-
server->caps |= server->nfs_client->cl_mvops->init_caps;
1081-
if (server->flags & NFS_MOUNT_NORDIRPLUS)
1082-
server->caps &= ~NFS_CAP_READDIRPLUS;
1083-
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
1084-
server->caps &= ~NFS_CAP_READ_PLUS;
1085-
1086-
/*
1087-
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
1088-
* authentication.
1089-
*/
1090-
if (nfs4_disable_idmapping &&
1091-
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
1092-
server->caps |= NFS_CAP_UIDGID_NOMAP;
1093-
}
1094-
10951077
static int nfs4_server_common_setup(struct nfs_server *server,
10961078
struct nfs_fh *mntfh, bool auth_probe)
10971079
{
@@ -1110,7 +1092,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
11101092
if (error < 0)
11111093
return error;
11121094

1113-
nfs4_server_set_init_caps(server);
1095+
nfs_server_set_init_caps(server);
11141096

11151097
/* Probe the root fh to retrieve its FSID and filehandle */
11161098
error = nfs4_get_rootfh(server, mntfh, auth_probe);

fs/nfs/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4092,7 +4092,7 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
40924092
};
40934093
int err;
40944094

4095-
nfs4_server_set_init_caps(server);
4095+
nfs_server_set_init_caps(server);
40964096
do {
40974097
err = nfs4_handle_exception(server,
40984098
_nfs4_server_capabilities(server, fhandle),

0 commit comments

Comments
 (0)