aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/ios.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2010-01-28 11:24:06 -0500
committerBoaz Harrosh <bharrosh@panasas.com>2010-02-28 06:44:42 -0500
commit86093aaff5be5b214613eb60553e236bdb389c84 (patch)
tree64993f3fff8b60408441e8912aa5690346108492 /fs/exofs/ios.c
parent5d952b8391692553c31e620a92d6e09262a9a307 (diff)
exofs: convert io_state to use pages array instead of bio at input
* inode.c operations are full-pages based, and not actually true scatter-gather * Lets us use more pages at once upto 512 (from 249) in 64 bit * Brings us much much closer to be able to use exofs's io_state engine from objlayout driver. (Once I decide where to put the common code) After RAID0 patch the outer (input) bio was never used as a bio, but was simply a page carrier into the raid engine. Even in the simple mirror/single-dev arrangement pages info was copied into a second bio. It is now easer to just pass a pages array into the io_state and prepare bio(s) once. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs/ios.c')
-rw-r--r--fs/exofs/ios.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 6e446b2670b9..263052c77f41 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -283,10 +283,11 @@ static void _offset_dev_unit_off(struct exofs_io_state *ios, u64 file_offset,
283 *dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1; 283 *dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1;
284} 284}
285 285
286static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_bvec, 286static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
287 struct exofs_per_dev_state *per_dev, int cur_len) 287 unsigned pgbase, struct exofs_per_dev_state *per_dev,
288 int cur_len)
288{ 289{
289 unsigned bv = *cur_bvec; 290 unsigned pg = *cur_pg;
290 struct request_queue *q = 291 struct request_queue *q =
291 osd_request_queue(exofs_ios_od(ios, per_dev->dev)); 292 osd_request_queue(exofs_ios_od(ios, per_dev->dev));
292 293
@@ -295,7 +296,7 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_bvec,
295 if (per_dev->bio == NULL) { 296 if (per_dev->bio == NULL) {
296 unsigned pages_in_stripe = ios->layout->group_width * 297 unsigned pages_in_stripe = ios->layout->group_width *
297 (ios->layout->stripe_unit / PAGE_SIZE); 298 (ios->layout->stripe_unit / PAGE_SIZE);
298 unsigned bio_size = (ios->bio->bi_vcnt + pages_in_stripe) / 299 unsigned bio_size = (ios->nr_pages + pages_in_stripe) /
299 ios->layout->group_width; 300 ios->layout->group_width;
300 301
301 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); 302 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
@@ -307,21 +308,22 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_bvec,
307 } 308 }
308 309
309 while (cur_len > 0) { 310 while (cur_len > 0) {
310 int added_len; 311 unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
311 struct bio_vec *bvec = &ios->bio->bi_io_vec[bv]; 312 unsigned added_len;
312 313
313 BUG_ON(ios->bio->bi_vcnt <= bv); 314 BUG_ON(ios->nr_pages <= pg);
314 cur_len -= bvec->bv_len; 315 cur_len -= pglen;
315 316
316 added_len = bio_add_pc_page(q, per_dev->bio, bvec->bv_page, 317 added_len = bio_add_pc_page(q, per_dev->bio, ios->pages[pg],
317 bvec->bv_len, bvec->bv_offset); 318 pglen, pgbase);
318 if (unlikely(bvec->bv_len != added_len)) 319 if (unlikely(pglen != added_len))
319 return -ENOMEM; 320 return -ENOMEM;
320 ++bv; 321 pgbase = 0;
322 ++pg;
321 } 323 }
322 BUG_ON(cur_len); 324 BUG_ON(cur_len);
323 325
324 *cur_bvec = bv; 326 *cur_pg = pg;
325 return 0; 327 return 0;
326} 328}
327 329
@@ -332,10 +334,10 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
332 unsigned stripe_unit = ios->layout->stripe_unit; 334 unsigned stripe_unit = ios->layout->stripe_unit;
333 unsigned comp = 0; 335 unsigned comp = 0;
334 unsigned stripes = 0; 336 unsigned stripes = 0;
335 unsigned cur_bvec = 0; 337 unsigned cur_pg = 0;
336 int ret; 338 int ret = 0;
337 339
338 if (!ios->bio) { 340 if (!ios->pages) {
339 if (ios->kern_buff) { 341 if (ios->kern_buff) {
340 struct exofs_per_dev_state *per_dev = &ios->per_dev[0]; 342 struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
341 unsigned unit_off; 343 unsigned unit_off;
@@ -352,7 +354,7 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
352 354
353 while (length) { 355 while (length) {
354 struct exofs_per_dev_state *per_dev = &ios->per_dev[comp]; 356 struct exofs_per_dev_state *per_dev = &ios->per_dev[comp];
355 unsigned cur_len; 357 unsigned cur_len, page_off;
356 358
357 if (!per_dev->length) { 359 if (!per_dev->length) {
358 unsigned unit_off; 360 unsigned unit_off;
@@ -362,11 +364,15 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
362 stripes++; 364 stripes++;
363 cur_len = min_t(u64, stripe_unit - unit_off, length); 365 cur_len = min_t(u64, stripe_unit - unit_off, length);
364 offset += cur_len; 366 offset += cur_len;
367 page_off = unit_off & ~PAGE_MASK;
368 BUG_ON(page_off != ios->pgbase);
365 } else { 369 } else {
366 cur_len = min_t(u64, stripe_unit, length); 370 cur_len = min_t(u64, stripe_unit, length);
371 page_off = 0;
367 } 372 }
368 373
369 ret = _add_stripe_unit(ios, &cur_bvec, per_dev, cur_len); 374 ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
375 cur_len);
370 if (unlikely(ret)) 376 if (unlikely(ret))
371 goto out; 377 goto out;
372 378
@@ -448,7 +454,7 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
448 per_dev->or = or; 454 per_dev->or = or;
449 per_dev->offset = master_dev->offset; 455 per_dev->offset = master_dev->offset;
450 456
451 if (ios->bio) { 457 if (ios->pages) {
452 struct bio *bio; 458 struct bio *bio;
453 459
454 if (per_dev != master_dev) { 460 if (per_dev != master_dev) {
@@ -541,7 +547,7 @@ static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
541 } 547 }
542 per_dev->or = or; 548 per_dev->or = or;
543 549
544 if (ios->bio) { 550 if (ios->pages) {
545 osd_req_read(or, &ios->obj, per_dev->offset, 551 osd_req_read(or, &ios->obj, per_dev->offset,
546 per_dev->bio, per_dev->length); 552 per_dev->bio, per_dev->length);
547 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx" 553 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"