From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Mon, 11 Mar 2013 16:09:34 +0000 Subject: [Cluster-devel] [PATCH] libgfs2: Remove gfs2_next_rg_meta In-Reply-To: <1363017038.2698.24.camel@menhir> References: <1363015543-9094-1-git-send-email-anprice@redhat.com> <1363017038.2698.24.camel@menhir> Message-ID: <513E01BE.5090906@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On 11/03/13 15:50, Steven Whitehouse wrote: > Hi, > > Looks good. Also possibly an opportunity to add readahead to the > savemeta thing? Sure, sounds like a good plan. I'll give it a shot in a separate patch. Andy > Steve. > > On Mon, 2013-03-11 at 15:25 +0000, Andrew Price wrote: >> This removes gfs2_next_rg_meta and gfs2_next_rg_metatype from libgfs2 >> and switches gfs2_edit to use lgfs2_bm_scan. The functions are pushed >> into gfs2_convert rather switching it to lgfs2_bm_scan to provide >> identical functionality in the absence of a gfs1 fs to test it with. >> >> Signed-off-by: Andrew Price >> --- >> gfs2/convert/gfs2_convert.c | 52 ++++++++++++++++++++++++++++- >> gfs2/edit/hexedit.c | 54 ++++++++++++++++++++---------- >> gfs2/edit/savemeta.c | 80 +++++++++++++++------------------------------ >> gfs2/libgfs2/libgfs2.h | 5 --- >> gfs2/libgfs2/structures.c | 76 ------------------------------------------ >> 5 files changed, 113 insertions(+), 154 deletions(-) >> >> diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c >> index 235c95c..d286512 100644 >> --- a/gfs2/convert/gfs2_convert.c >> +++ b/gfs2/convert/gfs2_convert.c >> @@ -999,6 +999,56 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh) >> return 0; >> } /* adjust_inode */ >> >> +static int next_rg_meta(struct rgrp_tree *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; >> + >> + if (!first && (*block < rgd->ri.ri_data0)) { >> + fprintf(stderr, "next_rg_meta: Start block is outside rgrp bounds.\n"); >> + exit(1); >> + } >> + for (i = 0; i < length; i++){ >> + bits = &rgd->bits[i]; >> + if (blk < bits->bi_len * GFS2_NBBY) >> + break; >> + blk -= bits->bi_len * GFS2_NBBY; >> + } >> + for (; i < length; i++){ >> + bits = &rgd->bits[i]; >> + 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; >> + break; >> + } >> + blk = 0; >> + } >> + if (i == length) >> + return -1; >> + return 0; >> +} >> + >> +static int next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, >> + uint64_t *block, uint32_t type, int first) >> +{ >> + struct gfs2_buffer_head *bh = NULL; >> + >> + do{ >> + if (bh) >> + brelse(bh); >> + if (next_rg_meta(rgd, block, first)) >> + return -1; >> + bh = bread(sdp, *block); >> + first = 0; >> + } while(gfs2_check_meta(bh, type)); >> + brelse(bh); >> + return 0; >> +} >> + >> /* ------------------------------------------------------------------------- */ >> /* inode_renumber - renumber the inodes */ >> /* */ >> @@ -1046,7 +1096,7 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li >> /* be "11" (used meta) for both inodes and indirect blocks. */ >> /* We need to process the inodes and change the indirect blocks */ >> /* to have a bitmap type of "01" (data). */ >> - if (gfs2_next_rg_metatype(sbp, rgd, &block, 0, first)) >> + if (next_rg_metatype(sbp, rgd, &block, 0, first)) >> break; >> /* If this is the root inode block, remember it for later: */ >> if (block == root_inode_addr) { >> diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c >> index 4856181..281be5a 100644 >> --- a/gfs2/edit/hexedit.c >> +++ b/gfs2/edit/hexedit.c >> @@ -1569,6 +1569,31 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p >> return blk; >> } >> >> +static int find_rg_metatype(struct rgrp_tree *rgd, uint64_t *blk, uint64_t startblk, int mtype) >> +{ >> + int found; >> + unsigned i, j, m; >> + struct gfs2_buffer_head *bhp = NULL; >> + uint64_t *ibuf = malloc(sbd.bsize * GFS2_NBBY * sizeof(uint64_t)); >> + >> + for (i = 0; i < rgd->ri.ri_length; i++) { >> + m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE); >> + >> + for (j = 0; j < m; j++) { >> + *blk = ibuf[j]; >> + bhp = bread(&sbd, *blk); >> + found = (*blk > startblk) && !gfs2_check_meta(bhp, mtype); >> + brelse(bhp); >> + if (found) { >> + free(ibuf); >> + return 0; >> + } >> + } >> + } >> + free(ibuf); >> + return -1; >> +} >> + >> /* ------------------------------------------------------------------------ */ >> /* Find next "metadata in use" block AFTER a given point in the fs */ >> /* */ >> @@ -1578,7 +1603,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p >> /* ------------------------------------------------------------------------ */ >> static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int print) >> { >> - struct osi_node *n, *next = NULL; >> + struct osi_node *next = NULL; >> uint64_t blk, errblk; >> int first = 1, found = 0; >> struct rgrp_tree *rgd; >> @@ -1586,9 +1611,8 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri >> >> blk = 0; >> /* Skip the rgs prior to the block we've been given */ >> - for (n = osi_first(&sbd.rgtree); n; n = next) { >> - next = osi_next(n); >> - rgd = (struct rgrp_tree *)n; >> + for (next = osi_first(&sbd.rgtree); next; next = osi_next(next)) { >> + rgd = (struct rgrp_tree *)next; >> ri = &rgd->ri; >> if (first && startblk <= ri->ri_data0) { >> startblk = ri->ri_data0; >> @@ -1607,25 +1631,19 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri >> if (print) >> exit(-1); >> } >> - for (; !found && n; n = next){ >> - next = osi_next(n); >> - rgd = (struct rgrp_tree *)n; >> + for (; !found && next; next = osi_next(next)){ >> + rgd = (struct rgrp_tree *)next; >> errblk = gfs2_rgrp_read(&sbd, rgd); >> if (errblk) >> continue; >> - first = 1; >> - do { >> - if (gfs2_next_rg_metatype(&sbd, rgd, &blk, metatype, >> - first)) >> - break; >> - if (blk > startblk) { >> - found = 1; >> - break; >> - } >> - first = 0; >> - } while (blk <= startblk); >> + >> + found = !find_rg_metatype(rgd, &blk, startblk, metatype); >> + if (found) >> + break; >> + >> gfs2_rgrp_relse(rgd); >> } >> + >> if (!found) >> blk = 0; >> if (print) { >> diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c >> index cfe18eb..986fdbe 100644 >> --- a/gfs2/edit/savemeta.c >> +++ b/gfs2/edit/savemeta.c >> @@ -635,43 +635,34 @@ static void get_journal_inode_blocks(void) >> } >> } >> >> -static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, >> - uint64_t *nrfblock, int first) >> +static void save_allocated(struct rgrp_tree *rgd, struct metafd *mfd) >> { >> - struct gfs2_bitmap *bits = NULL; >> - 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 *lbh; >> + int blktype; >> + unsigned i, j, m; >> + uint64_t *ibuf = malloc(sbd.bsize * GFS2_NBBY * sizeof(uint64_t)); >> >> - if(!first && (*nrfblock < rgd->ri.ri_data0)) { >> - log_err("next_rg_freemeta: Start block is outside rgrp " >> - "bounds.\n"); >> - exit(1); >> - } >> - for(i=0; i < length; i++){ >> - bits = &rgd->bits[i]; >> - if(blk < bits->bi_len*GFS2_NBBY) >> - break; >> - blk -= bits->bi_len*GFS2_NBBY; >> - } >> - for(; i < length; i++){ >> - bits = &rgd->bits[i]; >> - 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); >> - if(blk != BFITNOENT){ >> - *nrfblock = blk + (bits->bi_start * GFS2_NBBY) + >> - rgd->ri.ri_data0; >> - break; >> + for (i = 0; i < rgd->ri.ri_length; i++) { >> + m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE); >> + >> + for (j = 0; j < m; j++) { >> + block = ibuf[j]; >> + warm_fuzzy_stuff(block, FALSE); >> + blktype = save_block(sbd.device_fd, mfd, block); >> + if (blktype == GFS2_METATYPE_DI) >> + save_inode_data(mfd); >> + } >> + >> + if (!sbd.gfs1) >> + continue; >> + >> + /* For gfs1, Save off the free/unlinked meta blocks too. >> + * If we don't, we may run into metadata allocation issues. */ >> + m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_UNLINKED); >> + for (j = 0; j < m; j++) { >> + blktype = save_block(sbd.device_fd, mfd, block); >> } >> - blk=0; >> } >> - if(i == length) >> - return -1; >> - return 0; >> + free(ibuf); >> } >> >> void savemeta(char *out_fn, int saveoption, int gziplevel) >> @@ -771,7 +762,6 @@ void savemeta(char *out_fn, int saveoption, int gziplevel) >> } >> /* Walk through the resource groups saving everything within */ >> for (n = osi_first(&sbd.rgtree); n; n = next) { >> - int first; >> struct rgrp_tree *rgd; >> >> next = osi_next(n); >> @@ -782,33 +772,15 @@ void savemeta(char *out_fn, int saveoption, int gziplevel) >> (unsigned long long)rgd->ri.ri_addr, >> (unsigned long long)rgd->ri.ri_addr, >> rgd->ri.ri_length); >> - first = 1; >> /* Save off the rg and bitmaps */ >> for (block = rgd->ri.ri_addr; >> block < rgd->ri.ri_data0; block++) { >> warm_fuzzy_stuff(block, FALSE); >> save_block(sbd.device_fd, &mfd, block); >> } >> - /* Save off the other metadata: inodes, etc. */ >> + /* Save off the other metadata: inodes, etc. if mode is not 'savergs' */ >> if (saveoption != 2) { >> - int blktype; >> - >> - while (!gfs2_next_rg_meta(rgd, &block, first)){ >> - warm_fuzzy_stuff(block, FALSE); >> - blktype = save_block(sbd.device_fd, &mfd, >> - block); >> - if (blktype == GFS2_METATYPE_DI) >> - save_inode_data(&mfd); >> - first = 0; >> - } >> - /* Save off the free/unlinked meta blocks too. >> - If we don't, we may run into metadata >> - allocation issues. */ >> - while (!next_rg_freemeta(&sbd, rgd, &block, first)) { >> - blktype = save_block(sbd.device_fd, >> - &mfd, block); >> - first = 0; >> - } >> + save_allocated(rgd, &mfd); >> } >> gfs2_rgrp_relse(rgd); >> } >> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h >> index 8dd8210..7d2d9ff 100644 >> --- a/gfs2/libgfs2/libgfs2.h >> +++ b/gfs2/libgfs2/libgfs2.h >> @@ -756,11 +756,6 @@ extern int do_init_statfs(struct gfs2_sbd *sdp); >> extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type); >> extern unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, >> uint64_t *buf, uint8_t state); >> -extern int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, >> - int first); >> -extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *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); >> diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c >> index c60f3e4..46fd8df 100644 >> --- a/gfs2/libgfs2/structures.c >> +++ b/gfs2/libgfs2/structures.c >> @@ -512,79 +512,3 @@ unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8 >> >> return n; >> } >> - >> -/** >> - * gfs2_next_rg_meta >> - * @rgd: >> - * @block: >> - * @first: if set, start at zero and ignore block >> - * >> - * The position to start looking from is *block. When a block >> - * is found, it is returned in block. >> - * >> - * Returns: 0 on success, -1 when finished >> - */ >> -static int __gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, >> - int first, unsigned char state) >> -{ >> - 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; >> - >> - if (!first && (*block < rgd->ri.ri_data0)) { >> - fprintf(stderr, "next_rg_meta: Start block is outside rgrp bounds.\n"); >> - exit(1); >> - } >> - for (i = 0; i < length; i++){ >> - bits = &rgd->bits[i]; >> - if (blk < bits->bi_len * GFS2_NBBY) >> - break; >> - blk -= bits->bi_len * GFS2_NBBY; >> - } >> - for (; i < length; i++){ >> - bits = &rgd->bits[i]; >> - blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data + >> - bits->bi_offset, bits->bi_len, blk, state); >> - if(blk != BFITNOENT){ >> - *block = blk + (bits->bi_start * GFS2_NBBY) + >> - rgd->ri.ri_data0; >> - break; >> - } >> - blk = 0; >> - } >> - if (i == length) >> - return -1; >> - return 0; >> -} >> - >> -int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first) >> -{ >> - return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_DINODE); >> -} >> - >> -/** >> - * next_rg_metatype >> - * @rgd: >> - * @block: >> - * @type: the type of metadata we're looking for >> - * @first: if set we should start at block zero and block is ignored >> - * >> - * Returns: 0 on success, -1 on error or finished >> - */ >> -int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, >> - uint64_t *block, uint32_t type, int first) >> -{ >> - struct gfs2_buffer_head *bh = NULL; >> - >> - do{ >> - if (bh) >> - brelse(bh); >> - if (gfs2_next_rg_meta(rgd, block, first)) >> - return -1; >> - bh = bread(sdp, *block); >> - first = 0; >> - } while(gfs2_check_meta(bh, type)); >> - brelse(bh); >> - return 0; >> -} > >