aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorRobert Peterson <rpeterso@redhat.com>2007-05-10 17:54:38 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:22:14 -0400
commit6c53267f05dc6689ff662efeec426d25d2c0ab84 (patch)
treeaf0cfca8828ff5047a23efb31de8ccdaf46f7744 /fs/gfs2/rgrp.c
parent7ae8fa8451dfb3879ecbc04f2760a707dc65b988 (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>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c139
1 files changed, 91 insertions, 48 deletions
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
472static 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 */
563static 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
539fail:
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;