diff options
Diffstat (limited to 'fs/exofs/super.c')
-rw-r--r-- | fs/exofs/super.c | 121 |
1 files changed, 90 insertions, 31 deletions
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index a1d1e77b12eb..6cf5e4e84d61 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -210,7 +210,7 @@ int exofs_sync_fs(struct super_block *sb, int wait) | |||
210 | sbi = sb->s_fs_info; | 210 | sbi = sb->s_fs_info; |
211 | fscb = &sbi->s_fscb; | 211 | fscb = &sbi->s_fscb; |
212 | 212 | ||
213 | ret = exofs_get_io_state(sbi, &ios); | 213 | ret = exofs_get_io_state(&sbi->layout, &ios); |
214 | if (ret) | 214 | if (ret) |
215 | goto out; | 215 | goto out; |
216 | 216 | ||
@@ -264,12 +264,12 @@ static void _exofs_print_device(const char *msg, const char *dev_path, | |||
264 | 264 | ||
265 | void exofs_free_sbi(struct exofs_sb_info *sbi) | 265 | void exofs_free_sbi(struct exofs_sb_info *sbi) |
266 | { | 266 | { |
267 | while (sbi->s_numdevs) { | 267 | while (sbi->layout.s_numdevs) { |
268 | int i = --sbi->s_numdevs; | 268 | int i = --sbi->layout.s_numdevs; |
269 | struct osd_dev *od = sbi->s_ods[i]; | 269 | struct osd_dev *od = sbi->layout.s_ods[i]; |
270 | 270 | ||
271 | if (od) { | 271 | if (od) { |
272 | sbi->s_ods[i] = NULL; | 272 | sbi->layout.s_ods[i] = NULL; |
273 | osduld_put_device(od); | 273 | osduld_put_device(od); |
274 | } | 274 | } |
275 | } | 275 | } |
@@ -298,7 +298,8 @@ static void exofs_put_super(struct super_block *sb) | |||
298 | msecs_to_jiffies(100)); | 298 | msecs_to_jiffies(100)); |
299 | } | 299 | } |
300 | 300 | ||
301 | _exofs_print_device("Unmounting", NULL, sbi->s_ods[0], sbi->s_pid); | 301 | _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], |
302 | sbi->layout.s_pid); | ||
302 | 303 | ||
303 | exofs_free_sbi(sbi); | 304 | exofs_free_sbi(sbi); |
304 | sb->s_fs_info = NULL; | 305 | sb->s_fs_info = NULL; |
@@ -307,6 +308,8 @@ static void exofs_put_super(struct super_block *sb) | |||
307 | static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | 308 | static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, |
308 | struct exofs_device_table *dt) | 309 | struct exofs_device_table *dt) |
309 | { | 310 | { |
311 | u64 stripe_length; | ||
312 | |||
310 | sbi->data_map.odm_num_comps = | 313 | sbi->data_map.odm_num_comps = |
311 | le32_to_cpu(dt->dt_data_map.cb_num_comps); | 314 | le32_to_cpu(dt->dt_data_map.cb_num_comps); |
312 | sbi->data_map.odm_stripe_unit = | 315 | sbi->data_map.odm_stripe_unit = |
@@ -320,14 +323,63 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | |||
320 | sbi->data_map.odm_raid_algorithm = | 323 | sbi->data_map.odm_raid_algorithm = |
321 | le32_to_cpu(dt->dt_data_map.cb_raid_algorithm); | 324 | le32_to_cpu(dt->dt_data_map.cb_raid_algorithm); |
322 | 325 | ||
323 | /* FIXME: Hard coded mirror only for now. if not so do not mount */ | 326 | /* FIXME: Only raid0 for now. if not so, do not mount */ |
324 | if ((sbi->data_map.odm_num_comps != numdevs) || | 327 | if (sbi->data_map.odm_num_comps != numdevs) { |
325 | (sbi->data_map.odm_stripe_unit != EXOFS_BLKSIZE) || | 328 | EXOFS_ERR("odm_num_comps(%u) != numdevs(%u)\n", |
326 | (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) || | 329 | sbi->data_map.odm_num_comps, numdevs); |
327 | (sbi->data_map.odm_mirror_cnt != (numdevs - 1))) | ||
328 | return -EINVAL; | 330 | return -EINVAL; |
329 | else | 331 | } |
330 | return 0; | 332 | if (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) { |
333 | EXOFS_ERR("Only RAID_0 for now\n"); | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | if (0 != (numdevs % (sbi->data_map.odm_mirror_cnt + 1))) { | ||
337 | EXOFS_ERR("Data Map wrong, numdevs=%d mirrors=%d\n", | ||
338 | numdevs, sbi->data_map.odm_mirror_cnt); | ||
339 | return -EINVAL; | ||
340 | } | ||
341 | |||
342 | if (0 != (sbi->data_map.odm_stripe_unit & ~PAGE_MASK)) { | ||
343 | EXOFS_ERR("Stripe Unit(0x%llx)" | ||
344 | " must be Multples of PAGE_SIZE(0x%lx)\n", | ||
345 | _LLU(sbi->data_map.odm_stripe_unit), PAGE_SIZE); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | sbi->layout.stripe_unit = sbi->data_map.odm_stripe_unit; | ||
350 | sbi->layout.mirrors_p1 = sbi->data_map.odm_mirror_cnt + 1; | ||
351 | |||
352 | if (sbi->data_map.odm_group_width) { | ||
353 | sbi->layout.group_width = sbi->data_map.odm_group_width; | ||
354 | sbi->layout.group_depth = sbi->data_map.odm_group_depth; | ||
355 | if (!sbi->layout.group_depth) { | ||
356 | EXOFS_ERR("group_depth == 0 && group_width != 0\n"); | ||
357 | return -EINVAL; | ||
358 | } | ||
359 | sbi->layout.group_count = sbi->data_map.odm_num_comps / | ||
360 | sbi->layout.mirrors_p1 / | ||
361 | sbi->data_map.odm_group_width; | ||
362 | } else { | ||
363 | if (sbi->data_map.odm_group_depth) { | ||
364 | printk(KERN_NOTICE "Warning: group_depth ignored " | ||
365 | "group_width == 0 && group_depth == %d\n", | ||
366 | sbi->data_map.odm_group_depth); | ||
367 | sbi->data_map.odm_group_depth = 0; | ||
368 | } | ||
369 | sbi->layout.group_width = sbi->data_map.odm_num_comps / | ||
370 | sbi->layout.mirrors_p1; | ||
371 | sbi->layout.group_depth = -1; | ||
372 | sbi->layout.group_count = 1; | ||
373 | } | ||
374 | |||
375 | stripe_length = (u64)sbi->layout.group_width * sbi->layout.stripe_unit; | ||
376 | if (stripe_length >= (1ULL << 32)) { | ||
377 | EXOFS_ERR("Total Stripe length(0x%llx)" | ||
378 | " >= 32bit is not supported\n", _LLU(stripe_length)); | ||
379 | return -EINVAL; | ||
380 | } | ||
381 | |||
382 | return 0; | ||
331 | } | 383 | } |
332 | 384 | ||
333 | /* @odi is valid only as long as @fscb_dev is valid */ | 385 | /* @odi is valid only as long as @fscb_dev is valid */ |
@@ -361,7 +413,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, | |||
361 | { | 413 | { |
362 | struct exofs_sb_info *sbi = *psbi; | 414 | struct exofs_sb_info *sbi = *psbi; |
363 | struct osd_dev *fscb_od; | 415 | struct osd_dev *fscb_od; |
364 | struct osd_obj_id obj = {.partition = sbi->s_pid, | 416 | struct osd_obj_id obj = {.partition = sbi->layout.s_pid, |
365 | .id = EXOFS_DEVTABLE_ID}; | 417 | .id = EXOFS_DEVTABLE_ID}; |
366 | struct exofs_device_table *dt; | 418 | struct exofs_device_table *dt; |
367 | unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + | 419 | unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + |
@@ -376,9 +428,9 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, | |||
376 | return -ENOMEM; | 428 | return -ENOMEM; |
377 | } | 429 | } |
378 | 430 | ||
379 | fscb_od = sbi->s_ods[0]; | 431 | fscb_od = sbi->layout.s_ods[0]; |
380 | sbi->s_ods[0] = NULL; | 432 | sbi->layout.s_ods[0] = NULL; |
381 | sbi->s_numdevs = 0; | 433 | sbi->layout.s_numdevs = 0; |
382 | ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); | 434 | ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); |
383 | if (unlikely(ret)) { | 435 | if (unlikely(ret)) { |
384 | EXOFS_ERR("ERROR: reading device table\n"); | 436 | EXOFS_ERR("ERROR: reading device table\n"); |
@@ -397,14 +449,15 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, | |||
397 | goto out; | 449 | goto out; |
398 | 450 | ||
399 | if (likely(numdevs > 1)) { | 451 | if (likely(numdevs > 1)) { |
400 | unsigned size = numdevs * sizeof(sbi->s_ods[0]); | 452 | unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]); |
401 | 453 | ||
402 | sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL); | 454 | sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL); |
403 | if (unlikely(!sbi)) { | 455 | if (unlikely(!sbi)) { |
404 | ret = -ENOMEM; | 456 | ret = -ENOMEM; |
405 | goto out; | 457 | goto out; |
406 | } | 458 | } |
407 | memset(&sbi->s_ods[1], 0, size - sizeof(sbi->s_ods[0])); | 459 | memset(&sbi->layout.s_ods[1], 0, |
460 | size - sizeof(sbi->layout.s_ods[0])); | ||
408 | *psbi = sbi; | 461 | *psbi = sbi; |
409 | } | 462 | } |
410 | 463 | ||
@@ -427,8 +480,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, | |||
427 | * line. We always keep them in device-table order. | 480 | * line. We always keep them in device-table order. |
428 | */ | 481 | */ |
429 | if (fscb_od && osduld_device_same(fscb_od, &odi)) { | 482 | if (fscb_od && osduld_device_same(fscb_od, &odi)) { |
430 | sbi->s_ods[i] = fscb_od; | 483 | sbi->layout.s_ods[i] = fscb_od; |
431 | ++sbi->s_numdevs; | 484 | ++sbi->layout.s_numdevs; |
432 | fscb_od = NULL; | 485 | fscb_od = NULL; |
433 | continue; | 486 | continue; |
434 | } | 487 | } |
@@ -441,8 +494,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, | |||
441 | goto out; | 494 | goto out; |
442 | } | 495 | } |
443 | 496 | ||
444 | sbi->s_ods[i] = od; | 497 | sbi->layout.s_ods[i] = od; |
445 | ++sbi->s_numdevs; | 498 | ++sbi->layout.s_numdevs; |
446 | 499 | ||
447 | /* Read the fscb of the other devices to make sure the FS | 500 | /* Read the fscb of the other devices to make sure the FS |
448 | * partition is there. | 501 | * partition is there. |
@@ -499,9 +552,15 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
499 | goto free_sbi; | 552 | goto free_sbi; |
500 | } | 553 | } |
501 | 554 | ||
502 | sbi->s_ods[0] = od; | 555 | /* Default layout in case we do not have a device-table */ |
503 | sbi->s_numdevs = 1; | 556 | sbi->layout.stripe_unit = PAGE_SIZE; |
504 | sbi->s_pid = opts->pid; | 557 | sbi->layout.mirrors_p1 = 1; |
558 | sbi->layout.group_width = 1; | ||
559 | sbi->layout.group_depth = -1; | ||
560 | sbi->layout.group_count = 1; | ||
561 | sbi->layout.s_ods[0] = od; | ||
562 | sbi->layout.s_numdevs = 1; | ||
563 | sbi->layout.s_pid = opts->pid; | ||
505 | sbi->s_timeout = opts->timeout; | 564 | sbi->s_timeout = opts->timeout; |
506 | 565 | ||
507 | /* fill in some other data by hand */ | 566 | /* fill in some other data by hand */ |
@@ -514,7 +573,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
514 | sb->s_bdev = NULL; | 573 | sb->s_bdev = NULL; |
515 | sb->s_dev = 0; | 574 | sb->s_dev = 0; |
516 | 575 | ||
517 | obj.partition = sbi->s_pid; | 576 | obj.partition = sbi->layout.s_pid; |
518 | obj.id = EXOFS_SUPER_ID; | 577 | obj.id = EXOFS_SUPER_ID; |
519 | exofs_make_credential(sbi->s_cred, &obj); | 578 | exofs_make_credential(sbi->s_cred, &obj); |
520 | 579 | ||
@@ -578,13 +637,13 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
578 | goto free_sbi; | 637 | goto free_sbi; |
579 | } | 638 | } |
580 | 639 | ||
581 | _exofs_print_device("Mounting", opts->dev_name, sbi->s_ods[0], | 640 | _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0], |
582 | sbi->s_pid); | 641 | sbi->layout.s_pid); |
583 | return 0; | 642 | return 0; |
584 | 643 | ||
585 | free_sbi: | 644 | free_sbi: |
586 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", | 645 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", |
587 | opts->dev_name, sbi->s_pid, ret); | 646 | opts->dev_name, sbi->layout.s_pid, ret); |
588 | exofs_free_sbi(sbi); | 647 | exofs_free_sbi(sbi); |
589 | return ret; | 648 | return ret; |
590 | } | 649 | } |
@@ -627,7 +686,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
627 | uint8_t cred_a[OSD_CAP_LEN]; | 686 | uint8_t cred_a[OSD_CAP_LEN]; |
628 | int ret; | 687 | int ret; |
629 | 688 | ||
630 | ret = exofs_get_io_state(sbi, &ios); | 689 | ret = exofs_get_io_state(&sbi->layout, &ios); |
631 | if (ret) { | 690 | if (ret) { |
632 | EXOFS_DBGMSG("exofs_get_io_state failed.\n"); | 691 | EXOFS_DBGMSG("exofs_get_io_state failed.\n"); |
633 | return ret; | 692 | return ret; |