Skip to content

Commit dfab92f

Browse files
committed
Merge tag 'nfs-for-6.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Stable fixes and other bugfixes: - nfs: don't report STATX_BTIME in ->getattr - Revert 'NFSv4: Retry LOCK on OLD_STATEID during delegation return' since it breaks NFSv4 state recovery. - NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION - Fix the NFSv4.2 xattr cache shrinker_id - Force a ctime update after a NFSv4.2 SETXATTR call Features and cleanups: - NFS and RPC over TLS client code from Chuck Lever - Support for use of abstract unix socket addresses with the rpcbind daemon - Sysfs API to allow shutdown of the kernel RPC client and prevent umount() hangs if the server is known to be permanently down - XDR cleanups from Anna" * tag 'nfs-for-6.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (33 commits) Revert "NFSv4: Retry LOCK on OLD_STATEID during delegation return" NFS: Don't cleanup sysfs superblock entry if uninitialized nfs: don't report STATX_BTIME in ->getattr NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION NFSv4.2: fix wrong shrinker_id NFSv4: Clean up some shutdown loops NFS: Cancel all existing RPC tasks when shutdown NFS: add sysfs shutdown knob NFS: add a sysfs link to the acl rpc_client NFS: add a sysfs link to the lockd rpc_client NFS: Add sysfs links to sunrpc clients for nfs_clients NFS: add superblock sysfs entries NFS: Make all of /sys/fs/nfs network-namespace unique NFS: Open-code the nfs_kset kset_create_and_add() NFS: rename nfs_client_kobj to nfs_net_kobj NFS: rename nfs_client_kset to nfs_kset NFS: Add an "xprtsec=" NFS mount option NFS: Have struct nfs_client carry a TLS policy field SUNRPC: Add a TCP-with-TLS RPC transport class SUNRPC: Capture CMSG metadata on client-side receive ...
2 parents f8566aa + 5b4a82a commit dfab92f

31 files changed

+1566
-435
lines changed

fs/lockd/clntlock.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ void nlmclnt_prepare_block(struct nlm_wait *block, struct nlm_host *host, struct
9393
block->b_status = nlm_lck_blocked;
9494
}
9595

96+
struct rpc_clnt *nlmclnt_rpc_clnt(struct nlm_host *host)
97+
{
98+
return host->h_rpcclnt;
99+
}
100+
EXPORT_SYMBOL_GPL(nlmclnt_rpc_clnt);
101+
96102
/*
97103
* Queue up a lock for blocking so that the GRANTED request can see it
98104
*/

fs/nfs/client.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
184184
clp->cl_net = get_net(cl_init->net);
185185

186186
clp->cl_principal = "*";
187+
clp->cl_xprtsec = cl_init->xprtsec;
187188
return clp;
188189

189190
error_cleanup:
@@ -326,6 +327,10 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
326327
sap))
327328
continue;
328329

330+
/* Match the xprt security policy */
331+
if (clp->cl_xprtsec.policy != data->xprtsec.policy)
332+
continue;
333+
329334
refcount_inc(&clp->cl_count);
330335
return clp;
331336
}
@@ -458,6 +463,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
458463

459464
switch (proto) {
460465
case XPRT_TRANSPORT_TCP:
466+
case XPRT_TRANSPORT_TCP_TLS:
461467
case XPRT_TRANSPORT_RDMA:
462468
if (retrans == NFS_UNSPEC_RETRANS)
463469
to->to_retries = NFS_DEF_TCP_RETRANS;
@@ -510,6 +516,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
510516
.version = clp->rpc_ops->version,
511517
.authflavor = flavor,
512518
.cred = cl_init->cred,
519+
.xprtsec = cl_init->xprtsec,
513520
};
514521

515522
if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
@@ -592,6 +599,7 @@ static int nfs_start_lockd(struct nfs_server *server)
592599

593600
server->nlm_host = host;
594601
server->destroy = nfs_destroy_server;
602+
nfs_sysfs_link_rpc_client(server, nlmclnt_rpc_clnt(host), NULL);
595603
return 0;
596604
}
597605

