Commit 6a70f89c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-5.8-3' of git://git.linux-nfs.org/projects/anna/linux-nfs into master

Pull NFS client fixes from Anna Schumaker:
 "A few more NFS client bugfixes for Linux 5.8:

  NFS:
   - Fix interrupted slots by using the SEQUENCE operation

  SUNRPC:
   - revert d03727b2 to fix unkillable IOs

  xprtrdma:
   - Fix double-free in rpcrdma_ep_create()
   - Fix recursion into rpcrdma_xprt_disconnect()
   - Fix return code from rpcrdma_xprt_connect()
   - Fix handling of connect errors
   - Fix incorrect header size calculations"

* tag 'nfs-for-5.8-3' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  SUNRPC reverting d03727b2 ("NFSv4 fix CLOSE not waiting for direct IO compeletion")
  xprtrdma: fix incorrect header size calculations
  NFS: Fix interrupted slots by sending a solo SEQUENCE operation
  xprtrdma: Fix handling of connect errors
  xprtrdma: Fix return code from rpcrdma_xprt_connect()
  xprtrdma: Fix recursion into rpcrdma_xprt_disconnect()
  xprtrdma: Fix double-free in rpcrdma_ep_create()
parents 630c183b 65caafd0
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
@@ -267,6 +267,8 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)
{
	struct inode *inode = dreq->inode;

	inode_dio_end(inode);

	if (dreq->iocb) {
		long res = (long) dreq->error;
		if (dreq->count != 0) {
@@ -278,10 +280,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)

	complete(&dreq->completion);

	igrab(inode);
	nfs_direct_req_release(dreq);
	inode_dio_end(inode);
	iput(inode);
}

static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
@@ -411,10 +410,8 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
	 * generic layer handle the completion.
	 */
	if (requested_bytes == 0) {
		igrab(inode);
		nfs_direct_req_release(dreq);
		inode_dio_end(inode);
		iput(inode);
		nfs_direct_req_release(dreq);
		return result < 0 ? result : -EIO;
	}

@@ -867,10 +864,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
	 * generic layer handle the completion.
	 */
	if (requested_bytes == 0) {
		igrab(inode);
		nfs_direct_req_release(dreq);
		inode_dio_end(inode);
		iput(inode);
		nfs_direct_req_release(dreq);
		return result < 0 ? result : -EIO;
	}

+0 −1
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ nfs_file_release(struct inode *inode, struct file *filp)
	dprintk("NFS: release(%pD2)\n", filp);

	nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
	inode_dio_wait(inode);
	nfs_file_clear_open_context(filp);
	return 0;
}
+18 −2
Original line number Diff line number Diff line
@@ -774,6 +774,14 @@ static void nfs4_slot_sequence_acked(struct nfs4_slot *slot,
	slot->seq_nr_last_acked = seqnr;
}

static void nfs4_probe_sequence(struct nfs_client *client, const struct cred *cred,
				struct nfs4_slot *slot)
{
	struct rpc_task *task = _nfs41_proc_sequence(client, cred, slot, true);
	if (!IS_ERR(task))
		rpc_put_task_async(task);
}

static int nfs41_sequence_process(struct rpc_task *task,
		struct nfs4_sequence_res *res)
{
@@ -790,6 +798,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
		goto out;

	session = slot->table->session;
	clp = session->clp;

	trace_nfs4_sequence_done(session, res);

@@ -804,7 +813,6 @@ static int nfs41_sequence_process(struct rpc_task *task,
		nfs4_slot_sequence_acked(slot, slot->seq_nr);
		/* Update the slot's sequence and clientid lease timer */
		slot->seq_done = 1;
		clp = session->clp;
		do_renew_lease(clp, res->sr_timestamp);
		/* Check sequence flags */
		nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags,
@@ -852,10 +860,18 @@ static int nfs41_sequence_process(struct rpc_task *task,
		/*
		 * Were one or more calls using this slot interrupted?
		 * If the server never received the request, then our
		 * transmitted slot sequence number may be too high.
		 * transmitted slot sequence number may be too high. However,
		 * if the server did receive the request then it might
		 * accidentally give us a reply with a mismatched operation.
		 * We can sort this out by sending a lone sequence operation
		 * to the server on the same slot.
		 */
		if ((s32)(slot->seq_nr - slot->seq_nr_last_acked) > 1) {
			slot->seq_nr--;
			if (task->tk_msg.rpc_proc != &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE]) {
				nfs4_probe_sequence(clp, task->tk_msg.rpc_cred, slot);
				res->sr_slot = NULL;
			}
			goto retry_nowait;
		}
		/*
+2 −2
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ static unsigned int rpcrdma_max_call_header_size(unsigned int maxsegs)
	size = RPCRDMA_HDRLEN_MIN;

	/* Maximum Read list size */
	size = maxsegs * rpcrdma_readchunk_maxsz * sizeof(__be32);
	size += maxsegs * rpcrdma_readchunk_maxsz * sizeof(__be32);

	/* Minimal Read chunk size */
	size += sizeof(__be32);	/* segment count */
@@ -94,7 +94,7 @@ static unsigned int rpcrdma_max_reply_header_size(unsigned int maxsegs)
	size = RPCRDMA_HDRLEN_MIN;

	/* Maximum Write list size */
	size = sizeof(__be32);		/* segment count */
	size += sizeof(__be32);		/* segment count */
	size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32);
	size += sizeof(__be32);	/* list discriminator */

+5 −0
Original line number Diff line number Diff line
@@ -249,6 +249,11 @@ xprt_rdma_connect_worker(struct work_struct *work)
					   xprt->stat.connect_start;
		xprt_set_connected(xprt);
		rc = -EAGAIN;
	} else {
		/* Force a call to xprt_rdma_close to clean up */
		spin_lock(&xprt->transport_lock);
		set_bit(XPRT_CLOSE_WAIT, &xprt->state);
		spin_unlock(&xprt->transport_lock);
	}
	xprt_wake_pending_tasks(xprt, rc);
}
Loading