History

Merge tag 'nfs-for-5.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates from Trond Myklebust: "Highlights include: Features: - NFSv4.2 now supports cross device offloaded copy (i.e. offloaded copy of a file from one source server to a different target server). - New RDMA tracepoints for debugging congestion control and Local Invalidate WRs. Bugfixes and cleanups - Drop the NFSv4.1 session slot if nfs4_delegreturn_prepare waits for layoutreturn - Handle bad/dead sessions correctly in nfs41_sequence_process() - Various bugfixes to the delegation return operation. - Various bugfixes pertaining to delegations that have been revoked. - Cleanups to the NFS timespec code to avoid unnecessary conversions between timespec and timespec64. - Fix unstable RDMA connections after a reconnect - Close race between waking an RDMA sender and posting a receive - Wake pending RDMA tasks if connection fails - Fix MR list corruption, and clean up MR usage - Fix another RPCSEC_GSS issue with MIC buffer space" * tag 'nfs-for-5.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (79 commits) SUNRPC: Capture completion of all RPC tasks SUNRPC: Fix another issue with MIC buffer space NFS4: Trace lock reclaims NFS4: Trace state recovery operation NFSv4.2 fix memory leak in nfs42_ssc_open NFSv4.2 fix kfree in __nfs42_copy_file_range NFS: remove duplicated include from nfs4file.c NFSv4: Make _nfs42_proc_copy_notify() static NFS: Fallocate should use the nfs4_fattr_bitmap NFS: Return -ETXTBSY when attempting to write to a swapfile fs: nfs: sysfs: Remove NULL check before kfree NFS: remove unneeded semicolon NFSv4: add declaration of current_stateid NFSv4.x: Drop the slot if nfs4_delegreturn_prepare waits for layoutreturn NFSv4.x: Handle bad/dead sessions correctly in nfs41_sequence_process() nfsv4: Move NFSPROC4_CLNT_COPY_NOTIFY to end of list SUNRPC: Avoid RPC delays when exiting suspend NFS: Add a tracepoint in nfs_fh_to_dentry() NFSv4: Don't retry the GETATTR on old stateid in nfs4_delegreturn_done() NFSv4: Handle NFS4ERR_OLD_STATEID in delegreturn ...

Linus Torvalds committed 6 years ago

Commit fb9bf402 parents 94e89b4 a264aba49 files · +1756 −622Browse files

Unified · Split

49 files
  1. fs/lockd/host.c +2 −1
  2. fs/nfs/callback.h +2 −2
  3. fs/nfs/callback_proc.c +3 −5
  4. fs/nfs/callback_xdr.c +3 −3
  5. fs/nfs/client.c +11 −0
  6. fs/nfs/delegation.c +111 −47
  7. fs/nfs/delegation.h +2 −1
  8. fs/nfs/export.c +1 −0
  9. fs/nfs/file.c +1 −1
  10. fs/nfs/inode.c +27 −27
  11. fs/nfs/internal.h +1 −1
  12. fs/nfs/namespace.c +3 −0
  13. fs/nfs/nfs2xdr.c +8 −13
  14. fs/nfs/nfs3client.c +4 −1
  15. fs/nfs/nfs3xdr.c +5 −9
  16. fs/nfs/nfs42.h +14 −1
  17. fs/nfs/nfs42proc.c +168 −33
  18. fs/nfs/nfs42xdr.c +188 −2
  19. fs/nfs/nfs4_fs.h +19 −2
  20. fs/nfs/nfs4client.c +8 −5
  21. fs/nfs/nfs4file.c +139 −2
  22. fs/nfs/nfs4proc.c +46 −23
  23. fs/nfs/nfs4state.c +43 −8
  24. fs/nfs/nfs4super.c +2 −2
  25. fs/nfs/nfs4trace.h +175 −0
  26. fs/nfs/nfs4xdr.c +11 −13
  27. fs/nfs/nfstrace.h +33 −0
  28. fs/nfs/pnfs.c +0 −2
  29. fs/nfs/super.c +3 −3
  30. fs/nfs/sysfs.c +1 −2
  31. include/linux/nfs4.h +26 −0
  32. include/linux/nfs_fs.h +3 −1
  33. include/linux/nfs_fs_sb.h +5 −1
  34. include/linux/nfs_xdr.h +24 −7
  35. include/linux/sunrpc/clnt.h +1 −0
  36. include/linux/sunrpc/xprt.h +2 −1
  37. include/trace/events/rpcrdma.h +132 −66
  38. include/trace/events/sunrpc.h +94 −0
  39. net/sunrpc/clnt.c +8 −13
  40. net/sunrpc/sched.c +2 −1
  41. net/sunrpc/xdr.c +5 −6
  42. net/sunrpc/xprt.c +13 −9
  43. net/sunrpc/xprtrdma/backchannel.c +1 −1
  44. net/sunrpc/xprtrdma/frwr_ops.c +11 −42
  45. net/sunrpc/xprtrdma/rpc_rdma.c +268 −145
  46. net/sunrpc/xprtrdma/transport.c +10 −23
  47. net/sunrpc/xprtrdma/verbs.c +110 −84
  48. net/sunrpc/xprtrdma/xprt_rdma.h +6 −12
  49. net/sunrpc/xprtsock.c +1 −1
