[Cluster-devel] [Patch 06/44] fsck.gfs2: Check for blocks wrongly inside resource groups

Steven Whitehouse swhiteho at redhat.com
Fri Aug 12 09:17:40 UTC 2011


Looks good,

Steve.

On Thu, 2011-08-11 at 17:00 -0400, Bob Peterson wrote:
> >From 7bb269a5158f81c6c5d9190c4f76d73a83e3c9d7 Mon Sep 17 00:00:00 2001
> From: Bob Peterson <rpeterso at redhat.com>
> Date: Mon, 8 Aug 2011 12:46:29 -0500
> Subject: [PATCH 06/44] fsck.gfs2: Check for blocks wrongly inside resource
>  groups
> 
> It's not enough to range_check blocks in order to call them valid.
> We also need to check whether those block collide with resource groups.
> We don't want a bitmap block to ever be referenced unless it's part of
> the rgrp and rindex functions.  This patch changes most of the fsck code
> from doing simple block range checks to doing range checks plus checks
> for blocks inside the resource groups.
> 
> rhbz#675723
> ---
>  gfs2/fsck/lost_n_found.c |    2 +-
>  gfs2/fsck/metawalk.c     |   20 +++++++-------
>  gfs2/fsck/pass1.c        |   66 +++++++++++++++++++++++----------------------
>  gfs2/fsck/pass1b.c       |    2 +-
>  gfs2/fsck/pass1c.c       |   10 +++---
>  gfs2/fsck/pass2.c        |    4 +-
>  gfs2/fsck/rgrepair.c     |    9 +++---
>  gfs2/fsck/util.c         |    2 +-
>  gfs2/libgfs2/fs_bits.c   |   19 ++++++++++++-
>  gfs2/libgfs2/libgfs2.h   |    1 +
>  10 files changed, 77 insertions(+), 58 deletions(-)
> 
> diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
> index 04aa90d..4eff83b 100644
> --- a/gfs2/fsck/lost_n_found.c
> +++ b/gfs2/fsck/lost_n_found.c
> @@ -104,7 +104,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
>  		/* If there's a pre-existing .. directory entry, we have to
>  		   back out the links. */
>  		di = dirtree_find(ip->i_di.di_num.no_addr);
> -		if (di && gfs2_check_range(sdp, di->dotdot_parent) == 0) {
> +		if (di && !valid_block(sdp, di->dotdot_parent) == 0) {
>  			struct gfs2_inode *dip;
>  
>  			log_debug(_("Directory %lld (0x%llx) already had a "
> diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
> index 3cee0fd..5d0afa5 100644
> --- a/gfs2/fsck/metawalk.c
> +++ b/gfs2/fsck/metawalk.c
> @@ -455,7 +455,7 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
>  	}
>  	if (*leaf_no == *bad_leaf ||
>  	    query( _("Attempt to patch around it? (y/n) "))) {
> -		if (gfs2_check_range(ip->i_sbd, old_leaf) == 0)
> +		if (!valid_block(ip->i_sbd, old_leaf) == 0)
>  			gfs2_put_leaf_nr(ip, pindex, old_leaf);
>  		else
>  			gfs2_put_leaf_nr(ip, pindex, first_ok_leaf);
> @@ -605,7 +605,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
>  	first_ok_leaf = leaf_no = -1;
>  	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
>  		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
> -		if (gfs2_check_range(ip->i_sbd, leaf_no) == 0) {
> +		if (!valid_block(ip->i_sbd, leaf_no) == 0) {
>  			lbh = bread(sdp, leaf_no);
>  			/* Make sure it's really a valid leaf block. */
>  			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
> @@ -644,7 +644,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
>  		}
>  
>  		do {
> -			if (gfs2_check_range(ip->i_sbd, old_leaf) == 0) {
> +			if (!valid_block(ip->i_sbd, old_leaf) == 0) {
>  				error = check_num_ptrs(ip, old_leaf,
>  						       &ref_count, &exp_count,
>  						       &lindex, &oldleaf);
> @@ -656,7 +656,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
>  			if (fsck_abort)
>  				break;
>  			/* Make sure the block number is in range. */
> -			if (gfs2_check_range(ip->i_sbd, leaf_no)){
> +			if (!valid_block(ip->i_sbd, leaf_no)){
>  				log_err( _("Leaf block #%llu (0x%llx) is out "
>  					"of range for directory #%llu (0x%llx"
>  					").\n"), (unsigned long long)leaf_no,
> @@ -909,7 +909,7 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
>  		 struct gfs2_buffer_head **bh, const char *btype,
>  		 void *private)
>  {
> -	if (gfs2_check_range(ip->i_sbd, block) == 0) {
> +	if (!valid_block(ip->i_sbd, block) == 0) {
>  		fsck_blockmap_set(ip, block, btype, gfs2_block_free);
>  		return 0;
>  	}
> @@ -930,7 +930,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
>  	uint8_t q;
>  	struct duptree *d;
>  
> -	if (gfs2_check_range(ip->i_sbd, block) != 0)
> +	if (!valid_block(ip->i_sbd, block) != 0)
>  		return -EFAULT;
>  
>  	q = block_type(block);
> @@ -1190,7 +1190,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
>  						   (unsigned long long)block);
>  					continue;
>  				}
> -				if (gfs2_check_range(ip->i_sbd, block)) {
> +				if (!valid_block(ip->i_sbd, block)) {
>  					log_debug( _("Skipping invalid block "
>  						     "%lld (0x%llx)\n"),
>  						   (unsigned long long)block,
> @@ -1237,7 +1237,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
>  		if (skip_this_pass || fsck_abort)
>  			return error;
>  		block =  be64_to_cpu(*ptr);
> -		/* It's important that we don't call gfs2_check_range and
> +		/* It's important that we don't call !valid_block and
>  		   bypass calling check_data on invalid blocks because that
>  		   would defeat the rangecheck_block related functions in
>  		   pass1. Therefore the individual check_data functions
> @@ -1437,8 +1437,8 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
>  		     " (0x%llx)\n"), (unsigned long long)dentryblock,
>  		  (unsigned long long)dentryblock,
>  		  (unsigned long long)dir, (unsigned long long)dir);
> -	if (gfs2_check_range(sdp, dir)) {
> -		log_err( _("Parent directory out of range\n"));
> +	if (!valid_block(sdp, dir)) {
> +		log_err( _("Parent directory is invalid\n"));
>  		return 1;
>  	}
>  	remove_dentry_fxns.private = &dentryblock;
> diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
> index 2670d8c..e2fe73c 100644
> --- a/gfs2/fsck/pass1.c
> +++ b/gfs2/fsck/pass1.c
> @@ -122,11 +122,11 @@ static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block,
>  	struct block_count *bc = (struct block_count *)private;
>  
>  	*bh = NULL;
> -	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
> +	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
>  		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
>  				  _("itself"), gfs2_bad_block);
> -		log_err( _("Bad indirect block pointer (out of range) "
> -			   "found in system inode %lld (0x%llx).\n"),
> +		log_err( _("Bad indirect block pointer (invalid or out of "
> +			   "range) found in system inode %lld (0x%llx).\n"),
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr);
>  		return 1;
> @@ -166,10 +166,10 @@ static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
>  		strncpy(tmp_name, filename, de->de_name_len);
>  	else
>  		strncpy(tmp_name, filename, sizeof(tmp_name) - 1);
> -	if (gfs2_check_range(sdp, block)) {
> +	if (!valid_block(sdp, block)) {
>  		log_err( _("Block # referenced by system directory entry %s "
> -			   "in inode %lld (0x%llx) is out of range; "
> -			   "ignored.\n"),
> +			   "in inode %lld (0x%llx) is invalid or out of range;"
> +			   " ignored.\n"),
>  			 tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr);
>  		return 0;
> @@ -221,10 +221,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
>  
>  	*bh = NULL;
>  
> -	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
> +	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
>  		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
>  				  _("itself"), gfs2_bad_block);
> -		log_debug( _("Bad indirect block pointer (out of range) "
> +		log_debug( _("Bad indirect block (invalid/out of range) "
>  			     "found in inode %lld (0x%llx).\n"),
>  			   (unsigned long long)ip->i_di.di_num.no_addr,
>  			   (unsigned long long)ip->i_di.di_num.no_addr);
> @@ -295,7 +295,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
>  
>  	*bh = NULL;
>  
> -	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
> +	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
>  		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
>  				  _("itself"), gfs2_block_free);
>  		return 1;
> @@ -350,9 +350,9 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
>  	uint8_t q;
>  	struct block_count *bc = (struct block_count *) private;
>  
> -	if (gfs2_check_range(ip->i_sbd, block)) {
> +	if (!valid_block(ip->i_sbd, block)) {
>  		log_err( _("inode %lld (0x%llx) has a bad data block pointer "
> -			   "%lld (out of range)\n"),
> +			   "%lld (invalid or out of range)\n"),
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)block);
> @@ -401,12 +401,12 @@ static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
>  	struct duptree *d;
>  	struct block_count *bc = (struct block_count *) private;
>  
> -	if (gfs2_check_range(ip->i_sbd, block)) {
> +	if (!valid_block(ip->i_sbd, block)) {
>  		/* Mark the owner of this block with the bad_block
>  		 * designator so we know to check it for out of range
>  		 * blocks later */
>  		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
> -				  _("bad (out of range) data"),
> +				  _("bad (invalid or out of range) data"),
>  				  gfs2_block_free);
>  		return 1;
>  	}
> @@ -547,7 +547,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
>  
>  	/* This inode contains an eattr - it may be invalid, but the
>  	 * eattr attributes points to a non-zero block */
> -	if (gfs2_check_range(sdp, indirect)) {
> +	if (!valid_block(sdp, indirect)) {
>  		/* Doesn't help to mark this here - this gets checked
>  		 * in pass1c */
>  		return 1;
> @@ -713,10 +713,10 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
>  	struct gfs2_buffer_head *bh = NULL;
>  	int error;
>  
> -	if (gfs2_check_range(sdp, el_blk)){
> +	if (!valid_block(sdp, el_blk)){
>  		log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
>  			   "%llu (0x%llx) has an extended leaf block #%llu "
> -			   "(0x%llx) that is out of range.\n"),
> +			   "(0x%llx) that is invalid or out of range.\n"),
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_eattr,
> @@ -757,9 +757,10 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
>  	}
>  	if (!b || b->block != ip->i_di.di_num.no_addr)
>  		gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
> -	if (gfs2_check_range(sdp, block)) {
> +	if (!valid_block(sdp, block)) {
>  		log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
> -			    "block #%llu (0x%llx) is out of range.\n"),
> +			    "block #%llu (0x%llx) is invalid or out of "
> +			    "range.\n"),
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)block, (unsigned long long)block);
> @@ -825,15 +826,15 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
>  {
>  	uint8_t q;
>  
> -	if (gfs2_check_range(ip->i_sbd, block) != 0)
> +	if (!valid_block(ip->i_sbd, block) != 0)
>  		return -EFAULT;
>  
>  	q = block_type(block);
>  	if (q != gfs2_block_free) {
>  		add_duplicate_ref(ip, block, reftype, 0, INODE_INVALID);
>  		log_info( _("%s block %lld (0x%llx), part of inode "
> -			    "%lld (0x%llx), was free so the invalid "
> -			    "reference is ignored.\n"),
> +			    "%lld (0x%llx), was previously referenced so "
> +			    "the invalid reference is ignored.\n"),
>  			  btype, (unsigned long long)block,
>  			  (unsigned long long)block,
>  			  (unsigned long long)ip->i_di.di_num.no_addr,
> @@ -897,13 +898,13 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
>  	long *bad_pointers = (long *)private;
>  	uint8_t q;
>  
> -	if (gfs2_check_range(ip->i_sbd, block) != 0) {
> +	if (!valid_block(ip->i_sbd, block) != 0) {
>  		(*bad_pointers)++;
> -		log_debug( _("Bad %s block pointer (out of range #%ld) "
> -			     "found in inode %lld (0x%llx).\n"), btype,
> -			   *bad_pointers,
> -			   (unsigned long long)ip->i_di.di_num.no_addr,
> -			   (unsigned long long)ip->i_di.di_num.no_addr);
> +		log_info( _("Bad %s block pointer (invalid or out of range "
> +			    "#%ld) found in inode %lld (0x%llx).\n"),
> +			  btype, *bad_pointers,
> +			  (unsigned long long)ip->i_di.di_num.no_addr,
> +			  (unsigned long long)ip->i_di.di_num.no_addr);
>  		if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
>  			return ENOENT;
>  		else
> @@ -913,11 +914,12 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
>  	q = block_type(block);
>  	if (q != gfs2_block_free) {
>  		(*bad_pointers)++;
> -		log_debug( _("Duplicated %s block pointer (violation #%ld) "
> -			     "found in inode %lld (0x%llx).\n"), btype,
> -			   *bad_pointers,
> -			   (unsigned long long)ip->i_di.di_num.no_addr,
> -			   (unsigned long long)ip->i_di.di_num.no_addr);
> +		log_info( _("Duplicated %s block pointer (violation %ld, block"
> +			    " %lld (0x%llx)) found in inode %lld (0x%llx).\n"),
> +			  btype, *bad_pointers,
> +			  (unsigned long long)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);
>  		if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
>  			return ENOENT;
>  		else
> diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
> index 6b7bc41..bbf33d2 100644
> --- a/gfs2/fsck/pass1b.c
> +++ b/gfs2/fsck/pass1b.c
> @@ -205,7 +205,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
>  	struct dup_handler *dh = (struct dup_handler *) private;
>  	struct duptree *d;
>  
> -	if (gfs2_check_range(ip->i_sbd, block) != 0)
> +	if (!valid_block(ip->i_sbd, block) != 0)
>  		return 0;
>  
>  	/* This gets tricky. We're traversing a metadata tree trying to
> diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
> index 0fbe0ce..209c32d 100644
> --- a/gfs2/fsck/pass1c.c
> +++ b/gfs2/fsck/pass1c.c
> @@ -78,10 +78,10 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
>  	uint8_t q;
>  	struct gfs2_buffer_head *indir_bh = NULL;
>  
> -	if (gfs2_check_range(sdp, block)) {
> +	if (!valid_block(sdp, block)) {
>  		log_err( _("Extended attributes indirect block #%llu"
>  			" (0x%llx) for inode #%llu"
> -			" (0x%llx) out of range...removing\n"),
> +			" (0x%llx) is invalid...removing\n"),
>  			(unsigned long long)block,
>  			(unsigned long long)block,
>  			(unsigned long long)ip->i_di.di_num.no_addr,
> @@ -92,7 +92,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
>  	if (q != gfs2_indir_blk) {
>  		log_err( _("Extended attributes indirect block #%llu"
>  			" (0x%llx) for inode #%llu"
> -			" (0x%llx) invalid.\n"),
> +			" (0x%llx) is invalid.\n"),
>  			(unsigned long long)block,
>  			(unsigned long long)block,
>  			(unsigned long long)ip->i_di.di_num.no_addr,
> @@ -113,9 +113,9 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
>  	struct gfs2_sbd *sdp = ip->i_sbd;
>  	uint8_t q;
>  
> -	if (gfs2_check_range(sdp, block)) {
> +	if (!valid_block(sdp, block)) {
>  		log_err( _("Extended attributes block for inode #%llu"
> -			" (0x%llx) out of range.\n"),
> +			" (0x%llx) is 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);
> diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
> index 573ed30..72bd107 100644
> --- a/gfs2/fsck/pass2.c
> +++ b/gfs2/fsck/pass2.c
> @@ -206,9 +206,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
>  	else
>  		strncpy(tmp_name, filename, MAX_FILENAME - 1);
>  
> -	if (gfs2_check_range(ip->i_sbd, entryblock)) {
> +	if (!valid_block(ip->i_sbd, entryblock)) {
>  		log_err( _("Block # referenced by directory entry %s in inode "
> -			   "%lld (0x%llx) is out of range\n"),
> +			   "%lld (0x%llx) is invalid\n"),
>  			 tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
>  			 (unsigned long long)ip->i_di.di_num.no_addr);
>  		if (query( _("Clear directory entry to out of range block? "
> diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
> index 1dd49b1..24badef 100644
> --- a/gfs2/fsck/rgrepair.c
> +++ b/gfs2/fsck/rgrepair.c
> @@ -622,7 +622,7 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
>  	/* our rindex structures, then something's wrong and we can't trust  */
>  	/* the index.                                                        */
>  	/* ----------------------------------------------------------------- */
> -	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
> +	*num_rgs = sdp->md.riinode->i_di.di_size / risize(sdp);
>  
>  	osi_list_init(ret_list);
>  	if (device_geometry(sdp)) {
> @@ -710,7 +710,7 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
>  	osi_list_t *tmp;
>  	struct rgrp_list *exp, *rgd; /* expected, actual */
>  
> -	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
> +	*num_rgs = sdp->md.riinode->i_di.di_size / risize(sdp);
>  	osi_list_init(ret_list);
>  	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
>  		rgd = osi_list_entry(tmp, struct rgrp_list, list);
> @@ -833,7 +833,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
>  	/* Read in the rindex */
>  	osi_list_init(&sdp->rglist); /* Just to be safe */
>  	rindex_read(sdp, 0, &rgcount_from_index, sane);
> -	if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
> +	if (sdp->md.riinode->i_di.di_size % risize(sdp)) {
>  		log_warn( _("WARNING: rindex file is corrupt.\n"));
>  		gfs2_rgrp_free(&expected_rglist);
>  		gfs2_rgrp_free(&sdp->rglist);
> @@ -958,8 +958,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
>  			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),
> -					    sizeof(struct gfs2_rindex));
> +					    rg * risize(sdp), risize(sdp));
>  				actual->ri.ri_addr = expected->ri.ri_addr;
>  				actual->ri.ri_length = expected->ri.ri_length;
>  				actual->ri.ri_data0 = expected->ri.ri_data0;
> diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
> index 2a35989..9719d48 100644
> --- a/gfs2/fsck/util.c
> +++ b/gfs2/fsck/util.c
> @@ -203,7 +203,7 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
>  	struct inode_with_dups *id, *found_id;
>  	struct duptree *dt;
>  
> -	if (gfs2_check_range(ip->i_sbd, block) != 0)
> +	if (!valid_block(ip->i_sbd, block) != 0)
>  		return 0;
>  	/* If this is not the first reference (i.e. all calls from pass1) we
>  	   need to create the duplicate reference. If this is pass1b, we want
> diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
> index 97172df..9f71471 100644
> --- a/gfs2/libgfs2/fs_bits.c
> +++ b/gfs2/libgfs2/fs_bits.c
> @@ -145,7 +145,24 @@ int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno)
>  }
>  
>  /*
> - * fs_set_bitmap
> + * valid_block - check if blkno is valid and not part of our rgrps or bitmaps
> + * @sdp: super block
> + * @blkno: block number
> + *
> + * Returns: 1 if ok, 0 if out of bounds
> + */
> +int valid_block(struct gfs2_sbd *sdp, uint64_t blkno)
> +{
> +	if((blkno > sdp->fssize) || (blkno <= sdp->sb_addr))
> +		return 0;
> +	/* Check if the block is one of our rgrp or bitmap blocks */
> +	if (gfs2_get_bitmap(sdp, blkno, NULL) < 0)
> +		return 0;
> +	return 1;
> +}
> +
> +/*
> + * gfs2_set_bitmap
>   * @sdp: super block
>   * @blkno: block number relative to file system
>   * @state: one of three possible states
> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
> index 6ddfd19..8f2ac89 100644
> --- a/gfs2/libgfs2/libgfs2.h
> +++ b/gfs2/libgfs2/libgfs2.h
> @@ -410,6 +410,7 @@ extern uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
>  extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
>  
>  /* functions with blk #'s that are file system relative */
> +extern int valid_block(struct gfs2_sbd *sdp, uint64_t blkno);
>  extern int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
>  			   struct rgrp_list *rgd);
>  extern int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state);





More information about the Cluster-devel mailing list