diff options
-rw-r--r-- | fs/nfs/nfs4_fs.h | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 33 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 8 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
6 files changed, 33 insertions, 16 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 36880b9aa91e..42c58691fb41 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -258,7 +258,8 @@ extern int nfs4_proc_get_lease_time(struct nfs_client *clp, | |||
258 | extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, | 258 | extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, |
259 | bool sync); | 259 | bool sync); |
260 | 260 | ||
261 | extern struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags); | 261 | extern struct nfs4_slot *nfs4_alloc_slots(struct nfs4_slot_table *table, |
262 | u32 max_slots, gfp_t gfp_flags); | ||
262 | 263 | ||
263 | static inline bool | 264 | static inline bool |
264 | is_ds_only_client(struct nfs_client *clp) | 265 | is_ds_only_client(struct nfs_client *clp) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 14b39742b6e4..5b61c4a83191 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -467,25 +467,28 @@ void nfs4_check_drain_bc_complete(struct nfs4_session *ses) | |||
467 | 467 | ||
468 | static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) | 468 | static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) |
469 | { | 469 | { |
470 | struct nfs4_session *session; | ||
470 | struct nfs4_slot_table *tbl; | 471 | struct nfs4_slot_table *tbl; |
471 | 472 | ||
472 | tbl = &res->sr_session->fc_slot_table; | ||
473 | if (!res->sr_slot) { | 473 | if (!res->sr_slot) { |
474 | /* just wake up the next guy waiting since | 474 | /* just wake up the next guy waiting since |
475 | * we may have not consumed a slot after all */ | 475 | * we may have not consumed a slot after all */ |
476 | dprintk("%s: No slot\n", __func__); | 476 | dprintk("%s: No slot\n", __func__); |
477 | return; | 477 | return; |
478 | } | 478 | } |
479 | tbl = res->sr_slot->table; | ||
480 | session = tbl->session; | ||
479 | 481 | ||
480 | spin_lock(&tbl->slot_tbl_lock); | 482 | spin_lock(&tbl->slot_tbl_lock); |
481 | nfs4_free_slot(tbl, res->sr_slot - tbl->slots); | 483 | nfs4_free_slot(tbl, res->sr_slot - tbl->slots); |
482 | nfs4_check_drain_fc_complete(res->sr_session); | 484 | nfs4_check_drain_fc_complete(session); |
483 | spin_unlock(&tbl->slot_tbl_lock); | 485 | spin_unlock(&tbl->slot_tbl_lock); |
484 | res->sr_slot = NULL; | 486 | res->sr_slot = NULL; |
485 | } | 487 | } |
486 | 488 | ||
487 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 489 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) |
488 | { | 490 | { |
491 | struct nfs4_session *session; | ||
489 | struct nfs4_slot *slot; | 492 | struct nfs4_slot *slot; |
490 | unsigned long timestamp; | 493 | unsigned long timestamp; |
491 | struct nfs_client *clp; | 494 | struct nfs_client *clp; |
@@ -504,6 +507,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * | |||
504 | goto out; | 507 | goto out; |
505 | 508 | ||
506 | slot = res->sr_slot; | 509 | slot = res->sr_slot; |
510 | session = slot->table->session; | ||
507 | 511 | ||
508 | /* Check the SEQUENCE operation status */ | 512 | /* Check the SEQUENCE operation status */ |
509 | switch (res->sr_status) { | 513 | switch (res->sr_status) { |
@@ -511,7 +515,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * | |||
511 | /* Update the slot's sequence and clientid lease timer */ | 515 | /* Update the slot's sequence and clientid lease timer */ |
512 | ++slot->seq_nr; | 516 | ++slot->seq_nr; |
513 | timestamp = slot->renewal_time; | 517 | timestamp = slot->renewal_time; |
514 | clp = res->sr_session->clp; | 518 | clp = session->clp; |
515 | do_renew_lease(clp, timestamp); | 519 | do_renew_lease(clp, timestamp); |
516 | /* Check sequence flags */ | 520 | /* Check sequence flags */ |
517 | if (res->sr_status_flags != 0) | 521 | if (res->sr_status_flags != 0) |
@@ -524,7 +528,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * | |||
524 | */ | 528 | */ |
525 | dprintk("%s: slot=%td seq=%d: Operation in progress\n", | 529 | dprintk("%s: slot=%td seq=%d: Operation in progress\n", |
526 | __func__, | 530 | __func__, |
527 | slot - res->sr_session->fc_slot_table.slots, | 531 | slot - session->fc_slot_table.slots, |
528 | slot->seq_nr); | 532 | slot->seq_nr); |
529 | goto out_retry; | 533 | goto out_retry; |
530 | default: | 534 | default: |
@@ -546,7 +550,7 @@ out_retry: | |||
546 | static int nfs4_sequence_done(struct rpc_task *task, | 550 | static int nfs4_sequence_done(struct rpc_task *task, |
547 | struct nfs4_sequence_res *res) | 551 | struct nfs4_sequence_res *res) |
548 | { | 552 | { |
549 | if (res->sr_session == NULL) | 553 | if (res->sr_slot == NULL) |
550 | return 1; | 554 | return 1; |
551 | return nfs41_sequence_done(task, res); | 555 | return nfs41_sequence_done(task, res); |
552 | } | 556 | } |
@@ -591,7 +595,6 @@ static void nfs41_init_sequence(struct nfs4_sequence_args *args, | |||
591 | args->sa_cache_this = 0; | 595 | args->sa_cache_this = 0; |
592 | if (cache_reply) | 596 | if (cache_reply) |
593 | args->sa_cache_this = 1; | 597 | args->sa_cache_this = 1; |
594 | res->sr_session = NULL; | ||
595 | res->sr_slot = NULL; | 598 | res->sr_slot = NULL; |
596 | } | 599 | } |
597 | 600 | ||
@@ -646,7 +649,6 @@ int nfs41_setup_sequence(struct nfs4_session *session, | |||
646 | 649 | ||
647 | dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); | 650 | dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); |
648 | 651 | ||
649 | res->sr_session = session; | ||
650 | res->sr_slot = slot; | 652 | res->sr_slot = slot; |
651 | res->sr_status_flags = 0; | 653 | res->sr_status_flags = 0; |
652 | /* | 654 | /* |
@@ -5659,9 +5661,18 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo) | |||
5659 | return status; | 5661 | return status; |
5660 | } | 5662 | } |
5661 | 5663 | ||
5662 | struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags) | 5664 | struct nfs4_slot *nfs4_alloc_slots(struct nfs4_slot_table *table, |
5665 | u32 max_slots, gfp_t gfp_flags) | ||
5663 | { | 5666 | { |
5664 | return kmalloc_array(max_slots, sizeof(struct nfs4_slot), gfp_flags); | 5667 | struct nfs4_slot *tbl; |
5668 | u32 i; | ||
5669 | |||
5670 | tbl = kmalloc_array(max_slots, sizeof(*tbl), gfp_flags); | ||
5671 | if (tbl != NULL) { | ||
5672 | for (i = 0; i < max_slots; i++) | ||
5673 | tbl[i].table = table; | ||
5674 | } | ||
5675 | return tbl; | ||
5665 | } | 5676 | } |
5666 | 5677 | ||
5667 | static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, | 5678 | static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, |
@@ -5699,7 +5710,7 @@ static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, | |||
5699 | 5710 | ||
5700 | /* Does the newly negotiated max_reqs match the existing slot table? */ | 5711 | /* Does the newly negotiated max_reqs match the existing slot table? */ |
5701 | if (max_reqs != tbl->max_slots) { | 5712 | if (max_reqs != tbl->max_slots) { |
5702 | new = nfs4_alloc_slots(max_reqs, GFP_NOFS); | 5713 | new = nfs4_alloc_slots(tbl, max_reqs, GFP_NOFS); |
5703 | if (!new) | 5714 | if (!new) |
5704 | goto out; | 5715 | goto out; |
5705 | } | 5716 | } |
@@ -5738,11 +5749,13 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | |||
5738 | dprintk("--> %s\n", __func__); | 5749 | dprintk("--> %s\n", __func__); |
5739 | /* Fore channel */ | 5750 | /* Fore channel */ |
5740 | tbl = &ses->fc_slot_table; | 5751 | tbl = &ses->fc_slot_table; |
5752 | tbl->session = ses; | ||
5741 | status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); | 5753 | status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); |
5742 | if (status) /* -ENOMEM */ | 5754 | if (status) /* -ENOMEM */ |
5743 | return status; | 5755 | return status; |
5744 | /* Back channel */ | 5756 | /* Back channel */ |
5745 | tbl = &ses->bc_slot_table; | 5757 | tbl = &ses->bc_slot_table; |
5758 | tbl->session = ses; | ||
5746 | status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); | 5759 | status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); |
5747 | if (status && tbl->slots == NULL) | 5760 | if (status && tbl->slots == NULL) |
5748 | /* Fore and back channel share a connection so get | 5761 | /* Fore and back channel share a connection so get |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 96fcbb97fd6a..9495789c425b 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -2033,7 +2033,7 @@ static int nfs4_recall_slot(struct nfs_client *clp) | |||
2033 | return 0; | 2033 | return 0; |
2034 | nfs4_begin_drain_session(clp); | 2034 | nfs4_begin_drain_session(clp); |
2035 | fc_tbl = &clp->cl_session->fc_slot_table; | 2035 | fc_tbl = &clp->cl_session->fc_slot_table; |
2036 | new = nfs4_alloc_slots(fc_tbl->target_max_slots, GFP_NOFS); | 2036 | new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_max_slots, GFP_NOFS); |
2037 | if (!new) | 2037 | if (!new) |
2038 | return -ENOMEM; | 2038 | return -ENOMEM; |
2039 | 2039 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 672d9b0ef2c5..4126f054610a 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -5507,12 +5507,13 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
5507 | struct rpc_rqst *rqstp) | 5507 | struct rpc_rqst *rqstp) |
5508 | { | 5508 | { |
5509 | #if defined(CONFIG_NFS_V4_1) | 5509 | #if defined(CONFIG_NFS_V4_1) |
5510 | struct nfs4_session *session; | ||
5510 | struct nfs4_sessionid id; | 5511 | struct nfs4_sessionid id; |
5511 | u32 dummy; | 5512 | u32 dummy; |
5512 | int status; | 5513 | int status; |
5513 | __be32 *p; | 5514 | __be32 *p; |
5514 | 5515 | ||
5515 | if (!res->sr_session) | 5516 | if (res->sr_slot == NULL) |
5516 | return 0; | 5517 | return 0; |
5517 | 5518 | ||
5518 | status = decode_op_hdr(xdr, OP_SEQUENCE); | 5519 | status = decode_op_hdr(xdr, OP_SEQUENCE); |
@@ -5526,8 +5527,9 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
5526 | * sequence number, the server is looney tunes. | 5527 | * sequence number, the server is looney tunes. |
5527 | */ | 5528 | */ |
5528 | status = -EREMOTEIO; | 5529 | status = -EREMOTEIO; |
5530 | session = res->sr_slot->table->session; | ||
5529 | 5531 | ||
5530 | if (memcmp(id.data, res->sr_session->sess_id.data, | 5532 | if (memcmp(id.data, session->sess_id.data, |
5531 | NFS4_MAX_SESSIONID_LEN)) { | 5533 | NFS4_MAX_SESSIONID_LEN)) { |
5532 | dprintk("%s Invalid session id\n", __func__); | 5534 | dprintk("%s Invalid session id\n", __func__); |
5533 | goto out_err; | 5535 | goto out_err; |
@@ -5545,7 +5547,7 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
5545 | } | 5547 | } |
5546 | /* slot id */ | 5548 | /* slot id */ |
5547 | dummy = be32_to_cpup(p++); | 5549 | dummy = be32_to_cpup(p++); |
5548 | if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) { | 5550 | if (dummy != res->sr_slot - session->fc_slot_table.slots) { |
5549 | dprintk("%s Invalid slot id\n", __func__); | 5551 | dprintk("%s Invalid slot id\n", __func__); |
5550 | goto out_err; | 5552 | goto out_err; |
5551 | } | 5553 | } |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 97c8f9191880..b0412873d29c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -209,6 +209,7 @@ struct nfs_server { | |||
209 | /* Sessions */ | 209 | /* Sessions */ |
210 | #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) | 210 | #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) |
211 | struct nfs4_slot_table { | 211 | struct nfs4_slot_table { |
212 | struct nfs4_session *session; /* Parent session */ | ||
212 | struct nfs4_slot *slots; /* seqid per slot */ | 213 | struct nfs4_slot *slots; /* seqid per slot */ |
213 | unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */ | 214 | unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */ |
214 | spinlock_t slot_tbl_lock; | 215 | spinlock_t slot_tbl_lock; |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9cb1c63a70c2..0fd88ab0e814 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -187,6 +187,7 @@ struct nfs4_channel_attrs { | |||
187 | 187 | ||
188 | /* nfs41 sessions slot seqid */ | 188 | /* nfs41 sessions slot seqid */ |
189 | struct nfs4_slot { | 189 | struct nfs4_slot { |
190 | struct nfs4_slot_table *table; | ||
190 | unsigned long renewal_time; | 191 | unsigned long renewal_time; |
191 | u32 seq_nr; | 192 | u32 seq_nr; |
192 | }; | 193 | }; |
@@ -198,7 +199,6 @@ struct nfs4_sequence_args { | |||
198 | }; | 199 | }; |
199 | 200 | ||
200 | struct nfs4_sequence_res { | 201 | struct nfs4_sequence_res { |
201 | struct nfs4_session *sr_session; | ||
202 | struct nfs4_slot *sr_slot; /* slot used to send request */ | 202 | struct nfs4_slot *sr_slot; /* slot used to send request */ |
203 | int sr_status; /* sequence operation status */ | 203 | int sr_status; /* sequence operation status */ |
204 | u32 sr_status_flags; | 204 | u32 sr_status_flags; |