diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2010-01-28 11:24:06 -0500 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2010-02-28 06:44:42 -0500 |
commit | 86093aaff5be5b214613eb60553e236bdb389c84 (patch) | |
tree | 64993f3fff8b60408441e8912aa5690346108492 /fs/exofs/ios.c | |
parent | 5d952b8391692553c31e620a92d6e09262a9a307 (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.c | 46 |
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 | ||
286 | static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_bvec, | 286 | static 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" |