diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2011-09-28 06:18:45 -0400 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2011-10-14 12:54:41 -0400 |
commit | 5a51c0c7e9a913649aa65d8233470682bcbb7694 (patch) | |
tree | 4ed43b3a2f9fade227e098771a5bed66f6a71dc4 | |
parent | 3bd9856857339d7ee8c4ad50030583f1b9415c39 (diff) |
ore/exofs: Define new ore_verify_layout
All users of the ore will need to check if current code
supports the given layout. For example RAID5/6 is not
currently supported.
So move all the checks from exofs/super.c to a new
ore_verify_layout() to be used by ore users.
Note that any new layout should be passed through the
ore_verify_layout() because the ore engine will prepare
and verify some internal members of ore_layout, and
assumes it's called.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
-rw-r--r-- | fs/exofs/inode.c | 9 | ||||
-rw-r--r-- | fs/exofs/ore.c | 67 | ||||
-rw-r--r-- | fs/exofs/super.c | 49 | ||||
-rw-r--r-- | include/scsi/osd_ore.h | 8 |
4 files changed, 80 insertions, 53 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 96366a1d7eae..5a62420cbdb1 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -37,11 +37,7 @@ | |||
37 | 37 | ||
38 | #define EXOFS_DBGMSG2(M...) do {} while (0) | 38 | #define EXOFS_DBGMSG2(M...) do {} while (0) |
39 | 39 | ||
40 | enum { BIO_MAX_PAGES_KMALLOC = | 40 | enum {MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), }; |
41 | (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec), | ||
42 | MAX_PAGES_KMALLOC = | ||
43 | PAGE_SIZE / sizeof(struct page *), | ||
44 | }; | ||
45 | 41 | ||
46 | unsigned exofs_max_io_pages(struct ore_layout *layout, | 42 | unsigned exofs_max_io_pages(struct ore_layout *layout, |
47 | unsigned expected_pages) | 43 | unsigned expected_pages) |
@@ -49,8 +45,7 @@ unsigned exofs_max_io_pages(struct ore_layout *layout, | |||
49 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); | 45 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); |
50 | 46 | ||
51 | /* TODO: easily support bio chaining */ | 47 | /* TODO: easily support bio chaining */ |
52 | pages = min_t(unsigned, pages, | 48 | pages = min_t(unsigned, pages, layout->max_io_length / PAGE_SIZE); |
53 | layout->group_width * BIO_MAX_PAGES_KMALLOC); | ||
54 | return pages; | 49 | return pages; |
55 | } | 50 | } |
56 | 51 | ||
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index f1b718028a1f..4ca59d492798 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -47,9 +47,76 @@ MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); | |||
47 | MODULE_DESCRIPTION("Objects Raid Engine ore.ko"); | 47 | MODULE_DESCRIPTION("Objects Raid Engine ore.ko"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | /* ore_verify_layout does a couple of things: | ||
51 | * 1. Given a minimum number of needed parameters fixes up the rest of the | ||
52 | * members to be operatonals for the ore. The needed parameters are those | ||
53 | * that are defined by the pnfs-objects layout STD. | ||
54 | * 2. Check to see if the current ore code actually supports these parameters | ||
55 | * for example stripe_unit must be a multple of the system PAGE_SIZE, | ||
56 | * and etc... | ||
57 | * 3. Cache some havily used calculations that will be needed by users. | ||
58 | */ | ||
59 | |||
50 | static void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, | 60 | static void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, |
51 | struct ore_striping_info *si); | 61 | struct ore_striping_info *si); |
52 | 62 | ||
63 | enum { BIO_MAX_PAGES_KMALLOC = | ||
64 | (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),}; | ||
65 | |||
66 | int ore_verify_layout(unsigned total_comps, struct ore_layout *layout) | ||
67 | { | ||
68 | u64 stripe_length; | ||
69 | |||
70 | /* FIXME: Only raid0 is supported for now. */ | ||
71 | if (layout->raid_algorithm != PNFS_OSD_RAID_0) { | ||
72 | ORE_ERR("Only RAID_0 for now\n"); | ||
73 | return -EINVAL; | ||
74 | } | ||
75 | if (0 != (layout->stripe_unit & ~PAGE_MASK)) { | ||
76 | ORE_ERR("Stripe Unit(0x%llx)" | ||
77 | " must be Multples of PAGE_SIZE(0x%lx)\n", | ||
78 | _LLU(layout->stripe_unit), PAGE_SIZE); | ||
79 | return -EINVAL; | ||
80 | } | ||
81 | if (layout->group_width) { | ||
82 | if (!layout->group_depth) { | ||
83 | ORE_ERR("group_depth == 0 && group_width != 0\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | if (total_comps < (layout->group_width * layout->mirrors_p1)) { | ||
87 | ORE_ERR("Data Map wrong, " | ||
88 | "numdevs=%d < group_width=%d * mirrors=%d\n", | ||
89 | total_comps, layout->group_width, | ||
90 | layout->mirrors_p1); | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | layout->group_count = total_comps / layout->mirrors_p1 / | ||
94 | layout->group_width; | ||
95 | } else { | ||
96 | if (layout->group_depth) { | ||
97 | printk(KERN_NOTICE "Warning: group_depth ignored " | ||
98 | "group_width == 0 && group_depth == %lld\n", | ||
99 | _LLU(layout->group_depth)); | ||
100 | } | ||
101 | layout->group_width = total_comps / layout->mirrors_p1; | ||
102 | layout->group_depth = -1; | ||
103 | layout->group_count = 1; | ||
104 | } | ||
105 | |||
106 | stripe_length = (u64)layout->group_width * layout->stripe_unit; | ||
107 | if (stripe_length >= (1ULL << 32)) { | ||
108 | ORE_ERR("Stripe_length(0x%llx) >= 32bit is not supported\n", | ||
109 | _LLU(stripe_length)); | ||
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | layout->max_io_length = | ||
114 | (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * | ||
115 | layout->group_width; | ||
116 | return 0; | ||
117 | } | ||
118 | EXPORT_SYMBOL(ore_verify_layout); | ||
119 | |||
53 | static u8 *_ios_cred(struct ore_io_state *ios, unsigned index) | 120 | static u8 *_ios_cred(struct ore_io_state *ios, unsigned index) |
54 | { | 121 | { |
55 | return ios->oc->comps[index & ios->oc->single_comp].cred; | 122 | return ios->oc->comps[index & ios->oc->single_comp].cred; |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index bce3686f0aa0..057b237b8b69 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -480,7 +480,7 @@ static void exofs_put_super(struct super_block *sb) | |||
480 | static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | 480 | static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, |
481 | struct exofs_device_table *dt) | 481 | struct exofs_device_table *dt) |
482 | { | 482 | { |
483 | u64 stripe_length; | 483 | int ret; |
484 | 484 | ||
485 | sbi->layout.stripe_unit = | 485 | sbi->layout.stripe_unit = |
486 | le64_to_cpu(dt->dt_data_map.cb_stripe_unit); | 486 | le64_to_cpu(dt->dt_data_map.cb_stripe_unit); |
@@ -493,50 +493,7 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | |||
493 | sbi->layout.raid_algorithm = | 493 | sbi->layout.raid_algorithm = |
494 | le32_to_cpu(dt->dt_data_map.cb_raid_algorithm); | 494 | le32_to_cpu(dt->dt_data_map.cb_raid_algorithm); |
495 | 495 | ||
496 | /* FIXME: Only raid0 for now. if not so, do not mount */ | 496 | ret = ore_verify_layout(numdevs, &sbi->layout); |
497 | if (sbi->layout.raid_algorithm != PNFS_OSD_RAID_0) { | ||
498 | EXOFS_ERR("Only RAID_0 for now\n"); | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | if (numdevs < (sbi->layout.group_width * sbi->layout.mirrors_p1)) { | ||
502 | EXOFS_ERR("Data Map wrong, " | ||
503 | "numdevs=%d < group_width=%d * mirrors=%d\n", | ||
504 | numdevs, sbi->layout.group_width, | ||
505 | sbi->layout.mirrors_p1); | ||
506 | return -EINVAL; | ||
507 | } | ||
508 | |||
509 | if (0 != (sbi->layout.stripe_unit & ~PAGE_MASK)) { | ||
510 | EXOFS_ERR("Stripe Unit(0x%llx)" | ||
511 | " must be Multples of PAGE_SIZE(0x%lx)\n", | ||
512 | _LLU(sbi->layout.stripe_unit), PAGE_SIZE); | ||
513 | return -EINVAL; | ||
514 | } | ||
515 | |||
516 | if (sbi->layout.group_width) { | ||
517 | if (!sbi->layout.group_depth) { | ||
518 | EXOFS_ERR("group_depth == 0 && group_width != 0\n"); | ||
519 | return -EINVAL; | ||
520 | } | ||
521 | sbi->layout.group_count = numdevs / sbi->layout.mirrors_p1 / | ||
522 | sbi->layout.group_width; | ||
523 | } else { | ||
524 | if (sbi->layout.group_depth) { | ||
525 | printk(KERN_NOTICE "Warning: group_depth ignored " | ||
526 | "group_width == 0 && group_depth == %lld\n", | ||
527 | _LLU(sbi->layout.group_depth)); | ||
528 | } | ||
529 | sbi->layout.group_width = numdevs / sbi->layout.mirrors_p1; | ||
530 | sbi->layout.group_depth = -1; | ||
531 | sbi->layout.group_count = 1; | ||
532 | } | ||
533 | |||
534 | stripe_length = (u64)sbi->layout.group_width * sbi->layout.stripe_unit; | ||
535 | if (stripe_length >= (1ULL << 32)) { | ||
536 | EXOFS_ERR("Total Stripe length(0x%llx)" | ||
537 | " >= 32bit is not supported\n", _LLU(stripe_length)); | ||
538 | return -EINVAL; | ||
539 | } | ||
540 | 497 | ||
541 | EXOFS_DBGMSG("exofs: layout: " | 498 | EXOFS_DBGMSG("exofs: layout: " |
542 | "num_comps=%u stripe_unit=0x%x group_width=%u " | 499 | "num_comps=%u stripe_unit=0x%x group_width=%u " |
@@ -547,7 +504,7 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | |||
547 | _LLU(sbi->layout.group_depth), | 504 | _LLU(sbi->layout.group_depth), |
548 | sbi->layout.mirrors_p1, | 505 | sbi->layout.mirrors_p1, |
549 | sbi->layout.raid_algorithm); | 506 | sbi->layout.raid_algorithm); |
550 | return 0; | 507 | return ret; |
551 | } | 508 | } |
552 | 509 | ||
553 | static unsigned __ra_pages(struct ore_layout *layout) | 510 | static unsigned __ra_pages(struct ore_layout *layout) |
diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h index 492b70d43bb6..716dbeae8cd2 100644 --- a/include/scsi/osd_ore.h +++ b/include/scsi/osd_ore.h | |||
@@ -42,6 +42,13 @@ struct ore_layout { | |||
42 | unsigned group_width; | 42 | unsigned group_width; |
43 | u64 group_depth; | 43 | u64 group_depth; |
44 | unsigned group_count; | 44 | unsigned group_count; |
45 | |||
46 | /* Cached often needed calculations filled in by | ||
47 | * ore_verify_layout | ||
48 | */ | ||
49 | unsigned long max_io_length; /* Max length that should be passed to | ||
50 | * ore_get_rw_state | ||
51 | */ | ||
45 | }; | 52 | }; |
46 | 53 | ||
47 | struct ore_dev { | 54 | struct ore_dev { |
@@ -138,6 +145,7 @@ static inline unsigned ore_io_state_size(unsigned numdevs) | |||
138 | } | 145 | } |
139 | 146 | ||
140 | /* ore.c */ | 147 | /* ore.c */ |
148 | int ore_verify_layout(unsigned total_comps, struct ore_layout *layout); | ||
141 | int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, | 149 | int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, |
142 | bool is_reading, u64 offset, u64 length, | 150 | bool is_reading, u64 offset, u64 length, |
143 | struct ore_io_state **ios); | 151 | struct ore_io_state **ios); |