diff options
| author | Robert Peterson <rpeterso@redhat.com> | 2007-05-10 17:54:38 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-07-09 03:22:14 -0400 |
| commit | 6c53267f05dc6689ff662efeec426d25d2c0ab84 (patch) | |
| tree | af0cfca8828ff5047a23efb31de8ccdaf46f7744 | |
| parent | 7ae8fa8451dfb3879ecbc04f2760a707dc65b988 (diff) | |
[GFS2] Kernel changes to support new gfs2_grow command (part 2)
To avoid code redundancy, I separated out the operational "guts" into
a new function called read_rindex_entry. Then I made two functions:
the closer-to-original gfs2_ri_update (without the special condition
checks) and gfs2_ri_update_special that's designed with that condition
in mind. (I don't like the name, but if you have a suggestion, I'm
all ears).
Oh, and there's an added benefit: we don't need all the ugly gotos
anymore. ;)
This patch has been tested with gfs2_fsck_hellfire (which runs for
three and a half hours, btw).
Signed-off-By: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
| -rw-r--r-- | fs/gfs2/ops_address.c | 3 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 139 |
2 files changed, 93 insertions, 49 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 846c0ff75cff..e0b4e8c2b68d 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
| @@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode) | |||
| 469 | else | 469 | else |
| 470 | new_free = 0; | 470 | new_free = 0; |
| 471 | spin_unlock(&sdp->sd_statfs_spin); | 471 | spin_unlock(&sdp->sd_statfs_spin); |
| 472 | fs_warn(sdp, "File system extended by %llu blocks.\n", new_free); | 472 | fs_warn(sdp, "File system extended by %llu blocks.\n", |
| 473 | (unsigned long long)new_free); | ||
| 473 | gfs2_statfs_change(sdp, new_free, new_free, 0); | 474 | gfs2_statfs_change(sdp, new_free, new_free, 0); |
| 474 | } | 475 | } |
| 475 | 476 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e857f405353b..48a6461d601c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -463,9 +463,62 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) | |||
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | /** | 465 | /** |
| 466 | * gfs2_ri_update - Pull in a new resource index from the disk | 466 | * read_rindex_entry - Pull in a new resource index entry from the disk |
| 467 | * @gl: The glock covering the rindex inode | 467 | * @gl: The glock covering the rindex inode |
| 468 | * | 468 | * |
| 469 | * Returns: 0 on success, error code otherwise | ||
| 470 | */ | ||
| 471 | |||
| 472 | static int read_rindex_entry(struct gfs2_inode *ip, | ||
| 473 | struct file_ra_state *ra_state) | ||
| 474 | { | ||
| 475 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 476 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | ||
| 477 | char buf[sizeof(struct gfs2_rindex)]; | ||
| 478 | int error; | ||
| 479 | struct gfs2_rgrpd *rgd; | ||
| 480 | |||
| 481 | error = gfs2_internal_read(ip, ra_state, buf, &pos, | ||
| 482 | sizeof(struct gfs2_rindex)); | ||
| 483 | if (!error) | ||
| 484 | return 0; | ||
| 485 | if (error != sizeof(struct gfs2_rindex)) { | ||
| 486 | if (error > 0) | ||
| 487 | error = -EIO; | ||
| 488 | return error; | ||
| 489 | } | ||
| 490 | |||
| 491 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | ||
| 492 | error = -ENOMEM; | ||
| 493 | if (!rgd) | ||
| 494 | return error; | ||
| 495 | |||
| 496 | mutex_init(&rgd->rd_mutex); | ||
| 497 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
| 498 | rgd->rd_sbd = sdp; | ||
| 499 | |||
| 500 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
| 501 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
| 502 | |||
| 503 | gfs2_rindex_in(&rgd->rd_ri, buf); | ||
| 504 | error = compute_bitstructs(rgd); | ||
| 505 | if (error) | ||
| 506 | return error; | ||
| 507 | |||
| 508 | error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, | ||
| 509 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | ||
| 510 | if (error) | ||
| 511 | return error; | ||
| 512 | |||
| 513 | rgd->rd_gl->gl_object = rgd; | ||
| 514 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | ||
| 515 | return error; | ||
| 516 | } | ||
| 517 | |||
| 518 | /** | ||
| 519 | * gfs2_ri_update - Pull in a new resource index from the disk | ||
| 520 | * @ip: pointer to the rindex inode | ||
| 521 | * | ||
| 469 | * Returns: 0 on successful update, error code otherwise | 522 | * Returns: 0 on successful update, error code otherwise |
| 470 | */ | 523 | */ |
| 471 | 524 | ||
| @@ -473,18 +526,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
| 473 | { | 526 | { |
| 474 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 527 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
| 475 | struct inode *inode = &ip->i_inode; | 528 | struct inode *inode = &ip->i_inode; |
| 476 | struct gfs2_rgrpd *rgd; | ||
| 477 | char buf[sizeof(struct gfs2_rindex)]; | ||
| 478 | struct file_ra_state ra_state; | 529 | struct file_ra_state ra_state; |
| 479 | u64 junk = ip->i_di.di_size; | 530 | u64 junk = ip->i_di.di_size; |
| 480 | int error; | 531 | int error; |
| 481 | 532 | ||
| 482 | /* If someone is holding the rindex file with a glock, they must | 533 | if (do_div(junk, sizeof(struct gfs2_rindex))) { |
| 483 | be updating it, in which case we may have partial entries. | ||
| 484 | In this case, we ignore the partials. */ | ||
| 485 | if (!gfs2_glock_is_held_excl(ip->i_gl) && | ||
| 486 | !gfs2_glock_is_held_shrd(ip->i_gl) && | ||
| 487 | do_div(junk, sizeof(struct gfs2_rindex))) { | ||
| 488 | gfs2_consist_inode(ip); | 534 | gfs2_consist_inode(ip); |
| 489 | return -EIO; | 535 | return -EIO; |
| 490 | } | 536 | } |
| @@ -493,52 +539,49 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
| 493 | 539 | ||
| 494 | file_ra_state_init(&ra_state, inode->i_mapping); | 540 | file_ra_state_init(&ra_state, inode->i_mapping); |
| 495 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { | 541 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { |
| 496 | loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); | 542 | error = read_rindex_entry(ip, &ra_state); |
| 497 | 543 | if (error) { | |
| 498 | if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) | 544 | clear_rgrpdi(sdp); |
| 499 | break; | 545 | return error; |
| 500 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | ||
| 501 | sizeof(struct gfs2_rindex)); | ||
| 502 | if (!error) | ||
| 503 | break; | ||
| 504 | if (error != sizeof(struct gfs2_rindex)) { | ||
| 505 | if (error > 0) | ||
| 506 | error = -EIO; | ||
| 507 | goto fail; | ||
| 508 | } | 546 | } |
| 547 | } | ||
| 509 | 548 | ||
| 510 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | 549 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; |
| 511 | error = -ENOMEM; | 550 | return 0; |
| 512 | if (!rgd) | 551 | } |
| 513 | goto fail; | ||
| 514 | |||
| 515 | mutex_init(&rgd->rd_mutex); | ||
| 516 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
| 517 | rgd->rd_sbd = sdp; | ||
| 518 | |||
| 519 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
| 520 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
| 521 | |||
| 522 | gfs2_rindex_in(&rgd->rd_ri, buf); | ||
| 523 | error = compute_bitstructs(rgd); | ||
| 524 | if (error) | ||
| 525 | goto fail; | ||
| 526 | 552 | ||
| 527 | error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, | 553 | /** |
| 528 | &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); | 554 | * gfs2_ri_update_special - Pull in a new resource index from the disk |
| 529 | if (error) | 555 | * |
| 530 | goto fail; | 556 | * This is a special version that's safe to call from gfs2_inplace_reserve_i. |
| 557 | * In this case we know that we don't have any resource groups in memory yet. | ||
| 558 | * | ||
| 559 | * @ip: pointer to the rindex inode | ||
| 560 | * | ||
| 561 | * Returns: 0 on successful update, error code otherwise | ||
| 562 | */ | ||
| 563 | static int gfs2_ri_update_special(struct gfs2_inode *ip) | ||
| 564 | { | ||
| 565 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 566 | struct inode *inode = &ip->i_inode; | ||
| 567 | struct file_ra_state ra_state; | ||
| 568 | int error; | ||
| 531 | 569 | ||
| 532 | rgd->rd_gl->gl_object = rgd; | 570 | file_ra_state_init(&ra_state, inode->i_mapping); |
| 533 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | 571 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { |
| 572 | /* Ignore partials */ | ||
| 573 | if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > | ||
| 574 | ip->i_di.di_size) | ||
| 575 | break; | ||
| 576 | error = read_rindex_entry(ip, &ra_state); | ||
| 577 | if (error) { | ||
| 578 | clear_rgrpdi(sdp); | ||
| 579 | return error; | ||
| 580 | } | ||
| 534 | } | 581 | } |
| 535 | 582 | ||
| 536 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; | 583 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; |
| 537 | return 0; | 584 | return 0; |
| 538 | |||
| 539 | fail: | ||
| 540 | clear_rgrpdi(sdp); | ||
| 541 | return error; | ||
| 542 | } | 585 | } |
| 543 | 586 | ||
| 544 | /** | 587 | /** |
| @@ -1028,7 +1071,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) | |||
| 1028 | if (ip != GFS2_I(sdp->sd_rindex)) | 1071 | if (ip != GFS2_I(sdp->sd_rindex)) |
| 1029 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | 1072 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); |
| 1030 | else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ | 1073 | else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ |
| 1031 | error = gfs2_ri_update(ip); | 1074 | error = gfs2_ri_update_special(ip); |
| 1032 | 1075 | ||
| 1033 | if (error) | 1076 | if (error) |
| 1034 | return error; | 1077 | return error; |