fs/lockd/host.c+2−1
@@ -464,7 +464,8 @@ nlm_bind_host(struct nlm_host *host) · 463 unmodified lines
464 .version = host->h_version,464 .version = host->h_version,
465 .authflavor = RPC_AUTH_UNIX,465 .authflavor = RPC_AUTH_UNIX,
466 .flags = (RPC_CLNT_CREATE_NOPING |466 .flags = (RPC_CLNT_CREATE_NOPING |
467 RPC_CLNT_CREATE_AUTOBIND),467 RPC_CLNT_CREATE_AUTOBIND |
468 RPC_CLNT_CREATE_REUSEPORT),
468 .cred = host->h_cred,469 .cred = host->h_cred,
469 };470 };
470 471
fs/nfs/callback.h+2−2
@@ -72,8 +72,8 @@ struct cb_getattrres { · 71 unmodified lines
72 uint32_t bitmap[2];72 uint32_t bitmap[2];
73 uint64_t size;73 uint64_t size;
74 uint64_t change_attr;74 uint64_t change_attr;
75 struct timespec ctime;75 struct timespec64 ctime;
76 struct timespec mtime;76 struct timespec64 mtime;
77};77};
78 78
79struct cb_recallargs {79struct cb_recallargs {
fs/nfs/callback_proc.c+3−5
@@ -26,7 +26,6 @@ __be32 nfs4_callback_getattr(void *argp, void *resp, · 25 unmodified lines
26 struct cb_getattrargs *args = argp;26 struct cb_getattrargs *args = argp;
27 struct cb_getattrres *res = resp;27 struct cb_getattrres *res = resp;
28 struct nfs_delegation *delegation;28 struct nfs_delegation *delegation;
29 struct nfs_inode *nfsi;
30 struct inode *inode;29 struct inode *inode;
31 30
32 res->status = htonl(NFS4ERR_OP_NOT_IN_SESSION);31 res->status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
@@ -47,17 +46,16 @@ __be32 nfs4_callback_getattr(void *argp, void *resp, · 14 unmodified lines
47 -ntohl(res->status));46 -ntohl(res->status));
48 goto out;47 goto out;
49 }48 }
50 nfsi = NFS_I(inode);
51 rcu_read_lock();49 rcu_read_lock();
52 delegation = rcu_dereference(nfsi->delegation);50 delegation = nfs4_get_valid_delegation(inode);
53 if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)51 if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
54 goto out_iput;52 goto out_iput;
55 res->size = i_size_read(inode);53 res->size = i_size_read(inode);
56 res->change_attr = delegation->change_attr;54 res->change_attr = delegation->change_attr;
57 if (nfs_have_writebacks(inode))55 if (nfs_have_writebacks(inode))
58 res->change_attr++;56 res->change_attr++;
59 res->ctime = timespec64_to_timespec(inode->i_ctime);57 res->ctime = inode->i_ctime;
60 res->mtime = timespec64_to_timespec(inode->i_mtime);58 res->mtime = inode->i_mtime;
61 res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &59 res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
62 args->bitmap[0];60 args->bitmap[0];
63 res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &61 res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
fs/nfs/callback_xdr.c+3−3
@@ -627,7 +627,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u · 626 unmodified lines
627 return 0;627 return 0;
628}628}
629 629
630static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)630static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *time)
631{631{
632 __be32 *p;632 __be32 *p;
633 633
@@ -639,14 +639,14 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti · 5 unmodified lines
639 return 0;639 return 0;
640}640}
641 641
642static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)642static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
643{643{
644 if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))644 if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
645 return 0;645 return 0;
646 return encode_attr_time(xdr,time);646 return encode_attr_time(xdr,time);
647}647}
648 648
649static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)649static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
650{650{
651 if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))651 if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
652 return 0;652 return 0;
fs/nfs/client.c+11−0
@@ -312,6 +312,12 @@ again: · 311 unmodified lines
312 /* Match nfsv4 minorversion */312 /* Match nfsv4 minorversion */
313 if (clp->cl_minorversion != data->minorversion)313 if (clp->cl_minorversion != data->minorversion)
314 continue;314 continue;
315
316 /* Match request for a dedicated DS */
317 if (test_bit(NFS_CS_DS, &data->init_flags) !=
318 test_bit(NFS_CS_DS, &clp->cl_flags))
319 continue;
320
315 /* Match the full socket address */321 /* Match the full socket address */
316 if (!rpc_cmp_addr_port(sap, clap))322 if (!rpc_cmp_addr_port(sap, clap))
317 /* Match all xprt_switch full socket addresses */323 /* Match all xprt_switch full socket addresses */
@@ -515,6 +521,10 @@ int nfs_create_rpc_client(struct nfs_client *clp, · 197 unmodified lines
515 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;521 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
516 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))522 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
517 args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;523 args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
524 if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
525 args.flags |= RPC_CLNT_CREATE_NOPING;
526 if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
527 args.flags |= RPC_CLNT_CREATE_REUSEPORT;
518 528
519 if (!IS_ERR(clp->cl_rpcclient))529 if (!IS_ERR(clp->cl_rpcclient))
520 return 0;530 return 0;
@@ -662,6 +672,7 @@ static int nfs_init_server(struct nfs_server *server, · 141 unmodified lines
662 .timeparms = &timeparms,672 .timeparms = &timeparms,
663 .cred = server->cred,673 .cred = server->cred,
664 .nconnect = data->nfs_server.nconnect,674 .nconnect = data->nfs_server.nconnect,
675 .init_flags = (1UL << NFS_CS_REUSEPORT),
665 };676 };
666 struct nfs_client *clp;677 struct nfs_client *clp;
667 int error;678 int error;
fs/nfs/delegation.c+111−47
@@ -199,7 +199,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, · 198 unmodified lines
199 delegation = rcu_dereference(NFS_I(inode)->delegation);199 delegation = rcu_dereference(NFS_I(inode)->delegation);
200 if (delegation != NULL) {200 if (delegation != NULL) {
201 spin_lock(&delegation->lock);201 spin_lock(&delegation->lock);
202 if (delegation->inode != NULL) {202 if (nfs4_is_valid_delegation(delegation, 0)) {
203 nfs4_stateid_copy(&delegation->stateid, stateid);203 nfs4_stateid_copy(&delegation->stateid, stateid);
204 delegation->type = type;204 delegation->type = type;
205 delegation->pagemod_limit = pagemod_limit;205 delegation->pagemod_limit = pagemod_limit;
@@ -229,7 +229,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * · 23 unmodified lines
229 delegation->cred,229 delegation->cred,
230 &delegation->stateid,230 &delegation->stateid,
231 issync);231 issync);
232 nfs_free_delegation(delegation);
233 return res;232 return res;
234}233}
235 234
@@ -298,7 +297,10 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi, · 62 unmodified lines
298 return NULL;297 return NULL;
299 298
300 spin_lock(&delegation->lock);299 spin_lock(&delegation->lock);
301 set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);300 if (!delegation->inode) {
301 spin_unlock(&delegation->lock);
302 return NULL;
303 }
302 list_del_rcu(&delegation->super_list);304 list_del_rcu(&delegation->super_list);
303 delegation->inode = NULL;305 delegation->inode = NULL;
304 rcu_assign_pointer(nfsi->delegation, NULL);306 rcu_assign_pointer(nfsi->delegation, NULL);
@@ -325,10 +327,12 @@ nfs_inode_detach_delegation(struct inode *inode) · 20 unmodified lines
325 struct nfs_server *server = NFS_SERVER(inode);327 struct nfs_server *server = NFS_SERVER(inode);
326 struct nfs_delegation *delegation;328 struct nfs_delegation *delegation;
327 329
328 delegation = nfs_start_delegation_return(nfsi);330 rcu_read_lock();
329 if (delegation == NULL)331 delegation = rcu_dereference(nfsi->delegation);
330 return NULL;332 if (delegation != NULL)
331 return nfs_detach_delegation(nfsi, delegation, server);333 delegation = nfs_detach_delegation(nfsi, delegation, server);
334 rcu_read_unlock();
335 return delegation;
332}336}
333 337
334static void338static void
@@ -339,6 +343,7 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation, · 4 unmodified lines
339 delegation->stateid.seqid = update->stateid.seqid;343 delegation->stateid.seqid = update->stateid.seqid;
340 smp_wmb();344 smp_wmb();
341 delegation->type = update->type;345 delegation->type = update->type;
346 clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
342 }347 }
343}348}
344 349
@@ -379,14 +384,18 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, · 34 unmodified lines
379 spin_lock(&clp->cl_lock);384 spin_lock(&clp->cl_lock);
380 old_delegation = rcu_dereference_protected(nfsi->delegation,385 old_delegation = rcu_dereference_protected(nfsi->delegation,
381 lockdep_is_held(&clp->cl_lock));386 lockdep_is_held(&clp->cl_lock));
382 if (old_delegation != NULL) {387 if (old_delegation == NULL)
383 /* Is this an update of the existing delegation? */388 goto add_new;
384 if (nfs4_stateid_match_other(&old_delegation->stateid,389 /* Is this an update of the existing delegation? */
385 &delegation->stateid)) {390 if (nfs4_stateid_match_other(&old_delegation->stateid,
386 nfs_update_inplace_delegation(old_delegation,391 &delegation->stateid)) {
387 delegation);392 spin_lock(&old_delegation->lock);
388 goto out;393 nfs_update_inplace_delegation(old_delegation,
389 }394 delegation);
395 spin_unlock(&old_delegation->lock);
396 goto out;
397 }
398 if (!test_bit(NFS_DELEGATION_REVOKED, &old_delegation->flags)) {
390 /*399 /*
391 * Deal with broken servers that hand out two400 * Deal with broken servers that hand out two
392 * delegations for the same file.401 * delegations for the same file.
@@ -405,11 +414,11 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, · 12 unmodified lines
405 if (test_and_set_bit(NFS_DELEGATION_RETURNING,414 if (test_and_set_bit(NFS_DELEGATION_RETURNING,
406 &old_delegation->flags))415 &old_delegation->flags))
407 goto out;416 goto out;
408 freeme = nfs_detach_delegation_locked(nfsi,
409 old_delegation, clp);
410 if (freeme == NULL)
411 goto out;
412 }417 }
418 freeme = nfs_detach_delegation_locked(nfsi, old_delegation, clp);
419 if (freeme == NULL)
420 goto out;
421add_new:
413 list_add_tail_rcu(&delegation->super_list, &server->delegations);422 list_add_tail_rcu(&delegation->super_list, &server->delegations);
414 rcu_assign_pointer(nfsi->delegation, delegation);423 rcu_assign_pointer(nfsi->delegation, delegation);
415 delegation = NULL;424 delegation = NULL;
@@ -424,8 +433,10 @@ out: · 8 unmodified lines
424 spin_unlock(&clp->cl_lock);433 spin_unlock(&clp->cl_lock);
425 if (delegation != NULL)434 if (delegation != NULL)
426 nfs_free_delegation(delegation);435 nfs_free_delegation(delegation);
427 if (freeme != NULL)436 if (freeme != NULL) {
428 nfs_do_return_delegation(inode, freeme, 0);437 nfs_do_return_delegation(inode, freeme, 0);
438 nfs_free_delegation(freeme);
439 }
429 return status;440 return status;
430}441}
431 442
@@ -435,7 +446,6 @@ out: · 3 unmodified lines
435static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)446static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
436{447{
437 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;448 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
438 struct nfs_inode *nfsi = NFS_I(inode);
439 int err = 0;449 int err = 0;
440 450
441 if (delegation == NULL)451 if (delegation == NULL)
@@ -457,8 +467,6 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation · 15 unmodified lines
457 nfs_abort_delegation_return(delegation, clp);467 nfs_abort_delegation_return(delegation, clp);
458 goto out;468 goto out;
459 }469 }
460 if (!nfs_detach_delegation(nfsi, delegation, NFS_SERVER(inode)))
461 goto out;
462 470
463 err = nfs_do_return_delegation(inode, delegation, issync);471 err = nfs_do_return_delegation(inode, delegation, issync);
464out:472out:
@@ -469,8 +477,6 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation) · 4 unmodified lines
469{477{
470 bool ret = false;478 bool ret = false;
471 479
472 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
473 goto out;
474 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))480 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
475 ret = true;481 ret = true;
476 if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {482 if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
@@ -482,7 +488,10 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation) · 5 unmodified lines
482 ret = true;488 ret = true;
483 spin_unlock(&delegation->lock);489 spin_unlock(&delegation->lock);
484 }490 }
485out:491 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
492 test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
493 ret = false;
494
486 return ret;495 return ret;
487}496}
488 497
@@ -585,19 +594,23 @@ restart: · 96 unmodified lines
585}594}
586 595
587/**596/**
588 * nfs_inode_return_delegation_noreclaim - return delegation, don't reclaim opens597 * nfs_inode_evict_delegation - return delegation, don't reclaim opens
589 * @inode: inode to process598 * @inode: inode to process
590 *599 *
591 * Does not protect against delegation reclaims, therefore really only safe600 * Does not protect against delegation reclaims, therefore really only safe
592 * to be called from nfs4_clear_inode().601 * to be called from nfs4_clear_inode(). Guaranteed to always free
602 * the delegation structure.
593 */603 */
594void nfs_inode_return_delegation_noreclaim(struct inode *inode)604void nfs_inode_evict_delegation(struct inode *inode)
595{605{
596 struct nfs_delegation *delegation;606 struct nfs_delegation *delegation;
597 607
598 delegation = nfs_inode_detach_delegation(inode);608 delegation = nfs_inode_detach_delegation(inode);
599 if (delegation != NULL)609 if (delegation != NULL) {
610 set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
600 nfs_do_return_delegation(inode, delegation, 1);611 nfs_do_return_delegation(inode, delegation, 1);
612 nfs_free_delegation(delegation);
613 }
601}614}
602 615
603/**616/**
@@ -633,10 +646,18 @@ int nfs4_inode_return_delegation(struct inode *inode) · 29 unmodified lines
633 */646 */
634int nfs4_inode_make_writeable(struct inode *inode)647int nfs4_inode_make_writeable(struct inode *inode)
635{648{
636 if (!nfs4_has_session(NFS_SERVER(inode)->nfs_client) ||649 struct nfs_delegation *delegation;
637 !nfs4_check_delegation(inode, FMODE_WRITE))650
638 return nfs4_inode_return_delegation(inode);651 rcu_read_lock();
639 return 0;652 delegation = nfs4_get_valid_delegation(inode);
653 if (delegation == NULL ||
654 (nfs4_has_session(NFS_SERVER(inode)->nfs_client) &&
655 (delegation->type & FMODE_WRITE))) {
656 rcu_read_unlock();
657 return 0;
658 }
659 rcu_read_unlock();
660 return nfs4_inode_return_delegation(inode);
640}661}
641 662
642static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,663static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
@@ -744,10 +765,9 @@ static void nfs_mark_delegation_revoked(struct nfs_server *server, · 101 unmodified lines
744{765{
745 set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);766 set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
746 delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;767 delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
747 nfs_mark_return_delegation(server, delegation);
748}768}
749 769
750static bool nfs_revoke_delegation(struct inode *inode,770static void nfs_revoke_delegation(struct inode *inode,
751 const nfs4_stateid *stateid)771 const nfs4_stateid *stateid)
752{772{
753 struct nfs_delegation *delegation;773 struct nfs_delegation *delegation;
@@ -761,29 +781,69 @@ static bool nfs_revoke_delegation(struct inode *inode, · 7 unmodified lines
761 if (stateid == NULL) {781 if (stateid == NULL) {
762 nfs4_stateid_copy(&tmp, &delegation->stateid);782 nfs4_stateid_copy(&tmp, &delegation->stateid);
763 stateid = &tmp;783 stateid = &tmp;
764 } else if (!nfs4_stateid_match(stateid, &delegation->stateid))784 } else {
765 goto out;785 if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
786 goto out;
787 spin_lock(&delegation->lock);
788 if (stateid->seqid) {
789 if (nfs4_stateid_is_newer(&delegation->stateid, stateid)) {
790 spin_unlock(&delegation->lock);
791 goto out;
792 }
793 delegation->stateid.seqid = stateid->seqid;
794 }
795 spin_unlock(&delegation->lock);
796 }
766 nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);797 nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
767 ret = true;798 ret = true;
768out:799out:
769 rcu_read_unlock();800 rcu_read_unlock();
770 if (ret)801 if (ret)
771 nfs_inode_find_state_and_recover(inode, stateid);802 nfs_inode_find_state_and_recover(inode, stateid);
772 return ret;
773}803}
774 804
775void nfs_remove_bad_delegation(struct inode *inode,805void nfs_remove_bad_delegation(struct inode *inode,
776 const nfs4_stateid *stateid)806 const nfs4_stateid *stateid)
807{
808 nfs_revoke_delegation(inode, stateid);
809}
810EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
811
812void nfs_delegation_mark_returned(struct inode *inode,
813 const nfs4_stateid *stateid)
777{814{
778 struct nfs_delegation *delegation;815 struct nfs_delegation *delegation;
779 816
780 if (!nfs_revoke_delegation(inode, stateid))817 if (!inode)
781 return;818 return;
782 delegation = nfs_inode_detach_delegation(inode);819
783 if (delegation)820 rcu_read_lock();
784 nfs_free_delegation(delegation);821 delegation = rcu_dereference(NFS_I(inode)->delegation);
822 if (!delegation)
823 goto out_rcu_unlock;
824
825 spin_lock(&delegation->lock);
826 if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
827 goto out_spin_unlock;
828 if (stateid->seqid) {
829 /* If delegation->stateid is newer, dont mark as returned */
830 if (nfs4_stateid_is_newer(&delegation->stateid, stateid))
831 goto out_clear_returning;
832 if (delegation->stateid.seqid != stateid->seqid)
833 delegation->stateid.seqid = stateid->seqid;
834 }
835
836 nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
837
838out_clear_returning:
839 clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
840out_spin_unlock:
841 spin_unlock(&delegation->lock);
842out_rcu_unlock:
843 rcu_read_unlock();
844
845 nfs_inode_find_state_and_recover(inode, stateid);
785}846}
786EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
787 847
788/**848/**
789 * nfs_expire_unused_delegation_types849 * nfs_expire_unused_delegation_types
@@ -840,7 +900,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, · 50 unmodified lines
840 struct nfs_delegation *delegation;900 struct nfs_delegation *delegation;
841 901
842 rcu_read_lock();902 rcu_read_lock();
843 delegation = rcu_dereference(NFS_I(inode)->delegation);903 delegation = nfs4_get_valid_delegation(inode);
844 if (delegation == NULL)904 if (delegation == NULL)
845 goto out_enoent;905 goto out_enoent;
846 if (stateid != NULL &&906 if (stateid != NULL &&
@@ -866,6 +926,7 @@ nfs_delegation_find_inode_server(struct nfs_server *server, · 19 unmodified lines
866 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {926 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
867 spin_lock(&delegation->lock);927 spin_lock(&delegation->lock);
868 if (delegation->inode != NULL &&928 if (delegation->inode != NULL &&
929 !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
869 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {930 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
870 freeme = igrab(delegation->inode);931 freeme = igrab(delegation->inode);
871 if (freeme && nfs_sb_active(freeme->i_sb))932 if (freeme && nfs_sb_active(freeme->i_sb))
@@ -1140,7 +1201,8 @@ void nfs_inode_find_delegation_state_and_recover(struct inode *inode, · 268 unmodified lines
1140 rcu_read_lock();1201 rcu_read_lock();
1141 delegation = rcu_dereference(NFS_I(inode)->delegation);1202 delegation = rcu_dereference(NFS_I(inode)->delegation);
1142 if (delegation &&1203 if (delegation &&
1143 nfs4_stateid_match_other(&delegation->stateid, stateid)) {1204 nfs4_stateid_match_or_older(&delegation->stateid, stateid) &&
1205 !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
1144 nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);1206 nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
1145 found = true;1207 found = true;
1146 }1208 }
@@ -1189,7 +1251,9 @@ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode) · 42 unmodified lines
1189 rcu_read_lock();1251 rcu_read_lock();
1190 delegation = rcu_dereference(NFS_I(inode)->delegation);1252 delegation = rcu_dereference(NFS_I(inode)->delegation);
1191 if (delegation != NULL &&1253 if (delegation != NULL &&
1192 nfs4_stateid_match_other(dst, &delegation->stateid)) {1254 nfs4_stateid_match_other(dst, &delegation->stateid) &&
1255 nfs4_stateid_is_newer(&delegation->stateid, dst) &&
1256 !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
1193 dst->seqid = delegation->stateid.seqid;1257 dst->seqid = delegation->stateid.seqid;
1194 ret = true;1258 ret = true;
1195 }1259 }
fs/nfs/delegation.h+2−1
@@ -43,7 +43,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, · 42 unmodified lines
43 fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);43 fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
44int nfs4_inode_return_delegation(struct inode *inode);44int nfs4_inode_return_delegation(struct inode *inode);
45int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);45int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
46void nfs_inode_return_delegation_noreclaim(struct inode *inode);46void nfs_inode_evict_delegation(struct inode *inode);
47 47
48struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);48struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
49void nfs_server_return_all_delegations(struct nfs_server *);49void nfs_server_return_all_delegations(struct nfs_server *);
@@ -53,6 +53,7 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp); · 3 unmodified lines
53int nfs_client_return_marked_delegations(struct nfs_client *clp);53int nfs_client_return_marked_delegations(struct nfs_client *clp);
54int nfs_delegations_present(struct nfs_client *clp);54int nfs_delegations_present(struct nfs_client *clp);
55void nfs_remove_bad_delegation(struct inode *inode, const nfs4_stateid *stateid);55void nfs_remove_bad_delegation(struct inode *inode, const nfs4_stateid *stateid);
56void nfs_delegation_mark_returned(struct inode *inode, const nfs4_stateid *stateid);
56 57
57void nfs_delegation_mark_reclaim(struct nfs_client *clp);58void nfs_delegation_mark_reclaim(struct nfs_client *clp);
58void nfs_delegation_reap_unclaimed(struct nfs_client *clp);59void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
fs/nfs/export.c+1−0
@@ -105,6 +105,7 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, · 104 unmodified lines
105 ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label, NULL);105 ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label, NULL);
106 if (ret) {106 if (ret) {
107 dprintk("%s: getattr failed %d\n", __func__, ret);107 dprintk("%s: getattr failed %d\n", __func__, ret);
108 trace_nfs_fh_to_dentry(sb, server_fh, fattr->fileid, ret);
108 dentry = ERR_PTR(ret);109 dentry = ERR_PTR(ret);
109 goto out_free_label;110 goto out_free_label;
110 }111 }
fs/nfs/file.c+1−1
@@ -649,7 +649,7 @@ out: · 648 unmodified lines
649 649
650out_swapfile:650out_swapfile:
651 printk(KERN_INFO "NFS: attempt to write to active swap file!\n");651 printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
652 return -EBUSY;652 return -ETXTBSY;
653}653}
654EXPORT_SYMBOL_GPL(nfs_file_write);654EXPORT_SYMBOL_GPL(nfs_file_write);
655 655
fs/nfs/inode.c+27−27
@@ -504,15 +504,15 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st · 503 unmodified lines
504 nfsi->read_cache_jiffies = fattr->time_start;504 nfsi->read_cache_jiffies = fattr->time_start;
505 nfsi->attr_gencount = fattr->gencount;505 nfsi->attr_gencount = fattr->gencount;
506 if (fattr->valid & NFS_ATTR_FATTR_ATIME)506 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
507 inode->i_atime = timespec_to_timespec64(fattr->atime);507 inode->i_atime = fattr->atime;
508 else if (nfs_server_capable(inode, NFS_CAP_ATIME))508 else if (nfs_server_capable(inode, NFS_CAP_ATIME))
509 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);509 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
510 if (fattr->valid & NFS_ATTR_FATTR_MTIME)510 if (fattr->valid & NFS_ATTR_FATTR_MTIME)
511 inode->i_mtime = timespec_to_timespec64(fattr->mtime);511 inode->i_mtime = fattr->mtime;
512 else if (nfs_server_capable(inode, NFS_CAP_MTIME))512 else if (nfs_server_capable(inode, NFS_CAP_MTIME))
513 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);513 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
514 if (fattr->valid & NFS_ATTR_FATTR_CTIME)514 if (fattr->valid & NFS_ATTR_FATTR_CTIME)
515 inode->i_ctime = timespec_to_timespec64(fattr->ctime);515 inode->i_ctime = fattr->ctime;
516 else if (nfs_server_capable(inode, NFS_CAP_CTIME))516 else if (nfs_server_capable(inode, NFS_CAP_CTIME))
517 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);517 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
518 if (fattr->valid & NFS_ATTR_FATTR_CHANGE)518 if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -698,7 +698,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, · 179 unmodified lines
698 if ((attr->ia_valid & ATTR_GID) != 0)698 if ((attr->ia_valid & ATTR_GID) != 0)
699 inode->i_gid = attr->ia_gid;699 inode->i_gid = attr->ia_gid;
700 if (fattr->valid & NFS_ATTR_FATTR_CTIME)700 if (fattr->valid & NFS_ATTR_FATTR_CTIME)
701 inode->i_ctime = timespec_to_timespec64(fattr->ctime);701 inode->i_ctime = fattr->ctime;
702 else702 else
703 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE703 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
704 | NFS_INO_INVALID_CTIME);704 | NFS_INO_INVALID_CTIME);
@@ -709,14 +709,14 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, · 4 unmodified lines
709 NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_ATIME709 NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_ATIME
710 | NFS_INO_INVALID_CTIME);710 | NFS_INO_INVALID_CTIME);
711 if (fattr->valid & NFS_ATTR_FATTR_ATIME)711 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
712 inode->i_atime = timespec_to_timespec64(fattr->atime);712 inode->i_atime = fattr->atime;
713 else if (attr->ia_valid & ATTR_ATIME_SET)713 else if (attr->ia_valid & ATTR_ATIME_SET)
714 inode->i_atime = attr->ia_atime;714 inode->i_atime = attr->ia_atime;
715 else715 else
716 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);716 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
717 717
718 if (fattr->valid & NFS_ATTR_FATTR_CTIME)718 if (fattr->valid & NFS_ATTR_FATTR_CTIME)
719 inode->i_ctime = timespec_to_timespec64(fattr->ctime);719 inode->i_ctime = fattr->ctime;
720 else720 else
721 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE721 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
722 | NFS_INO_INVALID_CTIME);722 | NFS_INO_INVALID_CTIME);
@@ -725,14 +725,14 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, · 2 unmodified lines
725 NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_MTIME725 NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_MTIME
726 | NFS_INO_INVALID_CTIME);726 | NFS_INO_INVALID_CTIME);
727 if (fattr->valid & NFS_ATTR_FATTR_MTIME)727 if (fattr->valid & NFS_ATTR_FATTR_MTIME)
728 inode->i_mtime = timespec_to_timespec64(fattr->mtime);728 inode->i_mtime = fattr->mtime;
729 else if (attr->ia_valid & ATTR_MTIME_SET)729 else if (attr->ia_valid & ATTR_MTIME_SET)
730 inode->i_mtime = attr->ia_mtime;730 inode->i_mtime = attr->ia_mtime;
731 else731 else
732 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);732 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
733 733
734 if (fattr->valid & NFS_ATTR_FATTR_CTIME)734 if (fattr->valid & NFS_ATTR_FATTR_CTIME)
735 inode->i_ctime = timespec_to_timespec64(fattr->ctime);735 inode->i_ctime = fattr->ctime;
736 else736 else
737 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE737 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
738 | NFS_INO_INVALID_CTIME);738 | NFS_INO_INVALID_CTIME);
@@ -1351,7 +1351,7 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi) · 612 unmodified lines
1351 1351
1352static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)1352static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1353{1353{
1354 struct timespec ts;1354 struct timespec64 ts;
1355 1355
1356 if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)1356 if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
1357 && (fattr->valid & NFS_ATTR_FATTR_CHANGE)1357 && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -1361,18 +1361,18 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) · 3 unmodified lines
1361 nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);1361 nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
1362 }1362 }
1363 /* If we have atomic WCC data, we may update some attributes */1363 /* If we have atomic WCC data, we may update some attributes */
1364 ts = timespec64_to_timespec(inode->i_ctime);1364 ts = inode->i_ctime;
1365 if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)1365 if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)
1366 && (fattr->valid & NFS_ATTR_FATTR_CTIME)1366 && (fattr->valid & NFS_ATTR_FATTR_CTIME)
1367 && timespec_equal(&ts, &fattr->pre_ctime)) {1367 && timespec64_equal(&ts, &fattr->pre_ctime)) {
1368 inode->i_ctime = timespec_to_timespec64(fattr->ctime);1368 inode->i_ctime = fattr->ctime;
1369 }1369 }
1370 1370
1371 ts = timespec64_to_timespec(inode->i_mtime);1371 ts = inode->i_mtime;
1372 if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)1372 if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)
1373 && (fattr->valid & NFS_ATTR_FATTR_MTIME)1373 && (fattr->valid & NFS_ATTR_FATTR_MTIME)
1374 && timespec_equal(&ts, &fattr->pre_mtime)) {1374 && timespec64_equal(&ts, &fattr->pre_mtime)) {
1375 inode->i_mtime = timespec_to_timespec64(fattr->mtime);1375 inode->i_mtime = fattr->mtime;
1376 if (S_ISDIR(inode->i_mode))1376 if (S_ISDIR(inode->i_mode))
1377 nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);1377 nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
1378 }1378 }
@@ -1398,7 +1398,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat · 19 unmodified lines
1398 struct nfs_inode *nfsi = NFS_I(inode);1398 struct nfs_inode *nfsi = NFS_I(inode);
1399 loff_t cur_size, new_isize;1399 loff_t cur_size, new_isize;
1400 unsigned long invalid = 0;1400 unsigned long invalid = 0;
1401 struct timespec ts;1401 struct timespec64 ts;
1402 1402
1403 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))1403 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
1404 return 0;1404 return 0;
@@ -1425,12 +1425,12 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat · 20 unmodified lines
1425 invalid |= NFS_INO_INVALID_CHANGE1425 invalid |= NFS_INO_INVALID_CHANGE
1426 | NFS_INO_REVAL_PAGECACHE;1426 | NFS_INO_REVAL_PAGECACHE;
1427 1427
1428 ts = timespec64_to_timespec(inode->i_mtime);1428 ts = inode->i_mtime;
1429 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&ts, &fattr->mtime))1429 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec64_equal(&ts, &fattr->mtime))
1430 invalid |= NFS_INO_INVALID_MTIME;1430 invalid |= NFS_INO_INVALID_MTIME;
1431 1431
1432 ts = timespec64_to_timespec(inode->i_ctime);1432 ts = inode->i_ctime;
1433 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&ts, &fattr->ctime))1433 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec64_equal(&ts, &fattr->ctime))
1434 invalid |= NFS_INO_INVALID_CTIME;1434 invalid |= NFS_INO_INVALID_CTIME;
1435 1435
1436 if (fattr->valid & NFS_ATTR_FATTR_SIZE) {1436 if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
@@ -1460,8 +1460,8 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat · 23 unmodified lines
1460 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)1460 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
1461 invalid |= NFS_INO_INVALID_OTHER;1461 invalid |= NFS_INO_INVALID_OTHER;
1462 1462
1463 ts = timespec64_to_timespec(inode->i_atime);1463 ts = inode->i_atime;
1464 if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&ts, &fattr->atime))1464 if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec64_equal(&ts, &fattr->atime))
1465 invalid |= NFS_INO_INVALID_ATIME;1465 invalid |= NFS_INO_INVALID_ATIME;
1466 1466
1467 if (invalid != 0)1467 if (invalid != 0)
@@ -1733,12 +1733,12 @@ int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fa · 265 unmodified lines
1733 }1733 }
1734 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&1734 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
1735 (fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) {1735 (fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) {
1736 fattr->pre_ctime = timespec64_to_timespec(inode->i_ctime);1736 fattr->pre_ctime = inode->i_ctime;
1737 fattr->valid |= NFS_ATTR_FATTR_PRECTIME;1737 fattr->valid |= NFS_ATTR_FATTR_PRECTIME;
1738 }1738 }
1739 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 &&1739 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 &&
1740 (fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) {1740 (fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) {
1741 fattr->pre_mtime = timespec64_to_timespec(inode->i_mtime);1741 fattr->pre_mtime = inode->i_mtime;
1742 fattr->valid |= NFS_ATTR_FATTR_PREMTIME;1742 fattr->valid |= NFS_ATTR_FATTR_PREMTIME;
1743 }1743 }
1744 if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 &&1744 if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 &&
@@ -1899,7 +1899,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) · 154 unmodified lines
1899 }1899 }
1900 1900
1901 if (fattr->valid & NFS_ATTR_FATTR_MTIME) {1901 if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
1902 inode->i_mtime = timespec_to_timespec64(fattr->mtime);1902 inode->i_mtime = fattr->mtime;
1903 } else if (server->caps & NFS_CAP_MTIME) {1903 } else if (server->caps & NFS_CAP_MTIME) {
1904 nfsi->cache_validity |= save_cache_validity &1904 nfsi->cache_validity |= save_cache_validity &
1905 (NFS_INO_INVALID_MTIME1905 (NFS_INO_INVALID_MTIME
@@ -1908,7 +1908,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) · 2 unmodified lines
1908 }1908 }
1909 1909
1910 if (fattr->valid & NFS_ATTR_FATTR_CTIME) {1910 if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
1911 inode->i_ctime = timespec_to_timespec64(fattr->ctime);1911 inode->i_ctime = fattr->ctime;
1912 } else if (server->caps & NFS_CAP_CTIME) {1912 } else if (server->caps & NFS_CAP_CTIME) {
1913 nfsi->cache_validity |= save_cache_validity &1913 nfsi->cache_validity |= save_cache_validity &
1914 (NFS_INO_INVALID_CTIME1914 (NFS_INO_INVALID_CTIME
@@ -1946,7 +1946,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) · 31 unmodified lines
1946 1946
1947 1947
1948 if (fattr->valid & NFS_ATTR_FATTR_ATIME)1948 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
1949 inode->i_atime = timespec_to_timespec64(fattr->atime);1949 inode->i_atime = fattr->atime;
1950 else if (server->caps & NFS_CAP_ATIME) {1950 else if (server->caps & NFS_CAP_ATIME) {
1951 nfsi->cache_validity |= save_cache_validity &1951 nfsi->cache_validity |= save_cache_validity &
1952 (NFS_INO_INVALID_ATIME1952 (NFS_INO_INVALID_ATIME
fs/nfs/internal.h+1−1
@@ -713,7 +713,7 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len) · 712 unmodified lines
713 * 1024*1024*1024.713 * 1024*1024*1024.
714 */714 */
715static inline715static inline
716u64 nfs_timespec_to_change_attr(const struct timespec *ts)716u64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
717{717{
718 return ((u64)ts->tv_sec << 30) + ts->tv_nsec;718 return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
719}719}
fs/nfs/namespace.c+3−0
@@ -157,6 +157,9 @@ struct vfsmount *nfs_d_automount(struct path *path) · 156 unmodified lines
157 if (IS_ERR(mnt))157 if (IS_ERR(mnt))
158 goto out;158 goto out;
159 159
160 if (nfs_mountpoint_expiry_timeout < 0)
161 goto out;
162
160 mntget(mnt); /* prevent immediate expiration */163 mntget(mnt); /* prevent immediate expiration */
161 mnt_set_expiry(mnt, &nfs_automount_list);164 mnt_set_expiry(mnt, &nfs_automount_list);
162 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);165 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
fs/nfs/nfs2xdr.c+8−13
@@ -209,9 +209,9 @@ static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh) · 208 unmodified lines
209 * unsigned int useconds;209 * unsigned int useconds;
210 * };210 * };
211 */211 */
212static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)212static __be32 *xdr_encode_time(__be32 *p, const struct timespec64 *timep)
213{213{
214 *p++ = cpu_to_be32(timep->tv_sec);214 *p++ = cpu_to_be32((u32)timep->tv_sec);
215 if (timep->tv_nsec != 0)215 if (timep->tv_nsec != 0)
216 *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);216 *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
217 else217 else
@@ -227,14 +227,14 @@ static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep) · 9 unmodified lines
227 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.227 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
228 */228 */
229static __be32 *xdr_encode_current_server_time(__be32 *p,229static __be32 *xdr_encode_current_server_time(__be32 *p,
230 const struct timespec *timep)230 const struct timespec64 *timep)
231{231{
232 *p++ = cpu_to_be32(timep->tv_sec);232 *p++ = cpu_to_be32(timep->tv_sec);
233 *p++ = cpu_to_be32(1000000);233 *p++ = cpu_to_be32(1000000);
234 return p;234 return p;
235}235}
236 236
237static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)237static __be32 *xdr_decode_time(__be32 *p, struct timespec64 *timep)
238{238{
239 timep->tv_sec = be32_to_cpup(p++);239 timep->tv_sec = be32_to_cpup(p++);
240 timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;240 timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
@@ -339,7 +339,6 @@ static __be32 *xdr_time_not_set(__be32 *p) · 98 unmodified lines
339static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,339static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
340 struct user_namespace *userns)340 struct user_namespace *userns)
341{341{
342 struct timespec ts;
343 __be32 *p;342 __be32 *p;
344 343
345 p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);344 p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
@@ -362,19 +361,15 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr, · 16 unmodified lines
362 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);361 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
363 362
364 if (attr->ia_valid & ATTR_ATIME_SET) {363 if (attr->ia_valid & ATTR_ATIME_SET) {
365 ts = timespec64_to_timespec(attr->ia_atime);364 p = xdr_encode_time(p, &attr->ia_atime);
366 p = xdr_encode_time(p, &ts);
367 } else if (attr->ia_valid & ATTR_ATIME) {365 } else if (attr->ia_valid & ATTR_ATIME) {
368 ts = timespec64_to_timespec(attr->ia_atime);366 p = xdr_encode_current_server_time(p, &attr->ia_atime);
369 p = xdr_encode_current_server_time(p, &ts);
370 } else367 } else
371 p = xdr_time_not_set(p);368 p = xdr_time_not_set(p);
372 if (attr->ia_valid & ATTR_MTIME_SET) {369 if (attr->ia_valid & ATTR_MTIME_SET) {
373 ts = timespec64_to_timespec(attr->ia_atime);370 xdr_encode_time(p, &attr->ia_mtime);
374 xdr_encode_time(p, &ts);
375 } else if (attr->ia_valid & ATTR_MTIME) {371 } else if (attr->ia_valid & ATTR_MTIME) {
376 ts = timespec64_to_timespec(attr->ia_mtime);372 xdr_encode_current_server_time(p, &attr->ia_mtime);
377 xdr_encode_current_server_time(p, &ts);
378 } else373 } else
379 xdr_time_not_set(p);374 xdr_time_not_set(p);
380}375}
fs/nfs/nfs3client.c+4−1
@@ -106,7 +106,10 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv, · 105 unmodified lines
106 cl_init.nconnect = mds_clp->cl_nconnect;106 cl_init.nconnect = mds_clp->cl_nconnect;
107 107
108 if (mds_srv->flags & NFS_MOUNT_NORESVPORT)108 if (mds_srv->flags & NFS_MOUNT_NORESVPORT)
109 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);109 __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
110
111 __set_bit(NFS_CS_NOPING, &cl_init.init_flags);
112 __set_bit(NFS_CS_DS, &cl_init.init_flags);
110 113
111 /* Use the MDS nfs_client cl_ipaddr. */114 /* Use the MDS nfs_client cl_ipaddr. */
112 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);115 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
fs/nfs/nfs3xdr.c+5−9
@@ -456,14 +456,14 @@ static void zero_nfs_fh3(struct nfs_fh *fh) · 455 unmodified lines
456 * uint32 nseconds;456 * uint32 nseconds;
457 * };457 * };
458 */458 */
459static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)459static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec64 *timep)
460{460{
461 *p++ = cpu_to_be32(timep->tv_sec);461 *p++ = cpu_to_be32((u32)timep->tv_sec);
462 *p++ = cpu_to_be32(timep->tv_nsec);462 *p++ = cpu_to_be32(timep->tv_nsec);
463 return p;463 return p;
464}464}
465 465
466static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep)466static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec64 *timep)
467{467{
468 timep->tv_sec = be32_to_cpup(p++);468 timep->tv_sec = be32_to_cpup(p++);
469 timep->tv_nsec = be32_to_cpup(p++);469 timep->tv_nsec = be32_to_cpup(p++);
@@ -533,7 +533,6 @@ static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep) · 63 unmodified lines
533static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,533static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
534 struct user_namespace *userns)534 struct user_namespace *userns)
535{535{
536 struct timespec ts;
537 u32 nbytes;536 u32 nbytes;
538 __be32 *p;537 __be32 *p;
539 538
@@ -583,10 +582,8 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr, · 43 unmodified lines
583 *p++ = xdr_zero;582 *p++ = xdr_zero;
584 583
585 if (attr->ia_valid & ATTR_ATIME_SET) {584 if (attr->ia_valid & ATTR_ATIME_SET) {
586 struct timespec ts;
587 *p++ = xdr_two;585 *p++ = xdr_two;
588 ts = timespec64_to_timespec(attr->ia_atime);586 p = xdr_encode_nfstime3(p, &attr->ia_atime);
589 p = xdr_encode_nfstime3(p, &ts);
590 } else if (attr->ia_valid & ATTR_ATIME) {587 } else if (attr->ia_valid & ATTR_ATIME) {
591 *p++ = xdr_one;588 *p++ = xdr_one;
592 } else589 } else
@@ -594,8 +591,7 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr, · 1 unmodified line
594 591
595 if (attr->ia_valid & ATTR_MTIME_SET) {592 if (attr->ia_valid & ATTR_MTIME_SET) {
596 *p++ = xdr_two;593 *p++ = xdr_two;
597 ts = timespec64_to_timespec(attr->ia_mtime);594 xdr_encode_nfstime3(p, &attr->ia_mtime);
598 xdr_encode_nfstime3(p, &ts);
599 } else if (attr->ia_valid & ATTR_MTIME) {595 } else if (attr->ia_valid & ATTR_MTIME) {
600 *p = xdr_one;596 *p = xdr_one;
601 } else597 } else
fs/nfs/nfs42.h+14−1
@@ -13,8 +13,10 @@ · 12 unmodified lines
13#define PNFS_LAYOUTSTATS_MAXDEV (4)13#define PNFS_LAYOUTSTATS_MAXDEV (4)
14 14
15/* nfs4.2proc.c */15/* nfs4.2proc.c */
16#ifdef CONFIG_NFS_V4_2
16int nfs42_proc_allocate(struct file *, loff_t, loff_t);17int nfs42_proc_allocate(struct file *, loff_t, loff_t);
17ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t);18ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t,
19 struct nl4_server *, nfs4_stateid *, bool);
18int nfs42_proc_deallocate(struct file *, loff_t, loff_t);20int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
19loff_t nfs42_proc_llseek(struct file *, loff_t, int);21loff_t nfs42_proc_llseek(struct file *, loff_t, int);
20int nfs42_proc_layoutstats_generic(struct nfs_server *,22int nfs42_proc_layoutstats_generic(struct nfs_server *,
@@ -23,5 +25,16 @@ int nfs42_proc_clone(struct file *, struct file *, loff_t, loff_t, loff_t); · 2 unmodified lines
23int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,25int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,
24 const struct nfs42_layout_error *errors,26 const struct nfs42_layout_error *errors,
25 size_t n);27 size_t n);
28int nfs42_proc_copy_notify(struct file *, struct file *,
29 struct nfs42_copy_notify_res *);
30static inline bool nfs42_files_from_same_server(struct file *in,
31 struct file *out)
32{
33 struct nfs_client *c_in = (NFS_SERVER(file_inode(in)))->nfs_client;
34 struct nfs_client *c_out = (NFS_SERVER(file_inode(out)))->nfs_client;
26 35
36 return nfs4_check_serverowner_major_id(c_in->cl_serverowner,
37 c_out->cl_serverowner);
38}
39#endif /* CONFIG_NFS_V4_2 */
27#endif /* __LINUX_FS_NFS_NFS4_2_H */40#endif /* __LINUX_FS_NFS_NFS4_2_H */
fs/nfs/nfs42proc.c+168−33
@@ -3,6 +3,7 @@ · 2 unmodified lines
3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4 */4 */
5#include <linux/fs.h>5#include <linux/fs.h>
6#include <linux/sunrpc/addr.h>
6#include <linux/sunrpc/sched.h>7#include <linux/sunrpc/sched.h>
7#include <linux/nfs.h>8#include <linux/nfs.h>
8#include <linux/nfs3.h>9#include <linux/nfs3.h>
@@ -15,10 +16,30 @@ · 6 unmodified lines
15#include "pnfs.h"16#include "pnfs.h"
16#include "nfs4session.h"17#include "nfs4session.h"
17#include "internal.h"18#include "internal.h"
19#include "delegation.h"
18 20
19#define NFSDBG_FACILITY NFSDBG_PROC21#define NFSDBG_FACILITY NFSDBG_PROC
20static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);22static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
21 23
24static void nfs42_set_netaddr(struct file *filep, struct nfs42_netaddr *naddr)
25{
26 struct nfs_client *clp = (NFS_SERVER(file_inode(filep)))->nfs_client;
27 unsigned short port = 2049;
28
29 rcu_read_lock();
30 naddr->netid_len = scnprintf(naddr->netid,
31 sizeof(naddr->netid), "%s",
32 rpc_peeraddr2str(clp->cl_rpcclient,
33 RPC_DISPLAY_NETID));
34 naddr->addr_len = scnprintf(naddr->addr,
35 sizeof(naddr->addr),
36 "%s.%u.%u",
37 rpc_peeraddr2str(clp->cl_rpcclient,
38 RPC_DISPLAY_ADDR),
39 port >> 8, port & 255);
40 rcu_read_unlock();
41}
42
22static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,43static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
23 struct nfs_lock_context *lock, loff_t offset, loff_t len)44 struct nfs_lock_context *lock, loff_t offset, loff_t len)
24{45{
@@ -28,7 +49,7 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, · 3 unmodified lines
28 .falloc_fh = NFS_FH(inode),49 .falloc_fh = NFS_FH(inode),
29 .falloc_offset = offset,50 .falloc_offset = offset,
30 .falloc_length = len,51 .falloc_length = len,
31 .falloc_bitmask = server->cache_consistency_bitmask,52 .falloc_bitmask = nfs4_fattr_bitmap,
32 };53 };
33 struct nfs42_falloc_res res = {54 struct nfs42_falloc_res res = {
34 .falloc_server = server,55 .falloc_server = server,
@@ -132,22 +153,26 @@ out_unlock: · 97 unmodified lines
132}153}
133 154
134static int handle_async_copy(struct nfs42_copy_res *res,155static int handle_async_copy(struct nfs42_copy_res *res,
135 struct nfs_server *server,156 struct nfs_server *dst_server,
157 struct nfs_server *src_server,
136 struct file *src,158 struct file *src,
137 struct file *dst,159 struct file *dst,
138 nfs4_stateid *src_stateid)160 nfs4_stateid *src_stateid,
161 bool *restart)
139{162{
140 struct nfs4_copy_state *copy, *tmp_copy;163 struct nfs4_copy_state *copy, *tmp_copy;
141 int status = NFS4_OK;164 int status = NFS4_OK;
142 bool found_pending = false;165 bool found_pending = false;
143 struct nfs_open_context *ctx = nfs_file_open_context(dst);166 struct nfs_open_context *dst_ctx = nfs_file_open_context(dst);
167 struct nfs_open_context *src_ctx = nfs_file_open_context(src);
144 168
145 copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);169 copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
146 if (!copy)170 if (!copy)
147 return -ENOMEM;171 return -ENOMEM;
148 172
149 spin_lock(&server->nfs_client->cl_lock);173 spin_lock(&dst_server->nfs_client->cl_lock);
150 list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids,174 list_for_each_entry(tmp_copy,
175 &dst_server->nfs_client->pending_cb_stateids,
151 copies) {176 copies) {
152 if (memcmp(&res->write_res.stateid, &tmp_copy->stateid,177 if (memcmp(&res->write_res.stateid, &tmp_copy->stateid,
153 NFS4_STATEID_SIZE))178 NFS4_STATEID_SIZE))
@@ -157,7 +182,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, · 3 unmodified lines
157 break;182 break;
158 }183 }
159 if (found_pending) {184 if (found_pending) {
160 spin_unlock(&server->nfs_client->cl_lock);185 spin_unlock(&dst_server->nfs_client->cl_lock);
161 kfree(copy);186 kfree(copy);
162 copy = tmp_copy;187 copy = tmp_copy;
163 goto out;188 goto out;
@@ -165,19 +190,32 @@ static int handle_async_copy(struct nfs42_copy_res *res, · 1 unmodified line
165 190
166 memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);191 memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
167 init_completion(&copy->completion);192 init_completion(&copy->completion);
168 copy->parent_state = ctx->state;193 copy->parent_dst_state = dst_ctx->state;
194 copy->parent_src_state = src_ctx->state;
169 195
170 list_add_tail(&copy->copies, &server->ss_copies);196 list_add_tail(&copy->copies, &dst_server->ss_copies);
171 spin_unlock(&server->nfs_client->cl_lock);197 spin_unlock(&dst_server->nfs_client->cl_lock);
198
199 if (dst_server != src_server) {
200 spin_lock(&src_server->nfs_client->cl_lock);
201 list_add_tail(&copy->src_copies, &src_server->ss_copies);
202 spin_unlock(&src_server->nfs_client->cl_lock);
203 }
172 204
173 status = wait_for_completion_interruptible(&copy->completion);205 status = wait_for_completion_interruptible(&copy->completion);
174 spin_lock(&server->nfs_client->cl_lock);206 spin_lock(&dst_server->nfs_client->cl_lock);
175 list_del_init(&copy->copies);207 list_del_init(&copy->copies);
176 spin_unlock(&server->nfs_client->cl_lock);208 spin_unlock(&dst_server->nfs_client->cl_lock);
209 if (dst_server != src_server) {
210 spin_lock(&src_server->nfs_client->cl_lock);
211 list_del_init(&copy->src_copies);
212 spin_unlock(&src_server->nfs_client->cl_lock);
213 }
177 if (status == -ERESTARTSYS) {214 if (status == -ERESTARTSYS) {
178 goto out_cancel;215 goto out_cancel;
179 } else if (copy->flags) {216 } else if (copy->flags || copy->error == NFS4ERR_PARTNER_NO_AUTH) {
180 status = -EAGAIN;217 status = -EAGAIN;
218 *restart = true;
181 goto out_cancel;219 goto out_cancel;
182 }220 }
183out:221out:
@@ -185,12 +223,14 @@ out: · 1 unmodified line
185 memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));223 memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));
186 status = -copy->error;224 status = -copy->error;
187 225
226out_free:
188 kfree(copy);227 kfree(copy);
189 return status;228 return status;
190out_cancel:229out_cancel:
191 nfs42_do_offload_cancel_async(dst, &copy->stateid);230 nfs42_do_offload_cancel_async(dst, &copy->stateid);
192 kfree(copy);231 if (!nfs42_files_from_same_server(src, dst))
193 return status;232 nfs42_do_offload_cancel_async(src, src_stateid);
233 goto out_free;
194}234}
195 235
196static int process_copy_commit(struct file *dst, loff_t pos_dst,236static int process_copy_commit(struct file *dst, loff_t pos_dst,
@@ -222,7 +262,10 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 25 unmodified lines
222 struct file *dst,262 struct file *dst,
223 struct nfs_lock_context *dst_lock,263 struct nfs_lock_context *dst_lock,
224 struct nfs42_copy_args *args,264 struct nfs42_copy_args *args,
225 struct nfs42_copy_res *res)265 struct nfs42_copy_res *res,
266 struct nl4_server *nss,
267 nfs4_stateid *cnr_stateid,
268 bool *restart)
226{269{
227 struct rpc_message msg = {270 struct rpc_message msg = {
228 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],271 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
@@ -230,17 +273,23 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 1 unmodified line
230 .rpc_resp = res,273 .rpc_resp = res,
231 };274 };
232 struct inode *dst_inode = file_inode(dst);275 struct inode *dst_inode = file_inode(dst);
233 struct nfs_server *server = NFS_SERVER(dst_inode);276 struct inode *src_inode = file_inode(src);
277 struct nfs_server *dst_server = NFS_SERVER(dst_inode);
278 struct nfs_server *src_server = NFS_SERVER(src_inode);
234 loff_t pos_src = args->src_pos;279 loff_t pos_src = args->src_pos;
235 loff_t pos_dst = args->dst_pos;280 loff_t pos_dst = args->dst_pos;
236 size_t count = args->count;281 size_t count = args->count;
237 ssize_t status;282 ssize_t status;
238 283
239 status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,284 if (nss) {
240 src_lock, FMODE_READ);285 args->cp_src = nss;
241 if (status)286 nfs4_stateid_copy(&args->src_stateid, cnr_stateid);
242 return status;287 } else {
243 288 status = nfs4_set_rw_stateid(&args->src_stateid,
289 src_lock->open_context, src_lock, FMODE_READ);
290 if (status)
291 return status;
292 }
244 status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,293 status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
245 pos_src, pos_src + (loff_t)count - 1);294 pos_src, pos_src + (loff_t)count - 1);
246 if (status)295 if (status)
@@ -262,13 +311,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 15 unmodified lines
262 if (!res->commit_res.verf)311 if (!res->commit_res.verf)
263 return -ENOMEM;312 return -ENOMEM;
264 }313 }
314 set_bit(NFS_CLNT_SRC_SSC_COPY_STATE,
315 &src_lock->open_context->state->flags);
265 set_bit(NFS_CLNT_DST_SSC_COPY_STATE,316 set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
266 &dst_lock->open_context->state->flags);317 &dst_lock->open_context->state->flags);
267 318
268 status = nfs4_call_sync(server->client, server, &msg,319 status = nfs4_call_sync(dst_server->client, dst_server, &msg,
269 &args->seq_args, &res->seq_res, 0);320 &args->seq_args, &res->seq_res, 0);
270 if (status == -ENOTSUPP)321 if (status == -ENOTSUPP)
271 server->caps &= ~NFS_CAP_COPY;322 dst_server->caps &= ~NFS_CAP_COPY;
272 if (status)323 if (status)
273 goto out;324 goto out;
274 325
@@ -280,8 +331,8 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 5 unmodified lines
280 }331 }
281 332
282 if (!res->synchronous) {333 if (!res->synchronous) {
283 status = handle_async_copy(res, server, src, dst,334 status = handle_async_copy(res, dst_server, src_server, src,
284 &args->src_stateid);335 dst, &args->src_stateid, restart);
285 if (status)336 if (status)
286 return status;337 return status;
287 }338 }
@@ -304,8 +355,9 @@ out: · 16 unmodified lines
304}355}
305 356
306ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,357ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
307 struct file *dst, loff_t pos_dst,358 struct file *dst, loff_t pos_dst, size_t count,
308 size_t count)359 struct nl4_server *nss,
360 nfs4_stateid *cnr_stateid, bool sync)
309{361{
310 struct nfs_server *server = NFS_SERVER(file_inode(dst));362 struct nfs_server *server = NFS_SERVER(file_inode(dst));
311 struct nfs_lock_context *src_lock;363 struct nfs_lock_context *src_lock;
@@ -316,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, · 4 unmodified lines
316 .dst_fh = NFS_FH(file_inode(dst)),368 .dst_fh = NFS_FH(file_inode(dst)),
317 .dst_pos = pos_dst,369 .dst_pos = pos_dst,
318 .count = count,370 .count = count,
319 .sync = false,371 .sync = sync,
320 };372 };
321 struct nfs42_copy_res res;373 struct nfs42_copy_res res;
322 struct nfs4_exception src_exception = {374 struct nfs4_exception src_exception = {
@@ -328,6 +380,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, · 5 unmodified lines
328 .stateid = &args.dst_stateid,380 .stateid = &args.dst_stateid,
329 };381 };
330 ssize_t err, err2;382 ssize_t err, err2;
383 bool restart = false;
331 384
332 src_lock = nfs_get_lock_context(nfs_file_open_context(src));385 src_lock = nfs_get_lock_context(nfs_file_open_context(src));
333 if (IS_ERR(src_lock))386 if (IS_ERR(src_lock))
@@ -347,21 +400,33 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, · 13 unmodified lines
347 inode_lock(file_inode(dst));400 inode_lock(file_inode(dst));
348 err = _nfs42_proc_copy(src, src_lock,401 err = _nfs42_proc_copy(src, src_lock,
349 dst, dst_lock,402 dst, dst_lock,
350 &args, &res);403 &args, &res,
404 nss, cnr_stateid, &restart);
351 inode_unlock(file_inode(dst));405 inode_unlock(file_inode(dst));
352 406
353 if (err >= 0)407 if (err >= 0)
354 break;408 break;
355 if (err == -ENOTSUPP) {409 if (err == -ENOTSUPP &&
410 nfs42_files_from_same_server(src, dst)) {
356 err = -EOPNOTSUPP;411 err = -EOPNOTSUPP;
357 break;412 break;
358 } else if (err == -EAGAIN) {413 } else if (err == -EAGAIN) {
359 dst_exception.retry = 1;414 if (!restart) {
360 continue;415 dst_exception.retry = 1;
416 continue;
417 }
418 break;
361 } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {419 } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
362 args.sync = true;420 args.sync = true;
363 dst_exception.retry = 1;421 dst_exception.retry = 1;
364 continue;422 continue;
423 } else if ((err == -ESTALE ||
424 err == -NFS4ERR_OFFLOAD_DENIED ||
425 err == -ENOTSUPP) &&
426 !nfs42_files_from_same_server(src, dst)) {
427 nfs42_do_offload_cancel_async(src, &args.src_stateid);
428 err = -EOPNOTSUPP;
429 break;
365 }430 }
366 431
367 err2 = nfs4_handle_exception(server, err, &src_exception);432 err2 = nfs4_handle_exception(server, err, &src_exception);
@@ -459,6 +524,76 @@ static int nfs42_do_offload_cancel_async(struct file *dst, · 91 unmodified lines
459 return status;524 return status;
460}525}
461 526
527static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
528 struct nfs42_copy_notify_args *args,
529 struct nfs42_copy_notify_res *res)
530{
531 struct nfs_server *src_server = NFS_SERVER(file_inode(src));
532 struct rpc_message msg = {
533 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY_NOTIFY],
534 .rpc_argp = args,
535 .rpc_resp = res,
536 };
537 int status;
538 struct nfs_open_context *ctx;
539 struct nfs_lock_context *l_ctx;
540
541 ctx = get_nfs_open_context(nfs_file_open_context(src));
542 l_ctx = nfs_get_lock_context(ctx);
543 if (IS_ERR(l_ctx))
544 return PTR_ERR(l_ctx);
545
546 status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx,
547 FMODE_READ);
548 nfs_put_lock_context(l_ctx);
549 if (status)
550 return status;
551
552 status = nfs4_call_sync(src_server->client, src_server, &msg,
553 &args->cna_seq_args, &res->cnr_seq_res, 0);
554 if (status == -ENOTSUPP)
555 src_server->caps &= ~NFS_CAP_COPY_NOTIFY;
556
557 put_nfs_open_context(nfs_file_open_context(src));
558 return status;
559}
560
561int nfs42_proc_copy_notify(struct file *src, struct file *dst,
562 struct nfs42_copy_notify_res *res)
563{
564 struct nfs_server *src_server = NFS_SERVER(file_inode(src));
565 struct nfs42_copy_notify_args *args;
566 struct nfs4_exception exception = {
567 .inode = file_inode(src),
568 };
569 int status;
570
571 if (!(src_server->caps & NFS_CAP_COPY_NOTIFY))
572 return -EOPNOTSUPP;
573
574 args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_NOFS);
575 if (args == NULL)
576 return -ENOMEM;
577
578 args->cna_src_fh = NFS_FH(file_inode(src)),
579 args->cna_dst.nl4_type = NL4_NETADDR;
580 nfs42_set_netaddr(dst, &args->cna_dst.u.nl4_addr);
581 exception.stateid = &args->cna_src_stateid;
582
583 do {
584 status = _nfs42_proc_copy_notify(src, dst, args, res);
585 if (status == -ENOTSUPP) {
586 status = -EOPNOTSUPP;
587 goto out;
588 }
589 status = nfs4_handle_exception(src_server, status, &exception);
590 } while (exception.retry);
591
592out:
593 kfree(args);
594 return status;
595}
596
462static loff_t _nfs42_proc_llseek(struct file *filep,597static loff_t _nfs42_proc_llseek(struct file *filep,
463 struct nfs_lock_context *lock, loff_t offset, int whence)598 struct nfs_lock_context *lock, loff_t offset, int whence)
464{599{
fs/nfs/nfs42xdr.c+188−2
@@ -21,7 +21,10 @@ · 20 unmodified lines
21#define encode_copy_maxsz (op_encode_hdr_maxsz + \21#define encode_copy_maxsz (op_encode_hdr_maxsz + \
22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 XDR_QUADLEN(NFS4_STATEID_SIZE) + \23 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
24 2 + 2 + 2 + 1 + 1 + 1)24 2 + 2 + 2 + 1 + 1 + 1 +\
25 1 + /* One cnr_source_server */\
26 1 + /* nl4_type */ \
27 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
25#define decode_copy_maxsz (op_decode_hdr_maxsz + \28#define decode_copy_maxsz (op_decode_hdr_maxsz + \
26 NFS42_WRITE_RES_SIZE + \29 NFS42_WRITE_RES_SIZE + \
27 1 /* cr_consecutive */ + \30 1 /* cr_consecutive */ + \
@@ -29,6 +32,16 @@ · 1 unmodified line
29#define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \32#define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
30 XDR_QUADLEN(NFS4_STATEID_SIZE))33 XDR_QUADLEN(NFS4_STATEID_SIZE))
31#define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)34#define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
35#define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \
36 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
37 1 + /* nl4_type */ \
38 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
39#define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \
40 3 + /* cnr_lease_time */\
41 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
42 1 + /* Support 1 cnr_source_server */\
43 1 + /* nl4_type */ \
44 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
32#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \45#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
33 encode_fallocate_maxsz)46 encode_fallocate_maxsz)
34#define decode_deallocate_maxsz (op_decode_hdr_maxsz)47#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
@@ -99,6 +112,12 @@ · 64 unmodified lines
99 decode_sequence_maxsz + \112 decode_sequence_maxsz + \
100 decode_putfh_maxsz + \113 decode_putfh_maxsz + \
101 decode_offload_cancel_maxsz)114 decode_offload_cancel_maxsz)
115#define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \
116 encode_putfh_maxsz + \
117 encode_copy_notify_maxsz)
118#define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \
119 decode_putfh_maxsz + \
120 decode_copy_notify_maxsz)
102#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \121#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
103 encode_sequence_maxsz + \122 encode_sequence_maxsz + \
104 encode_putfh_maxsz + \123 encode_putfh_maxsz + \
@@ -166,6 +185,26 @@ static void encode_allocate(struct xdr_stream *xdr, · 61 unmodified lines
166 encode_fallocate(xdr, args);185 encode_fallocate(xdr, args);
167}186}
168 187
188static void encode_nl4_server(struct xdr_stream *xdr,
189 const struct nl4_server *ns)
190{
191 encode_uint32(xdr, ns->nl4_type);
192 switch (ns->nl4_type) {
193 case NL4_NAME:
194 case NL4_URL:
195 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
196 break;
197 case NL4_NETADDR:
198 encode_string(xdr, ns->u.nl4_addr.netid_len,
199 ns->u.nl4_addr.netid);
200 encode_string(xdr, ns->u.nl4_addr.addr_len,
201 ns->u.nl4_addr.addr);
202 break;
203 default:
204 WARN_ON_ONCE(1);
205 }
206}
207
169static void encode_copy(struct xdr_stream *xdr,208static void encode_copy(struct xdr_stream *xdr,
170 const struct nfs42_copy_args *args,209 const struct nfs42_copy_args *args,
171 struct compound_hdr *hdr)210 struct compound_hdr *hdr)
@@ -180,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr, · 8 unmodified lines
180 219
181 encode_uint32(xdr, 1); /* consecutive = true */220 encode_uint32(xdr, 1); /* consecutive = true */
182 encode_uint32(xdr, args->sync);221 encode_uint32(xdr, args->sync);
183 encode_uint32(xdr, 0); /* src server list */222 if (args->cp_src == NULL) { /* intra-ssc */
223 encode_uint32(xdr, 0); /* no src server list */
224 return;
225 }
226 encode_uint32(xdr, 1); /* supporting 1 server */
227 encode_nl4_server(xdr, args->cp_src);
184}228}
185 229
186static void encode_offload_cancel(struct xdr_stream *xdr,230static void encode_offload_cancel(struct xdr_stream *xdr,
@@ -191,6 +235,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr, · 4 unmodified lines
191 encode_nfs4_stateid(xdr, &args->osa_stateid);235 encode_nfs4_stateid(xdr, &args->osa_stateid);
192}236}
193 237
238static void encode_copy_notify(struct xdr_stream *xdr,
239 const struct nfs42_copy_notify_args *args,
240 struct compound_hdr *hdr)
241{
242 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
243 encode_nfs4_stateid(xdr, &args->cna_src_stateid);
244 encode_nl4_server(xdr, &args->cna_dst);
245}
246
194static void encode_deallocate(struct xdr_stream *xdr,247static void encode_deallocate(struct xdr_stream *xdr,
195 const struct nfs42_falloc_args *args,248 const struct nfs42_falloc_args *args,
196 struct compound_hdr *hdr)249 struct compound_hdr *hdr)
@@ -354,6 +407,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, · 157 unmodified lines
354 encode_nops(&hdr);407 encode_nops(&hdr);
355}408}
356 409
410/*
411 * Encode COPY_NOTIFY request
412 */
413static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
414 struct xdr_stream *xdr,
415 const void *data)
416{
417 const struct nfs42_copy_notify_args *args = data;
418 struct compound_hdr hdr = {
419 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
420 };
421
422 encode_compound_hdr(xdr, req, &hdr);
423 encode_sequence(xdr, &args->cna_seq_args, &hdr);
424 encode_putfh(xdr, args->cna_src_fh, &hdr);
425 encode_copy_notify(xdr, args, &hdr);
426 encode_nops(&hdr);
427}
428
357/*429/*
358 * Encode DEALLOCATE request430 * Encode DEALLOCATE request
359 */431 */
@@ -490,6 +562,58 @@ static int decode_write_response(struct xdr_stream *xdr, · 130 unmodified lines
490 return decode_verifier(xdr, &res->verifier.verifier);562 return decode_verifier(xdr, &res->verifier.verifier);
491}563}
492 564
565static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
566{
567 struct nfs42_netaddr *naddr;
568 uint32_t dummy;
569 char *dummy_str;
570 __be32 *p;
571 int status;
572
573 /* nl_type */
574 p = xdr_inline_decode(xdr, 4);
575 if (unlikely(!p))
576 return -EIO;
577 ns->nl4_type = be32_to_cpup(p);
578 switch (ns->nl4_type) {
579 case NL4_NAME:
580 case NL4_URL:
581 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
582 if (unlikely(status))
583 return status;
584 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
585 return -EIO;
586 memcpy(&ns->u.nl4_str, dummy_str, dummy);
587 ns->u.nl4_str_sz = dummy;
588 break;
589 case NL4_NETADDR:
590 naddr = &ns->u.nl4_addr;
591
592 /* netid string */
593 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
594 if (unlikely(status))
595 return status;
596 if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
597 return -EIO;
598 naddr->netid_len = dummy;
599 memcpy(naddr->netid, dummy_str, naddr->netid_len);
600
601 /* uaddr string */
602 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
603 if (unlikely(status))
604 return status;
605 if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
606 return -EIO;
607 naddr->addr_len = dummy;
608 memcpy(naddr->addr, dummy_str, naddr->addr_len);
609 break;
610 default:
611 WARN_ON_ONCE(1);
612 return -EIO;
613 }
614 return 0;
615}
616
493static int decode_copy_requirements(struct xdr_stream *xdr,617static int decode_copy_requirements(struct xdr_stream *xdr,
494 struct nfs42_copy_res *res) {618 struct nfs42_copy_res *res) {
495 __be32 *p;619 __be32 *p;
@@ -529,6 +653,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr, · 33 unmodified lines
529 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);653 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
530}654}
531 655
656static int decode_copy_notify(struct xdr_stream *xdr,
657 struct nfs42_copy_notify_res *res)
658{
659 __be32 *p;
660 int status, count;
661
662 status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
663 if (status)
664 return status;
665 /* cnr_lease_time */
666 p = xdr_inline_decode(xdr, 12);
667 if (unlikely(!p))
668 return -EIO;
669 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
670 res->cnr_lease_time.nseconds = be32_to_cpup(p);
671
672 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
673 if (unlikely(status))
674 return -EIO;
675
676 /* number of source addresses */
677 p = xdr_inline_decode(xdr, 4);
678 if (unlikely(!p))
679 return -EIO;
680
681 count = be32_to_cpup(p);
682 if (count > 1)
683 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
684 __func__, count);
685
686 status = decode_nl4_server(xdr, &res->cnr_src);
687 if (unlikely(status))
688 return -EIO;
689 return 0;
690}
691
532static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)692static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
533{693{
534 return decode_op_hdr(xdr, OP_DEALLOCATE);694 return decode_op_hdr(xdr, OP_DEALLOCATE);
@@ -656,6 +816,32 @@ out: · 121 unmodified lines
656 return status;816 return status;
657}817}
658 818
819/*
820 * Decode COPY_NOTIFY response
821 */
822static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
823 struct xdr_stream *xdr,
824 void *data)
825{
826 struct nfs42_copy_notify_res *res = data;
827 struct compound_hdr hdr;
828 int status;
829
830 status = decode_compound_hdr(xdr, &hdr);
831 if (status)
832 goto out;
833 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
834 if (status)
835 goto out;
836 status = decode_putfh(xdr);
837 if (status)
838 goto out;
839 status = decode_copy_notify(xdr, res);
840
841out:
842 return status;
843}
844
659/*845/*
660 * Decode DEALLOCATE request846 * Decode DEALLOCATE request
661 */847 */
fs/nfs/nfs4_fs.h+19−2
@@ -166,9 +166,9 @@ enum { · 165 unmodified lines
166 NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */166 NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */
167 NFS_STATE_MAY_NOTIFY_LOCK, /* server may CB_NOTIFY_LOCK */167 NFS_STATE_MAY_NOTIFY_LOCK, /* server may CB_NOTIFY_LOCK */
168 NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */168 NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */
169#ifdef CONFIG_NFS_V4_2
170 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/169 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/
171#endif /* CONFIG_NFS_V4_2 */170 NFS_CLNT_SRC_SSC_COPY_STATE, /* src server open state on client*/
171 NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */
172};172};
173 173
174struct nfs4_state {174struct nfs4_state {
@@ -311,6 +311,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, · 136 unmodified lines
311 const struct nfs_open_context *ctx,311 const struct nfs_open_context *ctx,
312 const struct nfs_lock_context *l_ctx,312 const struct nfs_lock_context *l_ctx,
313 fmode_t fmode);313 fmode_t fmode);
314extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
315 struct nfs_fattr *fattr, struct nfs4_label *label,
316 struct inode *inode);
317extern int update_open_stateid(struct nfs4_state *state,
318 const nfs4_stateid *open_stateid,
319 const nfs4_stateid *deleg_stateid,
320 fmode_t fmode);
314 321
315extern int nfs4_proc_get_lease_time(struct nfs_client *clp,322extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
316 struct nfs_fsinfo *fsinfo);323 struct nfs_fsinfo *fsinfo);
@@ -445,6 +452,8 @@ extern void nfs4_set_lease_period(struct nfs_client *clp, · 128 unmodified lines
445 452
446 453
447/* nfs4state.c */454/* nfs4state.c */
455extern const nfs4_stateid current_stateid;
456
448const struct cred *nfs4_get_clid_cred(struct nfs_client *clp);457const struct cred *nfs4_get_clid_cred(struct nfs_client *clp);
449const struct cred *nfs4_get_machine_cred(struct nfs_client *clp);458const struct cred *nfs4_get_machine_cred(struct nfs_client *clp);
450const struct cred *nfs4_get_renew_cred(struct nfs_client *clp);459const struct cred *nfs4_get_renew_cred(struct nfs_client *clp);
@@ -457,6 +466,8 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, · 6 unmodified lines
457 struct nfs_client **, const struct cred *);466 struct nfs_client **, const struct cred *);
458extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);467extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
459extern void nfs41_notify_server(struct nfs_client *);468extern void nfs41_notify_server(struct nfs_client *);
469bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,
470 struct nfs41_server_owner *o2);
460#else471#else
461static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)472static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
462{473{
@@ -572,6 +583,12 @@ static inline bool nfs4_stateid_is_newer(const nfs4_stateid *s1, const nfs4_stat · 109 unmodified lines
572 return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0;583 return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0;
573}584}
574 585
586static inline bool nfs4_stateid_match_or_older(const nfs4_stateid *dst, const nfs4_stateid *src)
587{
588 return nfs4_stateid_match_other(dst, src) &&
589 !(src->seqid && nfs4_stateid_is_newer(dst, src));
590}
591
575static inline void nfs4_stateid_seqid_inc(nfs4_stateid *s1)592static inline void nfs4_stateid_seqid_inc(nfs4_stateid *s1)
576{593{
577 u32 seqid = be32_to_cpu(s1->seqid);594 u32 seqid = be32_to_cpu(s1->seqid);
fs/nfs/nfs4client.c+8−5
@@ -629,7 +629,7 @@ out: · 628 unmodified lines
629/*629/*
630 * Returns true if the server major ids match630 * Returns true if the server major ids match
631 */631 */
632static bool632bool
633nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,633nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1,
634 struct nfs41_server_owner *o2)634 struct nfs41_server_owner *o2)
635{635{
@@ -879,14 +879,17 @@ static int nfs4_set_client(struct nfs_server *server, · 243 unmodified lines
879 };879 };
880 struct nfs_client *clp;880 struct nfs_client *clp;
881 881
882 if (minorversion > 0 && proto == XPRT_TRANSPORT_TCP)882 if (minorversion == 0)
883 __set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
884 else if (proto == XPRT_TRANSPORT_TCP)
883 cl_init.nconnect = nconnect;885 cl_init.nconnect = nconnect;
886
884 if (server->flags & NFS_MOUNT_NORESVPORT)887 if (server->flags & NFS_MOUNT_NORESVPORT)
885 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);888 __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
886 if (server->options & NFS_OPTION_MIGRATION)889 if (server->options & NFS_OPTION_MIGRATION)
887 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);890 __set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
888 if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))891 if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
889 set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);892 __set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
890 server->port = rpc_get_port(addr);893 server->port = rpc_get_port(addr);
891 894
892 /* Allocate or find a client reference we can use */895 /* Allocate or find a client reference we can use */
fs/nfs/nfs4file.c+139−2
@@ -133,14 +133,55 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, · 132 unmodified lines
133 struct file *file_out, loff_t pos_out,133 struct file *file_out, loff_t pos_out,
134 size_t count, unsigned int flags)134 size_t count, unsigned int flags)
135{135{
136 struct nfs42_copy_notify_res *cn_resp = NULL;
137 struct nl4_server *nss = NULL;
138 nfs4_stateid *cnrs = NULL;
139 ssize_t ret;
140 bool sync = false;
141
136 /* Only offload copy if superblock is the same */142 /* Only offload copy if superblock is the same */
137 if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)143 if (file_in->f_op != &nfs4_file_operations)
138 return -EXDEV;144 return -EXDEV;
139 if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY))145 if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY))
140 return -EOPNOTSUPP;146 return -EOPNOTSUPP;
141 if (file_inode(file_in) == file_inode(file_out))147 if (file_inode(file_in) == file_inode(file_out))
142 return -EOPNOTSUPP;148 return -EOPNOTSUPP;
143 return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);149 /* if the copy size if smaller than 2 RPC payloads, make it
150 * synchronous
151 */
152 if (count <= 2 * NFS_SERVER(file_inode(file_in))->rsize)
153 sync = true;
154retry:
155 if (!nfs42_files_from_same_server(file_in, file_out)) {
156 /* for inter copy, if copy size if smaller than 12 RPC
157 * payloads, fallback to traditional copy. There are
158 * 14 RPCs during an NFSv4.x mount between source/dest
159 * servers.
160 */
161 if (sync ||
162 count <= 14 * NFS_SERVER(file_inode(file_in))->rsize)
163 return -EOPNOTSUPP;
164 cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res),
165 GFP_NOFS);
166 if (unlikely(cn_resp == NULL))
167 return -ENOMEM;
168
169 ret = nfs42_proc_copy_notify(file_in, file_out, cn_resp);
170 if (ret) {
171 ret = -EOPNOTSUPP;
172 goto out;
173 }
174 nss = &cn_resp->cnr_src;
175 cnrs = &cn_resp->cnr_stateid;
176 }
177 ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count,
178 nss, cnrs, sync);
179out:
180 if (!nfs42_files_from_same_server(file_in, file_out))
181 kfree(cn_resp);
182 if (ret == -EAGAIN)
183 goto retry;
184 return ret;
144}185}
145 186
146static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,187static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
@@ -263,6 +304,102 @@ out_unlock: · 116 unmodified lines
263out:304out:
264 return ret < 0 ? ret : count;305 return ret < 0 ? ret : count;
265}306}
307
308static int read_name_gen = 1;
309#define SSC_READ_NAME_BODY "ssc_read_%d"
310
311struct file *
312nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
313 nfs4_stateid *stateid)
314{
315 struct nfs_fattr fattr;
316 struct file *filep, *res;
317 struct nfs_server *server;
318 struct inode *r_ino = NULL;
319 struct nfs_open_context *ctx;
320 struct nfs4_state_owner *sp;
321 char *read_name = NULL;
322 int len, status = 0;
323
324 server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
325
326 nfs_fattr_init(&fattr);
327
328 status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
329 if (status < 0) {
330 res = ERR_PTR(status);
331 goto out;
332 }
333
334 res = ERR_PTR(-ENOMEM);
335 len = strlen(SSC_READ_NAME_BODY) + 16;
336 read_name = kzalloc(len, GFP_NOFS);
337 if (read_name == NULL)
338 goto out;
339 snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
340
341 r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
342 NULL);
343 if (IS_ERR(r_ino)) {
344 res = ERR_CAST(r_ino);
345 goto out_free_name;
346 }
347
348 filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
349 r_ino->i_fop);
350 if (IS_ERR(filep)) {
351 res = ERR_CAST(filep);
352 goto out_free_name;
353 }
354 filep->f_mode |= FMODE_READ;
355
356 ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
357 filep);
358 if (IS_ERR(ctx)) {
359 res = ERR_CAST(ctx);
360 goto out_filep;
361 }
362
363 res = ERR_PTR(-EINVAL);
364 sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL);
365 if (sp == NULL)
366 goto out_ctx;
367
368 ctx->state = nfs4_get_open_state(r_ino, sp);
369 if (ctx->state == NULL)
370 goto out_stateowner;
371
372 set_bit(NFS_SRV_SSC_COPY_STATE, &ctx->state->flags);
373 set_bit(NFS_OPEN_STATE, &ctx->state->flags);
374 memcpy(&ctx->state->open_stateid.other, &stateid->other,
375 NFS4_STATEID_OTHER_SIZE);
376 update_open_stateid(ctx->state, stateid, NULL, filep->f_mode);
377
378 nfs_file_set_open_context(filep, ctx);
379 put_nfs_open_context(ctx);
380
381 file_ra_state_init(&filep->f_ra, filep->f_mapping->host->i_mapping);
382 res = filep;
383out_free_name:
384 kfree(read_name);
385out:
386 return res;
387out_stateowner:
388 nfs4_put_state_owner(sp);
389out_ctx:
390 put_nfs_open_context(ctx);
391out_filep:
392 fput(filep);
393 goto out_free_name;
394}
395EXPORT_SYMBOL_GPL(nfs42_ssc_open);
396void nfs42_ssc_close(struct file *filep)
397{
398 struct nfs_open_context *ctx = nfs_file_open_context(filep);
399
400 ctx->state->flags = 0;
401}
402EXPORT_SYMBOL_GPL(nfs42_ssc_close);
266#endif /* CONFIG_NFS_V4_2 */403#endif /* CONFIG_NFS_V4_2 */
267 404
268const struct file_operations nfs4_file_operations = {405const struct file_operations nfs4_file_operations = {
fs/nfs/nfs4proc.c+46−23
@@ -91,7 +91,6 @@ struct nfs4_opendata; · 90 unmodified lines
91static int _nfs4_recover_proc_open(struct nfs4_opendata *data);91static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
92static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);92static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
93static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);93static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
94static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode);
95static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);94static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
96static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,95static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
97 struct nfs_fattr *fattr, struct iattr *sattr,96 struct nfs_fattr *fattr, struct iattr *sattr,
@@ -476,6 +475,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, · 378 unmodified lines
476 case -NFS4ERR_ADMIN_REVOKED:475 case -NFS4ERR_ADMIN_REVOKED:
477 case -NFS4ERR_EXPIRED:476 case -NFS4ERR_EXPIRED:
478 case -NFS4ERR_BAD_STATEID:477 case -NFS4ERR_BAD_STATEID:
478 case -NFS4ERR_PARTNER_NO_AUTH:
479 if (inode != NULL && stateid != NULL) {479 if (inode != NULL && stateid != NULL) {
480 nfs_inode_find_state_and_recover(inode,480 nfs_inode_find_state_and_recover(inode,
481 stateid);481 stateid);
@@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, · 39 unmodified lines
521 case -NFS4ERR_DEADSESSION:521 case -NFS4ERR_DEADSESSION:
522 case -NFS4ERR_SEQ_FALSE_RETRY:522 case -NFS4ERR_SEQ_FALSE_RETRY:
523 case -NFS4ERR_SEQ_MISORDERED:523 case -NFS4ERR_SEQ_MISORDERED:
524 dprintk("%s ERROR: %d Reset session\n", __func__,524 /* Handled in nfs41_sequence_process() */
525 errorcode);
526 nfs4_schedule_session_recovery(clp->cl_session, errorcode);
527 goto wait_on_recovery;525 goto wait_on_recovery;
528#endif /* defined(CONFIG_NFS_V4_1) */526#endif /* defined(CONFIG_NFS_V4_1) */
529 case -NFS4ERR_FILE_OPEN:527 case -NFS4ERR_FILE_OPEN:
@@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task, · 252 unmodified lines
782 struct nfs4_session *session;780 struct nfs4_session *session;
783 struct nfs4_slot *slot = res->sr_slot;781 struct nfs4_slot *slot = res->sr_slot;
784 struct nfs_client *clp;782 struct nfs_client *clp;
783 int status;
785 int ret = 1;784 int ret = 1;
786 785
787 if (slot == NULL)786 if (slot == NULL)
@@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task, · 5 unmodified lines
793 session = slot->table->session;792 session = slot->table->session;
794 793
795 trace_nfs4_sequence_done(session, res);794 trace_nfs4_sequence_done(session, res);
795
796 status = res->sr_status;
797 if (task->tk_status == -NFS4ERR_DEADSESSION)
798 status = -NFS4ERR_DEADSESSION;
799
796 /* Check the SEQUENCE operation status */800 /* Check the SEQUENCE operation status */
797 switch (res->sr_status) {801 switch (status) {
798 case 0:802 case 0:
799 /* Mark this sequence number as having been acked */803 /* Mark this sequence number as having been acked */
800 nfs4_slot_sequence_acked(slot, slot->seq_nr);804 nfs4_slot_sequence_acked(slot, slot->seq_nr);
@@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task, · 65 unmodified lines
866 */870 */
867 slot->seq_nr = slot->seq_nr_highest_sent;871 slot->seq_nr = slot->seq_nr_highest_sent;
868 goto out_retry;872 goto out_retry;
873 case -NFS4ERR_BADSESSION:
874 case -NFS4ERR_DEADSESSION:
875 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
876 goto session_recover;
869 default:877 default:
870 /* Just update the slot sequence no. */878 /* Just update the slot sequence no. */
871 slot->seq_done = 1;879 slot->seq_done = 1;
@@ -876,8 +884,10 @@ out: · 4 unmodified lines
876out_noaction:884out_noaction:
877 return ret;885 return ret;
878session_recover:886session_recover:
879 nfs4_schedule_session_recovery(session, res->sr_status);887 nfs4_schedule_session_recovery(session, status);
880 goto retry_nowait;888 dprintk("%s ERROR: %d Reset session\n", __func__, status);
889 nfs41_sequence_free_slot(res);
890 goto out;
881retry_new_seq:891retry_new_seq:
882 ++slot->seq_nr;892 ++slot->seq_nr;
883retry_nowait:893retry_nowait:
@@ -1716,7 +1726,7 @@ static void nfs_state_clear_delegation(struct nfs4_state *state) · 832 unmodified lines
1716 write_sequnlock(&state->seqlock);1726 write_sequnlock(&state->seqlock);
1717}1727}
1718 1728
1719static int update_open_stateid(struct nfs4_state *state,1729int update_open_stateid(struct nfs4_state *state,
1720 const nfs4_stateid *open_stateid,1730 const nfs4_stateid *open_stateid,
1721 const nfs4_stateid *delegation,1731 const nfs4_stateid *delegation,
1722 fmode_t fmode)1732 fmode_t fmode)
@@ -1737,7 +1747,7 @@ static int update_open_stateid(struct nfs4_state *state, · 14 unmodified lines
1737 ret = 1;1747 ret = 1;
1738 }1748 }
1739 1749
1740 deleg_cur = rcu_dereference(nfsi->delegation);1750 deleg_cur = nfs4_get_valid_delegation(state->inode);
1741 if (deleg_cur == NULL)1751 if (deleg_cur == NULL)
1742 goto no_delegation;1752 goto no_delegation;
1743 1753
@@ -1749,7 +1759,7 @@ static int update_open_stateid(struct nfs4_state *state, · 5 unmodified lines
1749 1759
1750 if (delegation == NULL)1760 if (delegation == NULL)
1751 delegation = &deleg_cur->stateid;1761 delegation = &deleg_cur->stateid;
1752 else if (!nfs4_stateid_match(&deleg_cur->stateid, delegation))1762 else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
1753 goto no_delegation_unlock;1763 goto no_delegation_unlock;
1754 1764
1755 nfs_mark_delegation_referenced(deleg_cur);1765 nfs_mark_delegation_referenced(deleg_cur);
@@ -1796,7 +1806,7 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo · 40 unmodified lines
1796 1806
1797 fmode &= FMODE_READ|FMODE_WRITE;1807 fmode &= FMODE_READ|FMODE_WRITE;
1798 rcu_read_lock();1808 rcu_read_lock();
1799 delegation = rcu_dereference(NFS_I(inode)->delegation);1809 delegation = nfs4_get_valid_delegation(inode);
1800 if (delegation == NULL || (delegation->type & fmode) == fmode) {1810 if (delegation == NULL || (delegation->type & fmode) == fmode) {
1801 rcu_read_unlock();1811 rcu_read_unlock();
1802 return;1812 return;
@@ -2188,7 +2198,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct · 385 unmodified lines
2188 case -NFS4ERR_BAD_HIGH_SLOT:2198 case -NFS4ERR_BAD_HIGH_SLOT:
2189 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:2199 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
2190 case -NFS4ERR_DEADSESSION:2200 case -NFS4ERR_DEADSESSION:
2191 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
2192 return -EAGAIN;2201 return -EAGAIN;
2193 case -NFS4ERR_STALE_CLIENTID:2202 case -NFS4ERR_STALE_CLIENTID:
2194 case -NFS4ERR_STALE_STATEID:2203 case -NFS4ERR_STALE_STATEID:
@@ -4062,7 +4071,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 1867 unmodified lines
4062 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);4071 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
4063}4072}
4064 4073
4065static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,4074int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
4066 struct nfs_fattr *fattr, struct nfs4_label *label,4075 struct nfs_fattr *fattr, struct nfs4_label *label,
4067 struct inode *inode)4076 struct inode *inode)
4068{4077{
@@ -5098,12 +5107,12 @@ static bool nfs4_stateid_is_current(nfs4_stateid *stateid, · 1029 unmodified lines
5098 const struct nfs_lock_context *l_ctx,5107 const struct nfs_lock_context *l_ctx,
5099 fmode_t fmode)5108 fmode_t fmode)
5100{5109{
5101 nfs4_stateid current_stateid;5110 nfs4_stateid _current_stateid;
5102 5111
5103 /* If the current stateid represents a lost lock, then exit */5112 /* If the current stateid represents a lost lock, then exit */
5104 if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode) == -EIO)5113 if (nfs4_set_rw_stateid(&_current_stateid, ctx, l_ctx, fmode) == -EIO)
5105 return true;5114 return true;
5106 return nfs4_stateid_match(stateid, &current_stateid);5115 return nfs4_stateid_match(stateid, &_current_stateid);
5107}5116}
5108 5117
5109static bool nfs4_error_stateid_expired(int err)5118static bool nfs4_error_stateid_expired(int err)
@@ -6196,10 +6205,13 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) · 1086 unmodified lines
6196 task->tk_status = 0;6205 task->tk_status = 0;
6197 break;6206 break;
6198 case -NFS4ERR_OLD_STATEID:6207 case -NFS4ERR_OLD_STATEID:
6199 if (nfs4_refresh_delegation_stateid(&data->stateid, data->inode))6208 if (!nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
6200 goto out_restart;6209 nfs4_stateid_seqid_inc(&data->stateid);
6201 task->tk_status = 0;6210 if (data->args.bitmask) {
6202 break;6211 data->args.bitmask = NULL;
6212 data->res.fattr = NULL;
6213 }
6214 goto out_restart;
6203 case -NFS4ERR_ACCESS:6215 case -NFS4ERR_ACCESS:
6204 if (data->args.bitmask) {6216 if (data->args.bitmask) {
6205 data->args.bitmask = NULL;6217 data->args.bitmask = NULL;
@@ -6214,6 +6226,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) · 8 unmodified lines
6214 if (exception.retry)6226 if (exception.retry)
6215 goto out_restart;6227 goto out_restart;
6216 }6228 }
6229 nfs_delegation_mark_returned(data->inode, data->args.stateid);
6217 data->rpc_status = task->tk_status;6230 data->rpc_status = task->tk_status;
6218 return;6231 return;
6219out_restart:6232out_restart:
@@ -6243,8 +6256,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data) · 23 unmodified lines
6243 6256
6244 d_data = (struct nfs4_delegreturndata *)data;6257 d_data = (struct nfs4_delegreturndata *)data;
6245 6258
6246 if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task))6259 if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) {
6260 nfs4_sequence_done(task, &d_data->res.seq_res);
6247 return;6261 return;
6262 }
6248 6263
6249 lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL;6264 lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL;
6250 if (lo && !pnfs_layout_is_valid(lo)) {6265 if (lo && !pnfs_layout_is_valid(lo)) {
@@ -7820,6 +7835,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, · 1569 unmodified lines
7820static void7835static void
7821nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)7836nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
7822{7837{
7838 struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
7839 struct nfs_client *clp = args->client;
7840
7841 switch (task->tk_status) {
7842 case -NFS4ERR_BADSESSION:
7843 case -NFS4ERR_DEADSESSION:
7844 nfs4_schedule_session_recovery(clp->cl_session,
7845 task->tk_status);
7846 }
7823}7847}
7824 7848
7825static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {7849static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
@@ -8867,8 +8891,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf · 1041 unmodified lines
8867 case -NFS4ERR_BADSESSION:8891 case -NFS4ERR_BADSESSION:
8868 case -NFS4ERR_DEADSESSION:8892 case -NFS4ERR_DEADSESSION:
8869 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:8893 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
8870 nfs4_schedule_session_recovery(clp->cl_session,
8871 task->tk_status);
8872 break;8894 break;
8873 default:8895 default:
8874 nfs4_schedule_lease_recovery(clp);8896 nfs4_schedule_lease_recovery(clp);
@@ -9897,6 +9919,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { · 1022 unmodified lines
9897 | NFS_CAP_ALLOCATE9919 | NFS_CAP_ALLOCATE
9898 | NFS_CAP_COPY9920 | NFS_CAP_COPY
9899 | NFS_CAP_OFFLOAD_CANCEL9921 | NFS_CAP_OFFLOAD_CANCEL
9922 | NFS_CAP_COPY_NOTIFY
9900 | NFS_CAP_DEALLOCATE9923 | NFS_CAP_DEALLOCATE
9901 | NFS_CAP_SEEK9924 | NFS_CAP_SEEK
9902 | NFS_CAP_LAYOUTSTATS9925 | NFS_CAP_LAYOUTSTATS
fs/nfs/nfs4state.c+43−8
@@ -60,6 +60,7 @@ · 59 unmodified lines
60#include "nfs4session.h"60#include "nfs4session.h"
61#include "pnfs.h"61#include "pnfs.h"
62#include "netns.h"62#include "netns.h"
63#include "nfs4trace.h"
63 64
64#define NFSDBG_FACILITY NFSDBG_STATE65#define NFSDBG_FACILITY NFSDBG_STATE
65 66
@@ -1407,7 +1408,7 @@ nfs_state_find_lock_state_by_stateid(struct nfs4_state *state, · 1341 unmodified lines
1407 list_for_each_entry(pos, &state->lock_states, ls_locks) {1408 list_for_each_entry(pos, &state->lock_states, ls_locks) {
1408 if (!test_bit(NFS_LOCK_INITIALIZED, &pos->ls_flags))1409 if (!test_bit(NFS_LOCK_INITIALIZED, &pos->ls_flags))
1409 continue;1410 continue;
1410 if (nfs4_stateid_match_other(&pos->ls_stateid, stateid))1411 if (nfs4_stateid_match_or_older(&pos->ls_stateid, stateid))
1411 return pos;1412 return pos;
1412 }1413 }
1413 return NULL;1414 return NULL;
@@ -1441,12 +1442,13 @@ void nfs_inode_find_state_and_recover(struct inode *inode, · 27 unmodified lines
1441 state = ctx->state;1442 state = ctx->state;
1442 if (state == NULL)1443 if (state == NULL)
1443 continue;1444 continue;
1444 if (nfs4_stateid_match_other(&state->stateid, stateid) &&1445 if (nfs4_stateid_match_or_older(&state->stateid, stateid) &&
1445 nfs4_state_mark_reclaim_nograce(clp, state)) {1446 nfs4_state_mark_reclaim_nograce(clp, state)) {
1446 found = true;1447 found = true;
1447 continue;1448 continue;
1448 }1449 }
1449 if (nfs4_stateid_match_other(&state->open_stateid, stateid) &&1450 if (test_bit(NFS_OPEN_STATE, &state->flags) &&
1451 nfs4_stateid_match_or_older(&state->open_stateid, stateid) &&
1450 nfs4_state_mark_reclaim_nograce(clp, state)) {1452 nfs4_state_mark_reclaim_nograce(clp, state)) {
1451 found = true;1453 found = true;
1452 continue;1454 continue;
@@ -1556,16 +1558,32 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state · 103 unmodified lines
1556{1558{
1557 struct nfs4_copy_state *copy;1559 struct nfs4_copy_state *copy;
1558 1560
1559 if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags))1561 if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
1562 !test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags))
1560 return;1563 return;
1561 1564
1562 spin_lock(&sp->so_server->nfs_client->cl_lock);1565 spin_lock(&sp->so_server->nfs_client->cl_lock);
1563 list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {1566 list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
1564 if (!nfs4_stateid_match_other(&state->stateid, &copy->parent_state->stateid))1567 if ((test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
1565 continue;1568 !nfs4_stateid_match_other(&state->stateid,
1569 &copy->parent_dst_state->stateid)))
1570 continue;
1566 copy->flags = 1;1571 copy->flags = 1;
1567 complete(&copy->completion);1572 if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
1568 break;1573 &state->flags)) {
1574 clear_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags);
1575 complete(&copy->completion);
1576 }
1577 }
1578 list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
1579 if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
1580 !nfs4_stateid_match_other(&state->stateid,
1581 &copy->parent_src_state->stateid)))
1582 continue;
1583 copy->flags = 1;
1584 if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
1585 &state->flags))
1586 complete(&copy->completion);
1569 }1587 }
1570 spin_unlock(&sp->so_server->nfs_client->cl_lock);1588 spin_unlock(&sp->so_server->nfs_client->cl_lock);
1571}1589}
@@ -1593,6 +1611,7 @@ static int __nfs4_reclaim_open_state(struct nfs4_state_owner *sp, struct nfs4_st · 21 unmodified lines
1593 if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {1611 if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
1594 spin_lock(&state->state_lock);1612 spin_lock(&state->state_lock);
1595 list_for_each_entry(lock, &state->lock_states, ls_locks) {1613 list_for_each_entry(lock, &state->lock_states, ls_locks) {
1614 trace_nfs4_state_lock_reclaim(state, lock);
1596 if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))1615 if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
1597 pr_warn_ratelimited("NFS: %s: Lock reclaim failed!\n", __func__);1616 pr_warn_ratelimited("NFS: %s: Lock reclaim failed!\n", __func__);
1598 }1617 }
@@ -1609,6 +1628,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs · 10 unmodified lines
1609 struct nfs4_state *state;1628 struct nfs4_state *state;
1610 unsigned int loop = 0;1629 unsigned int loop = 0;
1611 int status = 0;1630 int status = 0;
1631#ifdef CONFIG_NFS_V4_2
1632 bool found_ssc_copy_state = false;
1633#endif /* CONFIG_NFS_V4_2 */
1612 1634
1613 /* Note: we rely on the sp->so_states list being ordered 1635 /* Note: we rely on the sp->so_states list being ordered
1614 * so that we always reclaim open(O_RDWR) and/or open(O_WRITE)1636 * so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
@@ -1628,6 +1650,13 @@ restart: · 13 unmodified lines
1628 continue;1650 continue;
1629 if (state->state == 0)1651 if (state->state == 0)
1630 continue;1652 continue;
1653#ifdef CONFIG_NFS_V4_2
1654 if (test_bit(NFS_SRV_SSC_COPY_STATE, &state->flags)) {
1655 nfs4_state_mark_recovery_failed(state, -EIO);
1656 found_ssc_copy_state = true;
1657 continue;
1658 }
1659#endif /* CONFIG_NFS_V4_2 */
1631 refcount_inc(&state->count);1660 refcount_inc(&state->count);
1632 spin_unlock(&sp->so_lock);1661 spin_unlock(&sp->so_lock);
1633 status = __nfs4_reclaim_open_state(sp, state, ops);1662 status = __nfs4_reclaim_open_state(sp, state, ops);
@@ -1682,6 +1711,10 @@ restart: · 48 unmodified lines
1682 }1711 }
1683 raw_write_seqcount_end(&sp->so_reclaim_seqcount);1712 raw_write_seqcount_end(&sp->so_reclaim_seqcount);
1684 spin_unlock(&sp->so_lock);1713 spin_unlock(&sp->so_lock);
1714#ifdef CONFIG_NFS_V4_2
1715 if (found_ssc_copy_state)
1716 return -EIO;
1717#endif /* CONFIG_NFS_V4_2 */
1685 return 0;1718 return 0;
1686out_err:1719out_err:
1687 nfs4_put_open_state(state);1720 nfs4_put_open_state(state);
@@ -2508,6 +2541,7 @@ static void nfs4_state_manager(struct nfs_client *clp) · 820 unmodified lines
2508 2541
2509 /* Ensure exclusive access to NFSv4 state */2542 /* Ensure exclusive access to NFSv4 state */
2510 do {2543 do {
2544 trace_nfs4_state_mgr(clp);
2511 clear_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);2545 clear_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
2512 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {2546 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
2513 section = "purge state";2547 section = "purge state";
@@ -2621,6 +2655,7 @@ static void nfs4_state_manager(struct nfs_client *clp) · 107 unmodified lines
2621out_error:2655out_error:
2622 if (strlen(section))2656 if (strlen(section))
2623 section_sep = ": ";2657 section_sep = ": ";
2658 trace_nfs4_state_mgr_failed(clp, section, status);
2624 pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"2659 pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"
2625 " with error %d\n", section_sep, section,2660 " with error %d\n", section_sep, section,
2626 clp->cl_hostname, -status);2661 clp->cl_hostname, -status);
fs/nfs/nfs4super.c+2−2
@@ -92,8 +92,8 @@ static void nfs4_evict_inode(struct inode *inode) · 91 unmodified lines
92{92{
93 truncate_inode_pages_final(&inode->i_data);93 truncate_inode_pages_final(&inode->i_data);
94 clear_inode(inode);94 clear_inode(inode);
95 /* If we are holding a delegation, return it! */95 /* If we are holding a delegation, return and free it */
96 nfs_inode_return_delegation_noreclaim(inode);96 nfs_inode_evict_delegation(inode);
97 /* Note that above delegreturn would trigger pnfs return-on-close */97 /* Note that above delegreturn would trigger pnfs return-on-close */
98 pnfs_return_layout(inode);98 pnfs_return_layout(inode);
99 pnfs_destroy_layout(NFS_I(inode));99 pnfs_destroy_layout(NFS_I(inode));
fs/nfs/nfs4trace.h+175−0
@@ -562,6 +562,99 @@ TRACE_EVENT(nfs4_setup_sequence, · 561 unmodified lines
562 )562 )
563);563);
564 564
565TRACE_DEFINE_ENUM(NFS4CLNT_MANAGER_RUNNING);
566TRACE_DEFINE_ENUM(NFS4CLNT_CHECK_LEASE);
567TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_EXPIRED);
568TRACE_DEFINE_ENUM(NFS4CLNT_RECLAIM_REBOOT);
569TRACE_DEFINE_ENUM(NFS4CLNT_RECLAIM_NOGRACE);
570TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN);
571TRACE_DEFINE_ENUM(NFS4CLNT_SESSION_RESET);
572TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_CONFIRM);
573TRACE_DEFINE_ENUM(NFS4CLNT_SERVER_SCOPE_MISMATCH);
574TRACE_DEFINE_ENUM(NFS4CLNT_PURGE_STATE);
575TRACE_DEFINE_ENUM(NFS4CLNT_BIND_CONN_TO_SESSION);
576TRACE_DEFINE_ENUM(NFS4CLNT_MOVED);
577TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_MOVED);
578TRACE_DEFINE_ENUM(NFS4CLNT_DELEGATION_EXPIRED);
579TRACE_DEFINE_ENUM(NFS4CLNT_RUN_MANAGER);
580TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN_RUNNING);
581
582#define show_nfs4_clp_state(state) \
583 __print_flags(state, "|", \
584 { NFS4CLNT_MANAGER_RUNNING, "MANAGER_RUNNING" }, \
585 { NFS4CLNT_CHECK_LEASE, "CHECK_LEASE" }, \
586 { NFS4CLNT_LEASE_EXPIRED, "LEASE_EXPIRED" }, \
587 { NFS4CLNT_RECLAIM_REBOOT, "RECLAIM_REBOOT" }, \
588 { NFS4CLNT_RECLAIM_NOGRACE, "RECLAIM_NOGRACE" }, \
589 { NFS4CLNT_DELEGRETURN, "DELEGRETURN" }, \
590 { NFS4CLNT_SESSION_RESET, "SESSION_RESET" }, \
591 { NFS4CLNT_LEASE_CONFIRM, "LEASE_CONFIRM" }, \
592 { NFS4CLNT_SERVER_SCOPE_MISMATCH, \
593 "SERVER_SCOPE_MISMATCH" }, \
594 { NFS4CLNT_PURGE_STATE, "PURGE_STATE" }, \
595 { NFS4CLNT_BIND_CONN_TO_SESSION, \
596 "BIND_CONN_TO_SESSION" }, \
597 { NFS4CLNT_MOVED, "MOVED" }, \
598 { NFS4CLNT_LEASE_MOVED, "LEASE_MOVED" }, \
599 { NFS4CLNT_DELEGATION_EXPIRED, "DELEGATION_EXPIRED" }, \
600 { NFS4CLNT_RUN_MANAGER, "RUN_MANAGER" }, \
601 { NFS4CLNT_DELEGRETURN_RUNNING, "DELEGRETURN_RUNNING" })
602
603TRACE_EVENT(nfs4_state_mgr,
604 TP_PROTO(
605 const struct nfs_client *clp
606 ),
607
608 TP_ARGS(clp),
609
610 TP_STRUCT__entry(
611 __field(unsigned long, state)
612 __string(hostname, clp->cl_hostname)
613 ),
614
615 TP_fast_assign(
616 __entry->state = clp->cl_state;
617 __assign_str(hostname, clp->cl_hostname)
618 ),
619
620 TP_printk(
621 "hostname=%s clp state=%s", __get_str(hostname),
622 show_nfs4_clp_state(__entry->state)
623 )
624)
625
626TRACE_EVENT(nfs4_state_mgr_failed,
627 TP_PROTO(
628 const struct nfs_client *clp,
629 const char *section,
630 int status
631 ),
632
633 TP_ARGS(clp, section, status),
634
635 TP_STRUCT__entry(
636 __field(unsigned long, error)
637 __field(unsigned long, state)
638 __string(hostname, clp->cl_hostname)
639 __string(section, section)
640 ),
641
642 TP_fast_assign(
643 __entry->error = status;
644 __entry->state = clp->cl_state;
645 __assign_str(hostname, clp->cl_hostname);
646 __assign_str(section, section);
647 ),
648
649 TP_printk(
650 "hostname=%s clp state=%s error=%ld (%s) section=%s",
651 __get_str(hostname),
652 show_nfs4_clp_state(__entry->state), -__entry->error,
653 show_nfsv4_errors(__entry->error), __get_str(section)
654
655 )
656)
657
565TRACE_EVENT(nfs4_xdr_status,658TRACE_EVENT(nfs4_xdr_status,
566 TP_PROTO(659 TP_PROTO(
567 const struct xdr_stream *xdr,660 const struct xdr_stream *xdr,
@@ -929,6 +1022,88 @@ TRACE_EVENT(nfs4_set_lock, · 361 unmodified lines
929 )1022 )
930);1023);
931 1024
1025TRACE_DEFINE_ENUM(LK_STATE_IN_USE);
1026TRACE_DEFINE_ENUM(NFS_DELEGATED_STATE);
1027TRACE_DEFINE_ENUM(NFS_OPEN_STATE);
1028TRACE_DEFINE_ENUM(NFS_O_RDONLY_STATE);
1029TRACE_DEFINE_ENUM(NFS_O_WRONLY_STATE);
1030TRACE_DEFINE_ENUM(NFS_O_RDWR_STATE);
1031TRACE_DEFINE_ENUM(NFS_STATE_RECLAIM_REBOOT);
1032TRACE_DEFINE_ENUM(NFS_STATE_RECLAIM_NOGRACE);
1033TRACE_DEFINE_ENUM(NFS_STATE_POSIX_LOCKS);
1034TRACE_DEFINE_ENUM(NFS_STATE_RECOVERY_FAILED);
1035TRACE_DEFINE_ENUM(NFS_STATE_MAY_NOTIFY_LOCK);
1036TRACE_DEFINE_ENUM(NFS_STATE_CHANGE_WAIT);
1037TRACE_DEFINE_ENUM(NFS_CLNT_DST_SSC_COPY_STATE);
1038TRACE_DEFINE_ENUM(NFS_CLNT_SRC_SSC_COPY_STATE);
1039TRACE_DEFINE_ENUM(NFS_SRV_SSC_COPY_STATE);
1040
1041#define show_nfs4_state_flags(flags) \
1042 __print_flags(flags, "|", \
1043 { LK_STATE_IN_USE, "IN_USE" }, \
1044 { NFS_DELEGATED_STATE, "DELEGATED" }, \
1045 { NFS_OPEN_STATE, "OPEN" }, \
1046 { NFS_O_RDONLY_STATE, "O_RDONLY" }, \
1047 { NFS_O_WRONLY_STATE, "O_WRONLY" }, \
1048 { NFS_O_RDWR_STATE, "O_RDWR" }, \
1049 { NFS_STATE_RECLAIM_REBOOT, "RECLAIM_REBOOT" }, \
1050 { NFS_STATE_RECLAIM_NOGRACE, "RECLAIM_NOGRACE" }, \
1051 { NFS_STATE_POSIX_LOCKS, "POSIX_LOCKS" }, \
1052 { NFS_STATE_RECOVERY_FAILED, "RECOVERY_FAILED" }, \
1053 { NFS_STATE_MAY_NOTIFY_LOCK, "MAY_NOTIFY_LOCK" }, \
1054 { NFS_STATE_CHANGE_WAIT, "CHANGE_WAIT" }, \
1055 { NFS_CLNT_DST_SSC_COPY_STATE, "CLNT_DST_SSC_COPY" }, \
1056 { NFS_CLNT_SRC_SSC_COPY_STATE, "CLNT_SRC_SSC_COPY" }, \
1057 { NFS_SRV_SSC_COPY_STATE, "SRV_SSC_COPY" })
1058
1059#define show_nfs4_lock_flags(flags) \
1060 __print_flags(flags, "|", \
1061 { BIT(NFS_LOCK_INITIALIZED), "INITIALIZED" }, \
1062 { BIT(NFS_LOCK_LOST), "LOST" })
1063
1064TRACE_EVENT(nfs4_state_lock_reclaim,
1065 TP_PROTO(
1066 const struct nfs4_state *state,
1067 const struct nfs4_lock_state *lock
1068 ),
1069
1070 TP_ARGS(state, lock),
1071
1072 TP_STRUCT__entry(
1073 __field(dev_t, dev)
1074 __field(u32, fhandle)
1075 __field(u64, fileid)
1076 __field(unsigned long, state_flags)
1077 __field(unsigned long, lock_flags)
1078 __field(int, stateid_seq)
1079 __field(u32, stateid_hash)
1080 ),
1081
1082 TP_fast_assign(
1083 const struct inode *inode = state->inode;
1084
1085 __entry->dev = inode->i_sb->s_dev;
1086 __entry->fileid = NFS_FILEID(inode);
1087 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
1088 __entry->state_flags = state->flags;
1089 __entry->lock_flags = lock->ls_flags;
1090 __entry->stateid_seq =
1091 be32_to_cpu(state->stateid.seqid);
1092 __entry->stateid_hash =
1093 nfs_stateid_hash(&state->stateid);
1094 ),
1095
1096 TP_printk(
1097 "fileid=%02x:%02x:%llu fhandle=0x%08x "
1098 "stateid=%d:0x%08x state_flags=%s lock_flags=%s",
1099 MAJOR(__entry->dev), MINOR(__entry->dev),
1100 (unsigned long long)__entry->fileid, __entry->fhandle,
1101 __entry->stateid_seq, __entry->stateid_hash,
1102 show_nfs4_state_flags(__entry->state_flags),
1103 show_nfs4_lock_flags(__entry->lock_flags)
1104 )
1105)
1106
932DECLARE_EVENT_CLASS(nfs4_set_delegation_event,1107DECLARE_EVENT_CLASS(nfs4_set_delegation_event,
933 TP_PROTO(1108 TP_PROTO(
934 const struct inode *inode,1109 const struct inode *inode,
fs/nfs/nfs4xdr.c+11−13
@@ -1059,7 +1059,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve · 1058 unmodified lines
1059}1059}
1060 1060
1061static __be32 *1061static __be32 *
1062xdr_encode_nfstime4(__be32 *p, const struct timespec *t)1062xdr_encode_nfstime4(__be32 *p, const struct timespec64 *t)
1063{1063{
1064 p = xdr_encode_hyper(p, (__s64)t->tv_sec);1064 p = xdr_encode_hyper(p, (__s64)t->tv_sec);
1065 *p++ = cpu_to_be32(t->tv_nsec);1065 *p++ = cpu_to_be32(t->tv_nsec);
@@ -1072,7 +1072,6 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, · 6 unmodified lines
1072 const struct nfs_server *server,1072 const struct nfs_server *server,
1073 const uint32_t attrmask[])1073 const uint32_t attrmask[])
1074{1074{
1075 struct timespec ts;
1076 char owner_name[IDMAP_NAMESZ];1075 char owner_name[IDMAP_NAMESZ];
1077 char owner_group[IDMAP_NAMESZ];1076 char owner_group[IDMAP_NAMESZ];
1078 int owner_namelen = 0;1077 int owner_namelen = 0;
@@ -1161,16 +1160,14 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, · 82 unmodified lines
1161 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {1160 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
1162 if (iap->ia_valid & ATTR_ATIME_SET) {1161 if (iap->ia_valid & ATTR_ATIME_SET) {
1163 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);1162 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1164 ts = timespec64_to_timespec(iap->ia_atime);1163 p = xdr_encode_nfstime4(p, &iap->ia_atime);
1165 p = xdr_encode_nfstime4(p, &ts);
1166 } else1164 } else
1167 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);1165 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1168 }1166 }
1169 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {1167 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
1170 if (iap->ia_valid & ATTR_MTIME_SET) {1168 if (iap->ia_valid & ATTR_MTIME_SET) {
1171 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);1169 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1172 ts = timespec64_to_timespec(iap->ia_mtime);1170 p = xdr_encode_nfstime4(p, &iap->ia_mtime);
1173 p = xdr_encode_nfstime4(p, &ts);
1174 } else1171 } else
1175 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);1172 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1176 }1173 }
@@ -4065,17 +4062,17 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint · 2888 unmodified lines
4065}4062}
4066 4063
4067static __be32 *4064static __be32 *
4068xdr_decode_nfstime4(__be32 *p, struct timespec *t)4065xdr_decode_nfstime4(__be32 *p, struct timespec64 *t)
4069{4066{
4070 __u64 sec;4067 __u64 sec;
4071 4068
4072 p = xdr_decode_hyper(p, &sec);4069 p = xdr_decode_hyper(p, &sec);
4073 t-> tv_sec = (time_t)sec;4070 t-> tv_sec = sec;
4074 t->tv_nsec = be32_to_cpup(p++);4071 t->tv_nsec = be32_to_cpup(p++);
4075 return p;4072 return p;
4076}4073}
4077 4074
4078static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)4075static int decode_attr_time(struct xdr_stream *xdr, struct timespec64 *time)
4079{4076{
4080 __be32 *p;4077 __be32 *p;
4081 4078
@@ -4086,7 +4083,7 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) · 4 unmodified lines
4086 return 0;4083 return 0;
4087}4084}
4088 4085
4089static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)4086static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
4090{4087{
4091 int status = 0;4088 int status = 0;
4092 4089
@@ -4104,7 +4101,7 @@ static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, str · 11 unmodified lines
4104 return status;4101 return status;
4105}4102}
4106 4103
4107static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)4104static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
4108{4105{
4109 int status = 0;4106 int status = 0;
4110 4107
@@ -4123,7 +4120,7 @@ static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, s · 12 unmodified lines
4123}4120}
4124 4121
4125static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,4122static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
4126 struct timespec *time)4123 struct timespec64 *time)
4127{4124{
4128 int status = 0;4125 int status = 0;
4129 4126
@@ -4186,7 +4183,7 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, · 56 unmodified lines
4186 return status;4183 return status;
4187}4184}
4188 4185
4189static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)4186static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
4190{4187{
4191 int status = 0;4188 int status = 0;
4192 4189
@@ -7581,6 +7578,7 @@ const struct rpc_procinfo nfs4_procedures[] = { · 3388 unmodified lines
7581 PROC42(CLONE, enc_clone, dec_clone),7578 PROC42(CLONE, enc_clone, dec_clone),
7582 PROC42(COPY, enc_copy, dec_copy),7579 PROC42(COPY, enc_copy, dec_copy),
7583 PROC42(OFFLOAD_CANCEL, enc_offload_cancel, dec_offload_cancel),7580 PROC42(OFFLOAD_CANCEL, enc_offload_cancel, dec_offload_cancel),
7581 PROC42(COPY_NOTIFY, enc_copy_notify, dec_copy_notify),
7584 PROC(LOOKUPP, enc_lookupp, dec_lookupp),7582 PROC(LOOKUPP, enc_lookupp, dec_lookupp),
7585 PROC42(LAYOUTERROR, enc_layouterror, dec_layouterror),7583 PROC42(LAYOUTERROR, enc_layouterror, dec_layouterror),
7586};7584};
fs/nfs/nfstrace.h+33−0
@@ -1065,6 +1065,39 @@ TRACE_EVENT(nfs_commit_done, · 1064 unmodified lines
1065 )1065 )
1066);1066);
1067 1067
1068TRACE_EVENT(nfs_fh_to_dentry,
1069 TP_PROTO(
1070 const struct super_block *sb,
1071 const struct nfs_fh *fh,
1072 u64 fileid,
1073 int error
1074 ),
1075
1076 TP_ARGS(sb, fh, fileid, error),
1077
1078 TP_STRUCT__entry(
1079 __field(int, error)
1080 __field(dev_t, dev)
1081 __field(u32, fhandle)
1082 __field(u64, fileid)
1083 ),
1084
1085 TP_fast_assign(
1086 __entry->error = error;
1087 __entry->dev = sb->s_dev;
1088 __entry->fileid = fileid;
1089 __entry->fhandle = nfs_fhandle_hash(fh);
1090 ),
1091
1092 TP_printk(
1093 "error=%d fileid=%02x:%02x:%llu fhandle=0x%08x ",
1094 __entry->error,
1095 MAJOR(__entry->dev), MINOR(__entry->dev),
1096 (unsigned long long)__entry->fileid,
1097 __entry->fhandle
1098 )
1099);
1100
1068TRACE_DEFINE_ENUM(NFS_OK);1101TRACE_DEFINE_ENUM(NFS_OK);
1069TRACE_DEFINE_ENUM(NFSERR_PERM);1102TRACE_DEFINE_ENUM(NFSERR_PERM);
1070TRACE_DEFINE_ENUM(NFSERR_NOENT);1103TRACE_DEFINE_ENUM(NFSERR_NOENT);
fs/nfs/pnfs.c+0−2
@@ -2160,8 +2160,6 @@ out_unlock: · 2159 unmodified lines
2160 return NULL;2160 return NULL;
2161}2161}
2162 2162
2163extern const nfs4_stateid current_stateid;
2164
2165static void _lgopen_prepare_attached(struct nfs4_opendata *data,2163static void _lgopen_prepare_attached(struct nfs4_opendata *data,
2166 struct nfs_open_context *ctx)2164 struct nfs_open_context *ctx)
2167{2165{
fs/nfs/super.c+3−3
@@ -1592,7 +1592,7 @@ static int nfs_parse_mount_options(char *raw, · 1591 unmodified lines
1592 dfprintk(MOUNT, "NFS: invalid "1592 dfprintk(MOUNT, "NFS: invalid "
1593 "lookupcache argument\n");1593 "lookupcache argument\n");
1594 return 0;1594 return 0;
1595 };1595 }
1596 break;1596 break;
1597 case Opt_fscache_uniq:1597 case Opt_fscache_uniq:
1598 if (nfs_get_option_str(args, &mnt->fscache_uniq))1598 if (nfs_get_option_str(args, &mnt->fscache_uniq))
@@ -1625,7 +1625,7 @@ static int nfs_parse_mount_options(char *raw, · 26 unmodified lines
1625 dfprintk(MOUNT, "NFS: invalid "1625 dfprintk(MOUNT, "NFS: invalid "
1626 "local_lock argument\n");1626 "local_lock argument\n");
1627 return 0;1627 return 0;
1628 };1628 }
1629 break;1629 break;
1630 1630
1631 /*1631 /*
@@ -2585,7 +2585,7 @@ static void nfs_get_cache_cookie(struct super_block *sb, · 953 unmodified lines
2585 if (mnt_s->fscache_key) {2585 if (mnt_s->fscache_key) {
2586 uniq = mnt_s->fscache_key->key.uniquifier;2586 uniq = mnt_s->fscache_key->key.uniquifier;
2587 ulen = mnt_s->fscache_key->key.uniq_len;2587 ulen = mnt_s->fscache_key->key.uniq_len;
2588 };2588 }
2589 } else2589 } else
2590 return;2590 return;
2591 2591
fs/nfs/sysfs.c+1−2
@@ -121,8 +121,7 @@ static void nfs_netns_client_release(struct kobject *kobj) · 120 unmodified lines
121 struct nfs_netns_client,121 struct nfs_netns_client,
122 kobject);122 kobject);
123 123
124 if (c->identifier)124 kfree(c->identifier);
125 kfree(c->identifier);
126 kfree(c);125 kfree(c);
127}126}
128 127
include/linux/nfs4.h+26−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/list.h>16#include <linux/list.h>
17#include <linux/uidgid.h>17#include <linux/uidgid.h>
18#include <uapi/linux/nfs4.h>18#include <uapi/linux/nfs4.h>
19#include <linux/sunrpc/msg_prot.h>
19 20
20enum nfs4_acl_whotype {21enum nfs4_acl_whotype {
21 NFS4_ACL_WHO_NAMED = 0,22 NFS4_ACL_WHO_NAMED = 0,
@@ -539,6 +540,8 @@ enum { · 517 unmodified lines
539 540
540 NFSPROC4_CLNT_LOOKUPP,541 NFSPROC4_CLNT_LOOKUPP,
541 NFSPROC4_CLNT_LAYOUTERROR,542 NFSPROC4_CLNT_LAYOUTERROR,
543
544 NFSPROC4_CLNT_COPY_NOTIFY,
542};545};
543 546
544/* nfs41 types */547/* nfs41 types */
@@ -674,4 +677,27 @@ struct nfs4_op_map { · 129 unmodified lines
674 } u;677 } u;
675};678};
676 679
680struct nfs42_netaddr {
681 char netid[RPCBIND_MAXNETIDLEN];
682 char addr[RPCBIND_MAXUADDRLEN + 1];
683 u32 netid_len;
684 u32 addr_len;
685};
686
687enum netloc_type4 {
688 NL4_NAME = 1,
689 NL4_URL = 2,
690 NL4_NETADDR = 3,
691};
692
693struct nl4_server {
694 enum netloc_type4 nl4_type;
695 union {
696 struct { /* NL4_NAME, NL4_URL */
697 int nl4_str_sz;
698 char nl4_str[NFS4_OPAQUE_LIMIT + 1];
699 };
700 struct nfs42_netaddr nl4_addr; /* NL4_NETADDR */
701 } u;
702};
677#endif703#endif
include/linux/nfs_fs.h+3−1
@@ -189,13 +189,15 @@ struct nfs_inode { · 188 unmodified lines
189 189
190struct nfs4_copy_state {190struct nfs4_copy_state {
191 struct list_head copies;191 struct list_head copies;
192 struct list_head src_copies;
192 nfs4_stateid stateid;193 nfs4_stateid stateid;
193 struct completion completion;194 struct completion completion;
194 uint64_t count;195 uint64_t count;
195 struct nfs_writeverf verf;196 struct nfs_writeverf verf;
196 int error;197 int error;
197 int flags;198 int flags;
198 struct nfs4_state *parent_state;199 struct nfs4_state *parent_src_state;
200 struct nfs4_state *parent_dst_state;
199};201};
200 202
201/*203/*
include/linux/nfs_fs_sb.h+5−1
@@ -45,6 +45,9 @@ struct nfs_client { · 44 unmodified lines
45#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */45#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */
46#define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */46#define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */
47#define NFS_CS_TSM_POSSIBLE 5 /* - Maybe state migration */47#define NFS_CS_TSM_POSSIBLE 5 /* - Maybe state migration */
48#define NFS_CS_NOPING 6 /* - don't ping on connect */
49#define NFS_CS_DS 7 /* - Server is a DS */
50#define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */
48 struct sockaddr_storage cl_addr; /* server identifier */51 struct sockaddr_storage cl_addr; /* server identifier */
49 size_t cl_addrlen;52 size_t cl_addrlen;
50 char * cl_hostname; /* hostname of server */53 char * cl_hostname; /* hostname of server */
@@ -171,7 +174,7 @@ struct nfs_server { · 120 unmodified lines
171 174
172 struct nfs_fsid fsid;175 struct nfs_fsid fsid;
173 __u64 maxfilesize; /* maximum file size */176 __u64 maxfilesize; /* maximum file size */
174 struct timespec time_delta; /* smallest time granularity */177 struct timespec64 time_delta; /* smallest time granularity */
175 unsigned long mount_time; /* when this fs was mounted */178 unsigned long mount_time; /* when this fs was mounted */
176 struct super_block *super; /* VFS super block */179 struct super_block *super; /* VFS super block */
177 dev_t s_dev; /* superblock dev numbers */180 dev_t s_dev; /* superblock dev numbers */
@@ -276,5 +279,6 @@ struct nfs_server { · 98 unmodified lines
276#define NFS_CAP_COPY (1U << 24)279#define NFS_CAP_COPY (1U << 24)
277#define NFS_CAP_OFFLOAD_CANCEL (1U << 25)280#define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
278#define NFS_CAP_LAYOUTERROR (1U << 26)281#define NFS_CAP_LAYOUTERROR (1U << 26)
282#define NFS_CAP_COPY_NOTIFY (1U << 27)
279 283
280#endif284#endif
include/linux/nfs_xdr.h+24−7
@@ -62,14 +62,14 @@ struct nfs_fattr { · 61 unmodified lines
62 struct nfs_fsid fsid;62 struct nfs_fsid fsid;
63 __u64 fileid;63 __u64 fileid;
64 __u64 mounted_on_fileid;64 __u64 mounted_on_fileid;
65 struct timespec atime;65 struct timespec64 atime;
66 struct timespec mtime;66 struct timespec64 mtime;
67 struct timespec ctime;67 struct timespec64 ctime;
68 __u64 change_attr; /* NFSv4 change attribute */68 __u64 change_attr; /* NFSv4 change attribute */
69 __u64 pre_change_attr;/* pre-op NFSv4 change attribute */69 __u64 pre_change_attr;/* pre-op NFSv4 change attribute */
70 __u64 pre_size; /* pre_op_attr.size */70 __u64 pre_size; /* pre_op_attr.size */
71 struct timespec pre_mtime; /* pre_op_attr.mtime */71 struct timespec64 pre_mtime; /* pre_op_attr.mtime */
72 struct timespec pre_ctime; /* pre_op_attr.ctime */72 struct timespec64 pre_ctime; /* pre_op_attr.ctime */
73 unsigned long time_start;73 unsigned long time_start;
74 unsigned long gencount;74 unsigned long gencount;
75 struct nfs4_string *owner_name;75 struct nfs4_string *owner_name;
@@ -143,7 +143,7 @@ struct nfs_fsinfo { · 67 unmodified lines
143 __u32 wtmult; /* writes should be multiple of this */143 __u32 wtmult; /* writes should be multiple of this */
144 __u32 dtpref; /* pref. readdir transfer size */144 __u32 dtpref; /* pref. readdir transfer size */
145 __u64 maxfilesize;145 __u64 maxfilesize;
146 struct timespec time_delta; /* server time granularity */146 struct timespec64 time_delta; /* server time granularity */
147 __u32 lease_time; /* in seconds */147 __u32 lease_time; /* in seconds */
148 __u32 nlayouttypes; /* number of layouttypes */148 __u32 nlayouttypes; /* number of layouttypes */
149 __u32 layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */149 __u32 layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */
@@ -869,7 +869,7 @@ struct nfs3_sattrargs { · 719 unmodified lines
869 struct nfs_fh * fh;869 struct nfs_fh * fh;
870 struct iattr * sattr;870 struct iattr * sattr;
871 unsigned int guard;871 unsigned int guard;
872 struct timespec guardtime;872 struct timespec64 guardtime;
873};873};
874 874
875struct nfs3_diropargs {875struct nfs3_diropargs {
@@ -1435,6 +1435,7 @@ struct nfs42_copy_args { · 559 unmodified lines
1435 1435
1436 u64 count;1436 u64 count;
1437 bool sync;1437 bool sync;
1438 struct nl4_server *cp_src;
1438};1439};
1439 1440
1440struct nfs42_write_res {1441struct nfs42_write_res {
@@ -1463,6 +1464,22 @@ struct nfs42_offload_status_res { · 22 unmodified lines
1463 int osr_status;1464 int osr_status;
1464};1465};
1465 1466
1467struct nfs42_copy_notify_args {
1468 struct nfs4_sequence_args cna_seq_args;
1469
1470 struct nfs_fh *cna_src_fh;
1471 nfs4_stateid cna_src_stateid;
1472 struct nl4_server cna_dst;
1473};
1474
1475struct nfs42_copy_notify_res {
1476 struct nfs4_sequence_res cnr_seq_res;
1477
1478 struct nfstime4 cnr_lease_time;
1479 nfs4_stateid cnr_stateid;
1480 struct nl4_server cnr_src;
1481};
1482
1466struct nfs42_seek_args {1483struct nfs42_seek_args {
1467 struct nfs4_sequence_args seq_args;1484 struct nfs4_sequence_args seq_args;
1468 1485
include/linux/sunrpc/clnt.h+1−0
@@ -149,6 +149,7 @@ struct rpc_add_xprt_test { · 148 unmodified lines
149#define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8)149#define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8)
150#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)150#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)
151#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)151#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)
152#define RPC_CLNT_CREATE_REUSEPORT (1UL << 11)
152 153
153struct rpc_clnt *rpc_create(struct rpc_create_args *args);154struct rpc_clnt *rpc_create(struct rpc_create_args *args);
154struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,155struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
include/linux/sunrpc/xprt.h+2−1
@@ -207,7 +207,8 @@ struct rpc_xprt { · 206 unmodified lines
207 unsigned int min_reqs; /* min number of slots */207 unsigned int min_reqs; /* min number of slots */
208 unsigned int num_reqs; /* total slots */208 unsigned int num_reqs; /* total slots */
209 unsigned long state; /* transport state */209 unsigned long state; /* transport state */
210 unsigned char resvport : 1; /* use a reserved port */210 unsigned char resvport : 1, /* use a reserved port */
211 reuseport : 1; /* reuse port on reconnect */
211 atomic_t swapper; /* we're swapping over this212 atomic_t swapper; /* we're swapping over this
212 transport */213 transport */
213 unsigned int bind_index; /* bind function index */214 unsigned int bind_index; /* bind function index */
include/trace/events/rpcrdma.h+132−66
@@ -85,6 +85,44 @@ DECLARE_EVENT_CLASS(xprtrdma_rxprt, · 84 unmodified lines
85 ), \85 ), \
86 TP_ARGS(r_xprt))86 TP_ARGS(r_xprt))
87 87
88DECLARE_EVENT_CLASS(xprtrdma_connect_class,
89 TP_PROTO(
90 const struct rpcrdma_xprt *r_xprt,
91 int rc
92 ),
93
94 TP_ARGS(r_xprt, rc),
95
96 TP_STRUCT__entry(
97 __field(const void *, r_xprt)
98 __field(int, rc)
99 __field(int, connect_status)
100 __string(addr, rpcrdma_addrstr(r_xprt))
101 __string(port, rpcrdma_portstr(r_xprt))
102 ),
103
104 TP_fast_assign(
105 __entry->r_xprt = r_xprt;
106 __entry->rc = rc;
107 __entry->connect_status = r_xprt->rx_ep.rep_connected;
108 __assign_str(addr, rpcrdma_addrstr(r_xprt));
109 __assign_str(port, rpcrdma_portstr(r_xprt));
110 ),
111
112 TP_printk("peer=[%s]:%s r_xprt=%p: rc=%d connect status=%d",
113 __get_str(addr), __get_str(port), __entry->r_xprt,
114 __entry->rc, __entry->connect_status
115 )
116);
117
118#define DEFINE_CONN_EVENT(name) \
119 DEFINE_EVENT(xprtrdma_connect_class, xprtrdma_##name, \
120 TP_PROTO( \
121 const struct rpcrdma_xprt *r_xprt, \
122 int rc \
123 ), \
124 TP_ARGS(r_xprt, rc))
125
88DECLARE_EVENT_CLASS(xprtrdma_rdch_event,126DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
89 TP_PROTO(127 TP_PROTO(
90 const struct rpc_task *task,128 const struct rpc_task *task,
@@ -333,47 +371,81 @@ TRACE_EVENT(xprtrdma_cm_event, · 242 unmodified lines
333 )371 )
334);372);
335 373
336TRACE_EVENT(xprtrdma_disconnect,374TRACE_EVENT(xprtrdma_inline_thresh,
337 TP_PROTO(375 TP_PROTO(
338 const struct rpcrdma_xprt *r_xprt,376 const struct rpcrdma_xprt *r_xprt
339 int status
340 ),377 ),
341 378
342 TP_ARGS(r_xprt, status),379 TP_ARGS(r_xprt),
343 380
344 TP_STRUCT__entry(381 TP_STRUCT__entry(
345 __field(const void *, r_xprt)382 __field(const void *, r_xprt)
346 __field(int, status)383 __field(unsigned int, inline_send)
347 __field(int, connected)384 __field(unsigned int, inline_recv)
385 __field(unsigned int, max_send)
386 __field(unsigned int, max_recv)
348 __string(addr, rpcrdma_addrstr(r_xprt))387 __string(addr, rpcrdma_addrstr(r_xprt))
349 __string(port, rpcrdma_portstr(r_xprt))388 __string(port, rpcrdma_portstr(r_xprt))
350 ),389 ),
351 390
352 TP_fast_assign(391 TP_fast_assign(
392 const struct rpcrdma_ep *ep = &r_xprt->rx_ep;
393
353 __entry->r_xprt = r_xprt;394 __entry->r_xprt = r_xprt;
354 __entry->status = status;395 __entry->inline_send = ep->rep_inline_send;
355 __entry->connected = r_xprt->rx_ep.rep_connected;396 __entry->inline_recv = ep->rep_inline_recv;
397 __entry->max_send = ep->rep_max_inline_send;
398 __entry->max_recv = ep->rep_max_inline_recv;
356 __assign_str(addr, rpcrdma_addrstr(r_xprt));399 __assign_str(addr, rpcrdma_addrstr(r_xprt));
357 __assign_str(port, rpcrdma_portstr(r_xprt));400 __assign_str(port, rpcrdma_portstr(r_xprt));
358 ),401 ),
359 402
360 TP_printk("peer=[%s]:%s r_xprt=%p: status=%d %sconnected",403 TP_printk("peer=[%s]:%s r_xprt=%p neg send/recv=%u/%u, calc send/recv=%u/%u",
361 __get_str(addr), __get_str(port),404 __get_str(addr), __get_str(port), __entry->r_xprt,
362 __entry->r_xprt, __entry->status,405 __entry->inline_send, __entry->inline_recv,
363 __entry->connected == 1 ? "still " : "dis"406 __entry->max_send, __entry->max_recv
364 )407 )
365);408);
366 409
367DEFINE_RXPRT_EVENT(xprtrdma_conn_start);410DEFINE_CONN_EVENT(connect);
368DEFINE_RXPRT_EVENT(xprtrdma_conn_tout);411DEFINE_CONN_EVENT(disconnect);
412
369DEFINE_RXPRT_EVENT(xprtrdma_create);413DEFINE_RXPRT_EVENT(xprtrdma_create);
370DEFINE_RXPRT_EVENT(xprtrdma_op_destroy);414DEFINE_RXPRT_EVENT(xprtrdma_op_destroy);
371DEFINE_RXPRT_EVENT(xprtrdma_remove);415DEFINE_RXPRT_EVENT(xprtrdma_remove);
372DEFINE_RXPRT_EVENT(xprtrdma_reinsert);416DEFINE_RXPRT_EVENT(xprtrdma_reinsert);
373DEFINE_RXPRT_EVENT(xprtrdma_reconnect);
374DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);417DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);
375DEFINE_RXPRT_EVENT(xprtrdma_op_close);418DEFINE_RXPRT_EVENT(xprtrdma_op_close);
376DEFINE_RXPRT_EVENT(xprtrdma_op_connect);419DEFINE_RXPRT_EVENT(xprtrdma_op_setport);
420
421TRACE_EVENT(xprtrdma_op_connect,
422 TP_PROTO(
423 const struct rpcrdma_xprt *r_xprt,
424 unsigned long delay
425 ),
426
427 TP_ARGS(r_xprt, delay),
428
429 TP_STRUCT__entry(
430 __field(const void *, r_xprt)
431 __field(unsigned long, delay)
432 __string(addr, rpcrdma_addrstr(r_xprt))
433 __string(port, rpcrdma_portstr(r_xprt))
434 ),
435
436 TP_fast_assign(
437 __entry->r_xprt = r_xprt;
438 __entry->delay = delay;
439 __assign_str(addr, rpcrdma_addrstr(r_xprt));
440 __assign_str(port, rpcrdma_portstr(r_xprt));
441 ),
442
443 TP_printk("peer=[%s]:%s r_xprt=%p delay=%lu",
444 __get_str(addr), __get_str(port), __entry->r_xprt,
445 __entry->delay
446 )
447);
448
377 449
378TRACE_EVENT(xprtrdma_op_set_cto,450TRACE_EVENT(xprtrdma_op_set_cto,
379 TP_PROTO(451 TP_PROTO(
@@ -532,6 +604,8 @@ DEFINE_WRCH_EVENT(write); · 152 unmodified lines
532DEFINE_WRCH_EVENT(reply);604DEFINE_WRCH_EVENT(reply);
533 605
534TRACE_DEFINE_ENUM(rpcrdma_noch);606TRACE_DEFINE_ENUM(rpcrdma_noch);
607TRACE_DEFINE_ENUM(rpcrdma_noch_pullup);
608TRACE_DEFINE_ENUM(rpcrdma_noch_mapped);
535TRACE_DEFINE_ENUM(rpcrdma_readch);609TRACE_DEFINE_ENUM(rpcrdma_readch);
536TRACE_DEFINE_ENUM(rpcrdma_areadch);610TRACE_DEFINE_ENUM(rpcrdma_areadch);
537TRACE_DEFINE_ENUM(rpcrdma_writech);611TRACE_DEFINE_ENUM(rpcrdma_writech);
@@ -540,6 +614,8 @@ TRACE_DEFINE_ENUM(rpcrdma_replych); · 2 unmodified lines
540#define xprtrdma_show_chunktype(x) \614#define xprtrdma_show_chunktype(x) \
541 __print_symbolic(x, \615 __print_symbolic(x, \
542 { rpcrdma_noch, "inline" }, \616 { rpcrdma_noch, "inline" }, \
617 { rpcrdma_noch_pullup, "pullup" }, \
618 { rpcrdma_noch_mapped, "mapped" }, \
543 { rpcrdma_readch, "read list" }, \619 { rpcrdma_readch, "read list" }, \
544 { rpcrdma_areadch, "*read list" }, \620 { rpcrdma_areadch, "*read list" }, \
545 { rpcrdma_writech, "write list" }, \621 { rpcrdma_writech, "write list" }, \
@@ -667,9 +743,8 @@ TRACE_EVENT(xprtrdma_post_send, · 121 unmodified lines
667 __entry->client_id = rqst->rq_task->tk_client ?743 __entry->client_id = rqst->rq_task->tk_client ?
668 rqst->rq_task->tk_client->cl_clid : -1;744 rqst->rq_task->tk_client->cl_clid : -1;
669 __entry->req = req;745 __entry->req = req;
670 __entry->num_sge = req->rl_sendctx->sc_wr.num_sge;746 __entry->num_sge = req->rl_wr.num_sge;
671 __entry->signaled = req->rl_sendctx->sc_wr.send_flags &747 __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
672 IB_SEND_SIGNALED;
673 __entry->status = status;748 __entry->status = status;
674 ),749 ),
675 750
@@ -735,6 +810,31 @@ TRACE_EVENT(xprtrdma_post_recvs, · 59 unmodified lines
735 )810 )
736);811);
737 812
813TRACE_EVENT(xprtrdma_post_linv,
814 TP_PROTO(
815 const struct rpcrdma_req *req,
816 int status
817 ),
818
819 TP_ARGS(req, status),
820
821 TP_STRUCT__entry(
822 __field(const void *, req)
823 __field(int, status)
824 __field(u32, xid)
825 ),
826
827 TP_fast_assign(
828 __entry->req = req;
829 __entry->status = status;
830 __entry->xid = be32_to_cpu(req->rl_slot.rq_xid);
831 ),
832
833 TP_printk("req=%p xid=0x%08x status=%d",
834 __entry->req, __entry->xid, __entry->status
835 )
836);
837
738/**838/**
739 ** Completion events839 ** Completion events
740 **/840 **/
@@ -1021,66 +1121,32 @@ DEFINE_REPLY_EVENT(xprtrdma_reply_hdr); · 280 unmodified lines
1021TRACE_EVENT(xprtrdma_fixup,1121TRACE_EVENT(xprtrdma_fixup,
1022 TP_PROTO(1122 TP_PROTO(
1023 const struct rpc_rqst *rqst,1123 const struct rpc_rqst *rqst,
1024 int len,1124 unsigned long fixup
1025 int hdrlen
1026 ),1125 ),
1027 1126
1028 TP_ARGS(rqst, len, hdrlen),1127 TP_ARGS(rqst, fixup),
1029 1128
1030 TP_STRUCT__entry(1129 TP_STRUCT__entry(
1031 __field(unsigned int, task_id)1130 __field(unsigned int, task_id)
1032 __field(unsigned int, client_id)1131 __field(unsigned int, client_id)
1033 __field(const void *, base)1132 __field(unsigned long, fixup)
1034 __field(int, len)1133 __field(size_t, headlen)
1035 __field(int, hdrlen)1134 __field(unsigned int, pagelen)
1036 ),1135 __field(size_t, taillen)
1037
1038 TP_fast_assign(
1039 __entry->task_id = rqst->rq_task->tk_pid;
1040 __entry->client_id = rqst->rq_task->tk_client->cl_clid;
1041 __entry->base = rqst->rq_rcv_buf.head[0].iov_base;
1042 __entry->len = len;
1043 __entry->hdrlen = hdrlen;
1044 ),
1045
1046 TP_printk("task:%u@%u base=%p len=%d hdrlen=%d",
1047 __entry->task_id, __entry->client_id,
1048 __entry->base, __entry->len, __entry->hdrlen
1049 )
1050);
1051
1052TRACE_EVENT(xprtrdma_fixup_pg,
1053 TP_PROTO(
1054 const struct rpc_rqst *rqst,
1055 int pageno,
1056 const void *pos,
1057 int len,
1058 int curlen
1059 ),
1060
1061 TP_ARGS(rqst, pageno, pos, len, curlen),
1062
1063 TP_STRUCT__entry(
1064 __field(unsigned int, task_id)
1065 __field(unsigned int, client_id)
1066 __field(const void *, pos)
1067 __field(int, pageno)
1068 __field(int, len)
1069 __field(int, curlen)
1070 ),1136 ),
1071 1137
1072 TP_fast_assign(1138 TP_fast_assign(
1073 __entry->task_id = rqst->rq_task->tk_pid;1139 __entry->task_id = rqst->rq_task->tk_pid;
1074 __entry->client_id = rqst->rq_task->tk_client->cl_clid;1140 __entry->client_id = rqst->rq_task->tk_client->cl_clid;
1075 __entry->pos = pos;1141 __entry->fixup = fixup;
1076 __entry->pageno = pageno;1142 __entry->headlen = rqst->rq_rcv_buf.head[0].iov_len;
1077 __entry->len = len;1143 __entry->pagelen = rqst->rq_rcv_buf.page_len;
1078 __entry->curlen = curlen;1144 __entry->taillen = rqst->rq_rcv_buf.tail[0].iov_len;
1079 ),1145 ),
1080 1146
1081 TP_printk("task:%u@%u pageno=%d pos=%p len=%d curlen=%d",1147 TP_printk("task:%u@%u fixup=%lu xdr=%zu/%u/%zu",
1082 __entry->task_id, __entry->client_id,1148 __entry->task_id, __entry->client_id, __entry->fixup,
1083 __entry->pageno, __entry->pos, __entry->len, __entry->curlen1149 __entry->headlen, __entry->pagelen, __entry->taillen
1084 )1150 )
1085);1151);
1086 1152
include/trace/events/sunrpc.h+94−0
@@ -165,6 +165,7 @@ DECLARE_EVENT_CLASS(rpc_task_running, · 164 unmodified lines
165DEFINE_RPC_RUNNING_EVENT(begin);165DEFINE_RPC_RUNNING_EVENT(begin);
166DEFINE_RPC_RUNNING_EVENT(run_action);166DEFINE_RPC_RUNNING_EVENT(run_action);
167DEFINE_RPC_RUNNING_EVENT(complete);167DEFINE_RPC_RUNNING_EVENT(complete);
168DEFINE_RPC_RUNNING_EVENT(end);
168 169
169DECLARE_EVENT_CLASS(rpc_task_queued,170DECLARE_EVENT_CLASS(rpc_task_queued,
170 171
@@ -777,6 +778,99 @@ TRACE_EVENT(xprt_ping, · 606 unmodified lines
777 __get_str(addr), __get_str(port), __entry->status)778 __get_str(addr), __get_str(port), __entry->status)
778);779);
779 780
781DECLARE_EVENT_CLASS(xprt_writelock_event,
782 TP_PROTO(
783 const struct rpc_xprt *xprt, const struct rpc_task *task
784 ),
785
786 TP_ARGS(xprt, task),
787
788 TP_STRUCT__entry(
789 __field(unsigned int, task_id)
790 __field(unsigned int, client_id)
791 __field(unsigned int, snd_task_id)
792 ),
793
794 TP_fast_assign(
795 if (task) {
796 __entry->task_id = task->tk_pid;
797 __entry->client_id = task->tk_client ?
798 task->tk_client->cl_clid : -1;
799 } else {
800 __entry->task_id = -1;
801 __entry->client_id = -1;
802 }
803 __entry->snd_task_id = xprt->snd_task ?
804 xprt->snd_task->tk_pid : -1;
805 ),
806
807 TP_printk("task:%u@%u snd_task:%u",
808 __entry->task_id, __entry->client_id,
809 __entry->snd_task_id)
810);
811
812#define DEFINE_WRITELOCK_EVENT(name) \
813 DEFINE_EVENT(xprt_writelock_event, xprt_##name, \
814 TP_PROTO( \
815 const struct rpc_xprt *xprt, \
816 const struct rpc_task *task \
817 ), \
818 TP_ARGS(xprt, task))
819
820DEFINE_WRITELOCK_EVENT(reserve_xprt);
821DEFINE_WRITELOCK_EVENT(release_xprt);
822
823DECLARE_EVENT_CLASS(xprt_cong_event,
824 TP_PROTO(
825 const struct rpc_xprt *xprt, const struct rpc_task *task
826 ),
827
828 TP_ARGS(xprt, task),
829
830 TP_STRUCT__entry(
831 __field(unsigned int, task_id)
832 __field(unsigned int, client_id)
833 __field(unsigned int, snd_task_id)
834 __field(unsigned long, cong)
835 __field(unsigned long, cwnd)
836 __field(bool, wait)
837 ),
838
839 TP_fast_assign(
840 if (task) {
841 __entry->task_id = task->tk_pid;
842 __entry->client_id = task->tk_client ?
843 task->tk_client->cl_clid : -1;
844 } else {
845 __entry->task_id = -1;
846 __entry->client_id = -1;
847 }
848 __entry->snd_task_id = xprt->snd_task ?
849 xprt->snd_task->tk_pid : -1;
850 __entry->cong = xprt->cong;
851 __entry->cwnd = xprt->cwnd;
852 __entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
853 ),
854
855 TP_printk("task:%u@%u snd_task:%u cong=%lu cwnd=%lu%s",
856 __entry->task_id, __entry->client_id,
857 __entry->snd_task_id, __entry->cong, __entry->cwnd,
858 __entry->wait ? " (wait)" : "")
859);
860
861#define DEFINE_CONG_EVENT(name) \
862 DEFINE_EVENT(xprt_cong_event, xprt_##name, \
863 TP_PROTO( \
864 const struct rpc_xprt *xprt, \
865 const struct rpc_task *task \
866 ), \
867 TP_ARGS(xprt, task))
868
869DEFINE_CONG_EVENT(reserve_cong);
870DEFINE_CONG_EVENT(release_cong);
871DEFINE_CONG_EVENT(get_cong);
872DEFINE_CONG_EVENT(put_cong);
873
780TRACE_EVENT(xs_stream_read_data,874TRACE_EVENT(xs_stream_read_data,
781 TP_PROTO(struct rpc_xprt *xprt, ssize_t err, size_t total),875 TP_PROTO(struct rpc_xprt *xprt, ssize_t err, size_t total),
782 876
net/sunrpc/clnt.c+8−13
@@ -591,6 +591,9 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) · 590 unmodified lines
591 xprt->resvport = 1;591 xprt->resvport = 1;
592 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)592 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
593 xprt->resvport = 0;593 xprt->resvport = 0;
594 xprt->reuseport = 0;
595 if (args->flags & RPC_CLNT_CREATE_REUSEPORT)
596 xprt->reuseport = 1;
594 597
595 clnt = rpc_create_xprt(args, xprt);598 clnt = rpc_create_xprt(args, xprt);
596 if (IS_ERR(clnt) || args->nconnect <= 1)599 if (IS_ERR(clnt) || args->nconnect <= 1)
@@ -1676,8 +1679,6 @@ call_reserveresult(struct rpc_task *task) · 1079 unmodified lines
1676 return;1679 return;
1677 }1680 }
1678 1681
1679 printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
1680 __func__, status);
1681 rpc_call_rpcerror(task, -EIO);1682 rpc_call_rpcerror(task, -EIO);
1682 return;1683 return;
1683 }1684 }
@@ -1686,11 +1687,8 @@ call_reserveresult(struct rpc_task *task) · 2 unmodified lines
1686 * Even though there was an error, we may have acquired1687 * Even though there was an error, we may have acquired
1687 * a request slot somehow. Make sure not to leak it.1688 * a request slot somehow. Make sure not to leak it.
1688 */1689 */
1689 if (task->tk_rqstp) {1690 if (task->tk_rqstp)
1690 printk(KERN_ERR "%s: status=%d, request allocated anyway\n",
1691 __func__, status);
1692 xprt_release(task);1691 xprt_release(task);
1693 }
1694 1692
1695 switch (status) {1693 switch (status) {
1696 case -ENOMEM:1694 case -ENOMEM:
@@ -1699,14 +1697,9 @@ call_reserveresult(struct rpc_task *task) · 2 unmodified lines
1699 case -EAGAIN: /* woken up; retry */1697 case -EAGAIN: /* woken up; retry */
1700 task->tk_action = call_retry_reserve;1698 task->tk_action = call_retry_reserve;
1701 return;1699 return;
1702 case -EIO: /* probably a shutdown */
1703 break;
1704 default:1700 default:
1705 printk(KERN_ERR "%s: unrecognized error %d, exiting\n",1701 rpc_call_rpcerror(task, status);
1706 __func__, status);
1707 break;
1708 }1702 }
1709 rpc_call_rpcerror(task, status);
1710}1703}
1711 1704
1712/*1705/*
@@ -2906,7 +2899,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, · 1193 unmodified lines
2906 struct rpc_xprt *xprt;2899 struct rpc_xprt *xprt;
2907 unsigned long connect_timeout;2900 unsigned long connect_timeout;
2908 unsigned long reconnect_timeout;2901 unsigned long reconnect_timeout;
2909 unsigned char resvport;2902 unsigned char resvport, reuseport;
2910 int ret = 0;2903 int ret = 0;
2911 2904
2912 rcu_read_lock();2905 rcu_read_lock();
@@ -2918,6 +2911,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, · 5 unmodified lines
2918 return -EAGAIN;2911 return -EAGAIN;
2919 }2912 }
2920 resvport = xprt->resvport;2913 resvport = xprt->resvport;
2914 reuseport = xprt->reuseport;
2921 connect_timeout = xprt->connect_timeout;2915 connect_timeout = xprt->connect_timeout;
2922 reconnect_timeout = xprt->max_reconnect_timeout;2916 reconnect_timeout = xprt->max_reconnect_timeout;
2923 rcu_read_unlock();2917 rcu_read_unlock();
@@ -2928,6 +2922,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, · 4 unmodified lines
2928 goto out_put_switch;2922 goto out_put_switch;
2929 }2923 }
2930 xprt->resvport = resvport;2924 xprt->resvport = resvport;
2925 xprt->reuseport = reuseport;
2931 if (xprt->ops->set_connect_timeout != NULL)2926 if (xprt->ops->set_connect_timeout != NULL)
2932 xprt->ops->set_connect_timeout(xprt,2927 xprt->ops->set_connect_timeout(xprt,
2933 connect_timeout,2928 connect_timeout,
net/sunrpc/sched.c+2−1
@@ -260,7 +260,7 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c · 259 unmodified lines
260 rpc_reset_waitqueue_priority(queue);260 rpc_reset_waitqueue_priority(queue);
261 queue->qlen = 0;261 queue->qlen = 0;
262 queue->timer_list.expires = 0;262 queue->timer_list.expires = 0;
263 INIT_DEFERRABLE_WORK(&queue->timer_list.dwork, __rpc_queue_timer_fn);263 INIT_DELAYED_WORK(&queue->timer_list.dwork, __rpc_queue_timer_fn);
264 INIT_LIST_HEAD(&queue->timer_list.list);264 INIT_LIST_HEAD(&queue->timer_list.list);
265 rpc_assign_waitqueue_name(queue, qname);265 rpc_assign_waitqueue_name(queue, qname);
266}266}
@@ -824,6 +824,7 @@ rpc_reset_task_statistics(struct rpc_task *task) · 557 unmodified lines
824 */824 */
825void rpc_exit_task(struct rpc_task *task)825void rpc_exit_task(struct rpc_task *task)
826{826{
827 trace_rpc_task_end(task, task->tk_action);
827 task->tk_action = NULL;828 task->tk_action = NULL;
828 if (task->tk_ops->rpc_count_stats)829 if (task->tk_ops->rpc_count_stats)
829 task->tk_ops->rpc_count_stats(task, task->tk_calldata);830 task->tk_ops->rpc_count_stats(task, task->tk_calldata);
net/sunrpc/xdr.c+5−6
@@ -436,13 +436,12 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len) · 435 unmodified lines
436}436}
437 437
438/**438/**
439 * xdr_shrink_pagelen439 * xdr_shrink_pagelen - shrinks buf->pages by up to @len bytes
440 * @buf: xdr_buf440 * @buf: xdr_buf
441 * @len: bytes to remove from buf->pages441 * @len: bytes to remove from buf->pages
442 *442 *
443 * Shrinks XDR buffer's page array buf->pages by443 * The extra data is not lost, but is instead moved into buf->tail.
444 * 'len' bytes. The extra data is not lost, but is instead444 * Returns the actual number of bytes moved.
445 * moved into the tail.
446 */445 */
447static unsigned int446static unsigned int
448xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)447xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
@@ -455,8 +454,8 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len) · 6 unmodified lines
455 454
456 result = 0;455 result = 0;
457 tail = buf->tail;456 tail = buf->tail;
458 BUG_ON (len > pglen);457 if (len > buf->page_len)
459 458 len = buf-> page_len;
460 tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;459 tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
461 460
462 /* Shift the tail first */461 /* Shift the tail first */
net/sunrpc/xprt.c+13−9
@@ -205,20 +205,20 @@ int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task) · 204 unmodified lines
205 205
206 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {206 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
207 if (task == xprt->snd_task)207 if (task == xprt->snd_task)
208 return 1;208 goto out_locked;
209 goto out_sleep;209 goto out_sleep;
210 }210 }
211 if (test_bit(XPRT_WRITE_SPACE, &xprt->state))211 if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
212 goto out_unlock;212 goto out_unlock;
213 xprt->snd_task = task;213 xprt->snd_task = task;
214 214
215out_locked:
216 trace_xprt_reserve_xprt(xprt, task);
215 return 1;217 return 1;
216 218
217out_unlock:219out_unlock:
218 xprt_clear_locked(xprt);220 xprt_clear_locked(xprt);
219out_sleep:221out_sleep:
220 dprintk("RPC: %5u failed to lock transport %p\n",
221 task->tk_pid, xprt);
222 task->tk_status = -EAGAIN;222 task->tk_status = -EAGAIN;
223 if (RPC_IS_SOFT(task))223 if (RPC_IS_SOFT(task))
224 rpc_sleep_on_timeout(&xprt->sending, task, NULL,224 rpc_sleep_on_timeout(&xprt->sending, task, NULL,
@@ -269,23 +269,22 @@ int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) · 44 unmodified lines
269 269
270 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {270 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
271 if (task == xprt->snd_task)271 if (task == xprt->snd_task)
272 return 1;272 goto out_locked;
273 goto out_sleep;273 goto out_sleep;
274 }274 }
275 if (req == NULL) {275 if (req == NULL) {
276 xprt->snd_task = task;276 xprt->snd_task = task;
277 return 1;277 goto out_locked;
278 }278 }
279 if (test_bit(XPRT_WRITE_SPACE, &xprt->state))279 if (test_bit(XPRT_WRITE_SPACE, &xprt->state))
280 goto out_unlock;280 goto out_unlock;
281 if (!xprt_need_congestion_window_wait(xprt)) {281 if (!xprt_need_congestion_window_wait(xprt)) {
282 xprt->snd_task = task;282 xprt->snd_task = task;
283 return 1;283 goto out_locked;
284 }284 }
285out_unlock:285out_unlock:
286 xprt_clear_locked(xprt);286 xprt_clear_locked(xprt);
287out_sleep:287out_sleep:
288 dprintk("RPC: %5u failed to lock transport %p\n", task->tk_pid, xprt);
289 task->tk_status = -EAGAIN;288 task->tk_status = -EAGAIN;
290 if (RPC_IS_SOFT(task))289 if (RPC_IS_SOFT(task))
291 rpc_sleep_on_timeout(&xprt->sending, task, NULL,290 rpc_sleep_on_timeout(&xprt->sending, task, NULL,
@@ -293,6 +292,9 @@ out_sleep: · 1 unmodified line
293 else292 else
294 rpc_sleep_on(&xprt->sending, task, NULL);293 rpc_sleep_on(&xprt->sending, task, NULL);
295 return 0;294 return 0;
295out_locked:
296 trace_xprt_reserve_cong(xprt, task);
297 return 1;
296}298}
297EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);299EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
298 300
@@ -357,6 +359,7 @@ void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) · 58 unmodified lines
357 xprt_clear_locked(xprt);359 xprt_clear_locked(xprt);
358 __xprt_lock_write_next(xprt);360 __xprt_lock_write_next(xprt);
359 }361 }
362 trace_xprt_release_xprt(xprt, task);
360}363}
361EXPORT_SYMBOL_GPL(xprt_release_xprt);364EXPORT_SYMBOL_GPL(xprt_release_xprt);
362 365
@@ -374,6 +377,7 @@ void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) · 11 unmodified lines
374 xprt_clear_locked(xprt);377 xprt_clear_locked(xprt);
375 __xprt_lock_write_next_cong(xprt);378 __xprt_lock_write_next_cong(xprt);
376 }379 }
380 trace_xprt_release_cong(xprt, task);
377}381}
378EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);382EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);
379 383
@@ -395,8 +399,7 @@ __xprt_get_cong(struct rpc_xprt *xprt, struct rpc_rqst *req) · 15 unmodified lines
395{399{
396 if (req->rq_cong)400 if (req->rq_cong)
397 return 1;401 return 1;
398 dprintk("RPC: %5u xprt_cwnd_limited cong = %lu cwnd = %lu\n",402 trace_xprt_get_cong(xprt, req->rq_task);
399 req->rq_task->tk_pid, xprt->cong, xprt->cwnd);
400 if (RPCXPRT_CONGESTED(xprt)) {403 if (RPCXPRT_CONGESTED(xprt)) {
401 xprt_set_congestion_window_wait(xprt);404 xprt_set_congestion_window_wait(xprt);
402 return 0;405 return 0;
@@ -418,6 +421,7 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req) · 15 unmodified lines
418 req->rq_cong = 0;421 req->rq_cong = 0;
419 xprt->cong -= RPC_CWNDSCALE;422 xprt->cong -= RPC_CWNDSCALE;
420 xprt_test_and_clear_congestion_window_wait(xprt);423 xprt_test_and_clear_congestion_window_wait(xprt);
424 trace_xprt_put_cong(xprt, req->rq_task);
421 __xprt_lock_write_next_cong(xprt);425 __xprt_lock_write_next_cong(xprt);
422}426}
423 427
net/sunrpc/xprtrdma/backchannel.c+1−1
@@ -79,7 +79,7 @@ static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst) · 78 unmodified lines
79 *p = xdr_zero;79 *p = xdr_zero;
80 80
81 if (rpcrdma_prepare_send_sges(r_xprt, req, RPCRDMA_HDRLEN_MIN,81 if (rpcrdma_prepare_send_sges(r_xprt, req, RPCRDMA_HDRLEN_MIN,
82 &rqst->rq_snd_buf, rpcrdma_noch))82 &rqst->rq_snd_buf, rpcrdma_noch_pullup))
83 return -EIO;83 return -EIO;
84 84
85 trace_xprtrdma_cb_reply(rqst);85 trace_xprtrdma_cb_reply(rqst);
net/sunrpc/xprtrdma/frwr_ops.c+11−42
@@ -36,8 +36,8 @@ · 35 unmodified lines
36 * connect worker from running concurrently.36 * connect worker from running concurrently.
37 *37 *
38 * When the underlying transport disconnects, MRs that are in flight38 * When the underlying transport disconnects, MRs that are in flight
39 * are flushed and are likely unusable. Thus all flushed MRs are39 * are flushed and are likely unusable. Thus all MRs are destroyed.
40 * destroyed. New MRs are created on demand.40 * New MRs are created on demand.
41 */41 */
42 42
43#include <linux/sunrpc/rpc_rdma.h>43#include <linux/sunrpc/rpc_rdma.h>
@@ -88,8 +88,10 @@ void frwr_release_mr(struct rpcrdma_mr *mr) · 44 unmodified lines
88 kfree(mr);88 kfree(mr);
89}89}
90 90
91static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)91static void frwr_mr_recycle(struct rpcrdma_mr *mr)
92{92{
93 struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
94
93 trace_xprtrdma_mr_recycle(mr);95 trace_xprtrdma_mr_recycle(mr);
94 96
95 if (mr->mr_dir != DMA_NONE) {97 if (mr->mr_dir != DMA_NONE) {
@@ -107,32 +109,6 @@ static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr) · 11 unmodified lines
107 frwr_release_mr(mr);109 frwr_release_mr(mr);
108}110}
109 111
110/* MRs are dynamically allocated, so simply clean up and release the MR.
111 * A replacement MR will subsequently be allocated on demand.
112 */
113static void
114frwr_mr_recycle_worker(struct work_struct *work)
115{
116 struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr,
117 mr_recycle);
118
119 frwr_mr_recycle(mr->mr_xprt, mr);
120}
121
122/* frwr_recycle - Discard MRs
123 * @req: request to reset
124 *
125 * Used after a reconnect. These MRs could be in flight, we can't
126 * tell. Safe thing to do is release them.
127 */
128void frwr_recycle(struct rpcrdma_req *req)
129{
130 struct rpcrdma_mr *mr;
131
132 while ((mr = rpcrdma_mr_pop(&req->rl_registered)))
133 frwr_mr_recycle(mr->mr_xprt, mr);
134}
135
136/* frwr_reset - Place MRs back on the free list112/* frwr_reset - Place MRs back on the free list
137 * @req: request to reset113 * @req: request to reset
138 *114 *
@@ -166,9 +142,6 @@ int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) · 27 unmodified lines
166 struct ib_mr *frmr;142 struct ib_mr *frmr;
167 int rc;143 int rc;
168 144
169 /* NB: ib_alloc_mr and device drivers typically allocate
170 * memory with GFP_KERNEL.
171 */
172 frmr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);145 frmr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);
173 if (IS_ERR(frmr))146 if (IS_ERR(frmr))
174 goto out_mr_err;147 goto out_mr_err;
@@ -180,7 +153,6 @@ int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) · 5 unmodified lines
180 mr->frwr.fr_mr = frmr;153 mr->frwr.fr_mr = frmr;
181 mr->mr_dir = DMA_NONE;154 mr->mr_dir = DMA_NONE;
182 INIT_LIST_HEAD(&mr->mr_list);155 INIT_LIST_HEAD(&mr->mr_list);
183 INIT_WORK(&mr->mr_recycle, frwr_mr_recycle_worker);
184 init_completion(&mr->frwr.fr_linv_done);156 init_completion(&mr->frwr.fr_linv_done);
185 157
186 sg_init_table(sg, depth);158 sg_init_table(sg, depth);
@@ -424,7 +396,7 @@ int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req) · 237 unmodified lines
424 struct ib_send_wr *post_wr;396 struct ib_send_wr *post_wr;
425 struct rpcrdma_mr *mr;397 struct rpcrdma_mr *mr;
426 398
427 post_wr = &req->rl_sendctx->sc_wr;399 post_wr = &req->rl_wr;
428 list_for_each_entry(mr, &req->rl_registered, mr_list) {400 list_for_each_entry(mr, &req->rl_registered, mr_list) {
429 struct rpcrdma_frwr *frwr;401 struct rpcrdma_frwr *frwr;
430 402
@@ -440,9 +412,6 @@ int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req) · 9 unmodified lines
440 post_wr = &frwr->fr_regwr.wr;412 post_wr = &frwr->fr_regwr.wr;
441 }413 }
442 414
443 /* If ib_post_send fails, the next ->send_request for
444 * @req will queue these MRs for recovery.
445 */
446 return ib_post_send(ia->ri_id->qp, post_wr, NULL);415 return ib_post_send(ia->ri_id->qp, post_wr, NULL);
447}416}
448 417
@@ -468,7 +437,7 @@ void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs) · 19 unmodified lines
468static void __frwr_release_mr(struct ib_wc *wc, struct rpcrdma_mr *mr)437static void __frwr_release_mr(struct ib_wc *wc, struct rpcrdma_mr *mr)
469{438{
470 if (wc->status != IB_WC_SUCCESS)439 if (wc->status != IB_WC_SUCCESS)
471 rpcrdma_mr_recycle(mr);440 frwr_mr_recycle(mr);
472 else441 else
473 rpcrdma_mr_put(mr);442 rpcrdma_mr_put(mr);
474}443}
@@ -570,7 +539,6 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 95 unmodified lines
570 */539 */
571 bad_wr = NULL;540 bad_wr = NULL;
572 rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);541 rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
573 trace_xprtrdma_post_send(req, rc);
574 542
575 /* The final LOCAL_INV WR in the chain is supposed to543 /* The final LOCAL_INV WR in the chain is supposed to
576 * do the wake. If it was never posted, the wake will544 * do the wake. If it was never posted, the wake will
@@ -583,6 +551,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 6 unmodified lines
583 551
584 /* Recycle MRs in the LOCAL_INV chain that did not get posted.552 /* Recycle MRs in the LOCAL_INV chain that did not get posted.
585 */553 */
554 trace_xprtrdma_post_linv(req, rc);
586 while (bad_wr) {555 while (bad_wr) {
587 frwr = container_of(bad_wr, struct rpcrdma_frwr,556 frwr = container_of(bad_wr, struct rpcrdma_frwr,
588 fr_invwr);557 fr_invwr);
@@ -590,7 +559,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 1 unmodified line
590 bad_wr = bad_wr->next;559 bad_wr = bad_wr->next;
591 560
592 list_del_init(&mr->mr_list);561 list_del_init(&mr->mr_list);
593 rpcrdma_mr_recycle(mr);562 frwr_mr_recycle(mr);
594 }563 }
595}564}
596 565
@@ -673,18 +642,18 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 76 unmodified lines
673 */642 */
674 bad_wr = NULL;643 bad_wr = NULL;
675 rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);644 rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
676 trace_xprtrdma_post_send(req, rc);
677 if (!rc)645 if (!rc)
678 return;646 return;
679 647
680 /* Recycle MRs in the LOCAL_INV chain that did not get posted.648 /* Recycle MRs in the LOCAL_INV chain that did not get posted.
681 */649 */
650 trace_xprtrdma_post_linv(req, rc);
682 while (bad_wr) {651 while (bad_wr) {
683 frwr = container_of(bad_wr, struct rpcrdma_frwr, fr_invwr);652 frwr = container_of(bad_wr, struct rpcrdma_frwr, fr_invwr);
684 mr = container_of(frwr, struct rpcrdma_mr, frwr);653 mr = container_of(frwr, struct rpcrdma_mr, frwr);
685 bad_wr = bad_wr->next;654 bad_wr = bad_wr->next;
686 655
687 rpcrdma_mr_recycle(mr);656 frwr_mr_recycle(mr);
688 }657 }
689 658
690 /* The final LOCAL_INV WR in the chain is supposed to659 /* The final LOCAL_INV WR in the chain is supposed to
net/sunrpc/xprtrdma/rpc_rdma.c+268−145
@@ -78,8 +78,6 @@ static unsigned int rpcrdma_max_call_header_size(unsigned int maxsegs) · 77 unmodified lines
78 size += rpcrdma_segment_maxsz * sizeof(__be32);78 size += rpcrdma_segment_maxsz * sizeof(__be32);
79 size += sizeof(__be32); /* list discriminator */79 size += sizeof(__be32); /* list discriminator */
80 80
81 dprintk("RPC: %s: max call header size = %u\n",
82 __func__, size);
83 return size;81 return size;
84}82}
85 83
@@ -100,8 +98,6 @@ static unsigned int rpcrdma_max_reply_header_size(unsigned int maxsegs) · 14 unmodified lines
100 size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32);98 size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32);
101 size += sizeof(__be32); /* list discriminator */99 size += sizeof(__be32); /* list discriminator */
102 100
103 dprintk("RPC: %s: max reply header size = %u\n",
104 __func__, size);
105 return size;101 return size;
106}102}
107 103
@@ -363,8 +359,7 @@ static struct rpcrdma_mr_seg *rpcrdma_mr_prepare(struct rpcrdma_xprt *r_xprt, · 255 unmodified lines
363out_getmr_err:359out_getmr_err:
364 trace_xprtrdma_nomrs(req);360 trace_xprtrdma_nomrs(req);
365 xprt_wait_for_buffer_space(&r_xprt->rx_xprt);361 xprt_wait_for_buffer_space(&r_xprt->rx_xprt);
366 if (r_xprt->rx_ep.rep_connected != -ENODEV)362 rpcrdma_mrs_refresh(r_xprt);
367 schedule_work(&r_xprt->rx_buf.rb_refresh_worker);
368 return ERR_PTR(-EAGAIN);363 return ERR_PTR(-EAGAIN);
369}364}
370 365
@@ -393,7 +388,7 @@ static int rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, · 22 unmodified lines
393 unsigned int pos;388 unsigned int pos;
394 int nsegs;389 int nsegs;
395 390
396 if (rtype == rpcrdma_noch)391 if (rtype == rpcrdma_noch_pullup || rtype == rpcrdma_noch_mapped)
397 goto done;392 goto done;
398 393
399 pos = rqst->rq_snd_buf.head[0].iov_len;394 pos = rqst->rq_snd_buf.head[0].iov_len;
@@ -565,6 +560,7 @@ static void rpcrdma_sendctx_done(struct kref *kref) · 165 unmodified lines
565 */560 */
566void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)561void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
567{562{
563 struct rpcrdma_regbuf *rb = sc->sc_req->rl_sendbuf;
568 struct ib_sge *sge;564 struct ib_sge *sge;
569 565
570 if (!sc->sc_unmap_count)566 if (!sc->sc_unmap_count)
@@ -576,7 +572,7 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc) · 5 unmodified lines
576 */572 */
577 for (sge = &sc->sc_sges[2]; sc->sc_unmap_count;573 for (sge = &sc->sc_sges[2]; sc->sc_unmap_count;
578 ++sge, --sc->sc_unmap_count)574 ++sge, --sc->sc_unmap_count)
579 ib_dma_unmap_page(sc->sc_device, sge->addr, sge->length,575 ib_dma_unmap_page(rdmab_device(rb), sge->addr, sge->length,
580 DMA_TO_DEVICE);576 DMA_TO_DEVICE);
581 577
582 kref_put(&sc->sc_req->rl_kref, rpcrdma_sendctx_done);578 kref_put(&sc->sc_req->rl_kref, rpcrdma_sendctx_done);
@@ -589,149 +585,228 @@ static bool rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt, · 6 unmodified lines
589{585{
590 struct rpcrdma_sendctx *sc = req->rl_sendctx;586 struct rpcrdma_sendctx *sc = req->rl_sendctx;
591 struct rpcrdma_regbuf *rb = req->rl_rdmabuf;587 struct rpcrdma_regbuf *rb = req->rl_rdmabuf;
592 struct ib_sge *sge = sc->sc_sges;588 struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
593 589
594 if (!rpcrdma_regbuf_dma_map(r_xprt, rb))590 if (!rpcrdma_regbuf_dma_map(r_xprt, rb))
595 goto out_regbuf;591 return false;
596 sge->addr = rdmab_addr(rb);592 sge->addr = rdmab_addr(rb);
597 sge->length = len;593 sge->length = len;
598 sge->lkey = rdmab_lkey(rb);594 sge->lkey = rdmab_lkey(rb);
599 595
600 ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length,596 ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length,
601 DMA_TO_DEVICE);597 DMA_TO_DEVICE);
602 sc->sc_wr.num_sge++;
603 return true;598 return true;
604
605out_regbuf:
606 pr_err("rpcrdma: failed to DMA map a Send buffer\n");
607 return false;
608}599}
609 600
610/* Prepare the Send SGEs. The head and tail iovec, and each entry601/* The head iovec is straightforward, as it is usually already
611 * in the page list, gets its own SGE.602 * DMA-mapped. Sync the content that has changed.
612 */603 */
613static bool rpcrdma_prepare_msg_sges(struct rpcrdma_xprt *r_xprt,604static bool rpcrdma_prepare_head_iov(struct rpcrdma_xprt *r_xprt,
614 struct rpcrdma_req *req,605 struct rpcrdma_req *req, unsigned int len)
615 struct xdr_buf *xdr,
616 enum rpcrdma_chunktype rtype)
617{606{
618 struct rpcrdma_sendctx *sc = req->rl_sendctx;607 struct rpcrdma_sendctx *sc = req->rl_sendctx;
619 unsigned int sge_no, page_base, len, remaining;608 struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
620 struct rpcrdma_regbuf *rb = req->rl_sendbuf;609 struct rpcrdma_regbuf *rb = req->rl_sendbuf;
621 struct ib_sge *sge = sc->sc_sges;
622 struct page *page, **ppages;
623 610
624 /* The head iovec is straightforward, as it is already
625 * DMA-mapped. Sync the content that has changed.
626 */
627 if (!rpcrdma_regbuf_dma_map(r_xprt, rb))611 if (!rpcrdma_regbuf_dma_map(r_xprt, rb))
628 goto out_regbuf;612 return false;
629 sc->sc_device = rdmab_device(rb);
630 sge_no = 1;
631 sge[sge_no].addr = rdmab_addr(rb);
632 sge[sge_no].length = xdr->head[0].iov_len;
633 sge[sge_no].lkey = rdmab_lkey(rb);
634 ib_dma_sync_single_for_device(rdmab_device(rb), sge[sge_no].addr,
635 sge[sge_no].length, DMA_TO_DEVICE);
636
637 /* If there is a Read chunk, the page list is being handled
638 * via explicit RDMA, and thus is skipped here. However, the
639 * tail iovec may include an XDR pad for the page list, as
640 * well as additional content, and may not reside in the
641 * same page as the head iovec.
642 */
643 if (rtype == rpcrdma_readch) {
644 len = xdr->tail[0].iov_len;
645 613
646 /* Do not include the tail if it is only an XDR pad */614 sge->addr = rdmab_addr(rb);
647 if (len < 4)615 sge->length = len;
648 goto out;616 sge->lkey = rdmab_lkey(rb);
649 617
650 page = virt_to_page(xdr->tail[0].iov_base);618 ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length,
651 page_base = offset_in_page(xdr->tail[0].iov_base);619 DMA_TO_DEVICE);
620 return true;
621}
652 622
653 /* If the content in the page list is an odd length,623/* If there is a page list present, DMA map and prepare an
654 * xdr_write_pages() has added a pad at the beginning624 * SGE for each page to be sent.
655 * of the tail iovec. Force the tail's non-pad content625 */
656 * to land at the next XDR position in the Send message.626static bool rpcrdma_prepare_pagelist(struct rpcrdma_req *req,
657 */627 struct xdr_buf *xdr)
658 page_base += len & 3;628{
659 len -= len & 3;629 struct rpcrdma_sendctx *sc = req->rl_sendctx;
660 goto map_tail;630 struct rpcrdma_regbuf *rb = req->rl_sendbuf;
661 }631 unsigned int page_base, len, remaining;
632 struct page **ppages;
633 struct ib_sge *sge;
662 634
663 /* If there is a page list present, temporarily DMA map635 ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
664 * and prepare an SGE for each page to be sent.636 page_base = offset_in_page(xdr->page_base);
665 */637 remaining = xdr->page_len;
666 if (xdr->page_len) {638 while (remaining) {
667 ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);639 sge = &sc->sc_sges[req->rl_wr.num_sge++];
668 page_base = offset_in_page(xdr->page_base);640 len = min_t(unsigned int, PAGE_SIZE - page_base, remaining);
669 remaining = xdr->page_len;641 sge->addr = ib_dma_map_page(rdmab_device(rb), *ppages,
670 while (remaining) {642 page_base, len, DMA_TO_DEVICE);
671 sge_no++;643 if (ib_dma_mapping_error(rdmab_device(rb), sge->addr))
672 if (sge_no > RPCRDMA_MAX_SEND_SGES - 2)644 goto out_mapping_err;
673 goto out_mapping_overflow;
674
675 len = min_t(u32, PAGE_SIZE - page_base, remaining);
676 sge[sge_no].addr =
677 ib_dma_map_page(rdmab_device(rb), *ppages,
678 page_base, len, DMA_TO_DEVICE);
679 if (ib_dma_mapping_error(rdmab_device(rb),
680 sge[sge_no].addr))
681 goto out_mapping_err;
682 sge[sge_no].length = len;
683 sge[sge_no].lkey = rdmab_lkey(rb);
684
685 sc->sc_unmap_count++;
686 ppages++;
687 remaining -= len;
688 page_base = 0;
689 }
690 }
691 645
692 /* The tail iovec is not always constructed in the same646 sge->length = len;
693 * page where the head iovec resides (see, for example,647 sge->lkey = rdmab_lkey(rb);
694 * gss_wrap_req_priv). To neatly accommodate that case,
695 * DMA map it separately.
696 */
697 if (xdr->tail[0].iov_len) {
698 page = virt_to_page(xdr->tail[0].iov_base);
699 page_base = offset_in_page(xdr->tail[0].iov_base);
700 len = xdr->tail[0].iov_len;
701 648
702map_tail:
703 sge_no++;
704 sge[sge_no].addr =
705 ib_dma_map_page(rdmab_device(rb), page, page_base, len,
706 DMA_TO_DEVICE);
707 if (ib_dma_mapping_error(rdmab_device(rb), sge[sge_no].addr))
708 goto out_mapping_err;
709 sge[sge_no].length = len;
710 sge[sge_no].lkey = rdmab_lkey(rb);
711 sc->sc_unmap_count++;649 sc->sc_unmap_count++;
650 ppages++;
651 remaining -= len;
652 page_base = 0;
712 }653 }
713 654
714out:
715 sc->sc_wr.num_sge += sge_no;
716 if (sc->sc_unmap_count)
717 kref_get(&req->rl_kref);
718 return true;655 return true;
719 656
720out_regbuf:657out_mapping_err:
721 pr_err("rpcrdma: failed to DMA map a Send buffer\n");658 trace_xprtrdma_dma_maperr(sge->addr);
722 return false;659 return false;
660}
723 661
724out_mapping_overflow:662/* The tail iovec may include an XDR pad for the page list,
725 rpcrdma_sendctx_unmap(sc);663 * as well as additional content, and may not reside in the
726 pr_err("rpcrdma: too many Send SGEs (%u)\n", sge_no);664 * same page as the head iovec.
727 return false;665 */
666static bool rpcrdma_prepare_tail_iov(struct rpcrdma_req *req,
667 struct xdr_buf *xdr,
668 unsigned int page_base, unsigned int len)
669{
670 struct rpcrdma_sendctx *sc = req->rl_sendctx;
671 struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
672 struct rpcrdma_regbuf *rb = req->rl_sendbuf;
673 struct page *page = virt_to_page(xdr->tail[0].iov_base);
674
675 sge->addr = ib_dma_map_page(rdmab_device(rb), page, page_base, len,
676 DMA_TO_DEVICE);
677 if (ib_dma_mapping_error(rdmab_device(rb), sge->addr))
678 goto out_mapping_err;
679
680 sge->length = len;
681 sge->lkey = rdmab_lkey(rb);
682 ++sc->sc_unmap_count;
683 return true;
728 684
729out_mapping_err:685out_mapping_err:
730 rpcrdma_sendctx_unmap(sc);686 trace_xprtrdma_dma_maperr(sge->addr);
731 trace_xprtrdma_dma_maperr(sge[sge_no].addr);
732 return false;687 return false;
733}688}
734 689
690/* Copy the tail to the end of the head buffer.
691 */
692static void rpcrdma_pullup_tail_iov(struct rpcrdma_xprt *r_xprt,
693 struct rpcrdma_req *req,
694 struct xdr_buf *xdr)
695{
696 unsigned char *dst;
697
698 dst = (unsigned char *)xdr->head[0].iov_base;
699 dst += xdr->head[0].iov_len + xdr->page_len;
700 memmove(dst, xdr->tail[0].iov_base, xdr->tail[0].iov_len);
701 r_xprt->rx_stats.pullup_copy_count += xdr->tail[0].iov_len;
702}
703
704/* Copy pagelist content into the head buffer.
705 */
706static void rpcrdma_pullup_pagelist(struct rpcrdma_xprt *r_xprt,
707 struct rpcrdma_req *req,
708 struct xdr_buf *xdr)
709{
710 unsigned int len, page_base, remaining;
711 struct page **ppages;
712 unsigned char *src, *dst;
713
714 dst = (unsigned char *)xdr->head[0].iov_base;
715 dst += xdr->head[0].iov_len;
716 ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
717 page_base = offset_in_page(xdr->page_base);
718 remaining = xdr->page_len;
719 while (remaining) {
720 src = page_address(*ppages);
721 src += page_base;
722 len = min_t(unsigned int, PAGE_SIZE - page_base, remaining);
723 memcpy(dst, src, len);
724 r_xprt->rx_stats.pullup_copy_count += len;
725
726 ppages++;
727 dst += len;
728 remaining -= len;
729 page_base = 0;
730 }
731}
732
733/* Copy the contents of @xdr into @rl_sendbuf and DMA sync it.
734 * When the head, pagelist, and tail are small, a pull-up copy
735 * is considerably less costly than DMA mapping the components
736 * of @xdr.
737 *
738 * Assumptions:
739 * - the caller has already verified that the total length
740 * of the RPC Call body will fit into @rl_sendbuf.
741 */
742static bool rpcrdma_prepare_noch_pullup(struct rpcrdma_xprt *r_xprt,
743 struct rpcrdma_req *req,
744 struct xdr_buf *xdr)
745{
746 if (unlikely(xdr->tail[0].iov_len))
747 rpcrdma_pullup_tail_iov(r_xprt, req, xdr);
748
749 if (unlikely(xdr->page_len))
750 rpcrdma_pullup_pagelist(r_xprt, req, xdr);
751
752 /* The whole RPC message resides in the head iovec now */
753 return rpcrdma_prepare_head_iov(r_xprt, req, xdr->len);
754}
755
756static bool rpcrdma_prepare_noch_mapped(struct rpcrdma_xprt *r_xprt,
757 struct rpcrdma_req *req,
758 struct xdr_buf *xdr)
759{
760 struct kvec *tail = &xdr->tail[0];
761
762 if (!rpcrdma_prepare_head_iov(r_xprt, req, xdr->head[0].iov_len))
763 return false;
764 if (xdr->page_len)
765 if (!rpcrdma_prepare_pagelist(req, xdr))
766 return false;
767 if (tail->iov_len)
768 if (!rpcrdma_prepare_tail_iov(req, xdr,
769 offset_in_page(tail->iov_base),
770 tail->iov_len))
771 return false;
772
773 if (req->rl_sendctx->sc_unmap_count)
774 kref_get(&req->rl_kref);
775 return true;
776}
777
778static bool rpcrdma_prepare_readch(struct rpcrdma_xprt *r_xprt,
779 struct rpcrdma_req *req,
780 struct xdr_buf *xdr)
781{
782 if (!rpcrdma_prepare_head_iov(r_xprt, req, xdr->head[0].iov_len))
783 return false;
784
785 /* If there is a Read chunk, the page list is being handled
786 * via explicit RDMA, and thus is skipped here.
787 */
788
789 /* Do not include the tail if it is only an XDR pad */
790 if (xdr->tail[0].iov_len > 3) {
791 unsigned int page_base, len;
792
793 /* If the content in the page list is an odd length,
794 * xdr_write_pages() adds a pad at the beginning of
795 * the tail iovec. Force the tail's non-pad content to
796 * land at the next XDR position in the Send message.
797 */
798 page_base = offset_in_page(xdr->tail[0].iov_base);
799 len = xdr->tail[0].iov_len;
800 page_base += len & 3;
801 len -= len & 3;
802 if (!rpcrdma_prepare_tail_iov(req, xdr, page_base, len))
803 return false;
804 kref_get(&req->rl_kref);
805 }
806
807 return true;
808}
809
735/**810/**
736 * rpcrdma_prepare_send_sges - Construct SGEs for a Send WR811 * rpcrdma_prepare_send_sges - Construct SGEs for a Send WR
737 * @r_xprt: controlling transport812 * @r_xprt: controlling transport
@@ -742,31 +817,53 @@ out_mapping_err: · 4 unmodified lines
742 *817 *
743 * Returns 0 on success; otherwise a negative errno is returned.818 * Returns 0 on success; otherwise a negative errno is returned.
744 */819 */
745int820inline int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,
746rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,821 struct rpcrdma_req *req, u32 hdrlen,
747 struct rpcrdma_req *req, u32 hdrlen,822 struct xdr_buf *xdr,
748 struct xdr_buf *xdr, enum rpcrdma_chunktype rtype)823 enum rpcrdma_chunktype rtype)
749{824{
750 int ret;825 int ret;
751 826
752 ret = -EAGAIN;827 ret = -EAGAIN;
753 req->rl_sendctx = rpcrdma_sendctx_get_locked(r_xprt);828 req->rl_sendctx = rpcrdma_sendctx_get_locked(r_xprt);
754 if (!req->rl_sendctx)829 if (!req->rl_sendctx)
755 goto err;830 goto out_nosc;
756 req->rl_sendctx->sc_wr.num_sge = 0;
757 req->rl_sendctx->sc_unmap_count = 0;831 req->rl_sendctx->sc_unmap_count = 0;
758 req->rl_sendctx->sc_req = req;832 req->rl_sendctx->sc_req = req;
759 kref_init(&req->rl_kref);833 kref_init(&req->rl_kref);
834 req->rl_wr.wr_cqe = &req->rl_sendctx->sc_cqe;
835 req->rl_wr.sg_list = req->rl_sendctx->sc_sges;
836 req->rl_wr.num_sge = 0;
837 req->rl_wr.opcode = IB_WR_SEND;
760 838
761 ret = -EIO;839 ret = -EIO;
762 if (!rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen))840 if (!rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen))
763 goto err;841 goto out_unmap;
764 if (rtype != rpcrdma_areadch)842
765 if (!rpcrdma_prepare_msg_sges(r_xprt, req, xdr, rtype))843 switch (rtype) {
766 goto err;844 case rpcrdma_noch_pullup:
845 if (!rpcrdma_prepare_noch_pullup(r_xprt, req, xdr))
846 goto out_unmap;
847 break;
848 case rpcrdma_noch_mapped:
849 if (!rpcrdma_prepare_noch_mapped(r_xprt, req, xdr))
850 goto out_unmap;
851 break;
852 case rpcrdma_readch:
853 if (!rpcrdma_prepare_readch(r_xprt, req, xdr))
854 goto out_unmap;
855 break;
856 case rpcrdma_areadch:
857 break;
858 default:
859 goto out_unmap;
860 }
861
767 return 0;862 return 0;
768 863
769err:864out_unmap:
865 rpcrdma_sendctx_unmap(req->rl_sendctx);
866out_nosc:
770 trace_xprtrdma_prepsend_failed(&req->rl_slot, ret);867 trace_xprtrdma_prepsend_failed(&req->rl_slot, ret);
771 return ret;868 return ret;
772}869}
@@ -796,6 +893,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) · 23 unmodified lines
796 struct rpcrdma_req *req = rpcr_to_rdmar(rqst);893 struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
797 struct xdr_stream *xdr = &req->rl_stream;894 struct xdr_stream *xdr = &req->rl_stream;
798 enum rpcrdma_chunktype rtype, wtype;895 enum rpcrdma_chunktype rtype, wtype;
896 struct xdr_buf *buf = &rqst->rq_snd_buf;
799 bool ddp_allowed;897 bool ddp_allowed;
800 __be32 *p;898 __be32 *p;
801 int ret;899 int ret;
@@ -853,8 +951,9 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) · 51 unmodified lines
853 */951 */
854 if (rpcrdma_args_inline(r_xprt, rqst)) {952 if (rpcrdma_args_inline(r_xprt, rqst)) {
855 *p++ = rdma_msg;953 *p++ = rdma_msg;
856 rtype = rpcrdma_noch;954 rtype = buf->len < rdmab_length(req->rl_sendbuf) ?
857 } else if (ddp_allowed && rqst->rq_snd_buf.flags & XDRBUF_WRITE) {955 rpcrdma_noch_pullup : rpcrdma_noch_mapped;
956 } else if (ddp_allowed && buf->flags & XDRBUF_WRITE) {
858 *p++ = rdma_msg;957 *p++ = rdma_msg;
859 rtype = rpcrdma_readch;958 rtype = rpcrdma_readch;
860 } else {959 } else {
@@ -863,12 +962,6 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) · 2 unmodified lines
863 rtype = rpcrdma_areadch;962 rtype = rpcrdma_areadch;
864 }963 }
865 964
866 /* If this is a retransmit, discard previously registered
867 * chunks. Very likely the connection has been replaced,
868 * so these registrations are invalid and unusable.
869 */
870 frwr_recycle(req);
871
872 /* This implementation supports the following combinations965 /* This implementation supports the following combinations
873 * of chunk lists in one RPC-over-RDMA Call message:966 * of chunk lists in one RPC-over-RDMA Call message:
874 *967 *
@@ -902,7 +995,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) · 27 unmodified lines
902 goto out_err;995 goto out_err;
903 996
904 ret = rpcrdma_prepare_send_sges(r_xprt, req, req->rl_hdrbuf.len,997 ret = rpcrdma_prepare_send_sges(r_xprt, req, req->rl_hdrbuf.len,
905 &rqst->rq_snd_buf, rtype);998 buf, rtype);
906 if (ret)999 if (ret)
907 goto out_err;1000 goto out_err;
908 1001
@@ -916,6 +1009,40 @@ out_err: · 7 unmodified lines
916 return ret;1009 return ret;
917}1010}
918 1011
1012static void __rpcrdma_update_cwnd_locked(struct rpc_xprt *xprt,
1013 struct rpcrdma_buffer *buf,
1014 u32 grant)
1015{
1016 buf->rb_credits = grant;
1017 xprt->cwnd = grant << RPC_CWNDSHIFT;
1018}
1019
1020static void rpcrdma_update_cwnd(struct rpcrdma_xprt *r_xprt, u32 grant)
1021{
1022 struct rpc_xprt *xprt = &r_xprt->rx_xprt;
1023
1024 spin_lock(&xprt->transport_lock);
1025 __rpcrdma_update_cwnd_locked(xprt, &r_xprt->rx_buf, grant);
1026 spin_unlock(&xprt->transport_lock);
1027}
1028
1029/**
1030 * rpcrdma_reset_cwnd - Reset the xprt's congestion window
1031 * @r_xprt: controlling transport instance
1032 *
1033 * Prepare @r_xprt for the next connection by reinitializing
1034 * its credit grant to one (see RFC 8166, Section 3.3.3).
1035 */
1036void rpcrdma_reset_cwnd(struct rpcrdma_xprt *r_xprt)
1037{
1038 struct rpc_xprt *xprt = &r_xprt->rx_xprt;
1039
1040 spin_lock(&xprt->transport_lock);
1041 xprt->cong = 0;
1042 __rpcrdma_update_cwnd_locked(xprt, &r_xprt->rx_buf, 1);
1043 spin_unlock(&xprt->transport_lock);
1044}
1045
919/**1046/**
920 * rpcrdma_inline_fixup - Scatter inline received data into rqst's iovecs1047 * rpcrdma_inline_fixup - Scatter inline received data into rqst's iovecs
921 * @rqst: controlling RPC request1048 * @rqst: controlling RPC request
@@ -955,7 +1082,6 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad) · 33 unmodified lines
955 curlen = rqst->rq_rcv_buf.head[0].iov_len;1082 curlen = rqst->rq_rcv_buf.head[0].iov_len;
956 if (curlen > copy_len)1083 if (curlen > copy_len)
957 curlen = copy_len;1084 curlen = copy_len;
958 trace_xprtrdma_fixup(rqst, copy_len, curlen);
959 srcp += curlen;1085 srcp += curlen;
960 copy_len -= curlen;1086 copy_len -= curlen;
961 1087
@@ -975,8 +1101,6 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad) · 13 unmodified lines
975 if (curlen > pagelist_len)1101 if (curlen > pagelist_len)
976 curlen = pagelist_len;1102 curlen = pagelist_len;
977 1103
978 trace_xprtrdma_fixup_pg(rqst, i, srcp,
979 copy_len, curlen);
980 destp = kmap_atomic(ppages[i]);1104 destp = kmap_atomic(ppages[i]);
981 memcpy(destp + page_base, srcp, curlen);1105 memcpy(destp + page_base, srcp, curlen);
982 flush_dcache_page(ppages[i]);1106 flush_dcache_page(ppages[i]);
@@ -1008,6 +1132,8 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad) · 25 unmodified lines
1008 rqst->rq_private_buf.tail[0].iov_base = srcp;1132 rqst->rq_private_buf.tail[0].iov_base = srcp;
1009 }1133 }
1010 1134
1135 if (fixup_copy_count)
1136 trace_xprtrdma_fixup(rqst, fixup_copy_count);
1011 return fixup_copy_count;1137 return fixup_copy_count;
1012}1138}
1013 1139
@@ -1356,12 +1482,9 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) · 342 unmodified lines
1356 credits = 1; /* don't deadlock */1482 credits = 1; /* don't deadlock */
1357 else if (credits > buf->rb_max_requests)1483 else if (credits > buf->rb_max_requests)
1358 credits = buf->rb_max_requests;1484 credits = buf->rb_max_requests;
1359 if (buf->rb_credits != credits) {1485 if (buf->rb_credits != credits)
1360 spin_lock(&xprt->transport_lock);1486 rpcrdma_update_cwnd(r_xprt, credits);
1361 buf->rb_credits = credits;1487 rpcrdma_post_recvs(r_xprt, false);
1362 xprt->cwnd = credits << RPC_CWNDSHIFT;
1363 spin_unlock(&xprt->transport_lock);
1364 }
1365 1488
1366 req = rpcr_to_rdmar(rqst);1489 req = rpcr_to_rdmar(rqst);
1367 if (req->rl_reply) {1490 if (req->rl_reply) {
net/sunrpc/xprtrdma/transport.c+10−23
@@ -243,16 +243,13 @@ xprt_rdma_connect_worker(struct work_struct *work) · 242 unmodified lines
243 rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);243 rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
244 xprt_clear_connecting(xprt);244 xprt_clear_connecting(xprt);
245 if (r_xprt->rx_ep.rep_connected > 0) {245 if (r_xprt->rx_ep.rep_connected > 0) {
246 if (!xprt_test_and_set_connected(xprt)) {246 xprt->stat.connect_count++;
247 xprt->stat.connect_count++;247 xprt->stat.connect_time += (long)jiffies -
248 xprt->stat.connect_time += (long)jiffies -248 xprt->stat.connect_start;
249 xprt->stat.connect_start;249 xprt_set_connected(xprt);
250 xprt_wake_pending_tasks(xprt, -EAGAIN);250 rc = -EAGAIN;
251 }
252 } else {
253 if (xprt_test_and_clear_connected(xprt))
254 xprt_wake_pending_tasks(xprt, rc);
255 }251 }
252 xprt_wake_pending_tasks(xprt, rc);
256}253}
257 254
258/**255/**
@@ -425,12 +422,6 @@ void xprt_rdma_close(struct rpc_xprt *xprt) · 166 unmodified lines
425 return;422 return;
426 rpcrdma_ep_disconnect(ep, ia);423 rpcrdma_ep_disconnect(ep, ia);
427 424
428 /* Prepare @xprt for the next connection by reinitializing
429 * its credit grant to one (see RFC 8166, Section 3.3.3).
430 */
431 r_xprt->rx_buf.rb_credits = 1;
432 xprt->cwnd = RPC_CWNDSHIFT;
433
434out:425out:
435 xprt->reestablish_timeout = 0;426 xprt->reestablish_timeout = 0;
436 ++xprt->connect_cookie;427 ++xprt->connect_cookie;
@@ -450,12 +441,6 @@ xprt_rdma_set_port(struct rpc_xprt *xprt, u16 port) · 13 unmodified lines
450 struct sockaddr *sap = (struct sockaddr *)&xprt->addr;441 struct sockaddr *sap = (struct sockaddr *)&xprt->addr;
451 char buf[8];442 char buf[8];
452 443
453 dprintk("RPC: %s: setting port for xprt %p (%s:%s) to %u\n",
454 __func__, xprt,
455 xprt->address_strings[RPC_DISPLAY_ADDR],
456 xprt->address_strings[RPC_DISPLAY_PORT],
457 port);
458
459 rpc_set_port(sap, port);444 rpc_set_port(sap, port);
460 445
461 kfree(xprt->address_strings[RPC_DISPLAY_PORT]);446 kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
@@ -465,6 +450,9 @@ xprt_rdma_set_port(struct rpc_xprt *xprt, u16 port) · 3 unmodified lines
465 kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);450 kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);
466 snprintf(buf, sizeof(buf), "%4hx", port);451 snprintf(buf, sizeof(buf), "%4hx", port);
467 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);452 xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
453
454 trace_xprtrdma_op_setport(container_of(xprt, struct rpcrdma_xprt,
455 rx_xprt));
468}456}
469 457
470/**458/**
@@ -536,13 +524,12 @@ xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task) · 65 unmodified lines
536 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);524 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
537 unsigned long delay;525 unsigned long delay;
538 526
539 trace_xprtrdma_op_connect(r_xprt);
540
541 delay = 0;527 delay = 0;
542 if (r_xprt->rx_ep.rep_connected != 0) {528 if (r_xprt->rx_ep.rep_connected != 0) {
543 delay = xprt_reconnect_delay(xprt);529 delay = xprt_reconnect_delay(xprt);
544 xprt_reconnect_backoff(xprt, RPCRDMA_INIT_REEST_TO);530 xprt_reconnect_backoff(xprt, RPCRDMA_INIT_REEST_TO);
545 }531 }
532 trace_xprtrdma_op_connect(r_xprt, delay);
546 queue_delayed_work(xprtiod_workqueue, &r_xprt->rx_connect_worker,533 queue_delayed_work(xprtiod_workqueue, &r_xprt->rx_connect_worker,
547 delay);534 delay);
548}535}
net/sunrpc/xprtrdma/verbs.c+110−84
@@ -74,17 +74,17 @@ · 73 unmodified lines
74/*74/*
75 * internal functions75 * internal functions
76 */76 */
77static void rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc);77static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
78 struct rpcrdma_sendctx *sc);
79static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
78static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);80static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);
79static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);81static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
80static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf);82static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
81static void rpcrdma_mr_free(struct rpcrdma_mr *mr);
82static struct rpcrdma_regbuf *83static struct rpcrdma_regbuf *
83rpcrdma_regbuf_alloc(size_t size, enum dma_data_direction direction,84rpcrdma_regbuf_alloc(size_t size, enum dma_data_direction direction,
84 gfp_t flags);85 gfp_t flags);
85static void rpcrdma_regbuf_dma_unmap(struct rpcrdma_regbuf *rb);86static void rpcrdma_regbuf_dma_unmap(struct rpcrdma_regbuf *rb);
86static void rpcrdma_regbuf_free(struct rpcrdma_regbuf *rb);87static void rpcrdma_regbuf_free(struct rpcrdma_regbuf *rb);
87static void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
88 88
89/* Wait for outstanding transport work to finish. ib_drain_qp89/* Wait for outstanding transport work to finish. ib_drain_qp
90 * handles the drains in the wrong order for us, so open code90 * handles the drains in the wrong order for us, so open code
@@ -125,7 +125,7 @@ rpcrdma_qp_event_handler(struct ib_event *event, void *context) · 34 unmodified lines
125 125
126/**126/**
127 * rpcrdma_wc_send - Invoked by RDMA provider for each polled Send WC127 * rpcrdma_wc_send - Invoked by RDMA provider for each polled Send WC
128 * @cq: completion queue (ignored)128 * @cq: completion queue
129 * @wc: completed WR129 * @wc: completed WR
130 *130 *
131 */131 */
@@ -138,7 +138,7 @@ rpcrdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) · 6 unmodified lines
138 138
139 /* WARNING: Only wr_cqe and status are reliable at this point */139 /* WARNING: Only wr_cqe and status are reliable at this point */
140 trace_xprtrdma_wc_send(sc, wc);140 trace_xprtrdma_wc_send(sc, wc);
141 rpcrdma_sendctx_put_locked(sc);141 rpcrdma_sendctx_put_locked((struct rpcrdma_xprt *)cq->cq_context, sc);
142}142}
143 143
144/**144/**
@@ -170,7 +170,6 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc) · 25 unmodified lines
170 rdmab_addr(rep->rr_rdmabuf),170 rdmab_addr(rep->rr_rdmabuf),
171 wc->byte_len, DMA_FROM_DEVICE);171 wc->byte_len, DMA_FROM_DEVICE);
172 172
173 rpcrdma_post_recvs(r_xprt, false);
174 rpcrdma_reply_handler(rep);173 rpcrdma_reply_handler(rep);
175 return;174 return;
176 175
@@ -178,11 +177,11 @@ out_flushed: · 1 unmodified line
178 rpcrdma_recv_buffer_put(rep);177 rpcrdma_recv_buffer_put(rep);
179}178}
180 179
181static void180static void rpcrdma_update_cm_private(struct rpcrdma_xprt *r_xprt,
182rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,181 struct rdma_conn_param *param)
183 struct rdma_conn_param *param)
184{182{
185 const struct rpcrdma_connect_private *pmsg = param->private_data;183 const struct rpcrdma_connect_private *pmsg = param->private_data;
184 struct rpcrdma_ep *ep = &r_xprt->rx_ep;
186 unsigned int rsize, wsize;185 unsigned int rsize, wsize;
187 186
188 /* Default settings for RPC-over-RDMA Version One */187 /* Default settings for RPC-over-RDMA Version One */
@@ -198,13 +197,11 @@ rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt, · 9 unmodified lines
198 wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);197 wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);
199 }198 }
200 199
201 if (rsize < r_xprt->rx_ep.rep_inline_recv)200 if (rsize < ep->rep_inline_recv)
202 r_xprt->rx_ep.rep_inline_recv = rsize;201 ep->rep_inline_recv = rsize;
203 if (wsize < r_xprt->rx_ep.rep_inline_send)202 if (wsize < ep->rep_inline_send)
204 r_xprt->rx_ep.rep_inline_send = wsize;203 ep->rep_inline_send = wsize;
205 dprintk("RPC: %s: max send %u, max recv %u\n", __func__,204
206 r_xprt->rx_ep.rep_inline_send,
207 r_xprt->rx_ep.rep_inline_recv);
208 rpcrdma_set_max_header_sizes(r_xprt);205 rpcrdma_set_max_header_sizes(r_xprt);
209}206}
210 207
@@ -258,7 +255,8 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) · 47 unmodified lines
258 case RDMA_CM_EVENT_ESTABLISHED:255 case RDMA_CM_EVENT_ESTABLISHED:
259 ++xprt->connect_cookie;256 ++xprt->connect_cookie;
260 ep->rep_connected = 1;257 ep->rep_connected = 1;
261 rpcrdma_update_connect_private(r_xprt, &event->param.conn);258 rpcrdma_update_cm_private(r_xprt, &event->param.conn);
259 trace_xprtrdma_inline_thresh(r_xprt);
262 wake_up_all(&ep->rep_connect_wait);260 wake_up_all(&ep->rep_connect_wait);
263 break;261 break;
264 case RDMA_CM_EVENT_CONNECT_ERROR:262 case RDMA_CM_EVENT_CONNECT_ERROR:
@@ -298,8 +296,6 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia) · 33 unmodified lines
298 struct rdma_cm_id *id;296 struct rdma_cm_id *id;
299 int rc;297 int rc;
300 298
301 trace_xprtrdma_conn_start(xprt);
302
303 init_completion(&ia->ri_done);299 init_completion(&ia->ri_done);
304 init_completion(&ia->ri_remove_done);300 init_completion(&ia->ri_remove_done);
305 301
@@ -315,10 +311,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia) · 9 unmodified lines
315 if (rc)311 if (rc)
316 goto out;312 goto out;
317 rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);313 rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
318 if (rc < 0) {314 if (rc < 0)
319 trace_xprtrdma_conn_tout(xprt);
320 goto out;315 goto out;
321 }
322 316
323 rc = ia->ri_async_rc;317 rc = ia->ri_async_rc;
324 if (rc)318 if (rc)
@@ -329,10 +323,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia) · 4 unmodified lines
329 if (rc)323 if (rc)
330 goto out;324 goto out;
331 rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);325 rc = wait_for_completion_interruptible_timeout(&ia->ri_done, wtimeout);
332 if (rc < 0) {326 if (rc < 0)
333 trace_xprtrdma_conn_tout(xprt);
334 goto out;327 goto out;
335 }
336 rc = ia->ri_async_rc;328 rc = ia->ri_async_rc;
337 if (rc)329 if (rc)
338 goto out;330 goto out;
@@ -409,8 +401,6 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia) · 70 unmodified lines
409 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;401 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
410 struct rpcrdma_req *req;402 struct rpcrdma_req *req;
411 403
412 cancel_work_sync(&buf->rb_refresh_worker);
413
414 /* This is similar to rpcrdma_ep_destroy, but:404 /* This is similar to rpcrdma_ep_destroy, but:
415 * - Don't cancel the connect worker.405 * - Don't cancel the connect worker.
416 * - Don't call rpcrdma_ep_disconnect, which waits406 * - Don't call rpcrdma_ep_disconnect, which waits
@@ -437,7 +427,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia) · 20 unmodified lines
437 rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);427 rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
438 rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);428 rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);
439 }429 }
440 rpcrdma_mrs_destroy(buf);430 rpcrdma_mrs_destroy(r_xprt);
441 ib_dealloc_pd(ia->ri_pd);431 ib_dealloc_pd(ia->ri_pd);
442 ia->ri_pd = NULL;432 ia->ri_pd = NULL;
443 433
@@ -522,7 +512,7 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) · 78 unmodified lines
522 init_waitqueue_head(&ep->rep_connect_wait);512 init_waitqueue_head(&ep->rep_connect_wait);
523 ep->rep_receive_count = 0;513 ep->rep_receive_count = 0;
524 514
525 sendcq = ib_alloc_cq_any(ia->ri_id->device, NULL,515 sendcq = ib_alloc_cq_any(ia->ri_id->device, r_xprt,
526 ep->rep_attr.cap.max_send_wr + 1,516 ep->rep_attr.cap.max_send_wr + 1,
527 IB_POLL_WORKQUEUE);517 IB_POLL_WORKQUEUE);
528 if (IS_ERR(sendcq)) {518 if (IS_ERR(sendcq)) {
@@ -630,8 +620,6 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt, · 101 unmodified lines
630 pr_err("rpcrdma: rdma_create_qp returned %d\n", err);620 pr_err("rpcrdma: rdma_create_qp returned %d\n", err);
631 goto out3;621 goto out3;
632 }622 }
633
634 rpcrdma_mrs_create(r_xprt);
635 return 0;623 return 0;
636 624
637out3:625out3:
@@ -649,8 +637,6 @@ static int rpcrdma_ep_reconnect(struct rpcrdma_xprt *r_xprt, · 11 unmodified lines
649 struct rdma_cm_id *id, *old;637 struct rdma_cm_id *id, *old;
650 int err, rc;638 int err, rc;
651 639
652 trace_xprtrdma_reconnect(r_xprt);
653
654 rpcrdma_ep_disconnect(&r_xprt->rx_ep, ia);640 rpcrdma_ep_disconnect(&r_xprt->rx_ep, ia);
655 641
656 rc = -EHOSTUNREACH;642 rc = -EHOSTUNREACH;
@@ -705,7 +691,6 @@ retry: · 48 unmodified lines
705 memcpy(&qp_init_attr, &ep->rep_attr, sizeof(qp_init_attr));691 memcpy(&qp_init_attr, &ep->rep_attr, sizeof(qp_init_attr));
706 switch (ep->rep_connected) {692 switch (ep->rep_connected) {
707 case 0:693 case 0:
708 dprintk("RPC: %s: connecting...\n", __func__);
709 rc = rdma_create_qp(ia->ri_id, ia->ri_pd, &qp_init_attr);694 rc = rdma_create_qp(ia->ri_id, ia->ri_pd, &qp_init_attr);
710 if (rc) {695 if (rc) {
711 rc = -ENETUNREACH;696 rc = -ENETUNREACH;
@@ -726,6 +711,7 @@ retry: · 14 unmodified lines
726 ep->rep_connected = 0;711 ep->rep_connected = 0;
727 xprt_clear_connected(xprt);712 xprt_clear_connected(xprt);
728 713
714 rpcrdma_reset_cwnd(r_xprt);
729 rpcrdma_post_recvs(r_xprt, true);715 rpcrdma_post_recvs(r_xprt, true);
730 716
731 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);717 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
@@ -742,13 +728,14 @@ retry: · 10 unmodified lines
742 goto out;728 goto out;
743 }729 }
744 730
745 dprintk("RPC: %s: connected\n", __func__);731 rpcrdma_mrs_create(r_xprt);
746 732
747out:733out:
748 if (rc)734 if (rc)
749 ep->rep_connected = rc;735 ep->rep_connected = rc;
750 736
751out_noupdate:737out_noupdate:
738 trace_xprtrdma_connect(r_xprt, rc);
752 return rc;739 return rc;
753}740}
754 741
@@ -757,11 +744,8 @@ out_noupdate: · 2 unmodified lines
757 * @ep: endpoint to disconnect744 * @ep: endpoint to disconnect
758 * @ia: associated interface adapter745 * @ia: associated interface adapter
759 *746 *
760 * This is separate from destroy to facilitate the ability747 * Caller serializes. Either the transport send lock is held,
761 * to reconnect without recreating the endpoint.748 * or we're being called to destroy the transport.
762 *
763 * This call is not reentrant, and must not be made in parallel
764 * on the same endpoint.
765 */749 */
766void750void
767rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)751rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
@@ -780,6 +764,8 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia) · 12 unmodified lines
780 trace_xprtrdma_disconnect(r_xprt, rc);764 trace_xprtrdma_disconnect(r_xprt, rc);
781 765
782 rpcrdma_xprt_drain(r_xprt);766 rpcrdma_xprt_drain(r_xprt);
767 rpcrdma_reqs_reset(r_xprt);
768 rpcrdma_mrs_destroy(r_xprt);
783}769}
784 770
785/* Fixed-size circular FIFO queue. This implementation is wait-free and771/* Fixed-size circular FIFO queue. This implementation is wait-free and
@@ -817,9 +803,6 @@ static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ia *ia) · 31 unmodified lines
817 if (!sc)803 if (!sc)
818 return NULL;804 return NULL;
819 805
820 sc->sc_wr.wr_cqe = &sc->sc_cqe;
821 sc->sc_wr.sg_list = sc->sc_sges;
822 sc->sc_wr.opcode = IB_WR_SEND;
823 sc->sc_cqe.done = rpcrdma_wc_send;806 sc->sc_cqe.done = rpcrdma_wc_send;
824 return sc;807 return sc;
825}808}
@@ -847,7 +830,6 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt) · 21 unmodified lines
847 if (!sc)830 if (!sc)
848 return -ENOMEM;831 return -ENOMEM;
849 832
850 sc->sc_xprt = r_xprt;
851 buf->rb_sc_ctxs[i] = sc;833 buf->rb_sc_ctxs[i] = sc;
852 }834 }
853 835
@@ -910,6 +892,7 @@ out_emptyq: · 56 unmodified lines
910 892
911/**893/**
912 * rpcrdma_sendctx_put_locked - Release a send context894 * rpcrdma_sendctx_put_locked - Release a send context
895 * @r_xprt: controlling transport instance
913 * @sc: send context to release896 * @sc: send context to release
914 *897 *
915 * Usage: Called from Send completion to return a sendctxt898 * Usage: Called from Send completion to return a sendctxt
@@ -917,10 +900,10 @@ out_emptyq: · 1 unmodified line
917 *900 *
918 * The caller serializes calls to this function (per transport).901 * The caller serializes calls to this function (per transport).
919 */902 */
920static void903static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
921rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc)904 struct rpcrdma_sendctx *sc)
922{905{
923 struct rpcrdma_buffer *buf = &sc->sc_xprt->rx_buf;906 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
924 unsigned long next_tail;907 unsigned long next_tail;
925 908
926 /* Unmap SGEs of previously completed but unsignaled909 /* Unmap SGEs of previously completed but unsignaled
@@ -938,7 +921,7 @@ rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc) · 11 unmodified lines
938 /* Paired with READ_ONCE */921 /* Paired with READ_ONCE */
939 smp_store_release(&buf->rb_sc_tail, next_tail);922 smp_store_release(&buf->rb_sc_tail, next_tail);
940 923
941 xprt_write_space(&sc->sc_xprt->rx_xprt);924 xprt_write_space(&r_xprt->rx_xprt);
942}925}
943 926
944static void927static void
@@ -965,7 +948,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt) · 20 unmodified lines
965 mr->mr_xprt = r_xprt;948 mr->mr_xprt = r_xprt;
966 949
967 spin_lock(&buf->rb_lock);950 spin_lock(&buf->rb_lock);
968 list_add(&mr->mr_list, &buf->rb_mrs);951 rpcrdma_mr_push(mr, &buf->rb_mrs);
969 list_add(&mr->mr_all, &buf->rb_all_mrs);952 list_add(&mr->mr_all, &buf->rb_all_mrs);
970 spin_unlock(&buf->rb_lock);953 spin_unlock(&buf->rb_lock);
971 }954 }
@@ -986,6 +969,28 @@ rpcrdma_mr_refresh_worker(struct work_struct *work) · 14 unmodified lines
986 xprt_write_space(&r_xprt->rx_xprt);969 xprt_write_space(&r_xprt->rx_xprt);
987}970}
988 971
972/**
973 * rpcrdma_mrs_refresh - Wake the MR refresh worker
974 * @r_xprt: controlling transport instance
975 *
976 */
977void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt)
978{
979 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
980 struct rpcrdma_ep *ep = &r_xprt->rx_ep;
981
982 /* If there is no underlying device, it's no use to
983 * wake the refresh worker.
984 */
985 if (ep->rep_connected != -ENODEV) {
986 /* The work is scheduled on a WQ_MEM_RECLAIM
987 * workqueue in order to prevent MR allocation
988 * from recursing into NFS during direct reclaim.
989 */
990 queue_work(xprtiod_workqueue, &buf->rb_refresh_worker);
991 }
992}
993
989/**994/**
990 * rpcrdma_req_create - Allocate an rpcrdma_req object995 * rpcrdma_req_create - Allocate an rpcrdma_req object
991 * @r_xprt: controlling r_xprt996 * @r_xprt: controlling r_xprt
@@ -1042,6 +1047,26 @@ out1: · 50 unmodified lines
1042 return NULL;1047 return NULL;
1043}1048}
1044 1049
1050/**
1051 * rpcrdma_reqs_reset - Reset all reqs owned by a transport
1052 * @r_xprt: controlling transport instance
1053 *
1054 * ASSUMPTION: the rb_allreqs list is stable for the duration,
1055 * and thus can be walked without holding rb_lock. Eg. the
1056 * caller is holding the transport send lock to exclude
1057 * device removal or disconnection.
1058 */
1059static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt)
1060{
1061 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1062 struct rpcrdma_req *req;
1063
1064 list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
1065 /* Credits are valid only for one connection */
1066 req->rl_slot.rq_cong = 0;
1067 }
1068}
1069
1045static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,1070static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
1046 bool temp)1071 bool temp)
1047{1072{
@@ -1125,8 +1150,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) · 77 unmodified lines
1125 INIT_LIST_HEAD(&buf->rb_all_mrs);1150 INIT_LIST_HEAD(&buf->rb_all_mrs);
1126 INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);1151 INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);
1127 1152
1128 rpcrdma_mrs_create(r_xprt);
1129
1130 INIT_LIST_HEAD(&buf->rb_send_bufs);1153 INIT_LIST_HEAD(&buf->rb_send_bufs);
1131 INIT_LIST_HEAD(&buf->rb_allreqs);1154 INIT_LIST_HEAD(&buf->rb_allreqs);
1132 1155
@@ -1134,14 +1157,13 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) · 1 unmodified line
1134 for (i = 0; i < buf->rb_max_requests; i++) {1157 for (i = 0; i < buf->rb_max_requests; i++) {
1135 struct rpcrdma_req *req;1158 struct rpcrdma_req *req;
1136 1159
1137 req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE,1160 req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE * 2,
1138 GFP_KERNEL);1161 GFP_KERNEL);
1139 if (!req)1162 if (!req)
1140 goto out;1163 goto out;
1141 list_add(&req->rl_list, &buf->rb_send_bufs);1164 list_add(&req->rl_list, &buf->rb_send_bufs);
1142 }1165 }
1143 1166
1144 buf->rb_credits = 1;
1145 init_llist_head(&buf->rb_free_reps);1167 init_llist_head(&buf->rb_free_reps);
1146 1168
1147 rc = rpcrdma_sendctxs_create(r_xprt);1169 rc = rpcrdma_sendctxs_create(r_xprt);
@@ -1158,15 +1180,24 @@ out: · 10 unmodified lines
1158 * rpcrdma_req_destroy - Destroy an rpcrdma_req object1180 * rpcrdma_req_destroy - Destroy an rpcrdma_req object
1159 * @req: unused object to be destroyed1181 * @req: unused object to be destroyed
1160 *1182 *
1161 * This function assumes that the caller prevents concurrent device1183 * Relies on caller holding the transport send lock to protect
1162 * unload and transport tear-down.1184 * removing req->rl_all from buf->rb_all_reqs safely.
1163 */1185 */
1164void rpcrdma_req_destroy(struct rpcrdma_req *req)1186void rpcrdma_req_destroy(struct rpcrdma_req *req)
1165{1187{
1188 struct rpcrdma_mr *mr;
1189
1166 list_del(&req->rl_all);1190 list_del(&req->rl_all);
1167 1191
1168 while (!list_empty(&req->rl_free_mrs))1192 while ((mr = rpcrdma_mr_pop(&req->rl_free_mrs))) {
1169 rpcrdma_mr_free(rpcrdma_mr_pop(&req->rl_free_mrs));1193 struct rpcrdma_buffer *buf = &mr->mr_xprt->rx_buf;
1194
1195 spin_lock(&buf->rb_lock);
1196 list_del(&mr->mr_all);
1197 spin_unlock(&buf->rb_lock);
1198
1199 frwr_release_mr(mr);
1200 }
1170 1201
1171 rpcrdma_regbuf_free(req->rl_recvbuf);1202 rpcrdma_regbuf_free(req->rl_recvbuf);
1172 rpcrdma_regbuf_free(req->rl_sendbuf);1203 rpcrdma_regbuf_free(req->rl_sendbuf);
@@ -1174,28 +1205,33 @@ void rpcrdma_req_destroy(struct rpcrdma_req *req) · 1 unmodified line
1174 kfree(req);1205 kfree(req);
1175}1206}
1176 1207
1177static void1208/**
1178rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)1209 * rpcrdma_mrs_destroy - Release all of a transport's MRs
1210 * @r_xprt: controlling transport instance
1211 *
1212 * Relies on caller holding the transport send lock to protect
1213 * removing mr->mr_list from req->rl_free_mrs safely.
1214 */
1215static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt)
1179{1216{
1180 struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,1217 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1181 rx_buf);
1182 struct rpcrdma_mr *mr;1218 struct rpcrdma_mr *mr;
1183 unsigned int count;
1184 1219
1185 count = 0;1220 cancel_work_sync(&buf->rb_refresh_worker);
1221
1186 spin_lock(&buf->rb_lock);1222 spin_lock(&buf->rb_lock);
1187 while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,1223 while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,
1188 struct rpcrdma_mr,1224 struct rpcrdma_mr,
1189 mr_all)) != NULL) {1225 mr_all)) != NULL) {
1226 list_del(&mr->mr_list);
1190 list_del(&mr->mr_all);1227 list_del(&mr->mr_all);
1191 spin_unlock(&buf->rb_lock);1228 spin_unlock(&buf->rb_lock);
1192 1229
1193 frwr_release_mr(mr);1230 frwr_release_mr(mr);
1194 count++;1231
1195 spin_lock(&buf->rb_lock);1232 spin_lock(&buf->rb_lock);
1196 }1233 }
1197 spin_unlock(&buf->rb_lock);1234 spin_unlock(&buf->rb_lock);
1198 r_xprt->rx_stats.mrs_allocated = 0;
1199}1235}
1200 1236
1201/**1237/**
@@ -1209,8 +1245,6 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf) · 7 unmodified lines
1209void1245void
1210rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)1246rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1211{1247{
1212 cancel_work_sync(&buf->rb_refresh_worker);
1213
1214 rpcrdma_sendctxs_destroy(buf);1248 rpcrdma_sendctxs_destroy(buf);
1215 rpcrdma_reps_destroy(buf);1249 rpcrdma_reps_destroy(buf);
1216 1250
@@ -1222,8 +1256,6 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) · 5 unmodified lines
1222 list_del(&req->rl_list);1256 list_del(&req->rl_list);
1223 rpcrdma_req_destroy(req);1257 rpcrdma_req_destroy(req);
1224 }1258 }
1225
1226 rpcrdma_mrs_destroy(buf);
1227}1259}
1228 1260
1229/**1261/**
@@ -1264,17 +1296,6 @@ void rpcrdma_mr_put(struct rpcrdma_mr *mr) · 34 unmodified lines
1264 rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs);1296 rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs);
1265}1297}
1266 1298
1267static void rpcrdma_mr_free(struct rpcrdma_mr *mr)
1268{
1269 struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
1270 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1271
1272 mr->mr_req = NULL;
1273 spin_lock(&buf->rb_lock);
1274 rpcrdma_mr_push(mr, &buf->rb_mrs);
1275 spin_unlock(&buf->rb_lock);
1276}
1277
1278/**1299/**
1279 * rpcrdma_buffer_get - Get a request buffer1300 * rpcrdma_buffer_get - Get a request buffer
1280 * @buffers: Buffer pool from which to obtain a buffer1301 * @buffers: Buffer pool from which to obtain a buffer
@@ -1437,7 +1458,7 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia, · 156 unmodified lines
1437 struct rpcrdma_ep *ep,1458 struct rpcrdma_ep *ep,
1438 struct rpcrdma_req *req)1459 struct rpcrdma_req *req)
1439{1460{
1440 struct ib_send_wr *send_wr = &req->rl_sendctx->sc_wr;1461 struct ib_send_wr *send_wr = &req->rl_wr;
1441 int rc;1462 int rc;
1442 1463
1443 if (!ep->rep_send_count || kref_read(&req->rl_kref) > 1) {1464 if (!ep->rep_send_count || kref_read(&req->rl_kref) > 1) {
@@ -1455,8 +1476,13 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia, · 11 unmodified lines
1455 return 0;1476 return 0;
1456}1477}
1457 1478
1458static void1479/**
1459rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)1480 * rpcrdma_post_recvs - Refill the Receive Queue
1481 * @r_xprt: controlling transport instance
1482 * @temp: mark Receive buffers to be deleted after use
1483 *
1484 */
1485void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
1460{1486{
1461 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;1487 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1462 struct rpcrdma_ep *ep = &r_xprt->rx_ep;1488 struct rpcrdma_ep *ep = &r_xprt->rx_ep;
net/sunrpc/xprtrdma/xprt_rdma.h+6−12
@@ -218,12 +218,8 @@ enum { · 217 unmodified lines
218/* struct rpcrdma_sendctx - DMA mapped SGEs to unmap after Send completes218/* struct rpcrdma_sendctx - DMA mapped SGEs to unmap after Send completes
219 */219 */
220struct rpcrdma_req;220struct rpcrdma_req;
221struct rpcrdma_xprt;
222struct rpcrdma_sendctx {221struct rpcrdma_sendctx {
223 struct ib_send_wr sc_wr;
224 struct ib_cqe sc_cqe;222 struct ib_cqe sc_cqe;
225 struct ib_device *sc_device;
226 struct rpcrdma_xprt *sc_xprt;
227 struct rpcrdma_req *sc_req;223 struct rpcrdma_req *sc_req;
228 unsigned int sc_unmap_count;224 unsigned int sc_unmap_count;
229 struct ib_sge sc_sges[];225 struct ib_sge sc_sges[];
@@ -257,7 +253,6 @@ struct rpcrdma_mr { · 27 unmodified lines
257 u32 mr_handle;253 u32 mr_handle;
258 u32 mr_length;254 u32 mr_length;
259 u64 mr_offset;255 u64 mr_offset;
260 struct work_struct mr_recycle;
261 struct list_head mr_all;256 struct list_head mr_all;
262};257};
263 258
@@ -318,6 +313,7 @@ struct rpcrdma_req { · 54 unmodified lines
318 struct rpcrdma_rep *rl_reply;313 struct rpcrdma_rep *rl_reply;
319 struct xdr_stream rl_stream;314 struct xdr_stream rl_stream;
320 struct xdr_buf rl_hdrbuf;315 struct xdr_buf rl_hdrbuf;
316 struct ib_send_wr rl_wr;
321 struct rpcrdma_sendctx *rl_sendctx;317 struct rpcrdma_sendctx *rl_sendctx;
322 struct rpcrdma_regbuf *rl_rdmabuf; /* xprt header */318 struct rpcrdma_regbuf *rl_rdmabuf; /* xprt header */
323 struct rpcrdma_regbuf *rl_sendbuf; /* rq_snd_buf */319 struct rpcrdma_regbuf *rl_sendbuf; /* rq_snd_buf */
@@ -474,6 +470,7 @@ void rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *); · 150 unmodified lines
474 470
475int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,471int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,
476 struct rpcrdma_req *);472 struct rpcrdma_req *);
473void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
477 474
478/*475/*
479 * Buffer calls - xprtrdma/verbs.c476 * Buffer calls - xprtrdma/verbs.c
@@ -487,12 +484,7 @@ struct rpcrdma_sendctx *rpcrdma_sendctx_get_locked(struct rpcrdma_xprt *r_xprt); · 7 unmodified lines
487 484
488struct rpcrdma_mr *rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt);485struct rpcrdma_mr *rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt);
489void rpcrdma_mr_put(struct rpcrdma_mr *mr);486void rpcrdma_mr_put(struct rpcrdma_mr *mr);
490 487void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt);
491static inline void
492rpcrdma_mr_recycle(struct rpcrdma_mr *mr)
493{
494 schedule_work(&mr->mr_recycle);
495}
496 488
497struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);489struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);
498void rpcrdma_buffer_put(struct rpcrdma_buffer *buffers,490void rpcrdma_buffer_put(struct rpcrdma_buffer *buffers,
@@ -542,7 +534,6 @@ rpcrdma_data_dir(bool writing) · 43 unmodified lines
542/* Memory registration calls xprtrdma/frwr_ops.c534/* Memory registration calls xprtrdma/frwr_ops.c
543 */535 */
544bool frwr_is_supported(struct ib_device *device);536bool frwr_is_supported(struct ib_device *device);
545void frwr_recycle(struct rpcrdma_req *req);
546void frwr_reset(struct rpcrdma_req *req);537void frwr_reset(struct rpcrdma_req *req);
547int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);538int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);
548int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);539int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
@@ -563,6 +554,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req); · 14 unmodified lines
563 554
564enum rpcrdma_chunktype {555enum rpcrdma_chunktype {
565 rpcrdma_noch = 0,556 rpcrdma_noch = 0,
557 rpcrdma_noch_pullup,
558 rpcrdma_noch_mapped,
566 rpcrdma_readch,559 rpcrdma_readch,
567 rpcrdma_areadch,560 rpcrdma_areadch,
568 rpcrdma_writech,561 rpcrdma_writech,
@@ -576,6 +569,7 @@ int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt, · 7 unmodified lines
576void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc);569void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc);
577int rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst);570int rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst);
578void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *);571void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *);
572void rpcrdma_reset_cwnd(struct rpcrdma_xprt *r_xprt);
579void rpcrdma_complete_rqst(struct rpcrdma_rep *rep);573void rpcrdma_complete_rqst(struct rpcrdma_rep *rep);
580void rpcrdma_reply_handler(struct rpcrdma_rep *rep);574void rpcrdma_reply_handler(struct rpcrdma_rep *rep);
581 575
net/sunrpc/xprtsock.c+1−1
@@ -1752,7 +1752,7 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) · 1751 unmodified lines
1752 1752
1753static void xs_set_srcport(struct sock_xprt *transport, struct socket *sock)1753static void xs_set_srcport(struct sock_xprt *transport, struct socket *sock)
1754{1754{
1755 if (transport->srcport == 0)1755 if (transport->srcport == 0 && transport->xprt.reuseport)
1756 transport->srcport = xs_sock_getport(sock);1756 transport->srcport = xs_sock_getport(sock);
1757}1757}
1758 1758

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t