diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 415 |
1 files changed, 2 insertions, 413 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d75e2a2576eb..a0c35ab12a6b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/mount.h> | 52 | #include <linux/mount.h> |
53 | #include <linux/module.h> | 53 | #include <linux/module.h> |
54 | #include <linux/nfs_idmap.h> | 54 | #include <linux/nfs_idmap.h> |
55 | #include <linux/sunrpc/bc_xprt.h> | ||
56 | #include <linux/xattr.h> | 55 | #include <linux/xattr.h> |
57 | #include <linux/utsname.h> | 56 | #include <linux/utsname.h> |
58 | #include <linux/freezer.h> | 57 | #include <linux/freezer.h> |
@@ -64,6 +63,8 @@ | |||
64 | #include "callback.h" | 63 | #include "callback.h" |
65 | #include "pnfs.h" | 64 | #include "pnfs.h" |
66 | #include "netns.h" | 65 | #include "netns.h" |
66 | #include "nfs4session.h" | ||
67 | |||
67 | 68 | ||
68 | #define NFSDBG_FACILITY NFSDBG_PROC | 69 | #define NFSDBG_FACILITY NFSDBG_PROC |
69 | 70 | ||
@@ -378,64 +379,6 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp | |||
378 | 379 | ||
379 | #if defined(CONFIG_NFS_V4_1) | 380 | #if defined(CONFIG_NFS_V4_1) |
380 | 381 | ||
381 | /* | ||
382 | * nfs4_shrink_slot_table - free retired slots from the slot table | ||
383 | */ | ||
384 | static void nfs4_shrink_slot_table(struct nfs4_slot_table *tbl, u32 newsize) | ||
385 | { | ||
386 | struct nfs4_slot **p; | ||
387 | if (newsize >= tbl->max_slots) | ||
388 | return; | ||
389 | |||
390 | p = &tbl->slots; | ||
391 | while (newsize--) | ||
392 | p = &(*p)->next; | ||
393 | while (*p) { | ||
394 | struct nfs4_slot *slot = *p; | ||
395 | |||
396 | *p = slot->next; | ||
397 | kfree(slot); | ||
398 | tbl->max_slots--; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * nfs4_free_slot - free a slot and efficiently update slot table. | ||
404 | * | ||
405 | * freeing a slot is trivially done by clearing its respective bit | ||
406 | * in the bitmap. | ||
407 | * If the freed slotid equals highest_used_slotid we want to update it | ||
408 | * so that the server would be able to size down the slot table if needed, | ||
409 | * otherwise we know that the highest_used_slotid is still in use. | ||
410 | * When updating highest_used_slotid there may be "holes" in the bitmap | ||
411 | * so we need to scan down from highest_used_slotid to 0 looking for the now | ||
412 | * highest slotid in use. | ||
413 | * If none found, highest_used_slotid is set to NFS4_NO_SLOT. | ||
414 | * | ||
415 | * Must be called while holding tbl->slot_tbl_lock | ||
416 | */ | ||
417 | static void | ||
418 | nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) | ||
419 | { | ||
420 | u32 slotid = slot->slot_nr; | ||
421 | |||
422 | /* clear used bit in bitmap */ | ||
423 | __clear_bit(slotid, tbl->used_slots); | ||
424 | |||
425 | /* update highest_used_slotid when it is freed */ | ||
426 | if (slotid == tbl->highest_used_slotid) { | ||
427 | u32 new_max = find_last_bit(tbl->used_slots, slotid); | ||
428 | if (new_max < slotid) | ||
429 | tbl->highest_used_slotid = new_max; | ||
430 | else { | ||
431 | tbl->highest_used_slotid = NFS4_NO_SLOT; | ||
432 | nfs4_session_drain_complete(tbl->session, tbl); | ||
433 | } | ||
434 | } | ||
435 | dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, | ||
436 | slotid, tbl->highest_used_slotid); | ||
437 | } | ||
438 | |||
439 | bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy) | 382 | bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy) |
440 | { | 383 | { |
441 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | 384 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); |
@@ -465,56 +408,6 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) | |||
465 | res->sr_slot = NULL; | 408 | res->sr_slot = NULL; |
466 | } | 409 | } |
467 | 410 | ||
468 | /* Update the client's idea of target_highest_slotid */ | ||
469 | static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, | ||
470 | u32 target_highest_slotid) | ||
471 | { | ||
472 | unsigned int max_slotid, i; | ||
473 | |||
474 | if (tbl->target_highest_slotid == target_highest_slotid) | ||
475 | return; | ||
476 | tbl->target_highest_slotid = target_highest_slotid; | ||
477 | tbl->generation++; | ||
478 | |||
479 | max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, tbl->target_highest_slotid); | ||
480 | for (i = tbl->max_slotid + 1; i <= max_slotid; i++) | ||
481 | rpc_wake_up_next(&tbl->slot_tbl_waitq); | ||
482 | tbl->max_slotid = max_slotid; | ||
483 | } | ||
484 | |||
485 | void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, | ||
486 | u32 target_highest_slotid) | ||
487 | { | ||
488 | spin_lock(&tbl->slot_tbl_lock); | ||
489 | nfs41_set_target_slotid_locked(tbl, target_highest_slotid); | ||
490 | spin_unlock(&tbl->slot_tbl_lock); | ||
491 | } | ||
492 | |||
493 | static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl, | ||
494 | u32 highest_slotid) | ||
495 | { | ||
496 | if (tbl->server_highest_slotid == highest_slotid) | ||
497 | return; | ||
498 | if (tbl->highest_used_slotid > highest_slotid) | ||
499 | return; | ||
500 | /* Deallocate slots */ | ||
501 | nfs4_shrink_slot_table(tbl, highest_slotid + 1); | ||
502 | tbl->server_highest_slotid = highest_slotid; | ||
503 | } | ||
504 | |||
505 | static void nfs41_update_target_slotid(struct nfs4_slot_table *tbl, | ||
506 | struct nfs4_slot *slot, | ||
507 | struct nfs4_sequence_res *res) | ||
508 | { | ||
509 | spin_lock(&tbl->slot_tbl_lock); | ||
510 | if (tbl->generation != slot->generation) | ||
511 | goto out; | ||
512 | nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid); | ||
513 | nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid); | ||
514 | out: | ||
515 | spin_unlock(&tbl->slot_tbl_lock); | ||
516 | } | ||
517 | |||
518 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 411 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) |
519 | { | 412 | { |
520 | struct nfs4_session *session; | 413 | struct nfs4_session *session; |
@@ -585,79 +478,6 @@ static int nfs4_sequence_done(struct rpc_task *task, | |||
585 | return nfs41_sequence_done(task, res); | 478 | return nfs41_sequence_done(task, res); |
586 | } | 479 | } |
587 | 480 | ||
588 | static struct nfs4_slot *nfs4_new_slot(struct nfs4_slot_table *tbl, | ||
589 | u32 slotid, u32 seq_init, gfp_t gfp_mask) | ||
590 | { | ||
591 | struct nfs4_slot *slot; | ||
592 | |||
593 | slot = kzalloc(sizeof(*slot), gfp_mask); | ||
594 | if (slot) { | ||
595 | slot->table = tbl; | ||
596 | slot->slot_nr = slotid; | ||
597 | slot->seq_nr = seq_init; | ||
598 | } | ||
599 | return slot; | ||
600 | } | ||
601 | |||
602 | static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, | ||
603 | u32 slotid, u32 seq_init, gfp_t gfp_mask) | ||
604 | { | ||
605 | struct nfs4_slot **p, *slot; | ||
606 | |||
607 | p = &tbl->slots; | ||
608 | for (;;) { | ||
609 | if (*p == NULL) { | ||
610 | *p = nfs4_new_slot(tbl, tbl->max_slots, | ||
611 | seq_init, gfp_mask); | ||
612 | if (*p == NULL) | ||
613 | break; | ||
614 | tbl->max_slots++; | ||
615 | } | ||
616 | slot = *p; | ||
617 | if (slot->slot_nr == slotid) | ||
618 | return slot; | ||
619 | p = &slot->next; | ||
620 | } | ||
621 | return ERR_PTR(-ENOMEM); | ||
622 | } | ||
623 | |||
624 | /* | ||
625 | * nfs4_alloc_slot - efficiently look for a free slot | ||
626 | * | ||
627 | * nfs4_alloc_slot looks for an unset bit in the used_slots bitmap. | ||
628 | * If found, we mark the slot as used, update the highest_used_slotid, | ||
629 | * and respectively set up the sequence operation args. | ||
630 | * | ||
631 | * Note: must be called with under the slot_tbl_lock. | ||
632 | */ | ||
633 | static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) | ||
634 | { | ||
635 | struct nfs4_slot *ret = ERR_PTR(-EBUSY); | ||
636 | u32 slotid; | ||
637 | |||
638 | dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n", | ||
639 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, | ||
640 | tbl->max_slotid + 1); | ||
641 | slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1); | ||
642 | if (slotid > tbl->max_slotid) | ||
643 | goto out; | ||
644 | ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); | ||
645 | if (IS_ERR(ret)) | ||
646 | goto out; | ||
647 | __set_bit(slotid, tbl->used_slots); | ||
648 | if (slotid > tbl->highest_used_slotid || | ||
649 | tbl->highest_used_slotid == NFS4_NO_SLOT) | ||
650 | tbl->highest_used_slotid = slotid; | ||
651 | ret->renewal_time = jiffies; | ||
652 | ret->generation = tbl->generation; | ||
653 | |||
654 | out: | ||
655 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", | ||
656 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, | ||
657 | !IS_ERR(ret) ? ret->slot_nr : -1); | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | static void nfs41_init_sequence(struct nfs4_sequence_args *args, | 481 | static void nfs41_init_sequence(struct nfs4_sequence_args *args, |
662 | struct nfs4_sequence_res *res, int cache_reply) | 482 | struct nfs4_sequence_res *res, int cache_reply) |
663 | { | 483 | { |
@@ -5716,143 +5536,6 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo) | |||
5716 | return status; | 5536 | return status; |
5717 | } | 5537 | } |
5718 | 5538 | ||
5719 | static int nfs4_grow_slot_table(struct nfs4_slot_table *tbl, | ||
5720 | u32 max_reqs, u32 ivalue) | ||
5721 | { | ||
5722 | if (max_reqs <= tbl->max_slots) | ||
5723 | return 0; | ||
5724 | if (!IS_ERR(nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS))) | ||
5725 | return 0; | ||
5726 | return -ENOMEM; | ||
5727 | } | ||
5728 | |||
5729 | static void nfs4_reset_slot_table(struct nfs4_slot_table *tbl, | ||
5730 | u32 server_highest_slotid, | ||
5731 | u32 ivalue) | ||
5732 | { | ||
5733 | struct nfs4_slot **p; | ||
5734 | |||
5735 | nfs4_shrink_slot_table(tbl, server_highest_slotid + 1); | ||
5736 | p = &tbl->slots; | ||
5737 | while (*p) { | ||
5738 | (*p)->seq_nr = ivalue; | ||
5739 | p = &(*p)->next; | ||
5740 | } | ||
5741 | tbl->highest_used_slotid = NFS4_NO_SLOT; | ||
5742 | tbl->target_highest_slotid = server_highest_slotid; | ||
5743 | tbl->server_highest_slotid = server_highest_slotid; | ||
5744 | tbl->max_slotid = server_highest_slotid; | ||
5745 | } | ||
5746 | |||
5747 | /* | ||
5748 | * (re)Initialise a slot table | ||
5749 | */ | ||
5750 | static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, | ||
5751 | u32 max_reqs, u32 ivalue) | ||
5752 | { | ||
5753 | int ret; | ||
5754 | |||
5755 | dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__, | ||
5756 | max_reqs, tbl->max_slots); | ||
5757 | |||
5758 | if (max_reqs > NFS4_MAX_SLOT_TABLE) | ||
5759 | max_reqs = NFS4_MAX_SLOT_TABLE; | ||
5760 | |||
5761 | ret = nfs4_grow_slot_table(tbl, max_reqs, ivalue); | ||
5762 | if (ret) | ||
5763 | goto out; | ||
5764 | |||
5765 | spin_lock(&tbl->slot_tbl_lock); | ||
5766 | nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue); | ||
5767 | spin_unlock(&tbl->slot_tbl_lock); | ||
5768 | |||
5769 | dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, | ||
5770 | tbl, tbl->slots, tbl->max_slots); | ||
5771 | out: | ||
5772 | dprintk("<-- %s: return %d\n", __func__, ret); | ||
5773 | return ret; | ||
5774 | } | ||
5775 | |||
5776 | /* Destroy the slot table */ | ||
5777 | static void nfs4_destroy_slot_tables(struct nfs4_session *session) | ||
5778 | { | ||
5779 | nfs4_shrink_slot_table(&session->fc_slot_table, 0); | ||
5780 | nfs4_shrink_slot_table(&session->bc_slot_table, 0); | ||
5781 | } | ||
5782 | |||
5783 | /* | ||
5784 | * Initialize or reset the forechannel and backchannel tables | ||
5785 | */ | ||
5786 | static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | ||
5787 | { | ||
5788 | struct nfs4_slot_table *tbl; | ||
5789 | int status; | ||
5790 | |||
5791 | dprintk("--> %s\n", __func__); | ||
5792 | /* Fore channel */ | ||
5793 | tbl = &ses->fc_slot_table; | ||
5794 | tbl->session = ses; | ||
5795 | status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); | ||
5796 | if (status) /* -ENOMEM */ | ||
5797 | return status; | ||
5798 | /* Back channel */ | ||
5799 | tbl = &ses->bc_slot_table; | ||
5800 | tbl->session = ses; | ||
5801 | status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); | ||
5802 | if (status && tbl->slots == NULL) | ||
5803 | /* Fore and back channel share a connection so get | ||
5804 | * both slot tables or neither */ | ||
5805 | nfs4_destroy_slot_tables(ses); | ||
5806 | return status; | ||
5807 | } | ||
5808 | |||
5809 | struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | ||
5810 | { | ||
5811 | struct nfs4_session *session; | ||
5812 | struct nfs4_slot_table *tbl; | ||
5813 | |||
5814 | session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); | ||
5815 | if (!session) | ||
5816 | return NULL; | ||
5817 | |||
5818 | tbl = &session->fc_slot_table; | ||
5819 | tbl->highest_used_slotid = NFS4_NO_SLOT; | ||
5820 | spin_lock_init(&tbl->slot_tbl_lock); | ||
5821 | rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); | ||
5822 | init_completion(&tbl->complete); | ||
5823 | |||
5824 | tbl = &session->bc_slot_table; | ||
5825 | tbl->highest_used_slotid = NFS4_NO_SLOT; | ||
5826 | spin_lock_init(&tbl->slot_tbl_lock); | ||
5827 | rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); | ||
5828 | init_completion(&tbl->complete); | ||
5829 | |||
5830 | session->session_state = 1<<NFS4_SESSION_INITING; | ||
5831 | |||
5832 | session->clp = clp; | ||
5833 | return session; | ||
5834 | } | ||
5835 | |||
5836 | void nfs4_destroy_session(struct nfs4_session *session) | ||
5837 | { | ||
5838 | struct rpc_xprt *xprt; | ||
5839 | struct rpc_cred *cred; | ||
5840 | |||
5841 | cred = nfs4_get_exchange_id_cred(session->clp); | ||
5842 | nfs4_proc_destroy_session(session, cred); | ||
5843 | if (cred) | ||
5844 | put_rpccred(cred); | ||
5845 | |||
5846 | rcu_read_lock(); | ||
5847 | xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt); | ||
5848 | rcu_read_unlock(); | ||
5849 | dprintk("%s Destroy backchannel for xprt %p\n", | ||
5850 | __func__, xprt); | ||
5851 | xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS); | ||
5852 | nfs4_destroy_slot_tables(session); | ||
5853 | kfree(session); | ||
5854 | } | ||
5855 | |||
5856 | /* | 5539 | /* |
5857 | * Initialize the values to be used by the client in CREATE_SESSION | 5540 | * Initialize the values to be used by the client in CREATE_SESSION |
5858 | * If nfs4_init_session set the fore channel request and response sizes, | 5541 | * If nfs4_init_session set the fore channel request and response sizes, |
@@ -6047,100 +5730,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session, | |||
6047 | } | 5730 | } |
6048 | 5731 | ||
6049 | /* | 5732 | /* |
6050 | * With sessions, the client is not marked ready until after a | ||
6051 | * successful EXCHANGE_ID and CREATE_SESSION. | ||
6052 | * | ||
6053 | * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate | ||
6054 | * other versions of NFS can be tried. | ||
6055 | */ | ||
6056 | static int nfs41_check_session_ready(struct nfs_client *clp) | ||
6057 | { | ||
6058 | int ret; | ||
6059 | |||
6060 | if (clp->cl_cons_state == NFS_CS_SESSION_INITING) { | ||
6061 | ret = nfs4_client_recover_expired_lease(clp); | ||
6062 | if (ret) | ||
6063 | return ret; | ||
6064 | } | ||
6065 | if (clp->cl_cons_state < NFS_CS_READY) | ||
6066 | return -EPROTONOSUPPORT; | ||
6067 | smp_rmb(); | ||
6068 | return 0; | ||
6069 | } | ||
6070 | |||
6071 | int nfs4_init_session(struct nfs_server *server) | ||
6072 | { | ||
6073 | struct nfs_client *clp = server->nfs_client; | ||
6074 | struct nfs4_session *session; | ||
6075 | unsigned int target_max_rqst_sz = NFS_MAX_FILE_IO_SIZE; | ||
6076 | unsigned int target_max_resp_sz = NFS_MAX_FILE_IO_SIZE; | ||
6077 | |||
6078 | if (!nfs4_has_session(clp)) | ||
6079 | return 0; | ||
6080 | |||
6081 | if (server->rsize != 0) | ||
6082 | target_max_resp_sz = server->rsize; | ||
6083 | target_max_resp_sz += nfs41_maxread_overhead; | ||
6084 | |||
6085 | if (server->wsize != 0) | ||
6086 | target_max_rqst_sz = server->wsize; | ||
6087 | target_max_rqst_sz += nfs41_maxwrite_overhead; | ||
6088 | |||
6089 | session = clp->cl_session; | ||
6090 | spin_lock(&clp->cl_lock); | ||
6091 | if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) { | ||
6092 | /* Initialise targets and channel attributes */ | ||
6093 | session->fc_target_max_rqst_sz = target_max_rqst_sz; | ||
6094 | session->fc_attrs.max_rqst_sz = target_max_rqst_sz; | ||
6095 | session->fc_target_max_resp_sz = target_max_resp_sz; | ||
6096 | session->fc_attrs.max_resp_sz = target_max_resp_sz; | ||
6097 | } else { | ||
6098 | /* Just adjust the targets */ | ||
6099 | if (target_max_rqst_sz > session->fc_target_max_rqst_sz) { | ||
6100 | session->fc_target_max_rqst_sz = target_max_rqst_sz; | ||
6101 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
6102 | } | ||
6103 | if (target_max_resp_sz > session->fc_target_max_resp_sz) { | ||
6104 | session->fc_target_max_resp_sz = target_max_resp_sz; | ||
6105 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
6106 | } | ||
6107 | } | ||
6108 | spin_unlock(&clp->cl_lock); | ||
6109 | |||
6110 | if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) | ||
6111 | nfs4_schedule_lease_recovery(clp); | ||
6112 | |||
6113 | return nfs41_check_session_ready(clp); | ||
6114 | } | ||
6115 | |||
6116 | int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time) | ||
6117 | { | ||
6118 | struct nfs4_session *session = clp->cl_session; | ||
6119 | int ret; | ||
6120 | |||
6121 | spin_lock(&clp->cl_lock); | ||
6122 | if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) { | ||
6123 | /* | ||
6124 | * Do not set NFS_CS_CHECK_LEASE_TIME instead set the | ||
6125 | * DS lease to be equal to the MDS lease. | ||
6126 | */ | ||
6127 | clp->cl_lease_time = lease_time; | ||
6128 | clp->cl_last_renewal = jiffies; | ||
6129 | } | ||
6130 | spin_unlock(&clp->cl_lock); | ||
6131 | |||
6132 | ret = nfs41_check_session_ready(clp); | ||
6133 | if (ret) | ||
6134 | return ret; | ||
6135 | /* Test for the DS role */ | ||
6136 | if (!is_ds_client(clp)) | ||
6137 | return -ENODEV; | ||
6138 | return 0; | ||
6139 | } | ||
6140 | EXPORT_SYMBOL_GPL(nfs4_init_ds_session); | ||
6141 | |||
6142 | |||
6143 | /* | ||
6144 | * Renew the cl_session lease. | 5733 | * Renew the cl_session lease. |
6145 | */ | 5734 | */ |
6146 | struct nfs4_sequence_data { | 5735 | struct nfs4_sequence_data { |