[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