summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-08-03 21:54:33 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-29 13:29:08 -0700
commitb861a2580da034f6a57517c687ded68e20f99763 (patch)
treeea6409d60334148fddb6a34c5a0cc50e3377d4c9
parent3be1216c9e9976074d49414a53abf572ec4b4a24 (diff)
downloadkernel-mfld-blackbay-b861a2580da034f6a57517c687ded68e20f99763.tar.gz
kernel-mfld-blackbay-b861a2580da034f6a57517c687ded68e20f99763.tar.bz2
kernel-mfld-blackbay-b861a2580da034f6a57517c687ded68e20f99763.zip
pnfs-obj: Bug when we are running out of bio
commit 20618b21da0796115e81906d24ff1601552701b7 upstream. When we have a situation that the number of pages we want to encode is bigger then the size of the bio. (Which can currently happen only when all IO is going to a single device .e.g group_width==1) then the IO is submitted short and we report back only the amount of bytes we actually wrote/read and all is fine. BUT ... There was a bug that the current length counter was advanced before the fail to add the extra page, and we come to a situation that the CDB length was one-page longer then the actual bio size, which is of course rejected by the osd-target. While here also fix the bio size calculation, in the case that we received more then one group of devices. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/nfs/objlayout/objio_osd.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 799e8cffdf4..1d1dc1ee394 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -587,22 +587,19 @@ static void _calc_stripe_info(struct objio_state *ios, u64 file_offset,
}
static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
- unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len,
+ unsigned pgbase, struct _objio_per_comp *per_dev, int len,
gfp_t gfp_flags)
{
unsigned pg = *cur_pg;
+ int cur_len = len;
struct request_queue *q =
osd_request_queue(_io_od(ios, per_dev->dev));
- per_dev->length += cur_len;
-
if (per_dev->bio == NULL) {
- unsigned stripes = ios->layout->num_comps /
- ios->layout->mirrors_p1;
- unsigned pages_in_stripe = stripes *
+ unsigned pages_in_stripe = ios->layout->group_width *
(ios->layout->stripe_unit / PAGE_SIZE);
unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) /
- stripes;
+ ios->layout->group_width;
if (BIO_MAX_PAGES_KMALLOC < bio_size)
bio_size = BIO_MAX_PAGES_KMALLOC;
@@ -630,6 +627,7 @@ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
}
BUG_ON(cur_len);
+ per_dev->length += len;
*cur_pg = pg;
return 0;
}