aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-09-28 06:18:45 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-10-14 12:54:41 -0400
commit5a51c0c7e9a913649aa65d8233470682bcbb7694 (patch)
tree4ed43b3a2f9fade227e098771a5bed66f6a71dc4
parent3bd9856857339d7ee8c4ad50030583f1b9415c39 (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.c9
-rw-r--r--fs/exofs/ore.c67
-rw-r--r--fs/exofs/super.c49
-rw-r--r--include/scsi/osd_ore.h8
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
40enum { BIO_MAX_PAGES_KMALLOC = 40enum {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
46unsigned exofs_max_io_pages(struct ore_layout *layout, 42unsigned 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>");
47MODULE_DESCRIPTION("Objects Raid Engine ore.ko"); 47MODULE_DESCRIPTION("Objects Raid Engine ore.ko");
48MODULE_LICENSE("GPL"); 48MODULE_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
50static void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, 60static 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
63enum { BIO_MAX_PAGES_KMALLOC =
64 (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),};
65
66int 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}
118EXPORT_SYMBOL(ore_verify_layout);
119
53static u8 *_ios_cred(struct ore_io_state *ios, unsigned index) 120static 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)
480static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, 480static 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
553static unsigned __ra_pages(struct ore_layout *layout) 510static 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
47struct ore_dev { 54struct 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 */
148int ore_verify_layout(unsigned total_comps, struct ore_layout *layout);
141int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, 149int 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);