@@ -621,6 +629,7 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
621629
if (server->flags & NFS_MOUNT_SOFT)
622630
server->client->cl_softrtry = 1;
623631

632+
nfs_sysfs_link_rpc_client(server, server->client, NULL);
624633
return 0;
625634
}
626635
EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
@@ -675,6 +684,7 @@ static int nfs_init_server(struct nfs_server *server,
675684
.cred = server->cred,
676685
.nconnect = ctx->nfs_server.nconnect,
677686
.init_flags = (1UL << NFS_CS_REUSEPORT),
687+
.xprtsec = ctx->xprtsec,
678688
};
679689
struct nfs_client *clp;
680690
int error;
@@ -690,6 +700,8 @@ static int nfs_init_server(struct nfs_server *server,
690700
return PTR_ERR(clp);
691701

692702
server->nfs_client = clp;
703+
nfs_sysfs_add_server(server);
704+
nfs_sysfs_link_rpc_client(server, clp->cl_rpcclient, "_state");
693705

694706
/* Initialise the client representation from the mount data */
695707
server->flags = ctx->flags;
@@ -944,6 +956,8 @@ void nfs_server_remove_lists(struct nfs_server *server)
944956
}
945957
EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
946958

959+
static DEFINE_IDA(s_sysfs_ids);
960+
947961
/*
948962
* Allocate and initialise a server record
949963
*/
@@ -955,6 +969,12 @@ struct nfs_server *nfs_alloc_server(void)
955969
if (!server)
956970
return NULL;
957971

972+
server->s_sysfs_id = ida_alloc(&s_sysfs_ids, GFP_KERNEL);
973+
if (server->s_sysfs_id < 0) {
974+
kfree(server);
975+
return NULL;
976+
}
977+
958978
server->client = server->client_acl = ERR_PTR(-EINVAL);
959979

960980
/* Zero out the NFS state stuff */
@@ -1001,6 +1021,12 @@ void nfs_free_server(struct nfs_server *server)
10011021

10021022
nfs_put_client(server->nfs_client);
10031023

1024+
if (server->kobj.state_initialized) {
1025+
nfs_sysfs_remove_server(server);
1026+
kobject_put(&server->kobj);
1027+
}
1028+
ida_free(&s_sysfs_ids, server->s_sysfs_id);
1029+
10041030
ida_destroy(&server->lockowner_id);
10051031
ida_destroy(&server->openowner_id);
10061032
nfs_free_iostats(server->io_stats);
@@ -1102,6 +1128,11 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
11021128

11031129
server->fsid = fattr->fsid;
11041130

1131+
nfs_sysfs_add_server(server);
1132+
1133+
nfs_sysfs_link_rpc_client(server,
1134+
server->nfs_client->cl_rpcclient, "_state");
1135+
11051136
error = nfs_init_server_rpcclient(server,
11061137
source->client->cl_timeout,
11071138
flavor);
@@ -1385,6 +1416,7 @@ int __init nfs_fs_proc_init(void)
13851416
void nfs_fs_proc_exit(void)
13861417
{
13871418
remove_proc_subtree("fs/nfsfs", NULL);
1419+
ida_destroy(&s_sysfs_ids);
13881420
}
13891421

13901422
#endif /* CONFIG_PROC_FS */

fs/nfs/fs_context.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include <linux/nfs_fs.h>
1919
#include <linux/nfs_mount.h>
2020
#include <linux/nfs4_mount.h>
21+
22+
#include <net/handshake.h>
23+
2124
#include "nfs.h"
2225
#include "internal.h"
2326

@@ -88,6 +91,7 @@ enum nfs_param {
8891
Opt_vers,
8992
Opt_wsize,
9093
Opt_write,
94+
Opt_xprtsec,
9195
};
9296

