Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 d03727b248d0 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 d03727b248d0 ("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()

+45 -33
+4 -9
fs/nfs/direct.c
··· 267 267 { 268 268 struct inode *inode = dreq->inode; 269 269 270 + inode_dio_end(inode); 271 + 270 272 if (dreq->iocb) { 271 273 long res = (long) dreq->error; 272 274 if (dreq->count != 0) { ··· 280 278 281 279 complete(&dreq->completion); 282 280 283 - igrab(inode); 284 281 nfs_direct_req_release(dreq); 285 - inode_dio_end(inode); 286 - iput(inode); 287 282 } 288 283 289 284 static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) ··· 410 411 * generic layer handle the completion. 411 412 */ 412 413 if (requested_bytes == 0) { 413 - igrab(inode); 414 - nfs_direct_req_release(dreq); 415 414 inode_dio_end(inode); 416 - iput(inode); 415 + nfs_direct_req_release(dreq); 417 416 return result < 0 ? result : -EIO; 418 417 } 419 418 ··· 864 867 * generic layer handle the completion. 865 868 */ 866 869 if (requested_bytes == 0) { 867 - igrab(inode); 868 - nfs_direct_req_release(dreq); 869 870 inode_dio_end(inode); 870 - iput(inode); 871 + nfs_direct_req_release(dreq); 871 872 return result < 0 ? result : -EIO; 872 873 } 873 874
-1
fs/nfs/file.c
··· 83 83 dprintk("NFS: release(%pD2)\n", filp); 84 84 85 85 nfs_inc_stats(inode, NFSIOS_VFSRELEASE); 86 - inode_dio_wait(inode); 87 86 nfs_file_clear_open_context(filp); 88 87 return 0; 89 88 }
+18 -2
fs/nfs/nfs4proc.c
··· 774 774 slot->seq_nr_last_acked = seqnr; 775 775 } 776 776 777 + static void nfs4_probe_sequence(struct nfs_client *client, const struct cred *cred, 778 + struct nfs4_slot *slot) 779 + { 780 + struct rpc_task *task = _nfs41_proc_sequence(client, cred, slot, true); 781 + if (!IS_ERR(task)) 782 + rpc_put_task_async(task); 783 + } 784 + 777 785 static int nfs41_sequence_process(struct rpc_task *task, 778 786 struct nfs4_sequence_res *res) 779 787 { ··· 798 790 goto out; 799 791 800 792 session = slot->table->session; 793 + clp = session->clp; 801 794 802 795 trace_nfs4_sequence_done(session, res); 803 796 ··· 813 804 nfs4_slot_sequence_acked(slot, slot->seq_nr); 814 805 /* Update the slot's sequence and clientid lease timer */ 815 806 slot->seq_done = 1; 816 - clp = session->clp; 817 807 do_renew_lease(clp, res->sr_timestamp); 818 808 /* Check sequence flags */ 819 809 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags, ··· 860 852 /* 861 853 * Were one or more calls using this slot interrupted? 862 854 * If the server never received the request, then our 863 - * transmitted slot sequence number may be too high. 855 + * transmitted slot sequence number may be too high. However, 856 + * if the server did receive the request then it might 857 + * accidentally give us a reply with a mismatched operation. 858 + * We can sort this out by sending a lone sequence operation 859 + * to the server on the same slot. 864 860 */ 865 861 if ((s32)(slot->seq_nr - slot->seq_nr_last_acked) > 1) { 866 862 slot->seq_nr--; 863 + if (task->tk_msg.rpc_proc != &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE]) { 864 + nfs4_probe_sequence(clp, task->tk_msg.rpc_cred, slot); 865 + res->sr_slot = NULL; 866 + } 867 867 goto retry_nowait; 868 868 } 869 869 /*
+2 -2
net/sunrpc/xprtrdma/rpc_rdma.c
··· 71 71 size = RPCRDMA_HDRLEN_MIN; 72 72 73 73 /* Maximum Read list size */ 74 - size = maxsegs * rpcrdma_readchunk_maxsz * sizeof(__be32); 74 + size += maxsegs * rpcrdma_readchunk_maxsz * sizeof(__be32); 75 75 76 76 /* Minimal Read chunk size */ 77 77 size += sizeof(__be32); /* segment count */ ··· 94 94 size = RPCRDMA_HDRLEN_MIN; 95 95 96 96 /* Maximum Write list size */ 97 - size = sizeof(__be32); /* segment count */ 97 + size += sizeof(__be32); /* segment count */ 98 98 size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32); 99 99 size += sizeof(__be32); /* list discriminator */ 100 100
+5
net/sunrpc/xprtrdma/transport.c
··· 249 249 xprt->stat.connect_start; 250 250 xprt_set_connected(xprt); 251 251 rc = -EAGAIN; 252 + } else { 253 + /* Force a call to xprt_rdma_close to clean up */ 254 + spin_lock(&xprt->transport_lock); 255 + set_bit(XPRT_CLOSE_WAIT, &xprt->state); 256 + spin_unlock(&xprt->transport_lock); 252 257 } 253 258 xprt_wake_pending_tasks(xprt, rc); 254 259 }
+16 -19
net/sunrpc/xprtrdma/verbs.c
··· 281 281 break; 282 282 case RDMA_CM_EVENT_CONNECT_ERROR: 283 283 ep->re_connect_status = -ENOTCONN; 284 - goto disconnected; 284 + goto wake_connect_worker; 285 285 case RDMA_CM_EVENT_UNREACHABLE: 286 286 ep->re_connect_status = -ENETUNREACH; 287 - goto disconnected; 287 + goto wake_connect_worker; 288 288 case RDMA_CM_EVENT_REJECTED: 289 289 dprintk("rpcrdma: connection to %pISpc rejected: %s\n", 290 290 sap, rdma_reject_msg(id, event->status)); 291 291 ep->re_connect_status = -ECONNREFUSED; 292 292 if (event->status == IB_CM_REJ_STALE_CONN) 293 - ep->re_connect_status = -EAGAIN; 294 - goto disconnected; 293 + ep->re_connect_status = -ENOTCONN; 294 + wake_connect_worker: 295 + wake_up_all(&ep->re_connect_wait); 296 + return 0; 295 297 case RDMA_CM_EVENT_DISCONNECTED: 296 298 ep->re_connect_status = -ECONNABORTED; 297 299 disconnected: ··· 402 400 403 401 ep = kzalloc(sizeof(*ep), GFP_NOFS); 404 402 if (!ep) 405 - return -EAGAIN; 403 + return -ENOTCONN; 406 404 ep->re_xprt = &r_xprt->rx_xprt; 407 405 kref_init(&ep->re_kref); 408 406 409 407 id = rpcrdma_create_id(r_xprt, ep); 410 408 if (IS_ERR(id)) { 411 - rc = PTR_ERR(id); 412 - goto out_free; 409 + kfree(ep); 410 + return PTR_ERR(id); 413 411 } 414 412 __module_get(THIS_MODULE); 415 413 device = id->device; ··· 508 506 out_destroy: 509 507 rpcrdma_ep_put(ep); 510 508 rdma_destroy_id(id); 511 - out_free: 512 - kfree(ep); 513 - r_xprt->rx_ep = NULL; 514 509 return rc; 515 510 } 516 511 ··· 523 524 struct rpcrdma_ep *ep; 524 525 int rc; 525 526 526 - retry: 527 - rpcrdma_xprt_disconnect(r_xprt); 528 527 rc = rpcrdma_ep_create(r_xprt); 529 528 if (rc) 530 529 return rc; ··· 537 540 rpcrdma_ep_get(ep); 538 541 rpcrdma_post_recvs(r_xprt, true); 539 542 540 - rc = rpcrdma_sendctxs_create(r_xprt); 541 - if (rc) 542 - goto out; 543 - 544 543 rc = rdma_connect(ep->re_id, &ep->re_remote_cma); 545 544 if (rc) 546 545 goto out; ··· 546 553 wait_event_interruptible(ep->re_connect_wait, 547 554 ep->re_connect_status != 0); 548 555 if (ep->re_connect_status <= 0) { 549 - if (ep->re_connect_status == -EAGAIN) 550 - goto retry; 551 556 rc = ep->re_connect_status; 557 + goto out; 558 + } 559 + 560 + rc = rpcrdma_sendctxs_create(r_xprt); 561 + if (rc) { 562 + rc = -ENOTCONN; 552 563 goto out; 553 564 } 554 565 555 566 rc = rpcrdma_reqs_setup(r_xprt); 556 567 if (rc) { 557 - rpcrdma_xprt_disconnect(r_xprt); 568 + rc = -ENOTCONN; 558 569 goto out; 559 570 } 560 571 rpcrdma_mrs_create(r_xprt);