Skip to content

Commit 35a21b4

Browse files
committed
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv4.1: Return NFS4ERR_BADSESSION to callbacks during session resets NFSv4.1: Fix the callback 'highest_used_slotid' behaviour pnfs-obj: Fix the comp_index != 0 case pnfs-obj: Bug when we are running out of bio nfs: add missing prefetch.h include
2 parents 5c80c71 + 910ac68 commit 35a21b4

File tree

6 files changed

+43
-40
lines changed

6 files changed

+43
-40
lines changed

fs/nfs/blocklayout/blocklayout.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/namei.h>
3737
#include <linux/bio.h> /* struct bio */
3838
#include <linux/buffer_head.h> /* various write calls */
39+
#include <linux/prefetch.h>
3940

4041
#include "blocklayout.h"
4142

fs/nfs/callback.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ enum nfs4_callback_opnum {
3838
struct cb_process_state {
3939
__be32 drc_status;
4040
struct nfs_client *clp;
41+
int slotid;
4142
};
4243

4344
struct cb_compound_hdr_arg {
@@ -166,7 +167,6 @@ extern unsigned nfs4_callback_layoutrecall(
166167
void *dummy, struct cb_process_state *cps);
167168

168169
extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
169-
extern void nfs4_cb_take_slot(struct nfs_client *clp);
170170

171171
struct cb_devicenotifyitem {
172172
uint32_t cbd_notify_type;

fs/nfs/callback_proc.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
348348
/* Normal */
349349
if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
350350
slot->seq_nr++;
351-
return htonl(NFS4_OK);
351+
goto out_ok;
352352
}
353353

354354
/* Replay */
@@ -367,11 +367,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
367367
/* Wraparound */
368368
if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
369369
slot->seq_nr = 1;
370-
return htonl(NFS4_OK);
370+
goto out_ok;
371371
}
372372

373373
/* Misordered request */
374374
return htonl(NFS4ERR_SEQ_MISORDERED);
375+
out_ok:
376+
tbl->highest_used_slotid = args->csa_slotid;
377+
return htonl(NFS4_OK);
375378
}
376379

377380
/*
@@ -433,26 +436,37 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
433436
struct cb_sequenceres *res,
434437
struct cb_process_state *cps)
435438
{
439+
struct nfs4_slot_table *tbl;
436440
struct nfs_client *clp;
437441
int i;
438442
__be32 status = htonl(NFS4ERR_BADSESSION);
439443

440-
cps->clp = NULL;
441-
442444
clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
443445
if (clp == NULL)
444446
goto out;
445447

448+
tbl = &clp->cl_session->bc_slot_table;
449+
450+
spin_lock(&tbl->slot_tbl_lock);
446451
/* state manager is resetting the session */
447452
if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) {
448-
status = NFS4ERR_DELAY;
453+
spin_unlock(&tbl->slot_tbl_lock);
454+
status = htonl(NFS4ERR_DELAY);
455+
/* Return NFS4ERR_BADSESSION if we're draining the session
456+
* in order to reset it.
457+
*/
458+
if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
459+
status = htonl(NFS4ERR_BADSESSION);
449460
goto out;
450461
}
451462

452463
status = validate_seqid(&clp->cl_session->bc_slot_table, args);
464+
spin_unlock(&tbl->slot_tbl_lock);
453465
if (status)
454466
goto out;
455467

468+
cps->slotid = args->csa_slotid;
469+
456470
/*
457471
* Check for pending referring calls. If a match is found, a
458472
* related callback was received before the response to the original
@@ -469,7 +483,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
469483
res->csr_slotid = args->csa_slotid;
470484
res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
471485
res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
472-
nfs4_cb_take_slot(clp);
473486

474487
out:
475488
cps->clp = clp; /* put in nfs4_callback_compound */

fs/nfs/callback_xdr.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -754,26 +754,15 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
754754
* Let the state manager know callback processing done.
755755
* A single slot, so highest used slotid is either 0 or -1
756756
*/
757-
tbl->highest_used_slotid--;
757+
tbl->highest_used_slotid = -1;
758758
nfs4_check_drain_bc_complete(session);
759759
spin_unlock(&tbl->slot_tbl_lock);
760760
}
761761

762-
static void nfs4_cb_free_slot(struct nfs_client *clp)
762+
static void nfs4_cb_free_slot(struct cb_process_state *cps)
763763
{
764-
if (clp && clp->cl_session)
765-
nfs4_callback_free_slot(clp->cl_session);
766-
}
767-
768-
/* A single slot, so highest used slotid is either 0 or -1 */
769-
void nfs4_cb_take_slot(struct nfs_client *clp)
770-
{
771-
struct nfs4_slot_table *tbl = &clp->cl_session->bc_slot_table;
772-
773-
spin_lock(&tbl->slot_tbl_lock);
774-
tbl->highest_used_slotid++;
775-
BUG_ON(tbl->highest_used_slotid != 0);
776-
spin_unlock(&tbl->slot_tbl_lock);
764+
if (cps->slotid != -1)
765+
nfs4_callback_free_slot(cps->clp->cl_session);
777766
}
778767

779768
#else /* CONFIG_NFS_V4_1 */
@@ -784,7 +773,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
784773
return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
785774
}
786775

