aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/ios.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-08-05 18:06:04 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-08-06 22:35:32 -0400
commit9e9db45649eb5d3ee5622fdad741914ecf1016a0 (patch)
tree19ab9e1431e3d6535cef3f2cba6fcff12bb6ba6c /fs/exofs/ios.c
parent85e44df4748670a1a7d8441b2d75843cdebc478a (diff)
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info, single pid, and a single device-table, global to the filesystem. Then passing a credential and object_id info at the io_state level, private for each inode. It would also devise this contraption of rotating the device table view for each inode->ino to spread out the device usage. This is not compatible with the pnfs-objects standard, demanding that each inode can have it's own layout-info, device-table, and each object component it's own pid, oid and creds. So: Bring exofs raid engine to be usable for generic pnfs-objects use by: * Define an exofs_comp structure that holds obj_id and credential info. * Break up exofs_layout struct to an exofs_components structure that holds a possible array of exofs_comp and the array of devices + the size of the arrays. * Add a "comps" parameter to get_io_state() that specifies the ids creds and device array to use for each IO. This enables to keep the layout global, but the device-table view, creds and IDs at the inode level. It only adds two 64bit to each inode, since some of these members already existed in another form. * ios raid engine now access layout-info and comps-info through the passed pointers. Everything is pre-prepared by caller for generic access of these structures and arrays. At the exofs Level: * Super block holds an exofs_components struct that holds the device array, previously in layout. The devices there are in device-table order. The device-array is twice bigger and repeats the device-table twice so now each inode's device array can point to a random device and have a round-robin view of the table, making it compatible to previous exofs versions. * Each inode has an exofs_components struct that is initialized at load time, with it's own view of the device table IDs and creds. When doing IO this gets passed to the io_state together with the layout. While preforming this change. Bugs where found where credentials with the wrong IDs where used to access the different SB objects (super.c). As well as some dead code. It was never noticed because the target we use does not check the credentials. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs/ios.c')
-rw-r--r--fs/exofs/ios.c102
1 files changed, 62 insertions, 40 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 21d6130b462..f9d5c5a823f 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -31,24 +31,41 @@
31#define EXOFS_DBGMSG2(M...) do {} while (0) 31#define EXOFS_DBGMSG2(M...) do {} while (0)
32/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */ 32/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */
33 33
34int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, 34static u8 *_ios_cred(struct exofs_io_state *ios, unsigned index)
35 u64 offset, u64 length, struct exofs_io_state **pios) 35{
36 return ios->comps->comps[index & ios->comps->single_comp].cred;
37}
38
39static struct osd_obj_id *_ios_obj(struct exofs_io_state *ios, unsigned index)
40{
41 return &ios->comps->comps[index & ios->comps->single_comp].obj;
42}
43
44static struct osd_dev *_ios_od(struct exofs_io_state *ios, unsigned index)
45{
46 return ios->comps->ods[index];
47}
48
49int exofs_get_rw_state(struct exofs_layout *layout,
50 struct exofs_components *comps,
51 bool is_reading, u64 offset, u64 length,
52 struct exofs_io_state **pios)
36{ 53{
37 struct exofs_io_state *ios; 54 struct exofs_io_state *ios;
38 55
39 /*TODO: Maybe use kmem_cach per sbi of size 56 /*TODO: Maybe use kmem_cach per sbi of size
40 * exofs_io_state_size(layout->s_numdevs) 57 * exofs_io_state_size(layout->s_numdevs)
41 */ 58 */
42 ios = kzalloc(exofs_io_state_size(layout->s_numdevs), GFP_KERNEL); 59 ios = kzalloc(exofs_io_state_size(comps->numdevs), GFP_KERNEL);
43 if (unlikely(!ios)) { 60 if (unlikely(!ios)) {
44 EXOFS_DBGMSG("Failed kzalloc bytes=%d\n", 61 EXOFS_DBGMSG("Failed kzalloc bytes=%d\n",
45 exofs_io_state_size(layout->s_numdevs)); 62 exofs_io_state_size(comps->numdevs));
46 *pios = NULL; 63 *pios = NULL;
47 return -ENOMEM; 64 return -ENOMEM;
48 } 65 }
49 66
50 ios->layout = layout; 67 ios->layout = layout;
51 ios->obj.partition = layout->s_pid; 68 ios->comps = comps;
52 ios->offset = offset; 69 ios->offset = offset;
53 ios->length = length; 70 ios->length = length;
54 ios->reading = is_reading; 71 ios->reading = is_reading;
@@ -58,9 +75,10 @@ int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading,
58} 75}
59 76
60int exofs_get_io_state(struct exofs_layout *layout, 77int exofs_get_io_state(struct exofs_layout *layout,
78 struct exofs_components *comps,
61 struct exofs_io_state **ios) 79 struct exofs_io_state **ios)
62{ 80{
63 return exofs_get_rw_state(layout, true, 0, 0, ios); 81 return exofs_get_rw_state(layout, comps, true, 0, 0, ios);
64} 82}
65 83
66void exofs_put_io_state(struct exofs_io_state *ios) 84void exofs_put_io_state(struct exofs_io_state *ios)
@@ -119,7 +137,7 @@ static int exofs_io_execute(struct exofs_io_state *ios)
119 if (unlikely(!or)) 137 if (unlikely(!or))
120 continue; 138 continue;
121 139
122 ret = osd_finalize_request(or, 0, ios->cred, NULL); 140 ret = osd_finalize_request(or, 0, _ios_cred(ios, i), NULL);
123 if (unlikely(ret)) { 141 if (unlikely(ret)) {
124 EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", 142 EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n",
125 ret); 143 ret);
@@ -300,7 +318,7 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
300{ 318{
301 unsigned pg = *cur_pg; 319 unsigned pg = *cur_pg;
302 struct request_queue *q = 320 struct request_queue *q =
303 osd_request_queue(exofs_ios_od(ios, per_dev->dev)); 321 osd_request_queue(_ios_od(ios, per_dev->dev));
304 322
305 per_dev->length += cur_len; 323 per_dev->length += cur_len;
306 324
@@ -440,10 +458,10 @@ int exofs_sbi_create(struct exofs_io_state *ios)
440{ 458{
441 int i, ret; 459 int i, ret;
442 460
443 for (i = 0; i < ios->layout->s_numdevs; i++) { 461 for (i = 0; i < ios->comps->numdevs; i++) {
444 struct osd_request *or; 462 struct osd_request *or;
445 463
446 or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); 464 or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
447 if (unlikely(!or)) { 465 if (unlikely(!or)) {
448 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 466 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
449 ret = -ENOMEM; 467 ret = -ENOMEM;
@@ -452,7 +470,7 @@ int exofs_sbi_create(struct exofs_io_state *ios)
452 ios->per_dev[i].or = or; 470 ios->per_dev[i].or = or;
453 ios->numdevs++; 471 ios->numdevs++;
454 472
455 osd_req_create_object(or, &ios->obj); 473 osd_req_create_object(or, _ios_obj(ios, i));
456 } 474 }
457 ret = exofs_io_execute(ios); 475 ret = exofs_io_execute(ios);
458 476
@@ -464,10 +482,10 @@ int exofs_sbi_remove(struct exofs_io_state *ios)
464{ 482{
465 int i, ret; 483 int i, ret;
466 484
467 for (i = 0; i < ios->layout->s_numdevs; i++) { 485 for (i = 0; i < ios->comps->numdevs; i++) {
468 struct osd_request *or; 486 struct osd_request *or;
469 487
470 or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); 488 or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
471 if (unlikely(!or)) { 489 if (unlikely(!or)) {
472 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 490 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
473 ret = -ENOMEM; 491 ret = -ENOMEM;
@@ -476,7 +494,7 @@ int exofs_sbi_remove(struct exofs_io_state *ios)
476 ios->per_dev[i].or = or; 494 ios->per_dev[i].or = or;
477 ios->numdevs++; 495 ios->numdevs++;
478 496
479 osd_req_remove_object(or, &ios->obj); 497 osd_req_remove_object(or, _ios_obj(ios, i));
480 } 498 }
481 ret = exofs_io_execute(ios); 499 ret = exofs_io_execute(ios);
482 500
@@ -498,7 +516,7 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
498 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 516 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
499 struct osd_request *or; 517 struct osd_request *or;
500 518
501 or = osd_start_request(exofs_ios_od(ios, dev), GFP_KERNEL); 519 or = osd_start_request(_ios_od(ios, dev), GFP_KERNEL);
502 if (unlikely(!or)) { 520 if (unlikely(!or)) {
503 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 521 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
504 ret = -ENOMEM; 522 ret = -ENOMEM;
@@ -533,25 +551,29 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
533 bio->bi_rw |= REQ_WRITE; 551 bio->bi_rw |= REQ_WRITE;
534 } 552 }
535 553
536 osd_req_write(or, &ios->obj, per_dev->offset, bio, 554 osd_req_write(or, _ios_obj(ios, dev), per_dev->offset,
537 per_dev->length); 555 bio, per_dev->length);
538 EXOFS_DBGMSG("write(0x%llx) offset=0x%llx " 556 EXOFS_DBGMSG("write(0x%llx) offset=0x%llx "
539 "length=0x%llx dev=%d\n", 557 "length=0x%llx dev=%d\n",
540 _LLU(ios->obj.id), _LLU(per_dev->offset), 558 _LLU(_ios_obj(ios, dev)->id),
559 _LLU(per_dev->offset),
541 _LLU(per_dev->length), dev); 560 _LLU(per_dev->length), dev);
542 } else if (ios->kern_buff) { 561 } else if (ios->kern_buff) {
543 ret = osd_req_write_kern(or, &ios->obj, per_dev->offset, 562 ret = osd_req_write_kern(or, _ios_obj(ios, dev),
544 ios->kern_buff, ios->length); 563 per_dev->offset,
564 ios->kern_buff, ios->length);
545 if (unlikely(ret)) 565 if (unlikely(ret))
546 goto out; 566 goto out;
547 EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx " 567 EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
548 "length=0x%llx dev=%d\n", 568 "length=0x%llx dev=%d\n",
549 _LLU(ios->obj.id), _LLU(per_dev->offset), 569 _LLU(_ios_obj(ios, dev)->id),
570 _LLU(per_dev->offset),
550 _LLU(ios->length), dev); 571 _LLU(ios->length), dev);
551 } else { 572 } else {
552 osd_req_set_attributes(or, &ios->obj); 573 osd_req_set_attributes(or, _ios_obj(ios, dev));
553 EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", 574 EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n",
554 _LLU(ios->obj.id), ios->out_attr_len, dev); 575 _LLU(_ios_obj(ios, dev)->id),
576 ios->out_attr_len, dev);
555 } 577 }
556 578
557 if (ios->out_attr) 579 if (ios->out_attr)
@@ -590,13 +612,14 @@ static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
590{ 612{
591 struct osd_request *or; 613 struct osd_request *or;
592 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 614 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
593 unsigned first_dev = (unsigned)ios->obj.id; 615 struct osd_obj_id *obj = _ios_obj(ios, cur_comp);
616 unsigned first_dev = (unsigned)obj->id;
594 617
595 if (ios->pages && !per_dev->length) 618 if (ios->pages && !per_dev->length)
596 return 0; /* Just an empty slot */ 619 return 0; /* Just an empty slot */
597 620
598 first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1; 621 first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1;
599 or = osd_start_request(exofs_ios_od(ios, first_dev), GFP_KERNEL); 622 or = osd_start_request(_ios_od(ios, first_dev), GFP_KERNEL);
600 if (unlikely(!or)) { 623 if (unlikely(!or)) {
601 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 624 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
602 return -ENOMEM; 625 return -ENOMEM;
@@ -604,25 +627,26 @@ static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
604 per_dev->or = or; 627 per_dev->or = or;
605 628
606 if (ios->pages) { 629 if (ios->pages) {
607 osd_req_read(or, &ios->obj, per_dev->offset, 630 osd_req_read(or, obj, per_dev->offset,
608 per_dev->bio, per_dev->length); 631 per_dev->bio, per_dev->length);
609 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx" 632 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"
610 " dev=%d\n", _LLU(ios->obj.id), 633 " dev=%d\n", _LLU(obj->id),
611 _LLU(per_dev->offset), _LLU(per_dev->length), 634 _LLU(per_dev->offset), _LLU(per_dev->length),
612 first_dev); 635 first_dev);
613 } else if (ios->kern_buff) { 636 } else if (ios->kern_buff) {
614 int ret = osd_req_read_kern(or, &ios->obj, per_dev->offset, 637 int ret = osd_req_read_kern(or, obj, per_dev->offset,
615 ios->kern_buff, ios->length); 638 ios->kern_buff, ios->length);
616 EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx " 639 EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx "
617 "length=0x%llx dev=%d ret=>%d\n", 640 "length=0x%llx dev=%d ret=>%d\n",
618 _LLU(ios->obj.id), _LLU(per_dev->offset), 641 _LLU(obj->id), _LLU(per_dev->offset),
619 _LLU(ios->length), first_dev, ret); 642 _LLU(ios->length), first_dev, ret);
620 if (unlikely(ret)) 643 if (unlikely(ret))
621 return ret; 644 return ret;
622 } else { 645 } else {
623 osd_req_get_attributes(or, &ios->obj); 646 osd_req_get_attributes(or, obj);
624 EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n", 647 EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n",
625 _LLU(ios->obj.id), ios->in_attr_len, first_dev); 648 _LLU(obj->id),
649 ios->in_attr_len, first_dev);
626 } 650 }
627 if (ios->out_attr) 651 if (ios->out_attr)
628 osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len); 652 osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len);
@@ -682,14 +706,14 @@ static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp,
682 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 706 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
683 struct osd_request *or; 707 struct osd_request *or;
684 708
685 or = osd_start_request(exofs_ios_od(ios, cur_comp), GFP_KERNEL); 709 or = osd_start_request(_ios_od(ios, cur_comp), GFP_KERNEL);
686 if (unlikely(!or)) { 710 if (unlikely(!or)) {
687 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 711 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
688 return -ENOMEM; 712 return -ENOMEM;
689 } 713 }
690 per_dev->or = or; 714 per_dev->or = or;
691 715
692 osd_req_set_attributes(or, &ios->obj); 716 osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
693 osd_req_add_set_attr_list(or, attr, 1); 717 osd_req_add_set_attr_list(or, attr, 1);
694 } 718 }
695 719
@@ -721,9 +745,9 @@ void _calc_trunk_info(struct exofs_layout *layout, u64 file_offset,
721 ti->max_devs = layout->group_width * layout->group_count; 745 ti->max_devs = layout->group_width * layout->group_count;
722} 746}
723 747
724int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) 748int exofs_truncate(struct exofs_layout *layout, struct exofs_components *comps,
749 u64 size)
725{ 750{
726 struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info;
727 struct exofs_io_state *ios; 751 struct exofs_io_state *ios;
728 struct exofs_trunc_attr { 752 struct exofs_trunc_attr {
729 struct osd_attr attr; 753 struct osd_attr attr;
@@ -732,7 +756,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
732 struct _trunc_info ti; 756 struct _trunc_info ti;
733 int i, ret; 757 int i, ret;
734 758
735 ret = exofs_get_io_state(&sbi->layout, &ios); 759 ret = exofs_get_io_state(layout, comps, &ios);
736 if (unlikely(ret)) 760 if (unlikely(ret))
737 return ret; 761 return ret;
738 762
@@ -745,9 +769,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
745 goto out; 769 goto out;
746 } 770 }
747 771
748 ios->obj.id = exofs_oi_objno(oi); 772 ios->numdevs = ios->comps->numdevs;
749 ios->cred = oi->i_cred;
750 ios->numdevs = ios->layout->s_numdevs;
751 773
752 for (i = 0; i < ti.max_devs; ++i) { 774 for (i = 0; i < ti.max_devs; ++i) {
753 struct exofs_trunc_attr *size_attr = &size_attrs[i]; 775 struct exofs_trunc_attr *size_attr = &size_attrs[i];
@@ -770,7 +792,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
770 size_attr->attr.val_ptr = &size_attr->newsize; 792 size_attr->attr.val_ptr = &size_attr->newsize;
771 793
772 EXOFS_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", 794 EXOFS_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
773 _LLU(ios->obj.id), _LLU(obj_size), i); 795 _LLU(comps->comps->obj.id), _LLU(obj_size), i);
774 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, 796 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
775 &size_attr->attr); 797 &size_attr->attr);
776 if (unlikely(ret)) 798 if (unlikely(ret))