Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
List overview
Download
cluster-commits
January 2010
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
cluster-commits@lists.stg.fedorahosted.org
7 participants
186 discussions
Start a n
N
ew thread
cluster: STABLE3 - gfs2: Remove buf_lists
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a0…
Commit: a099128a0f504eca010cb7435a740830ce272153 Parent: 71fb85ae21db98d08128ff27ca4c17ac7dd4139d Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Tue Jan 19 15:05:52 2010 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:28 2010 -0600 gfs2: Remove buf_lists This patch removes once and for all the linked lists of buffer_heads attached to the superblock. We should trust that the vfs layer of the kernel is going to keep the blocks we most want in memory rather than trying to do it in user space. While this was likely put in place for performance reasons, it actually performs better with vfs managing the buffers because we ended up spending too much time searching through the linked lists for the buffer we need to use. rhbz#455300 --- gfs2/convert/gfs2_convert.c | 22 ++--- gfs2/edit/gfs2hex.c | 2 +- gfs2/edit/hexedit.c | 47 ++++----- gfs2/edit/savemeta.c | 25 +++-- gfs2/fsck/fs_recovery.c | 8 +- gfs2/fsck/initialize.c | 1 - gfs2/fsck/main.c | 10 +-- gfs2/fsck/metawalk.c | 12 +-- gfs2/fsck/pass1.c | 8 +- gfs2/fsck/pass1b.c | 6 +- gfs2/fsck/pass1c.c | 6 +- gfs2/fsck/pass2.c | 6 +- gfs2/fsck/pass3.c | 1 - gfs2/fsck/rgrepair.c | 10 +- gfs2/libgfs2/buf.c | 229 +++++------------------------------------- gfs2/libgfs2/fs_geometry.c | 2 +- gfs2/libgfs2/fs_ops.c | 47 +++++----- gfs2/libgfs2/gfs1.c | 8 +- gfs2/libgfs2/libgfs2.h | 38 ++----- gfs2/libgfs2/recovery.c | 4 +- gfs2/libgfs2/rgrp.c | 2 +- gfs2/libgfs2/structures.c | 6 +- gfs2/libgfs2/super.c | 6 +- gfs2/mkfs/main_grow.c | 3 +- gfs2/mkfs/main_mkfs.c | 4 - 25 files changed, 152 insertions(+), 361 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 02bd9b9..2e10496 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -320,7 +320,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, if (!block) break; - bh = bread(&sbp->buf_list, block); + bh = bread(sbp, block); if (new) memset(bh->b_data, 0, sbp->bsize); gfs2_meta_header_out(&mh, bh); @@ -493,7 +493,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_inode *ip) osi_list_add_prev(&newblk->list, &blocks.list); /* read the new metadata block's pointers */ - bh = bread(&sbp->buf_list, block); + bh = bread(sbp, block); memcpy(newblk->ptrbuf, bh->b_data + sizeof(struct gfs_indirect), bufsize); /* Zero the buffer so we can fill it in later */ @@ -721,7 +721,7 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) sbp->sd_sb.sb_root_dir.no_addr = block; sbp->sd_sb.sb_root_dir.no_formal_ino = sbp->md.next_inum; } - bh = bread(&sbp->buf_list, block); + bh = bread(sbp, block); if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) /* if it is an dinode */ error = adjust_inode(sbp, bh); else { /* It's metadata, but not an inode, so fix the bitmap. */ @@ -1076,13 +1076,12 @@ static int init(struct gfs2_sbd *sbp) sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; sbp->bsize = sbp->sd_sb.sb_bsize; osi_list_init(&sbp->rglist); - init_buf_list(sbp, &sbp->buf_list, 1 << 20); /* only use 1MB of bufs */ if (compute_constants(sbp)) { log_crit("Error: Bad constants (1)\n"); exit(-1); } - bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); + bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data, sizeof(struct gfs1_sb)); gfs2_sb_in(&sbp->sd_sb, bh); @@ -1370,7 +1369,7 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) return -1; } for (x = 0; x < rgd->ri.ri_length; x++) { - rgd->bh[x] = bget(&sdp->buf_list, rgd->ri.ri_addr + x); + rgd->bh[x] = bget(sdp, rgd->ri.ri_addr + x); memset(rgd->bh[x]->b_data, 0, sdp->bsize); } if (gfs2_compute_bitstructs(sdp, rgd)) { @@ -1527,7 +1526,7 @@ int main(int argc, char **argv) if (error) log_crit("%s: Unable to convert resource groups.\n", device); - bcommit(&sb2.buf_list); /* write the buffers to disk */ + fsync(sb2.device_fd); /* write the buffers to disk */ } /* ---------------------------------------------- */ /* Renumber the inodes consecutively. */ @@ -1536,7 +1535,7 @@ int main(int argc, char **argv) error = inode_renumber(&sb2, sb2.sd_sb.sb_root_dir.no_addr); if (error) log_crit("\n%s: Error renumbering inodes.\n", device); - bcommit(&sb2.buf_list); /* write the buffers to disk */ + fsync(sb2.device_fd); /* write the buffers to disk */ } /* ---------------------------------------------- */ /* Fix the directories to match the new numbers. */ @@ -1557,7 +1556,7 @@ int main(int argc, char **argv) error = journ_space_to_rg(&sb2); if (error) log_crit("%s: Error converting journal space.\n", device); - bcommit(&sb2.buf_list); /* write the buffers to disk */ + fsync(sb2.device_fd); /* write the buffers to disk */ } /* ---------------------------------------------- */ /* Create our system files and directories. */ @@ -1594,7 +1593,7 @@ int main(int argc, char **argv) inode_put(&sb2.md.inum); inode_put(&sb2.md.statfs); - bcommit(&sb2.buf_list); /* write the buffers to disk */ + fsync(sb2.device_fd); /* write the buffers to disk */ /* Now delete the now-obsolete gfs1 files: */ remove_obsolete_gfs1(&sb2); @@ -1606,13 +1605,12 @@ int main(int argc, char **argv) /* end because if the tool is interrupted in the middle, we want */ /* it to not reject the partially converted fs as already done */ /* when it's run a second time. */ - bh = bread(&sb2.buf_list, sb2.sb_addr); + bh = bread(&sb2, sb2.sb_addr); sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS; sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI; gfs2_sb_out(&sb2.sd_sb, bh); brelse(bh); - bsync(&sb2.buf_list); /* write the buffers to disk */ error = fsync(sb2.device_fd); if (error) perror(device); diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c index 55f36db..cbf8dc0 100644 --- a/gfs2/edit/gfs2hex.c +++ b/gfs2/edit/gfs2hex.c @@ -335,7 +335,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh) if (last >= max_block) break; - tmp_bh = bread(&sbd.buf_list, last); + tmp_bh = bread(&sbd, last); gfs2_leaf_in(&leaf, tmp_bh); indirect->ii[indirect_blocks].dirents = 0; for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf); diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index b3f31e6..0017a60 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -904,7 +904,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) uint64_t rgblk; rgblk = get_rg_addr(rgnum); - rbh = bread(&sbd.buf_list, rgblk); + rbh = bread(&sbd, rgblk); if (gfs1) gfs_rgrp_in(&rg.rg1, rbh); else @@ -936,7 +936,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) brelse(rbh); } if (modify) - bsync(&sbd.buf_list); + fsync(sbd.device_fd); } /* ------------------------------------------------------------------------ */ @@ -988,7 +988,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex) else { struct gfs2_buffer_head *tmp_bh; - tmp_bh = bread(&sbd.buf_list, ri.ri_addr); + tmp_bh = bread(&sbd, ri.ri_addr); if (gfs1) { struct gfs_rgrp rg1; gfs_rgrp_in(&rg1, tmp_bh); @@ -1637,7 +1637,7 @@ static int display_extended(void) /* Display any indirect pointers that we have. */ if (block_is_rindex()) { - tmp_bh = bread(&sbd.buf_list, block); + tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); parse_rindex(tmp_inode, TRUE); brelse(tmp_bh); @@ -1649,34 +1649,34 @@ static int display_extended(void) return -1; else if (block_is_rglist()) { if (gfs1) - tmp_bh = bread(&sbd.buf_list, + tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr); else - tmp_bh = bread(&sbd.buf_list, masterblock("rindex")); + tmp_bh = bread(&sbd, masterblock("rindex")); tmp_inode = inode_get(&sbd, tmp_bh); parse_rindex(tmp_inode, FALSE); brelse(tmp_bh); } else if (block_is_jindex()) { - tmp_bh = bread(&sbd.buf_list, block); + tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_jindex(tmp_inode); brelse(tmp_bh); } else if (block_is_inum_file()) { - tmp_bh = bread(&sbd.buf_list, block); + tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_inum(tmp_inode); brelse(tmp_bh); } else if (block_is_statfs_file()) { - tmp_bh = bread(&sbd.buf_list, block); + tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_statfs(tmp_inode); brelse(tmp_bh); } else if (block_is_quota_file()) { - tmp_bh = bread(&sbd.buf_list, block); + tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_quota(tmp_inode); brelse(tmp_bh); @@ -1696,14 +1696,13 @@ static void read_superblock(int fd) memset(&sbd, 0, sizeof(struct gfs2_sbd)); sbd.bsize = GFS2_DEFAULT_BSIZE; sbd.device_fd = fd; - bh = bread(&sbd.buf_list, 0x10); + bh = bread(&sbd, 0x10); sbd.jsize = GFS2_DEFAULT_JSIZE; sbd.rgsize = GFS2_DEFAULT_RGSIZE; sbd.utsize = GFS2_DEFAULT_UTSIZE; sbd.qcsize = GFS2_DEFAULT_QCSIZE; sbd.time = time(NULL); osi_list_init(&sbd.rglist); - init_buf_list(&sbd, &sbd.buf_list, 1 << 20); gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */ /* Check to see if this is really gfs1 */ if (sbd1->sb_fs_format == GFS_FORMAT_FS && @@ -1800,7 +1799,7 @@ int display(int identify_only) if (block_in_mem != blk) { /* If we changed blocks from the last read */ dev_offset = blk * sbd.bsize; ioctl(sbd.device_fd, BLKFLSBUF, 0); - if (!(bh = bread(&sbd.buf_list, blk))) { + if (!(bh = bread(&sbd, blk))) { fprintf(stderr, "read error: %s from %s:%d: " "offset %lld (0x%llx)\n", strerror(errno), __FUNCTION__, __LINE__, @@ -1953,7 +1952,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) else jindex_block = masterblock("jindex"); /* read in the block */ - jindex_bh = bread(&sbd.buf_list, jindex_block); + jindex_bh = bread(&sbd, jindex_block); /* get the dinode data from it. */ gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/ @@ -1978,7 +1977,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) struct gfs2_dinode jdi; jblock = indirect->ii[0].dirent[journal_num + 2].block; - j_bh = bread(&sbd.buf_list, jblock); + j_bh = bread(&sbd, jblock); j_inode = inode_get(&sbd, j_bh); gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */ *j_size = jdi.di_size; @@ -2001,7 +2000,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize; for (blk = startblk + 1; blk < last_fs_block; blk++) { - lbh = bread(&sbd.buf_list, blk); + lbh = bread(&sbd, blk); /* Can't use get_block_type here (returns false "none") */ if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 && lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 && @@ -2426,7 +2425,7 @@ static void find_print_block_type(void) int type; tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block; - lbh = bread(&sbd.buf_list, tblock); + lbh = bread(&sbd, tblock); type = get_block_type(lbh); print_block_type(tblock, type, ""); brelse(lbh); @@ -2522,7 +2521,7 @@ static void find_change_block_alloc(int *newval) } gfs2_rgrp_free(&sbd.rglist); if (newval) - bcommit(&sbd.buf_list); + fsync(sbd.device_fd); exit(0); } @@ -2537,7 +2536,7 @@ static void process_field(const char *field, uint64_t *newval, int print_field) struct gfs2_rgrp rg; fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block; - rbh = bread(&sbd.buf_list, block); + rbh = bread(&sbd, block); type = get_block_type(rbh); switch (type) { case GFS2_METATYPE_SB: @@ -2589,10 +2588,8 @@ static void process_field(const char *field, uint64_t *newval, int print_field) " which is not implemented"); break; } - if (newval) - bmodified(rbh); brelse(rbh); - bcommit(&sbd.buf_list); + fsync(sbd.device_fd); } /* ------------------------------------------------------------------------ */ @@ -2974,7 +2971,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset, block_map(ip, lblock, ¬_new, &dblock, &extlen, FALSE); if (dblock) { - lbh = bread(&sdp->buf_list, dblock); + lbh = bread(sdp, dblock); if (*abs_block == 0) *abs_block = lbh->b_blocknr; dblock++; @@ -3032,7 +3029,7 @@ static void dump_journal(const char *journal) if (!jblock) return; if (!gfs1) { - j_bh = bread(&sbd.buf_list, jblock); + j_bh = bread(&sbd, jblock); j_inode = inode_get(&sbd, j_bh); jbuf = malloc(sbd.bsize); } @@ -3041,7 +3038,7 @@ static void dump_journal(const char *journal) if (gfs1) { if (j_bh) brelse(j_bh); - j_bh = bread(&sbd.buf_list, jblock + jb); + j_bh = bread(&sbd, jblock + jb); abs_block = jblock + jb; dummy_bh.b_data = j_bh->b_data; } else { diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 18a0798..1651a94 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -188,7 +188,7 @@ static int save_block(int fd, int out_fd, uint64_t blk) return 0; } memset(savedata, 0, sizeof(struct saved_metablock)); - savebh = bread(&sbd.buf_list, blk); + savebh = bread(&sbd, blk); memcpy(&savedata->buf, savebh->b_data, sbd.bsize); /* If this isn't metadata and isn't a system file, we don't want it. @@ -293,12 +293,12 @@ static void save_indirect_blocks(int out_fd, osi_list_t *cur_list, old_block = indir_block; blktype = save_block(sbd.device_fd, out_fd, indir_block); if (blktype == GFS2_METATYPE_EA) { - nbh = bread(&sbd.buf_list, indir_block); + nbh = bread(&sbd, indir_block); save_ea_block(out_fd, nbh); brelse(nbh); } if (height != hgt) { /* If not at max height */ - nbh = bread(&sbd.buf_list, indir_block); + nbh = bread(&sbd, indir_block); osi_list_add_prev(&nbh->b_altlist, cur_list); brelse(nbh); @@ -332,7 +332,7 @@ static void save_inode_data(int out_fd) for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) osi_list_init(&metalist[i]); - metabh = bread(&sbd.buf_list, block); + metabh = bread(&sbd, block); if (gfs1) inode = inode_get(&sbd, metabh); else @@ -383,7 +383,7 @@ static void save_inode_data(int out_fd) struct gfs2_meta_header mh; struct gfs2_buffer_head *lbh; - lbh = bread(&sbd.buf_list, inode->i_di.di_eattr); + lbh = bread(&sbd, inode->i_di.di_eattr); save_block(sbd.device_fd, out_fd, inode->i_di.di_eattr); gfs2_meta_header_in(&mh, lbh); if (mh.mh_magic == GFS2_MAGIC && @@ -477,8 +477,8 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, } for(; i < length; i++){ bits = &rgd->bits[i]; - lbh = bread(&sdp->buf_list, rgd->ri.ri_addr + i); - blk = gfs2_bitfit((unsigned char *)bh->b_data + + lbh = bread(sdp, rgd->ri.ri_addr + i); + blk = gfs2_bitfit((unsigned char *)lbh->b_data + bits->bi_offset, bits->bi_len, blk, GFS2_BLKST_UNLINKED); brelse(lbh); @@ -539,7 +539,6 @@ void savemeta(char *out_fn, int saveoption) exit(-1); } osi_list_init(&sbd.rglist); - init_buf_list(&sbd, &sbd.buf_list, 1 << 20); if (!gfs1) sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; if (compute_constants(&sbd)) { @@ -584,7 +583,7 @@ void savemeta(char *out_fn, int saveoption) &sbd.md.riinode); jindex_block = masterblock("jindex"); } - lbh = bread(&sbd.buf_list, jindex_block); + lbh = bread(&sbd, jindex_block); gfs2_dinode_in(&di, lbh); if (!gfs1) do_dinode_extended(&di, lbh); @@ -753,6 +752,8 @@ static int restore_data(int fd, int in_fd, int printblocksonly) blks_saved = total_out = 0; last_fs_block = 0; while (TRUE) { + struct gfs2_buffer_head dummy_bh; + memset(savedata, 0, sizeof(struct saved_metablock)); rs = read(in_fd, &buf64, sizeof(uint64_t)); if (!rs) @@ -794,8 +795,9 @@ static int restore_data(int fd, int in_fd, int printblocksonly) if (first) { struct gfs2_sb bufsb; + dummy_bh.b_data = (char *)&bufsb; memcpy(&bufsb, savedata->buf, sizeof(bufsb)); - gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb); + gfs2_sb_in(&sbd.sd_sb, &dummy_bh); sbd1 = (struct gfs_sb *)&sbd.sd_sb; if (sbd1->sb_fs_format == GFS_FORMAT_FS && sbd1->sb_header.mh_type == @@ -823,12 +825,13 @@ static int restore_data(int fd, int in_fd, int printblocksonly) } first = 0; } + bh = &dummy_bh; + bh->b_data = savedata->buf; if (printblocksonly) { block = savedata->blk; if (block > highest_valid_block) highest_valid_block = block; if (printblocksonly > 1 && printblocksonly == block) { - memcpy(bh->b_data, savedata->buf, sbd.bsize); block_in_mem = block; display(0); return 0; diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 71f1544..893b622 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -118,7 +118,7 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, if (error) return error; - bh_ip = bget(&sdp->buf_list, blkno); + bh_ip = bget(sdp, blkno); memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize); check_magic = ((struct gfs2_meta_header *) @@ -217,7 +217,7 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, if (error) return error; - bh_ip = bget(&sdp->buf_list, blkno); + bh_ip = bget(sdp, blkno); memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize); /* Unescape */ @@ -372,7 +372,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip) prev_seq = lh.lh_sequence; log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence); block_map(ip, blk, &new, &dblock, &extlen, FALSE); - bh = bread(&ip->i_sbd->buf_list, dblock); + bh = bread(ip->i_sbd, dblock); gfs2_log_header_out(&lh, bh); brelse(bh); } @@ -581,6 +581,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check, inode_put(&sdp->master_dir); inode_put(&sdp->md.jiinode); /* Sync the buffers to disk so we get a fresh start. */ - bsync(&sdp->buf_list); + fsync(sdp->device_fd); return error; } diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index 9d3def5..0844187 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -276,7 +276,6 @@ static int fill_super_block(struct gfs2_sbd *sdp) ********************************************************************/ log_info( _("Initializing lists...\n")); osi_list_init(&sdp->rglist); - init_buf_list(sdp, &sdp->buf_list, 1 << 20); for(i = 0; i < FSCK_HASH_SIZE; i++) { osi_list_init(&dir_hash[i]); osi_list_init(&inode_hash[i]); diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index fba0c42..ffd7530 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -333,8 +333,6 @@ int main(int argc, char **argv) int j; int error = 0; int all_clean = 0; - osi_list_t *tmp; - struct rgrp_list *rgd; setlocale(LC_ALL, ""); textdomain("gfs2-utils"); @@ -470,13 +468,7 @@ int main(int argc, char **argv) if (!opts.no && errors_corrected) log_notice( _("Writing changes to disk\n")); - - for (tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next) { - rgd = osi_list_entry(tmp, struct rgrp_list, list); - gfs2_rgrp_relse(rgd); - } - - bsync(&sbp->buf_list); + fsync(sbp->device_fd); destroy(sbp); log_notice( _("gfs2_fsck complete \n")); diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index bdb8b80..75ad1e7 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -349,7 +349,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) if (first_leaf_ptr == -1) first_leaf_ptr = first_ok_leaf; if(gfs2_check_range(ip->i_sbd, first_ok_leaf) == 0) { - lbh = bread(&sbp->buf_list, first_ok_leaf); + lbh = bread(sbp, first_ok_leaf); /* Make sure it's really a valid leaf block. */ if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) { brelse(lbh); @@ -393,7 +393,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) if (query( _("Attempt to fix it? (y/n) "))) { int factor = 0, divisor = ref_count; - lbh = bread(&sbp->buf_list, old_leaf); + lbh = bread(sbp, old_leaf); while (divisor > 1) { factor++; divisor /= 2; @@ -430,7 +430,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) } /* Try to read in the leaf block. */ - lbh = bread(&sbp->buf_list, leaf_no); + lbh = bread(sbp, leaf_no); /* Make sure it's really a valid leaf block. */ if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) { warn_and_patch(ip, &leaf_no, &bad_leaf, @@ -496,7 +496,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) } if(count != leaf.lf_entries) { - lbh = bread(&sbp->buf_list, leaf_no); + lbh = bread(sbp, leaf_no); gfs2_leaf_in(&leaf, lbh); log_err( _("Leaf %llu (0x%llx) entry " @@ -866,9 +866,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, continue; } if(!nbh) - nbh = bread(&ip->i_sbd->buf_list, - block); - + nbh = bread(ip->i_sbd, block); osi_list_add(&nbh->b_altlist, cur_list); } /* for all data on the indirect block */ } /* for blocks at that height */ diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 40dc6e2..ca36e8d 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -107,7 +107,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block, gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block); found_dup = 1; } - nbh = bread(&ip->i_sbd->buf_list, block); + nbh = bread(ip->i_sbd, block); if (gfs2_check_meta(nbh, GFS2_METATYPE_IN)){ log_debug( _("Bad indirect block pointer (points to " @@ -327,7 +327,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, check if it really is an EA. If it is, let duplicate handling sort it out. If it isn't, clear it but don't count it as a duplicate. */ - *bh = bread(&sdp->buf_list, indirect); + *bh = bread(sdp, indirect); if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) { if(q.block_type != gfs2_block_free) { /* Duplicate? */ if (!clear_eas(ip, bc, indirect, 1, @@ -411,7 +411,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype, /* Special duplicate processing: If we have an EA block, check if it really is an EA. If it is, let duplicate handling sort it out. If it isn't, clear it but don't count it as a duplicate. */ - leaf_bh = bread(&sdp->buf_list, block); + leaf_bh = bread(sdp, block); if(gfs2_check_meta(leaf_bh, btype)) { if(q.block_type != gfs2_block_free) { /* Duplicate? */ clear_eas(ip, bc, block, 1, @@ -978,7 +978,7 @@ int pass1(struct gfs2_sbd *sbp) skip_this_pass = FALSE; fflush(stdout); } - bh = bread(&sbp->buf_list, block); + bh = bread(sbp, block); if (scan_meta(sbp, bh, block)) { stack; diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index a1b327a..3d093ad 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -66,7 +66,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, struct gfs2_buffer_head *indir_bh = NULL; inc_if_found(block, 0, private); - indir_bh = bread(&sbp->buf_list, block); + indir_bh = bread(sbp, block); *bh = indir_bh; return 0; @@ -80,7 +80,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, struct gfs2_buffer_head *leaf_bh = NULL; inc_if_found(block, 0, private); - leaf_bh = bread(&sbp->buf_list, block); + leaf_bh = bread(sbp, block); *bh = leaf_bh; return 0; @@ -402,7 +402,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) struct gfs2_buffer_head *bh; uint32_t cmagic; - bh = bread(&sbp->buf_list, b->block_no); + bh = bread(sbp, b->block_no); cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic; brelse(bh); if (be32_to_cpu(cmagic) == GFS2_MAGIC) { diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index 4d9c820..e3bd010 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -100,7 +100,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, return ask_remove_eattr(ip); } else - indir_bh = bread(&sbp->buf_list, block); + indir_bh = bread(sbp, block); *bh = indir_bh; return 0; @@ -132,7 +132,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, return ask_remove_eattr(ip); } else - *bh = bread(&sbp->buf_list, block); + *bh = bread(sbp, block); return 0; } @@ -252,7 +252,7 @@ int pass1c(struct gfs2_sbd *sbp) if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; - bh = bread(&sbp->buf_list, block_no); + bh = bread(sbp, block_no); if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */ log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"), block_no, block_no); diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index 40256a5..147fd12 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -79,14 +79,14 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, void *private) { - *bh = bread(&ip->i_sbd->buf_list, block); + *bh = bread(ip->i_sbd, block); return 0; } static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, void *private) { - *bh = bread(&ip->i_sbd->buf_list, block); + *bh = bread(ip->i_sbd, block); return 0; } @@ -295,7 +295,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, return 1; /* Now try to clear the dinode, if it is an dinode */ - bhi = bread(&sbp->buf_list, de->de_inum.no_addr); + bhi = bread(sbp, de->de_inum.no_addr); error = gfs2_check_meta(bhi, GFS2_METATYPE_DI); bmodified(bhi); brelse(bhi); diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c index feeebdc..807ced2 100644 --- a/gfs2/fsck/pass3.c +++ b/gfs2/fsck/pass3.c @@ -53,7 +53,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot, increment_link(sbp, newdotdot); bmodified(ip->i_bh); fsck_inode_put(&ip); - bmodified(pip->i_bh); fsck_inode_put(&pip); return 0; } diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 34c9149..0cb99d2 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -54,7 +54,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp) block_map(ip, b, &new, &dblock, &extlen, 0); if (!dblock) break; - bh = bread(&sdp->buf_list, dblock); + bh = bread(sdp, dblock); if (!gfs2_check_meta(bh, GFS2_METATYPE_RG)) { log_debug( _("False RG found at block " "0x%" PRIx64 "\n"), dblock); @@ -128,7 +128,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, for (blk = sdp->sb_addr + 1; blk < sdp->device.length && number_of_rgs < 6; blk++) { - bh = bread(&sdp->buf_list, blk); + bh = bread(sdp, blk); if (((blk == sdp->sb_addr + 1) || (!gfs2_check_meta(bh, GFS2_METATYPE_RG))) && !is_false_rg(blk)) { @@ -206,7 +206,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, for (blk = sdp->sb_addr + 1; blk <= sdp->device.length; blk += block_bump) { log_debug( _("Block 0x%" PRIx64 "\n"), blk); - bh = bread(&sdp->buf_list, blk); + bh = bread(sdp, blk); rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG)); brelse(bh); /* Allocate a new RG and index. */ @@ -240,7 +240,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, for (fwd_block = blk + 1; fwd_block < sdp->device.length; fwd_block++) { - bh = bread(&sdp->buf_list, fwd_block); + bh = bread(sdp, fwd_block); bitmap_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RB)); brelse(bh); @@ -384,7 +384,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg, (int)x+1, (int)rg->ri.ri_length); if (query( _("Fix the Resource Group? (y/n)"))) { log_err( _("Attempting to repair the RG.\n")); - rg->bh[x] = bread(&sdp->buf_list, rg->ri.ri_addr + x); + rg->bh[x] = bread(sdp, rg->ri.ri_addr + x); if (x) { struct gfs2_meta_header mh; diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c index 8997503..5b8d29d 100644 --- a/gfs2/libgfs2/buf.c +++ b/gfs2/libgfs2/buf.c @@ -12,120 +12,18 @@ #include "libgfs2.h" -static __inline__ osi_list_t * -blkno2head(struct buf_list *bl, uint64_t blkno) -{ - return bl->buf_hash + - (gfs2_disk_hash((char *)&blkno, sizeof(uint64_t)) & BUF_HASH_MASK); -} - -static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh) -{ - struct gfs2_sbd *sdp = bl->sbp; - - osi_list_del(&bh->b_list); - osi_list_del(&bh->b_hash); - bl->num_bufs--; - if (bh->b_changed) { - if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize, - SEEK_SET) != bh->b_blocknr * sdp->bsize) { - return -1; - } - if (write(sdp->device_fd, bh->b_data, sdp->bsize) != - sdp->bsize) { - return -1; - } - sdp->writes++; - } - bh->b_blocknr = -1; - bh->b_data = NULL; - bh->b_count = -1; - bh->b_changed = -1; - free(bh); - return 0; -} - -void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit) -{ - int i; - - bl->num_bufs = 0; - bl->spills = 0; - bl->limit = limit; - bl->sbp = sdp; - osi_list_init(&bl->list); - for(i = 0; i < BUF_HASH_SIZE; i++) - osi_list_init(&bl->buf_hash[i]); -} - -static int add_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh) -{ - osi_list_t *head = blkno2head(bl, bh->b_blocknr); - - osi_list_add(&bh->b_list, &bl->list); - osi_list_add(&bh->b_hash, head); - bl->num_bufs++; - - if (bl->num_bufs * bl->sbp->bsize > bl->limit) { - int found = 0; - osi_list_t *tmp, *x; - - for (tmp = bl->list.prev, x = tmp->prev; tmp != &bl->list; - tmp = x, x = x->prev) { - bh = osi_list_entry(tmp, struct gfs2_buffer_head, - b_list); - if (!bh->b_count) { - if (write_buffer(bl, bh)) - return -1; - found++; - if (found >= 10) - break; - } - } - bl->spills++; - } - return 0; -} - -struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num) -{ - osi_list_t *head = blkno2head(bl, num); - osi_list_t *tmp; - struct gfs2_buffer_head *bh; - - for (tmp = head->next; tmp != head; tmp = tmp->next) { - bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_hash); - if (bh->b_blocknr == num) { - osi_list_del(&bh->b_list); - osi_list_add(&bh->b_list, &bl->list); - osi_list_del(&bh->b_hash); - osi_list_add(&bh->b_hash, head); - bh->b_count++; - return bh; - } - } - - return NULL; -} - -struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, uint64_t num, - int find_existing, int read_disk, +struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, uint64_t num, + int read_disk, int line, const char *caller) { struct gfs2_buffer_head *bh; - struct gfs2_sbd *sdp = bl->sbp; - if (find_existing) { - bh = bfind(bl, num); - if (bh) - return bh; - } bh = calloc(1, sizeof(struct gfs2_buffer_head) + sdp->bsize); if (bh == NULL) return NULL; - bh->b_count = 1; bh->b_blocknr = num; + bh->sdp = sdp; bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head); if (read_disk) { if (lseek(sdp->device_fd, num * sdp->bsize, SEEK_SET) != @@ -144,119 +42,48 @@ struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, uint64_t num, exit(-1); } } - if (add_buffer(bl, bh)) { - fprintf(stderr, "bad write: %s from %s:%d: block " - "%llu (0x%llx)\n", strerror(errno), - caller, line, (unsigned long long)num, - (unsigned long long)num); - exit(-1); - } - bh->b_changed = FALSE; return bh; } -struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, int line, +struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num, int line, const char *caller) { - return __bget_generic(bl, num, TRUE, FALSE, line, caller); + return __bget_generic(sdp, num, FALSE, line, caller); } -struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, int line, +struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line, const char *caller) { - return __bget_generic(bl, num, TRUE, TRUE, line, caller); -} - -struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh) -{ - if (!bh->b_count) - return NULL; - bh->b_count++; - return bh; -} - -void bmodified(struct gfs2_buffer_head *bh) -{ - bh->b_changed = 1; -} - -void brelse(struct gfs2_buffer_head *bh) -{ - /* We can't just say b_changed = updated because we don't want to */ - /* set it FALSE if it's TRUE until we write the changed data to disk. */ - if (!bh->b_count) { - fprintf(stderr, "buffer count underflow for block %" PRIu64 - " (0x%" PRIx64")\n", bh->b_blocknr, bh->b_blocknr); - exit(-1); - } - bh->b_count--; + return __bget_generic(sdp, num, TRUE, line, caller); } -void __bsync(struct buf_list *bl, int line, const char *caller) +int bwrite(struct gfs2_buffer_head *bh) { - struct gfs2_buffer_head *bh; + struct gfs2_sbd *sdp = bh->sdp; - while (!osi_list_empty(&bl->list)) { - bh = osi_list_entry(bl->list.prev, struct gfs2_buffer_head, - b_list); - if (bh->b_count) { - fprintf(stderr, "buffer still held for block: %" PRIu64 - " (0x%" PRIx64")\n", bh->b_blocknr, bh->b_blocknr); - exit(-1); - } - if (write_buffer(bl, bh)) { - fprintf(stderr, "bad write: %s from %s:%d: block " - "%lld (0x%llx)\n", strerror(errno), - caller, line, - (unsigned long long)bh->b_blocknr, - (unsigned long long)bh->b_blocknr); - exit(-1); - } + if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize, SEEK_SET) != + bh->b_blocknr * sdp->bsize) { + return -1; } + if (write(sdp->device_fd, bh->b_data, sdp->bsize) != sdp->bsize) + return -1; + sdp->writes++; + bh->b_changed = 0; + return 0; } -/* commit buffers to disk but do not discard */ -void __bcommit(struct buf_list *bl, int line, const char *caller) +int brelse(struct gfs2_buffer_head *bh) { - osi_list_t *tmp, *x; - struct gfs2_buffer_head *bh; - struct gfs2_sbd *sdp = bl->sbp; + int error = 0; - osi_list_foreach_safe(tmp, &bl->list, x) { - bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list); - if (!bh->b_count) { /* if not reserved for later */ - if (write_buffer(bl, bh)) { /* write & free */ - fprintf(stderr, "bad write: %s from %s:%d: " - "block %lld (0x%llx)\n", - strerror(errno), caller, line, - (unsigned long long)bh->b_blocknr, - (unsigned long long)bh->b_blocknr); - exit(-1); - } - } else if (bh->b_changed) { /* if buffer has changed */ - if (lseek(sdp->device_fd, - bh->b_blocknr * sdp->bsize, SEEK_SET) != - bh->b_blocknr * sdp->bsize) { - fprintf(stderr, "bad seek: %s from %s:%d: " - "block %lld (0x%llx)\n", - strerror(errno), caller, line, - (unsigned long long)bh->b_blocknr, - (unsigned long long)bh->b_blocknr); - exit(-1); - } - if (write(sdp->device_fd, bh->b_data, sdp->bsize) != - sdp->bsize) { - fprintf(stderr, "bad write: %s from %s:%d: " - "block %lld (0x%llx)\n", - strerror(errno), caller, line, - (unsigned long long)bh->b_blocknr, - (unsigned long long)bh->b_blocknr); - exit(-1); - } - bh->b_changed = FALSE; /* no longer changed */ - } - } - fsync(sdp->device_fd); + if (bh->b_blocknr == -1) + printf("Double free!\n"); + if (bh->b_changed) + error = bwrite(bh); + bh->b_blocknr = -1; + if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist)) + osi_list_del(&bh->b_altlist); + free(bh); + return error; } - diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c index 6fbc10f..3fe26fa 100644 --- a/gfs2/libgfs2/fs_geometry.c +++ b/gfs2/libgfs2/fs_geometry.c @@ -214,7 +214,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write) if (do_write) { for (x = 0; x < bitblocks; x++) { - bh = bget(&sdp->buf_list, rl->start + x); + bh = bget(sdp, rl->start + x); if (x) gfs2_meta_header_out(&mh, bh); else diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c index 4279d99..b3b527f 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -53,7 +53,7 @@ struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr) fprintf(stderr, "Out of memory in %s\n", __FUNCTION__); exit(-1); } - ip->i_bh = bread(&sdp->buf_list, di_addr); + ip->i_bh = bread(sdp, di_addr); gfs2_dinode_in(&ip->i_di, ip->i_bh); ip->i_sbd = sdp; ip->bh_owned = 1; /* We did the bread so we own the bh */ @@ -235,7 +235,7 @@ void unstuff_dinode(struct gfs2_inode *ip) if (ip->i_di.di_size) { if (isdir) { block = meta_alloc(ip); - bh = bget(&sdp->buf_list, block); + bh = bget(sdp, block); { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -251,7 +251,7 @@ void unstuff_dinode(struct gfs2_inode *ip) brelse(bh); } else { block = data_alloc(ip); - bh = bget(&sdp->buf_list, block); + bh = bget(sdp, block); buffer_copy_tail(sdp, bh, 0, ip->i_bh, sizeof(struct gfs2_dinode)); @@ -313,7 +313,7 @@ void build_height(struct gfs2_inode *ip, int height) if (new_block) { block = meta_alloc(ip); - bh = bget(&sdp->buf_list, block); + bh = bget(sdp, block); { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -439,7 +439,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, if (*new) { struct gfs2_meta_header mh; - bh = bget(&sdp->buf_list, *dblock); + bh = bget(sdp, *dblock); mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; @@ -448,7 +448,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, if (*dblock == ip->i_di.di_num.no_addr) bh = ip->i_bh; else - bh = bread(&sdp->buf_list, *dblock); + bh = bread(sdp, *dblock); } } @@ -547,7 +547,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf, if (dblock == ip->i_di.di_num.no_addr) bh = ip->i_bh; else - bh = bread(&sdp->buf_list, dblock); + bh = bread(sdp, dblock); dblock++; extlen--; } else @@ -622,7 +622,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, } if (new) { - bh = bget(&sdp->buf_list, dblock); + bh = bget(sdp, dblock); if (isdir) { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -634,7 +634,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, if (dblock == ip->i_di.di_num.no_addr) bh = ip->i_bh; else - bh = bread(&sdp->buf_list, dblock); + bh = bread(sdp, dblock); } copy_from_mem(bh, &buf, o, amount); if (bh != ip->i_bh) @@ -676,12 +676,12 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn, ip->i_di.di_size = (lbn + 1) << sdp->sd_sb.sb_bsize_shift; } if (new) - return bget(&sdp->buf_list, dbn); + return bget(sdp, dbn); else { if (dbn == ip->i_di.di_num.no_addr) return ip->i_bh; else - return bread(&sdp->buf_list, dbn); + return bread(sdp, dbn); } } @@ -850,7 +850,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea int count; bn = meta_alloc(dip); - nbh = bget(&dip->i_sbd->buf_list, bn); + nbh = bget(dip->i_sbd, bn); { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -862,7 +862,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea nleaf = (struct gfs2_leaf *)nbh->b_data; nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE); - obh = bread(&dip->i_sbd->buf_list, leaf_no); + obh = bread(dip->i_sbd, leaf_no); oleaf = (struct gfs2_leaf *)obh->b_data; len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth)); @@ -1002,7 +1002,7 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no, { int error = 0; - *bhp = bread(&dip->i_sbd->buf_list, leaf_no); + *bhp = bread(dip->i_sbd, leaf_no); if (error) return error; error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF); @@ -1026,7 +1026,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no; gfs2_get_leaf_nr(dip, lindex, &leaf_no); - *bh_out = bread(&dip->i_sbd->buf_list, leaf_no); + *bh_out = bread(dip->i_sbd, leaf_no); return 0; } @@ -1048,7 +1048,7 @@ static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in, if (!leaf->lf_next) return -1; - *bh_out = bread(&dip->i_sbd->buf_list, be64_to_cpu(leaf->lf_next)); + *bh_out = bread(dip->i_sbd, be64_to_cpu(leaf->lf_next)); return 0; } @@ -1073,7 +1073,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, gfs2_get_leaf_nr(dip, lindex, &leaf_no); for (;;) { - bh = bread(&dip->i_sbd->buf_list, leaf_no); + bh = bread(dip->i_sbd, leaf_no); leaf = (struct gfs2_leaf *)bh->b_data; if (dirent_alloc(dip, bh, len, &dent)) { @@ -1095,7 +1095,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, } else { bn = meta_alloc(dip); - nbh = bget(&dip->i_sbd->buf_list, bn); + nbh = bget(dip->i_sbd, bn); { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -1145,7 +1145,7 @@ static void dir_make_exhash(struct gfs2_inode *dip) uint64_t *lp, bn; bn = meta_alloc(dip); - bh = bget(&sdp->buf_list, bn); + bh = bget(sdp, bn); { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; @@ -1195,6 +1195,7 @@ static void dir_make_exhash(struct gfs2_inode *dip) dip->i_di.di_depth = y; gfs2_dinode_out(&dip->i_di, dip->i_bh); + bwrite(dip->i_bh); } static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len, @@ -1231,7 +1232,7 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh; struct gfs2_dinode di; - bh = bget(&sdp->buf_list, inum->no_addr); + bh = bget(sdp, inum->no_addr); memset(&di, 0, sizeof(struct gfs2_dinode)); di.di_header.mh_magic = GFS2_MAGIC; @@ -1557,7 +1558,7 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len) gfs2_get_leaf_nr(dip, lindex, &leaf_no); while(leaf_no && !found){ - bh = bread(&dip->i_sbd->buf_list, leaf_no); + bh = bread(dip->i_sbd, leaf_no); error = leaf_search(dip, bh, filename, len, &cur, &prev); if (error) { if(error != -ENOENT){ @@ -1696,7 +1697,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) for (h = 0; h < GFS2_MAX_META_HEIGHT; h++) osi_list_init(&metalist[h]); - bh = bread(&sdp->buf_list, diblock); + bh = bread(sdp, diblock); ip = inode_get(sdp, bh); height = ip->i_di.di_height; osi_list_add(&bh->b_altlist, &metalist[0]); @@ -1721,7 +1722,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) if (h == height - 1) /* if not metadata */ continue; /* don't queue it up */ /* Read the next metadata block in the chain */ - nbh = bread(&sdp->buf_list, block); + nbh = bread(sdp, block); osi_list_add(&nbh->b_altlist, next_list); brelse(nbh); } diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c index 5232c01..5cced66 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -110,13 +110,13 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, if (*new) { struct gfs2_meta_header mh; - bh = bget(&sdp->buf_list, *dblock); + bh = bget(sdp, *dblock); mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; gfs2_meta_header_out(&mh, bh); } else { - bh = bread(&sdp->buf_list, *dblock); + bh = bread(sdp, *dblock); } } @@ -199,7 +199,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin, &extlen, FALSE); if (dblock) { - bh = bread(&sdp->buf_list, dblock); + bh = bread(sdp, dblock); dblock++; extlen--; } else @@ -412,7 +412,7 @@ struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr) exit(-1); } - ip->i_bh = bread(&sdp->buf_list, di_addr); + ip->i_bh = bread(sdp, di_addr); gfs_dinode_in(&gfs1_dinode, ip->i_bh); memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header, sizeof(struct gfs2_meta_header)); diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 643c728..db1b38e 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -105,15 +105,11 @@ struct rgrp_list { }; struct gfs2_buffer_head { - osi_list_t b_list; - osi_list_t b_hash; osi_list_t b_altlist; /* alternate list */ - - unsigned int b_count; uint64_t b_blocknr; - char *b_data; - int b_changed; + char *b_data; + struct gfs2_sbd *sdp; }; struct dup_blocks { @@ -174,15 +170,6 @@ struct master_dir struct per_node *pn; /* Array of per_node entries */ }; -struct buf_list { - unsigned int num_bufs; - unsigned int spills; - uint32_t limit; - osi_list_t list; - struct gfs2_sbd *sbp; - osi_list_t buf_hash[BUF_HASH_SIZE]; -}; - struct gfs2_sbd { struct gfs2_sb sd_sb; /* a copy of the ondisk structure */ char lockproto[GFS2_LOCKNAME_LEN]; @@ -243,8 +230,6 @@ struct gfs2_sbd { unsigned int orig_journals; - struct buf_list buf_list; /* transient buffer list */ - struct gfs2_inode *master_dir; struct master_dir md; @@ -346,21 +331,18 @@ extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il, extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il); /* buf.c */ -extern void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit); -extern struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num); -extern struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, - uint64_t num, int find_existing, +extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, + uint64_t num, int read_disk, int line, const char *caller); -extern struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, +extern struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num, int line, const char *caller); -extern struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, +extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line, const char *caller); -extern struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh); -extern void bmodified(struct gfs2_buffer_head *bh); -extern void brelse(struct gfs2_buffer_head *bh); -extern void __bsync(struct buf_list *bl, int line, const char *caller); -extern void __bcommit(struct buf_list *bl, int line, const char *caller); +extern int bwrite(struct gfs2_buffer_head *bh); +extern int brelse(struct gfs2_buffer_head *bh); + +#define bmodified(bh) do { bh->b_changed = 1; } while(0) #define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \ __LINE__, \ diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c index fee7ef2..74f896e 100644 --- a/gfs2/libgfs2/recovery.c +++ b/gfs2/libgfs2/recovery.c @@ -31,7 +31,7 @@ int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk, if (!dblock) return -EIO; - *bh = bread(&ip->i_sbd->buf_list, dblock); + *bh = bread(ip->i_sbd, dblock); return 0; } @@ -223,7 +223,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) if (!dblock) return -EIO; - bh = bread(&ip->i_sbd->buf_list, dblock); + bh = bread(ip->i_sbd, dblock); memset(bh->b_data, 0, ip->i_sbd->bsize); lh = (struct gfs2_log_header *)bh->b_data; diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index ed1df78..f42fdaa 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -126,7 +126,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd) int x, length = rgd->ri.ri_length; for (x = 0; x < length; x++){ - rgd->bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x); + rgd->bh[x] = bread(sdp, rgd->ri.ri_addr + x); if(gfs2_check_meta(rgd->bh[x], (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG)) { diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c index 5343f88..b1dd4ff 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -42,7 +42,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) /* Zero out the beginning of the device up to the superblock */ for (x = 0; x < sdp->sb_addr; x++) { - bh = bget(&sdp->buf_list, x); + bh = bget(sdp, x); memset(bh->b_data, 0, sdp->bsize); bmodified(bh); brelse(bh); @@ -63,7 +63,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) #ifdef GFS2_HAS_UUID memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid)); #endif - bh = bget(&sdp->buf_list, sdp->sb_addr); + bh = bget(sdp, sdp->sb_addr); gfs2_sb_out(&sb, bh); brelse(bh); @@ -492,7 +492,7 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, brelse(bh); if (gfs2_next_rg_meta(rgd, block, first)) return -1; - bh = bread(&sdp->buf_list, *block); + bh = bread(sdp, *block); first = 0; } while(gfs2_check_meta(bh, type)); brelse(bh); diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 00a2ae7..0d65928 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -58,7 +58,7 @@ int read_sb(struct gfs2_sbd *sdp) unsigned int x; int error; - bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); gfs2_sb_in(&sdp->sd_sb, bh); brelse(bh); @@ -256,10 +256,10 @@ int write_sb(struct gfs2_sbd *sbp) { struct gfs2_buffer_head *bh; - bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); + bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); gfs2_sb_out(&sbp->sd_sb, bh); brelse(bh); - bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */ + fsync(sbp->device_fd); /* make sure the change gets to disk ASAP */ return 0; } diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c index 2da353a..4245155 100644 --- a/gfs2/mkfs/main_grow.c +++ b/gfs2/mkfs/main_grow.c @@ -171,7 +171,7 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count) inode_put(&sdp->master_dir); /* We're done with the libgfs portion, so commit it to disk. */ - bsync(&sdp->buf_list); + fsync(sdp->device_fd); } /** @@ -283,7 +283,6 @@ main_grow(int argc, char *argv[]) } log_info( _("Initializing lists...\n")); osi_list_init(&sdp->rglist); - init_buf_list(sdp, &sdp->buf_list, 1 << 20); sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; sdp->bsize = sdp->sd_sb.sb_bsize; diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 3d3012f..ceff0dc 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -528,8 +528,6 @@ print_results(struct gfs2_sbd *sdp, uint64_t real_device_size, if (sdp->debug) { printf("\n"); - printf( _("Spills: %u\n"), - sdp->buf_list.spills); printf( _("Writes: %u\n"), sdp->writes); } @@ -561,7 +559,6 @@ void main_mkfs(int argc, char *argv[]) strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO); sdp->time = time(NULL); osi_list_init(&sdp->rglist); - init_buf_list(sdp, &sdp->buf_list, 1 << 20); decode_arguments(argc, argv, sdp); if (sdp->rgsize == -1) /* if rg size not specified */ @@ -641,7 +638,6 @@ void main_mkfs(int argc, char *argv[]) inode_put(&sdp->master_dir); inode_put(&sdp->md.inum); inode_put(&sdp->md.statfs); - bsync(&sdp->buf_list); error = fsync(sdp->device_fd); if (error)
1
0
0
0
cluster: STABLE3 - Attach bh's to inodes
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=71…
Commit: 71fb85ae21db98d08128ff27ca4c17ac7dd4139d Parent: 8956735abb1523be8d63cfbbb55d16c535795cae Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Tue Jan 19 13:51:13 2010 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:28 2010 -0600 Attach bh's to inodes This patch attaches buffer_heads to inodes. This gives us better performance because we don't have to constantly keep searching for the buffer based on the dinode address. It's also another step in eliminating the linked list of buffers altogether. rhbz#455300 --- gfs2/convert/gfs2_convert.c | 73 ++++++++--------- gfs2/edit/hexedit.c | 23 ++--- gfs2/edit/savemeta.c | 20 ++--- gfs2/fsck/fs_recovery.c | 9 +- gfs2/fsck/fsck.h | 6 +- gfs2/fsck/initialize.c | 5 +- gfs2/fsck/lost_n_found.c | 2 +- gfs2/fsck/main.c | 20 ++-- gfs2/fsck/metawalk.c | 111 ++++++++++-------------- gfs2/fsck/pass1.c | 40 ++++----- gfs2/fsck/pass1b.c | 10 +- gfs2/fsck/pass1c.c | 4 +- gfs2/fsck/pass2.c | 31 ++----- gfs2/fsck/pass3.c | 22 +++--- gfs2/fsck/pass4.c | 16 ++-- gfs2/libgfs2/fs_ops.c | 196 ++++++++++++++++++++++++++++++------------- gfs2/libgfs2/gfs1.c | 52 +++++++++++- gfs2/libgfs2/libgfs2.h | 13 ++- gfs2/libgfs2/structures.c | 41 ++++------ gfs2/mkfs/main_grow.c | 9 +-- gfs2/mkfs/main_mkfs.c | 12 +-- 21 files changed, 390 insertions(+), 325 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index ba21e94..02bd9b9 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -310,12 +310,13 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, amount = size; while (copied < size) { - bh = bhold(ip->i_bh); - + bh = ip->i_bh; /* First, build up the metatree */ for (h = 0; h < blk->height; h++) { - lookup_block(ip, bh, h, &blk->mp, 1, &new, &block); - brelse(bh); + lookup_block(ip, ip->i_bh, h, &blk->mp, 1, &new, + &block); + if (bh != ip->i_bh) + brelse(bh); if (!block) break; @@ -334,7 +335,8 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, (char *)srcptr, amount); srcptr += amount; bmodified(bh); - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); copied += amount; @@ -404,8 +406,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, /* */ /* Adapted from gfs2_fsck metawalk.c's build_and_check_metalist */ /* ------------------------------------------------------------------------- */ -static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head *dibh, - struct gfs2_inode *ip) +static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_inode *ip) { uint32_t gfs2_hgt; struct gfs2_buffer_head *bh; @@ -416,6 +417,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head int error = 0, di_height; struct blocklist blocks, *blk, *newblk; struct metapath gfs2mp; + struct gfs2_buffer_head *dibh = ip->i_bh; /* if there are no indirect blocks to check */ if (ip->i_di.di_height <= 1) @@ -656,11 +658,12 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh) inode->i_di.di_goal_data = 0; /* make sure the upper 32b are 0 */ inode->i_di.di_goal_data = gfs1_dinode_struct->di_goal_dblk; inode->i_di.di_generation = 0; - if (adjust_indirect_blocks(sbp, bh, inode)) + if (adjust_indirect_blocks(sbp, inode)) return -1; } - gfs2_dinode_out(&inode->i_di, bh); + bmodified(inode->i_bh); + inode_put(&inode); /* does gfs2_dinode_out if modified */ sbp->md.next_inum++; /* update inode count */ return 0; } /* adjust_inode */ @@ -763,15 +766,12 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) static int fetch_inum(struct gfs2_sbd *sbp, uint64_t iblock, struct gfs2_inum *inum) { - struct gfs2_buffer_head *bh_fix; struct gfs2_inode *fix_inode; - bh_fix = bread(&sbp->buf_list, iblock); - fix_inode = inode_get(sbp, bh_fix); + fix_inode = inode_read(sbp, iblock); inum->no_formal_ino = fix_inode->i_di.di_num.no_formal_ino; inum->no_addr = fix_inode->i_di.di_num.no_addr; - bmodified(bh_fix); - brelse(bh_fix); + inode_put(&fix_inode); return 0; }/* fetch_inum */ @@ -926,7 +926,6 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix) struct inode_block *dir_iblk; uint64_t offset, dirblock; struct gfs2_inode *dip; - struct gfs2_buffer_head *bh_dir; dirs_fixed = 0; dirents_fixed = 0; @@ -948,27 +947,24 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix) dir_iblk = (struct inode_block *)fix; dirblock = dir_iblk->di_addr; /* addr of dir inode */ /* read in the directory inode */ - bh_dir = bread(&sbp->buf_list, dirblock); - dip = inode_get(sbp, bh_dir); + dip = inode_read(sbp, dirblock); /* fix the directory: either exhash (leaves) or linear (stuffed) */ if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { if (fix_one_directory_exhash(sbp, dip)) { log_crit("Error fixing exhash directory.\n"); - bmodified(bh_dir); - brelse(bh_dir); + inode_put(&dip); return -1; } } else { - if (process_dirent_info(dip, sbp, bh_dir, dip->i_di.di_entries)) { + if (process_dirent_info(dip, sbp, dip->i_bh, + dip->i_di.di_entries)) { log_crit("Error fixing linear directory.\n"); - bmodified(bh_dir); - brelse(bh_dir); + inode_put(&dip); return -1; } } - bmodified(bh_dir); - brelse(bh_dir); + inode_put(&dip); } /* Free the last entry in memory: */ if (tmp) { @@ -1140,11 +1136,10 @@ static int init(struct gfs2_sbd *sbp) } /* get gfs1 rindex inode - gfs1's rindex inode ptr became __pad2 */ gfs2_inum_in(&inum, (char *)&raw_gfs1_ondisk_sb.sb_rindex_di); - bh = bread(&sbp->buf_list, inum.no_addr); - sbp->md.riinode = gfs_inode_get(sbp, bh); + sbp->md.riinode = gfs_inode_read(sbp, inum.no_addr); /* get gfs1 jindex inode - gfs1's journal index inode ptr became master */ gfs2_inum_in(&inum, (char *)&raw_gfs1_ondisk_sb.sb_jindex_di); - sbp->md.jiinode = gfs2_load_inode(sbp, inum.no_addr); + sbp->md.jiinode = inode_read(sbp, inum.no_addr); /* read in the journal index data */ read_gfs1_jiindex(sbp); /* read in the resource group index data: */ @@ -1163,8 +1158,8 @@ static int init(struct gfs2_sbd *sbp) } printf("\n"); fflush(stdout); - inode_put(sbp->md.riinode); - inode_put(sbp->md.jiinode); + inode_put(&sbp->md.riinode); + inode_put(&sbp->md.jiinode); log_debug("%d rgs found.\n", rgcount); return 0; }/* fill_super_block */ @@ -1464,11 +1459,10 @@ static void remove_obsolete_gfs1(struct gfs2_sbd *sbp) /* ------------------------------------------------------------------------- */ static void conv_build_jindex(struct gfs2_sbd *sdp) { - struct gfs2_inode *jindex; unsigned int j; - jindex = createi(sdp->master_dir, "jindex", S_IFDIR | 0700, - GFS2_DIF_SYSTEM); + sdp->md.jiinode = createi(sdp->master_dir, "jindex", S_IFDIR | 0700, + GFS2_DIF_SYSTEM); for (j = 0; j < sdp->md.journals; j++) { char name[256]; @@ -1477,20 +1471,21 @@ static void conv_build_jindex(struct gfs2_sbd *sdp) printf("Writing journal #%d...", j + 1); fflush(stdout); sprintf(name, "journal%u", j); - ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM); + ip = createi(sdp->md.jiinode, name, S_IFREG | 0600, + GFS2_DIF_SYSTEM); write_journal(sdp, ip, j, sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift); - inode_put(ip); + inode_put(&ip); printf("done.\n"); fflush(stdout); } if (sdp->debug) { printf("\nJindex:\n"); - gfs2_dinode_print(&jindex->i_di); + gfs2_dinode_print(&sdp->md.jiinode->i_di); } - inode_put(jindex); + inode_put(&sdp->md.jiinode); } /* ------------------------------------------------------------------------- */ @@ -1595,9 +1590,9 @@ int main(int argc, char **argv) update_inode_file(&sb2); write_statfs_file(&sb2); - inode_put(sb2.master_dir); - inode_put(sb2.md.inum); - inode_put(sb2.md.statfs); + inode_put(&sb2.master_dir); + inode_put(&sb2.md.inum); + inode_put(&sb2.md.statfs); bcommit(&sb2.buf_list); /* write the buffers to disk */ diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index a277b7a..b3f31e6 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -786,7 +786,7 @@ static void rgcount(void) { printf("%lld RGs in this file system.\n", (unsigned long long)sbd.md.riinode->i_di.di_size / risize()); - inode_put(sbd.md.riinode); + inode_put(&sbd.md.riinode); gfs2_rgrp_free(&sbd.rglist); exit(EXIT_SUCCESS); } @@ -870,7 +870,6 @@ static void gfs_rgrp_print(struct gfs_rgrp *rg) /* ------------------------------------------------------------------------ */ static uint64_t get_rg_addr(int rgnum) { - struct gfs2_buffer_head *lbh; uint64_t rgblk = 0, gblock; struct gfs2_inode *riinode; @@ -878,14 +877,13 @@ static uint64_t get_rg_addr(int rgnum) gblock = sbd1->sb_rindex_di.no_addr; else gblock = masterblock("rindex"); - lbh = bread(&sbd.buf_list, gblock); - riinode = inode_get(&sbd, lbh); + riinode = inode_read(&sbd, gblock); if (rgnum < riinode->i_di.di_size / risize()) rgblk = find_rgrp_block(riinode, rgnum); else fprintf(stderr, "Error: File system only has %lld RGs.\n", (unsigned long long)riinode->i_di.di_size / risize()); - inode_put(riinode); + inode_put(&riinode); return rgblk; } @@ -1596,17 +1594,15 @@ int block_is_per_node(void) int block_is_in_per_node(void) { int d; - struct gfs2_dinode per_node_di; - struct gfs2_buffer_head *per_node_bh; + struct gfs2_inode *per_node_di; if (gfs1) return FALSE; - per_node_bh = bread(&sbd.buf_list, masterblock("per_node")); - gfs2_dinode_in(&per_node_di, per_node_bh); + per_node_di = inode_read(&sbd, masterblock("per_node")); - do_dinode_extended(&per_node_di, per_node_bh); - brelse(per_node_bh); + do_dinode_extended(&per_node_di->i_di, per_node_di->i_bh); + inode_put(&per_node_di); for (d = 0; d < indirect->ii[0].dirents; d++) { if (block == indirect->ii[0].dirent[d].block) @@ -1744,8 +1740,7 @@ static void read_superblock(int fd) sizeof(uint64_t); sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) / sizeof(uint64_t); - sbd.md.riinode = gfs2_load_inode(&sbd, - sbd1->sb_rindex_di.no_addr); + sbd.md.riinode = inode_read(&sbd, sbd1->sb_rindex_di.no_addr); sbd.fssize = sbd.device.length; gfs1_rindex_read(&sbd, 0, &count); } else { @@ -1753,7 +1748,7 @@ static void read_superblock(int fd) sizeof(uint64_t); sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) / sizeof(uint64_t); - sbd.master_dir = gfs2_load_inode(&sbd, + sbd.master_dir = inode_read(&sbd, sbd.sd_sb.sb_master_dir.no_addr); gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode); sbd.fssize = sbd.device.length; diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 99bc986..18a0798 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -407,7 +407,7 @@ static void save_inode_data(int out_fd) } brelse(lbh); } - inode_put(inode); + inode_put(&inode); brelse(metabh); } @@ -429,19 +429,18 @@ static void get_journal_inode_blocks(void) for (journal = 0; ; journal++) { /* while journals exist */ uint64_t jblock; int amt; - struct gfs2_dinode jdi; struct gfs2_inode *j_inode = NULL; if (gfs1) { struct gfs_jindex ji; char jbuf[sizeof(struct gfs_jindex)]; - bh = bread(&sbd.buf_list, sbd1->sb_jindex_di.no_addr); - j_inode = gfs_inode_get(&sbd, bh); + j_inode = gfs_inode_read(&sbd, + sbd1->sb_jindex_di.no_addr); amt = gfs2_readi(j_inode, (void *)&jbuf, journal * sizeof(struct gfs_jindex), sizeof(struct gfs_jindex)); - brelse(bh); + inode_put(&j_inode); if (!amt) break; gfs_jindex_in(&ji, jbuf); @@ -451,10 +450,6 @@ static void get_journal_inode_blocks(void) if (journal > indirect->ii[0].dirents - 3) break; jblock = indirect->ii[0].dirent[journal + 2].block; - bh = bread(&sbd.buf_list, jblock); - j_inode = inode_get(&sbd, bh); - gfs2_dinode_in(&jdi, bh); - inode_put(j_inode); } journal_blocks[journals_found++] = jblock; } @@ -577,14 +572,13 @@ void savemeta(char *out_fn, int saveoption) last_fs_block, sbd.bsize); if (!slow) { if (gfs1) { - sbd.md.riinode = - gfs2_load_inode(&sbd, + sbd.md.riinode = inode_read(&sbd, sbd1->sb_rindex_di.no_addr); jindex_block = sbd1->sb_jindex_di.no_addr; } else { sbd.master_dir = - gfs2_load_inode(&sbd, - sbd.sd_sb.sb_master_dir.no_addr); + inode_read(&sbd, + sbd.sd_sb.sb_master_dir.no_addr); slow = gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode); diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index be9d3d0..71f1544 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -552,8 +552,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check, *clean_journals = 0; /* Get master dinode */ - sdp->master_dir = gfs2_load_inode(sdp, - sdp->sd_sb.sb_master_dir.no_addr); + sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr); gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode); /* read in the journal index data */ @@ -577,10 +576,10 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check, } *clean_journals += clean; } - inode_put(sdp->md.journal[i]); + inode_put(&sdp->md.journal[i]); } - inode_put(sdp->master_dir); - inode_put(sdp->md.jiinode); + inode_put(&sdp->master_dir); + inode_put(&sdp->md.jiinode); /* Sync the buffers to disk so we get a fresh start. */ bsync(&sdp->buf_list); return error; diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index bf3b74c..15c33f9 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -59,10 +59,10 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */ gfs2_grow or something. Count the RGs by hand. */ }; -struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block); -struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, +extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block); +extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); -void fsck_inode_put(struct gfs2_inode *ip); +extern void fsck_inode_put(struct gfs2_inode **ip); int initialize(struct gfs2_sbd *sbp, int force_check, int preen, int *all_clean); diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index 555e8e4..9d3def5 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -178,10 +178,9 @@ static int init_system_inodes(struct gfs2_sbd *sdp) log_info( _("Initializing special inodes...\n")); /* Get master dinode */ - sdp->master_dir = gfs2_load_inode(sdp, - sdp->sd_sb.sb_master_dir.no_addr); + sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr); /* Get root dinode */ - sdp->md.rooti = gfs2_load_inode(sdp, sdp->sd_sb.sb_root_dir.no_addr); + sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr); /* Look for "inum" entry in master dinode */ gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum); diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c index 4170380..cc2ba14 100644 --- a/gfs2/fsck/lost_n_found.c +++ b/gfs2/fsck/lost_n_found.c @@ -77,7 +77,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){ } memcpy(filename, tmp_name, filename_len); - if(gfs2_dirent_del(ip, NULL, filename, filename_len)) + if(gfs2_dirent_del(ip, filename, filename_len)) log_warn( _("add_inode_to_lf: " "Unable to remove \"..\" directory entry.\n")); diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 616cbdc..fba0c42 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -455,18 +455,18 @@ int main(int argc, char **argv) check_statfs(sbp); /* Free up our system inodes */ - inode_put(sbp->md.inum); - inode_put(sbp->md.statfs); + inode_put(&sbp->md.inum); + inode_put(&sbp->md.statfs); for (j = 0; j < sbp->md.journals; j++) - inode_put(sbp->md.journal[j]); - inode_put(sbp->md.jiinode); - inode_put(sbp->md.riinode); - inode_put(sbp->md.qinode); - inode_put(sbp->md.pinode); - inode_put(sbp->md.rooti); - inode_put(sbp->master_dir); + inode_put(&sbp->md.journal[j]); + inode_put(&sbp->md.jiinode); + inode_put(&sbp->md.riinode); + inode_put(&sbp->md.qinode); + inode_put(&sbp->md.pinode); + inode_put(&sbp->md.rooti); + inode_put(&sbp->master_dir); if (lf_dip) - inode_put(lf_dip); + inode_put(&lf_dip); if (!opts.no && errors_corrected) log_notice( _("Writing changes to disk\n")); diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index f34a185..bdb8b80 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -19,8 +19,6 @@ static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block) { - int j; - if (block == sbp->md.inum->i_di.di_num.no_addr) return sbp->md.inum; if (block == sbp->md.statfs->i_di.di_num.no_addr) @@ -39,10 +37,7 @@ static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, return sbp->master_dir; if (lf_dip && block == lf_dip->i_di.di_num.no_addr) return lf_dip; - for (j = 0; j < sbp->md.journals; j++) - if (block == sbp->md.journal[j]->i_di.di_num.no_addr) - return sbp->md.journal[j]; - return NULL; + return is_system_inode(sbp, block); } /* fsck_load_inode - same as gfs2_load_inode() in libgfs2 but system inodes @@ -52,11 +47,9 @@ struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block) struct gfs2_inode *ip = NULL; ip = get_system_inode(sbp, block); - if (ip) { - bhold(ip->i_bh); + if (ip) return ip; - } - return gfs2_load_inode(sbp, block); + return inode_read(sbp, block); } /* fsck_inode_get - same as inode_get() in libgfs2 but system inodes @@ -64,39 +57,25 @@ struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block) struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh) { - struct gfs2_inode *ip, *sysip; - - ip = calloc(1, sizeof(struct gfs2_inode)); - if (ip == NULL) { - fprintf(stderr, _("Out of memory in %s\n"), __FUNCTION__); - exit(-1); - } - gfs2_dinode_in(&ip->i_di, bh); - ip->i_bh = bh; - ip->i_sbd = sdp; + struct gfs2_inode *sysip; - sysip = get_system_inode(sdp, ip->i_di.di_num.no_addr); - if (sysip) { - free(ip); + sysip = get_system_inode(sdp, bh->b_blocknr); + if (sysip) return sysip; - } - return ip; + + return inode_get(sdp, bh); } /* fsck_inode_put - same as inode_put() in libgfs2 but system inodes get special treatment. */ -void fsck_inode_put(struct gfs2_inode *ip) +void fsck_inode_put(struct gfs2_inode **ip_in) { + struct gfs2_inode *ip = *ip_in; struct gfs2_inode *sysip; sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr); - if (sysip) { - if (ip->i_bh->b_changed) - gfs2_dinode_out(&ip->i_di, ip->i_bh); - brelse(ip->i_bh); - } else { - inode_put(ip); - } + if (!sysip) + inode_put(ip_in); } /** @@ -244,7 +223,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, } else { log_err( _("Corrupt directory entry " "repaired.\n")); - bmodified(bh); /* keep looping through dentries */ } } else { @@ -753,6 +731,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, GGGG when we finish. To do that, we set di_eattr to 0 temporarily. */ ip->i_di.di_eattr = 0; + bmodified(ip->i_bh); } ea_leaf_ptr++; } @@ -825,14 +804,12 @@ static int build_and_check_metalist(struct gfs2_inode *ip, struct metawalk_fxns *pass) { uint32_t height = ip->i_di.di_height; - struct gfs2_buffer_head *bh, *nbh, *metabh; + struct gfs2_buffer_head *bh, *nbh, *metabh = ip->i_bh; osi_list_t *prev_list, *cur_list, *tmp; int i, head_size; uint64_t *ptr, block; int err; - metabh = bread(&ip->i_sbd->buf_list, ip->i_di.di_num.no_addr); - osi_list_add(&metabh->b_altlist, &mlp[0]); /* if(<there are no indirect blocks to check>) */ @@ -877,8 +854,15 @@ static int build_and_check_metalist(struct gfs2_inode *ip, } if(err > 0) { log_debug( _("Skipping block %" PRIu64 - " (0x%" PRIx64 ")\n"), - block, block); + " (0x%" PRIx64 ")\n"), + block, block); + continue; + } + if (gfs2_check_range(ip->i_sbd, block)) { + log_debug( _("Skipping invalid block " + "%lld (0x%llx)\n"), + (unsigned long long)block, + (unsigned long long)block); continue; } if(!nbh) @@ -901,8 +885,6 @@ fail: osi_list_del(&nbh->b_altlist); } } - /* This is an error path, so we need to release the buffer here: */ - brelse(metabh); return -1; } @@ -951,14 +933,23 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_altlist); if (height > 1) { - /* if this isn't really a block list skip it */ - if (gfs2_check_meta(bh, GFS2_METATYPE_IN)) + if (gfs2_check_meta(bh, GFS2_METATYPE_IN)) { + if (bh == ip->i_bh) + osi_list_del(&bh->b_altlist); + else + brelse(bh); continue; + } head_size = sizeof(struct gfs2_meta_header); } else { /* if this isn't really a dinode, skip it */ - if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) + if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) { + if (bh == ip->i_bh) + osi_list_del(&bh->b_altlist); + else + brelse(bh); continue; + } head_size = sizeof(struct gfs2_dinode); } ptr = (uint64_t *)(bh->b_data + head_size); @@ -997,7 +988,10 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) { bh = osi_list_entry(list->next, struct gfs2_buffer_head, b_altlist); - brelse(bh); + if (bh == ip->i_bh) + osi_list_del(&bh->b_altlist); + else + brelse(bh); osi_list_del(&bh->b_altlist); } } @@ -1036,31 +1030,20 @@ static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass) { - struct gfs2_buffer_head *bh; struct gfs2_inode *ip; int error = 0; - bh = bread(&sbp->buf_list, block); - ip = fsck_inode_get(sbp, bh); + ip = fsck_load_inode(sbp, block); - if(ip->i_di.di_flags & GFS2_DIF_EXHASH) { + if(ip->i_di.di_flags & GFS2_DIF_EXHASH) error = check_leaf_blks(ip, pass); - if(error < 0) { - stack; - fsck_inode_put(ip); /* does brelse(bh); */ - return -1; - } - } - else { - error = check_linear_dir(ip, bh, pass); - if(error < 0) { - stack; - fsck_inode_put(ip); /* does brelse(bh); */ - return -1; - } - } + else + error = check_linear_dir(ip, ip->i_bh, pass); + + if(error < 0) + stack; - fsck_inode_put(ip); /* does a brelse */ + fsck_inode_put(&ip); /* does a brelse */ return error; } diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 3638102..40dc6e2 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -421,7 +421,6 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype, _("Extended Attribute leaf block " "has incorrect type")); } - bmodified(leaf_bh); brelse(leaf_bh); return 1; } @@ -687,7 +686,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, if(gfs2_block_check(sdp, bl, block, &q)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } if(q.block_type != gfs2_block_free) { @@ -695,10 +694,10 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, "#%" PRIu64 " (0x%" PRIx64 ")\n"), block, block); if(gfs2_block_mark(sdp, bl, block, gfs2_dup_block)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } @@ -709,12 +708,12 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_dir)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } if(add_to_dir_list(sdp, block)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -723,7 +722,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_file)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -732,7 +731,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_lnk)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -741,7 +740,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_blk)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -750,7 +749,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_chr)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -759,7 +758,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_fifo)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -768,7 +767,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_sock)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } break; @@ -777,16 +776,16 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } if(set_link_count(ip->i_sbd, ip->i_di.di_num.no_addr, ip->i_di.di_nlink)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } @@ -803,11 +802,11 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, log_warn( _("Marking inode invalid\n")); if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } } @@ -816,7 +815,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, error = check_metatree(ip, &pass1_fxns); if (fsck_abort || error < 0) { - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } if(error > 0) { @@ -828,7 +827,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, gfs2_block_set(sdp, bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE); - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } @@ -865,7 +864,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, (unsigned long long)ip->i_di.di_num.no_addr); } - fsck_inode_put(ip); + fsck_inode_put(&ip); return 0; } @@ -895,7 +894,6 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* handle_di calls inode_get, then inode_put, which does brelse. */ /* In order to prevent brelse from getting the count off, hold it. */ - bhold(bh); if(handle_di(sdp, bh, block)) { stack; return -1; diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 8eaca6f..a1b327a 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -336,14 +336,14 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block ")\n"), inode, inode, b->block_no, b->block_no); if(check_metatree(ip, &find_refs)) { stack; - fsck_inode_put(ip); /* out, brelse, free */ + fsck_inode_put(&ip); /* out, brelse, free */ return -1; } log_debug( _("Done checking metatree\n")); /* Check for ea references in the inode */ if(check_inode_eattr(ip, &find_refs) < 0){ stack; - fsck_inode_put(ip); /* out, brelse, free */ + fsck_inode_put(&ip); /* out, brelse, free */ return -1; } if (myfi.found) { @@ -363,7 +363,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block id->ea_only = myfi.ea_only; osi_list_add_prev(&id->list, &b->ref_inode_list); } - fsck_inode_put(ip); /* out, brelse, free */ + fsck_inode_put(&ip); /* out, brelse, free */ return 0; } @@ -428,7 +428,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) ip->i_di.di_num.no_addr, gfs2_meta_inval); bmodified(ip->i_bh); - fsck_inode_put(ip); + fsck_inode_put(&ip); } else { log_warn( _("The bad inode was not cleared.")); } @@ -474,7 +474,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); - fsck_inode_put(ip); /* out, brelse, free */ + fsck_inode_put(&ip); /* out, brelse, free */ dh.ref_inode_count--; if(dh.ref_inode_count == 1) break; diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index 9bb7b4a..4d9c820 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -258,6 +258,7 @@ int pass1c(struct gfs2_sbd *sbp) block_no, block_no); gfs2_special_clear(&sbp->eattr_blocks, block_no); ip = fsck_inode_get(sbp, bh); + ip->bh_owned = 1; log_debug( _("Found eattr at %llu (0x%llx)\n"), (unsigned long long)ip->i_di.di_eattr, @@ -269,7 +270,8 @@ int pass1c(struct gfs2_sbd *sbp) brelse(bh); return FSCK_ERROR; } - fsck_inode_put(ip); /* dinode_out, brelse, free */ + + fsck_inode_put(&ip); /* dinode_out, brelse, free */ } else { brelse(bh); } diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index f7ad911..40256a5 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -250,7 +250,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, check_inode_eattr(entry_ip, &pass2_fxns_delete); check_metatree(entry_ip, &pass2_fxns_delete); bmodified(entry_ip->i_bh); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); gfs2_block_set(sbp, bl, de->de_inum.no_addr, gfs2_block_free); @@ -306,7 +306,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, check_inode_eattr(entry_ip, &pass2_fxns_delete); check_metatree(entry_ip, &pass2_fxns_delete); bmodified(entry_ip->i_bh); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); gfs2_block_set(sbp, bl, de->de_inum.no_addr, gfs2_block_free); @@ -334,7 +334,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query( _("Clear stale directory entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -359,7 +359,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query( _("Clear duplicate '.' entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -394,7 +394,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query( _("Remove '.' reference? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -429,7 +429,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -454,7 +454,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query( _("Clear bad '..' directory entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); - fsck_inode_put(entry_ip); + fsck_inode_put(&entry_ip); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -544,7 +544,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, { uint64_t iblock = 0; struct dir_status ds = {0}; - struct gfs2_buffer_head b, *bh = &b; char *filename; int filename_len; char tmp_name[256]; @@ -574,7 +573,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, if (error > 0) gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval); - bh = bhold(sysinode->i_bh); if(check_inode_eattr(sysinode, &pass2_fxns)) { stack; return -1; @@ -603,7 +601,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, sysinode->i_di.di_num.no_addr); ds.entry_count++; free(filename); - bmodified(sysinode->i_bh); } else log_err( _("The directory was not fixed.\n")); } @@ -629,10 +626,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, sysinode->i_di.di_num.no_addr); } } - - if (!opts.no) - bmodified(bh); - brelse(bh); return 0; } @@ -666,7 +659,6 @@ int pass2(struct gfs2_sbd *sbp) struct gfs2_block_query q; struct dir_status ds = {0}; struct gfs2_inode *ip; - struct gfs2_buffer_head *bh = NULL; char *filename; int filename_len; char tmp_name[256]; @@ -720,11 +712,10 @@ int pass2(struct gfs2_sbd *sbp) * is valid */ ip = fsck_load_inode(sbp, i); if(check_metatree(ip, &pass2_fxns)) { - fsck_inode_put(ip); + fsck_inode_put(&ip); stack; return FSCK_ERROR; } - fsck_inode_put(ip); } error = check_dir(sbp, i, &pass2_fxns); if(error < 0) { @@ -762,8 +753,7 @@ int pass2(struct gfs2_sbd *sbp) } gfs2_block_set(sbp, bl, i, gfs2_meta_inval); } - bh = bread(&sbp->buf_list, i); - ip = fsck_inode_get(sbp, bh); + ip = fsck_load_inode(sbp, i); if(!ds.dotdir) { log_err(_("No '.' entry found for directory inode at " "block %"PRIu64" (0x%" PRIx64 ")\n"), i, i); @@ -793,7 +783,6 @@ int pass2(struct gfs2_sbd *sbp) ds.entry_count++; free(filename); log_err( _("The directory was fixed.\n")); - bmodified(ip->i_bh); } else { log_err( _("The directory was not fixed.\n")); } @@ -812,7 +801,7 @@ int pass2(struct gfs2_sbd *sbp) log_err( _("The entry count was not fixed.\n")); } } - fsck_inode_put(ip); /* does a gfs2_dinode_out, brelse */ + fsck_inode_put(&ip); /* does a gfs2_dinode_out, brelse */ } /* Now that we've deleted the inodes marked "bad" we can safely get rid of the duplicate block list. If we do it any sooner, diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c index 16fa086..feeebdc 100644 --- a/gfs2/fsck/pass3.c +++ b/gfs2/fsck/pass3.c @@ -32,29 +32,29 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot, filename_len = strlen(".."); if(!(filename = malloc((sizeof(char) * filename_len) + 1))) { log_err( _("Unable to allocate name\n")); - fsck_inode_put(ip); - fsck_inode_put(pip); + fsck_inode_put(&ip); + fsck_inode_put(&pip); stack; return -1; } if(!memset(filename, 0, (sizeof(char) * filename_len) + 1)) { log_err( _("Unable to zero name\n")); - fsck_inode_put(ip); - fsck_inode_put(pip); + fsck_inode_put(&ip); + fsck_inode_put(&pip); stack; return -1; } memcpy(filename, "..", filename_len); - if(gfs2_dirent_del(ip, NULL, filename, filename_len)) + if(gfs2_dirent_del(ip, filename, filename_len)) log_warn( _("Unable to remove \"..\" directory entry.\n")); else decrement_link(sbp, olddotdot); dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR); increment_link(sbp, newdotdot); bmodified(ip->i_bh); - fsck_inode_put(ip); + fsck_inode_put(&ip); bmodified(pip->i_bh); - fsck_inode_put(pip); + fsck_inode_put(&pip); return 0; } @@ -253,7 +253,7 @@ int pass3(struct gfs2_sbd *sbp) gfs2_block_set(sbp, bl, di->dinode, gfs2_block_free); - fsck_inode_put(ip); + fsck_inode_put(&ip); break; } else { log_err( _("Zero-size unlinked directory remains\n")); @@ -262,16 +262,16 @@ int pass3(struct gfs2_sbd *sbp) if(query( _("Add unlinked directory to " "lost+found? (y/n) "))) { if(add_inode_to_lf(ip)) { - fsck_inode_put(ip); + fsck_inode_put(&ip); stack; return FSCK_ERROR; } log_warn( _("Directory relinked to lost+found\n")); bmodified(ip->i_bh); - fsck_inode_put(ip); + fsck_inode_put(&ip); } else { log_err( _("Unlinked directory remains unlinked\n")); - fsck_inode_put(ip); + fsck_inode_put(&ip); } break; } diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c index 1ab18ea..6389342 100644 --- a/gfs2/fsck/pass4.c +++ b/gfs2/fsck/pass4.c @@ -75,7 +75,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { &pass4_fxns_delete); check_metatree(ip, &pass4_fxns_delete); bmodified(ip->i_bh); - fsck_inode_put(ip); + fsck_inode_put(&ip); gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); continue; @@ -104,7 +104,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { } else { log_err( _("The inode was not " "deleted\n")); - fsck_inode_put(ip); + fsck_inode_put(&ip); } continue; } @@ -118,16 +118,16 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { if(query( _("Clear zero-size unlinked inode? (y/n) "))) { gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); - fsck_inode_put(ip); + fsck_inode_put(&ip); continue; } } - if(query( _("Add unlinked inode to lost+found? (y/n)"))) { - bmodified(ip->i_bh); + if(query( _("Add unlinked inode to lost+found? " + "(y/n)"))) { if(add_inode_to_lf(ip)) { stack; - fsck_inode_put(ip); + fsck_inode_put(&ip); return -1; } else { @@ -136,7 +136,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { } } else log_err( _("Unlinked inode left unlinked\n")); - fsck_inode_put(ip); + fsck_inode_put(&ip); } /* if(ii->counted_links == 0) */ else if(ii->link_count != ii->counted_links) { log_err( _("Link count inconsistent for inode %" PRIu64 @@ -150,7 +150,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */ fix_inode_count(sbp, ii, ip); bmodified(ip->i_bh); - fsck_inode_put(ip); /* out, brelse, free */ + fsck_inode_put(&ip); /* out, brelse, free */ log_warn( _("Link count updated for inode %" PRIu64 " (0x%" PRIx64 ") \n"), ii->inode, ii->inode); } else { diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c index 19ebc38..4279d99 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -40,15 +40,76 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh) gfs2_dinode_in(&ip->i_di, bh); ip->i_bh = bh; ip->i_sbd = sdp; + ip->bh_owned = 0; /* caller did the bread so we don't own the bh */ return ip; } -void inode_put(struct gfs2_inode *ip) +struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr) { - if (ip->i_bh->b_changed) + struct gfs2_inode *ip; + + ip = calloc(1, sizeof(struct gfs2_inode)); + if (ip == NULL) { + fprintf(stderr, "Out of memory in %s\n", __FUNCTION__); + exit(-1); + } + ip->i_bh = bread(&sdp->buf_list, di_addr); + gfs2_dinode_in(&ip->i_di, ip->i_bh); + ip->i_sbd = sdp; + ip->bh_owned = 1; /* We did the bread so we own the bh */ + return ip; +} + +struct gfs2_inode *is_system_inode(struct gfs2_sbd *sdp, uint64_t block) +{ + int j; + + if (sdp->md.inum && block == sdp->md.inum->i_di.di_num.no_addr) + return sdp->md.inum; + if (sdp->md.statfs && block == sdp->md.statfs->i_di.di_num.no_addr) + return sdp->md.statfs; + if (sdp->md.jiinode && block == sdp->md.jiinode->i_di.di_num.no_addr) + return sdp->md.jiinode; + if (sdp->md.riinode && block == sdp->md.riinode->i_di.di_num.no_addr) + return sdp->md.riinode; + if (sdp->md.qinode && block == sdp->md.qinode->i_di.di_num.no_addr) + return sdp->md.qinode; + if (sdp->md.pinode && block == sdp->md.pinode->i_di.di_num.no_addr) + return sdp->md.pinode; + if (sdp->md.rooti && block == sdp->md.rooti->i_di.di_num.no_addr) + return sdp->md.rooti; + if (sdp->master_dir && block == sdp->master_dir->i_di.di_num.no_addr) + return sdp->master_dir; + for (j = 0; j < sdp->md.journals; j++) + if (sdp->md.journal && sdp->md.journal[j] && + block == sdp->md.journal[j]->i_di.di_num.no_addr) + return sdp->md.journal[j]; + return NULL; +} + +void inode_put(struct gfs2_inode **ip_in) +{ + struct gfs2_inode *ip = *ip_in; + uint64_t block = ip->i_di.di_num.no_addr; + struct gfs2_sbd *sdp = ip->i_sbd; + + if (ip->i_bh->b_changed) { gfs2_dinode_out(&ip->i_di, ip->i_bh); - brelse(ip->i_bh); + if (!ip->bh_owned && is_system_inode(sdp, block)) + fprintf(stderr, "Warning: Change made to inode " + "were discarded.\n"); + /* This is for debugging only: a convenient place to set + a breakpoint. This means a system inode was modified but + not written. That's not fatal: some places like + adjust_inode in gfs2_convert will do this on purpose. + It can also point out a coding problem, but we don't + want to raise alarm in the users either. */ + } + if (ip->bh_owned) + brelse(ip->i_bh); + ip->i_bh = NULL; free(ip); + *ip_in = NULL; /* make sure the memory isn't accessed again */ } static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type) @@ -126,6 +187,7 @@ uint64_t data_alloc(struct gfs2_inode *ip) uint64_t x; x = blk_alloc_i(ip->i_sbd, DATA); ip->i_di.di_goal_data = x; + bmodified(ip->i_bh); return x; } @@ -134,6 +196,7 @@ uint64_t meta_alloc(struct gfs2_inode *ip) uint64_t x; x = blk_alloc_i(ip->i_sbd, META); ip->i_di.di_goal_meta = x; + bmodified(ip->i_bh); return x; } @@ -321,6 +384,7 @@ void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, *ptr = cpu_to_be64(*block); bmodified(bh); ip->i_di.di_blocks++; + bmodified(ip->i_bh); *new = 1; } @@ -364,11 +428,12 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mp = find_metapath(ip, lblock); end_of_metadata = ip->i_di.di_height - 1; - bh = bhold(ip->i_bh); + bh = ip->i_bh; for (x = 0; x < end_of_metadata; x++) { lookup_block(ip, bh, x, mp, create, new, dblock); - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); if (!*dblock) goto out; @@ -379,8 +444,12 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; gfs2_meta_header_out(&mh, bh); - } else - bh = bread(&sdp->buf_list, *dblock); + } else { + if (*dblock == ip->i_di.di_num.no_addr) + bh = ip->i_bh; + else + bh = bread(&sdp->buf_list, *dblock); + } } if (!prealloc) @@ -408,7 +477,8 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, } } - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); out: free(mp); @@ -474,14 +544,17 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf, FALSE); if (dblock) { - bh = bread(&sdp->buf_list, dblock); + if (dblock == ip->i_di.di_num.no_addr) + bh = ip->i_bh; + else + bh = bread(&sdp->buf_list, dblock); dblock++; extlen--; } else bh = NULL; copy2mem(bh, &buf, o, amount); - if (bh) + if (bh && bh != ip->i_bh) brelse(bh); copied += amount; @@ -557,11 +630,15 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, mh.mh_format = GFS2_FORMAT_JD; gfs2_meta_header_out(&mh, bh); } - } else - bh = bread(&sdp->buf_list, dblock); + } else { + if (dblock == ip->i_di.di_num.no_addr) + bh = ip->i_bh; + else + bh = bread(&sdp->buf_list, dblock); + } copy_from_mem(bh, &buf, o, amount); - bmodified(bh); - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); copied += amount; lblock++; @@ -571,8 +648,10 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, o = (isdir) ? sizeof(struct gfs2_meta_header) : 0; } - if (ip->i_di.di_size < start + copied) + if (ip->i_di.di_size < start + copied) { + bmodified(ip->i_bh); ip->i_di.di_size = start + copied; + } return copied; } @@ -592,13 +671,18 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn, die("get_file_buf\n"); if (!prealloc && new && - ip->i_di.di_size < (lbn + 1) << sdp->sd_sb.sb_bsize_shift) + ip->i_di.di_size < (lbn + 1) << sdp->sd_sb.sb_bsize_shift) { + bmodified(ip->i_bh); ip->i_di.di_size = (lbn + 1) << sdp->sd_sb.sb_bsize_shift; - + } if (new) return bget(&sdp->buf_list, dbn); - else - return bread(&sdp->buf_list, dbn); + else { + if (dbn == ip->i_di.di_num.no_addr) + return ip->i_bh; + else + return bread(&sdp->buf_list, dbn); + } } int gfs2_dirent_first(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, @@ -657,6 +741,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, dent->de_name_len = cpu_to_be16(name_len); bmodified(bh); *dent_out = dent; + dip->i_di.di_entries++; + bmodified(dip->i_bh); return 0; } @@ -685,6 +771,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, *dent_out = new; bmodified(bh); + dip->i_di.di_entries++; + bmodified(dip->i_bh); return 0; } @@ -692,6 +780,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, *dent_out = dent; bmodified(bh); + dip->i_di.di_entries++; + bmodified(dip->i_bh); return 0; } } while (gfs2_dirent_next(dip, bh, &dent) == 0); @@ -705,9 +795,10 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, uint16_t cur_rec_len, prev_rec_len; bmodified(bh); - bmodified(dip->i_bh); - if (dip->i_di.di_entries) + if (dip->i_di.di_entries) { + bmodified(dip->i_bh); dip->i_di.di_entries--; + } if (!prev) { cur->de_inum.no_formal_ino = 0; return; @@ -847,8 +938,10 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea nleaf->lf_depth = oleaf->lf_depth; dip->i_di.di_blocks++; + bmodified(dip->i_bh); brelse(obh); + bmodified(nbh); brelse(nbh); } @@ -892,6 +985,7 @@ static void dir_double_exhash(struct gfs2_inode *dip) free(buf); dip->i_di.di_depth++; + bmodified(dip->i_bh); } /** @@ -1018,6 +1112,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, dirent_alloc(dip, nbh, len, &dent); dip->i_di.di_blocks++; + bmodified(dip->i_bh); bmodified(bh); brelse(bh); bh = nbh; @@ -1035,9 +1130,6 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, bmodified(bh); brelse(bh); - - dip->i_di.di_entries++; - bmodified(dip->i_bh); return; } } @@ -1101,6 +1193,8 @@ static void dir_make_exhash(struct gfs2_inode *dip) for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; dip->i_di.di_depth = y; + + gfs2_dinode_out(&dip->i_di, dip->i_bh); } static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len, @@ -1119,9 +1213,6 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len, dent->de_hash = cpu_to_be32(dent->de_hash); dent->de_type = cpu_to_be16(type); memcpy((char *)(dent + 1), filename, len); - - dip->i_di.di_entries++; - bmodified(dip->i_bh); } void dir_add(struct gfs2_inode *dip, const char *filename, int len, @@ -1213,13 +1304,16 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename, dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode)); - if(S_ISDIR(mode)) + if(S_ISDIR(mode)) { + bmodified(dip->i_bh); dip->i_di.di_nlink++; + } bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num); ip = inode_get(sdp, bh); bmodified(bh); } + ip->bh_owned = 1; return ip; } @@ -1335,7 +1429,7 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename, /* Find the entry */ do{ - if (bh) + if (bh && bh != dip->i_bh) brelse(bh); bh = bh_next; @@ -1350,14 +1444,16 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename, break; default: - brelse(bh); + if (bh && bh != dip->i_bh) + brelse(bh); return error; } error = get_next_leaf(dip, bh, &bh_next); } while (!error); - brelse(bh); + if (bh && bh != dip->i_bh) + brelse(bh); return error; } @@ -1402,21 +1498,18 @@ static int dir_e_search(struct gfs2_inode *dip, const char *filename, static int dir_l_search(struct gfs2_inode *dip, const char *filename, int len, unsigned int *type, struct gfs2_inum *inum) { - struct gfs2_buffer_head *dibh; struct gfs2_dirent *dent; int error; if(!inode_is_stuffed(dip)) return -1; - dibh = bread(&dip->i_sbd->buf_list, dip->i_di.di_num.no_addr); - error = leaf_search(dip, dibh, filename, len, &dent, NULL); + error = leaf_search(dip, dip->i_bh, filename, len, &dent, NULL); if (!error) { gfs2_inum_in(inum, (char *)&dent->de_inum); if(type) *type = be16_to_cpu(dent->de_type); } - brelse(dibh); return error; } @@ -1488,37 +1581,23 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len) return 0; } -static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh, - const char *filename, int len){ +static int dir_l_del(struct gfs2_inode *dip, const char *filename, int len) +{ int error=0; - int got_buf = 0; struct gfs2_dirent *cur, *prev; if(!inode_is_stuffed(dip)) return -1; - if(!dibh) { - dibh = bread(&dip->i_sbd->buf_list, dip->i_di.di_num.no_addr); - if (error) - return -1; - got_buf = 1; - } - - error = leaf_search(dip, dibh, filename, len, &cur, &prev); + error = leaf_search(dip, dip->i_bh, filename, len, &cur, &prev); if (error) { - if (got_buf) - brelse(dibh); if (error == -ENOENT) return 1; else return -1; } - dirent2_del(dip, dibh, prev, cur); - if (got_buf) { - bmodified(dibh); - brelse(dibh); - } + dirent2_del(dip, dip->i_bh, prev, cur); return 0; } @@ -1534,8 +1613,8 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh, * * Returns: 0 on success (or if it doesn't already exist), -1 on failure */ -int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, - const char *filename, int len){ +int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, int len) +{ int error; if(!S_ISDIR(dip->i_di.di_mode)) @@ -1544,7 +1623,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, if (dip->i_di.di_flags & GFS2_DIF_EXHASH) error = dir_e_del(dip, filename, len); else - error = dir_l_del(dip, bh, filename, len); + error = dir_l_del(dip, filename, len); bmodified(dip->i_bh); return error; } @@ -1578,7 +1657,7 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len, return 0; } else - *ipp = gfs2_load_inode(sdp, inum.no_addr); + *ipp = inode_read(sdp, inum.no_addr); return error; } @@ -1650,8 +1729,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) } /* Set the bitmap type for inode to free space: */ gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE); - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); /* Now we have to adjust the rg freespace count and inode count: */ rgd = gfs2_blk2rgrpd(sdp, diblock); rgd->rg.rg_free++; diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c index a06fe11..5232c01 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -98,11 +98,12 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mp = find_metapath(ip, lblock); end_of_metadata = ip->i_di.di_height - 1; - bh = bhold(ip->i_bh); + bh = ip->i_bh; for (x = 0; x < end_of_metadata; x++) { gfs1_lookup_block(ip, bh, x, mp, create, new, dblock); - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); if (!*dblock) goto out; @@ -146,7 +147,8 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, } } - brelse(bh); + if (bh != ip->i_bh) + brelse(bh); out: free(mp); @@ -395,5 +397,49 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp, ip->i_di.di_eattr = gfs1_dinode.di_eattr; ip->i_bh = bh; ip->i_sbd = sdp; + ip->bh_owned = 0; + return ip; +} + +struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr) +{ + struct gfs_dinode gfs1_dinode; + struct gfs2_inode *ip; + + ip = calloc(1, sizeof(struct gfs2_inode)); + if (ip == NULL) { + fprintf(stderr, "Out of memory in %s\n", __FUNCTION__); + exit(-1); + } + + ip->i_bh = bread(&sdp->buf_list, di_addr); + gfs_dinode_in(&gfs1_dinode, ip->i_bh); + memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header, + sizeof(struct gfs2_meta_header)); + memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num, + sizeof(struct gfs2_inum)); + ip->i_di.di_mode = gfs1_dinode.di_mode; + ip->i_di.di_uid = gfs1_dinode.di_uid; + ip->i_di.di_gid = gfs1_dinode.di_gid; + ip->i_di.di_nlink = gfs1_dinode.di_nlink; + ip->i_di.di_size = gfs1_dinode.di_size; + ip->i_di.di_blocks = gfs1_dinode.di_blocks; + ip->i_di.di_atime = gfs1_dinode.di_atime; + ip->i_di.di_mtime = gfs1_dinode.di_mtime; + ip->i_di.di_ctime = gfs1_dinode.di_ctime; + ip->i_di.di_major = gfs1_dinode.di_major; + ip->i_di.di_minor = gfs1_dinode.di_minor; + ip->i_di.di_goal_data = gfs1_dinode.di_goal_dblk; + ip->i_di.di_goal_meta = gfs1_dinode.di_goal_mblk; + ip->i_di.di_flags = gfs1_dinode.di_flags; + ip->i_di.di_payload_format = gfs1_dinode.di_payload_format; + ip->i_di.__pad1 = gfs1_dinode.di_type; + ip->i_di.di_height = gfs1_dinode.di_height; + ip->i_di.di_depth = gfs1_dinode.di_depth; + ip->i_di.di_entries = gfs1_dinode.di_entries; + ip->i_di.di_eattr = gfs1_dinode.di_eattr; + ip->i_sbd = sdp; + ip->bh_owned = 1; return ip; } + diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 49bc151..643c728 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -129,6 +129,7 @@ struct special_blocks { struct gfs2_sbd; struct gfs2_inode { + int bh_owned; /* Is this bh owned, iow, should we release it later? */ struct gfs2_dinode i_di; struct gfs2_buffer_head *i_bh; struct gfs2_sbd *i_sbd; @@ -409,7 +410,10 @@ extern void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, int create, int *new, uint64_t *block); extern struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); -extern void inode_put(struct gfs2_inode *ip); +extern struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr); +extern struct gfs2_inode *is_system_inode(struct gfs2_sbd *sdp, + uint64_t block); +extern void inode_put(struct gfs2_inode **ip); extern uint64_t data_alloc(struct gfs2_inode *ip); extern uint64_t meta_alloc(struct gfs2_inode *ip); extern uint64_t dinode_alloc(struct gfs2_sbd *sdp); @@ -427,13 +431,12 @@ extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename, unsigned int mode, uint32_t flags); extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, struct gfs2_dirent *prev, struct gfs2_dirent *cur); -extern struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block); extern int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len, struct gfs2_inode **ipp); extern void dir_add(struct gfs2_inode *dip, const char *filename, int len, struct gfs2_inum *inum, unsigned int type); -extern int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, - const char *filename, int filename_len); +extern int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, + int filename_len); extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, uint64_t *dblock, uint32_t *extlen, int prealloc); extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index, @@ -529,6 +532,8 @@ extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1); extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet); extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); +extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, + uint64_t di_addr); /* gfs2_log.c */ struct gfs2_options { diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c index 6a481bc..5343f88 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -30,6 +30,7 @@ int build_master(struct gfs2_sbd *sdp) printf("\nMaster dir:\n"); gfs2_dinode_print(&sdp->master_dir->i_di); } + sdp->master_dir->bh_owned = 1; return 0; } @@ -110,6 +111,7 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j, hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); ((struct gfs2_log_header *)bh->b_data)->lh_hash = cpu_to_be32(hash); + bmodified(bh); brelse(bh); if (++seq == blocks) @@ -142,8 +144,7 @@ int build_jindex(struct gfs2_sbd *sdp) sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift); if (ret) return ret; - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); } if (sdp->debug) { @@ -151,8 +152,7 @@ int build_jindex(struct gfs2_sbd *sdp) gfs2_dinode_print(&jindex->i_di); } - bmodified(jindex->i_bh); - inode_put(jindex); + inode_put(&jindex); return 0; } @@ -166,14 +166,14 @@ static int build_inum_range(struct gfs2_inode *per_node, unsigned int j) ip = createi(per_node, name, S_IFREG | 0600, GFS2_DIF_SYSTEM | GFS2_DIF_JDATA); ip->i_di.di_size = sizeof(struct gfs2_inum_range); + gfs2_dinode_out(&ip->i_di, ip->i_bh); if (sdp->debug) { printf("\nInum Range %u:\n", j); gfs2_dinode_print(&ip->i_di); } - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); return 0; } @@ -187,14 +187,14 @@ static void build_statfs_change(struct gfs2_inode *per_node, unsigned int j) ip = createi(per_node, name, S_IFREG | 0600, GFS2_DIF_SYSTEM | GFS2_DIF_JDATA); ip->i_di.di_size = sizeof(struct gfs2_statfs_change); + gfs2_dinode_out(&ip->i_di, ip->i_bh); if (sdp->debug) { printf("\nStatFS Change %u:\n", j); gfs2_dinode_print(&ip->i_di); } - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); } static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) @@ -230,8 +230,7 @@ static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) gfs2_dinode_print(&ip->i_di); } - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); return 0; } @@ -254,8 +253,7 @@ int build_per_node(struct gfs2_sbd *sdp) gfs2_dinode_print(&per_node->i_di); } - bmodified(per_node->i_bh); - inode_put(per_node); + inode_put(&per_node); return 0; } @@ -302,6 +300,7 @@ int build_rindex(struct gfs2_sbd *sdp) ip = createi(sdp->master_dir, "rindex", S_IFREG | 0600, GFS2_DIF_SYSTEM | GFS2_DIF_JDATA); ip->i_di.di_payload_format = GFS2_FORMAT_RI; + bmodified(ip->i_bh); for (head = &sdp->rglist, tmp = head->next; tmp != head; @@ -321,8 +320,7 @@ int build_rindex(struct gfs2_sbd *sdp) gfs2_dinode_print(&ip->i_di); } - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); return 0; } @@ -336,6 +334,7 @@ int build_quota(struct gfs2_sbd *sdp) ip = createi(sdp->master_dir, "quota", S_IFREG | 0600, GFS2_DIF_SYSTEM | GFS2_DIF_JDATA); ip->i_di.di_payload_format = GFS2_FORMAT_QU; + bmodified(ip->i_bh); memset(&qu, 0, sizeof(struct gfs2_quota)); qu.qu_value = 1; @@ -353,8 +352,7 @@ int build_quota(struct gfs2_sbd *sdp) gfs2_quota_print(&qu); } - bmodified(ip->i_bh); - inode_put(ip); + inode_put(&ip); return 0; } @@ -375,6 +373,7 @@ int build_root(struct gfs2_sbd *sdp) printf("\nRoot directory:\n"); gfs2_dinode_print(&sdp->md.rooti->i_di); } + sdp->md.rooti->bh_owned = 1; return 0; } @@ -418,16 +417,6 @@ int do_init_statfs(struct gfs2_sbd *sdp) return 0; } -struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block) -{ - struct gfs2_buffer_head *bh; - struct gfs2_inode *ip; - - bh = bread(&sbp->buf_list, block); - ip = inode_get(sbp, bh); - return ip; -} - int gfs2_check_meta(struct gfs2_buffer_head *bh, int type) { uint32_t check_magic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic; diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c index 52b8c38..2da353a 100644 --- a/gfs2/mkfs/main_grow.c +++ b/gfs2/mkfs/main_grow.c @@ -167,11 +167,8 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count) /* Build the remaining resource groups */ build_rgrps(sdp, !test); - /* Note: We do inode_put with not_updated because we only updated */ - /* the new RGs/bitmaps themselves on disk. The rindex file must */ - /* be updated through the meta_fs so the gfs2 kernel is informed. */ - inode_put(sdp->md.riinode); - inode_put(sdp->master_dir); + inode_put(&sdp->md.riinode); + inode_put(&sdp->master_dir); /* We're done with the libgfs portion, so commit it to disk. */ bsync(&sdp->buf_list); @@ -317,7 +314,7 @@ main_grow(int argc, char *argv[]) } /* Get master dinode */ sdp->master_dir = - gfs2_load_inode(sdp, sdp->sd_sb.sb_master_dir.no_addr); + inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr); gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode); /* Fetch the rindex from disk. We aren't using gfs2 here, */ /* which means that the bitmaps will most likely be cached */ diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 6ebaa99..3d3012f 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -637,14 +637,10 @@ void main_mkfs(int argc, char *argv[]) /* Cleanup */ - bmodified(sdp->md.rooti->i_bh); - inode_put(sdp->md.rooti); - bmodified(sdp->master_dir->i_bh); - inode_put(sdp->master_dir); - bmodified(sdp->md.inum->i_bh); - inode_put(sdp->md.inum); - bmodified(sdp->md.statfs->i_bh); - inode_put(sdp->md.statfs); + inode_put(&sdp->md.rooti); + inode_put(&sdp->master_dir); + inode_put(&sdp->md.inum); + inode_put(&sdp->md.statfs); bsync(&sdp->buf_list); error = fsync(sdp->device_fd);
1
0
0
0
cluster: STABLE3 - Make struct_out functions operate on bh's
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=89…
Commit: 8956735abb1523be8d63cfbbb55d16c535795cae Parent: 8a6c9c5238df2449dd05b27a0a2b25c098961962 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Sat Jan 16 12:07:00 2010 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 Make struct_out functions operate on bh's This patch changes most the gfs2_struct_in and gfs2_struct_out functions so that they take a bh parameter rather than a buffer. It ensures that whenever a structure is pushed to a buffer, the buffer is marked as modified so that it later gets written to disk. This is one step in getting rid of the buffer lists and helps ensure data integrity. This takes most of the guess-work out of the buffer writing: No more "rewrite the buffer because it may or may not have been changed." Some structures, such as rindex entries and dentry pointers, can't operate on a bh, mostly because they use the readi/writei functions to write the data out, but this covers the majority of gfs2 structures. rhbz#455300 --- gfs2/convert/gfs2_convert.c | 17 ++-- gfs2/edit/gfs2hex.c | 51 ++++++----- gfs2/edit/gfs2hex.h | 2 +- gfs2/edit/hexedit.c | 210 +++++++++++++++++++++---------------------- gfs2/edit/hexedit.h | 13 ++-- gfs2/edit/savemeta.c | 63 ++++++-------- gfs2/fsck/fs_recovery.c | 3 +- gfs2/fsck/main.c | 21 +++-- gfs2/fsck/metawalk.c | 19 ++--- gfs2/fsck/pass1.c | 4 +- gfs2/fsck/pass1b.c | 2 +- gfs2/fsck/pass5.c | 2 +- gfs2/fsck/rgrepair.c | 5 +- gfs2/libgfs2/fs_geometry.c | 5 +- gfs2/libgfs2/fs_ops.c | 35 +++---- gfs2/libgfs2/gfs1.c | 11 +-- gfs2/libgfs2/libgfs2.h | 44 ++++++---- gfs2/libgfs2/ondisk.c | 136 ++++++++++++++-------------- gfs2/libgfs2/recovery.c | 2 +- gfs2/libgfs2/rgrp.c | 2 +- gfs2/libgfs2/structures.c | 9 +-- gfs2/libgfs2/super.c | 5 +- gfs2/mkfs/main_jadd.c | 8 ++- gfs2/quota/main.c | 6 +- gfs2/tool/sb.c | 6 +- 25 files changed, 335 insertions(+), 346 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 13ba9d7..ba21e94 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -207,7 +207,7 @@ static int convert_rgs(struct gfs2_sbd *sbp) sbp->dinodes_alloced += rgd1->rg_useddi; convert_bitmaps(sbp, rgd); /* Write the updated rgrp to the gfs2 buffer */ - gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); rgs++; if (rgs % 100 == 0) { printf("."); @@ -322,7 +322,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, bh = bread(&sbp->buf_list, block); if (new) memset(bh->b_data, 0, sbp->bsize); - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } hdrsize = sizeof(struct gfs2_meta_header); @@ -660,7 +660,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh) return -1; } - gfs2_dinode_out(&inode->i_di, bh->b_data); + gfs2_dinode_out(&inode->i_di, bh); sbp->md.next_inum++; /* update inode count */ return 0; } /* adjust_inode */ @@ -908,7 +908,7 @@ static int fix_one_directory_exhash(struct gfs2_sbd *sbp, struct gfs2_inode *dip log_crit("Error reading leaf %" PRIx64 "\n", leaf_block); break; } - gfs2_leaf_in(&leaf, (char *)bh_leaf->b_data); /* buffer to structure */ + gfs2_leaf_in(&leaf, bh_leaf); /* buffer to structure */ error = process_dirent_info(dip, sbp, bh_leaf, leaf.lf_entries); bmodified(bh_leaf); brelse(bh_leaf); @@ -1089,7 +1089,7 @@ static int init(struct gfs2_sbd *sbp) bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data, sizeof(struct gfs1_sb)); - gfs2_sb_in(&sbp->sd_sb, bh->b_data); + gfs2_sb_in(&sbp->sd_sb, bh); sbp->bsize = sbp->sd_sb.sb_bsize; sbp->sd_inptrs = (sbp->bsize - sizeof(struct gfs_indirect)) / sizeof(uint64_t); @@ -1385,9 +1385,9 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) convert_bitmaps(sdp, rgd); for (x = 0; x < rgd->ri.ri_length; x++) { if (x) - gfs2_meta_header_out(&mh, rgd->bh[x]->b_data); + gfs2_meta_header_out(&mh, rgd->bh[x]); else - gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data); + gfs2_rgrp_out(&rgd->rg, rgd->bh[x]); } /* Add the new gfs2 rg to our list: We'll output the rg index later. */ osi_list_add_prev((osi_list_t *)&rgd->list, @@ -1614,8 +1614,7 @@ int main(int argc, char **argv) bh = bread(&sb2.buf_list, sb2.sb_addr); sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS; sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI; - gfs2_sb_out(&sb2.sd_sb, bh->b_data); - bmodified(bh); + gfs2_sb_out(&sb2.sd_sb, bh); brelse(bh); bsync(&sb2.buf_list); /* write the buffers to disk */ diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c index 1d34730..55f36db 100644 --- a/gfs2/edit/gfs2hex.c +++ b/gfs2/edit/gfs2hex.c @@ -28,7 +28,7 @@ struct gfs2_sb sb; -char *buf; +struct gfs2_buffer_head *bh; struct gfs2_dinode di; int line, termlines; char edit_fmt[80]; @@ -276,7 +276,7 @@ static int indirect_dirent(struct indirect_info *indir, char *ptr, int d) ** ******************************************************************************* ******************************************************************************/ -void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) +void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh) { unsigned int x, y, ptroff = 0; uint64_t p, last; @@ -289,7 +289,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) /* Indirect pointers */ for (x = sizeof(struct gfs2_dinode); x < sbd.bsize; x += sizeof(uint64_t)) { - p = be64_to_cpu(*(uint64_t *)(dinebuf + x)); + p = be64_to_cpu(*(uint64_t *)(lbh->b_data + x)); if (p) { indirect->ii[indirect_blocks].block = p; indirect->ii[indirect_blocks].mp.mp_list[0] = @@ -308,8 +308,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) indirect->ii[0].block = block; indirect->ii[0].is_dir = TRUE; for (x = sizeof(struct gfs2_dinode); x < sbd.bsize; x += skip) { - skip = indirect_dirent(indirect->ii, - dinebuf + x, + skip = indirect_dirent(indirect->ii, lbh->b_data + x, indirect->ii[0].dirents); if (skip <= 0) break; @@ -320,12 +319,13 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) dine->di_height == 0) { /* Leaf Pointers: */ - last = be64_to_cpu(*(uint64_t *)(dinebuf + sizeof(struct gfs2_dinode))); + last = be64_to_cpu(*(uint64_t *)(lbh->b_data + + sizeof(struct gfs2_dinode))); for (x = sizeof(struct gfs2_dinode), y = 0; y < (1 << dine->di_depth); x += sizeof(uint64_t), y++) { - p = be64_to_cpu(*(uint64_t *)(dinebuf + x)); + p = be64_to_cpu(*(uint64_t *)(lbh->b_data + x)); if (p != last || ((y + 1) * sizeof(uint64_t) == dine->di_size)) { struct gfs2_buffer_head *tmp_bh; @@ -336,7 +336,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) if (last >= max_block) break; tmp_bh = bread(&sbd.buf_list, last); - gfs2_leaf_in(&leaf, tmp_bh->b_data); + gfs2_leaf_in(&leaf, tmp_bh); indirect->ii[indirect_blocks].dirents = 0; for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf); bufoffset < sbd.bsize; @@ -461,7 +461,7 @@ void do_leaf_extended(char *dlebuf, struct iinfo *indir) ******************************************************************************* ******************************************************************************/ -static void do_eattr_extended(char *deebuf) +static void do_eattr_extended(struct gfs2_buffer_head *ebh) { struct gfs2_ea_header ea; unsigned int x; @@ -473,8 +473,9 @@ static void do_eattr_extended(char *deebuf) for (x = sizeof(struct gfs2_meta_header); x < sbd.bsize; x += ea.ea_rec_len) { eol(0); - gfs2_ea_header_in(&ea, deebuf + x); - gfs2_ea_header_print(&ea, deebuf + x + sizeof(struct gfs2_ea_header)); + gfs2_ea_header_in(&ea, ebh->b_data + x); + gfs2_ea_header_print(&ea, ebh->b_data + x + + sizeof(struct gfs2_ea_header)); } } @@ -532,11 +533,11 @@ static void gfs2_sb_print2(struct gfs2_sb *sbp2) /** * gfs1_rgrp_in - read in a gfs1 rgrp */ -static void gfs1_rgrp_in(struct gfs1_rgrp *rgrp, char *rbuf) +static void gfs1_rgrp_in(struct gfs1_rgrp *rgrp, struct gfs2_buffer_head *rbh) { - struct gfs1_rgrp *str = (struct gfs1_rgrp *)rbuf; + struct gfs1_rgrp *str = (struct gfs1_rgrp *)rbh->b_data; - gfs2_meta_header_in(&rgrp->rg_header, rbuf); + gfs2_meta_header_in(&rgrp->rg_header, rbh); rgrp->rg_flags = be32_to_cpu(str->rg_flags); rgrp->rg_free = be32_to_cpu(str->rg_free); rgrp->rg_useddi = be32_to_cpu(str->rg_useddi); @@ -592,12 +593,12 @@ int display_gfs2(void) uint32_t magic; - magic = be32_to_cpu(*(uint32_t *)buf); + magic = be32_to_cpu(*(uint32_t *)bh->b_data); switch (magic) { case GFS2_MAGIC: - gfs2_meta_header_in(&mh, buf); + gfs2_meta_header_in(&mh, bh); if (mh.mh_type > GFS2_METATYPE_QC) print_gfs2("Unknown metadata type"); else @@ -607,7 +608,7 @@ int display_gfs2(void) switch (mh.mh_type) { case GFS2_METATYPE_SB: - gfs2_sb_in(&sbd.sd_sb, buf); + gfs2_sb_in(&sbd.sd_sb, bh); gfs2_sb_print2(&sbd.sd_sb); break; @@ -615,10 +616,10 @@ int display_gfs2(void) if (gfs1) { struct gfs1_rgrp rg1; - gfs1_rgrp_in(&rg1, buf); + gfs1_rgrp_in(&rg1, bh); gfs1_rgrp_print(&rg1); } else { - gfs2_rgrp_in(&rg, buf); + gfs2_rgrp_in(&rg, bh); gfs2_rgrp_print(&rg); } break; @@ -636,7 +637,7 @@ int display_gfs2(void) break; case GFS2_METATYPE_LF: - gfs2_leaf_in(&lf, buf); + gfs2_leaf_in(&lf, bh); gfs2_leaf_print(&lf); break; @@ -646,21 +647,21 @@ int display_gfs2(void) case GFS2_METATYPE_LH: if (gfs1) { - gfs_log_header_in(&lh1, buf); + gfs_log_header_in(&lh1, bh); gfs_log_header_print(&lh1); } else { - gfs2_log_header_in(&lh, buf); + gfs2_log_header_in(&lh, bh); gfs2_log_header_print(&lh); } break; case GFS2_METATYPE_LD: - gfs2_log_descriptor_in(&ld, buf); + gfs2_log_descriptor_in(&ld, bh); gfs2_log_descriptor_print(&ld); break; case GFS2_METATYPE_EA: - do_eattr_extended(buf); + do_eattr_extended(bh); break; case GFS2_METATYPE_ED: @@ -672,7 +673,7 @@ int display_gfs2(void) break; case GFS2_METATYPE_QC: - gfs2_quota_change_in(&qc, buf); + gfs2_quota_change_in(&qc, bh); gfs2_quota_change_print(&qc); break; diff --git a/gfs2/edit/gfs2hex.h b/gfs2/edit/gfs2hex.h index 5a351d6..d18dd59 100644 --- a/gfs2/edit/gfs2hex.h +++ b/gfs2/edit/gfs2hex.h @@ -5,7 +5,7 @@ int display_gfs2(void); int edit_gfs2(void); -void do_dinode_extended(struct gfs2_dinode *di, char *buf); +void do_dinode_extended(struct gfs2_dinode *di, struct gfs2_buffer_head *lbh); void print_gfs2(const char *fmt, ...); int do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt); void do_leaf_extended(char *dlebuf, struct iinfo *indir); diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 437d931..a277b7a 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -427,9 +427,10 @@ static void print_usage(void) /* returns: metatype if block is a GFS2 structure block type */ /* 0 if block is not a GFS2 structure */ /* ------------------------------------------------------------------------ */ -static int get_block_type(const char *lpBuffer) +static int get_block_type(struct gfs2_buffer_head *lbh) { int ret_type = 0; + char *lpBuffer = lbh->b_data; if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 && *(lpBuffer+2)==0x19 && *(lpBuffer+3)==0x70 && @@ -444,7 +445,7 @@ static int get_block_type(const char *lpBuffer) /* returns: metatype if block is a GFS2 structure block type */ /* 0 if block is not a GFS2 structure */ /* ------------------------------------------------------------------------ */ -int display_block_type(const char *lpBuffer, int from_restore) +int display_block_type(int from_restore) { int ret_type = 0; /* return type */ @@ -481,8 +482,8 @@ int display_block_type(const char *lpBuffer, int from_restore) ret_type = GFS2_METATYPE_RG; struct_len = gfs1 ? sizeof(struct gfs_rgrp) : sizeof(struct gfs2_rgrp); } - else if ((ret_type = get_block_type(lpBuffer))) { - switch (*(lpBuffer+7)) { + else if ((ret_type = get_block_type(bh))) { + switch (*(bh->b_data + 7)) { case GFS2_METATYPE_SB: /* 1 */ print_gfs2("(superblock)"); if (gfs1) @@ -578,9 +579,9 @@ int display_block_type(const char *lpBuffer, int from_restore) sbd.bsize / screen_chunk_size + 1 : sbd.bsize / screen_chunk_size, allocdesc[gfs1][type]); /*eol(9);*/ - if ((*(lpBuffer+7) == GFS2_METATYPE_IN) || - (*(lpBuffer+7) == GFS2_METATYPE_DI && - (*(lpBuffer + 0x8b) || *(lpBuffer + 0x8a)))) { + if ((*(bh->b_data + 7) == GFS2_METATYPE_IN) || + (*(bh->b_data + 7) == GFS2_METATYPE_DI && + (*(bh->b_data + 0x8b) || *(bh->b_data + 0x8a)))) { int ptroffset = edit_row[dmode] * 16 + edit_col[dmode]; if (ptroffset >= struct_len || pgnum) { @@ -639,11 +640,12 @@ int display_block_type(const char *lpBuffer, int from_restore) /* ------------------------------------------------------------------------ */ /* hexdump - hex dump the filesystem block to the screen */ /* ------------------------------------------------------------------------ */ -static int hexdump(uint64_t startaddr, const char *lpBuffer, int len) +static int hexdump(uint64_t startaddr, int len) { const unsigned char *pointer,*ptr2; int i; uint64_t l; + const char *lpBuffer = bh->b_data; strcpy(edit_fmt,"%02X"); pointer = (unsigned char *)lpBuffer + offset; @@ -817,11 +819,11 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg) /* ------------------------------------------------------------------------ */ /* gfs_rgrp_in - Read in a resource group header */ /* ------------------------------------------------------------------------ */ -static void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *gbuf) +static void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh) { - struct gfs_rgrp *str = (struct gfs_rgrp *)gbuf; + struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data; - gfs2_meta_header_in(&rgrp->rg_header, gbuf); + gfs2_meta_header_in(&rgrp->rg_header, rbh); rgrp->rg_flags = be32_to_cpu(str->rg_flags); rgrp->rg_free = be32_to_cpu(str->rg_free); rgrp->rg_useddi = be32_to_cpu(str->rg_useddi); @@ -834,11 +836,11 @@ static void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *gbuf) /* ------------------------------------------------------------------------ */ /* gfs_rgrp_out */ /* ------------------------------------------------------------------------ */ -static void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *gbuf) +static void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh) { - struct gfs_rgrp *str = (struct gfs_rgrp *)gbuf; + struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data; - gfs2_meta_header_out(&rgrp->rg_header, gbuf); + gfs2_meta_header_out(&rgrp->rg_header, rbh); str->rg_flags = cpu_to_be32(rgrp->rg_flags); str->rg_free = cpu_to_be32(rgrp->rg_free); str->rg_useddi = cpu_to_be32(rgrp->rg_useddi); @@ -868,7 +870,7 @@ static void gfs_rgrp_print(struct gfs_rgrp *rg) /* ------------------------------------------------------------------------ */ static uint64_t get_rg_addr(int rgnum) { - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; uint64_t rgblk = 0, gblock; struct gfs2_inode *riinode; @@ -876,8 +878,8 @@ static uint64_t get_rg_addr(int rgnum) gblock = sbd1->sb_rindex_di.no_addr; else gblock = masterblock("rindex"); - bh = bread(&sbd.buf_list, gblock); - riinode = inode_get(&sbd, bh); + lbh = bread(&sbd.buf_list, gblock); + riinode = inode_get(&sbd, lbh); if (rgnum < riinode->i_di.di_size / risize()) rgblk = find_rgrp_block(riinode, rgnum); else @@ -900,26 +902,25 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) struct gfs2_rgrp rg2; struct gfs_rgrp rg1; } rg; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *rbh; uint64_t rgblk; rgblk = get_rg_addr(rgnum); - bh = bread(&sbd.buf_list, rgblk); + rbh = bread(&sbd.buf_list, rgblk); if (gfs1) - gfs_rgrp_in(&rg.rg1, bh->b_data); + gfs_rgrp_in(&rg.rg1, rbh); else - gfs2_rgrp_in(&rg.rg2, bh->b_data); + gfs2_rgrp_in(&rg.rg2, rbh); if (modify) { printf("RG #%d (block %llu / 0x%llx) rg_flags changed from 0x%08x to 0x%08x\n", rgnum, (unsigned long long)rgblk, (unsigned long long)rgblk, rg.rg2.rg_flags, new_flags); rg.rg2.rg_flags = new_flags; if (gfs1) - gfs_rgrp_out(&rg.rg1, bh->b_data); + gfs_rgrp_out(&rg.rg1, rbh); else - gfs2_rgrp_out(&rg.rg2, bh->b_data); - bmodified(bh); - brelse(bh); + gfs2_rgrp_out(&rg.rg2, rbh); + brelse(rbh); } else { if (full) { print_gfs2("RG #%d", rgnum); @@ -934,7 +935,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) printf("RG #%d (block %llu / 0x%llx) rg_flags = 0x%08x\n", rgnum, (unsigned long long)rgblk, (unsigned long long)rgblk, rg.rg2.rg_flags); - brelse(bh); + brelse(rbh); } if (modify) bsync(&sbd.buf_list); @@ -992,11 +993,11 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex) tmp_bh = bread(&sbd.buf_list, ri.ri_addr); if (gfs1) { struct gfs_rgrp rg1; - gfs_rgrp_in(&rg1, tmp_bh->b_data); + gfs_rgrp_in(&rg1, tmp_bh); gfs_rgrp_print(&rg1); } else { struct gfs2_rgrp rg; - gfs2_rgrp_in(&rg, tmp_bh->b_data); + gfs2_rgrp_in(&rg, tmp_bh); gfs2_rgrp_print(&rg); } brelse(tmp_bh); @@ -1602,9 +1603,9 @@ int block_is_in_per_node(void) return FALSE; per_node_bh = bread(&sbd.buf_list, masterblock("per_node")); - gfs2_dinode_in(&per_node_di, per_node_bh->b_data); + gfs2_dinode_in(&per_node_di, per_node_bh); - do_dinode_extended(&per_node_di, per_node_bh->b_data); + do_dinode_extended(&per_node_di, per_node_bh); brelse(per_node_bh); for (d = 0; d < indirect->ii[0].dirents; d++) { @@ -1696,15 +1697,10 @@ static void read_superblock(int fd) sbd1 = (struct gfs_sb *)&sbd.sd_sb; ioctl(fd, BLKFLSBUF, 0); - lseek(fd, 0x10 * 4096, SEEK_SET); - if (read(fd, buf, sbd.bsize) != sbd.bsize) { - fprintf(stderr, "bad read: %s from %s:%d: superblock\n", - strerror(errno), __FUNCTION__, __LINE__); - exit(-1); - } memset(&sbd, 0, sizeof(struct gfs2_sbd)); - sbd.device_fd = fd; sbd.bsize = GFS2_DEFAULT_BSIZE; + sbd.device_fd = fd; + bh = bread(&sbd.buf_list, 0x10); sbd.jsize = GFS2_DEFAULT_JSIZE; sbd.rgsize = GFS2_DEFAULT_RGSIZE; sbd.utsize = GFS2_DEFAULT_UTSIZE; @@ -1712,13 +1708,13 @@ static void read_superblock(int fd) sbd.time = time(NULL); osi_list_init(&sbd.rglist); init_buf_list(&sbd, &sbd.buf_list, 1 << 20); - gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */ + gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */ /* Check to see if this is really gfs1 */ if (sbd1->sb_fs_format == GFS_FORMAT_FS && sbd1->sb_header.mh_type == GFS_METATYPE_SB && sbd1->sb_header.mh_format == GFS_FORMAT_SB && sbd1->sb_multihost_format == GFS_FORMAT_MULTI) { - struct gfs_sb *sbbuf = (struct gfs_sb *)buf; + struct gfs_sb *sbbuf = (struct gfs_sb *)bh->b_data; gfs1 = TRUE; sbd1->sb_flags = be32_to_cpu(sbbuf->sb_flags); @@ -1774,7 +1770,7 @@ static void read_master_dir(void) ioctl(sbd.device_fd, BLKFLSBUF, 0); lseek(sbd.device_fd, sbd.sd_sb.sb_master_dir.no_addr * sbd.bsize, SEEK_SET); - if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) { + if (read(sbd.device_fd, bh->b_data, sbd.bsize) != sbd.bsize) { fprintf(stderr, "read error: %s from %s:%d: " "master dir block %lld (0x%llx)\n", strerror(errno), __FUNCTION__, @@ -1783,8 +1779,8 @@ static void read_master_dir(void) (unsigned long long)sbd.sd_sb.sb_master_dir.no_addr); exit(-1); } - gfs2_dinode_in(&di, buf); /* parse disk inode into structure */ - do_dinode_extended(&di, buf); /* get extended data, if any */ + gfs2_dinode_in(&di, bh); /* parse disk inode into structure */ + do_dinode_extended(&di, bh); /* get extended data, if any */ memcpy(&masterdir, &indirect[0], sizeof(struct indirect_info)); } @@ -1809,8 +1805,7 @@ int display(int identify_only) if (block_in_mem != blk) { /* If we changed blocks from the last read */ dev_offset = blk * sbd.bsize; ioctl(sbd.device_fd, BLKFLSBUF, 0); - lseek(sbd.device_fd, dev_offset, SEEK_SET); - if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) { + if (!(bh = bread(&sbd.buf_list, blk))) { fprintf(stderr, "read error: %s from %s:%d: " "offset %lld (0x%llx)\n", strerror(errno), __FUNCTION__, __LINE__, @@ -1821,13 +1816,13 @@ int display(int identify_only) block_in_mem = blk; /* remember which block is in memory */ } line = 1; - gfs2_struct_type = display_block_type(buf, FALSE); + gfs2_struct_type = display_block_type(FALSE); if (identify_only) return 0; indirect_blocks = 0; lines_per_row[dmode] = 1; if (gfs2_struct_type == GFS2_METATYPE_SB || blk == 0x10 * (4096 / sbd.bsize)) { - gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */ + gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */ memset(indirect, 0, sizeof(indirect)); indirect->ii[0].block = sbd.sd_sb.sb_master_dir.no_addr; indirect->ii[0].is_dir = TRUE; @@ -1850,8 +1845,8 @@ int display(int identify_only) indirect->ii[0].dirent[1].dirent.de_type = DT_DIR; } else if (gfs2_struct_type == GFS2_METATYPE_DI) { - gfs2_dinode_in(&di, buf); /* parse disk inode into structure */ - do_dinode_extended(&di, buf); /* get extended data, if any */ + gfs2_dinode_in(&di, bh); /* parse disk inode into structure */ + do_dinode_extended(&di, bh); /* get extended data, if any */ } else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */ int i, hgt = get_height(); @@ -1862,10 +1857,11 @@ int display(int identify_only) &blockstack[blockhist - 1].mp, sizeof(struct metapath)); } - indirect_blocks = do_indirect_extended(buf, indirect, hgt); + indirect_blocks = do_indirect_extended(bh->b_data, indirect, + hgt); } else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */ - do_leaf_extended(buf, indirect); + do_leaf_extended(bh->b_data, indirect); } last_entry_onscreen[dmode] = 0; if (dmode == EXTENDED_MODE && !block_has_extended_info()) @@ -1880,8 +1876,7 @@ int display(int identify_only) move(line, 0); } if (dmode == HEX_MODE) /* if hex display mode */ - hexdump(dev_offset, buf, - (gfs2_struct_type == GFS2_METATYPE_DI)? + hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)? struct_len + di.di_size:sbd.bsize); else if (dmode == GFS2_MODE) /* if structure display */ display_gfs2(); /* display the gfs2 structure */ @@ -1965,10 +1960,10 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) /* read in the block */ jindex_bh = bread(&sbd.buf_list, jindex_block); /* get the dinode data from it. */ - gfs2_dinode_in(&di, jindex_bh->b_data); /* parse disk inode to struct*/ + gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/ if (!gfs1) - do_dinode_extended(&di, jindex_bh->b_data); /* parse dir. */ + do_dinode_extended(&di, jindex_bh); /* parse dir. */ brelse(jindex_bh); if (gfs1) { @@ -1990,7 +1985,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) jblock = indirect->ii[0].dirent[journal_num + 2].block; j_bh = bread(&sbd.buf_list, jblock); j_inode = inode_get(&sbd, j_bh); - gfs2_dinode_in(&jdi, j_bh->b_data);/* parse dinode to struct */ + gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */ *j_size = jdi.di_size; brelse(j_bh); } @@ -2007,21 +2002,21 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p { uint64_t blk, last_fs_block; int found = 0; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize; for (blk = startblk + 1; blk < last_fs_block; blk++) { - bh = bread(&sbd.buf_list, blk); + lbh = bread(&sbd.buf_list, blk); /* Can't use get_block_type here (returns false "none") */ - if (bh->b_data[0] == 0x01 && bh->b_data[1] == 0x16 && - bh->b_data[2] == 0x19 && bh->b_data[3] == 0x70 && - bh->b_data[4] == 0x00 && bh->b_data[5] == 0x00 && - bh->b_data[6] == 0x00 && bh->b_data[7] == metatype) { + if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 && + lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 && + lbh->b_data[4] == 0x00 && lbh->b_data[5] == 0x00 && + lbh->b_data[6] == 0x00 && lbh->b_data[7] == metatype) { found = 1; - brelse(bh); + brelse(lbh); break; } - brelse(bh); + brelse(lbh); } if (!found) blk = 0; @@ -2302,10 +2297,10 @@ static void hex_edit(int *exitch) else if (estring[i+1] >= 'A' && estring[i+1] <= 'F') ch += (estring[i+1] - 'A' + 0x0a); - buf[offset + hexoffset] = ch; + bh->b_data[offset + hexoffset] = ch; } lseek(sbd.device_fd, dev_offset, SEEK_SET); - if (write(sbd.device_fd, buf, sbd.bsize) != + if (write(sbd.device_fd, bh->b_data, sbd.bsize) != sbd.bsize) { fprintf(stderr, "write error: %s from %s:%d: " "offset %lld (0x%llx)\n", @@ -2392,7 +2387,8 @@ static void jump(void) if (edit_row[dmode] >= 0) { col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */ - b = (uint64_t *)&buf[edit_row[dmode]*16 + offset + col2]; + b = (uint64_t *)&bh->b_data[edit_row[dmode]*16 + + offset + col2]; temp_blk=be64_to_cpu(*b); } } @@ -2431,14 +2427,14 @@ static void print_block_type(uint64_t tblock, int type, const char *additional) static void find_print_block_type(void) { uint64_t tblock; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; int type; tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block; - bh = bread(&sbd.buf_list, tblock); - type = get_block_type(bh->b_data); + lbh = bread(&sbd.buf_list, tblock); + type = get_block_type(lbh); print_block_type(tblock, type, ""); - brelse(bh); + brelse(lbh); gfs2_rgrp_free(&sbd.rglist); exit(0); } @@ -2541,13 +2537,13 @@ static void find_change_block_alloc(int *newval) static void process_field(const char *field, uint64_t *newval, int print_field) { uint64_t fblock; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *rbh; int type; struct gfs2_rgrp rg; fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block; - bh = bread(&sbd.buf_list, block); - type = get_block_type(bh->b_data); + rbh = bread(&sbd.buf_list, block); + type = get_block_type(rbh); switch (type) { case GFS2_METATYPE_SB: if (print_field) @@ -2555,10 +2551,10 @@ static void process_field(const char *field, uint64_t *newval, int print_field) " which is not implemented"); break; case GFS2_METATYPE_RG: - gfs2_rgrp_in(&rg, bh->b_data); + gfs2_rgrp_in(&rg, rbh); if (newval) { gfs2_rgrp_assignval(&rg, field, *newval); - gfs2_rgrp_out(&rg, bh->b_data); + gfs2_rgrp_out(&rg, rbh); if (print_field) gfs2_rgrp_printval(&rg, field); } else { @@ -2572,10 +2568,10 @@ static void process_field(const char *field, uint64_t *newval, int print_field) " which is not implemented"); break; case GFS2_METATYPE_DI: - gfs2_dinode_in(&di, bh->b_data); + gfs2_dinode_in(&di, rbh); if (newval) { gfs2_dinode_assignval(&di, field, *newval); - gfs2_dinode_out(&di, bh->b_data); + gfs2_dinode_out(&di, rbh); if (print_field) gfs2_dinode_printval(&di, field); } else { @@ -2599,8 +2595,8 @@ static void process_field(const char *field, uint64_t *newval, int print_field) break; } if (newval) - bmodified(bh); - brelse(bh); + bmodified(rbh); + brelse(rbh); bcommit(&sbd.buf_list); } @@ -2872,11 +2868,12 @@ static void interactive_mode(void) /* ------------------------------------------------------------------------ */ /* gfs_log_header_in - read in a gfs1-style log header */ /* ------------------------------------------------------------------------ */ -void gfs_log_header_in(struct gfs_log_header *head, char *inbuf) +void gfs_log_header_in(struct gfs_log_header *head, + struct gfs2_buffer_head *lbh) { - struct gfs_log_header *str = (struct gfs_log_header *) inbuf; + struct gfs_log_header *str = (struct gfs_log_header *)lbh->b_data; - gfs2_meta_header_in(&head->lh_header, inbuf); + gfs2_meta_header_in(&head->lh_header, lbh); head->lh_flags = be32_to_cpu(str->lh_flags); head->lh_pad = be32_to_cpu(str->lh_pad); @@ -2945,7 +2942,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset, unsigned int size, uint64_t *abs_block) { struct gfs2_sbd *sdp = ip->i_sbd; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; uint64_t lblock, dblock; unsigned int o; uint32_t extlen = 0; @@ -2982,16 +2979,16 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset, block_map(ip, lblock, ¬_new, &dblock, &extlen, FALSE); if (dblock) { - bh = bread(&sdp->buf_list, dblock); + lbh = bread(&sdp->buf_list, dblock); if (*abs_block == 0) - *abs_block = bh->b_blocknr; + *abs_block = lbh->b_blocknr; dblock++; extlen--; } else - bh = NULL; - if (bh) { - memcpy(rbuf, bh->b_data + o, amount); - brelse(bh); + lbh = NULL; + if (lbh) { + memcpy(rbuf, lbh->b_data + o, amount); + brelse(lbh); } else { memset(rbuf, 0, amount); } @@ -3022,13 +3019,13 @@ static void check_journal_wrap(uint64_t seq, uint64_t *highest_seq) /* ------------------------------------------------------------------------ */ static void dump_journal(const char *journal) { - struct gfs2_buffer_head *j_bh = NULL; + struct gfs2_buffer_head *j_bh = NULL, dummy_bh; uint64_t jblock, j_size, jb, abs_block; int error, start_line, journal_num; - char jbuf[sbd.bsize]; struct gfs2_inode *j_inode = NULL; int ld_blocks = 0; uint64_t highest_seq = 0; + char *jbuf = NULL; start_line = line; lines_per_row[dmode] = 1; @@ -3042,6 +3039,7 @@ static void dump_journal(const char *journal) if (!gfs1) { j_bh = bread(&sbd.buf_list, jblock); j_inode = inode_get(&sbd, j_bh); + jbuf = malloc(sbd.bsize); } for (jb = 0; jb < j_size; jb += (gfs1 ? 1:sbd.bsize)) { @@ -3050,14 +3048,15 @@ static void dump_journal(const char *journal) brelse(j_bh); j_bh = bread(&sbd.buf_list, jblock + jb); abs_block = jblock + jb; - memcpy(jbuf, j_bh->b_data, sbd.bsize); + dummy_bh.b_data = j_bh->b_data; } else { error = fsck_readi(j_inode, (void *)&jbuf, jb, sbd.bsize, &abs_block); if (!error) /* end of file */ break; + dummy_bh.b_data = jbuf; } - if (get_block_type(jbuf) == GFS2_METATYPE_LD) { + if (get_block_type(&dummy_bh) == GFS2_METATYPE_LD) { uint64_t *b; struct gfs2_log_descriptor ld; int ltndx; @@ -3080,7 +3079,7 @@ static void dump_journal(const char *journal) print_gfs2("0x%llx (j+%4llx): Log descriptor, ", abs_block, jb / (gfs1 ? 1 : sbd.bsize)); - gfs2_log_descriptor_in(&ld, jbuf); + gfs2_log_descriptor_in(&ld, &dummy_bh); print_gfs2("type %d ", ld.ld_type); for (ltndx = 0;; ltndx++) { @@ -3094,20 +3093,21 @@ static void dump_journal(const char *journal) eol(0); print_gfs2(" "); if (gfs1) - b = (uint64_t *)(jbuf + + b = (uint64_t *)(dummy_bh.b_data + sizeof(struct gfs_log_descriptor)); else - b = (uint64_t *)(jbuf + + b = (uint64_t *)(dummy_bh.b_data + sizeof(struct gfs2_log_descriptor)); ld_blocks = ld.ld_data1; - ld_blocks -= print_ld_blocks(b, (jbuf + sbd.bsize), + ld_blocks -= print_ld_blocks(b, (dummy_bh.b_data + + sbd.bsize), start_line); - } else if (get_block_type(jbuf) == GFS2_METATYPE_LH) { + } else if (get_block_type(&dummy_bh) == GFS2_METATYPE_LH) { struct gfs2_log_header lh; struct gfs_log_header lh1; if (gfs1) { - gfs_log_header_in(&lh1, jbuf); + gfs_log_header_in(&lh1, &dummy_bh); check_journal_wrap(lh1.lh_sequence, &highest_seq); print_gfs2("0x%llx (j+%4llx): Log header: " @@ -3118,7 +3118,7 @@ static void dump_journal(const char *journal) lh1.lh_first, lh1.lh_tail, lh1.lh_last_dump); } else { - gfs2_log_header_in(&lh, jbuf); + gfs2_log_header_in(&lh, &dummy_bh); check_journal_wrap(lh.lh_sequence, &highest_seq); print_gfs2("0x%llx (j+%4llx): Log header: Seq" @@ -3133,13 +3133,14 @@ static void dump_journal(const char *journal) " continuation block", abs_block, jb); eol(0); print_gfs2(" "); - ld_blocks -= print_ld_blocks((uint64_t *)jbuf, - (jbuf + sbd.bsize), - start_line); + ld_blocks -= print_ld_blocks((uint64_t *)dummy_bh.b_data, + (dummy_bh.b_data + + sbd.bsize), start_line); } } brelse(j_bh); blockhist = -1; /* So we don't print anything else */ + free(jbuf); } /* ------------------------------------------------------------------------ */ @@ -3466,7 +3467,6 @@ int main(int argc, char *argv[]) memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen)); dmode = INIT_MODE; sbd.bsize = 4096; - type_alloc(buf, char, sbd.bsize); /* allocate/malloc a new 4K buffer */ block = starting_blk = 0x10; for (i = 0; i < BLOCK_STACK_SIZE; i++) { blockstack[i].dmode = HEX_MODE; @@ -3523,8 +3523,6 @@ int main(int argc, char *argv[]) } } close(fd); - if (buf) - free(buf); if (indirect) free(indirect); gfs2_rgrp_free(&sbd.rglist); diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h index 88964a2..549c3af 100644 --- a/gfs2/edit/hexedit.h +++ b/gfs2/edit/hexedit.h @@ -51,7 +51,7 @@ extern char estring[1024]; /* edit string */ extern char efield[64]; extern uint64_t dev_offset; extern uint64_t max_block; -extern char *buf; +extern struct gfs2_buffer_head *bh; extern int termlines; extern int termcols; extern int insert; @@ -154,16 +154,17 @@ extern int block_is_statfs_file(void); extern int block_is_quota_file(void); extern int block_is_per_node(void); extern int block_is_in_per_node(void); -extern int display_block_type(const char *lpBuffer, int from_restore); +extern int display_block_type(int from_restore); extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); -extern void gfs_log_header_in(struct gfs_log_header *head, char *buf); +extern void gfs_log_header_in(struct gfs_log_header *head, + struct gfs2_buffer_head *bh); extern void gfs_log_header_print(struct gfs_log_header *lh); -extern void gfs_dinode_in(struct gfs_dinode *di, char *buf); -extern int display(int identify_only); -extern uint64_t check_keywords(const char *kword); +extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh); extern void savemeta(char *out_fn, int saveoption); extern void restoremeta(const char *in_fn, const char *out_device, uint64_t printblocksonly); +extern int display(int identify_only); +extern uint64_t check_keywords(const char *kword); extern uint64_t masterblock(const char *fn); struct gfs2_dirents { diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 88dca25..99bc986 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -33,6 +33,7 @@ struct saved_metablock { }; struct saved_metablock *savedata; +struct gfs2_buffer_head *savebh; uint64_t last_fs_block, last_reported_block, blks_saved, total_out, pct; struct gfs2_bmap *blocklist = NULL; uint64_t journal_blocks[MAX_JOURNALS_SAVED]; @@ -50,15 +51,15 @@ extern void read_superblock(void); * returns: 0 if successful * -1 if this isn't gfs metadata. */ -static int get_gfs_struct_info(char *gbuf, int *block_type, int *gstruct_len) +static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type, + int *gstruct_len) { - struct gfs2_meta_header mh, mhbuf; + struct gfs2_meta_header mh; *block_type = 0; *gstruct_len = sbd.bsize; - memcpy(&mhbuf, gbuf, sizeof(mhbuf)); - gfs2_meta_header_in(&mh, (void *)&mhbuf); + gfs2_meta_header_in(&mh, lbh); if (mh.mh_magic != GFS2_MAGIC) return -1; @@ -187,28 +188,15 @@ static int save_block(int fd, int out_fd, uint64_t blk) return 0; } memset(savedata, 0, sizeof(struct saved_metablock)); - if (lseek(fd, blk * sbd.bsize, SEEK_SET) != blk * sbd.bsize) { - fprintf(stderr, "bad seek: %s from %s:%d: " - "block %lld (0x%llx)\n", strerror(errno), - __FUNCTION__, __LINE__, - (unsigned long long)blk, (unsigned long long)blk); - exit(-1); - } - /* read in the block */ - if (read(fd, savedata->buf, sbd.bsize) != sbd.bsize) { - fprintf(stderr, "bad read: %s from %s:%d: " - "block %lld (0x%llx)\n", strerror(errno), - __FUNCTION__, __LINE__, - (unsigned long long)blk, (unsigned long long)blk); - exit(-1); - } + savebh = bread(&sbd.buf_list, blk); + memcpy(&savedata->buf, savebh->b_data, sbd.bsize); /* If this isn't metadata and isn't a system file, we don't want it. Note that we're checking "block" here rather than blk. That's because we want to know if the source inode's "block" is a system inode, not the block within the inode "blk". They may or may not be the same thing. */ - if (get_gfs_struct_info(savedata->buf, &blktype, &blklen) && + if (get_gfs_struct_info(savebh, &blktype, &blklen) && !block_is_systemfile()) return 0; /* Not metadata, and not system file, so skip it */ trailing0 = 0; @@ -393,16 +381,17 @@ static void save_inode_data(int out_fd) } if (inode->i_di.di_eattr) { /* if this inode has extended attributes */ struct gfs2_meta_header mh; + struct gfs2_buffer_head *lbh; - metabh = bread(&sbd.buf_list, inode->i_di.di_eattr); + lbh = bread(&sbd.buf_list, inode->i_di.di_eattr); save_block(sbd.device_fd, out_fd, inode->i_di.di_eattr); - gfs2_meta_header_in(&mh, metabh->b_data); + gfs2_meta_header_in(&mh, lbh); if (mh.mh_magic == GFS2_MAGIC && mh.mh_type == GFS2_METATYPE_EA) - save_ea_block(out_fd, metabh); + save_ea_block(out_fd, lbh); else if (mh.mh_magic == GFS2_MAGIC && mh.mh_type == GFS2_METATYPE_IN) - save_indirect_blocks(out_fd, cur_list, metabh, 2, 2); + save_indirect_blocks(out_fd, cur_list, lbh, 2, 2); else { if (mh.mh_magic == GFS2_MAGIC) /* if it's metadata */ save_block(sbd.device_fd, out_fd, @@ -416,15 +405,15 @@ static void save_inode_data(int out_fd) (unsigned long long)block, (unsigned long long)block); } - brelse(metabh); + brelse(lbh); } inode_put(inode); + brelse(metabh); } static void get_journal_inode_blocks(void) { int journal; - struct gfs2_buffer_head *bh; journals_found = 0; memset(journal_blocks, 0, sizeof(journal_blocks)); @@ -464,7 +453,7 @@ static void get_journal_inode_blocks(void) jblock = indirect->ii[0].dirent[journal + 2].block; bh = bread(&sbd.buf_list, jblock); j_inode = inode_get(&sbd, bh); - gfs2_dinode_in(&jdi, bh->b_data); + gfs2_dinode_in(&jdi, bh); inode_put(j_inode); } journal_blocks[journals_found++] = jblock; @@ -478,7 +467,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, uint32_t length = rgd->ri.ri_length; uint32_t blk = (first)? 0: (uint32_t)((*nrfblock+1)-rgd->ri.ri_data0); int i; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; if(!first && (*nrfblock < rgd->ri.ri_data0)) { log_err("next_rg_freemeta: Start block is outside rgrp " @@ -493,11 +482,11 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, } for(; i < length; i++){ bits = &rgd->bits[i]; - bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i); + lbh = bread(&sdp->buf_list, rgd->ri.ri_addr + i); blk = gfs2_bitfit((unsigned char *)bh->b_data + bits->bi_offset, bits->bi_len, blk, GFS2_BLKST_UNLINKED); - brelse(bh); + brelse(lbh); if(blk != BFITNOENT){ *nrfblock = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0; @@ -518,7 +507,7 @@ void savemeta(char *out_fn, int saveoption) uint64_t memreq; int rgcount; uint64_t jindex_block; - struct gfs2_buffer_head *bh; + struct gfs2_buffer_head *lbh; slow = (saveoption == 1); sbd.md.journals = 1; @@ -601,11 +590,11 @@ void savemeta(char *out_fn, int saveoption) &sbd.md.riinode); jindex_block = masterblock("jindex"); } - bh = bread(&sbd.buf_list, jindex_block); - gfs2_dinode_in(&di, bh->b_data); + lbh = bread(&sbd.buf_list, jindex_block); + gfs2_dinode_in(&di, lbh); if (!gfs1) - do_dinode_extended(&di, bh->b_data); - brelse(bh); + do_dinode_extended(&di, lbh); + brelse(lbh); } if (!slow) { printf("Reading resource groups..."); @@ -845,14 +834,14 @@ static int restore_data(int fd, int in_fd, int printblocksonly) if (block > highest_valid_block) highest_valid_block = block; if (printblocksonly > 1 && printblocksonly == block) { - memcpy(buf, savedata->buf, sbd.bsize); + memcpy(bh->b_data, savedata->buf, sbd.bsize); block_in_mem = block; display(0); return 0; } else if (printblocksonly == 1) { print_gfs2("%d (l=0x%x): ", blks_saved, savedata->siglen); - display_block_type(savedata->buf, TRUE); + display_block_type(TRUE); } } else { warm_fuzzy_stuff(savedata->blk, FALSE, FALSE); diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 95c0681..be9d3d0 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -373,8 +373,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip) log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence); block_map(ip, blk, &new, &dblock, &extlen, FALSE); bh = bread(&ip->i_sbd->buf_list, dblock); - gfs2_log_header_out(&lh, bh->b_data); - bmodified(bh); + gfs2_log_header_out(&lh, bh); brelse(bh); } return 0; diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 2083e94..616cbdc 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -295,23 +295,28 @@ static void check_statfs(struct gfs2_sbd *sdp) log_err( _("The statfs file is wrong:\n\n")); log_err( _("Current statfs values:\n")); log_err( _("blocks: %lld (0x%llx)\n"), - sc.sc_total, sc.sc_total); + (unsigned long long)sc.sc_total, + (unsigned long long)sc.sc_total); log_err( _("free: %lld (0x%llx)\n"), - sc.sc_free, sc.sc_free); + (unsigned long long)sc.sc_free, + (unsigned long long)sc.sc_free); log_err( _("dinodes: %lld (0x%llx)\n\n"), - sc.sc_dinodes, sc.sc_dinodes); + (unsigned long long)sc.sc_dinodes, + (unsigned long long)sc.sc_dinodes); log_err( _("Calculated statfs values:\n")); log_err( _("blocks: %lld (0x%llx)\n"), - sdp->blks_total, sdp->blks_total); + (unsigned long long)sdp->blks_total, + (unsigned long long)sdp->blks_total); log_err( _("free: %lld (0x%llx)\n"), - sdp->blks_total - sdp->blks_alloced, - sdp->blks_total - sdp->blks_alloced); + (unsigned long long)(sdp->blks_total - sdp->blks_alloced), + (unsigned long long)(sdp->blks_total - sdp->blks_alloced)); log_err( _("dinodes: %lld (0x%llx)\n"), - sdp->dinodes_alloced, sdp->dinodes_alloced); + (unsigned long long)sdp->dinodes_alloced, + (unsigned long long)sdp->dinodes_alloced); errors_found++; - if (!query(&opts, _("Okay to fix the master statfs file? (y/n)"))) { + if (!query( _("Okay to fix the master statfs file? (y/n)"))) { log_err( _("The statfs file was not fixed.\n")); return; } diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index b9448b5..f34a185 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -71,7 +71,7 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, fprintf(stderr, _("Out of memory in %s\n"), __FUNCTION__); exit(-1); } - gfs2_dinode_in(&ip->i_di, bh->b_data); + gfs2_dinode_in(&ip->i_di, bh); ip->i_bh = bh; ip->i_sbd = sdp; @@ -92,7 +92,7 @@ void fsck_inode_put(struct gfs2_inode *ip) sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr); if (sysip) { if (ip->i_bh->b_changed) - gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); + gfs2_dinode_out(&ip->i_di, ip->i_bh); brelse(ip->i_bh); } else { inode_put(ip); @@ -420,10 +420,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) factor++; divisor /= 2; } - gfs2_leaf_in(&oldleaf, lbh->b_data); + gfs2_leaf_in(&oldleaf, lbh); oldleaf.lf_depth = ip->i_di.di_depth - factor; - gfs2_leaf_out(&oldleaf, lbh->b_data); - bmodified(lbh); + gfs2_leaf_out(&oldleaf, lbh); brelse(lbh); } else @@ -464,7 +463,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) brelse(lbh); break; } - gfs2_leaf_in(&leaf, lbh->b_data); + gfs2_leaf_in(&leaf, lbh); if(pass->check_leaf) { error = pass->check_leaf(ip, leaf_no, lbh, pass->private); @@ -480,9 +479,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) if (leaf.lf_dirent_format == (GFS2_FORMAT_DE << 16)) { log_debug( _("incorrect lf_dirent_format at leaf #%" PRIu64 "\n"), leaf_no); leaf.lf_dirent_format = GFS2_FORMAT_DE; - gfs2_leaf_out(&leaf, lbh->b_data); + gfs2_leaf_out(&leaf, lbh); log_debug( _("Fixing lf_dirent_format.\n")); - bmodified(lbh); } /* Make sure it's really a leaf. */ @@ -521,7 +519,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) if(count != leaf.lf_entries) { lbh = bread(&sbp->buf_list, leaf_no); - gfs2_leaf_in(&leaf, lbh->b_data); + gfs2_leaf_in(&leaf, lbh); log_err( _("Leaf %llu (0x%llx) entry " "count in directory %llu" @@ -537,9 +535,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) leaf.lf_entries, count); if(query( _("Update leaf entry count? (y/n) "))) { leaf.lf_entries = count; - gfs2_leaf_out(&leaf, lbh->b_data); + gfs2_leaf_out(&leaf, lbh); log_warn( _("Leaf entry count updated\n")); - bmodified(lbh); } else log_err( _("Leaf entry count left in inconsistant state\n")); brelse(lbh); diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 09493b8..3638102 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -678,7 +678,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, PRIu64 " (0x%" PRIx64 ")? (y/n) "), block, block)) { ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block; - gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); + gfs2_dinode_out(&ip->i_di, ip->i_bh); bmodified(ip->i_bh); } else log_err( _("Address in inode at block #%" PRIu64 @@ -857,7 +857,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count + bc.ea_count; bmodified(ip->i_bh); - gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); + gfs2_dinode_out(&ip->i_di, ip->i_bh); } else log_err( _("Bad block count for #%llu (0x%llx" ") not fixed\n"), diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 97f29a2..8eaca6f 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -149,7 +149,7 @@ static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de, } /* Return the number of leaf entries so metawalk doesn't flag this leaf as having none. */ - gfs2_leaf_in(&leaf, bh->b_data); + gfs2_leaf_in(&leaf, bh); *count = leaf.lf_entries; return 0; } diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index d384816..f0d5911 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -189,7 +189,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, if(query( _("Update resource group counts? (y/n) "))) { log_warn( _("Resource group counts updated\n")); /* write out the rgrp */ - gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data); + gfs2_rgrp_out(&rgp->rg, rgp->bh[0]); } else log_err( _("Resource group counts left inconsistent\n")); } diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 7cd0b32..34c9149 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -391,16 +391,15 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_RB; mh.mh_format = GFS2_FORMAT_RB; - gfs2_meta_header_out(&mh, rg->bh[x]->b_data); + gfs2_meta_header_out(&mh, rg->bh[x]); } else { memset(&rg->rg, 0, sizeof(struct gfs2_rgrp)); rg->rg.rg_header.mh_magic = GFS2_MAGIC; rg->rg.rg_header.mh_type = GFS2_METATYPE_RG; rg->rg.rg_header.mh_format = GFS2_FORMAT_RG; rg->rg.rg_free = rg->ri.ri_data; - gfs2_rgrp_out(&rg->rg, rg->bh[x]->b_data); + gfs2_rgrp_out(&rg->rg, rg->bh[x]); } - bmodified(rg->bh[x]); brelse(rg->bh[x]); return 0; } diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c index f2993f5..6fbc10f 100644 --- a/gfs2/libgfs2/fs_geometry.c +++ b/gfs2/libgfs2/fs_geometry.c @@ -216,10 +216,9 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write) for (x = 0; x < bitblocks; x++) { bh = bget(&sdp->buf_list, rl->start + x); if (x) - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); else - gfs2_rgrp_out(&rg, bh->b_data); - bmodified(bh); + gfs2_rgrp_out(&rg, bh); brelse(bh); } } diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c index 32f1cac..19ebc38 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -37,7 +37,7 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh) fprintf(stderr, "Out of memory in %s\n", __FUNCTION__); exit(-1); } - gfs2_dinode_in(&ip->i_di, bh->b_data); + gfs2_dinode_in(&ip->i_di, bh); ip->i_bh = bh; ip->i_sbd = sdp; return ip; @@ -46,7 +46,7 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh) void inode_put(struct gfs2_inode *ip) { if (ip->i_bh->b_changed) - gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); + gfs2_dinode_out(&ip->i_di, ip->i_bh); brelse(ip->i_bh); free(ip); } @@ -115,7 +115,7 @@ found: rg->rg_free--; bmodified(bh); - gfs2_rgrp_out(rg, rl->bh[0]->b_data); + gfs2_rgrp_out(rg, rl->bh[0]); sdp->blks_alloced++; return ri->ri_data0 + bn; @@ -178,14 +178,13 @@ void unstuff_dinode(struct gfs2_inode *ip) mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_JD; mh.mh_format = GFS2_FORMAT_JD; - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } buffer_copy_tail(sdp, bh, sizeof(struct gfs2_meta_header), ip->i_bh, sizeof(struct gfs2_dinode)); - bmodified(bh); brelse(bh); } else { block = data_alloc(ip); @@ -193,8 +192,6 @@ void unstuff_dinode(struct gfs2_inode *ip) buffer_copy_tail(sdp, bh, 0, ip->i_bh, sizeof(struct gfs2_dinode)); - - bmodified(bh); brelse(bh); } } @@ -203,6 +200,7 @@ void unstuff_dinode(struct gfs2_inode *ip) if (ip->i_di.di_size) { *(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block); + /* no need: bmodified(ip->i_bh); buffer_clear_tail does it */ ip->i_di.di_blocks++; } @@ -258,13 +256,11 @@ void build_height(struct gfs2_inode *ip, int height) mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } buffer_copy_tail(sdp, bh, sizeof(struct gfs2_meta_header), ip->i_bh, sizeof(struct gfs2_dinode)); - - bmodified(bh); brelse(bh); } @@ -272,6 +268,7 @@ void build_height(struct gfs2_inode *ip, int height) if (new_block) { *(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block); + /* no need: bmodified(ip->i_bh);*/ ip->i_di.di_blocks++; } @@ -381,8 +378,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; - bmodified(bh); - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } else bh = bread(&sdp->buf_list, *dblock); } @@ -559,7 +555,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_JD; mh.mh_format = GFS2_FORMAT_JD; - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } } else bh = bread(&sdp->buf_list, dblock); @@ -769,7 +765,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_LF; mh.mh_format = GFS2_FORMAT_LF; - gfs2_meta_header_out(&mh, nbh->b_data); + gfs2_meta_header_out(&mh, nbh); } nleaf = (struct gfs2_leaf *)nbh->b_data; @@ -853,7 +849,6 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea dip->i_di.di_blocks++; brelse(obh); - bmodified(nbh); brelse(nbh); } @@ -1012,7 +1007,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_LF; mh.mh_format = GFS2_FORMAT_LF; - gfs2_meta_header_out(&mh, nbh->b_data); + gfs2_meta_header_out(&mh, nbh); } leaf->lf_next = cpu_to_be64(bn); @@ -1064,7 +1059,7 @@ static void dir_make_exhash(struct gfs2_inode *dip) mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_LF; mh.mh_format = GFS2_FORMAT_LF; - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); } leaf = (struct gfs2_leaf *)bh->b_data; @@ -1195,7 +1190,7 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp, di.di_entries = 2; } - gfs2_dinode_out(&di, bh->b_data); + gfs2_dinode_out(&di, bh); return bh; } @@ -1600,7 +1595,7 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block) if (rgd) { gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); rgd->rg.rg_free++; /* adjust the free count */ - gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); /* back to the buffer */ + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); /* back to the buffer */ } } @@ -1661,6 +1656,6 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) rgd = gfs2_blk2rgrpd(sdp, diblock); rgd->rg.rg_free++; rgd->rg.rg_dinodes--; /* one less inode in use */ - gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); return 0; } diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c index a5b5810..a06fe11 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -113,8 +113,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; - gfs2_meta_header_out(&mh, bh->b_data); - bmodified(bh); + gfs2_meta_header_out(&mh, bh); } else { bh = bread(&sdp->buf_list, *dblock); } @@ -328,11 +327,11 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet) /* ------------------------------------------------------------------------ */ /* gfs_dinode_in */ /* ------------------------------------------------------------------------ */ -static void gfs_dinode_in(struct gfs_dinode *di, char *buf) +static void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh) { - struct gfs_dinode *str = (struct gfs_dinode *)buf; + struct gfs_dinode *str = (struct gfs_dinode *)bh->b_data; - gfs2_meta_header_in(&di->di_header, buf); + gfs2_meta_header_in(&di->di_header, bh); gfs2_inum_in(&di->di_num, (char *)&str->di_num); di->di_mode = be32_to_cpu(str->di_mode); @@ -369,7 +368,7 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp, exit(-1); } - gfs_dinode_in(&gfs1_dinode, bh->b_data); + gfs_dinode_in(&gfs1_dinode, bh); memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header, sizeof(struct gfs2_meta_header)); memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num, diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 3369d0a..49bc151 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -675,34 +675,42 @@ extern void print_it(const char *label, const char *fmt, const char *fmt2, ...) extern void gfs2_inum_in(struct gfs2_inum *no, char *buf); extern void gfs2_inum_out(struct gfs2_inum *no, char *buf); -extern void gfs2_meta_header_in(struct gfs2_meta_header *mh, char *buf); -extern void gfs2_meta_header_out(struct gfs2_meta_header *mh, char *buf); -extern void gfs2_sb_in(struct gfs2_sb *sb, char *buf); -extern void gfs2_sb_out(struct gfs2_sb *sb, char *buf); +extern void gfs2_meta_header_in(struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh); +extern void gfs2_meta_header_out(struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh); +extern void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh); +extern void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh); extern void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf); extern void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf); -extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf); -extern void gfs2_rgrp_out(struct gfs2_rgrp *rg, char *buf); +extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh); +extern void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh); extern void gfs2_quota_in(struct gfs2_quota *qu, char *buf); extern void gfs2_quota_out(struct gfs2_quota *qu, char *buf); -extern void gfs2_dinode_in(struct gfs2_dinode *di, char *buf); -extern void gfs2_dinode_out(struct gfs2_dinode *di, char *buf); +extern void gfs2_dinode_in(struct gfs2_dinode *di, + struct gfs2_buffer_head *bh); +extern void gfs2_dinode_out(struct gfs2_dinode *di, + struct gfs2_buffer_head *bh); extern void gfs2_dirent_in(struct gfs2_dirent *de, char *buf); extern void gfs2_dirent_out(struct gfs2_dirent *de, char *buf); -extern void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf); -extern void gfs2_leaf_out(struct gfs2_leaf *lf, char *buf); +extern void gfs2_leaf_in(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh); +extern void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh); extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, char *buf); extern void gfs2_ea_header_out(struct gfs2_ea_header *ea, char *buf); -extern void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf); -extern void gfs2_log_header_out(struct gfs2_log_header *lh, char *buf); -extern void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf); -extern void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, char *buf); -extern void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf); -extern void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf); +extern void gfs2_log_header_in(struct gfs2_log_header *lh, + struct gfs2_buffer_head *bh); +extern void gfs2_log_header_out(struct gfs2_log_header *lh, + struct gfs2_buffer_head *bh); +extern void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, + struct gfs2_buffer_head *bh); +extern void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, + struct gfs2_buffer_head *bh); extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf); extern void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf); -extern void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf); -extern void gfs2_quota_change_out(struct gfs2_quota_change *qc, char *buf); +extern void gfs2_quota_change_in(struct gfs2_quota_change *qc, + struct gfs2_buffer_head *bh); +extern void gfs2_quota_change_out(struct gfs2_quota_change *qc, + struct gfs2_buffer_head *bh); /* Printing functions */ diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c index bd9afd3..829bb10 100644 --- a/gfs2/libgfs2/ondisk.c +++ b/gfs2/libgfs2/ondisk.c @@ -28,11 +28,11 @@ /* * gfs2_xxx_in - read in an xxx struct * first arg: the cpu-order structure - * buf: the disk-order buffer + * bh: the disk-order buffer_head * * gfs2_xxx_out - write out an xxx struct * first arg: the cpu-order structure - * buf: the disk-order buffer + * bh: the disk-order buffer_head * * gfs2_xxx_print - print out an xxx struct * first arg: the cpu-order structure @@ -60,24 +60,27 @@ void gfs2_inum_print(struct gfs2_inum *no) pv(no, no_addr, "%llu", "0x%llx"); } -void gfs2_meta_header_in(struct gfs2_meta_header *mh, char *buf) +void gfs2_meta_header_in(struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh) { - struct gfs2_meta_header *str = (struct gfs2_meta_header *)buf; + struct gfs2_meta_header *str = (struct gfs2_meta_header *)bh->b_data; CPIN_32(mh, str, mh_magic); CPIN_32(mh, str, mh_type); CPIN_32(mh, str, mh_format); } -void gfs2_meta_header_out(struct gfs2_meta_header *mh, char *buf) +void gfs2_meta_header_out(struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh) { - struct gfs2_meta_header *str = (struct gfs2_meta_header *)buf; + struct gfs2_meta_header *str = (struct gfs2_meta_header *)bh->b_data; CPOUT_32(mh, str, mh_magic); CPOUT_32(mh, str, mh_type); CPOUT_32(mh, str, mh_format); str->__pad0 = 0; str->__pad1 = 0; + bmodified(bh); } void gfs2_meta_header_print(struct gfs2_meta_header *mh) @@ -87,11 +90,11 @@ void gfs2_meta_header_print(struct gfs2_meta_header *mh) pv(mh, mh_format, "%u", "0x%x"); } -void gfs2_sb_in(struct gfs2_sb *sb, char *buf) +void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh) { - struct gfs2_sb *str = (struct gfs2_sb *)buf; + struct gfs2_sb *str = (struct gfs2_sb *)bh->b_data; - gfs2_meta_header_in(&sb->sb_header, buf); + gfs2_meta_header_in(&sb->sb_header, bh); CPIN_32(sb, str, sb_fs_format); CPIN_32(sb, str, sb_multihost_format); @@ -109,11 +112,11 @@ void gfs2_sb_in(struct gfs2_sb *sb, char *buf) #endif } -void gfs2_sb_out(struct gfs2_sb *sb, char *buf) +void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh) { - struct gfs2_sb *str = (struct gfs2_sb *)buf; + struct gfs2_sb *str = (struct gfs2_sb *)bh->b_data; - gfs2_meta_header_out(&sb->sb_header, buf); + gfs2_meta_header_out(&sb->sb_header, bh); CPOUT_32(sb, str, sb_fs_format); CPOUT_32(sb, str, sb_multihost_format); @@ -129,6 +132,7 @@ void gfs2_sb_out(struct gfs2_sb *sb, char *buf) #ifdef GFS2_HAS_UUID memcpy(str->sb_uuid, sb->sb_uuid, 16); #endif + bmodified(bh); } const char *str_uuid(const unsigned char *uuid) @@ -220,11 +224,11 @@ void gfs2_rindex_print(struct gfs2_rindex *ri) pv(ri, ri_bitbytes, "%u", "0x%x"); } -void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf) +void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh) { - struct gfs2_rgrp *str = (struct gfs2_rgrp *)buf; + struct gfs2_rgrp *str = (struct gfs2_rgrp *)bh->b_data; - gfs2_meta_header_in(&rg->rg_header, buf); + gfs2_meta_header_in(&rg->rg_header, bh); CPIN_32(rg, str, rg_flags); CPIN_32(rg, str, rg_free); CPIN_32(rg, str, rg_dinodes); @@ -232,16 +236,17 @@ void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf) CPIN_08(rg, str, rg_reserved, 36); } -void gfs2_rgrp_out(struct gfs2_rgrp *rg, char *buf) +void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh) { - struct gfs2_rgrp *str = (struct gfs2_rgrp *)buf; + struct gfs2_rgrp *str = (struct gfs2_rgrp *)bh->b_data; - gfs2_meta_header_out(&rg->rg_header, buf); + gfs2_meta_header_out(&rg->rg_header, bh); CPOUT_32(rg, str, rg_flags); CPOUT_32(rg, str, rg_free); CPOUT_32(rg, str, rg_dinodes); CPOUT_08(rg, str, rg_reserved, 36); + bmodified(bh); } void gfs2_rgrp_print(struct gfs2_rgrp *rg) @@ -259,7 +264,8 @@ void gfs2_quota_in(struct gfs2_quota *qu, char *buf) CPIN_64(qu, str, qu_limit); CPIN_64(qu, str, qu_warn); CPIN_64(qu, str, qu_value); - CPIN_08(qu, str, qu_reserved, sizeof(qu->qu_reserved)); + CPIN_32(qu, str, qu_ll_next); + CPIN_08(qu, str, qu_reserved, 60); } void gfs2_quota_out(struct gfs2_quota *qu, char *buf) @@ -269,7 +275,8 @@ void gfs2_quota_out(struct gfs2_quota *qu, char *buf) CPOUT_64(qu, str, qu_limit); CPOUT_64(qu, str, qu_warn); CPOUT_64(qu, str, qu_value); - memset(qu->qu_reserved, 0, sizeof(qu->qu_reserved)); + CPOUT_32(qu, str, qu_ll_next); + CPOUT_08(qu, str, qu_reserved, 60); } void gfs2_quota_print(struct gfs2_quota *qu) @@ -279,11 +286,11 @@ void gfs2_quota_print(struct gfs2_quota *qu) pv(qu, qu_value, "%lld", "0x%llx"); } -void gfs2_dinode_in(struct gfs2_dinode *di, char *buf) +void gfs2_dinode_in(struct gfs2_dinode *di, struct gfs2_buffer_head *bh) { - struct gfs2_dinode *str = (struct gfs2_dinode *)buf; + struct gfs2_dinode *str = (struct gfs2_dinode *)bh->b_data; - gfs2_meta_header_in(&di->di_header, buf); + gfs2_meta_header_in(&di->di_header, bh); gfs2_inum_in(&di->di_num, (char *)&str->di_num); CPIN_32(di, str, di_mode); @@ -314,11 +321,11 @@ void gfs2_dinode_in(struct gfs2_dinode *di, char *buf) CPIN_08(di, str, di_reserved, 32); } -void gfs2_dinode_out(struct gfs2_dinode *di, char *buf) +void gfs2_dinode_out(struct gfs2_dinode *di, struct gfs2_buffer_head *bh) { - struct gfs2_dinode *str = (struct gfs2_dinode *)buf; + struct gfs2_dinode *str = (struct gfs2_dinode *)bh->b_data; - gfs2_meta_header_out(&di->di_header, buf); + gfs2_meta_header_out(&di->di_header, bh); gfs2_inum_out(&di->di_num, (char *)&str->di_num); CPOUT_32(di, str, di_mode); @@ -346,6 +353,7 @@ void gfs2_dinode_out(struct gfs2_dinode *di, char *buf) CPOUT_64(di, str, di_eattr); CPOUT_08(di, str, di_reserved, 32); + bmodified(bh); } void gfs2_dinode_print(struct gfs2_dinode *di) @@ -416,11 +424,11 @@ void gfs2_dirent_print(struct gfs2_dirent *de, char *name) print_it(" name", "%s", NULL, buf); } -void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf) +void gfs2_leaf_in(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh) { - struct gfs2_leaf *str = (struct gfs2_leaf *)buf; + struct gfs2_leaf *str = (struct gfs2_leaf *)bh->b_data; - gfs2_meta_header_in(&lf->lf_header, buf); + gfs2_meta_header_in(&lf->lf_header, bh); CPIN_16(lf, str, lf_depth); CPIN_16(lf, str, lf_entries); CPIN_32(lf, str, lf_dirent_format); @@ -429,17 +437,18 @@ void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf) CPIN_08(lf, str, lf_reserved, 32); } -void gfs2_leaf_out(struct gfs2_leaf *lf, char *buf) +void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh) { - struct gfs2_leaf *str = (struct gfs2_leaf *)buf; + struct gfs2_leaf *str = (struct gfs2_leaf *)bh->b_data; - gfs2_meta_header_out(&lf->lf_header, buf); + gfs2_meta_header_out(&lf->lf_header, bh); CPOUT_16(lf, str, lf_depth); CPOUT_16(lf, str, lf_entries); CPOUT_32(lf, str, lf_dirent_format); CPOUT_64(lf, str, lf_next); CPOUT_08(lf, str, lf_reserved, 32); + bmodified(bh); } void gfs2_leaf_print(struct gfs2_leaf *lf) @@ -492,11 +501,12 @@ void gfs2_ea_header_print(struct gfs2_ea_header *ea, char *name) print_it(" name", "%s", NULL, buf); } -void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf) +void gfs2_log_header_in(struct gfs2_log_header *lh, + struct gfs2_buffer_head *bh) { - struct gfs2_log_header *str = (struct gfs2_log_header *)buf; + struct gfs2_log_header *str = (struct gfs2_log_header *)bh->b_data; - gfs2_meta_header_in(&lh->lh_header, buf); + gfs2_meta_header_in(&lh->lh_header, bh); CPIN_64(lh, str, lh_sequence); CPIN_32(lh, str, lh_flags); CPIN_32(lh, str, lh_tail); @@ -504,16 +514,18 @@ void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf) CPIN_32(lh, str, lh_hash); } -void gfs2_log_header_out(struct gfs2_log_header *lh, char *buf) +void gfs2_log_header_out(struct gfs2_log_header *lh, + struct gfs2_buffer_head *bh) { - struct gfs2_log_header *str = (struct gfs2_log_header *)buf; + struct gfs2_log_header *str = (struct gfs2_log_header *)bh->b_data; - gfs2_meta_header_out(&lh->lh_header, buf); + gfs2_meta_header_out(&lh->lh_header, bh); CPOUT_64(lh, str, lh_sequence); CPOUT_32(lh, str, lh_flags); CPOUT_32(lh, str, lh_tail); CPOUT_32(lh, str, lh_blkno); CPOUT_32(lh, str, lh_hash); + bmodified(bh); } void gfs2_log_header_print(struct gfs2_log_header *lh) @@ -526,11 +538,12 @@ void gfs2_log_header_print(struct gfs2_log_header *lh) pv(lh, lh_hash, "0x%.8X", NULL); } -void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf) +void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, + struct gfs2_buffer_head *bh) { - struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)buf; + struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)bh->b_data; - gfs2_meta_header_in(&ld->ld_header, buf); + gfs2_meta_header_in(&ld->ld_header, bh); CPIN_32(ld, str, ld_type); CPIN_32(ld, str, ld_length); CPIN_32(ld, str, ld_data1); @@ -539,17 +552,19 @@ void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf) CPIN_08(ld, str, ld_reserved, 32); } -void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, char *buf) +void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, + struct gfs2_buffer_head *bh) { - struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)buf; + struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)bh->b_data; - gfs2_meta_header_out(&ld->ld_header, buf); + gfs2_meta_header_out(&ld->ld_header, bh); CPOUT_32(ld, str, ld_type); CPOUT_32(ld, str, ld_length); CPOUT_32(ld, str, ld_data1); CPOUT_32(ld, str, ld_data2); CPOUT_08(ld, str, ld_reserved, 32); + bmodified(bh); } void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld) @@ -561,28 +576,6 @@ void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld) pv(ld, ld_data2, "%u", "0x%x"); } -void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf) -{ - struct gfs2_inum_range *str = (struct gfs2_inum_range *)buf; - - CPIN_64(ir, str, ir_start); - CPIN_64(ir, str, ir_length); -} - -void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf) -{ - struct gfs2_inum_range *str = (struct gfs2_inum_range *)buf; - - CPOUT_64(ir, str, ir_start); - CPOUT_64(ir, str, ir_length); -} - -void gfs2_inum_range_print(struct gfs2_inum_range *ir) -{ - pv(ir, ir_start, "%llu", "0x%llx"); - pv(ir, ir_length, "%llu", "0x%llx"); -} - void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf) { struct gfs2_statfs_change *str = (struct gfs2_statfs_change *)buf; @@ -608,22 +601,25 @@ void gfs2_statfs_change_print(struct gfs2_statfs_change *sc) pv(sc, sc_dinodes, "%lld", "0x%llx"); } -void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf) +void gfs2_quota_change_in(struct gfs2_quota_change *qc, + struct gfs2_buffer_head *bh) { - struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf; + struct gfs2_quota_change *str = (struct gfs2_quota_change *)bh->b_data; CPIN_64(qc, str, qc_change); CPIN_32(qc, str, qc_flags); CPIN_32(qc, str, qc_id); } -void gfs2_quota_change_out(struct gfs2_quota_change *qc, char *buf) +void gfs2_quota_change_out(struct gfs2_quota_change *qc, + struct gfs2_buffer_head *bh) { - struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf; + struct gfs2_quota_change *str = (struct gfs2_quota_change *)bh->b_data; CPOUT_64(qc, str, qc_change); CPOUT_32(qc, str, qc_flags); CPOUT_32(qc, str, qc_id); + bmodified(bh); } void gfs2_quota_change_print(struct gfs2_quota_change *qc) diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c index 03c1703..fee7ef2 100644 --- a/gfs2/libgfs2/recovery.c +++ b/gfs2/libgfs2/recovery.c @@ -66,7 +66,7 @@ int get_log_header(struct gfs2_inode *ip, unsigned int blk, tmp->lh_hash = 0; hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); tmp->lh_hash = saved_hash; - gfs2_log_header_in(&lh, bh->b_data); + gfs2_log_header_in(&lh, bh); brelse(bh); if (error || lh.lh_blkno != blk || lh.lh_hash != hash) diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index 2d0d7a4..ed1df78 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -139,7 +139,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd) } } - gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data); + gfs2_rgrp_in(&rgd->rg, rgd->bh[0]); return 0; } diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c index 06fa439..6a481bc 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -63,8 +63,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid)); #endif bh = bget(&sdp->buf_list, sdp->sb_addr); - gfs2_sb_out(&sb, bh->b_data); - bmodified(bh); + gfs2_sb_out(&sb, bh); brelse(bh); if (sdp->debug) { @@ -107,11 +106,10 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j, lh.lh_sequence = seq; lh.lh_blkno = x; - gfs2_log_header_out(&lh, bh->b_data); + gfs2_log_header_out(&lh, bh); hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); ((struct gfs2_log_header *)bh->b_data)->lh_hash = cpu_to_be32(hash); - bmodified(bh); brelse(bh); if (++seq == blocks) @@ -222,9 +220,8 @@ static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) if (!bh) return -1; - gfs2_meta_header_out(&mh, bh->b_data); + gfs2_meta_header_out(&mh, bh); - bmodified(bh); brelse(bh); } diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 8e20ec0..00a2ae7 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -59,7 +59,7 @@ int read_sb(struct gfs2_sbd *sdp) int error; bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - gfs2_sb_in(&sdp->sd_sb, bh->b_data); + gfs2_sb_in(&sdp->sd_sb, bh); brelse(bh); error = check_sb(&sdp->sd_sb); @@ -257,8 +257,7 @@ int write_sb(struct gfs2_sbd *sbp) struct gfs2_buffer_head *bh; bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); - gfs2_sb_out(&sbp->sd_sb, bh->b_data); - bmodified(bh); + gfs2_sb_out(&sbp->sd_sb, bh); brelse(bh); bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */ return 0; diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c index ff2ba28..be13271 100644 --- a/gfs2/mkfs/main_jadd.c +++ b/gfs2/mkfs/main_jadd.c @@ -297,7 +297,9 @@ add_qc(struct gfs2_sbd *sdp) sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); unsigned int x; struct gfs2_meta_header mh; + struct gfs2_buffer_head dummy_bh; + dummy_bh.b_data = buf; make_jdata(fd, "clear"); memset(buf, 0, sdp->bsize); @@ -319,7 +321,7 @@ add_qc(struct gfs2_sbd *sdp) mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_QC; mh.mh_format = GFS2_FORMAT_QC; - gfs2_meta_header_out(&mh, buf); + gfs2_meta_header_out(&mh, &dummy_bh); for (x=0; x<blocks; x++) { if (write(fd, buf, sdp->bsize) != sdp->bsize) { @@ -431,10 +433,12 @@ add_j(struct gfs2_sbd *sdp) for (x=0; x<blocks; x++) { uint32_t hash; + struct gfs2_buffer_head dummy_bh; + dummy_bh.b_data = buf; lh.lh_sequence = seq; lh.lh_blkno = x; - gfs2_log_header_out(&lh, buf); + gfs2_log_header_out(&lh, &dummy_bh); hash = gfs2_disk_hash(buf, sizeof(struct gfs2_log_header)); ((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash); diff --git a/gfs2/quota/main.c b/gfs2/quota/main.c index 3812669..fa8f4c3 100644 --- a/gfs2/quota/main.c +++ b/gfs2/quota/main.c @@ -285,7 +285,9 @@ read_superblock(struct gfs2_sb *sb, struct gfs2_sbd *sdp) { int fd; char buf[PATH_MAX]; - + struct gfs2_buffer_head dummy_bh; + + dummy_bh.b_data = buf; fd = open(sdp->device_name, O_RDONLY); if (fd < 0) { die("Could not open the block device %s: %s\n", @@ -303,7 +305,7 @@ read_superblock(struct gfs2_sb *sb, struct gfs2_sbd *sdp) strerror(errno), __FUNCTION__, __LINE__); exit(-1); } - gfs2_sb_in(sb, buf); + gfs2_sb_in(sb, &dummy_bh); close(fd); } diff --git a/gfs2/tool/sb.c b/gfs2/tool/sb.c index 3d378e9..0930aaf 100644 --- a/gfs2/tool/sb.c +++ b/gfs2/tool/sb.c @@ -71,7 +71,9 @@ do_sb(int argc, char **argv) int fd; unsigned char buf[GFS2_BASIC_BLOCK], input[256]; struct gfs2_sb sb; + struct gfs2_buffer_head dummy_bh; + dummy_bh.b_data = (char *)buf; if (optind == argc) die("Usage: gfs2_tool sb <device> <field> [newval]\n"); @@ -117,7 +119,7 @@ do_sb(int argc, char **argv) exit(-1); } - gfs2_sb_in(&sb, (char*) buf); + gfs2_sb_in(&sb, &dummy_bh); if (sb.sb_header.mh_magic != GFS2_MAGIC || sb.sb_header.mh_type != GFS2_METATYPE_SB) @@ -201,7 +203,7 @@ do_sb(int argc, char **argv) die( _("unknown field %s\n"), field); if (newval) { - gfs2_sb_out(&sb,(char*) buf); + gfs2_sb_out(&sb, &dummy_bh); if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) != GFS2_SB_ADDR * GFS2_BASIC_BLOCK) {
1
0
0
0
cluster: STABLE3 - Attach buffers to rgrp_list structs
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=8a…
Commit: 8a6c9c5238df2449dd05b27a0a2b25c098961962 Parent: 010c004b1dbe1622868dbc4bb0ba7a1426e2ecea Author: Bob Peterson <rpeterso(a)redhat.com> AuthorDate: Fri Dec 4 10:40:54 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 Attach buffers to rgrp_list structs This patch attaches a buffer_head to every rgrp_list in memory. This greatly improves performance because it no longer needs to get and put the buffers for the rgrps all the time. Since the buffers are linked to the rgrp list, they no longer need to be linked to each other, so it helps untangle the buffer_head mess. rhbz#455300 --- gfs2/convert/gfs2_convert.c | 100 ++++++++++++++----------------------------- gfs2/edit/hexedit.c | 16 ++++--- gfs2/edit/savemeta.c | 19 +------- gfs2/fsck/initialize.c | 12 +----- gfs2/fsck/main.c | 7 +++ gfs2/fsck/pass1.c | 32 +------------- gfs2/fsck/pass5.c | 45 ++++++-------------- gfs2/fsck/rgrepair.c | 65 +++++++++------------------ gfs2/libgfs2/fs_bits.c | 61 ++++---------------------- gfs2/libgfs2/fs_geometry.c | 1 - gfs2/libgfs2/fs_ops.c | 79 ++++++++++------------------------ gfs2/libgfs2/gfs1.c | 33 ++++---------- gfs2/libgfs2/libgfs2.h | 20 +++----- gfs2/libgfs2/rgrp.c | 57 +++++++++++++++++-------- gfs2/libgfs2/structures.c | 13 ++---- gfs2/libgfs2/super.c | 31 +++----------- 16 files changed, 188 insertions(+), 403 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 49e6058..13ba9d7 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -156,29 +156,24 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...) /* Fixes all unallocated metadata bitmap states (which are */ /* valid in gfs1 but invalid in gfs2). */ /* ------------------------------------------------------------------------- */ -static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2, - struct gfs2_buffer_head **rgbh) +static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg) { uint32_t blk; int x, y; struct gfs2_rindex *ri; unsigned char state; - ri = &rgd2->ri; - if (gfs2_compute_bitstructs(sdp, rgd2)) { - log_crit("gfs2_convert: Error converting bitmaps.\n"); - exit(-1); - } + ri = &rg->ri; for (blk = 0; blk < ri->ri_length; blk++) { x = (blk) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp); for (; x < sdp->bsize; x++) for (y = 0; y < GFS2_NBBY; y++) { - state = (rgbh[blk]->b_data[x] >> + state = (rg->bh[blk]->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03; if (state == 0x02) /* unallocated metadata state invalid */ - rgbh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y)); + rg->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y)); } } }/* convert_bitmaps */ @@ -190,49 +185,34 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2, static int convert_rgs(struct gfs2_sbd *sbp) { struct rgrp_list *rgd; - struct gfs2_rgrp rg; osi_list_t *tmp; struct gfs1_rgrp *rgd1; int rgs = 0; - struct gfs2_buffer_head **rgbh; /* --------------------------------- */ /* Now convert its rgs into gfs2 rgs */ /* --------------------------------- */ osi_list_foreach(tmp, &sbp->rglist) { rgd = osi_list_entry(tmp, struct rgrp_list, list); - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } - - gfs2_rgrp_read(sbp, rgd, rgbh, &rg); - rgd1 = (struct gfs1_rgrp *)&rg; /* recast as gfs1 structure */ + rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */ /* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */ /* convert from be to cpu. We must do it now. */ - rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta); - rgd->rg_free = rg.rg_free; + rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta); /* Zero it out so we don't add it again in case something breaks */ /* later on in the process and we have to re-run convert */ rgd1->rg_freemeta = 0; sbp->blks_total += rgd->ri.ri_data; - sbp->blks_alloced += (rgd->ri.ri_data - rg.rg_free); + sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free); sbp->dinodes_alloced += rgd1->rg_useddi; - convert_bitmaps(sbp, rgd, rgbh); + convert_bitmaps(sbp, rgd); /* Write the updated rgrp to the gfs2 buffer */ - gfs2_rgrp_out(&rg, rgbh[0]->b_data); + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); rgs++; if (rgs % 100 == 0) { printf("."); fflush(stdout); } - free(rgbh); } return 0; }/* superblock_cvt */ @@ -702,8 +682,6 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) int first; int error = 0; int rgs_processed = 0; - struct gfs2_buffer_head **rgbh; - struct gfs2_rgrp rg; log_notice("Converting inodes.\n"); sbp->md.next_inum = 1; /* starting inode numbering */ @@ -717,20 +695,6 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) rgs_processed++; rgd = osi_list_entry(tmp, struct rgrp_list, list); first = 1; - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } - if (gfs2_rgrp_read(sbp, rgd, rgbh, &rg)) { - log_crit("Unable to read rgrp.\n"); - free(rgbh); - return -1; - } while (1) { /* for all inodes in the resource group */ gettimeofday(&tv, NULL); /* Put out a warm, fuzzy message every second so the customer */ @@ -773,21 +737,19 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) sizeof(struct gfs2_rgrp); /* if it's on this page */ if (buf_offset + bitmap_byte < sbp->bsize) { - rgbh[blk]->b_data[buf_offset + bitmap_byte] &= + rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &= ~(0x03 << (GFS2_BIT_SIZE * byte_bit)); - rgbh[blk]->b_data[buf_offset + bitmap_byte] |= + rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |= (0x01 << (GFS2_BIT_SIZE * byte_bit)); break; } bitmap_byte -= (sbp->bsize - buf_offset); - bmodified(bh); + bmodified(rgd->bh[blk]); } } brelse(bh); first = 0; } /* while 1 */ - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); } /* for all rgs */ log_notice("\r%" PRIu64" inodes from %d rgs converted.", sbp->md.next_inum, rgs_processed); @@ -1345,8 +1307,6 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) struct rgrp_list *rgd, *rgdhigh; osi_list_t *tmp; struct gfs2_meta_header mh; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_RB; @@ -1387,11 +1347,11 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) } memset(rgd, 0, sizeof(struct rgrp_list)); size = jndx->ji_nsegment * be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size); - rg.rg_header.mh_magic = GFS2_MAGIC; - rg.rg_header.mh_type = GFS2_METATYPE_RG; - rg.rg_header.mh_format = GFS2_FORMAT_RG; - rg.rg_flags = 0; - rg.rg_dinodes = 0; + rgd->rg.rg_header.mh_magic = GFS2_MAGIC; + rgd->rg.rg_header.mh_type = GFS2_METATYPE_RG; + rgd->rg.rg_header.mh_format = GFS2_FORMAT_RG; + rgd->rg.rg_flags = 0; + rgd->rg.rg_dinodes = 0; rgd->ri.ri_addr = jndx->ji_addr; /* new rg addr becomes ji addr */ rgd->ri.ri_length = rgrp_length(size, sdp); /* aka bitblocks */ @@ -1402,32 +1362,36 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) /* Round down to nearest multiple of GFS2_NBBY */ while (rgd->ri.ri_data & 0x03) rgd->ri.ri_data--; - rg.rg_free = rgd->ri.ri_data; - rgd->rg_free = rg.rg_free; + rgd->rg.rg_free = rgd->ri.ri_data; rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY; - if(!(rgbh = (struct gfs2_buffer_head **) + if(!(rgd->bh = (struct gfs2_buffer_head **) malloc(rgd->ri.ri_length * sizeof(struct gfs2_buffer_head *)))) return -1; - if(!memset(rgbh, 0, rgd->ri.ri_length * + if(!memset(rgd->bh, 0, rgd->ri.ri_length * sizeof(struct gfs2_buffer_head *))) { - free(rgbh); + free(rgd->bh); return -1; } - - convert_bitmaps(sdp, rgd, rgbh); for (x = 0; x < rgd->ri.ri_length; x++) { - rgbh[x]->b_count++; + rgd->bh[x] = bget(&sdp->buf_list, rgd->ri.ri_addr + x); + memset(rgd->bh[x]->b_data, 0, sdp->bsize); + } + if (gfs2_compute_bitstructs(sdp, rgd)) { + log_crit("gfs2_convert: Error converting bitmaps.\n"); + exit(-1); + } + convert_bitmaps(sdp, rgd); + for (x = 0; x < rgd->ri.ri_length; x++) { if (x) - gfs2_meta_header_out(&mh, rgbh[x]->b_data); + gfs2_meta_header_out(&mh, rgd->bh[x]->b_data); else - gfs2_rgrp_out(&rg, rgbh[x]->b_data); + gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data); } /* Add the new gfs2 rg to our list: We'll output the rg index later. */ osi_list_add_prev((osi_list_t *)&rgd->list, (osi_list_t *)&sdp->rglist); - free(rgbh); } /* for each journal */ return error; }/* journ_space_to_rg */ diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 933871a..437d931 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -563,9 +563,11 @@ int display_block_type(const char *lpBuffer, int from_restore) struct rgrp_list *rgd; rgd = gfs2_blk2rgrpd(&sbd, block); - if (rgd) + if (rgd) { + gfs2_rgrp_read(&sbd, rgd); type = gfs2_get_bitmap(&sbd, block, rgd); - else + gfs2_rgrp_relse(rgd); + } else type = 4; screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8; if (!screen_chunk_size) @@ -1690,7 +1692,7 @@ static int display_extended(void) /* ------------------------------------------------------------------------ */ static void read_superblock(int fd) { - int count, bitmap_blocks = 0; + int count; sbd1 = (struct gfs_sb *)&sbd.sd_sb; ioctl(fd, BLKFLSBUF, 0); @@ -1749,8 +1751,7 @@ static void read_superblock(int fd) sbd.md.riinode = gfs2_load_inode(&sbd, sbd1->sb_rindex_di.no_addr); sbd.fssize = sbd.device.length; - gfs1_rindex_read(&sbd, fd, &count, &bitmap_blocks); - /*gfs1_ri_update(&sbd, 0, &count, 1);*/ + gfs1_rindex_read(&sbd, 0, &count); } else { sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) / sizeof(uint64_t); @@ -1760,8 +1761,7 @@ static void read_superblock(int fd) sbd.sd_sb.sb_master_dir.no_addr); gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode); sbd.fssize = sbd.device.length; - rindex_read(&sbd, fd, &count, &bitmap_blocks); - /*ri_update(&sbd, 0, &count);*/ + rindex_read(&sbd, 0, &count); } } @@ -2518,7 +2518,9 @@ static void find_change_block_alloc(int *newval) } else { rgd = gfs2_blk2rgrpd(&sbd, ablock); if (rgd) { + gfs2_rgrp_read(&sbd, rgd); type = gfs2_get_bitmap(&sbd, ablock, rgd); + gfs2_rgrp_relse(rgd); printf("%d (%s)\n", type, allocdesc[gfs1][type]); } else { gfs2_rgrp_free(&sbd.rglist); diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 46a6522..88dca25 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -519,8 +519,6 @@ void savemeta(char *out_fn, int saveoption) int rgcount; uint64_t jindex_block; struct gfs2_buffer_head *bh; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; slow = (saveoption == 1); sbd.md.journals = 1; @@ -654,16 +652,7 @@ void savemeta(char *out_fn, int saveoption) int i, first; rgd = osi_list_entry(tmp, struct rgrp_list, list); - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - break; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - break; - } - slow = gfs2_rgrp_read(&sbd, rgd, rgbh, &rg); + slow = gfs2_rgrp_read(&sbd, rgd); if (slow) continue; log_debug("RG at %lld (0x%llx) is %u long\n", @@ -687,8 +676,7 @@ void savemeta(char *out_fn, int saveoption) if (saveoption != 2) { int blktype; - while (!gfs2_next_rg_meta(&sbd, rgd, &block, - first)) { + while (!gfs2_next_rg_meta(rgd, &block, first)){ warm_fuzzy_stuff(block, FALSE, TRUE); blktype = save_block(sbd.device_fd, out_fd, block); @@ -706,8 +694,7 @@ void savemeta(char *out_fn, int saveoption) first = 0; } } - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); + gfs2_rgrp_relse(rgd); } } if (slow) { diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index 2241df2..555e8e4 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -70,17 +70,7 @@ static void empty_super_block(struct gfs2_sbd *sdp) uint32_t i; log_info( _("Freeing buffers.\n")); - while(!osi_list_empty(&sdp->rglist)){ - struct rgrp_list *rgd; - - rgd = osi_list_entry(sdp->rglist.next, struct rgrp_list, list); - log_debug( _("Deleting rgd for 0x%llx: rgd=0x%p bits=0x%p\n"), - (unsigned long long)rgd->ri.ri_addr, rgd, rgd->bits); - osi_list_del(&rgd->list); - if(rgd->bits) - free(rgd->bits); - free(rgd); - } + gfs2_rgrp_free(&sdp->rglist); for(i = 0; i < FSCK_HASH_SIZE; i++) { while(!osi_list_empty(&inode_hash[i])) { diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 91396d3..2083e94 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -328,6 +328,8 @@ int main(int argc, char **argv) int j; int error = 0; int all_clean = 0; + osi_list_t *tmp; + struct rgrp_list *rgd; setlocale(LC_ALL, ""); textdomain("gfs2-utils"); @@ -464,6 +466,11 @@ int main(int argc, char **argv) if (!opts.no && errors_corrected) log_notice( _("Writing changes to disk\n")); + for (tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next) { + rgd = osi_list_entry(tmp, struct rgrp_list, list); + gfs2_rgrp_relse(rgd); + } + bsync(&sbp->buf_list); destroy(sbp); log_notice( _("gfs2_fsck complete \n")); diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index a64bf3c..09493b8 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -934,8 +934,6 @@ int pass1(struct gfs2_sbd *sbp) uint64_t blk_count; uint64_t offset; uint64_t rg_count = 0; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; /* FIXME: In the gfs fsck, we had to mark things like the * journals and indices and such as 'other_meta' - in gfs2, @@ -958,29 +956,10 @@ int pass1(struct gfs2_sbd *sbp) log_info( _("Checking metadata in Resource Group #%" PRIu64 "\n"), rg_count); rgd = osi_list_entry(tmp, struct rgrp_list, list); - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return FSCK_ERROR; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return FSCK_ERROR; - } - if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){ - stack; - free(rgbh); - return FSCK_ERROR; - } - log_debug( _("RG at %llu (0x%llx) is %u long\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - rgd->ri.ri_length); for (i = 0; i < rgd->ri.ri_length; i++) { if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i, gfs2_meta_other)){ stack; - free(rgbh); return FSCK_ERROR; } } @@ -991,14 +970,11 @@ int pass1(struct gfs2_sbd *sbp) while (1) { /* "block" is relative to the entire file system */ - if (gfs2_next_rg_meta(sbp, rgd, &block, first)) + if (gfs2_next_rg_meta(rgd, &block, first)) break; warm_fuzzy_stuff(block); - if (fsck_abort) { /* if asked to abort */ - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); + if (fsck_abort) /* if asked to abort */ return FSCK_OK; - } if (skip_this_pass) { printf( _("Skipping pass 1 is not a good idea.\n")); skip_this_pass = FALSE; @@ -1009,15 +985,11 @@ int pass1(struct gfs2_sbd *sbp) if (scan_meta(sbp, bh, block)) { stack; brelse(bh); - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); return FSCK_ERROR; } brelse(bh); first = 0; } - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); } return FSCK_OK; } diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index 495ad0a..d384816 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -145,8 +145,7 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b } static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, - uint32_t *count, struct gfs2_buffer_head **rgbh, - struct gfs2_rgrp *rg) + uint32_t *count) { uint32_t i; struct gfs2_bitmap *bits; @@ -157,26 +156,26 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, bits = &rgp->bits[i]; /* update the bitmaps */ - check_block_status(sbp, rgbh[i]->b_data + bits->bi_offset, + check_block_status(sbp, rgp->bh[i]->b_data + bits->bi_offset, bits->bi_len, &rg_block, rgp->ri.ri_data0, count); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return; } /* actually adjust counters and write out to disk */ - if(rgp->rg_free != count[0]) { + if(rgp->rg.rg_free != count[0]) { log_err( _("RG #%llu (0x%llx) free count inconsistent: " "is %u should be %u\n"), (unsigned long long)rgp->ri.ri_addr, (unsigned long long)rgp->ri.ri_addr, - rgp->rg_free, count[0]); - rgp->rg_free = count[0]; + rgp->rg.rg_free, count[0]); + rgp->rg.rg_free = count[0]; update = 1; } - if(rg->rg_dinodes != count[1]) { + if(rgp->rg.rg_dinodes != count[1]) { log_err( _("Inode count inconsistent: is %u should be %u\n"), - rg->rg_dinodes, count[1]); - rg->rg_dinodes = count[1]; + rgp->rg.rg_dinodes, count[1]); + rgp->rg.rg_dinodes = count[1]; update = 1; } if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) { @@ -190,7 +189,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, if(query( _("Update resource group counts? (y/n) "))) { log_warn( _("Resource group counts updated\n")); /* write out the rgrp */ - gfs2_rgrp_out(rg, rgbh[0]->b_data); + gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data); } else log_err( _("Resource group counts left inconsistent\n")); } @@ -205,11 +204,9 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, int pass5(struct gfs2_sbd *sbp) { osi_list_t *tmp; - struct rgrp_list *rgd = NULL; + struct rgrp_list *rgp = NULL; uint32_t count[3]; uint64_t rg_count = 0; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; /* Reconcile RG bitmaps with fsck bitmap */ for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){ @@ -217,27 +214,11 @@ int pass5(struct gfs2_sbd *sbp) return FSCK_OK; log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count); memset(count, 0, sizeof(count)); - rgd = osi_list_entry(tmp, struct rgrp_list, list); - - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return FSCK_ERROR; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return FSCK_ERROR; - } - if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){ - stack; - free(rgbh); - return FSCK_ERROR; - } + rgp = osi_list_entry(tmp, struct rgrp_list, list); + rg_count++; /* Compare the bitmaps and report the differences */ - update_rgrp(sbp, rgd, count, rgbh, &rg); - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); + update_rgrp(sbp, rgp, count); } /* Fix up superblock info based on this - don't think there's * anything to do here... */ diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 3ce0f95..7cd0b32 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -373,36 +373,35 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list, * rewrite_rg_block - rewrite ("fix") a buffer with rg or bitmap data * returns: 0 if the rg was repaired, otherwise 1 */ -static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - uint64_t errblock, struct gfs2_buffer_head **rgbh, - struct gfs2_rgrp *rg) +static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg, + uint64_t errblock) { - int x = errblock - rgd->ri.ri_addr; + int x = errblock - rg->ri.ri_addr; log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither" " GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"), - rgbh[x]->b_blocknr, rgbh[x]->b_blocknr, - (int)x+1, (int)rgd->ri.ri_length); - if (query( _("Fix the RG? (y/n)"))) { + rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr, + (int)x+1, (int)rg->ri.ri_length); + if (query( _("Fix the Resource Group? (y/n)"))) { log_err( _("Attempting to repair the RG.\n")); - rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x); + rg->bh[x] = bread(&sdp->buf_list, rg->ri.ri_addr + x); if (x) { struct gfs2_meta_header mh; mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_RB; mh.mh_format = GFS2_FORMAT_RB; - gfs2_meta_header_out(&mh, rgbh[x]->b_data); + gfs2_meta_header_out(&mh, rg->bh[x]->b_data); } else { - memset(rg, 0, sizeof(struct gfs2_rgrp)); - rg->rg_header.mh_magic = GFS2_MAGIC; - rg->rg_header.mh_type = GFS2_METATYPE_RG; - rg->rg_header.mh_format = GFS2_FORMAT_RG; - rg->rg_free = rgd->ri.ri_data; - gfs2_rgrp_out(rg, rgbh[x]->b_data); + memset(&rg->rg, 0, sizeof(struct gfs2_rgrp)); + rg->rg.rg_header.mh_magic = GFS2_MAGIC; + rg->rg.rg_header.mh_type = GFS2_METATYPE_RG; + rg->rg.rg_header.mh_format = GFS2_FORMAT_RG; + rg->rg.rg_free = rg->ri.ri_data; + gfs2_rgrp_out(&rg->rg, rg->bh[x]->b_data); } - bmodified(rgbh[x]); - brelse(rgbh[x]); + bmodified(rg->bh[x]); + brelse(rg->bh[x]); return 0; } return 1; @@ -423,7 +422,6 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) int calc_rg_count = 0, rgcount_from_index, rg; osi_list_t *exp, *act; /* expected, actual */ struct gfs2_rindex buf; - int bitmap_blocks; if (trust_lvl == blind_faith) return 0; @@ -448,7 +446,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) } /* Read in the rindex */ osi_list_init(&sdp->rglist); /* Just to be safe */ - rindex_read(sdp, 0, &rgcount_from_index, &bitmap_blocks); + rindex_read(sdp, 0, &rgcount_from_index); if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) { log_warn( _("WARNING: rindex file is corrupt.\n")); gfs2_rgrp_free(&expected_rglist); @@ -549,41 +547,22 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) struct rgrp_list *rgd; uint64_t prev_err = 0, errblock; int i; - struct gfs2_rgrp rgrp; - struct gfs2_buffer_head **rgbh; /* Now we try repeatedly to read in the rg. For every block */ /* we encounter that has errors, repair it and try again. */ i = 0; do { rgd = osi_list_entry(act, struct rgrp_list, list); - - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, bitmap_blocks * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } - - errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rgrp); + errblock = gfs2_rgrp_read(sdp, rgd); if (errblock) { - if (errblock == prev_err) { - free(rgbh); + if (errblock == prev_err) break; - } prev_err = errblock; - rewrite_rg_block(sdp, rgd, errblock, rgbh, - &rgrp); - } - else { - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); + rewrite_rg_block(sdp, rgd, errblock); + } else { + gfs2_rgrp_relse(rgd); break; } - free(rgbh); i++; } while (i < rgd->ri.ri_length); } diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c index 7c874ad..e657aa5 100644 --- a/gfs2/libgfs2/fs_bits.c +++ b/gfs2/libgfs2/fs_bits.c @@ -113,8 +113,6 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state) struct rgrp_list *rgd; unsigned char *byte, cur_state; unsigned int bit; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; /* FIXME: should GFS2_BLKST_INVALID be allowed */ if ((state < GFS2_BLKST_FREE) || (state > GFS2_BLKST_DINODE)) @@ -125,20 +123,6 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state) if(!rgd) return -1; - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, rgd->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } - - if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg)) { - free(rgbh); - return -1; - } rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0); for(buf= 0; buf < rgd->ri.ri_length; buf++){ bits = &(rgd->bits[buf]); @@ -146,7 +130,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state) break; } - byte = (unsigned char *)(rgbh[buf]->b_data + bits->bi_offset) + + byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) + (rgrp_block/GFS2_NBBY - bits->bi_start); bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE; @@ -154,9 +138,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state) *byte ^= cur_state << bit; *byte |= state << bit; - bmodified(rgbh[buf]); - gfs2_rgrp_relse(rgd, rgbh); - free(rgbh); + bmodified(rgd->bh[buf]); return 0; } @@ -183,51 +165,28 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, struct gfs2_bitmap *bits = NULL; unsigned int bit; unsigned char *byte; - int local_rgd = 0; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; - int bitmap_blocks = rgd->length; - if(gfs2_check_range(sdp, blkno)) - return -1; - if(rgd == NULL) { - local_rgd = 1; + if (rgd == NULL) { rgd = gfs2_blk2rgrpd(sdp, blkno); - } - if(rgd == NULL) - return -1; - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, bitmap_blocks * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; + if(rgd == NULL) + return -1; } - if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg)) - return -1; - rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0); - for(i= 0; i < rgd->ri.ri_length; i++){ + for (i = 0; i < rgd->ri.ri_length; i++) { bits = &(rgd->bits[i]); - if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){ + if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)) break; - } } - if(i >= rgd->ri.ri_length){ - gfs2_rgrp_relse(rgd, rgbh); + if (i >= rgd->ri.ri_length) return -1; - } - - byte = (unsigned char *)(rgbh[i]->b_data + bits->bi_offset) + + byte = (unsigned char *)(rgd->bh[i]->b_data + bits->bi_offset) + (rgrp_block/GFS2_NBBY - bits->bi_start); bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE; val = ((*byte >> bit) & GFS2_BIT_MASK); - if(local_rgd) - gfs2_rgrp_relse(rgd, rgbh); + return val; } diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c index f666459..f2993f5 100644 --- a/gfs2/libgfs2/fs_geometry.c +++ b/gfs2/libgfs2/fs_geometry.c @@ -211,7 +211,6 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write) rg.rg_header.mh_type = GFS2_METATYPE_RG; rg.rg_header.mh_format = GFS2_FORMAT_RG; rg.rg_free = rgblocks; - rl->rg_free = rgblocks; if (do_write) { for (x = 0; x < bitblocks; x++) { diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c index cef5d21..32f1cac 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -56,17 +56,16 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type) osi_list_t *tmp, *head; struct rgrp_list *rl = NULL; struct gfs2_rindex *ri; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh; + struct gfs2_rgrp *rg; unsigned int block, bn = 0, x = 0, y = 0; unsigned int state; + struct gfs2_buffer_head *bh; memset(&rg, 0, sizeof(rg)); - for (head = &sdp->rglist, tmp = head->next; - tmp != head; + for (head = &sdp->rglist, tmp = head->next; tmp != head; tmp = tmp->next) { rl = osi_list_entry(tmp, struct rgrp_list, list); - if (rl->rg_free) + if (rl->rg.rg_free) break; } @@ -74,43 +73,29 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type) die("out of space\n"); ri = &rl->ri; - - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(rl->ri.ri_length * - sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, rl->ri.ri_length * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } + rg = &rl->rg; for (block = 0; block < ri->ri_length; block++) { - rgbh[block] = bread(&sdp->buf_list, ri->ri_addr + block); + bh = rl->bh[block]; x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp); - if (!block) - gfs2_rgrp_in(&rg, rgbh[0]->b_data); for (; x < sdp->bsize; x++) for (y = 0; y < GFS2_NBBY; y++) { - state = (rgbh[block]->b_data[x] >> - (GFS2_BIT_SIZE * y)) & 0x03; + state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03; if (state == GFS2_BLKST_FREE) goto found; bn++; } - - brelse(rgbh[block]); } die("allocation is broken (1): %"PRIu64" %u\n", - (uint64_t)rl->ri.ri_addr, rl->rg_free); + (uint64_t)rl->ri.ri_addr, rl->rg.rg_free); found: if (bn >= ri->ri_bitbytes * GFS2_NBBY) die("allocation is broken (2): %u %u %"PRIu64" %u\n", bn, ri->ri_bitbytes * GFS2_NBBY, - (uint64_t)rl->ri.ri_addr, rl->rg_free); + (uint64_t)rl->ri.ri_addr, rl->rg.rg_free); switch (type) { case DATA: @@ -119,27 +104,20 @@ found: break; case DINODE: state = GFS2_BLKST_DINODE; - rg.rg_dinodes++; + rg->rg_dinodes++; break; default: die("bad state\n"); } - rgbh[block]->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y)); - rgbh[block]->b_data[x] |= state << (GFS2_BIT_SIZE * y); - rg.rg_free--; - rl->rg_free--; + bh->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y)); + bh->b_data[x] |= state << (GFS2_BIT_SIZE * y); + rg->rg_free--; - bmodified(rgbh[block]); - brelse(rgbh[block]); - - rgbh[0] = bread(&sdp->buf_list, ri->ri_addr); - gfs2_rgrp_out(&rg, rgbh[0]->b_data); - bmodified(rgbh[0]); - brelse(rgbh[0]); + bmodified(bh); + gfs2_rgrp_out(rg, rl->bh[0]->b_data); sdp->blks_alloced++; - free(rgbh); return ri->ri_data0 + bn; } @@ -1615,20 +1593,15 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len, */ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block) { - struct gfs2_buffer_head *bh; struct rgrp_list *rgd; - struct gfs2_rgrp rg; - gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); /* Adjust the free space count for the freed block */ rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */ - bh = bget(&sdp->buf_list, rgd->ri.ri_addr); /* get the rg buffer */ - gfs2_rgrp_in(&rg, bh->b_data); /* back to the buffer */ - rg.rg_free++; /* adjust the free count */ - rgd->rg_free++; - gfs2_rgrp_out(&rg, bh->b_data); /* back to the buffer */ - bmodified(bh); - brelse(bh); /* release the buffer */ + if (rgd) { + gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); + rgd->rg.rg_free++; /* adjust the free count */ + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); /* back to the buffer */ + } } /** @@ -1645,7 +1618,6 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) uint32_t height; osi_list_t metalist[GFS2_MAX_META_HEIGHT]; osi_list_t *cur_list, *next_list, *tmp; - struct gfs2_rgrp rg; for (h = 0; h < GFS2_MAX_META_HEIGHT; h++) osi_list_init(&metalist[h]); @@ -1687,13 +1659,8 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) inode_put(ip); /* Now we have to adjust the rg freespace count and inode count: */ rgd = gfs2_blk2rgrpd(sdp, diblock); - bh = bread(&sdp->buf_list, rgd->ri.ri_addr); /* get the buffer */ - gfs2_rgrp_in(&rg, bh->b_data); - rg.rg_free++; - rgd->rg_free++; - rg.rg_dinodes--; /* one less inode in use */ - gfs2_rgrp_out(&rg, bh->b_data); - bmodified(bh); - brelse(bh); /* release the buffer */ + rgd->rg.rg_free++; + rgd->rg.rg_dinodes--; /* one less inode in use */ + gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); return 0; } diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c index 2b0dd8d..a5b5810 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -229,8 +229,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin, * * Returns: 0 on success, -1 on failure */ -int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, - int *bitmap_blocks) +int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) { unsigned int rg; int error; @@ -240,7 +239,6 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, *count1 = 0; prev_rgd = NULL; - *bitmap_blocks = 0; for (rg = 0; ; rg++) { if (fd > 0) error = read(fd, &buf, sizeof(struct gfs2_rindex)); @@ -263,8 +261,6 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, gfs2_rindex_in(&rgd->ri, (char *)&buf); - if (rgd->ri.ri_length > *bitmap_blocks) - *bitmap_blocks = rgd->ri.ri_length; rgd->start = rgd->ri.ri_addr; if (prev_rgd) { prev_length = rgd->start - prev_rgd->start; @@ -295,48 +291,37 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet) { struct rgrp_list *rgd; + struct gfs2_rindex *ri; osi_list_t *tmp; int count1 = 0, count2 = 0; uint64_t errblock = 0; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh = NULL; - int bitmap_blocks; + uint64_t rmax = 0; - if (gfs1_rindex_read(sdp, fd, &count1, &bitmap_blocks)) + if (gfs1_rindex_read(sdp, fd, &count1)) goto fail; - - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, bitmap_blocks * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) { rgd = osi_list_entry(tmp, struct rgrp_list, list); - errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg); - if (errblock) { - free(rgbh); + errblock = gfs2_rgrp_read(sdp, rgd); + if (errblock) return errblock; - } count2++; if (!quiet && count2 % 100 == 0) { printf("."); fflush(stdout); } + ri = &rgd->ri; + if (ri->ri_data0 + ri->ri_data - 1 > rmax) + rmax = ri->ri_data0 + ri->ri_data - 1; } *rgcount = count1; if (count1 != count2) goto fail; - free(rgbh); return 0; fail: gfs2_rgrp_free(&sdp->rglist); - free(rgbh); return -1; } diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 1f10027..3369d0a 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -97,10 +97,11 @@ struct rgrp_list { osi_list_t list; uint64_t start; /* The offset of the beginning of this resource group */ uint64_t length; /* The length of this resource group */ - uint32_t rg_free; /* Free blocks */ struct gfs2_rindex ri; + struct gfs2_rgrp rg; struct gfs2_bitmap *bits; + struct gfs2_buffer_head **bh; }; struct gfs2_buffer_head { @@ -524,8 +525,7 @@ extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, uint64_t *dblock, uint32_t *extlen, int prealloc); extern int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset, unsigned int size); -extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, - int *bitmap_blocks); +extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1); extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet); extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); @@ -635,11 +635,8 @@ extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head); /* rgrp.c */ extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd); extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk); -extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - struct gfs2_buffer_head **bh, - struct gfs2_rgrp *rg); -extern void gfs2_rgrp_relse(struct rgrp_list *rgd, - struct gfs2_buffer_head **bh); +extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd); +extern void gfs2_rgrp_relse(struct rgrp_list *rgd); extern void gfs2_rgrp_free(osi_list_t *rglist); /* structures.c */ @@ -655,16 +652,15 @@ extern int build_root(struct gfs2_sbd *sdp); extern int do_init_inum(struct gfs2_sbd *sdp); extern int do_init_statfs(struct gfs2_sbd *sdp); extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type); -extern int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - uint64_t *block, int first); +extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, + int first); extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, uint64_t *block, uint32_t type, int first); /* super.c */ extern int check_sb(struct gfs2_sb *sb); extern int read_sb(struct gfs2_sbd *sdp); extern int ji_update(struct gfs2_sbd *sdp); -extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, - int *bitmap_blocks); +extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1); extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount); extern int write_sb(struct gfs2_sbd *sdp); diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index 1e10200..2d0d7a4 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -72,6 +72,14 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd) rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data) return -1; + if (rgd->bh) /* If we already have a bh allocated */ + return 0; /* don't want to allocate another */ + if(!(rgd->bh = (struct gfs2_buffer_head **) + malloc(length * sizeof(struct gfs2_buffer_head *)))) + return -1; + if(!memset(rgd->bh, 0, length * sizeof(struct gfs2_buffer_head *))) + return -1; + return 0; } @@ -86,56 +94,63 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd) struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk) { osi_list_t *tmp; - struct rgrp_list *rgd = NULL; + struct rgrp_list *rgd; + static struct rgrp_list *prev_rgd = NULL; struct gfs2_rindex *ri; - for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ + if (prev_rgd) { + ri = &prev_rgd->ri; + if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) + return prev_rgd; + } + + for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) { rgd = osi_list_entry(tmp, struct rgrp_list, list); ri = &rgd->ri; - if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data){ - break; - } else - rgd = NULL; + if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) { + prev_rgd = rgd; + return rgd; + } } - return rgd; + return NULL; } /** - * fs_rgrp_read - read in the resource group information from disk. + * gfs2_rgrp_read - read in the resource group information from disk. * @rgd - resource group structure * returns: 0 if no error, otherwise the block number that failed */ -uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg) +uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd) { int x, length = rgd->ri.ri_length; for (x = 0; x < length; x++){ - bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x); - if(gfs2_check_meta(bh[x], + rgd->bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x); + if(gfs2_check_meta(rgd->bh[x], (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG)) { uint64_t error; error = rgd->ri.ri_addr + x; for (; x >= 0; x--) - brelse(bh[x]); + brelse(rgd->bh[x]); return error; } } - gfs2_rgrp_in(rg, bh[0]->b_data); - rgd->rg_free = rg->rg_free; + gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data); return 0; } -void gfs2_rgrp_relse(struct rgrp_list *rgd, struct gfs2_buffer_head **bh) +void gfs2_rgrp_relse(struct rgrp_list *rgd) { int x, length = rgd->ri.ri_length; - for (x = 0; x < length; x++) - brelse(bh[x]); + for (x = 0; x < length; x++) { + brelse(rgd->bh[x]); + rgd->bh[x] = NULL; + } } void gfs2_rgrp_free(osi_list_t *rglist) @@ -144,8 +159,14 @@ void gfs2_rgrp_free(osi_list_t *rglist) while(!osi_list_empty(rglist->next)){ rgd = osi_list_entry(rglist->next, struct rgrp_list, list); + if (rgd->bh && rgd->bh[0]) /* if a buffer exists */ + gfs2_rgrp_relse(rgd); /* free them all. */ if(rgd->bits) free(rgd->bits); + if(rgd->bh) { + free(rgd->bh); + rgd->bh = NULL; + } osi_list_del(&rgd->list); free(rgd); } diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c index 02a512e..06fa439 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -454,14 +454,12 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type) * * Returns: 0 on success, -1 when finished */ -int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - uint64_t *block, int first) +int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first) { struct gfs2_bitmap *bits = NULL; uint32_t length = rgd->ri.ri_length; uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0); int i; - struct gfs2_buffer_head *bh; if(!first && (*block < rgd->ri.ri_data0)) { log_err("next_rg_meta: Start block is outside rgrp bounds.\n"); @@ -475,17 +473,14 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, } for(; i < length; i++){ bits = &rgd->bits[i]; - bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i); - blk = gfs2_bitfit((unsigned char *)bh->b_data + + blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data + bits->bi_offset, bits->bi_len, blk, GFS2_BLKST_DINODE); if(blk != BFITNOENT){ *block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0; - brelse(bh); break; } blk=0; - brelse(bh); } if(i == length) return -1; @@ -502,14 +497,14 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, * Returns: 0 on success, -1 on error or finished */ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, - uint64_t *block, uint32_t type, int first) + uint64_t *block, uint32_t type, int first) { struct gfs2_buffer_head *bh = NULL; do{ if (bh) brelse(bh); - if (gfs2_next_rg_meta(sdp, rgd, block, first)) + if (gfs2_next_rg_meta(rgd, block, first)) return -1; bh = bread(&sdp->buf_list, *block); first = 0; diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 67eb77a..8e20ec0 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -162,7 +162,7 @@ int ji_update(struct gfs2_sbd *sdp) * * Returns: 0 on success, -1 on failure */ -int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks) +int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) { unsigned int rg; int error; @@ -172,7 +172,6 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks) *count1 = 0; prev_rgd = NULL; - *bitmap_blocks = 0; for (rg = 0; ; rg++) { if (fd > 0) error = read(fd, &buf, sizeof(struct gfs2_rindex)); @@ -195,8 +194,6 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks) gfs2_rindex_in(&rgd->ri, (char *)&buf); - if (rgd->ri.ri_length > *bitmap_blocks) - *bitmap_blocks = rgd->ri.ri_length; rgd->start = rgd->ri.ri_addr; if (prev_rgd) { prev_length = rgd->start - prev_rgd->start; @@ -228,33 +225,19 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks) int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount) { struct rgrp_list *rgd; + struct gfs2_rindex *ri; osi_list_t *tmp; int count1 = 0, count2 = 0; uint64_t errblock = 0; - struct gfs2_rgrp rg; - struct gfs2_buffer_head **rgbh = NULL; - int bitmap_blocks; - if (rindex_read(sdp, fd, &count1, &bitmap_blocks)) + if (rindex_read(sdp, fd, &count1)) goto fail; - - if(!(rgbh = (struct gfs2_buffer_head **) - malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *)))) - return -1; - if(!memset(rgbh, 0, bitmap_blocks * - sizeof(struct gfs2_buffer_head *))) { - free(rgbh); - return -1; - } - for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) { rgd = osi_list_entry(tmp, struct rgrp_list, list); - errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg); - if (errblock) { - free(rgbh); + errblock = gfs2_rgrp_read(sdp, rgd); + if (errblock) return errblock; - } else - gfs2_rgrp_relse(rgd, rgbh); + ri = &rgd->ri; count2++; } @@ -262,12 +245,10 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount) if (count1 != count2) goto fail; - free(rgbh); return 0; fail: gfs2_rgrp_free(&sdp->rglist); - free(rgbh); return -1; }
1
0
0
0
cluster: STABLE3 - fsck.gfs2: make query() count errors_found, errors_fixed
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=01…
Commit: 010c004b1dbe1622868dbc4bb0ba7a1426e2ecea Parent: 98c92b66e11138e325165cb5e42d21abfc76e8f9 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Wed Dec 2 14:42:55 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 fsck.gfs2: make query() count errors_found, errors_fixed This patch changes the query() function so that it keeps track of errors_found and errors_corrected. This enforces a consistent count of errors found and corrected so that the return code from fsck.gfs2 is correct and future code changes that require calls to query don't have to code it. It also makes the calls a tiny bit faster because they no longer have to pass the opt variable. rhbz#455300 --- gfs2/fsck/fs_recovery.c | 12 +++--- gfs2/fsck/fsck.h | 4 ++- gfs2/fsck/main.c | 5 +-- gfs2/fsck/metawalk.c | 34 +++++-------------- gfs2/fsck/pass1.c | 34 +++++-------------- gfs2/fsck/pass1b.c | 19 ++++------- gfs2/fsck/pass1c.c | 9 +---- gfs2/fsck/pass2.c | 80 +++++++++++++--------------------------------- gfs2/fsck/pass3.c | 23 +++++--------- gfs2/fsck/pass4.c | 24 +++++--------- gfs2/fsck/pass5.c | 22 +++++-------- gfs2/fsck/rgrepair.c | 9 +---- gfs2/fsck/util.c | 61 +++++++++++++++++++++++++++++++++++ gfs2/libgfs2/gfs2_log.c | 2 +- gfs2/libgfs2/libgfs2.h | 1 + 15 files changed, 149 insertions(+), 190 deletions(-) diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 9eff8ec..95c0681 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -447,9 +447,9 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen, "without -a or -p.\n")); goto out; } - if (!query(&opts, _("\nJournal #%d (\"journal%d\") is " - "corrupt. Okay to repair it? (y/n)"), - j+1, j)) { + if (!query( _("\nJournal #%d (\"journal%d\") is " + "corrupt. Okay to repair it? (y/n)"), + j+1, j)) { log_err( _("jid=%u: The journal was not repaired.\n"), j); goto out; @@ -492,8 +492,8 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen, error = FSCK_ERROR; goto out; } - if (query(&opts, _("\nJournal #%d (\"journal%d\") is dirty. Okay to " - "replay it? (y/n)"), j+1, j)) { + if (query( _("\nJournal #%d (\"journal%d\") is dirty. Okay to " + "replay it? (y/n)"), j+1, j)) { log_info( _("jid=%u: Replaying journal...\n"), j); sd_found_jblocks = sd_replayed_jblocks = 0; @@ -517,7 +517,7 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen, log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"), j, sd_replayed_metablocks, sd_found_metablocks); } else { - if (query(&opts, _("Do you want to clear the dirty journal instead? (y/n)"))) { + if (query( _("Do you want to clear the dirty journal instead? (y/n)"))) { write_journal(sdp, sdp->md.journal[j], j, sdp->md.journal[j]->i_di.di_size / sdp->sd_sb.sb_bsize); diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index 840a526..bf3b74c 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -7,7 +7,7 @@ #define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) #define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) -#define query(opts, fmt, args...) gfs2_query(&fsck_abort, opts, fmt, ##args) +#define query(fmt, args...) fsck_query(fmt, ##args) /* * Exit codes used by fsck-type programs @@ -75,6 +75,8 @@ int pass3(struct gfs2_sbd *sbp); int pass4(struct gfs2_sbd *sbp); int pass5(struct gfs2_sbd *sbp); int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count); +int fsck_query(const char *format, ...) + __attribute__((format(printf,1,2))); /* FIXME: Hack to get this going for pass2 - this should be pulled out * of pass1 and put somewhere else... */ diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 82655d8..91396d3 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -189,10 +189,7 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename, * system inodes before we can do any of that. */ if(!sysinode || ds.q.block_type != mark) { log_err( _("Invalid or missing %s system inode.\n"), filename); - errors_found++; - if (query(&opts, _("Create new %s system inode? (y/n) "), - filename)) { - errors_corrected++; + if (query(_("Create new %s system inode? (y/n) "), filename)) { builder(sysinode->i_sbd); gfs2_block_set(sysinode->i_sbd, bl, sysinode->i_di.di_num.no_addr, diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index 43dd766..b9448b5 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -229,8 +229,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, (*count) + 1, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if (query(&opts, _("Attempt to repair it? (y/n) "))) { + if (query( _("Attempt to repair it? (y/n) "))) { if (dirent_repair(ip, bh, &de, dent, type, first)) { if (first) /* make a new sentinel */ @@ -245,7 +244,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, } else { log_err( _("Corrupt directory entry " "repaired.\n")); - errors_corrected++; bmodified(bh); /* keep looping through dentries */ } @@ -269,8 +267,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, (unsigned long long)bh->b_blocknr, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - if (query(&opts, - _("Attempt to remove it? (y/n) "))) { + if (query(_("Attempt to remove it? (y/n) "))) { dirblk_truncate(ip, prev, bh); log_err(_("The corrupt directory " "entry was removed.\n")); @@ -336,10 +333,8 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no, (unsigned long long)*leaf_no, (unsigned long long)*leaf_no, msg); } - errors_found++; if (*leaf_no == *bad_leaf || - query(&opts, _("Attempt to patch around it? (y/n) "))) { - errors_corrected++; + query( _("Attempt to patch around it? (y/n) "))) { if (gfs2_check_range(ip->i_sbd, old_leaf) == 0) gfs2_put_leaf_nr(ip, pindex, old_leaf); else @@ -417,11 +412,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) (unsigned long long)old_leaf, (unsigned long long)old_leaf, ref_count, exp_count); - errors_found++; - if (query(&opts, _("Attempt to fix it? (y/n) "))) { + if (query( _("Attempt to fix it? (y/n) "))) { int factor = 0, divisor = ref_count; - errors_corrected++; lbh = bread(&sbp->buf_list, old_leaf); while (divisor > 1) { factor++; @@ -542,9 +535,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) (unsigned long long) ip->i_di.di_num.no_addr, leaf.lf_entries, count); - errors_found++; - if(query(&opts, _("Update leaf entry count? (y/n) "))) { - errors_corrected++; + if(query( _("Update leaf entry count? (y/n) "))) { leaf.lf_entries = count; gfs2_leaf_out(&leaf, lbh->b_data); log_warn( _("Leaf entry count updated\n")); @@ -620,11 +611,8 @@ static int check_eattr_entries(struct gfs2_inode *ip, bh, ea_hdr, ea_hdr_prev, pass->private)) { - errors_found++; - if (query(&opts, _("Repair the bad " - "Extended Attribute? " - "(y/n) "))) { - errors_corrected++; + if (query( _("Repair the bad Extended " + "Attribute? (y/n) "))) { ea_hdr->ea_num_ptrs = i; ea_hdr->ea_data_len = cpu_to_be32(tot_ealen); @@ -740,13 +728,9 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, error = check_leaf_eattr(ip, block, indirect, pass); if (error) { leaf_pointer_errors++; - errors_found++; - if (query(&opts, _("Fix the indirect " - "block too? (y/n) "))) { - bmodified(indirect_buf); - errors_corrected++; + if (query( _("Fix the indirect " + "block too? (y/n) "))) *ea_leaf_ptr = 0; - } } /* If the first eattr lead is bad, we can't have a hole, so we have to treat this as an unrecoverable diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 7b0651b..a64bf3c 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -205,12 +205,10 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private) const char *allocdesc[] = {"free space", "data", "unlinked", "metadata", "reserved"}; - errors_found++; log_err( _("Block %llu (0x%llx) seems to be data, but is " "marked as %s.\n"), (unsigned long long)block, (unsigned long long)block, allocdesc[btype]); - if(query(&opts, _("Okay to mark it as 'data'? (y/n)"))) { - errors_corrected++; + if(query( _("Okay to mark it as 'data'? (y/n)"))) { gfs2_set_bitmap(ip->i_sbd, block, GFS2_BLKST_USED); log_err( _("The block was reassigned as data.\n")); } else { @@ -244,12 +242,10 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip, log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute " "errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if (query(&opts, _("Clear all Extended Attributes from the " - "inode? (y/n) "))) { + if (query( _("Clear all Extended Attributes from the " + "inode? (y/n) "))) { struct gfs2_block_query q; - errors_corrected++; if(gfs2_block_check(ip->i_sbd, bl, ip->i_di.di_eattr, &q)) { stack; return -1; @@ -284,9 +280,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, (unsigned long long)ip->i_di.di_num.no_addr, emsg); log_err( _(" at block #%lld (0x%llx).\n"), (unsigned long long)block, (unsigned long long)block); - errors_found++; - if (query(&opts, _("Clear the bad Extended Attribute? (y/n) "))) { - errors_corrected++; + if (query( _("Clear the bad Extended Attribute? (y/n) "))) { if (block == ip->i_di.di_eattr) { remove_inode_eattr(ip, bc, duplicate); log_err( _("The bad extended attribute was " @@ -391,10 +385,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, "Extended Attribute errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if (query(&opts, _("Okay to fix the block count for the inode? " - "(y/n) "))) { - errors_corrected++; + if (query( _("Okay to fix the block count for the inode? (y/n) "))) { ip->i_di.di_blocks = 1 + bc->indir_count + bc->data_count + bc->ea_count; bmodified(ip->i_bh); @@ -683,11 +674,9 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, (unsigned long long)block, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if(query(&opts, _("Fix address in inode at block #%" - PRIu64 " (0x%" PRIx64 ")? (y/n) "), + if(query( _("Fix address in inode at block #%" + PRIu64 " (0x%" PRIx64 ")? (y/n) "), block, block)) { - errors_corrected++; ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block; gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); bmodified(ip->i_bh); @@ -864,9 +853,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, (unsigned long long)bc.indir_count, (unsigned long long)bc.data_count, (unsigned long long)bc.ea_count); - errors_found++; - if (query(&opts, _("Fix ondisk block count? (y/n) "))) { - errors_corrected++; + if (query( _("Fix ondisk block count? (y/n) "))) { ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count + bc.ea_count; bmodified(ip->i_bh); @@ -886,8 +873,6 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, uint64_t block) { if (gfs2_check_meta(bh, 0)) { - errors_found++; - log_info( _("Found invalid metadata at #%llu (0x%llx)\n"), (unsigned long long)block, (unsigned long long)block); @@ -895,8 +880,7 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, stack; return -1; } - if(query(&opts, _("Okay to free the invalid block? (y/n)"))) { - errors_corrected++; + if(query( _("Okay to free the invalid block? (y/n)"))) { gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); log_err( _("The invalid block was freed.\n")); } else { diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 04b4226..97f29a2 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -415,9 +415,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) (unsigned long long)id->block_no, (unsigned long long)b->block_no, (unsigned long long)b->block_no); - errors_found++; - if (query(&opts, _("Clear the inode? (y/n) "))) { - errors_corrected++; + if (query( _("Clear the inode? (y/n) "))) { log_warn( _("Clearing inode %lld (0x%llx)...\n"), (unsigned long long)id->block_no, (unsigned long long)id->block_no); @@ -455,18 +453,15 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) } osi_list_foreach(tmp, &b->ref_inode_list) { id = osi_list_entry(tmp, struct inode_with_dups, list); - errors_found++; - if (!(query(&opts, _("Okay to clear inode %lld (0x%llx)? " - "(y/n) "), - (unsigned long long)id->block_no, - (unsigned long long)id->block_no))) { + if (!(query( _("Okay to clear inode %lld (0x%llx)? (y/n) "), + (unsigned long long)id->block_no, + (unsigned long long)id->block_no))) { log_warn( _("The bad inode was not cleared...\n")); continue; } - errors_corrected++; - log_warn( _("Clearing inode %lld (0x%llx)...\n"), - (unsigned long long)id->block_no, - (unsigned long long)id->block_no); + log_warn( _("Clearing inode %lld (0x%llx)...\n"), + (unsigned long long)id->block_no, + (unsigned long long)id->block_no); ip = fsck_load_inode(sbp, id->block_no); dh.b = b; dh.id = id; diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index 6d06d83..9bb7b4a 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -37,10 +37,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp, struct gfs2_ea_header *prev, int fix_curr, int fix_curr_len) { - errors_found++; - if (query(&opts, _("Remove the bad Extended Attribute entry? " - "(y/n) "))) { - errors_corrected++; + if (query( _("Remove the bad Extended Attribute entry? (y/n) "))) { if (fix_curr) curr->ea_flags |= GFS2_EAFLAG_LAST; if (fix_curr_len) { @@ -61,9 +58,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp, static int ask_remove_eattr(struct gfs2_inode *ip) { - errors_found++; - if (query(&opts, _("Remove the bad Extended Attribute? (y/n) "))) { - errors_corrected++; + if (query( _("Remove the bad Extended Attribute? (y/n) "))) { ip->i_di.di_eattr = 0; bmodified(ip->i_bh); log_err( _("Bad Extended Attribute removed.\n")); diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index 0a3f63d..f7ad911 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -200,10 +200,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, log_err( _("\tName length found = %u\n" "\tHash expected = %u (0x%x)\n"), de->de_name_len, calculated_hash, calculated_hash); - errors_found++; - if(query(&opts, _("Fix directory hash for %s? (y/n) "), - filename)) { - errors_corrected++; + if(query( _("Fix directory hash for %s? (y/n) "), + filename)) { de->de_hash = calculated_hash; gfs2_dirent_out(de, (char *)dent); log_err( _("Directory entry hash for %s fixed.\n"), filename); @@ -224,10 +222,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(gfs2_check_range(ip->i_sbd, entryblock)) { log_err( _("Block # referenced by directory entry %s is out of range\n"), tmp_name); - errors_found++; - if(query(&opts, - _("Clear directory entry tp out of range block? (y/n) "))) { - errors_corrected++; + if(query( _("Clear directory entry tp out of range block? (y/n) "))) { log_err( _("Clearing %s\n"), tmp_name); dirent2_del(ip, bh, prev_de, dent); bmodified(bh); @@ -250,9 +245,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, /* Handle bad blocks */ log_err( _("Found a bad directory entry: %s\n"), filename); - errors_found++; - if(query(&opts, _("Delete inode containing bad blocks? (y/n)"))) { - errors_corrected++; + if(query( _("Delete inode containing bad blocks? (y/n)"))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &pass2_fxns_delete); check_metatree(entry_ip, &pass2_fxns_delete); @@ -288,12 +281,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, _("previously marked invalid") : _("is not an inode")); - errors_found++; - if(query(&opts, _("Clear directory entry to non-inode block? " - "(y/n) "))) { + if(query( _("Clear directory entry to non-inode block? " + "(y/n) "))) { struct gfs2_buffer_head *bhi; - errors_corrected++; dirent2_del(ip, bh, prev_de, dent); bmodified(bh); log_warn( _("Directory entry '%s' cleared\n"), tmp_name); @@ -340,9 +331,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, (unsigned long long)de->de_inum.no_addr, (unsigned long long)de->de_inum.no_addr, block_type_string(&q)); - errors_found++; - if(query(&opts, _("Clear stale directory entry? (y/n) "))) { - errors_corrected++; + if(query( _("Clear stale directory entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); fsck_inode_put(entry_ip); @@ -367,10 +356,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, " (0x%llx)\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if(query(&opts, _("Clear duplicate '.' entry? (y/n) "))) { - - errors_corrected++; + if(query( _("Clear duplicate '.' entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); fsck_inode_put(entry_ip); @@ -405,9 +391,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, (unsigned long long)de->de_inum.no_addr, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if(query(&opts, _("Remove '.' reference? (y/n) "))) { - errors_corrected++; + if(query( _("Remove '.' reference? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); fsck_inode_put(entry_ip); @@ -441,10 +425,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, "(0x%llx)\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if(query(&opts, _("Clear duplicate '..' entry? (y/n) "))) { + if(query( _("Clear duplicate '..' entry? (y/n) "))) { - errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); fsck_inode_put(entry_ip); @@ -469,9 +451,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, "pointing to something that's not a directory"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if(query(&opts, _("Clear bad '..' directory entry? (y/n) "))) { - errors_corrected++; + if(query( _("Clear bad '..' directory entry? (y/n) "))) { entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); check_inode_eattr(entry_ip, &clear_eattrs); fsck_inode_put(entry_ip); @@ -521,9 +501,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64 ") detected.\n"), filename, entryblock, entryblock); - errors_found++; - if(query(&opts, _("Clear hard link to directory? (y/n) "))) { - errors_corrected++; + if(query( _("Clear hard link to directory? (y/n) "))) { bmodified(bh); dirent2_del(ip, bh, prev_de, dent); log_warn( _("Directory entry %s cleared\n"), filename); @@ -603,9 +581,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, } if(!ds.dotdir) { log_err( _("No '.' entry found for %s directory.\n"), dirname); - errors_found++; - if (query(&opts, _("Is it okay to add '.' entry? (y/n) "))) { - errors_corrected++; + if (query( _("Is it okay to add '.' entry? (y/n) "))) { sprintf(tmp_name, "."); filename_len = strlen(tmp_name); /* no trailing NULL */ if(!(filename = malloc(sizeof(char) * filename_len))) { @@ -637,12 +613,10 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, (unsigned long long)sysinode->i_di.di_num.no_addr, (unsigned long long)sysinode->i_di.di_num.no_addr, sysinode->i_di.di_entries, ds.entry_count); - errors_found++; - if(query(&opts, _("Fix entries for %s inode %llu (0x%llx" - ")? (y/n) "), dirname, - (unsigned long long)sysinode->i_di.di_num.no_addr, - (unsigned long long)sysinode->i_di.di_num.no_addr)) { - errors_corrected++; + if(query( _("Fix entries for %s inode %llu (0x%llx)? (y/n) "), + dirname, + (unsigned long long)sysinode->i_di.di_num.no_addr, + (unsigned long long)sysinode->i_di.di_num.no_addr)) { sysinode->i_di.di_entries = ds.entry_count; bmodified(sysinode->i_bh); log_warn( _("Entries updated\n")); @@ -766,12 +740,10 @@ int pass2(struct gfs2_sbd *sbp) } if(error == 0) { /* FIXME: factor */ - errors_found++; - if(query(&opts, _("Remove directory entry for bad" - " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64 - " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent, - di->treewalk_parent)) { - errors_corrected++; + if(query( _("Remove directory entry for bad" + " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64 + " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent, + di->treewalk_parent)) { error = remove_dentry_from_dir(sbp, di->treewalk_parent, i); if(error < 0) { @@ -796,10 +768,7 @@ int pass2(struct gfs2_sbd *sbp) log_err(_("No '.' entry found for directory inode at " "block %"PRIu64" (0x%" PRIx64 ")\n"), i, i); - errors_found++; - if (query(&opts, - _("Is it okay to add '.' entry? (y/n) "))) { - errors_corrected++; + if (query( _("Is it okay to add '.' entry? (y/n) "))) { sprintf(tmp_name, "."); filename_len = strlen(tmp_name); /* no trailing NULL */ @@ -836,10 +805,7 @@ int pass2(struct gfs2_sbd *sbp) ip->i_di.di_entries, ds.entry_count, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - errors_found++; - if (query(&opts, - _("Fix the entry count? (y/n) "))) { - errors_corrected++; + if (query( _("Fix the entry count? (y/n) "))) { ip->i_di.di_entries = ds.entry_count; bmodified(ip->i_bh); } else { diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c index 14c25a7..16fa086 100644 --- a/gfs2/fsck/pass3.c +++ b/gfs2/fsck/pass3.c @@ -118,12 +118,10 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp, /* FIXME: add a dinode for this entry instead? */ - errors_found++; - if(query(&opts, _("Remove directory entry for bad" - " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64 - " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode, - di->treewalk_parent, di->treewalk_parent)) { - errors_corrected++; + if(query( _("Remove directory entry for bad" + " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64 + " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode, + di->treewalk_parent, di->treewalk_parent)) { error = remove_dentry_from_dir(sbp, di->treewalk_parent, di->dinode); if(error < 0) { @@ -221,10 +219,8 @@ int pass3(struct gfs2_sbd *sbp) } if(q.block_type == gfs2_bad_block) { log_err( _("Found unlinked directory containing bad block\n")); - errors_found++; - if(query(&opts, + if(query( _("Clear unlinked directory with bad blocks? (y/n) "))) { - errors_corrected++; gfs2_block_set(sbp, bl, di->dinode, gfs2_block_free); @@ -253,9 +249,7 @@ int pass3(struct gfs2_sbd *sbp) * with eattrs */ if(!ip->i_di.di_size && !ip->i_di.di_eattr){ log_err( _("Unlinked directory has zero size.\n")); - errors_found++; - if(query(&opts, _("Remove zero-size unlinked directory? (y/n) "))) { - errors_corrected++; + if(query( _("Remove zero-size unlinked directory? (y/n) "))) { gfs2_block_set(sbp, bl, di->dinode, gfs2_block_free); @@ -265,9 +259,8 @@ int pass3(struct gfs2_sbd *sbp) log_err( _("Zero-size unlinked directory remains\n")); } } - errors_found++; - if(query(&opts, _("Add unlinked directory to lost+found? (y/n) "))) { - errors_corrected++; + if(query( _("Add unlinked directory to " + "lost+found? (y/n) "))) { if(add_inode_to_lf(ip)) { fsck_inode_put(ip); stack; diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c index 503d297..1ab18ea 100644 --- a/gfs2/fsck/pass4.c +++ b/gfs2/fsck/pass4.c @@ -68,10 +68,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { "bad blocks\n"), (unsigned long long)ii->inode, (unsigned long long)ii->inode); - errors_found++; - if(query(&opts, - _("Delete unlinked inode with bad blocks? (y/n) "))) { - errors_corrected++; + if(query( _("Delete unlinked inode with bad " + "blocks? (y/n) "))) { ip = fsck_load_inode(sbp, ii->inode); check_inode_eattr(ip, &pass4_fxns_delete); @@ -95,8 +93,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { "not an inode (%d)\n"), q.block_type); ip = fsck_load_inode(sbp, ii->inode); - if(query(&opts, _("Delete unlinked inode " - "? (y/n) "))) { + if(query(_("Delete unlinked inode? (y/n) "))) { check_inode_eattr(ip, &pass4_fxns_delete); check_metatree(ip, &pass4_fxns_delete); @@ -118,9 +115,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { * them. */ if(!ip->i_di.di_size && !ip->i_di.di_eattr){ log_err( _("Unlinked inode has zero size\n")); - errors_found++; - if(query(&opts, _("Clear zero-size unlinked inode? (y/n) "))) { - errors_corrected++; + if(query( _("Clear zero-size unlinked inode? (y/n) "))) { gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); fsck_inode_put(ip); @@ -128,9 +123,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { } } - errors_found++; - if(query(&opts, _("Add unlinked inode to lost+found? (y/n)"))) { - errors_corrected++; + if(query( _("Add unlinked inode to lost+found? (y/n)"))) { bmodified(ip->i_bh); if(add_inode_to_lf(ip)) { stack; @@ -151,10 +144,9 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { ii->inode, ii->link_count, ii->counted_links); /* Read in the inode, adjust the link count, * and write it back out */ - errors_found++; - if(query(&opts, _("Update link count for inode %" - PRIu64 " (0x%" PRIx64 ") ? (y/n) "), ii->inode, ii->inode)) { - errors_corrected++; + if(query( _("Update link count for inode %" PRIu64 + " (0x%" PRIx64 ") ? (y/n) "), + ii->inode, ii->inode)) { ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */ fix_inode_count(sbp, ii, ip); bmodified(ip->i_bh); diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index 0479301..495ad0a 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -81,15 +81,14 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b So we ignore it. */ if (rg_status == GFS2_BLKST_UNLINKED && block_status == GFS2_BLKST_FREE) { - errors_found++; if (free_unlinked == -1) { log_err( _("Unlinked inode block found at " "block %llu (0x%llx).\n"), (unsigned long long)block, (unsigned long long)block); - if(query(&opts, _("Do you want me to fix the " - "bitmap for all unlinked " - "blocks? (y/n) "))) + if(query( _("Do you want me to fix the " + "bitmap for all unlinked " + "blocks? (y/n) "))) free_unlinked = 1; else free_unlinked = 0; @@ -101,13 +100,11 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b "\n"), (unsigned long long)block, (unsigned long long)block); - else { + else log_err(_("Unlinked block %llu " "(0x%llx) bitmap fixed.\n"), (unsigned long long)block, (unsigned long long)block); - errors_corrected++; - } } else { log_info( _("Unlinked block found at block %" PRIu64" (0x%" PRIx64 "), left " @@ -125,10 +122,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b log_err( _("Metadata type is %u (%s)\n"), q.block_type, block_type_string(&q)); - errors_found++; - if(query(&opts, _("Fix bitmap for block %" - PRIu64" (0x%" PRIx64 ") ? (y/n) "), block, block)) { - errors_corrected++; + if(query( _("Fix bitmap for block %" PRIu64 + " (0x%" PRIx64 ") ? (y/n) "), + block, block)) { if(gfs2_set_bitmap(sbp, block, block_status)) log_err( _("Failed.\n")); else @@ -191,9 +187,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, exit(FSCK_ERROR); } if(update) { - errors_found++; - if(query(&opts, _("Update resource group counts? (y/n) "))) { - errors_corrected++; + if(query( _("Update resource group counts? (y/n) "))) { log_warn( _("Resource group counts updated\n")); /* write out the rgrp */ gfs2_rgrp_out(rg, rgbh[0]->b_data); diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 169cf19..3ce0f95 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -383,10 +383,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd, " GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"), rgbh[x]->b_blocknr, rgbh[x]->b_blocknr, (int)x+1, (int)rgd->ri.ri_length); - errors_found++; - if (query(&opts, "Fix the RG? (y/n)")) { - - errors_corrected++; + if (query( _("Fix the RG? (y/n)"))) { log_err( _("Attempting to repair the RG.\n")); rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x); if (x) { @@ -518,9 +515,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) ri_compare(rg, actual->ri, expected->ri, ri_bitbytes, PRIx32); /* If we modified the index, write it back to disk. */ if (rindex_modified) { - errors_found++; - if (query(&opts, _("Fix the index? (y/n)"))) { - errors_corrected++; + if (query( _("Fix the index? (y/n)"))) { gfs2_rindex_out(&expected->ri, (char *)&buf); gfs2_writei(sdp->md.riinode, (char *)&buf, rg * sizeof(struct gfs2_rindex), diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c index 7cdcdc9..3159720 100644 --- a/gfs2/fsck/util.c +++ b/gfs2/fsck/util.c @@ -72,6 +72,7 @@ void warm_fuzzy_stuff(uint64_t block) if (last_fs_block) { percent = (block * 100) / last_fs_block; log_notice( _("\r%" PRIu64 " percent complete.\r"), percent); + fflush(stdout); } } } @@ -88,3 +89,63 @@ const char *block_type_string(struct gfs2_block_query *q) return (blktyp[q->block_type]); return blktyp[15]; } + +/* fsck_query: Same as gfs2_query except it adjusts errors_found and + errors_corrected. */ +int fsck_query(const char *format, ...) +{ + va_list args; + const char *transform; + char response; + int ret = 0; + + errors_found++; + fsck_abort = 0; + if(opts.yes) { + errors_corrected++; + return 1; + } + if(opts.no) + return 0; + + opts.query = TRUE; + while (1) { + va_start(args, format); + transform = _(format); + vprintf(transform, args); + va_end(args); + + /* Make sure query is printed out */ + fflush(NULL); + response = gfs2_getch(); + + printf("\n"); + fflush(NULL); + if (response == 0x3) { /* if interrupted, by ctrl-c */ + response = generic_interrupt("Question", "response", + NULL, + "Do you want to abort " \ + "or continue (a/c)?", + "ac"); + if (response == 'a') { + ret = 0; + fsck_abort = 1; + break; + } + printf("Continuing.\n"); + } else if(tolower(response) == 'y') { + errors_corrected++; + ret = 1; + break; + } else if (tolower(response) == 'n') { + ret = 0; + break; + } else { + printf("Bad response %d, please type 'y' or 'n'.\n", + response); + } + } + + opts.query = FALSE; + return ret; +} diff --git a/gfs2/libgfs2/gfs2_log.c b/gfs2/libgfs2/gfs2_log.c index 41f4faa..907c5f7 100644 --- a/gfs2/libgfs2/gfs2_log.c +++ b/gfs2/libgfs2/gfs2_log.c @@ -72,7 +72,7 @@ void print_fsck_log(int iif, int priority, const char *file, int line, va_end(args); } -static char gfs2_getch(void) +char gfs2_getch(void) { struct termios termattr, savetermattr; char ch; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 0428481..1f10027 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -586,6 +586,7 @@ do { print_log(1, MSG_ERROR, format); } while(0) #define log_at_crit(format...) \ do { print_log(1, MSG_CRITICAL, format); } while(0) +extern char gfs2_getch(void); extern void increase_verbosity(void); extern void decrease_verbosity(void); extern void print_fsck_log(int iif, int priority, const char *file, int line,
1
0
0
0
cluster: STABLE3 - fsck.gfs2: give comfort when processing lots of data blocks
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=98…
Commit: 98c92b66e11138e325165cb5e42d21abfc76e8f9 Parent: 1b47697dc8905507cd7ad50fd249ca6c86942b82 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Mon Nov 30 16:03:10 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 fsck.gfs2: give comfort when processing lots of data blocks When fsck.gfs2 is running, it can seem to silently hang when it is processing a large number of data blocks. This is noticeable when files get over 20GB in size. This patch periodically prints status messages when big files are being checked so customers know it's still doing something valid. rhbz#455300 --- gfs2/fsck/fsck.h | 1 + gfs2/fsck/main.c | 1 + gfs2/fsck/metawalk.c | 17 +++++++++++++++++ gfs2/fsck/util.c | 39 +++++++++++++++++++++++++++++++++++++++ gfs2/fsck/util.h | 1 + 5 files changed, 59 insertions(+), 0 deletions(-) diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index 9c9a3fe..840a526 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -86,6 +86,7 @@ extern osi_list_t dir_hash[FSCK_HASH_SIZE]; extern osi_list_t inode_hash[FSCK_HASH_SIZE]; extern struct gfs2_bmap *bl; extern uint64_t last_fs_block, last_reported_block; +extern int64_t last_reported_fblock; extern int skip_this_pass, fsck_abort; extern int errors_found, errors_corrected; extern uint64_t last_data_block; diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 1ef2cba..82655d8 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -22,6 +22,7 @@ osi_list_t dir_hash[FSCK_HASH_SIZE]; osi_list_t inode_hash[FSCK_HASH_SIZE]; struct gfs2_bmap *bl = NULL; uint64_t last_fs_block, last_reported_block = -1; +int64_t last_reported_fblock = -1000000; int skip_this_pass = FALSE, fsck_abort = FALSE; int errors_found = 0, errors_corrected = 0; const char *pass = ""; diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index 42235be..43dd766 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -14,6 +14,8 @@ #include "metawalk.h" #include "hash.h" +#define COMFORTABLE_BLKS 5242880 /* 20GB in 4K blocks */ + static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block) { @@ -937,6 +939,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) uint64_t block, *ptr; uint32_t height = ip->i_di.di_height; int i, head_size; + uint64_t blks_checked = 0; int error = 0; if (!height) @@ -960,6 +963,8 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) /* check data blocks */ list = &metalist[height - 1]; + if (ip->i_di.di_blocks > COMFORTABLE_BLKS) + last_reported_fblock = -10000000; for (tmp = list->next; tmp != list; tmp = tmp->next) { bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_altlist); @@ -988,9 +993,21 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) stack; return -1; } + blks_checked++; + if (ip->i_di.di_blocks > COMFORTABLE_BLKS) + big_file_comfort(ip, blks_checked); } } + if (ip->i_di.di_blocks > COMFORTABLE_BLKS) { + log_notice( _("\rLarge file at %lld (0x%llx) - 100 percent " + "complete. " + "\n"), + (unsigned long long)ip->i_di.di_num.no_addr, + (unsigned long long)ip->i_di.di_num.no_addr); + fflush(stdout); + } + /* free metalists */ for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) { diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c index eac0e1b..7cdcdc9 100644 --- a/gfs2/fsck/util.c +++ b/gfs2/fsck/util.c @@ -5,12 +5,51 @@ #include <sys/time.h> #include <stdio.h> #include <libintl.h> +#include <ctype.h> #define _(String) gettext(String) #include "libgfs2.h" #include "fs_bits.h" #include "util.h" +void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked) +{ + static struct timeval tv; + static uint32_t seconds = 0; + static uint64_t percent, fsize, chksize; + uint64_t one_percent = 0; + int i, cs; + const char *human_abbrev = " KMGTPE"; + + one_percent = ip->i_di.di_blocks / 100; + if (blks_checked - last_reported_fblock < one_percent) + return; + + last_reported_block = blks_checked; + gettimeofday(&tv, NULL); + if (!seconds) + seconds = tv.tv_sec; + if (tv.tv_sec == seconds) + return; + + fsize = ip->i_di.di_size; + for (i = 0; i < 6 && fsize > 1024; i++) + fsize /= 1024; + chksize = blks_checked * ip->i_sbd->bsize; + for (cs = 0; cs < 6 && chksize > 1024; cs++) + chksize /= 1024; + seconds = tv.tv_sec; + percent = (blks_checked * 100) / ip->i_di.di_blocks; + log_notice( _("\rChecking %lld%c of %lld%c of file at %lld (0x%llx)" + "- %llu percent complete. \r"), + (long long)chksize, human_abbrev[cs], + (unsigned long long)fsize, human_abbrev[i], + (unsigned long long)ip->i_di.di_num.no_addr, + (unsigned long long)ip->i_di.di_num.no_addr, + (unsigned long long)percent); + fflush(stdout); +} + /* Put out a warm, fuzzy message every second so the user */ /* doesn't think we hung. (This may take a long time). */ void warm_fuzzy_stuff(uint64_t block) diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h index f84ab41..fa18506 100644 --- a/gfs2/fsck/util.h +++ b/gfs2/fsck/util.h @@ -7,6 +7,7 @@ ((lseek((fd), (off), SEEK_SET) == (off)) ? 0 : -1) struct di_info *search_list(osi_list_t *list, uint64_t addr); +void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked); void warm_fuzzy_stuff(uint64_t block); const char *block_type_string(struct gfs2_block_query *q);
1
0
0
0
cluster: STABLE3 - gfs2: remove update_flags everywhere
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=1b…
Commit: 1b47697dc8905507cd7ad50fd249ca6c86942b82 Parent: 7ea0206f2410a56993f6019b9065db95d15a9396 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Mon Nov 30 15:16:07 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 gfs2: remove update_flags everywhere This patch removes the update_flags from all the gfs2-utils code. This help to untangle the buffer_head mess and helps solve issues where file systems were being updated even when no errors are found. rhbz#455300 --- gfs2/convert/gfs2_convert.c | 47 ++++++++------ gfs2/edit/gfs2hex.c | 2 +- gfs2/edit/hexedit.c | 47 +++++++------ gfs2/edit/savemeta.c | 18 +++--- gfs2/fsck/eattr.c | 10 +-- gfs2/fsck/eattr.h | 9 +-- gfs2/fsck/fs_recovery.c | 56 +++++++++------- gfs2/fsck/fsck.h | 2 +- gfs2/fsck/main.c | 22 +++---- gfs2/fsck/metawalk.c | 152 ++++++++++++++++--------------------------- gfs2/fsck/metawalk.h | 19 ++---- gfs2/fsck/pass1.c | 129 +++++++++++++++++-------------------- gfs2/fsck/pass1b.c | 37 ++++------- gfs2/fsck/pass1c.c | 34 ++++------ gfs2/fsck/pass2.c | 95 ++++++++++++--------------- gfs2/fsck/pass3.c | 23 ++++--- gfs2/fsck/pass4.c | 25 ++++---- gfs2/fsck/pass5.c | 16 ++--- gfs2/fsck/rgrepair.c | 16 ++-- gfs2/libgfs2/buf.c | 9 ++- gfs2/libgfs2/fs_bits.c | 8 +- gfs2/libgfs2/fs_geometry.c | 3 +- gfs2/libgfs2/fs_ops.c | 117 ++++++++++++++++++++------------- gfs2/libgfs2/gfs1.c | 11 +-- gfs2/libgfs2/libgfs2.h | 26 ++------ gfs2/libgfs2/recovery.c | 10 ++-- gfs2/libgfs2/rgrp.c | 7 +- gfs2/libgfs2/structures.c | 47 +++++++++----- gfs2/libgfs2/super.c | 10 +-- gfs2/mkfs/main_grow.c | 4 +- gfs2/mkfs/main_mkfs.c | 12 ++- 31 files changed, 488 insertions(+), 535 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 020b4e5..49e6058 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -335,7 +335,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, /* First, build up the metatree */ for (h = 0; h < blk->height; h++) { lookup_block(ip, bh, h, &blk->mp, 1, &new, &block); - brelse(bh, updated); + brelse(bh); if (!block) break; @@ -353,7 +353,8 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, memcpy(bh->b_data + hdrsize + ptramt, (char *)srcptr, amount); srcptr += amount; - brelse(bh, updated); + bmodified(bh); + brelse(bh); copied += amount; @@ -516,7 +517,8 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head /* Zero the buffer so we can fill it in later */ memset(bh->b_data + sizeof(struct gfs_indirect), 0, bufsize); - brelse(bh, updated); + bmodified(bh); + brelse(bh); /* Free the metadata block so we can reuse it. This allows us to convert a "full" file system. */ ip->i_di.di_blocks--; @@ -778,12 +780,13 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr) break; } bitmap_byte -= (sbp->bsize - buf_offset); + bmodified(bh); } } - brelse(bh, updated); + brelse(bh); first = 0; } /* while 1 */ - gfs2_rgrp_relse(rgd, updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); } /* for all rgs */ log_notice("\r%" PRIu64" inodes from %d rgs converted.", @@ -805,7 +808,8 @@ static int fetch_inum(struct gfs2_sbd *sbp, uint64_t iblock, fix_inode = inode_get(sbp, bh_fix); inum->no_formal_ino = fix_inode->i_di.di_num.no_formal_ino; inum->no_addr = fix_inode->i_di.di_num.no_addr; - brelse(bh_fix, updated); + bmodified(bh_fix); + brelse(bh_fix); return 0; }/* fetch_inum */ @@ -944,7 +948,8 @@ static int fix_one_directory_exhash(struct gfs2_sbd *sbp, struct gfs2_inode *dip } gfs2_leaf_in(&leaf, (char *)bh_leaf->b_data); /* buffer to structure */ error = process_dirent_info(dip, sbp, bh_leaf, leaf.lf_entries); - brelse(bh_leaf, updated); + bmodified(bh_leaf); + brelse(bh_leaf); } /* for leaf_num */ return 0; }/* fix_one_directory_exhash */ @@ -987,18 +992,21 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix) if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { if (fix_one_directory_exhash(sbp, dip)) { log_crit("Error fixing exhash directory.\n"); - brelse(bh_dir, updated); + bmodified(bh_dir); + brelse(bh_dir); return -1; } } else { if (process_dirent_info(dip, sbp, bh_dir, dip->i_di.di_entries)) { log_crit("Error fixing linear directory.\n"); - brelse(bh_dir, updated); + bmodified(bh_dir); + brelse(bh_dir); return -1; } } - brelse(bh_dir, updated); + bmodified(bh_dir); + brelse(bh_dir); } /* Free the last entry in memory: */ if (tmp) { @@ -1126,7 +1134,7 @@ static int init(struct gfs2_sbd *sbp) sbp->sd_diptrs = (sbp->bsize - sizeof(struct gfs_dinode)) / sizeof(uint64_t); sbp->sd_jbsize = sbp->bsize - sizeof(struct gfs2_meta_header); - brelse(bh, not_updated); + brelse(bh); if (compute_heightsize(sbp, sbp->sd_heightsize, &sbp->sd_max_height, sbp->bsize, sbp->sd_diptrs, sbp->sd_inptrs)) { log_crit("Error: Bad constants (1)\n"); @@ -1193,8 +1201,8 @@ static int init(struct gfs2_sbd *sbp) } printf("\n"); fflush(stdout); - inode_put(sbp->md.riinode, updated); - inode_put(sbp->md.jiinode, updated); + inode_put(sbp->md.riinode); + inode_put(sbp->md.jiinode); log_debug("%d rgs found.\n", rgcount); return 0; }/* fill_super_block */ @@ -1508,7 +1516,7 @@ static void conv_build_jindex(struct gfs2_sbd *sdp) ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM); write_journal(sdp, ip, j, sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift); - inode_put(ip, updated); + inode_put(ip); printf("done.\n"); fflush(stdout); } @@ -1518,7 +1526,7 @@ static void conv_build_jindex(struct gfs2_sbd *sdp) gfs2_dinode_print(&jindex->i_di); } - inode_put(jindex, updated); + inode_put(jindex); } /* ------------------------------------------------------------------------- */ @@ -1623,9 +1631,9 @@ int main(int argc, char **argv) update_inode_file(&sb2); write_statfs_file(&sb2); - inode_put(sb2.master_dir, updated); - inode_put(sb2.md.inum, updated); - inode_put(sb2.md.statfs, updated); + inode_put(sb2.master_dir); + inode_put(sb2.md.inum); + inode_put(sb2.md.statfs); bcommit(&sb2.buf_list); /* write the buffers to disk */ @@ -1643,7 +1651,8 @@ int main(int argc, char **argv) sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS; sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI; gfs2_sb_out(&sb2.sd_sb, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); bsync(&sb2.buf_list); /* write the buffers to disk */ error = fsync(sb2.device_fd); diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c index a4ec02c..1d34730 100644 --- a/gfs2/edit/gfs2hex.c +++ b/gfs2/edit/gfs2hex.c @@ -347,7 +347,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf) if (skip <= 0) break; } - brelse(tmp_bh, not_updated); + brelse(tmp_bh); indirect->ii[indirect_blocks].block = last; indirect_blocks++; last = p; diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 6a052b2..933871a 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -782,7 +782,7 @@ static void rgcount(void) { printf("%lld RGs in this file system.\n", (unsigned long long)sbd.md.riinode->i_di.di_size / risize()); - inode_put(sbd.md.riinode, not_updated); + inode_put(sbd.md.riinode); gfs2_rgrp_free(&sbd.rglist); exit(EXIT_SUCCESS); } @@ -881,7 +881,7 @@ static uint64_t get_rg_addr(int rgnum) else fprintf(stderr, "Error: File system only has %lld RGs.\n", (unsigned long long)riinode->i_di.di_size / risize()); - inode_put(riinode, not_updated); + inode_put(riinode); return rgblk; } @@ -916,7 +916,8 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) gfs_rgrp_out(&rg.rg1, bh->b_data); else gfs2_rgrp_out(&rg.rg2, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } else { if (full) { print_gfs2("RG #%d", rgnum); @@ -931,7 +932,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) printf("RG #%d (block %llu / 0x%llx) rg_flags = 0x%08x\n", rgnum, (unsigned long long)rgblk, (unsigned long long)rgblk, rg.rg2.rg_flags); - brelse(bh, not_updated); + brelse(bh); } if (modify) bsync(&sbd.buf_list); @@ -996,7 +997,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex) gfs2_rgrp_in(&rg, tmp_bh->b_data); gfs2_rgrp_print(&rg); } - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } last_entry_onscreen[dmode] = print_entry_ndx; } @@ -1602,7 +1603,7 @@ int block_is_in_per_node(void) gfs2_dinode_in(&per_node_di, per_node_bh->b_data); do_dinode_extended(&per_node_di, per_node_bh->b_data); - brelse(per_node_bh, not_updated); + brelse(per_node_bh); for (d = 0; d < indirect->ii[0].dirents; d++) { if (block == indirect->ii[0].dirent[d].block) @@ -1640,7 +1641,7 @@ static int display_extended(void) tmp_bh = bread(&sbd.buf_list, block); tmp_inode = inode_get(&sbd, tmp_bh); parse_rindex(tmp_inode, TRUE); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } else if (has_indirect_blocks() && !indirect_blocks && !display_leaf(indirect)) @@ -1655,31 +1656,31 @@ static int display_extended(void) tmp_bh = bread(&sbd.buf_list, masterblock("rindex")); tmp_inode = inode_get(&sbd, tmp_bh); parse_rindex(tmp_inode, FALSE); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } else if (block_is_jindex()) { tmp_bh = bread(&sbd.buf_list, block); tmp_inode = inode_get(&sbd, tmp_bh); print_jindex(tmp_inode); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } else if (block_is_inum_file()) { tmp_bh = bread(&sbd.buf_list, block); tmp_inode = inode_get(&sbd, tmp_bh); print_inum(tmp_inode); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } else if (block_is_statfs_file()) { tmp_bh = bread(&sbd.buf_list, block); tmp_inode = inode_get(&sbd, tmp_bh); print_statfs(tmp_inode); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } else if (block_is_quota_file()) { tmp_bh = bread(&sbd.buf_list, block); tmp_inode = inode_get(&sbd, tmp_bh); print_quota(tmp_inode); - brelse(tmp_bh, not_updated); + brelse(tmp_bh); } return 0; } @@ -1968,7 +1969,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) if (!gfs1) do_dinode_extended(&di, jindex_bh->b_data); /* parse dir. */ - brelse(jindex_bh, not_updated); + brelse(jindex_bh); if (gfs1) { struct gfs2_inode *jiinode; @@ -1991,7 +1992,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size) j_inode = inode_get(&sbd, j_bh); gfs2_dinode_in(&jdi, j_bh->b_data);/* parse dinode to struct */ *j_size = jdi.di_size; - brelse(j_bh, not_updated); + brelse(j_bh); } return jblock; } @@ -2017,10 +2018,10 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p bh->b_data[4] == 0x00 && bh->b_data[5] == 0x00 && bh->b_data[6] == 0x00 && bh->b_data[7] == metatype) { found = 1; - brelse(bh, not_updated); + brelse(bh); break; } - brelse(bh, not_updated); + brelse(bh); } if (!found) blk = 0; @@ -2437,7 +2438,7 @@ static void find_print_block_type(void) bh = bread(&sbd.buf_list, tblock); type = get_block_type(bh->b_data); print_block_type(tblock, type, ""); - brelse(bh, NOT_UPDATED); + brelse(bh); gfs2_rgrp_free(&sbd.rglist); exit(0); } @@ -2595,7 +2596,9 @@ static void process_field(const char *field, uint64_t *newval, int print_field) " which is not implemented"); break; } - brelse(bh, newval ? UPDATED : NOT_UPDATED); + if (newval) + bmodified(bh); + brelse(bh); bcommit(&sbd.buf_list); } @@ -2975,7 +2978,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset, amount = sdp->bsize - o; if (!extlen) block_map(ip, lblock, ¬_new, &dblock, &extlen, - FALSE, not_updated); + FALSE); if (dblock) { bh = bread(&sdp->buf_list, dblock); if (*abs_block == 0) @@ -2986,7 +2989,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset, bh = NULL; if (bh) { memcpy(rbuf, bh->b_data + o, amount); - brelse(bh, not_updated); + brelse(bh); } else { memset(rbuf, 0, amount); } @@ -3042,7 +3045,7 @@ static void dump_journal(const char *journal) for (jb = 0; jb < j_size; jb += (gfs1 ? 1:sbd.bsize)) { if (gfs1) { if (j_bh) - brelse(j_bh, not_updated); + brelse(j_bh); j_bh = bread(&sbd.buf_list, jblock + jb); abs_block = jblock + jb; memcpy(jbuf, j_bh->b_data, sbd.bsize); @@ -3133,7 +3136,7 @@ static void dump_journal(const char *journal) start_line); } } - brelse(j_bh, not_updated); + brelse(j_bh); blockhist = -1; /* So we don't print anything else */ } diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 1bdadbe..46a6522 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -307,13 +307,13 @@ static void save_indirect_blocks(int out_fd, osi_list_t *cur_list, if (blktype == GFS2_METATYPE_EA) { nbh = bread(&sbd.buf_list, indir_block); save_ea_block(out_fd, nbh); - brelse(nbh, not_updated); + brelse(nbh); } if (height != hgt) { /* If not at max height */ nbh = bread(&sbd.buf_list, indir_block); osi_list_add_prev(&nbh->b_altlist, cur_list); - brelse(nbh, not_updated); + brelse(nbh); } } /* for all data on the indirect block */ } @@ -416,9 +416,9 @@ static void save_inode_data(int out_fd) (unsigned long long)block, (unsigned long long)block); } - brelse(metabh, not_updated); + brelse(metabh); } - inode_put(inode, not_updated); + inode_put(inode); } static void get_journal_inode_blocks(void) @@ -452,7 +452,7 @@ static void get_journal_inode_blocks(void) amt = gfs2_readi(j_inode, (void *)&jbuf, journal * sizeof(struct gfs_jindex), sizeof(struct gfs_jindex)); - brelse(bh, not_updated); + brelse(bh); if (!amt) break; gfs_jindex_in(&ji, jbuf); @@ -465,7 +465,7 @@ static void get_journal_inode_blocks(void) bh = bread(&sbd.buf_list, jblock); j_inode = inode_get(&sbd, bh); gfs2_dinode_in(&jdi, bh->b_data); - inode_put(j_inode, not_updated); + inode_put(j_inode); } journal_blocks[journals_found++] = jblock; } @@ -497,7 +497,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, blk = gfs2_bitfit((unsigned char *)bh->b_data + bits->bi_offset, bits->bi_len, blk, GFS2_BLKST_UNLINKED); - brelse(bh, not_updated); + brelse(bh); if(blk != BFITNOENT){ *nrfblock = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0; @@ -607,7 +607,7 @@ void savemeta(char *out_fn, int saveoption) gfs2_dinode_in(&di, bh->b_data); if (!gfs1) do_dinode_extended(&di, bh->b_data); - brelse(bh, not_updated); + brelse(bh); } if (!slow) { printf("Reading resource groups..."); @@ -706,7 +706,7 @@ void savemeta(char *out_fn, int saveoption) first = 0; } } - gfs2_rgrp_relse(rgd, not_updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); } } diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c index 6489e6d..6194244 100644 --- a/gfs2/fsck/eattr.c +++ b/gfs2/fsck/eattr.c @@ -29,17 +29,15 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block) int clear_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { - *want_updated = not_updated; return clear_blk_nodup(ip->i_sbd, block); } int clear_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { - *want_updated = not_updated; return clear_blk_nodup(ip->i_sbd, block); } @@ -91,12 +89,10 @@ int clear_eattr_entry (struct gfs2_inode *ip, int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, - struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private) + struct gfs2_ea_header *ea_hdr_prev, void *private) { uint64_t block = be64_to_cpu(*ea_data_ptr); - *want_updated = not_updated; return clear_blk_nodup(ip->i_sbd, block); } diff --git a/gfs2/fsck/eattr.h b/gfs2/fsck/eattr.h index b93b50b..f4264b0 100644 --- a/gfs2/fsck/eattr.h +++ b/gfs2/fsck/eattr.h @@ -2,11 +2,9 @@ #define _EATTR_H int clear_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + struct gfs2_buffer_head **bh, void *private); int clear_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + struct gfs2_buffer_head **bh, void *private); int clear_eattr_entry (struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, @@ -15,7 +13,6 @@ int clear_eattr_entry (struct gfs2_inode *ip, int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, - struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private); + struct gfs2_ea_header *ea_hdr_prev, void *private); #endif /* _EATTR_H */ diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 763190e..9eff8ec 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -98,7 +98,6 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, struct gfs2_buffer_head *bh_log, *bh_ip; uint64_t blkno; int error = 0; - enum update_flags if_modified; if (pass != 1 || be32_to_cpu(ld->ld_type) != GFS2_LOG_DESC_METADATA) return 0; @@ -125,14 +124,13 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, check_magic = ((struct gfs2_meta_header *) (bh_ip->b_data))->mh_magic; check_magic = be32_to_cpu(check_magic); - if (check_magic != GFS2_MAGIC) { - if_modified = not_updated; + if (check_magic != GFS2_MAGIC) error = -EIO; - } else - if_modified = updated; + else + bmodified(bh_ip); - brelse(bh_log, not_updated); - brelse(bh_ip, if_modified); + brelse(bh_log); + brelse(bh_ip); if (error) break; @@ -181,7 +179,8 @@ static int revoke_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, offset += sizeof(uint64_t); } - brelse(bh, updated); + bmodified(bh); + brelse(bh); offset = sizeof(struct gfs2_meta_header); first = 0; } @@ -227,8 +226,9 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, *eptr = cpu_to_be32(GFS2_MAGIC); } - brelse(bh_log, not_updated); - brelse(bh_ip, updated); + brelse(bh_log); + bmodified(bh_ip); + brelse(bh_ip); sd_replayed_jblocks++; } @@ -269,7 +269,8 @@ static int foreach_descriptor(struct gfs2_inode *ip, unsigned int start, (bh->b_data))->mh_magic; check_magic = be32_to_cpu(check_magic); if (check_magic != GFS2_MAGIC) { - brelse(bh, updated); + bmodified(bh); + brelse(bh); return -EIO; } ld = (struct gfs2_log_descriptor *)bh->b_data; @@ -281,38 +282,45 @@ static int foreach_descriptor(struct gfs2_inode *ip, unsigned int start, error = get_log_header(ip, start, &lh); if (!error) { gfs2_replay_incr_blk(ip, &start); - brelse(bh, updated); + bmodified(bh); + brelse(bh); continue; } if (error == 1) error = -EIO; - brelse(bh, updated); + bmodified(bh); + brelse(bh); return error; } else if (gfs2_check_meta(bh, GFS2_METATYPE_LD)) { - brelse(bh, updated); + bmodified(bh); + brelse(bh); return -EIO; } ptr = (__be64 *)(bh->b_data + offset); error = databuf_lo_scan_elements(ip, start, ld, ptr, pass); if (error) { - brelse(bh, updated); + bmodified(bh); + brelse(bh); return error; } error = buf_lo_scan_elements(ip, start, ld, ptr, pass); if (error) { - brelse(bh, updated); + bmodified(bh); + brelse(bh); return error; } error = revoke_lo_scan_elements(ip, start, ld, ptr, pass); if (error) { - brelse(bh, updated); + bmodified(bh); + brelse(bh); return error; } while (length--) gfs2_replay_incr_blk(ip, &start); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } return 0; @@ -363,10 +371,11 @@ static int fix_journal_seq_no(struct gfs2_inode *ip) lh.lh_sequence = highest_seq; prev_seq = lh.lh_sequence; log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence); - block_map(ip, blk, &new, &dblock, &extlen, FALSE, not_updated); + block_map(ip, blk, &new, &dblock, &extlen, FALSE); bh = bread(&ip->i_sbd->buf_list, dblock); gfs2_log_header_out(&lh, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } return 0; } @@ -569,11 +578,10 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check, } *clean_journals += clean; } - inode_put(sdp->md.journal[i], - (opts.no ? not_updated : updated)); + inode_put(sdp->md.journal[i]); } - inode_put(sdp->master_dir, not_updated); - inode_put(sdp->md.jiinode, not_updated); + inode_put(sdp->master_dir); + inode_put(sdp->md.jiinode); /* Sync the buffers to disk so we get a fresh start. */ bsync(&sdp->buf_list); return error; diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index dae785c..9c9a3fe 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -62,7 +62,7 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */ struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block); struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); -void fsck_inode_put(struct gfs2_inode *ip, enum update_flags update); +void fsck_inode_put(struct gfs2_inode *ip); int initialize(struct gfs2_sbd *sbp, int force_check, int preen, int *all_clean); diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index aa14f98..1ef2cba 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -328,7 +328,6 @@ int main(int argc, char **argv) struct gfs2_sbd sb; struct gfs2_sbd *sbp = &sb; int j; - enum update_flags update_sys_files; int error = 0; int all_clean = 0; @@ -447,23 +446,22 @@ int main(int argc, char **argv) } else { error = FSCK_CANCELED; } - update_sys_files = (opts.no ? not_updated : updated); check_statfs(sbp); /* Free up our system inodes */ - inode_put(sbp->md.inum, update_sys_files); - inode_put(sbp->md.statfs, update_sys_files); + inode_put(sbp->md.inum); + inode_put(sbp->md.statfs); for (j = 0; j < sbp->md.journals; j++) - inode_put(sbp->md.journal[j], update_sys_files); - inode_put(sbp->md.jiinode, update_sys_files); - inode_put(sbp->md.riinode, update_sys_files); - inode_put(sbp->md.qinode, update_sys_files); - inode_put(sbp->md.pinode, update_sys_files); - inode_put(sbp->md.rooti, update_sys_files); - inode_put(sbp->master_dir, update_sys_files); + inode_put(sbp->md.journal[j]); + inode_put(sbp->md.jiinode); + inode_put(sbp->md.riinode); + inode_put(sbp->md.qinode); + inode_put(sbp->md.pinode); + inode_put(sbp->md.rooti); + inode_put(sbp->master_dir); if (lf_dip) - inode_put(lf_dip, update_sys_files); + inode_put(lf_dip); if (!opts.no && errors_corrected) log_notice( _("Writing changes to disk\n")); diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index 8db0274..42235be 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -83,17 +83,17 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, /* fsck_inode_put - same as inode_put() in libgfs2 but system inodes get special treatment. */ -void fsck_inode_put(struct gfs2_inode *ip, enum update_flags update) +void fsck_inode_put(struct gfs2_inode *ip) { struct gfs2_inode *sysip; sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr); if (sysip) { - if (update) + if (ip->i_bh->b_changed) gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); - brelse(ip->i_bh, update); + brelse(ip->i_bh); } else { - inode_put(ip, update); + inode_put(ip); } } @@ -163,6 +163,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb, old_rec_len = de.de_rec_len; de.de_rec_len = bh_end - (char *)fixb; gfs2_dirent_out(&de, (char *)fixb); + bmodified(bh); } /* @@ -171,7 +172,6 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb, * @ip - dinode associated with this leaf block * bh - buffer for the leaf block * type - type of block this is (linear or exhash) - * @update - set to 1 if the block was updated * @count - set to the count entries * @pass - structure pointing to pass-specific functions * @@ -179,8 +179,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb, * -1 - error occurred */ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, - int type, enum update_flags *update, - uint16_t *count, struct metawalk_fxns *pass) + int type, uint16_t *count, struct metawalk_fxns *pass) { struct gfs2_leaf *leaf = NULL; struct gfs2_dirent *dent; @@ -236,7 +235,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, dirblk_truncate(ip, dent, bh); else dirblk_truncate(ip, prev, bh); - *update = updated; log_err( _("Unable to repair corrupt " "directory entry; the " "entry was removed " @@ -246,7 +244,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, log_err( _("Corrupt directory entry " "repaired.\n")); errors_corrected++; - *update = updated; + bmodified(bh); /* keep looping through dentries */ } } else { @@ -272,7 +270,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, if (query(&opts, _("Attempt to remove it? (y/n) "))) { dirblk_truncate(ip, prev, bh); - *update = 1; log_err(_("The corrupt directory " "entry was removed.\n")); } else { @@ -290,14 +287,13 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, de.de_inum.no_addr = de.de_inum.no_formal_ino; de.de_inum.no_formal_ino = 0; gfs2_dirent_out(&de, (char *)dent); - *update = (opts.no ? not_updated : updated); + bmodified(bh); /* Mark dirent buffer as modified */ first = 0; } else { error = pass->check_dentry(ip, dent, prev, bh, - filename, update, - count, + filename, count, pass->private); if(error < 0) { stack; @@ -357,8 +353,7 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no, } /* Checks exhash directory entries */ -static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, - struct metawalk_fxns *pass) +static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) { int error; struct gfs2_leaf leaf, oldleaf; @@ -382,10 +377,10 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, lbh = bread(&sbp->buf_list, first_ok_leaf); /* Make sure it's really a valid leaf block. */ if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) { - brelse(lbh, not_updated); + brelse(lbh); break; } - brelse(lbh, not_updated); + brelse(lbh); } } old_leaf = -1; @@ -433,7 +428,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, gfs2_leaf_in(&oldleaf, lbh->b_data); oldleaf.lf_depth = ip->i_di.di_depth - factor; gfs2_leaf_out(&oldleaf, lbh->b_data); - brelse(lbh, updated); + bmodified(lbh); + brelse(lbh); } else return 1; @@ -461,7 +457,6 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, break; } - *update = not_updated; /* Try to read in the leaf block. */ lbh = bread(&sbp->buf_list, leaf_no); /* Make sure it's really a valid leaf block. */ @@ -470,7 +465,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, old_leaf, first_ok_leaf, lindex, _("that is not really a leaf")); memcpy(&leaf, &oldleaf, sizeof(oldleaf)); - brelse(lbh, not_updated); + bmodified(lbh); + brelse(lbh); break; } gfs2_leaf_in(&leaf, lbh->b_data); @@ -491,7 +487,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, leaf.lf_dirent_format = GFS2_FORMAT_DE; gfs2_leaf_out(&leaf, lbh->b_data); log_debug( _("Fixing lf_dirent_format.\n")); - *update = (opts.no ? not_updated : updated); + bmodified(lbh); } /* Make sure it's really a leaf. */ @@ -505,7 +501,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, ip->i_di.di_num.no_addr, (unsigned long long)leaf_no, (unsigned long long)leaf_no); - brelse(lbh, *update); + brelse(lbh); break; } exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth)); @@ -515,22 +511,20 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, if(pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) { error = check_entries(ip, lbh, DIR_EXHASH, - update, &count, pass); + &count, pass); /* Since the buffer possibly got * updated directly, release it now, * and grab it again later if we need it. */ - brelse(lbh, *update); + brelse(lbh); if(error < 0) { stack; return -1; } - if(update && (count != leaf.lf_entries)) { - enum update_flags f = not_updated; - + if(count != leaf.lf_entries) { lbh = bread(&sbp->buf_list, leaf_no); gfs2_leaf_in(&leaf, lbh->b_data); @@ -552,16 +546,16 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, leaf.lf_entries = count; gfs2_leaf_out(&leaf, lbh->b_data); log_warn( _("Leaf entry count updated\n")); - f = updated; + bmodified(lbh); } else log_err( _("Leaf entry count left in inconsistant state\n")); - brelse(lbh, f); + brelse(lbh); } /* FIXME: Need to get entry count and * compare it against leaf->lf_entries */ break; /* not a chain; go back to outer loop */ } else { - brelse(lbh, *update); + brelse(lbh); if(!leaf.lf_next) break; leaf_no = leaf.lf_next; @@ -576,8 +570,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update, static int check_eattr_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, - struct metawalk_fxns *pass, - enum update_flags *update_it) + struct metawalk_fxns *pass) { struct gfs2_ea_header *ea_hdr, *ea_hdr_prev = NULL; uint64_t *ea_data_ptr = NULL; @@ -585,7 +578,6 @@ static int check_eattr_entries(struct gfs2_inode *ip, int error = 0; uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header); - *update_it = 0; if(!pass->check_eattr_entry) { return 0; } @@ -604,8 +596,6 @@ static int check_eattr_entries(struct gfs2_inode *ip, stack; return -1; } - if (error > 0) - *update_it = updated; if(error == 0 && pass->check_eattr_extentry && ea_hdr->ea_num_ptrs) { uint32_t tot_ealen = 0; @@ -627,7 +617,6 @@ static int check_eattr_entries(struct gfs2_inode *ip, ea_data_ptr, bh, ea_hdr, ea_hdr_prev, - update_it, pass->private)) { errors_found++; if (query(&opts, _("Repair the bad " @@ -638,7 +627,7 @@ static int check_eattr_entries(struct gfs2_inode *ip, ea_hdr->ea_data_len = cpu_to_be32(tot_ealen); *ea_data_ptr = 0; - *update_it = 1; + bmodified(bh); /* Endianness doesn't matter in this case because it's a single byte. */ @@ -680,38 +669,29 @@ static int check_eattr_entries(struct gfs2_inode *ip, * Returns: 0 on success, 1 if removal is needed, -1 on error */ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block, - uint64_t parent, enum update_flags *want_updated, - struct metawalk_fxns *pass) + uint64_t parent, struct metawalk_fxns *pass) { struct gfs2_buffer_head *bh = NULL; int error = 0; - enum update_flags updated_this_leaf = not_updated; log_debug( _("Checking EA leaf block #%"PRIu64" (0x%" PRIx64 ").\n"), block, block); if(pass->check_eattr_leaf) { error = pass->check_eattr_leaf(ip, block, parent, &bh, - &updated_this_leaf, pass->private); - if (updated_this_leaf) /* if this leaf was updated */ - *want_updated = updated; /* signal it for the parent */ if(error < 0) { stack; return -1; } if(error > 0) { if (bh) - brelse(bh, updated_this_leaf); + brelse(bh); return 1; } if (bh) { - error = check_eattr_entries(ip, bh, pass, - &updated_this_leaf); - brelse(bh, updated_this_leaf); - if (updated_this_leaf) /* if this leaf was updated */ - *want_updated = updated; /* signal it for - the parent */ + error = check_eattr_entries(ip, bh, pass); + brelse(bh); } return error; } @@ -727,7 +707,6 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block, * Returns: 0 on success -1 on error */ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, - enum update_flags *want_updated, struct metawalk_fxns *pass) { int error = 0; @@ -735,19 +714,16 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, uint64_t block; struct gfs2_buffer_head *indirect_buf = NULL; struct gfs2_sbd *sdp = ip->i_sbd; - enum update_flags update_indir_block = not_updated; int first_ea_is_bad = 0; uint64_t di_eattr_save = ip->i_di.di_eattr; - *want_updated = not_updated; log_debug( _("Checking EA indirect block #%"PRIu64" (0x%" PRIx64 ").\n"), indirect, indirect); if (!pass->check_eattr_indir) return 0; error = pass->check_eattr_indir(ip, indirect, ip->i_di.di_num.no_addr, - &indirect_buf, want_updated, - pass->private); + &indirect_buf, pass->private); if (!error) { int leaf_pointers = 0, leaf_pointer_errors = 0; @@ -759,20 +735,16 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, while(*ea_leaf_ptr && (ea_leaf_ptr < end)){ block = be64_to_cpu(*ea_leaf_ptr); leaf_pointers++; - error = check_leaf_eattr(ip, block, indirect, - want_updated, pass); + error = check_leaf_eattr(ip, block, indirect, pass); if (error) { leaf_pointer_errors++; - if (update_indir_block == not_updated) { - errors_found++; - if (query(&opts, _("Fix the indirect " - "block too? (y/n) "))) { - update_indir_block = updated; - errors_corrected++; - *ea_leaf_ptr = 0; - } - } else + errors_found++; + if (query(&opts, _("Fix the indirect " + "block too? (y/n) "))) { + bmodified(indirect_buf); + errors_corrected++; *ea_leaf_ptr = 0; + } } /* If the first eattr lead is bad, we can't have a hole, so we have to treat this as an unrecoverable @@ -788,7 +760,6 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, pass->finish_eattr_indir(ip, leaf_pointers, leaf_pointer_errors, - want_updated, pass->private); } else if (leaf_pointer_errors) { /* This is a bit tricky. We can't have eattr @@ -811,11 +782,10 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, ip->i_di.di_eattr = di_eattr_save; pass->finish_eattr_indir(ip, leaf_pointers, leaf_pointer_errors, - want_updated, pass->private); } if (leaf_pointer_errors == leaf_pointers) { - if (*want_updated) + if (indirect_buf->b_changed) gfs2_set_bitmap(sdp, indirect, GFS2_BLKST_FREE); gfs2_block_set(sdp, bl, indirect, @@ -825,7 +795,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, } } if (indirect_buf) - brelse(indirect_buf, update_indir_block); + brelse(indirect_buf); return error; } @@ -836,8 +806,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, * * Returns: 0 on success, -1 on error */ -int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated, - struct metawalk_fxns *pass) +int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass) { int error = 0; @@ -850,12 +819,11 @@ int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated, if(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT){ if((error = check_indirect_eattr(ip, ip->i_di.di_eattr, - want_updated, pass))) + pass))) stack; } else { error = check_leaf_eattr(ip, ip->i_di.di_eattr, - ip->i_di.di_num.no_addr, - want_updated, pass); + ip->i_di.di_num.no_addr, pass); if (error) stack; } @@ -946,12 +914,12 @@ fail: while (!osi_list_empty(list)) { nbh = osi_list_entry(list->next, struct gfs2_buffer_head, b_altlist); - brelse(nbh, not_updated); + brelse(nbh); osi_list_del(&nbh->b_altlist); } } /* This is an error path, so we need to release the buffer here: */ - brelse(metabh, not_updated); + brelse(metabh); return -1; } @@ -969,7 +937,6 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) uint64_t block, *ptr; uint32_t height = ip->i_di.di_height; int i, head_size; - enum update_flags update = not_updated; int error = 0; if (!height) @@ -1032,7 +999,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) { bh = osi_list_entry(list->next, struct gfs2_buffer_head, b_altlist); - brelse(bh, not_updated); + brelse(bh); osi_list_del(&bh->b_altlist); } } @@ -1041,7 +1008,7 @@ end: if (S_ISDIR(ip->i_di.di_mode)) { /* check validity of leaf blocks and leaf chains */ if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { - error = check_leaf_blks(ip, &update, pass); + error = check_leaf_blks(ip, pass); if(error < 0) return -1; if(error > 0) @@ -1054,12 +1021,12 @@ end: /* Checks stuffed inode directories */ static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, - enum update_flags *update, struct metawalk_fxns *pass) + struct metawalk_fxns *pass) { int error = 0; uint16_t count = 0; - error = check_entries(ip, bh, DIR_LINEAR, update, &count, pass); + error = check_entries(ip, bh, DIR_LINEAR, &count, pass); if(error < 0) { stack; return -1; @@ -1073,38 +1040,36 @@ int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass) { struct gfs2_buffer_head *bh; struct gfs2_inode *ip; - enum update_flags update = not_updated; int error = 0; bh = bread(&sbp->buf_list, block); ip = fsck_inode_get(sbp, bh); if(ip->i_di.di_flags & GFS2_DIF_EXHASH) { - error = check_leaf_blks(ip, &update, pass); + error = check_leaf_blks(ip, pass); if(error < 0) { stack; - fsck_inode_put(ip, not_updated); /* does brelse(bh); */ + fsck_inode_put(ip); /* does brelse(bh); */ return -1; } } else { - error = check_linear_dir(ip, bh, &update, pass); + error = check_linear_dir(ip, bh, pass); if(error < 0) { stack; - fsck_inode_put(ip, not_updated); /* does brelse(bh); */ + fsck_inode_put(ip); /* does brelse(bh); */ return -1; } } - fsck_inode_put(ip, opts.no ? not_updated : update); /* does a brelse */ + fsck_inode_put(ip); /* does a brelse */ return error; } static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct gfs2_buffer_head *bh, - char *filename, enum update_flags *update, - uint16_t *count, void *private) + char *filename, uint16_t *count, void *private) { /* the metawalk_fxn's private field must be set to the dentry * block we want to clear */ @@ -1114,7 +1079,6 @@ static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, memset(&dentry, 0, sizeof(struct gfs2_dirent)); gfs2_dirent_in(&dentry, (char *)dent); de = &dentry; - *update = (opts.no ? not_updated : updated); if(de->de_inum.no_addr == *dentryblock) dirent2_del(ip, bh, prev_de, dent); @@ -1267,16 +1231,14 @@ int delete_data(struct gfs2_inode *ip, uint64_t block, void *private) } int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + struct gfs2_buffer_head **bh, void *private) { return delete_blocks(ip, block, NULL, _("indirect extended attribute"), private); } int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + struct gfs2_buffer_head **bh, void *private) { return delete_blocks(ip, block, NULL, _("extended attribute"), private); diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h index 0721ed1..b720516 100644 --- a/gfs2/fsck/metawalk.h +++ b/gfs2/fsck/metawalk.h @@ -6,8 +6,7 @@ struct metawalk_fxns; -int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated, - struct metawalk_fxns *pass); +int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass); int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass); int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass); @@ -23,11 +22,9 @@ int delete_metadata(struct gfs2_inode *ip, uint64_t block, struct gfs2_buffer_head **bh, void *private); int delete_data(struct gfs2_inode *ip, uint64_t block, void *private); int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + struct gfs2_buffer_head **bh, void *private); int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + struct gfs2_buffer_head **bh, void *private); /* metawalk_fxns: function pointers to check various parts of the fs * @@ -54,18 +51,14 @@ struct metawalk_fxns { void *private); int (*check_eattr_indir) (struct gfs2_inode *ip, uint64_t block, uint64_t parent, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, - void *private); + struct gfs2_buffer_head **bh, void *private); int (*check_eattr_leaf) (struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); int (*check_dentry) (struct gfs2_inode *ip, struct gfs2_dirent *de, struct gfs2_dirent *prev, struct gfs2_buffer_head *bh, - char *filename, enum update_flags *update, - uint16_t *count, void *private); + char *filename, uint16_t *count, void *private); int (*check_eattr_entry) (struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, @@ -76,11 +69,9 @@ struct metawalk_fxns { struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private); int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers, int leaf_pointer_errors, - enum update_flags *want_updated, void *private); }; diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 139daa8..7b0651b 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -38,10 +38,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block, static int check_data(struct gfs2_inode *ip, uint64_t block, void *private); static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + void *private); static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private); + void *private); static int check_eattr_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, @@ -51,11 +51,9 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private); static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, - int leaf_pointer_errors, - enum update_flags *want_updated, void *private); + int leaf_pointer_errors, void *private); struct metawalk_fxns pass1_fxns = { .private = NULL, @@ -116,10 +114,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block, "something that is not an indirect block).\n")); if(!found_dup) { gfs2_block_set(ip->i_sbd, bl, block, gfs2_meta_inval); - brelse(nbh, not_updated); + brelse(nbh); return 1; } - brelse(nbh, not_updated); + brelse(nbh); } else /* blk check ok */ *bh = nbh; @@ -224,7 +222,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private) } static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc, - int duplicate, enum update_flags *want_updated) + int duplicate) { if (!duplicate) { gfs2_set_bitmap(ip->i_sbd, ip->i_di.di_eattr, @@ -236,13 +234,12 @@ static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc, bc->ea_count = 0; ip->i_di.di_blocks = 1 + bc->indir_count + bc->data_count; ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT; - *want_updated = updated; + bmodified(ip->i_bh); return 0; } static int ask_remove_inode_eattr(struct gfs2_inode *ip, - struct block_count *bc, - enum update_flags *want_updated) + struct block_count *bc) { log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute " "errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr, @@ -257,7 +254,7 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip, stack; return -1; } - if (!remove_inode_eattr(ip, bc, q.dup_block, want_updated)) + if (!remove_inode_eattr(ip, bc, q.dup_block)) log_err( _("Extended attributes were removed.\n")); else log_err( _("Unable to remove inode eattr pointer; " @@ -278,12 +275,10 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip, * Returns: 1 if the EA is fixed, else 0 if it was not fixed. */ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, - uint64_t block, int duplicate, - enum update_flags *want_updated, const char *emsg) + uint64_t block, int duplicate, const char *emsg) { struct gfs2_sbd *sdp = ip->i_sbd; - *want_updated = not_updated; log_err( _("Inode #%llu (0x%llx): %s"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr, emsg); @@ -293,7 +288,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, if (query(&opts, _("Clear the bad Extended Attribute? (y/n) "))) { errors_corrected++; if (block == ip->i_di.di_eattr) { - remove_inode_eattr(ip, bc, duplicate, want_updated); + remove_inode_eattr(ip, bc, duplicate); log_err( _("The bad extended attribute was " "removed.\n")); } else if (!duplicate) { @@ -302,7 +297,6 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, log_err( _("The bad Extended Attribute was " "removed.\n")); } - *want_updated = updated; return 1; } else { log_err( _("The bad Extended Attribute was not fixed.\n")); @@ -313,7 +307,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { struct gfs2_sbd *sdp = ip->i_sbd; int ret = 0; @@ -342,7 +336,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, *bh = bread(&sdp->buf_list, indirect); if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) { if(q.block_type != gfs2_block_free) { /* Duplicate? */ - if (!clear_eas(ip, bc, indirect, 1, want_updated, + if (!clear_eas(ip, bc, indirect, 1, _("Bad indirect Extended Attribute " "duplicate found"))) { gfs2_block_mark(sdp, bl, indirect, @@ -351,7 +345,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, } return 1; } - clear_eas(ip, bc, indirect, 0, want_updated, + clear_eas(ip, bc, indirect, 0, _("Extended Attribute indirect block has incorrect " "type")); return 1; @@ -378,13 +372,12 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, } static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, - int leaf_pointer_errors, - enum update_flags *want_updated, void *private) + int leaf_pointer_errors, void *private) { struct block_count *bc = (struct block_count *) private; if (leaf_pointer_errors == leaf_pointers) /* All eas were bad */ - return ask_remove_inode_eattr(ip, bc, want_updated); + return ask_remove_inode_eattr(ip, bc); log_debug( _("Marking inode #%llu (0x%llx) with extended " "attribute block\n"), (unsigned long long)ip->i_di.di_num.no_addr, @@ -404,7 +397,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, errors_corrected++; ip->i_di.di_blocks = 1 + bc->indir_count + bc->data_count + bc->ea_count; - *want_updated = updated; + bmodified(ip->i_bh); log_err( _("Block count fixed.\n")); return 1; } @@ -413,8 +406,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, } static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype, - struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + struct gfs2_buffer_head **bh, void *private) { struct gfs2_buffer_head *leaf_bh = NULL; struct gfs2_sbd *sdp = ip->i_sbd; @@ -431,14 +423,15 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype, leaf_bh = bread(&sdp->buf_list, block); if(gfs2_check_meta(leaf_bh, btype)) { if(q.block_type != gfs2_block_free) { /* Duplicate? */ - clear_eas(ip, bc, block, 1, want_updated, + clear_eas(ip, bc, block, 1, _("Bad Extended Attribute duplicate found")); } else { - clear_eas(ip, bc, block, 0, want_updated, + clear_eas(ip, bc, block, 0, _("Extended Attribute leaf block " "has incorrect type")); } - brelse(leaf_bh, *want_updated); + bmodified(leaf_bh); + brelse(leaf_bh); return 1; } if(q.block_type != gfs2_block_free) { /* Duplicate? */ @@ -447,17 +440,18 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype, (unsigned long long)block); gfs2_block_mark(sdp, bl, block, gfs2_dup_block); bc->ea_count++; - brelse(leaf_bh, not_updated); + brelse(leaf_bh); return 1; } if (ip->i_di.di_eattr == 0) { /* Can only get in here if there were unrecoverable ea errors that caused clear_eas to be called. What we need to do here is remove the subsequent ea blocks. */ - clear_eas(ip, bc, block, 0, want_updated, + clear_eas(ip, bc, block, 0, _("Extended Attribute block removed due to " "previous errors.\n")); - brelse(leaf_bh, *want_updated); + bmodified(leaf_bh); + brelse(leaf_bh); return 1; } log_debug( _("Setting block #%lld (0x%llx) to eattr block\n"), @@ -486,7 +480,6 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private) { uint64_t el_blk = be64_to_cpu(*data_ptr); @@ -507,16 +500,15 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr, gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block); return 1; } - error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, - want_updated, private); + error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private); if (bh) - brelse(bh, not_updated); + brelse(bh); return error; } static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { struct gfs2_sbd *sdp = ip->i_sbd; @@ -539,8 +531,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block); return 1; } - return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, want_updated, - private); + return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, private); } static int check_eattr_entries(struct gfs2_inode *ip, @@ -680,9 +671,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, int error; struct block_count bc = {0}; struct metawalk_fxns invalidate_metatree = {0}; - enum update_flags f; - f = not_updated; invalidate_metatree.check_metalist = clear_metalist; invalidate_metatree.check_data = clear_data; invalidate_metatree.check_leaf = clear_leaf; @@ -701,7 +690,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, errors_corrected++; ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block; gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); - f = updated; + bmodified(ip->i_bh); } else log_err( _("Address in inode at block #%" PRIu64 " (0x%" PRIx64 ") not fixed\n"), block, block); @@ -709,7 +698,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, if(gfs2_block_check(sdp, bl, block, &q)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } if(q.block_type != gfs2_block_free) { @@ -717,10 +706,10 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, "#%" PRIu64 " (0x%" PRIx64 ")\n"), block, block); if(gfs2_block_mark(sdp, bl, block, gfs2_dup_block)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } @@ -731,12 +720,12 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_dir)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } if(add_to_dir_list(sdp, block)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -745,7 +734,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_file)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -754,7 +743,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_lnk)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -763,7 +752,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_blk)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -772,7 +761,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_chr)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -781,7 +770,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_fifo)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -790,7 +779,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_inode_sock)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } break; @@ -799,16 +788,16 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, block, block); if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } if(set_link_count(ip->i_sbd, ip->i_di.di_num.no_addr, ip->i_di.di_nlink)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } @@ -825,11 +814,11 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, log_warn( _("Marking inode invalid\n")); if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { stack; - fsck_inode_put(ip, f); + fsck_inode_put(ip); return -1; } gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } } @@ -838,7 +827,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, error = check_metatree(ip, &pass1_fxns); if (fsck_abort || error < 0) { - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } if(error > 0) { @@ -850,15 +839,15 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, gfs2_block_set(sdp, bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE); - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } - error = check_inode_eattr(ip, &f, &pass1_fxns); + error = check_inode_eattr(ip, &pass1_fxns); - if (error && f == updated && + if (error && !(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT)) - ask_remove_inode_eattr(ip, &bc, &f); + ask_remove_inode_eattr(ip, &bc); if (ip->i_di.di_blocks != (1 + bc.indir_count + bc.data_count + bc.ea_count)) { @@ -880,8 +869,8 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, errors_corrected++; ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count + bc.ea_count; + bmodified(ip->i_bh); gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); - f = updated; } else log_err( _("Bad block count for #%llu (0x%llx" ") not fixed\n"), @@ -889,7 +878,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, (unsigned long long)ip->i_di.di_num.no_addr); } - fsck_inode_put(ip, f); + fsck_inode_put(ip); return 0; } @@ -1022,7 +1011,7 @@ int pass1(struct gfs2_sbd *sbp) break; warm_fuzzy_stuff(block); if (fsck_abort) { /* if asked to abort */ - gfs2_rgrp_relse(rgd, not_updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); return FSCK_OK; } @@ -1035,15 +1024,15 @@ int pass1(struct gfs2_sbd *sbp) if (scan_meta(sbp, bh, block)) { stack; - brelse(bh, not_updated); - gfs2_rgrp_relse(rgd, not_updated, rgbh); + brelse(bh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); return FSCK_ERROR; } - brelse(bh, not_updated); + brelse(bh); first = 0; } - gfs2_rgrp_relse(rgd, not_updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); } return FSCK_OK; diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c index 3cf102b..04b4226 100644 --- a/gfs2/fsck/pass1b.c +++ b/gfs2/fsck/pass1b.c @@ -60,12 +60,11 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private) static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { struct gfs2_sbd *sbp = ip->i_sbd; struct gfs2_buffer_head *indir_bh = NULL; - *want_updated = not_updated; inc_if_found(block, 0, private); indir_bh = bread(&sbp->buf_list, block); *bh = indir_bh; @@ -75,12 +74,11 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { struct gfs2_sbd *sbp = ip->i_sbd; struct gfs2_buffer_head *leaf_bh = NULL; - *want_updated = not_updated; inc_if_found(block, 0, private); leaf_bh = bread(&sbp->buf_list, block); @@ -100,11 +98,10 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private) + void *private) { uint64_t block = be64_to_cpu(*ea_data_ptr); - *want_updated = not_updated; inc_if_found(block, 0, private); return 0; @@ -113,7 +110,7 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de, struct gfs2_dirent *prev, struct gfs2_buffer_head *bh, char *filename, - enum update_flags *update, uint16_t *count, void *priv) + uint16_t *count, void *priv) { osi_list_t *tmp1, *tmp2; struct dup_blocks *b; @@ -190,14 +187,12 @@ static int clear_dup_data(struct gfs2_inode *ip, uint64_t block, void *private) static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) { struct dup_handler *dh = (struct dup_handler *) private; /* Can't use fxns from eattr.c since we need to check the ref * count */ *bh = NULL; - *want_updated = not_updated; if(dh->ref_count == 1) return 1; if(block == dh->b->block_no) { @@ -220,11 +215,10 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block, static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { struct dup_handler *dh = (struct dup_handler *) private; - *want_updated = not_updated; if(dh->ref_count == 1) return 1; if(block == dh->b->block_no) { @@ -292,13 +286,11 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private) { uint64_t block = be64_to_cpu(*ea_data_ptr); struct dup_handler *dh = (struct dup_handler *) private; - *want_updated = not_updated; if(dh->ref_count == 1) return 1; if(block == dh->b->block_no) { @@ -337,7 +329,6 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block .check_eattr_entry = check_eattr_entry, .check_eattr_extentry = check_eattr_extentry, }; - enum update_flags update; ip = fsck_load_inode(sbp, inode); /* bread, inode_get */ log_debug( _("Checking inode %" PRIu64 " (0x%" PRIx64 ")'s " @@ -345,14 +336,14 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block ")\n"), inode, inode, b->block_no, b->block_no); if(check_metatree(ip, &find_refs)) { stack; - fsck_inode_put(ip, not_updated); /* out, brelse, free */ + fsck_inode_put(ip); /* out, brelse, free */ return -1; } log_debug( _("Done checking metatree\n")); /* Check for ea references in the inode */ - if(check_inode_eattr(ip, &update, &find_refs) < 0){ + if(check_inode_eattr(ip, &find_refs) < 0){ stack; - fsck_inode_put(ip, not_updated); /* out, brelse, free */ + fsck_inode_put(ip); /* out, brelse, free */ return -1; } if (myfi.found) { @@ -372,7 +363,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block id->ea_only = myfi.ea_only; osi_list_add_prev(&id->list, &b->ref_inode_list); } - fsck_inode_put(ip, (opts.no ? not_updated : updated)); /* out, brelse, free */ + fsck_inode_put(ip); /* out, brelse, free */ return 0; } @@ -393,7 +384,6 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) }; struct gfs2_inode *ip; struct dup_handler dh = {0}; - enum update_flags update; osi_list_foreach(tmp, &b->ref_inode_list) { id = osi_list_entry(tmp, struct inode_with_dups, list); @@ -414,7 +404,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) bh = bread(&sbp->buf_list, b->block_no); cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic; - brelse(bh, not_updated); + brelse(bh); if (be32_to_cpu(cmagic) == GFS2_MAGIC) { tmp = b->ref_inode_list.next; id = osi_list_entry(tmp, struct inode_with_dups, list); @@ -439,7 +429,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); - fsck_inode_put(ip, updated); + bmodified(ip->i_bh); + fsck_inode_put(ip); } else { log_warn( _("The bad inode was not cleared.")); } @@ -481,14 +472,14 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b) dh.id = id; clear_dup_fxns.private = (void *) &dh; /* Clear the EAs for the inode first */ - check_inode_eattr(ip, &update, &clear_dup_fxns); + check_inode_eattr(ip, &clear_dup_fxns); /* If the dup wasn't only in the EA, clear the inode */ if(!id->ea_only) check_metatree(ip, &clear_dup_fxns); gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); - fsck_inode_put(ip, updated); /* out, brelse, free */ + fsck_inode_put(ip); /* out, brelse, free */ dh.ref_inode_count--; if(dh.ref_inode_count == 1) break; diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index c8b05b1..6d06d83 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -27,6 +27,7 @@ static int remove_eattr_entry(struct gfs2_sbd *sdp, log_err( _("Bad Extended Attribute at block #%"PRIu64 " (0x%" PRIx64 ") removed.\n"), leaf_bh->b_blocknr, leaf_bh->b_blocknr); + bmodified(leaf_bh); return 0; } @@ -58,14 +59,13 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp, return 1; } -static int ask_remove_eattr(struct gfs2_inode *ip, - enum update_flags *need_update) +static int ask_remove_eattr(struct gfs2_inode *ip) { errors_found++; if (query(&opts, _("Remove the bad Extended Attribute? (y/n) "))) { errors_corrected++; ip->i_di.di_eattr = 0; - *need_update = updated; + bmodified(ip->i_bh); log_err( _("Bad Extended Attribute removed.\n")); } else log_err( _("Bad Extended Attribute not removed.\n")); @@ -74,13 +74,12 @@ static int ask_remove_eattr(struct gfs2_inode *ip, static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *need_update, void *private) + void *private) { struct gfs2_sbd *sbp = ip->i_sbd; struct gfs2_block_query q; struct gfs2_buffer_head *indir_bh = NULL; - *need_update = not_updated; if(gfs2_check_range(sbp, block)) { log_err( _("Extended attributes indirect block #%llu" " (0x%llx) for inode #%llu" @@ -89,7 +88,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, (unsigned long long)block, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - return ask_remove_eattr(ip, need_update); + return ask_remove_eattr(ip); } else if (gfs2_block_check(sbp, bl, block, &q)) { stack; @@ -103,7 +102,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, (unsigned long long)block, (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - return ask_remove_eattr(ip, need_update); + return ask_remove_eattr(ip); } else indir_bh = bread(&sbp->buf_list, block); @@ -114,7 +113,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *need_update, void *private) + void *private) { struct gfs2_sbd *sbp = ip->i_sbd; struct gfs2_block_query q; @@ -124,7 +123,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, " (0x%llx) out of range.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - return ask_remove_eattr(ip, need_update); + return ask_remove_eattr(ip); } else if (gfs2_block_check(sbp, bl, block, &q)) { stack; @@ -135,7 +134,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, " (0x%llx) invalid.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - return ask_remove_eattr(ip, need_update); + return ask_remove_eattr(ip); } else *bh = bread(&sbp->buf_list, block); @@ -213,8 +212,7 @@ static int check_eattr_entry(struct gfs2_inode *ip, static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr, struct gfs2_buffer_head *leaf_bh, struct gfs2_ea_header *ea_hdr, - struct gfs2_ea_header *ea_hdr_prev, - enum update_flags *want_updated, void *private) + struct gfs2_ea_header *ea_hdr_prev, void *private) { struct gfs2_block_query q; struct gfs2_sbd *sbp = ip->i_sbd; @@ -244,7 +242,6 @@ int pass1c(struct gfs2_sbd *sbp) int error = 0; osi_list_t *tmp, *x; struct special_blocks *ea_block; - enum update_flags want_updated = not_updated; pass1c_fxns.check_eattr_indir = &check_eattr_indir; pass1c_fxns.check_eattr_leaf = &check_eattr_leaf; @@ -271,18 +268,15 @@ int pass1c(struct gfs2_sbd *sbp) (unsigned long long)ip->i_di.di_eattr, (unsigned long long)ip->i_di.di_eattr); /* FIXME: Handle walking the eattr here */ - error = check_inode_eattr(ip, &want_updated, - &pass1c_fxns); + error = check_inode_eattr(ip, &pass1c_fxns); if(error < 0) { stack; - brelse(bh, not_updated); + brelse(bh); return FSCK_ERROR; } - - fsck_inode_put(ip, want_updated); /* dinode_out, - brelse, free */ + fsck_inode_put(ip); /* dinode_out, brelse, free */ } else { - brelse(bh, want_updated); + brelse(bh); } } return FSCK_OK; diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index 15b7594..0a3f63d 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -76,18 +76,16 @@ static int set_dotdot_dir(struct gfs2_sbd *sbp, uint64_t childblock, } static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, - uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + uint64_t parent, struct gfs2_buffer_head **bh, + void *private) { - *want_updated = not_updated; *bh = bread(&ip->i_sbd->buf_list, block); return 0; } static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent, struct gfs2_buffer_head **bh, - enum update_flags *want_updated, void *private) + void *private) { - *want_updated = not_updated; *bh = bread(&ip->i_sbd->buf_list, block); return 0; } @@ -155,7 +153,7 @@ struct metawalk_fxns pass2_fxns_delete = { static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, struct gfs2_dirent *prev_de, struct gfs2_buffer_head *bh, char *filename, - enum update_flags *update, uint16_t *count, void *priv) + uint16_t *count, void *priv) { struct gfs2_sbd *sbp = ip->i_sbd; struct gfs2_block_query q = {0}; @@ -232,7 +230,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, errors_corrected++; log_err( _("Clearing %s\n"), tmp_name); dirent2_del(ip, bh, prev_de, dent); - *update = updated; + bmodified(bh); return 1; } else { log_err( _("Directory entry to out of range block remains\n")); @@ -256,14 +254,14 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query(&opts, _("Delete inode containing bad blocks? (y/n)"))) { errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &pass2_fxns_delete); + check_inode_eattr(entry_ip, &pass2_fxns_delete); check_metatree(entry_ip, &pass2_fxns_delete); - fsck_inode_put(entry_ip, updated); + bmodified(entry_ip->i_bh); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); gfs2_block_set(sbp, bl, de->de_inum.no_addr, gfs2_block_free); - *update = updated; + bmodified(bh); log_warn( _("The inode containing bad blocks was " "deleted.\n")); return 1; @@ -297,7 +295,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, errors_corrected++; dirent2_del(ip, bh, prev_de, dent); - *update = updated; + bmodified(bh); log_warn( _("Directory entry '%s' cleared\n"), tmp_name); /* If it was previously marked invalid (i.e. known to be bad, not just a free block, etc.) then @@ -308,15 +306,16 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, /* Now try to clear the dinode, if it is an dinode */ bhi = bread(&sbp->buf_list, de->de_inum.no_addr); error = gfs2_check_meta(bhi, GFS2_METATYPE_DI); - brelse(bhi, updated); + bmodified(bhi); + brelse(bhi); if (error) return 1; /* not a dinode: nothing to delete */ entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &pass2_fxns_delete); + check_inode_eattr(entry_ip, &pass2_fxns_delete); check_metatree(entry_ip, &pass2_fxns_delete); - fsck_inode_put(entry_ip, updated); + bmodified(entry_ip->i_bh); + fsck_inode_put(entry_ip); gfs2_block_set(sbp, bl, de->de_inum.no_addr, gfs2_block_free); @@ -345,11 +344,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query(&opts, _("Clear stale directory entry? (y/n) "))) { errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, &clear_eattrs); - fsck_inode_put(entry_ip, not_updated); + check_inode_eattr(entry_ip, &clear_eattrs); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); - *update = updated; + bmodified(bh); log_err( _("Stale directory entry deleted\n")); return 1; } else { @@ -373,12 +372,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &clear_eattrs); - fsck_inode_put(entry_ip, not_updated); + check_inode_eattr(entry_ip, &clear_eattrs); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); - *update = updated; + bmodified(bh); return 1; } else { log_err( _("Duplicate '.' entry remains\n")); @@ -411,12 +409,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query(&opts, _("Remove '.' reference? (y/n) "))) { errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &clear_eattrs); - fsck_inode_put(entry_ip, not_updated); + check_inode_eattr(entry_ip, &clear_eattrs); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); - *update = updated; + bmodified(bh); return 1; } else { @@ -449,12 +446,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &clear_eattrs); - fsck_inode_put(entry_ip, not_updated); + check_inode_eattr(entry_ip, &clear_eattrs); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); - *update = 1; + bmodified(bh); return 1; } else { log_err( _("Duplicate '..' entry remains\n")); @@ -477,12 +473,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(query(&opts, _("Clear bad '..' directory entry? (y/n) "))) { errors_corrected++; entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr); - check_inode_eattr(entry_ip, update, - &clear_eattrs); - fsck_inode_put(entry_ip, not_updated); + check_inode_eattr(entry_ip, &clear_eattrs); + fsck_inode_put(entry_ip); dirent2_del(ip, bh, prev_de, dent); - *update = 1; + bmodified(bh); return 1; } else { log_err( _("Bad '..' directory entry remains\n")); @@ -505,7 +500,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, ds->dotdotdir = 1; increment_link(sbp, de->de_inum.no_addr); - *update = (opts.no ? not_updated : updated); (*count)++; ds->entry_count++; return 0; @@ -516,7 +510,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, if(q.block_type != gfs2_inode_dir) { log_debug( _("Found non-dir inode dentry\n")); increment_link(sbp, de->de_inum.no_addr); - *update = (opts.no ? not_updated : updated); (*count)++; ds->entry_count++; return 0; @@ -531,8 +524,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, errors_found++; if(query(&opts, _("Clear hard link to directory? (y/n) "))) { errors_corrected++; - *update = 1; - + bmodified(bh); dirent2_del(ip, bh, prev_de, dent); log_warn( _("Directory entry %s cleared\n"), filename); @@ -549,7 +541,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, return -1; } increment_link(sbp, de->de_inum.no_addr); - *update = (opts.no ? not_updated : updated); (*count)++; ds->entry_count++; /* End of checks */ @@ -579,7 +570,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, char *filename; int filename_len; char tmp_name[256]; - enum update_flags update = not_updated; int error = 0; log_info( _("Checking system directory inode '%s'\n"), dirname); @@ -607,7 +597,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval); bh = bhold(sysinode->i_bh); - if(check_inode_eattr(sysinode, &update, &pass2_fxns)) { + if(check_inode_eattr(sysinode, &pass2_fxns)) { stack; return -1; } @@ -637,7 +627,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, sysinode->i_di.di_num.no_addr); ds.entry_count++; free(filename); - update = 1; + bmodified(sysinode->i_bh); } else log_err( _("The directory was not fixed.\n")); } @@ -654,8 +644,8 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, (unsigned long long)sysinode->i_di.di_num.no_addr)) { errors_corrected++; sysinode->i_di.di_entries = ds.entry_count; + bmodified(sysinode->i_bh); log_warn( _("Entries updated\n")); - update = 1; } else { log_err( _("Entries for inode %llu (0x%llx" ") left out of sync\n"), @@ -666,7 +656,9 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, } } - brelse(bh, opts.no ? not_updated : update); + if (!opts.no) + bmodified(bh); + brelse(bh); return 0; } @@ -705,7 +697,6 @@ int pass2(struct gfs2_sbd *sbp) int filename_len; char tmp_name[256]; int error = 0; - enum update_flags need_update = NOT_UPDATED; struct dup_blocks *b; /* Check all the system directory inodes. */ @@ -728,7 +719,6 @@ int pass2(struct gfs2_sbd *sbp) log_info( _("Checking directory inodes.\n")); /* Grab each directory inode, and run checks on it */ for(i = 0; i < last_fs_block; i++) { - need_update = 0; warm_fuzzy_stuff(i); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; @@ -756,11 +746,11 @@ int pass2(struct gfs2_sbd *sbp) * is valid */ ip = fsck_load_inode(sbp, i); if(check_metatree(ip, &pass2_fxns)) { - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); stack; return FSCK_ERROR; } - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); } error = check_dir(sbp, i, &pass2_fxns); if(error < 0) { @@ -834,7 +824,7 @@ int pass2(struct gfs2_sbd *sbp) ds.entry_count++; free(filename); log_err( _("The directory was fixed.\n")); - need_update = UPDATED; + bmodified(ip->i_bh); } else { log_err( _("The directory was not fixed.\n")); } @@ -851,13 +841,12 @@ int pass2(struct gfs2_sbd *sbp) _("Fix the entry count? (y/n) "))) { errors_corrected++; ip->i_di.di_entries = ds.entry_count; - need_update = UPDATED; + bmodified(ip->i_bh); } else { log_err( _("The entry count was not fixed.\n")); } } - fsck_inode_put(ip, need_update); /* does a gfs2_dinode_out, - brelse */ + fsck_inode_put(ip); /* does a gfs2_dinode_out, brelse */ } /* Now that we've deleted the inodes marked "bad" we can safely get rid of the duplicate block list. If we do it any sooner, diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c index d119915..14c25a7 100644 --- a/gfs2/fsck/pass3.c +++ b/gfs2/fsck/pass3.c @@ -32,15 +32,15 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot, filename_len = strlen(".."); if(!(filename = malloc((sizeof(char) * filename_len) + 1))) { log_err( _("Unable to allocate name\n")); - fsck_inode_put(ip, not_updated); - fsck_inode_put(pip, not_updated); + fsck_inode_put(ip); + fsck_inode_put(pip); stack; return -1; } if(!memset(filename, 0, (sizeof(char) * filename_len) + 1)) { log_err( _("Unable to zero name\n")); - fsck_inode_put(ip, not_updated); - fsck_inode_put(pip, not_updated); + fsck_inode_put(ip); + fsck_inode_put(pip); stack; return -1; } @@ -51,8 +51,10 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot, decrement_link(sbp, olddotdot); dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR); increment_link(sbp, newdotdot); - fsck_inode_put(ip, updated); - fsck_inode_put(pip, updated); + bmodified(ip->i_bh); + fsck_inode_put(ip); + bmodified(pip->i_bh); + fsck_inode_put(pip); return 0; } @@ -257,7 +259,7 @@ int pass3(struct gfs2_sbd *sbp) gfs2_block_set(sbp, bl, di->dinode, gfs2_block_free); - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); break; } else { log_err( _("Zero-size unlinked directory remains\n")); @@ -267,15 +269,16 @@ int pass3(struct gfs2_sbd *sbp) if(query(&opts, _("Add unlinked directory to lost+found? (y/n) "))) { errors_corrected++; if(add_inode_to_lf(ip)) { - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); stack; return FSCK_ERROR; } log_warn( _("Directory relinked to lost+found\n")); - fsck_inode_put(ip, updated); + bmodified(ip->i_bh); + fsck_inode_put(ip); } else { log_err( _("Unlinked directory remains unlinked\n")); - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); } break; } diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c index 09a11a6..503d297 100644 --- a/gfs2/fsck/pass4.c +++ b/gfs2/fsck/pass4.c @@ -29,6 +29,7 @@ static int fix_inode_count(struct gfs2_sbd *sbp, struct inode_info *ii, if(ip->i_di.di_nlink == ii->counted_links) return 0; ip->i_di.di_nlink = ii->counted_links; + bmodified(ip->i_bh); log_debug( _("Changing inode %llu (0x%llx) to have %u links\n"), (unsigned long long)ip->i_di.di_num.no_addr, @@ -43,14 +44,12 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { struct gfs2_inode *ip; int lf_addition = 0; struct gfs2_block_query q; - enum update_flags f; /* FIXME: should probably factor this out into a generic * scanning fxn */ osi_list_foreach(tmp, list) { if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return 0; - f = not_updated; if(!(ii = osi_list_entry(tmp, struct inode_info, list))) { log_crit( _("osi_list_foreach broken in scan_info_list!!\n")); exit(FSCK_ERROR); @@ -74,10 +73,11 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { _("Delete unlinked inode with bad blocks? (y/n) "))) { errors_corrected++; ip = fsck_load_inode(sbp, ii->inode); - check_inode_eattr(ip, &f, + check_inode_eattr(ip, &pass4_fxns_delete); check_metatree(ip, &pass4_fxns_delete); - fsck_inode_put(ip, updated); + bmodified(ip->i_bh); + fsck_inode_put(ip); gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); continue; @@ -97,17 +97,17 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { ip = fsck_load_inode(sbp, ii->inode); if(query(&opts, _("Delete unlinked inode " "? (y/n) "))) { - check_inode_eattr(ip, &f, + check_inode_eattr(ip, &pass4_fxns_delete); check_metatree(ip, &pass4_fxns_delete); - fsck_inode_put(ip, updated); + bmodified(ip->i_bh); gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); log_err( _("The inode was deleted\n")); } else { log_err( _("The inode was not " "deleted\n")); - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); } continue; } @@ -123,7 +123,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { errors_corrected++; gfs2_block_set(sbp, bl, ii->inode, gfs2_block_free); - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); continue; } @@ -131,10 +131,10 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { errors_found++; if(query(&opts, _("Add unlinked inode to lost+found? (y/n)"))) { errors_corrected++; - f = updated; + bmodified(ip->i_bh); if(add_inode_to_lf(ip)) { stack; - fsck_inode_put(ip, not_updated); + fsck_inode_put(ip); return -1; } else { @@ -143,7 +143,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { } } else log_err( _("Unlinked inode left unlinked\n")); - fsck_inode_put(ip, f); + fsck_inode_put(ip); } /* if(ii->counted_links == 0) */ else if(ii->link_count != ii->counted_links) { log_err( _("Link count inconsistent for inode %" PRIu64 @@ -157,7 +157,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { errors_corrected++; ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */ fix_inode_count(sbp, ii, ip); - fsck_inode_put(ip, updated); /* out, brelse, free */ + bmodified(ip->i_bh); + fsck_inode_put(ip); /* out, brelse, free */ log_warn( _("Link count updated for inode %" PRIu64 " (0x%" PRIx64 ") \n"), ii->inode, ii->inode); } else { diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index fd09562..0479301 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -148,9 +148,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b return 0; } -static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, - uint32_t *count, struct gfs2_buffer_head **rgbh, - struct gfs2_rgrp *rg) +static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp, + uint32_t *count, struct gfs2_buffer_head **rgbh, + struct gfs2_rgrp *rg) { uint32_t i; struct gfs2_bitmap *bits; @@ -164,7 +164,7 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp check_block_status(sbp, rgbh[i]->b_data + bits->bi_offset, bits->bi_len, &rg_block, rgp->ri.ri_data0, count); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; + return; } /* actually adjust counters and write out to disk */ @@ -197,11 +197,9 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp log_warn( _("Resource group counts updated\n")); /* write out the rgrp */ gfs2_rgrp_out(rg, rgbh[0]->b_data); - return updated; } else log_err( _("Resource group counts left inconsistent\n")); } - return not_updated; } /** @@ -221,8 +219,6 @@ int pass5(struct gfs2_sbd *sbp) /* Reconcile RG bitmaps with fsck bitmap */ for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){ - enum update_flags f; - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count); @@ -245,8 +241,8 @@ int pass5(struct gfs2_sbd *sbp) } rg_count++; /* Compare the bitmaps and report the differences */ - f = update_rgrp(sbp, rgd, count, rgbh, &rg); - gfs2_rgrp_relse(rgd, f, rgbh); + update_rgrp(sbp, rgd, count, rgbh, &rg); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); } /* Fix up superblock info based on this - don't think there's diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index a4c8cf7..169cf19 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -51,8 +51,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp) ip = sdp->md.journal[j]; jblocks = ip->i_di.di_size / sdp->sd_sb.sb_bsize; for (b = 0; b < jblocks; b++) { - block_map(ip, b, &new, &dblock, &extlen, 0, - not_updated); + block_map(ip, b, &new, &dblock, &extlen, 0); if (!dblock) break; bh = bread(&sdp->buf_list, dblock); @@ -61,7 +60,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp) "0x%" PRIx64 "\n"), dblock); gfs2_special_set(&false_rgrps, dblock); } - brelse(bh, not_updated); + brelse(bh); } } } @@ -163,7 +162,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, number_of_rgs++; blk += 250; /* skip ahead for performance */ } - brelse(bh, not_updated); + brelse(bh); } number_of_rgs = 0; gfs2_special_free(&false_rgrps); @@ -209,7 +208,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, log_debug( _("Block 0x%" PRIx64 "\n"), blk); bh = bread(&sdp->buf_list, blk); rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG)); - brelse(bh, not_updated); + brelse(bh); /* Allocate a new RG and index. */ calc_rgd = malloc(sizeof(struct rgrp_list)); if (!calc_rgd) { @@ -244,7 +243,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, bh = bread(&sdp->buf_list, fwd_block); bitmap_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RB)); - brelse(bh, not_updated); + brelse(bh); if (bitmap_was_fnd) /* if a bitmap */ calc_rgd->ri.ri_length++; else @@ -405,7 +404,8 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd, rg->rg_free = rgd->ri.ri_data; gfs2_rgrp_out(rg, rgbh[x]->b_data); } - brelse(rgbh[x], updated); + bmodified(rgbh[x]); + brelse(rgbh[x]); return 0; } return 1; @@ -584,7 +584,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count) &rgrp); } else { - gfs2_rgrp_relse(rgd, not_updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); break; } diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c index a12c19c..8997503 100644 --- a/gfs2/libgfs2/buf.c +++ b/gfs2/libgfs2/buf.c @@ -176,12 +176,15 @@ struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh) return bh; } -void brelse(struct gfs2_buffer_head *bh, enum update_flags is_updated) +void bmodified(struct gfs2_buffer_head *bh) +{ + bh->b_changed = 1; +} + +void brelse(struct gfs2_buffer_head *bh) { /* We can't just say b_changed = updated because we don't want to */ /* set it FALSE if it's TRUE until we write the changed data to disk. */ - if (is_updated) - bh->b_changed = TRUE; if (!bh->b_count) { fprintf(stderr, "buffer count underflow for block %" PRIu64 " (0x%" PRIx64")\n", bh->b_blocknr, bh->b_blocknr); diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c index 1f197b1..7c874ad 100644 --- a/gfs2/libgfs2/fs_bits.c +++ b/gfs2/libgfs2/fs_bits.c @@ -154,7 +154,8 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state) *byte ^= cur_state << bit; *byte |= state << bit; - gfs2_rgrp_relse(rgd, updated, rgbh); + bmodified(rgbh[buf]); + gfs2_rgrp_relse(rgd, rgbh); free(rgbh); return 0; } @@ -217,7 +218,7 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, } if(i >= rgd->ri.ri_length){ - gfs2_rgrp_relse(rgd, not_updated, rgbh); + gfs2_rgrp_relse(rgd, rgbh); return -1; } @@ -227,7 +228,6 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, val = ((*byte >> bit) & GFS2_BIT_MASK); if(local_rgd) - gfs2_rgrp_relse(rgd, not_updated, rgbh); - + gfs2_rgrp_relse(rgd, rgbh); return val; } diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c index dfdd7e7..f666459 100644 --- a/gfs2/libgfs2/fs_geometry.c +++ b/gfs2/libgfs2/fs_geometry.c @@ -220,7 +220,8 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write) gfs2_meta_header_out(&mh, bh->b_data); else gfs2_rgrp_out(&rg, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } } diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c index 7c44a8c..cef5d21 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -43,11 +43,11 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh) return ip; } -void inode_put(struct gfs2_inode *ip, enum update_flags is_updated) +void inode_put(struct gfs2_inode *ip) { - if (is_updated) + if (ip->i_bh->b_changed) gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data); - brelse(ip->i_bh, is_updated); + brelse(ip->i_bh); free(ip); } @@ -100,7 +100,7 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type) bn++; } - brelse(rgbh[block], FALSE); + brelse(rgbh[block]); } die("allocation is broken (1): %"PRIu64" %u\n", @@ -130,11 +130,13 @@ found: rg.rg_free--; rl->rg_free--; - brelse(rgbh[block], updated); + bmodified(rgbh[block]); + brelse(rgbh[block]); rgbh[0] = bread(&sdp->buf_list, ri->ri_addr); gfs2_rgrp_out(&rg, rgbh[0]->b_data); - brelse(rgbh[0], updated); + bmodified(rgbh[0]); + brelse(rgbh[0]); sdp->blks_alloced++; free(rgbh); @@ -167,6 +169,7 @@ static __inline__ void buffer_clear_tail(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, int head) { memset(bh->b_data + head, 0, sdp->bsize - head); + bmodified(bh); } static __inline__ void @@ -178,6 +181,7 @@ buffer_copy_tail(struct gfs2_sbd *sdp, sdp->bsize - from_head); memset(to_bh->b_data + sdp->bsize + to_head - from_head, 0, from_head - to_head); + bmodified(to_bh); } void unstuff_dinode(struct gfs2_inode *ip) @@ -203,7 +207,8 @@ void unstuff_dinode(struct gfs2_inode *ip) sizeof(struct gfs2_meta_header), ip->i_bh, sizeof(struct gfs2_dinode)); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } else { block = data_alloc(ip); bh = bget(&sdp->buf_list, block); @@ -211,7 +216,8 @@ void unstuff_dinode(struct gfs2_inode *ip) buffer_copy_tail(sdp, bh, 0, ip->i_bh, sizeof(struct gfs2_dinode)); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } } @@ -280,7 +286,8 @@ void build_height(struct gfs2_inode *ip, int height) sizeof(struct gfs2_meta_header), ip->i_bh, sizeof(struct gfs2_dinode)); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } buffer_clear_tail(sdp, ip->i_bh, sizeof(struct gfs2_dinode)); @@ -337,14 +344,14 @@ void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, *block = meta_alloc(ip); *ptr = cpu_to_be64(*block); + bmodified(bh); ip->i_di.di_blocks++; *new = 1; } void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen, int prealloc, - enum update_flags if_changed) + uint64_t *dblock, uint32_t *extlen, int prealloc) { struct gfs2_sbd *sdp = ip->i_sbd; struct gfs2_buffer_head *bh; @@ -386,7 +393,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, for (x = 0; x < end_of_metadata; x++) { lookup_block(ip, bh, x, mp, create, new, dblock); - brelse(bh, if_changed); + brelse(bh); if (!*dblock) goto out; @@ -396,6 +403,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; + bmodified(bh); gfs2_meta_header_out(&mh, bh->b_data); } else bh = bread(&sdp->buf_list, *dblock); @@ -426,7 +434,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, } } - brelse(bh, if_changed); + brelse(bh); out: free(mp); @@ -489,7 +497,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf, if (!extlen) block_map(ip, lblock, ¬_new, &dblock, &extlen, - FALSE, not_updated); + FALSE); if (dblock) { bh = bread(&sdp->buf_list, dblock); @@ -500,7 +508,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf, copy2mem(bh, &buf, o, amount); if (bh) - brelse(bh, not_updated); + brelse(bh); copied += amount; lblock++; @@ -517,6 +525,7 @@ static void copy_from_mem(struct gfs2_buffer_head *bh, void **buf, char **p = (char **)buf; memcpy(bh->b_data + offset, *p, size); + bmodified(bh); *p += size; } @@ -562,8 +571,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, if (!extlen) { new = TRUE; - block_map(ip, lblock, &new, &dblock, &extlen, FALSE, - updated); + block_map(ip, lblock, &new, &dblock, &extlen, FALSE); } if (new) { @@ -578,7 +586,8 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf, } else bh = bread(&sdp->buf_list, dblock); copy_from_mem(bh, &buf, o, amount); - brelse(bh, updated); + bmodified(bh); + brelse(bh); copied += amount; lblock++; @@ -604,7 +613,7 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn, if (inode_is_stuffed(ip)) unstuff_dinode(ip); - block_map(ip, lbn, &new, &dbn, NULL, prealloc, updated); + block_map(ip, lbn, &new, &dbn, NULL, prealloc); if (!dbn) die("get_file_buf\n"); @@ -672,7 +681,7 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, if (!entries) { dent->de_rec_len = cpu_to_be16(dip->i_sbd->bsize - offset); dent->de_name_len = cpu_to_be16(name_len); - + bmodified(bh); *dent_out = dent; return 0; } @@ -701,12 +710,14 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, dent->de_rec_len = cpu_to_be16(cur_rec_len - new_rec_len); *dent_out = new; + bmodified(bh); return 0; } dent->de_name_len = cpu_to_be16(name_len); *dent_out = dent; + bmodified(bh); return 0; } } while (gfs2_dirent_next(dip, bh, &dent) == 0); @@ -719,6 +730,8 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, { uint16_t cur_rec_len, prev_rec_len; + bmodified(bh); + bmodified(dip->i_bh); if (dip->i_di.di_entries) dip->i_di.di_entries--; if (!prev) { @@ -861,8 +874,9 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea dip->i_di.di_blocks++; - brelse(obh, not_updated); - brelse(nbh, updated); + brelse(obh); + bmodified(nbh); + brelse(nbh); } static void dir_double_exhash(struct gfs2_inode *dip) @@ -926,7 +940,7 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no, return error; error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF); if(error) - brelse(*bhp, not_updated); + brelse(*bhp); return error; } @@ -998,18 +1012,18 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, if (dirent_alloc(dip, bh, len, &dent)) { if (be16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) { - brelse(bh, not_updated); + brelse(bh); dir_split_leaf(dip, lindex, leaf_no); goto restart; } else if (dip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) { - brelse(bh, not_updated); + brelse(bh); dir_double_exhash(dip); goto restart; } else if (leaf->lf_next) { leaf_no = be64_to_cpu(leaf->lf_next); - brelse(bh, not_updated); + brelse(bh); continue; } else { @@ -1031,7 +1045,8 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, dirent_alloc(dip, nbh, len, &dent); dip->i_di.di_blocks++; - brelse(bh, updated); + bmodified(bh); + brelse(bh); bh = nbh; leaf = nleaf; } @@ -1045,10 +1060,11 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len, leaf->lf_entries = be16_to_cpu(leaf->lf_entries) + 1; leaf->lf_entries = cpu_to_be16(leaf->lf_entries); - brelse(bh, updated); + bmodified(bh); + brelse(bh); dip->i_di.di_entries++; - + bmodified(dip->i_bh); return; } } @@ -1094,7 +1110,8 @@ static void dir_make_exhash(struct gfs2_inode *dip) dent->de_rec_len = cpu_to_be16(dent->de_rec_len + sizeof(struct gfs2_dinode) - sizeof(struct gfs2_leaf)); - brelse(bh, updated); + /* no need to: bmodified(bh); (buffer_copy_tail does it) */ + brelse(bh); buffer_clear_tail(sdp, dip->i_bh, sizeof(struct gfs2_dinode)); @@ -1107,6 +1124,7 @@ static void dir_make_exhash(struct gfs2_inode *dip) dip->i_di.di_blocks++; dip->i_di.di_flags |= GFS2_DIF_EXHASH; dip->i_di.di_payload_format = 0; + /* no need: bmodified(dip->i_bh); buffer_clear_tail does it. */ for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; dip->i_di.di_depth = y; @@ -1130,6 +1148,7 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len, memcpy((char *)(dent + 1), filename, len); dip->i_di.di_entries++; + bmodified(dip->i_bh); } void dir_add(struct gfs2_inode *dip, const char *filename, int len, @@ -1226,6 +1245,7 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename, bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num); ip = inode_get(sdp, bh); + bmodified(bh); } return ip; } @@ -1343,7 +1363,7 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename, /* Find the entry */ do{ if (bh) - brelse(bh, not_updated); + brelse(bh); bh = bh_next; @@ -1357,14 +1377,14 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename, break; default: - brelse(bh, not_updated); + brelse(bh); return error; } error = get_next_leaf(dip, bh, &bh_next); } while (!error); - brelse(bh, not_updated); + brelse(bh); return error; } @@ -1392,7 +1412,7 @@ static int dir_e_search(struct gfs2_inode *dip, const char *filename, if (type) *type = be16_to_cpu(dent->de_type); - brelse(bh, not_updated); + brelse(bh); return 0; } @@ -1423,7 +1443,7 @@ static int dir_l_search(struct gfs2_inode *dip, const char *filename, if(type) *type = be16_to_cpu(dent->de_type); } - brelse(dibh, not_updated); + brelse(dibh); return error; } @@ -1475,11 +1495,11 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len) error = leaf_search(dip, bh, filename, len, &cur, &prev); if (error) { if(error != -ENOENT){ - brelse(bh, updated); + brelse(bh); return -1; } leaf_no = be64_to_cpu(((struct gfs2_leaf *)bh->b_data)->lf_next); - brelse(bh, updated); + brelse(bh); } else found = 1; } @@ -1490,7 +1510,7 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len) if (bh) { dirent2_del(dip, bh, prev, cur); - brelse(bh, updated); + brelse(bh); } return 0; } @@ -1514,7 +1534,7 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh, error = leaf_search(dip, dibh, filename, len, &cur, &prev); if (error) { if (got_buf) - brelse(dibh, not_updated); + brelse(dibh); if (error == -ENOENT) return 1; else @@ -1522,8 +1542,10 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh, } dirent2_del(dip, dibh, prev, cur); - if (got_buf) - brelse(dibh, updated); + if (got_buf) { + bmodified(dibh); + brelse(dibh); + } return 0; } @@ -1550,7 +1572,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, error = dir_e_del(dip, filename, len); else error = dir_l_del(dip, bh, filename, len); - + bmodified(dip->i_bh); return error; } @@ -1605,7 +1627,8 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block) rg.rg_free++; /* adjust the free count */ rgd->rg_free++; gfs2_rgrp_out(&rg, bh->b_data); /* back to the buffer */ - brelse(bh, updated); /* release the buffer */ + bmodified(bh); + brelse(bh); /* release the buffer */ } /** @@ -1654,13 +1677,14 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) /* Read the next metadata block in the chain */ nbh = bread(&sdp->buf_list, block); osi_list_add(&nbh->b_altlist, next_list); - brelse(nbh, not_updated); + brelse(nbh); } } } /* Set the bitmap type for inode to free space: */ gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE); - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); /* Now we have to adjust the rg freespace count and inode count: */ rgd = gfs2_blk2rgrpd(sdp, diblock); bh = bread(&sdp->buf_list, rgd->ri.ri_addr); /* get the buffer */ @@ -1669,6 +1693,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) rgd->rg_free++; rg.rg_dinodes--; /* one less inode in use */ gfs2_rgrp_out(&rg, bh->b_data); - brelse(bh, updated); /* release the buffer */ + bmodified(bh); + brelse(bh); /* release the buffer */ return 0; } diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c index eb266a5..2b0dd8d 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -70,9 +70,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, unsigned int height; unsigned int end_of_metadata; unsigned int x; - enum update_flags f; - f = not_updated; *new = 0; *dblock = 0; if (extlen) @@ -104,7 +102,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, for (x = 0; x < end_of_metadata; x++) { gfs1_lookup_block(ip, bh, x, mp, create, new, dblock); - brelse(bh, f); + brelse(bh); if (!*dblock) goto out; @@ -116,10 +114,9 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; gfs2_meta_header_out(&mh, bh->b_data); - f = updated; + bmodified(bh); } else { bh = bread(&sdp->buf_list, *dblock); - f = not_updated; } } @@ -150,7 +147,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, } } - brelse(bh, f); + brelse(bh); out: free(mp); @@ -210,7 +207,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin, if (bh) { memcpy(buf+copied, bh->b_data + offset, amount); - brelse(bh, not_updated); + brelse(bh); } else memset(buf+copied, 0, amount); copied += amount; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 524c10b..0428481 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -271,20 +271,6 @@ struct metapath { #define META (2) #define DINODE (3) -#define NOT_UPDATED (0) -#define UPDATED (1) - -/* A bit of explanation is in order: */ -/* updated flag means the buffer was updated from THIS function before */ -/* brelse was called. */ -/* not_updated flag means the buffer may or may not have been updated */ -/* by a function called within this one, but it wasn't updated */ -/* by this function. */ -enum update_flags { - not_updated = NOT_UPDATED, - updated = UPDATED -}; - /* bitmap.c */ struct gfs2_bmap { uint64_t size; @@ -369,7 +355,8 @@ extern struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, extern struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, int line, const char *caller); extern struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh); -extern void brelse(struct gfs2_buffer_head *bh, enum update_flags is_updated); +extern void bmodified(struct gfs2_buffer_head *bh); +extern void brelse(struct gfs2_buffer_head *bh); extern void __bsync(struct buf_list *bl, int line, const char *caller); extern void __bcommit(struct buf_list *bl, int line, const char *caller); @@ -421,7 +408,7 @@ extern void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, int create, int *new, uint64_t *block); extern struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); -extern void inode_put(struct gfs2_inode *ip, enum update_flags updated); +extern void inode_put(struct gfs2_inode *ip); extern uint64_t data_alloc(struct gfs2_inode *ip); extern uint64_t meta_alloc(struct gfs2_inode *ip); extern uint64_t dinode_alloc(struct gfs2_sbd *sdp); @@ -447,8 +434,7 @@ extern void dir_add(struct gfs2_inode *dip, const char *filename, int len, extern int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, const char *filename, int filename_len); extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen, int prealloc, - enum update_flags if_changed); + uint64_t *dblock, uint32_t *extlen, int prealloc); extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index, uint64_t *leaf_out); extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out); @@ -651,8 +637,8 @@ extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk); extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd, struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg); -extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated, - struct gfs2_buffer_head **bh); +extern void gfs2_rgrp_relse(struct rgrp_list *rgd, + struct gfs2_buffer_head **bh); extern void gfs2_rgrp_free(osi_list_t *rglist); /* structures.c */ diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c index b10fe77..03c1703 100644 --- a/gfs2/libgfs2/recovery.c +++ b/gfs2/libgfs2/recovery.c @@ -27,7 +27,7 @@ int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk, uint64_t dblock; uint32_t extlen; - block_map(ip, blk, &new, &dblock, &extlen, FALSE, not_updated); + block_map(ip, blk, &new, &dblock, &extlen, FALSE); if (!dblock) return -EIO; @@ -67,7 +67,7 @@ int get_log_header(struct gfs2_inode *ip, unsigned int blk, hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); tmp->lh_hash = saved_hash; gfs2_log_header_in(&lh, bh->b_data); - brelse(bh, not_updated); + brelse(bh); if (error || lh.lh_blkno != blk || lh.lh_hash != hash) return 1; @@ -219,7 +219,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) lblock = head->lh_blkno; gfs2_replay_incr_blk(ip, &lblock); - block_map(ip, lblock, &new, &dblock, &extlen, 0, not_updated); + block_map(ip, lblock, &new, &dblock, &extlen, 0); if (!dblock) return -EIO; @@ -236,8 +236,8 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) lh->lh_blkno = cpu_to_be32(lblock); hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header)); lh->lh_hash = cpu_to_be32(hash); - - brelse(bh, updated); + bmodified(bh); + brelse(bh); return 0; } diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index 21c7033..1e10200 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -120,7 +120,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd, error = rgd->ri.ri_addr + x; for (; x >= 0; x--) - brelse(bh[x], not_updated); + brelse(bh[x]); return error; } } @@ -130,13 +130,12 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd, return 0; } -void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated, - struct gfs2_buffer_head **bh) +void gfs2_rgrp_relse(struct rgrp_list *rgd, struct gfs2_buffer_head **bh) { int x, length = rgd->ri.ri_length; for (x = 0; x < length; x++) - brelse(bh[x], is_updated); + brelse(bh[x]); } void gfs2_rgrp_free(osi_list_t *rglist) diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c index 97c56b8..02a512e 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -43,7 +43,8 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) for (x = 0; x < sdp->sb_addr; x++) { bh = bget(&sdp->buf_list, x); memset(bh->b_data, 0, sdp->bsize); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } memset(&sb, 0, sizeof(struct gfs2_sb)); @@ -63,7 +64,8 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) #endif bh = bget(&sdp->buf_list, sdp->sb_addr); gfs2_sb_out(&sb, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); if (sdp->debug) { printf("\nSuper Block:\n"); @@ -95,7 +97,8 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j, struct gfs2_buffer_head *bh = get_file_buf(ip, x, TRUE); if (!bh) return -1; - brelse(bh, updated); + bmodified(bh); + brelse(bh); } for (x = 0; x < blocks; x++) { struct gfs2_buffer_head *bh = get_file_buf(ip, x, FALSE); @@ -108,7 +111,8 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j, hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); ((struct gfs2_log_header *)bh->b_data)->lh_hash = cpu_to_be32(hash); - brelse(bh, updated); + bmodified(bh); + brelse(bh); if (++seq == blocks) seq = 0; @@ -140,7 +144,8 @@ int build_jindex(struct gfs2_sbd *sdp) sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift); if (ret) return ret; - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); } if (sdp->debug) { @@ -148,7 +153,8 @@ int build_jindex(struct gfs2_sbd *sdp) gfs2_dinode_print(&jindex->i_di); } - inode_put(jindex, updated); + bmodified(jindex->i_bh); + inode_put(jindex); return 0; } @@ -168,7 +174,8 @@ static int build_inum_range(struct gfs2_inode *per_node, unsigned int j) gfs2_dinode_print(&ip->i_di); } - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); return 0; } @@ -188,7 +195,8 @@ static void build_statfs_change(struct gfs2_inode *per_node, unsigned int j) gfs2_dinode_print(&ip->i_di); } - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); } static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) @@ -216,7 +224,8 @@ static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) gfs2_meta_header_out(&mh, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); } if (sdp->debug) { @@ -224,7 +233,8 @@ static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) gfs2_dinode_print(&ip->i_di); } - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); return 0; } @@ -247,7 +257,8 @@ int build_per_node(struct gfs2_sbd *sdp) gfs2_dinode_print(&per_node->i_di); } - inode_put(per_node, updated); + bmodified(per_node->i_bh); + inode_put(per_node); return 0; } @@ -313,7 +324,8 @@ int build_rindex(struct gfs2_sbd *sdp) gfs2_dinode_print(&ip->i_di); } - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); return 0; } @@ -344,7 +356,8 @@ int build_quota(struct gfs2_sbd *sdp) gfs2_quota_print(&qu); } - inode_put(ip, updated); + bmodified(ip->i_bh); + inode_put(ip); return 0; } @@ -468,11 +481,11 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd, GFS2_BLKST_DINODE); if(blk != BFITNOENT){ *block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0; - brelse(bh, not_updated); + brelse(bh); break; } blk=0; - brelse(bh, not_updated); + brelse(bh); } if(i == length) return -1; @@ -495,12 +508,12 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, do{ if (bh) - brelse(bh, not_updated); + brelse(bh); if (gfs2_next_rg_meta(sdp, rgd, block, first)) return -1; bh = bread(&sdp->buf_list, *block); first = 0; } while(gfs2_check_meta(bh, type)); - brelse(bh, not_updated); + brelse(bh); return 0; } diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 7aeeaa7..67eb77a 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -60,7 +60,7 @@ int read_sb(struct gfs2_sbd *sdp) bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); gfs2_sb_in(&sdp->sd_sb, bh->b_data); - brelse(bh, not_updated); + brelse(bh); error = check_sb(&sdp->sd_sb); if (error) @@ -248,16 +248,13 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount) } for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) { - enum update_flags f; - - f = not_updated; rgd = osi_list_entry(tmp, struct rgrp_list, list); errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg); if (errblock) { free(rgbh); return errblock; } else - gfs2_rgrp_relse(rgd, f, rgbh); + gfs2_rgrp_relse(rgd, rgbh); count2++; } @@ -280,7 +277,8 @@ int write_sb(struct gfs2_sbd *sbp) bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); gfs2_sb_out(&sbp->sd_sb, bh->b_data); - brelse(bh, updated); + bmodified(bh); + brelse(bh); bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */ return 0; } diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c index 10d9731..52b8c38 100644 --- a/gfs2/mkfs/main_grow.c +++ b/gfs2/mkfs/main_grow.c @@ -170,8 +170,8 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count) /* Note: We do inode_put with not_updated because we only updated */ /* the new RGs/bitmaps themselves on disk. The rindex file must */ /* be updated through the meta_fs so the gfs2 kernel is informed. */ - inode_put(sdp->md.riinode, not_updated); - inode_put(sdp->master_dir, not_updated); + inode_put(sdp->md.riinode); + inode_put(sdp->master_dir); /* We're done with the libgfs portion, so commit it to disk. */ bsync(&sdp->buf_list); diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index cb6a3cc..6ebaa99 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -637,10 +637,14 @@ void main_mkfs(int argc, char *argv[]) /* Cleanup */ - inode_put(sdp->md.rooti, updated); - inode_put(sdp->master_dir, updated); - inode_put(sdp->md.inum, updated); - inode_put(sdp->md.statfs, updated); + bmodified(sdp->md.rooti->i_bh); + inode_put(sdp->md.rooti); + bmodified(sdp->master_dir->i_bh); + inode_put(sdp->master_dir); + bmodified(sdp->md.inum->i_bh); + inode_put(sdp->md.inum); + bmodified(sdp->md.statfs->i_bh); + inode_put(sdp->md.statfs); bsync(&sdp->buf_list); error = fsync(sdp->device_fd);
1
0
0
0
cluster: STABLE3 - Separate eattr_block list from the rest for efficiency
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=7e…
Commit: 7ea0206f2410a56993f6019b9065db95d15a9396 Parent: bbfbde76dde0ce9a504015ac07dc483f4e1fdc32 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Wed Nov 25 14:36:14 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 Separate eattr_block list from the rest for efficiency There were only a few rare places where the eattr special list was being used in fsck.gfs2. By moving those places outside the general bitmap functions the general case is faster. rhbz#455300 --- gfs2/fsck/pass1.c | 5 ++--- gfs2/fsck/pass1c.c | 2 +- gfs2/fsck/pass5.c | 4 ---- gfs2/libgfs2/block_list.c | 33 +++++++++------------------------ gfs2/libgfs2/libgfs2.h | 4 ++-- 5 files changed, 14 insertions(+), 34 deletions(-) diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index 7a59e13..139daa8 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -391,8 +391,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, (unsigned long long)ip->i_di.di_num.no_addr); /* Mark the inode as having an eattr in the block map so pass1c can check it. */ - gfs2_block_mark(ip->i_sbd, bl, ip->i_di.di_num.no_addr, - gfs2_eattr_block); + gfs2_special_set(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr); if (!leaf_pointer_errors) return 0; log_err( _("Inode %lld (0x%llx) has recoverable indirect " @@ -530,7 +529,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, "block(s) attached.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - gfs2_block_mark(sdp, bl, ip->i_di.di_num.no_addr, gfs2_eattr_block); + gfs2_special_set(&sdp->eattr_blocks, ip->i_di.di_num.no_addr); if(gfs2_check_range(sdp, block)) { log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf " "block #%llu (0x%llx) is out of range.\n"), diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index 62026f6..c8b05b1 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -264,7 +264,7 @@ int pass1c(struct gfs2_sbd *sbp) if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */ log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"), block_no, block_no); - gfs2_block_unmark(sbp, bl, block_no, gfs2_eattr_block); + gfs2_special_clear(&sbp->eattr_blocks, block_no); ip = fsck_inode_get(sbp, bh); log_debug( _("Found eattr at %llu (0x%llx)\n"), diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index 925e8cc..fd09562 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -12,10 +12,6 @@ static int convert_mark(struct gfs2_block_query *q, uint32_t *count) { - if (q->eattr_block) { - count[2]++; - return GFS2_BLKST_USED; - } switch(q->block_type) { case gfs2_meta_inval: diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c index e5e6962..569c1e2 100644 --- a/gfs2/libgfs2/block_list.c +++ b/gfs2/libgfs2/block_list.c @@ -179,22 +179,22 @@ static void gfs2_dup_set(struct dup_blocks *blocklist, uint64_t block) return; } -static void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block) +static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block) { - struct special_blocks *b; + struct dup_blocks *b; - b = blockfind(blocklist, block); + b = dupfind(blocklist, block); if (b) { osi_list_del(&b->list); free(b); } } -static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block) +void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block) { - struct dup_blocks *b; + struct special_blocks *b; - b = dupfind(blocklist, block); + b = blockfind(blocklist, block); if (b) { osi_list_del(&b->list); free(b); @@ -208,8 +208,6 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, if(mark == gfs2_dup_block) gfs2_dup_set(&sdp->dup_blocks, block); - else if(mark == gfs2_eattr_block) - gfs2_special_set(&sdp->eattr_blocks, block); else err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]); return err; @@ -221,18 +219,10 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, { int err = 0; - switch (mark) { - case gfs2_dup_block: + if (mark == gfs2_dup_block) gfs2_dup_clear(&sdp->dup_blocks, block); - break; - case gfs2_eattr_block: - gfs2_special_clear(&sdp->eattr_blocks, block); - break; - default: - /* FIXME: check types */ + else err = gfs2_bitmap_clear(il, block); - break; - } return err; } @@ -240,12 +230,8 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block) { - int err; - gfs2_dup_clear(&sdp->dup_blocks, block); - gfs2_special_clear(&sdp->eattr_blocks, block); - err = gfs2_bitmap_clear(il, block); - return err; + return gfs2_bitmap_clear(il, block); } int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il, @@ -269,7 +255,6 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il, return -1; val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0); - val->eattr_block = (blockfind(&sdp->eattr_blocks, block) ? 1 : 0); byte = il->map + BITMAP_SIZE4(block); b = BITMAP_BYTE_OFFSET4(block); val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 27035e8..524c10b 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -329,13 +329,11 @@ enum gfs2_mark_block { gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */ gfs2_meta_inval = INVALID_META, gfs2_dup_block, /* Contains at least one duplicate block */ - gfs2_eattr_block, /* Contains an eattr */ }; struct gfs2_block_query { uint8_t block_type; uint8_t dup_block; - uint8_t eattr_block; }; extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size, @@ -347,6 +345,8 @@ extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block mark); extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block mark); +extern void gfs2_special_clear(struct special_blocks *blocklist, + uint64_t block); /* gfs2_block_unmark clears ONE mark for the given block */ extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block m);
1
0
0
0
cluster: STABLE3 - Misc blocklist optimizations
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=bb…
Commit: bbfbde76dde0ce9a504015ac07dc483f4e1fdc32 Parent: b7d8ec76e2dc8d5ccfbab2bb74319ee966d51da8 Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Wed Nov 25 14:35:29 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 Misc blocklist optimizations rhbz#455300 --- gfs2/fsck/fsck.h | 1 - gfs2/fsck/metawalk.c | 3 ++- gfs2/libgfs2/block_list.c | 37 ++++++++++++------------------------- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index 0431e4b..dae785c 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -59,7 +59,6 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */ gfs2_grow or something. Count the RGs by hand. */ }; -struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block); struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block); struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c index b60b8ca..8db0274 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -14,7 +14,8 @@ #include "metawalk.h" #include "hash.h" -struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block) +static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, + uint64_t block) { int j; diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c index 6af4f38..e5e6962 100644 --- a/gfs2/libgfs2/block_list.c +++ b/gfs2/libgfs2/block_list.c @@ -13,7 +13,7 @@ static int mark_to_gbmap[16] = { FREE, BLOCK_IN_USE, DIR_INDIR_BLK, DIR_INODE, FILE_INODE, LNK_INODE, BLK_INODE, CHR_INODE, FIFO_INODE, SOCK_INODE, DIR_LEAF_INODE, JOURNAL_BLK, OTHER_META, EATTR_META, - INVALID_META, INVALID_META + BAD_BLOCK, INVALID_META }; #define BITMAP_SIZE4(size) (size >> 1) @@ -52,20 +52,6 @@ static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val) return -1; } -static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val) -{ - static char *byte; - static uint64_t b; - - if(bit < bmap->size) { - byte = bmap->map + BITMAP_SIZE4(bit); - b = BITMAP_BYTE_OFFSET4(bit); - *val = (*byte & (BITMAP_MASK4 << b )) >> b; - return 0; - } - return -1; -} - static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset) { static char *byte; @@ -254,7 +240,7 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block) { - int err = 0; + int err; gfs2_dup_clear(&sdp->dup_blocks, block); gfs2_special_clear(&sdp->eattr_blocks, block); @@ -276,16 +262,17 @@ int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il, int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, struct gfs2_block_query *val) { - int err = 0; + static char *byte; + static uint64_t b; + + if(block >= il->size) + return -1; - val->dup_block = 0; - val->eattr_block = 0; - if (dupfind(&sdp->dup_blocks, block)) - val->dup_block = 1; - if (blockfind(&sdp->eattr_blocks, block)) - val->eattr_block = 1; - if((err = gfs2_bitmap_get(il, block, &val->block_type))) - return err; + val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0); + val->eattr_block = (blockfind(&sdp->eattr_blocks, block) ? 1 : 0); + byte = il->map + BITMAP_SIZE4(block); + b = BITMAP_BYTE_OFFSET4(block); + val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b; return 0; }
1
0
0
0
cluster: STABLE3 - Streamline the bitmap code by always using 4-bit size per block
by Bob Peterson
26 Jan '10
26 Jan '10
Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=b7…
Commit: b7d8ec76e2dc8d5ccfbab2bb74319ee966d51da8 Parent: c779e31178fa82f5b7d2e7f80e871dadfac0bb1b Author: Bob Peterson <bob(a)ganesha.peterson> AuthorDate: Wed Nov 25 14:34:55 2009 -0600 Committer: Bob Peterson <rpeterso(a)redhat.com> CommitterDate: Tue Jan 26 14:39:27 2010 -0600 Streamline the bitmap code by always using 4-bit size per block The block_map code was always using four bits to represent blocks in the bitmap. Therefore, it didn't need all the logic to handle bitmaps with one bit per block. This should improve performance. rhbz#455300 --- gfs2/libgfs2/block_list.c | 85 +++++++-------------------------------------- gfs2/libgfs2/libgfs2.h | 2 - 2 files changed, 13 insertions(+), 74 deletions(-) diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c index 65df23f..6af4f38 100644 --- a/gfs2/libgfs2/block_list.c +++ b/gfs2/libgfs2/block_list.c @@ -16,56 +16,17 @@ static int mark_to_gbmap[16] = { INVALID_META, INVALID_META }; -#define BITMAP_SIZE(size, cpb) (size / cpb) -#define BITMAP_SIZE1(size) (size >> 3) #define BITMAP_SIZE4(size) (size >> 1) - -#define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \ - * map->chunksize ) - -/* BITMAP_BYTE_OFFSET1 is for chunksize==1, which implies chunks_per_byte==8 */ -/* Reducing the math, we get: */ -/* #define BITMAP_BYTE_OFFSET1(x) ((x % 8) * 1) */ -/* #define BITMAP_BYTE_OFFSET1(x) (x % 8) */ -/* #define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) */ -#define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) - -/* BITMAP_BYTE_OFFSET4 is for chunksize==4, which implies chunks_per_byte==2 */ -/* Reducing the math, we get: */ -/* #define BITMAP_BYTE_OFFSET4(x) ((x % 2) * 4) */ -/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) * 4) */ -/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) */ #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) +#define BITMAP_MASK4 (0xf) -#define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1) -/* BITMAP_MASK1 is for chunksize==1 */ -/* Reducing the math, we get: */ -/* #define BITMAP_MASK1(chunksize) ((2 << (1 - 1)) - 1) */ -/* #define BITMAP_MASK1(chunksize) ((2 << 0) - 1) */ -/* #define BITMAP_MASK1(chunksize) ((2) - 1) */ -#define BITMAP_MASK1(chunksize) (1) - -/* BITMAP_MASK4 is for chunksize==4 */ -/* #define BITMAP_MASK(chunksize) ((2 << (4 - 1)) - 1) */ -/* #define BITMAP_MASK(chunksize) ((2 << 3) - 1) */ -/* #define BITMAP_MASK(chunksize) (0x10 - 1) */ -#define BITMAP_MASK4(chunksize) (0xf) - -static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size, - uint8_t chunksize) +static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size) { - if((((chunksize >> 1) << 1) != chunksize) && chunksize != 1) - return -1; - if(chunksize > 8) - return -1; - bmap->chunksize = chunksize; - bmap->chunks_per_byte = 8 / chunksize; - bmap->size = size; /* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs * must be 1-based */ - bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1; + bmap->mapsize = BITMAP_SIZE4(size); if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize))) return -ENOMEM; @@ -83,15 +44,9 @@ static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val) static uint64_t b; if(offset < bmap->size) { - if (bmap->chunksize == 1) { - byte = bmap->map + BITMAP_SIZE1(offset); - b = BITMAP_BYTE_OFFSET1(offset); - *byte |= (val & BITMAP_MASK1(bmap->chunksize)); - } else { - byte = bmap->map + BITMAP_SIZE4(offset); - b = BITMAP_BYTE_OFFSET4(offset); - *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b; - } + byte = bmap->map + BITMAP_SIZE4(offset); + b = BITMAP_BYTE_OFFSET4(offset); + *byte |= (val & BITMAP_MASK4) << b; return 0; } return -1; @@ -103,15 +58,9 @@ static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val) static uint64_t b; if(bit < bmap->size) { - if (bmap->chunksize == 1) { - byte = bmap->map + BITMAP_SIZE1(bit); - b = BITMAP_BYTE_OFFSET1(bit); - *val = (*byte & (BITMAP_MASK1(bmap->chunksize) << b )) >> b; - } else { - byte = bmap->map + BITMAP_SIZE4(bit); - b = BITMAP_BYTE_OFFSET4(bit); - *val = (*byte & (BITMAP_MASK4(bmap->chunksize) << b )) >> b; - } + byte = bmap->map + BITMAP_SIZE4(bit); + b = BITMAP_BYTE_OFFSET4(bit); + *val = (*byte & (BITMAP_MASK4 << b )) >> b; return 0; } return -1; @@ -123,15 +72,9 @@ static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset) static uint64_t b; if(offset < bmap->size) { - if (bmap->chunksize == 1) { - byte = bmap->map + BITMAP_SIZE1(offset); - b = BITMAP_BYTE_OFFSET1(offset); - *byte &= ~(BITMAP_MASK1(bmap->chunksize) << b); - } else { - byte = bmap->map + BITMAP_SIZE4(offset); - b = BITMAP_BYTE_OFFSET4(offset); - *byte &= ~(BITMAP_MASK4(bmap->chunksize) << b); - } + byte = bmap->map + BITMAP_SIZE4(offset); + b = BITMAP_BYTE_OFFSET4(offset); + *byte &= ~(BITMAP_MASK4 << b); return 0; } return -1; @@ -144,8 +87,6 @@ static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap) free(bmap->map); bmap->size = 0; bmap->mapsize = 0; - bmap->chunksize = 0; - bmap->chunks_per_byte = 0; } struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size, @@ -158,7 +99,7 @@ struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size, if (!il || !memset(il, 0, sizeof(*il))) return NULL; - if(gfs2_bitmap_create(il, size, 4)) { + if(gfs2_bitmap_create(il, size)) { *addl_mem_needed = il->mapsize; free(il); il = NULL; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 38100d3..27035e8 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -289,8 +289,6 @@ enum update_flags { struct gfs2_bmap { uint64_t size; uint64_t mapsize; - int chunksize; - int chunks_per_byte; char *map; };
1
0
0
0
← Newer
1
2
3
4
5
6
7
8
9
...
19
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Results per page:
10
25
50
100
200