aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exofs/super.c')
-rw-r--r--fs/exofs/super.c130
1 files changed, 99 insertions, 31 deletions
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index a1d1e77b12eb..03149b9a5178 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -37,6 +37,7 @@
37#include <linux/vfs.h> 37#include <linux/vfs.h>
38#include <linux/random.h> 38#include <linux/random.h>
39#include <linux/exportfs.h> 39#include <linux/exportfs.h>
40#include <linux/slab.h>
40 41
41#include "exofs.h" 42#include "exofs.h"
42 43
@@ -210,7 +211,7 @@ int exofs_sync_fs(struct super_block *sb, int wait)
210 sbi = sb->s_fs_info; 211 sbi = sb->s_fs_info;
211 fscb = &sbi->s_fscb; 212 fscb = &sbi->s_fscb;
212 213
213 ret = exofs_get_io_state(sbi, &ios); 214 ret = exofs_get_io_state(&sbi->layout, &ios);
214 if (ret) 215 if (ret)
215 goto out; 216 goto out;
216 217
@@ -264,12 +265,12 @@ static void _exofs_print_device(const char *msg, const char *dev_path,
264 265
265void exofs_free_sbi(struct exofs_sb_info *sbi) 266void exofs_free_sbi(struct exofs_sb_info *sbi)
266{ 267{
267 while (sbi->s_numdevs) { 268 while (sbi->layout.s_numdevs) {
268 int i = --sbi->s_numdevs; 269 int i = --sbi->layout.s_numdevs;
269 struct osd_dev *od = sbi->s_ods[i]; 270 struct osd_dev *od = sbi->layout.s_ods[i];
270 271
271 if (od) { 272 if (od) {
272 sbi->s_ods[i] = NULL; 273 sbi->layout.s_ods[i] = NULL;
273 osduld_put_device(od); 274 osduld_put_device(od);
274 } 275 }
275 } 276 }
@@ -298,8 +299,10 @@ static void exofs_put_super(struct super_block *sb)
298 msecs_to_jiffies(100)); 299 msecs_to_jiffies(100));
299 } 300 }
300 301
301 _exofs_print_device("Unmounting", NULL, sbi->s_ods[0], sbi->s_pid); 302 _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
303 sbi->layout.s_pid);
302 304
305 bdi_destroy(&sbi->bdi);
303 exofs_free_sbi(sbi); 306 exofs_free_sbi(sbi);
304 sb->s_fs_info = NULL; 307 sb->s_fs_info = NULL;
305} 308}
@@ -307,6 +310,8 @@ static void exofs_put_super(struct super_block *sb)
307static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, 310static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
308 struct exofs_device_table *dt) 311 struct exofs_device_table *dt)
309{ 312{
313 u64 stripe_length;
314
310 sbi->data_map.odm_num_comps = 315 sbi->data_map.odm_num_comps =
311 le32_to_cpu(dt->dt_data_map.cb_num_comps); 316 le32_to_cpu(dt->dt_data_map.cb_num_comps);
312 sbi->data_map.odm_stripe_unit = 317 sbi->data_map.odm_stripe_unit =
@@ -320,14 +325,63 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
320 sbi->data_map.odm_raid_algorithm = 325 sbi->data_map.odm_raid_algorithm =
321 le32_to_cpu(dt->dt_data_map.cb_raid_algorithm); 326 le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
322 327
323/* FIXME: Hard coded mirror only for now. if not so do not mount */ 328/* FIXME: Only raid0 for now. if not so, do not mount */
324 if ((sbi->data_map.odm_num_comps != numdevs) || 329 if (sbi->data_map.odm_num_comps != numdevs) {
325 (sbi->data_map.odm_stripe_unit != EXOFS_BLKSIZE) || 330 EXOFS_ERR("odm_num_comps(%u) != numdevs(%u)\n",
326 (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) || 331 sbi->data_map.odm_num_comps, numdevs);
327 (sbi->data_map.odm_mirror_cnt != (numdevs - 1)))
328 return -EINVAL; 332 return -EINVAL;
329 else 333 }
330 return 0; 334 if (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) {
335 EXOFS_ERR("Only RAID_0 for now\n");
336 return -EINVAL;
337 }
338 if (0 != (numdevs % (sbi->data_map.odm_mirror_cnt + 1))) {
339 EXOFS_ERR("Data Map wrong, numdevs=%d mirrors=%d\n",
340 numdevs, sbi->data_map.odm_mirror_cnt);
341 return -EINVAL;
342 }
343
344 if (0 != (sbi->data_map.odm_stripe_unit & ~PAGE_MASK)) {
345 EXOFS_ERR("Stripe Unit(0x%llx)"
346 " must be Multples of PAGE_SIZE(0x%lx)\n",
347 _LLU(sbi->data_map.odm_stripe_unit), PAGE_SIZE);
348 return -EINVAL;
349 }
350
351 sbi->layout.stripe_unit = sbi->data_map.odm_stripe_unit;
352 sbi->layout.mirrors_p1 = sbi->data_map.odm_mirror_cnt + 1;
353
354 if (sbi->data_map.odm_group_width) {
355 sbi->layout.group_width = sbi->data_map.odm_group_width;
356 sbi->layout.group_depth = sbi->data_map.odm_group_depth;
357 if (!sbi->layout.group_depth) {
358 EXOFS_ERR("group_depth == 0 && group_width != 0\n");
359 return -EINVAL;
360 }
361 sbi->layout.group_count = sbi->data_map.odm_num_comps /
362 sbi->layout.mirrors_p1 /
363 sbi->data_map.odm_group_width;
364 } else {
365 if (sbi->data_map.odm_group_depth) {
366 printk(KERN_NOTICE "Warning: group_depth ignored "
367 "group_width == 0 && group_depth == %d\n",
368 sbi->data_map.odm_group_depth);
369 sbi->data_map.odm_group_depth = 0;
370 }
371 sbi->layout.group_width = sbi->data_map.odm_num_comps /
372 sbi->layout.mirrors_p1;
373 sbi->layout.group_depth = -1;
374 sbi->layout.group_count = 1;
375 }
376
377 stripe_length = (u64)sbi->layout.group_width * sbi->layout.stripe_unit;
378 if (stripe_length >= (1ULL << 32)) {
379 EXOFS_ERR("Total Stripe length(0x%llx)"
380 " >= 32bit is not supported\n", _LLU(stripe_length));
381 return -EINVAL;
382 }
383
384 return 0;
331} 385}
332 386
333/* @odi is valid only as long as @fscb_dev is valid */ 387/* @odi is valid only as long as @fscb_dev is valid */
@@ -361,7 +415,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
361{ 415{
362 struct exofs_sb_info *sbi = *psbi; 416 struct exofs_sb_info *sbi = *psbi;
363 struct osd_dev *fscb_od; 417 struct osd_dev *fscb_od;
364 struct osd_obj_id obj = {.partition = sbi->s_pid, 418 struct osd_obj_id obj = {.partition = sbi->layout.s_pid,
365 .id = EXOFS_DEVTABLE_ID}; 419 .id = EXOFS_DEVTABLE_ID};
366 struct exofs_device_table *dt; 420 struct exofs_device_table *dt;
367 unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + 421 unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
@@ -376,9 +430,9 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
376 return -ENOMEM; 430 return -ENOMEM;
377 } 431 }
378 432
379 fscb_od = sbi->s_ods[0]; 433 fscb_od = sbi->layout.s_ods[0];
380 sbi->s_ods[0] = NULL; 434 sbi->layout.s_ods[0] = NULL;
381 sbi->s_numdevs = 0; 435 sbi->layout.s_numdevs = 0;
382 ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); 436 ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes);
383 if (unlikely(ret)) { 437 if (unlikely(ret)) {
384 EXOFS_ERR("ERROR: reading device table\n"); 438 EXOFS_ERR("ERROR: reading device table\n");
@@ -397,14 +451,15 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
397 goto out; 451 goto out;
398 452
399 if (likely(numdevs > 1)) { 453 if (likely(numdevs > 1)) {
400 unsigned size = numdevs * sizeof(sbi->s_ods[0]); 454 unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]);
401 455
402 sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL); 456 sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL);
403 if (unlikely(!sbi)) { 457 if (unlikely(!sbi)) {
404 ret = -ENOMEM; 458 ret = -ENOMEM;
405 goto out; 459 goto out;
406 } 460 }
407 memset(&sbi->s_ods[1], 0, size - sizeof(sbi->s_ods[0])); 461 memset(&sbi->layout.s_ods[1], 0,
462 size - sizeof(sbi->layout.s_ods[0]));
408 *psbi = sbi; 463 *psbi = sbi;
409 } 464 }
410 465
@@ -427,8 +482,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
427 * line. We always keep them in device-table order. 482 * line. We always keep them in device-table order.
428 */ 483 */
429 if (fscb_od && osduld_device_same(fscb_od, &odi)) { 484 if (fscb_od && osduld_device_same(fscb_od, &odi)) {
430 sbi->s_ods[i] = fscb_od; 485 sbi->layout.s_ods[i] = fscb_od;
431 ++sbi->s_numdevs; 486 ++sbi->layout.s_numdevs;
432 fscb_od = NULL; 487 fscb_od = NULL;
433 continue; 488 continue;
434 } 489 }
@@ -441,8 +496,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
441 goto out; 496 goto out;
442 } 497 }
443 498
444 sbi->s_ods[i] = od; 499 sbi->layout.s_ods[i] = od;
445 ++sbi->s_numdevs; 500 ++sbi->layout.s_numdevs;
446 501
447 /* Read the fscb of the other devices to make sure the FS 502 /* Read the fscb of the other devices to make sure the FS
448 * partition is there. 503 * partition is there.
@@ -492,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
492 if (!sbi) 547 if (!sbi)
493 return -ENOMEM; 548 return -ENOMEM;
494 549
550 ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
551 if (ret)
552 goto free_bdi;
553
495 /* use mount options to fill superblock */ 554 /* use mount options to fill superblock */
496 od = osduld_path_lookup(opts->dev_name); 555 od = osduld_path_lookup(opts->dev_name);
497 if (IS_ERR(od)) { 556 if (IS_ERR(od)) {
@@ -499,9 +558,15 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
499 goto free_sbi; 558 goto free_sbi;
500 } 559 }
501 560
502 sbi->s_ods[0] = od; 561 /* Default layout in case we do not have a device-table */
503 sbi->s_numdevs = 1; 562 sbi->layout.stripe_unit = PAGE_SIZE;
504 sbi->s_pid = opts->pid; 563 sbi->layout.mirrors_p1 = 1;
564 sbi->layout.group_width = 1;
565 sbi->layout.group_depth = -1;
566 sbi->layout.group_count = 1;
567 sbi->layout.s_ods[0] = od;
568 sbi->layout.s_numdevs = 1;
569 sbi->layout.s_pid = opts->pid;
505 sbi->s_timeout = opts->timeout; 570 sbi->s_timeout = opts->timeout;
506 571
507 /* fill in some other data by hand */ 572 /* fill in some other data by hand */
@@ -514,7 +579,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
514 sb->s_bdev = NULL; 579 sb->s_bdev = NULL;
515 sb->s_dev = 0; 580 sb->s_dev = 0;
516 581
517 obj.partition = sbi->s_pid; 582 obj.partition = sbi->layout.s_pid;
518 obj.id = EXOFS_SUPER_ID; 583 obj.id = EXOFS_SUPER_ID;
519 exofs_make_credential(sbi->s_cred, &obj); 584 exofs_make_credential(sbi->s_cred, &obj);
520 585
@@ -552,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
552 } 617 }
553 618
554 /* set up operation vectors */ 619 /* set up operation vectors */
620 sb->s_bdi = &sbi->bdi;
555 sb->s_fs_info = sbi; 621 sb->s_fs_info = sbi;
556 sb->s_op = &exofs_sops; 622 sb->s_op = &exofs_sops;
557 sb->s_export_op = &exofs_export_ops; 623 sb->s_export_op = &exofs_export_ops;
@@ -578,13 +644,15 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
578 goto free_sbi; 644 goto free_sbi;
579 } 645 }
580 646
581 _exofs_print_device("Mounting", opts->dev_name, sbi->s_ods[0], 647 _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0],
582 sbi->s_pid); 648 sbi->layout.s_pid);
583 return 0; 649 return 0;
584 650
585free_sbi: 651free_sbi:
652 bdi_destroy(&sbi->bdi);
653free_bdi:
586 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", 654 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
587 opts->dev_name, sbi->s_pid, ret); 655 opts->dev_name, sbi->layout.s_pid, ret);
588 exofs_free_sbi(sbi); 656 exofs_free_sbi(sbi);
589 return ret; 657 return ret;
590} 658}
@@ -627,7 +695,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
627 uint8_t cred_a[OSD_CAP_LEN]; 695 uint8_t cred_a[OSD_CAP_LEN];
628 int ret; 696 int ret;
629 697
630 ret = exofs_get_io_state(sbi, &ios); 698 ret = exofs_get_io_state(&sbi->layout, &ios);
631 if (ret) { 699 if (ret) {
632 EXOFS_DBGMSG("exofs_get_io_state failed.\n"); 700 EXOFS_DBGMSG("exofs_get_io_state failed.\n");
633 return ret; 701 return ret;