9397
enum {
@@ -194,6 +198,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
194198
fsparam_string("vers", Opt_vers),
195199
fsparam_enum ("write", Opt_write, nfs_param_enums_write),
196200
fsparam_u32 ("wsize", Opt_wsize),
201+
fsparam_string("xprtsec", Opt_xprtsec),
197202
{}
198203
};
199204

@@ -267,6 +272,20 @@ static const struct constant_table nfs_secflavor_tokens[] = {
267272
{}
268273
};
269274

275+
enum {
276+
Opt_xprtsec_none,
277+
Opt_xprtsec_tls,
278+
Opt_xprtsec_mtls,
279+
nr__Opt_xprtsec
280+
};
281+
282+
static const struct constant_table nfs_xprtsec_policies[] = {
283+
{ "none", Opt_xprtsec_none },
284+
{ "tls", Opt_xprtsec_tls },
285+
{ "mtls", Opt_xprtsec_mtls },
286+
{}
287+
};
288+
270289
/*
271290
* Sanity-check a server address provided by the mount command.
272291
*
@@ -320,9 +339,21 @@ static int nfs_validate_transport_protocol(struct fs_context *fc,
320339
default:
321340
ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
322341
}
342+
343+
if (ctx->xprtsec.policy != RPC_XPRTSEC_NONE)
344+
switch (ctx->nfs_server.protocol) {
345+
case XPRT_TRANSPORT_TCP:
346+
ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP_TLS;
347+
break;
348+
default:
349+
goto out_invalid_xprtsec_policy;
350+
}
351+
323352
return 0;
324353
out_invalid_transport_udp:
325354
return nfs_invalf(fc, "NFS: Unsupported transport protocol udp");
355+
out_invalid_xprtsec_policy:
356+
return nfs_invalf(fc, "NFS: Transport does not support xprtsec");
326357
}
327358

328359
/*
@@ -430,6 +461,29 @@ static int nfs_parse_security_flavors(struct fs_context *fc,
430461
return 0;
431462
}
432463

464+
static int nfs_parse_xprtsec_policy(struct fs_context *fc,
465+
struct fs_parameter *param)
466+
{
467+
struct nfs_fs_context *ctx = nfs_fc2context(fc);
468+
469+
trace_nfs_mount_assign(param->key, param->string);
470+
471+
switch (lookup_constant(nfs_xprtsec_policies, param->string, -1)) {
472+
case Opt_xprtsec_none:
473+
ctx->xprtsec.policy = RPC_XPRTSEC_NONE;
474+
break;
475+
case Opt_xprtsec_tls:
476+
ctx->xprtsec.policy = RPC_XPRTSEC_TLS_ANON;
477+
break;
478+
case Opt_xprtsec_mtls:
479+
ctx->xprtsec.policy = RPC_XPRTSEC_TLS_X509;
480+
break;
481+
default:
482+
return nfs_invalf(fc, "NFS: Unrecognized transport security policy");
483+
}
484+
return 0;
485+
}
486+
433487
static int nfs_parse_version_string(struct fs_context *fc,
434488
const char *string)
435489
{
@@ -696,6 +750,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
696750
if (ret < 0)
697751
return ret;
698752
break;
753+
case Opt_xprtsec:
754+
ret = nfs_parse_xprtsec_policy(fc, param);
755+
if (ret < 0)
756+
return ret;
757+
break;
699758

700759
case Opt_proto:
701760
if (!param->string)
@@ -791,16 +850,19 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
791850
ctx->mount_server.addrlen = len;
792851
break;
793852
case Opt_nconnect:
853+
trace_nfs_mount_assign(param->key, param->string);
794854
if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS)
795855
goto out_of_bounds;
796856
ctx->nfs_server.nconnect = result.uint_32;
797857
break;
798858
case Opt_max_connect:
859+
trace_nfs_mount_assign(param->key, param->string);
799860
if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_TRANSPORTS)
800861
goto out_of_bounds;
801862
ctx->nfs_server.max_connect = result.uint_32;
802863
break;
803864
case Opt_lookupcache:
865+
trace_nfs_mount_assign(param->key, param->string);
804866
switch (result.uint_32) {
805867
case Opt_lookupcache_all:
806868
ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
@@ -817,6 +879,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
817879
}
818880
break;
819881
case Opt_local_lock:
882+
trace_nfs_mount_assign(param->key, param->string);
820883
switch (result.uint_32) {
821884
case Opt_local_lock_all:
822885
ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK |
@@ -837,6 +900,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
837900
}
838901
break;
839902
case Opt_write:
903+
trace_nfs_mount_assign(param->key, param->string);
840904
switch (result.uint_32) {
841905
case Opt_write_lazy:
842906
ctx->flags &=
@@ -1569,6 +1633,9 @@ static int nfs_init_fs_context(struct fs_context *fc)
15691633
ctx->selected_flavor = RPC_AUTH_MAXFLAVOR;
15701634
ctx->minorversion = 0;
15711635
ctx->need_mount = true;
1636+
ctx->xprtsec.policy = RPC_XPRTSEC_NONE;
1637+
ctx->xprtsec.cert_serial = TLS_NO_CERT;
1638+
ctx->xprtsec.privkey_serial = TLS_NO_PRIVKEY;
15721639

15731640
fc->s_iflags |= SB_I_STABLE_WRITES;
15741641
}

fs/nfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
845845

846846
request_mask &= STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_UID |
847847
STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME |
848-
STATX_INO | STATX_SIZE | STATX_BLOCKS | STATX_BTIME |
848+
STATX_INO | STATX_SIZE | STATX_BLOCKS |
849849
STATX_CHANGE_COOKIE;
850850

851851
if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {

fs/nfs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct nfs_client_initdata {
8181
struct net *net;
8282
const struct rpc_timeout *timeparms;
8383
const struct cred *cred;
84+
struct xprtsec_parms xprtsec;
8485
};
8586

8687
/*
@@ -101,6 +102,7 @@ struct nfs_fs_context {
101102
unsigned int bsize;
102103
struct nfs_auth_info auth_info;
103104
rpc_authflavor_t selected_flavor;
105+
struct xprtsec_parms xprtsec;
104106
char *client_address;
105107
unsigned int version;
106108
unsigned int minorversion;

fs/nfs/nfs3client.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <linux/sunrpc/addr.h>
55
#include "internal.h"
66
#include "nfs3_fs.h"
7+
#include "netns.h"
8+
#include "sysfs.h"
79

810
#ifdef CONFIG_NFS_V3_ACL
911
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
@@ -31,6 +33,8 @@ static void nfs_init_server_aclclient(struct nfs_server *server)
3133
if (IS_ERR(server->client_acl))
3234
goto out_noacl;
3335

36+
nfs_sysfs_link_rpc_client(server, server->client_acl, NULL);
37+
3438
/* No errors! Assume that Sun nfsacls are supported */
3539
server->caps |= NFS_CAP_ACLS;
3640
return;
@@ -93,6 +97,7 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
9397
.net = mds_clp->cl_net,
9498
.timeparms = &ds_timeout,
9599
.cred = mds_srv->cred,
100+
.xprtsec = mds_clp->cl_xprtsec,
96101
};
97102
struct nfs_client *clp;
98103
char buf[INET6_ADDRSTRLEN + 1];
@@ -102,8 +107,12 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
102107
return ERR_PTR(-EINVAL);
103108
cl_init.hostname = buf;
104109

105-
if (mds_clp->cl_nconnect > 1 && ds_proto == XPRT_TRANSPORT_TCP)
106-
cl_init.nconnect = mds_clp->cl_nconnect;
110+
switch (ds_proto) {
111+
case XPRT_TRANSPORT_TCP:
112+
case XPRT_TRANSPORT_TCP_TLS:
113+
if (mds_clp->cl_nconnect > 1)
114+
cl_init.nconnect = mds_clp->cl_nconnect;
115+
}
107116

108117
if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
109118
__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);

0 commit comments

Comments
 (0)