787-
static void nfs4_cb_free_slot(struct nfs_client *clp)
776+
static void nfs4_cb_free_slot(struct cb_process_state *cps)
788777
{
789778
}
790779
#endif /* CONFIG_NFS_V4_1 */
@@ -866,6 +855,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
866855
struct cb_process_state cps = {
867856
.drc_status = 0,
868857
.clp = NULL,
858+
.slotid = -1,
869859
};
870860
unsigned int nops = 0;
871861

@@ -906,7 +896,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
906896

907897
*hdr_res.status = status;
908898
*hdr_res.nops = htonl(nops);
909-
nfs4_cb_free_slot(cps.clp);
899+
nfs4_cb_free_slot(&cps);
910900
nfs_put_client(cps.clp);
911901
dprintk("%s: done, status = %u\n", __func__, ntohl(status));
912902
return rpc_success;

fs/nfs/objlayout/objio_osd.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@ static int _io_check(struct objio_state *ios, bool is_write)
479479
for (i = 0; i < ios->numdevs; i++) {
480480
struct osd_sense_info osi;
481481
struct osd_request *or = ios->per_dev[i].or;
482-
unsigned dev;
483482
int ret;
484483

485484
if (!or)
@@ -500,9 +499,8 @@ static int _io_check(struct objio_state *ios, bool is_write)
500499

501500
continue; /* we recovered */
502501
}
503-
dev = ios->per_dev[i].dev;
504-
objlayout_io_set_result(&ios->ol_state, dev,
505-
&ios->layout->comps[dev].oc_object_id,
502+
objlayout_io_set_result(&ios->ol_state, i,
503+
&ios->layout->comps[i].oc_object_id,
506504
osd_pri_2_pnfs_err(osi.osd_err_pri),
507505
ios->per_dev[i].offset,
508506
ios->per_dev[i].length,
@@ -589,22 +587,19 @@ static void _calc_stripe_info(struct objio_state *ios, u64 file_offset,
589587
}
590588

591589
static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
592-
unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len,
590+
unsigned pgbase, struct _objio_per_comp *per_dev, int len,
593591
gfp_t gfp_flags)
594592
{
595593
unsigned pg = *cur_pg;
594+
int cur_len = len;
596595
struct request_queue *q =
597596
osd_request_queue(_io_od(ios, per_dev->dev));
598597

599-
per_dev->length += cur_len;
600-
601598
if (per_dev->bio == NULL) {
602-
unsigned stripes = ios->layout->num_comps /
603-
ios->layout->mirrors_p1;
604-
unsigned pages_in_stripe = stripes *
599+
unsigned pages_in_stripe = ios->layout->group_width *
605600
(ios->layout->stripe_unit / PAGE_SIZE);
606601
unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) /
607-
stripes;
602+
ios->layout->group_width;
608603

609604
if (BIO_MAX_PAGES_KMALLOC < bio_size)
610605
bio_size = BIO_MAX_PAGES_KMALLOC;
@@ -632,6 +627,7 @@ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
632627
}
633628
BUG_ON(cur_len);
634629

630+
per_dev->length += len;
635631
*cur_pg = pg;
636632
return 0;
637633
}
@@ -650,7 +646,7 @@ static int _prepare_one_group(struct objio_state *ios, u64 length,
650646
int ret = 0;
651647

652648
while (length) {
653-
struct _objio_per_comp *per_dev = &ios->per_dev[dev];
649+
struct _objio_per_comp *per_dev = &ios->per_dev[dev - first_dev];
654650
unsigned cur_len, page_off = 0;
655651

656652
if (!per_dev->length) {
@@ -670,8 +666,8 @@ static int _prepare_one_group(struct objio_state *ios, u64 length,
670666
cur_len = stripe_unit;
671667
}
672668

673-
if (max_comp < dev)
674-
max_comp = dev;
669+
if (max_comp < dev - first_dev)
670+
max_comp = dev - first_dev;
675671
} else {
676672
cur_len = stripe_unit;
677673
}
@@ -806,7 +802,7 @@ static int _read_mirrors(struct objio_state *ios, unsigned cur_comp)
806802
struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp];
807803
unsigned dev = per_dev->dev;
808804
struct pnfs_osd_object_cred *cred =
809-
&ios->layout->comps[dev];
805+
&ios->layout->comps[cur_comp];
810806
struct osd_obj_id obj = {
811807
.partition = cred->oc_object_id.oid_partition_id,
812808
.id = cred->oc_object_id.oid_object_id,
@@ -904,7 +900,7 @@ static int _write_mirrors(struct objio_state *ios, unsigned cur_comp)
904900
for (; cur_comp < last_comp; ++cur_comp, ++dev) {
905901
struct osd_request *or = NULL;
906902
struct pnfs_osd_object_cred *cred =
907-
&ios->layout->comps[dev];
903+
&ios->layout->comps[cur_comp];
908904
struct osd_obj_id obj = {
909905
.partition = cred->oc_object_id.oid_partition_id,
910906
.id = cred->oc_object_id.oid_object_id,

fs/nfs/objlayout/pnfs_osd_xdr_cli.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout,
170170
p = _osd_xdr_decode_data_map(p, &layout->olo_map);
171171
layout->olo_comps_index = be32_to_cpup(p++);
172172
layout->olo_num_comps = be32_to_cpup(p++);
173+
dprintk("%s: olo_comps_index=%d olo_num_comps=%d\n", __func__,
174+
layout->olo_comps_index, layout->olo_num_comps);
175+
173176
iter->total_comps = layout->olo_num_comps;
174177
return 0;
175178
}

0 commit comments

Comments
 (0)