aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-08-04 00:54:33 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-08-04 11:54:38 -0400
commit20618b21da0796115e81906d24ff1601552701b7 (patch)
tree11f544d34a9e27ff941597018dc9ba2ae74c845e /fs/nfs
parent88c9e42196285a7c573e2abda11a4b5037c669bc (diff)
pnfs-obj: Bug when we are running out of bio
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. CC: Stable Tree <stable@kernel.org> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-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 9383ca7245bc..aa8663a8938f 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -589,22 +589,19 @@ static void _calc_stripe_info(struct objio_state *ios, u64 file_offset,
589} 589}
590 590
591static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, 591static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
592 unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len, 592 unsigned pgbase, struct _objio_per_comp *per_dev, int len,
593 gfp_t gfp_flags) 593 gfp_t gfp_flags)
594{ 594{
595 unsigned pg = *cur_pg; 595 unsigned pg = *cur_pg;
596 int cur_len = len;
596 struct request_queue *q = 597 struct request_queue *q =
597 osd_request_queue(_io_od(ios, per_dev->dev)); 598 osd_request_queue(_io_od(ios, per_dev->dev));
598 599
599 per_dev->length += cur_len;
600
601 if (per_dev->bio == NULL) { 600 if (per_dev->bio == NULL) {
602 unsigned stripes = ios->layout->num_comps / 601 unsigned pages_in_stripe = ios->layout->group_width *
603 ios->layout->mirrors_p1;
604 unsigned pages_in_stripe = stripes *
605 (ios->layout->stripe_unit / PAGE_SIZE); 602 (ios->layout->stripe_unit / PAGE_SIZE);
606 unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) / 603 unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) /
607 stripes; 604 ios->layout->group_width;
608 605
609 if (BIO_MAX_PAGES_KMALLOC < bio_size) 606 if (BIO_MAX_PAGES_KMALLOC < bio_size)
610 bio_size = BIO_MAX_PAGES_KMALLOC; 607 bio_size = BIO_MAX_PAGES_KMALLOC;
@@ -632,6 +629,7 @@ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
632 } 629 }
633 BUG_ON(cur_len); 630 BUG_ON(cur_len);
634 631
632 per_dev->length += len;
635 *cur_pg = pg; 633 *cur_pg = pg;
636 return 0; 634 return 0;
637} 635}