[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Cluster-devel] [PATCH] libgfs2: Remove gfs2_next_rg_meta



Hi,

Looks good. Also possibly an opportunity to add readahead to the
savemeta thing?

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 <anprice redhat com>
> ---
>  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;
> -}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]