Commit b0efca46 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client fixes from Anna Schumaker:
 "These are mostly fixes for SUNRPC bugs, with a single v4.2
  copy_file_range() fix mixed in.

  Stable bugfixes:
   - Fix TCP receive code on archs with flush_dcache_page()

  Other bugfixes:
   - Fix error code in rpcrdma_buffer_create()
   - Fix a double free in rpcrdma_send_ctxs_create()
   - Fix kernel BUG at kernel/cred.c:825
   - Fix unnecessary retry in nfs42_proc_copy_file_range()
   - Ensure rq_bytes_sent is reset before request transmission
   - Ensure we respect the RPCSEC_GSS sequence number limit
   - Address Kerberos performance/behavior regression"

* tag 'nfs-for-5.0-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  SUNRPC: Address Kerberos performance/behavior regression
  SUNRPC: Ensure we respect the RPCSEC_GSS sequence number limit
  SUNRPC: Ensure rq_bytes_sent is reset before request transmission
  NFSv4.2 fix unnecessary retry in nfs4_copy_file_range
  sunrpc: kernel BUG at kernel/cred.c:825!
  SUNRPC: Fix TCP receive code on archs with flush_dcache_page()
  xprtrdma: Double free in rpcrdma_sendctxs_create()
  xprtrdma: Fix error code in rpcrdma_buffer_create()
parents 4d5f6e02 deaa5c96
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -133,15 +133,9 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
				    struct file *file_out, loff_t pos_out,
				    size_t count, unsigned int flags)
{
	ssize_t ret;

	if (file_inode(file_in) == file_inode(file_out))
		return -EINVAL;
retry:
	ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
	if (ret == -EAGAIN)
		goto retry;
	return ret;
	return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
}

static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@ static unsigned long number_cred_unused;

static struct cred machine_cred = {
	.usage = ATOMIC_INIT(1),
#ifdef CONFIG_DEBUG_CREDENTIALS
	.magic = CRED_MAGIC,
#endif
};

/*
+9 −3
Original line number Diff line number Diff line
@@ -1549,8 +1549,10 @@ gss_marshal(struct rpc_task *task, __be32 *p)
	cred_len = p++;

	spin_lock(&ctx->gc_seq_lock);
	req->rq_seqno = ctx->gc_seq++;
	req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ;
	spin_unlock(&ctx->gc_seq_lock);
	if (req->rq_seqno == MAXSEQ)
		goto out_expired;

	*p++ = htonl((u32) RPC_GSS_VERSION);
	*p++ = htonl((u32) ctx->gc_proc);
@@ -1572,14 +1574,18 @@ gss_marshal(struct rpc_task *task, __be32 *p)
	mic.data = (u8 *)(p + 1);
	maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
	if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
		clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
		goto out_expired;
	} else if (maj_stat != 0) {
		printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
		pr_warn("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
		task->tk_status = -EIO;
		goto out_put_ctx;
	}
	p = xdr_encode_opaque(p, NULL, mic.len);
	gss_put_ctx(ctx);
	return p;
out_expired:
	clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
	task->tk_status = -EKEYEXPIRED;
out_put_ctx:
	gss_put_ctx(ctx);
	return NULL;
+12 −8
Original line number Diff line number Diff line
@@ -1739,14 +1739,10 @@ rpc_xdr_encode(struct rpc_task *task)
	xdr_buf_init(&req->rq_rcv_buf,
		     req->rq_rbuffer,
		     req->rq_rcvsize);
	req->rq_bytes_sent = 0;

	p = rpc_encode_header(task);
	if (p == NULL) {
		printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n");
		rpc_exit(task, -EIO);
	if (p == NULL)
		return;
	}

	encode = task->tk_msg.rpc_proc->p_encode;
	if (encode == NULL)
@@ -1771,10 +1767,17 @@ call_encode(struct rpc_task *task)
	/* Did the encode result in an error condition? */
	if (task->tk_status != 0) {
		/* Was the error nonfatal? */
		if (task->tk_status == -EAGAIN || task->tk_status == -ENOMEM)
		switch (task->tk_status) {
		case -EAGAIN:
		case -ENOMEM:
			rpc_delay(task, HZ >> 4);
		else
			break;
		case -EKEYEXPIRED:
			task->tk_action = call_refresh;
			break;
		default:
			rpc_exit(task, task->tk_status);
		}
		return;
	}

@@ -2336,6 +2339,7 @@ rpc_encode_header(struct rpc_task *task)
	*p++ = htonl(clnt->cl_vers);	/* program version */
	*p++ = htonl(task->tk_msg.rpc_proc->p_proc);	/* procedure */
	p = rpcauth_marshcred(task, p);
	if (p)
		req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
	return p;
}
+2 −1
Original line number Diff line number Diff line
@@ -1151,6 +1151,7 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
	struct rpc_xprt *xprt = req->rq_xprt;

	if (xprt_request_need_enqueue_transmit(task, req)) {
		req->rq_bytes_sent = 0;
		spin_lock(&xprt->queue_lock);
		/*
		 * Requests that carry congestion control credits are added
@@ -1177,7 +1178,7 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
				INIT_LIST_HEAD(&req->rq_xmit2);
				goto out;
			}
		} else {
		} else if (!req->rq_seqno) {
			list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
				if (pos->rq_task->tk_owner != task->tk_owner)
					continue;
Loading