Commit 0961f0c0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-5.15-1' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client updates from Anna Schumaker:
 "New Features:
   - Better client responsiveness when server isn't replying
   - Use refcount_t in sunrpc rpc_client refcount tracking
   - Add srcaddr and dst_port to the sunrpc sysfs info files
   - Add basic support for connection sharing between servers with multiple NICs`

  Bugfixes and Cleanups:
   - Sunrpc tracepoint cleanups
   - Disconnect after ib_post_send() errors to avoid deadlocks
   - Fix for tearing down rpcrdma_reps
   - Fix a potential pNFS layoutget livelock loop
   - pNFS layout barrier fixes
   - Fix a potential memory corruption in rpc_wake_up_queued_task_set_status()
   - Fix reconnection locking
   - Fix return value of get_srcport()
   - Remove rpcrdma_post_sends()
   - Remove pNFS dead code
   - Remove copy size restriction for inter-server copies
   - Overhaul the NFS callback service
   - Clean up sunrpc TCP socket shutdowns
   - Always provide aligned buffers to RPC read layers"

* tag 'nfs-for-5.15-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (39 commits)
  NFS: Always provide aligned buffers to the RPC read layers
  NFSv4.1 add network transport when session trunking is detected
  SUNRPC enforce creation of no more than max_connect xprts
  NFSv4 introduce max_connect mount options
  SUNRPC add xps_nunique_destaddr_xprts to xprt_switch_info in sysfs
  SUNRPC keep track of number of transports to unique addresses
  NFSv3: Delete duplicate judgement in nfs3_async_handle_jukebox
  SUNRPC: Tweak TCP socket shutdown in the RPC client
  SUNRPC: Simplify socket shutdown when not reusing TCP ports
  NFSv4.2: remove restriction of copy size for inter-server copy.
  NFS: Clean up the synopsis of callback process_op()
  NFS: Extract the xdr_init_encode/decode() calls from decode_compound
  NFS: Remove unused callback void decoder
  NFS: Add a private local dispatcher for NFSv4 callback operations
  SUNRPC: Eliminate the RQ_AUTHERR flag
  SUNRPC: Set rq_auth_stat in the pg_authenticate() callout
  SUNRPC: Add svc_rqst::rq_auth_stat
  SUNRPC: Add dst_port to the sysfs xprt info file
  SUNRPC: Add srcaddr as a file in sysfs
  sunrpc: Fix return value of get_srcport()
  ...
parents f1583cb1 8cfb9015
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -649,6 +649,7 @@ static int lockd_authenticate(struct svc_rqst *rqstp)
	switch (rqstp->rq_authop->flavour) {
		case RPC_AUTH_NULL:
		case RPC_AUTH_UNIX:
			rqstp->rq_auth_stat = rpc_auth_ok;
			if (rqstp->rq_proc == 0)
				return SVC_OK;
			if (is_callback(rqstp->rq_proc)) {
@@ -659,6 +660,7 @@ static int lockd_authenticate(struct svc_rqst *rqstp)
			}
			return svc_set_client(rqstp);
	}
	rqstp->rq_auth_stat = rpc_autherr_badcred;
	return SVC_DENIED;
}

+4 −0
Original line number Diff line number Diff line
@@ -429,6 +429,8 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
 */
static int nfs_callback_authenticate(struct svc_rqst *rqstp)
{
	rqstp->rq_auth_stat = rpc_autherr_badcred;

	switch (rqstp->rq_authop->flavour) {
	case RPC_AUTH_NULL:
		if (rqstp->rq_proc != CB_NULL)
@@ -439,6 +441,8 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
		 if (svc_is_backchannel(rqstp))
			return SVC_DENIED;
	}

	rqstp->rq_auth_stat = rpc_auth_ok;
	return SVC_OK;
}

+32 −29
Original line number Diff line number Diff line
@@ -63,11 +63,10 @@ static __be32 nfs4_callback_null(struct svc_rqst *rqstp)
	return htonl(NFS4_OK);
}

static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p)
{
	return xdr_argsize_check(rqstp, p);
}

/*
 * svc_process_common() looks for an XDR encoder to know when
 * not to drop a Reply.
 */
static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p)
{
	return xdr_ressize_check(rqstp, p);
@@ -864,17 +863,16 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
}

static __be32 process_op(int nop, struct svc_rqst *rqstp,
		struct xdr_stream *xdr_in, void *argp,
		struct xdr_stream *xdr_out, void *resp,
			 struct cb_process_state *cps)
{
	struct xdr_stream *xdr_out = &rqstp->rq_res_stream;
	struct callback_op *op = &callback_ops[0];
	unsigned int op_nr;
	__be32 status;
	long maxlen;
	__be32 res;

	status = decode_op_hdr(xdr_in, &op_nr);
	status = decode_op_hdr(&rqstp->rq_arg_stream, &op_nr);
	if (unlikely(status))
		return status;

@@ -904,9 +902,11 @@ static __be32 process_op(int nop, struct svc_rqst *rqstp,

	maxlen = xdr_out->end - xdr_out->p;
	if (maxlen > 0 && maxlen < PAGE_SIZE) {
		status = op->decode_args(rqstp, xdr_in, argp);
		status = op->decode_args(rqstp, &rqstp->rq_arg_stream,
					 rqstp->rq_argp);
		if (likely(status == 0))
			status = op->process_op(argp, resp, cps);
			status = op->process_op(rqstp->rq_argp, rqstp->rq_resp,
						cps);
	} else
		status = htonl(NFS4ERR_RESOURCE);

@@ -915,7 +915,7 @@ static __be32 process_op(int nop, struct svc_rqst *rqstp,
	if (unlikely(res))
		return res;
	if (op->encode_res != NULL && status == 0)
		status = op->encode_res(rqstp, xdr_out, resp);
		status = op->encode_res(rqstp, xdr_out, rqstp->rq_resp);
	return status;
}

@@ -926,22 +926,15 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p, status;
	struct cb_process_state cps = {
		.drc_status = 0,
		.clp = NULL,
		.net = SVC_NET(rqstp),
	};
	unsigned int nops = 0;
	__be32 status;

	xdr_init_decode(&xdr_in, &rqstp->rq_arg,
			rqstp->rq_arg.head[0].iov_base, NULL);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p, NULL);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	status = decode_compound_hdr_arg(&rqstp->rq_arg_stream, &hdr_arg);
	if (status == htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

@@ -961,15 +954,13 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
	cps.minorversion = hdr_arg.minorversion;
	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) {
	if (encode_compound_hdr_res(&rqstp->rq_res_stream, &hdr_res) != 0) {
		if (cps.clp)
			nfs_put_client(cps.clp);
		return rpc_system_err;
	}
	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(nops, rqstp, &xdr_in,
				    rqstp->rq_argp, &xdr_out, rqstp->rq_resp,
				    &cps);
		status = process_op(nops, rqstp, &cps);
		nops++;
	}

@@ -988,7 +979,20 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)

out_invalidcred:
	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
	return svc_return_autherr(rqstp, rpc_autherr_badcred);
	rqstp->rq_auth_stat = rpc_autherr_badcred;
	return rpc_success;
}

static int
nfs_callback_dispatch(struct svc_rqst *rqstp, __be32 *statp)
{
	const struct svc_procedure *procp = rqstp->rq_procinfo;

	svcxdr_init_decode(rqstp);
	svcxdr_init_encode(rqstp);

	*statp = procp->pc_func(rqstp);
	return 1;
}

/*
@@ -1057,7 +1061,6 @@ static struct callback_op callback_ops[] = {
static const struct svc_procedure nfs4_callback_procedures1[] = {
	[CB_NULL] = {
		.pc_func = nfs4_callback_null,
		.pc_decode = nfs4_decode_void,
		.pc_encode = nfs4_encode_void,
		.pc_xdrressize = 1,
		.pc_name = "NULL",
@@ -1079,7 +1082,7 @@ const struct svc_version nfs4_callback_version1 = {
	.vs_proc = nfs4_callback_procedures1,
	.vs_count = nfs4_callback_count1,
	.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
	.vs_dispatch = NULL,
	.vs_dispatch = nfs_callback_dispatch,
	.vs_hidden = true,
	.vs_need_cong_ctrl = true,
};
@@ -1091,7 +1094,7 @@ const struct svc_version nfs4_callback_version4 = {
	.vs_proc = nfs4_callback_procedures1,
	.vs_count = nfs4_callback_count4,
	.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
	.vs_dispatch = NULL,
	.vs_dispatch = nfs_callback_dispatch,
	.vs_hidden = true,
	.vs_need_cong_ctrl = true,
};
+2 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)

	clp->cl_proto = cl_init->proto;
	clp->cl_nconnect = cl_init->nconnect;
	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
	clp->cl_net = get_net(cl_init->net);

	clp->cl_principal = "*";
@@ -540,6 +541,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,

	clnt->cl_principal = clp->cl_principal;
	clp->cl_rpcclient = clnt;
	clnt->cl_max_connect = clp->cl_max_connect;
	return 0;
}
EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
+7 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ enum nfs_param {
	Opt_mountvers,
	Opt_namelen,
	Opt_nconnect,
	Opt_max_connect,
	Opt_port,
	Opt_posix,
	Opt_proto,
@@ -158,6 +159,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
	fsparam_u32   ("mountvers",	Opt_mountvers),
	fsparam_u32   ("namlen",	Opt_namelen),
	fsparam_u32   ("nconnect",	Opt_nconnect),
	fsparam_u32   ("max_connect",	Opt_max_connect),
	fsparam_string("nfsvers",	Opt_vers),
	fsparam_u32   ("port",		Opt_port),
	fsparam_flag_no("posix",	Opt_posix),
@@ -770,6 +772,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
			goto out_of_bounds;
		ctx->nfs_server.nconnect = result.uint_32;
		break;
	case Opt_max_connect:
		if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_TRANSPORTS)
			goto out_of_bounds;
		ctx->nfs_server.max_connect = result.uint_32;
		break;
	case Opt_lookupcache:
		switch (result.uint_32) {
		case Opt_lookupcache_all:
Loading