[Ocfs2-tools-devel] [PATCH 1/3] fsck.ocfs2: Handle errors from ocfs2_bitmap_set/clear()

Sunil Mushran sunil.mushran at oracle.com
Thu Jul 23 12:55:39 PDT 2009


Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>


Joel Becker wrote:
> o2fsck expects to be able to treat ocfs2_bitmap_set() and
> ocfs2_bitmap_clear() as void functions.  However, since o2fsck uses the
> sparse-memory bitmaps a lot, they can (in theory) have allocation
> failures.  A silent allocation failure looks like clear bits, which is
> not a safe behavior.
>
> So, let's wrap ocfs2_bitmap_set/clear() with o2fsck_bitmap_set/clear().
> These are true void functions.  If they get an error from
> ocfs2_bitmap_set/clear() they will print the caller, the error, and the
> bit number.  Then they abort o2fsck.
>
> Signed-off-by: Joel Becker <joel.becker at oracle.com>
> ---
>  fsck.ocfs2/icount.c       |    4 ++--
>  fsck.ocfs2/include/util.h |   15 +++++++++++++++
>  fsck.ocfs2/journal.c      |    2 +-
>  fsck.ocfs2/pass0.c        |   10 +++++-----
>  fsck.ocfs2/pass1.c        |    4 ++--
>  fsck.ocfs2/util.c         |   43 +++++++++++++++++++++++++++++++++++++++++--
>  6 files changed, 66 insertions(+), 12 deletions(-)
>
> diff --git a/fsck.ocfs2/icount.c b/fsck.ocfs2/icount.c
> index 858063a..1fa7aab 100644
> --- a/fsck.ocfs2/icount.c
> +++ b/fsck.ocfs2/icount.c
> @@ -95,9 +95,9 @@ errcode_t o2fsck_icount_set(o2fsck_icount *icount, uint64_t blkno,
>  	errcode_t ret = 0;
>  
>  	if (count == 1)
> -		ocfs2_bitmap_set(icount->ic_single_bm, blkno, NULL);
> +		o2fsck_bitmap_set(icount->ic_single_bm, blkno, NULL);
>  	else
> -		ocfs2_bitmap_clear(icount->ic_single_bm, blkno, NULL);
> +		o2fsck_bitmap_clear(icount->ic_single_bm, blkno, NULL);
>  
>  	in = icount_search(icount, blkno, NULL);
>  	if (in) {
> diff --git a/fsck.ocfs2/include/util.h b/fsck.ocfs2/include/util.h
> index 77d36e4..c4e58ba 100644
> --- a/fsck.ocfs2/include/util.h
> +++ b/fsck.ocfs2/include/util.h
> @@ -65,4 +65,19 @@ errcode_t handle_slots_system_file(ocfs2_filesys *fs,
>  				   errcode_t (*func)(ocfs2_filesys *fs,
>  						     struct ocfs2_dinode *di,
>  						     int slot));
> +
> +/*
> + * Wrap the ocfs2 bitmap functions to abort when errors are found.  They're
> + * not supposed to fail, so we want to handle it.
> + */
> +void __o2fsck_bitmap_set(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
> +			 const char *where);
> +void __o2fsck_bitmap_clear(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
> +			   const char *where);
> +
> +/* These wrappers pass the caller into __o2fsck_bitmap_*() */
> +#define o2fsck_bitmap_set(_map, _bit, _old)     			\
> +	__o2fsck_bitmap_set((_map), (_bit), (_old), __FUNCTION__)
> +#define o2fsck_bitmap_clear(_map, _bit, _old)				\
> +	__o2fsck_bitmap_clear((_map), (_bit), (_old), __FUNCTION__);
>  #endif /* __O2FSCK_UTIL_H__ */
> diff --git a/fsck.ocfs2/journal.c b/fsck.ocfs2/journal.c
> index 4ed7653..ee1ce60 100644
> --- a/fsck.ocfs2/journal.c
> +++ b/fsck.ocfs2/journal.c
> @@ -247,7 +247,7 @@ static errcode_t lookup_journal_block(ocfs2_filesys *fs,
>  	}
>  
>  	if (check_dup) {
> -		ocfs2_bitmap_set(ji->ji_used_blocks, *blkno, &was_set);
> +		o2fsck_bitmap_set(ji->ji_used_blocks, *blkno, &was_set);
>  		if (was_set)  {
>  			printf("Logical block %"PRIu64" in slot %d's journal "
>  			       "maps to block %"PRIu64" which has already "
> diff --git a/fsck.ocfs2/pass0.c b/fsck.ocfs2/pass0.c
> index b2172ce..66e18c7 100644
> --- a/fsck.ocfs2/pass0.c
> +++ b/fsck.ocfs2/pass0.c
> @@ -494,13 +494,13 @@ static errcode_t check_chain(o2fsck_state *ost,
>  				int was_set;
>  				ocfs2_bitmap_test(allowed, blkno, &was_set);
>  				if (was_set) {
> -					ocfs2_bitmap_clear(allowed, blkno,
> -							   &was_set);
> +					o2fsck_bitmap_clear(allowed, blkno,
> +							    &was_set);
>  					mark_group_used(ost, cs, bg1->bg_blkno,
>  							allowed != NULL);
>  				} else if (forbidden)
> -					ocfs2_bitmap_set(forbidden, blkno,
> -							 &was_set);
> +					o2fsck_bitmap_set(forbidden, blkno,
> +							  &was_set);
>  			} else
>  				mark_group_used(ost, cs, bg1->bg_blkno,
>  						allowed != NULL);
> @@ -906,7 +906,7 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
>  	     i < cgs.cgs_cluster_groups; 
>  	     i++, blkno = i * ocfs2_clusters_to_blocks(ost->ost_fs,
>  						       cgs.cgs_cpg)) {
> -		ocfs2_bitmap_set(allowed, blkno, NULL);
> +		o2fsck_bitmap_set(allowed, blkno, NULL);
>  	}
>  
>  	ret = verify_chain_alloc(ost, di, buf1, buf2, NULL, allowed, forbidden);
> diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
> index 15880bc..de09788 100644
> --- a/fsck.ocfs2/pass1.c
> +++ b/fsck.ocfs2/pass1.c
> @@ -509,11 +509,11 @@ static void o2fsck_verify_inode_fields(ocfs2_filesys *fs,
>  	}
>  
>  	if (S_ISDIR(di->i_mode)) {
> -		ocfs2_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
> +		o2fsck_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
>  		o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, 0, 0,
>  				      di->i_flags & OCFS2_ORPHANED_FL);
>  	} else if (S_ISREG(di->i_mode)) {
> -		ocfs2_bitmap_set(ost->ost_reg_inodes, blkno, NULL);
> +		o2fsck_bitmap_set(ost->ost_reg_inodes, blkno, NULL);
>  	} else if (S_ISLNK(di->i_mode)) {
>  		/* we only make sure a link's i_size matches
>  		 * the link names length in the file data later when
> diff --git a/fsck.ocfs2/util.c b/fsck.ocfs2/util.c
> index 0238709..b12e3e1 100644
> --- a/fsck.ocfs2/util.c
> +++ b/fsck.ocfs2/util.c
> @@ -28,6 +28,9 @@
>  #include <inttypes.h>
>  #include <string.h>
>  #include <assert.h>
> +#include <sys/types.h>
> +#include <signal.h>
> +#include <unistd.h>
>  #include "ocfs2/ocfs2.h"
>  
>  #include "util.h"
> @@ -57,7 +60,7 @@ void o2fsck_mark_cluster_allocated(o2fsck_state *ost, uint32_t cluster)
>  {
>  	int was_set;
>  
> -	ocfs2_bitmap_set(ost->ost_allocated_clusters, cluster, &was_set);
> +	o2fsck_bitmap_set(ost->ost_allocated_clusters, cluster, &was_set);
>  
>  	if (was_set) /* XX can go away one all callers handle this */
>  		com_err(__FUNCTION__, OCFS2_ET_INTERNAL_FAILURE,
> @@ -75,7 +78,7 @@ void o2fsck_mark_cluster_unallocated(o2fsck_state *ost, uint32_t cluster)
>  {
>  	int was_set;
>  
> -	ocfs2_bitmap_clear(ost->ost_allocated_clusters, cluster, &was_set);
> +	o2fsck_bitmap_clear(ost->ost_allocated_clusters, cluster, &was_set);
>  }
>  
>  errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino,
> @@ -275,3 +278,39 @@ void o2fsck_reset_blocks_cached(void)
>  {
>  	blocks_cached = 0;
>  }
> +
> +void __o2fsck_bitmap_set(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
> +			 const char *where)
> +{
> +	errcode_t ret;
> +
> +	ret = ocfs2_bitmap_set(bitmap, bitno, oldval);
> +	if (ret) {
> +		com_err(where, ret,
> +			"while trying to set bit %"PRIu64", aborting\n",
> +			bitno);
> +		/*
> +		 * We abort with SIGTERM so that the signal handler can
> +		 * clean up the cluster stack.
> +		 */
> +		kill(getpid(), SIGTERM);
> +	}
> +}
> +
> +void __o2fsck_bitmap_clear(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
> +			   const char *where)
> +{
> +	errcode_t ret;
> +
> +	ret = ocfs2_bitmap_clear(bitmap, bitno, oldval);
> +	if (ret) {
> +		com_err(where, ret,
> +			"while trying to clear bit %"PRIu64", aborting\n",
> +			bitno);
> +		/*
> +		 * We abort with SIGTERM so that the signal handler can
> +		 * clean up the cluster stack.
> +		 */
> +		kill(getpid(), SIGTERM);
> +	}
> +}
>   




More information about the Ocfs2-tools-devel mailing list