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; |
