commit 5b78e00a39c53d81281978ab575dff5801c0d1a6 Author: Bob Peterson <rpeterso@redhat.com> Date: Mon Feb 14 13:59:50 2011 -0600 GFS: speed up gfs_fsck This patch reduces the memory requirements of gfs_fsck by combining bitmap and block_map settings that were rarely used. It also speeds up gfs_fsck by eliminating un-needed parameter passing, optimizing bitmap math and simplifying bitmap structures. rhbz#515834 diff --git a/gfs/gfs_fsck/bio.c b/gfs/gfs_fsck/bio.c index cfa5cc5..cd6833c 100644 --- a/gfs/gfs_fsck/bio.c +++ b/gfs/gfs_fsck/bio.c @@ -91,11 +91,10 @@ void relse_buf(struct fsck_sb *sdp, osi_buf_t *bh){ * @sdp: the super block * @blkno: block number * @bhp: place where buffer is returned - * @flags: * * Returns 0 on success, -1 on error */ -int read_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags){ +int read_buf(struct fsck_sb *sdp, osi_buf_t *bh){ int disk_fd = sdp->diskfd; if(do_lseek(disk_fd, (uint64)(BH_BLKNO(bh)*BH_SIZE(bh)))){ @@ -161,15 +160,14 @@ int write_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags){ * * Returns: 0 on success, -1 on error */ -int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp, - int flags) +int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp) { if(get_buf(sdp, blkno, bhp)) { stack; return -1; } - if(read_buf(sdp, *bhp, flags)){ + if(read_buf(sdp, *bhp)){ stack; relse_buf(sdp, *bhp); *bhp = NULL; /* guarantee that ptr is NULL in failure cases */ diff --git a/gfs/gfs_fsck/bio.h b/gfs/gfs_fsck/bio.h index 0f4ef62..bbf34be 100644 --- a/gfs/gfs_fsck/bio.h +++ b/gfs/gfs_fsck/bio.h @@ -27,9 +27,9 @@ int get_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp); void relse_buf(struct fsck_sb *sdp, osi_buf_t *bh); -int read_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags); +int read_buf(struct fsck_sb *sdp, osi_buf_t *bh); int write_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags); -int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp, int flags); +int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp); #endif /* __BIO_H */ diff --git a/gfs/gfs_fsck/bitmap.c b/gfs/gfs_fsck/bitmap.c index 507dcc8..1e87d93 100644 --- a/gfs/gfs_fsck/bitmap.c +++ b/gfs/gfs_fsck/bitmap.c @@ -22,11 +22,39 @@ #define BITMAP_SIZE(size, cpb) (size / cpb) +#define BITMAP_SIZE1(size) (size >> 3) +#define BITMAP_SIZE4(size) (size >> 1) #define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \ * map->chunksize ) +/* BITMAP_BYTE_OFFSET1 is for chunksize==1, which implies chunks_per_byte==8 */ +/* Reducing the math, we get: */ +/* #define BITMAP_BYTE_OFFSET1(x) ((x % 8) * 1) */ +/* #define BITMAP_BYTE_OFFSET1(x) (x % 8) */ +/* #define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) */ +#define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) + +/* BITMAP_BYTE_OFFSET4 is for chunksize==4, which implies chunks_per_byte==2 */ +/* Reducing the math, we get: */ +/* #define BITMAP_BYTE_OFFSET4(x) ((x % 2) * 4) */ +/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) * 4) */ +/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) */ +#define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) + #define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1) +/* BITMAP_MASK1 is for chunksize==1 */ +/* Reducing the math, we get: */ +/* #define BITMAP_MASK1(chunksize) ((2 << (1 - 1)) - 1) */ +/* #define BITMAP_MASK1(chunksize) ((2 << 0) - 1) */ +/* #define BITMAP_MASK1(chunksize) ((2) - 1) */ +#define BITMAP_MASK1(chunksize) (1) + +/* BITMAP_MASK4 is for chunksize==4 */ +/* #define BITMAP_MASK(chunksize) ((2 << (4 - 1)) - 1) */ +/* #define BITMAP_MASK(chunksize) ((2 << 3) - 1) */ +/* #define BITMAP_MASK(chunksize) (0x10 - 1) */ +#define BITMAP_MASK4(chunksize) (0xf) uint64_t bitmap_size(struct bmap *bmap) { return bmap->size; @@ -71,14 +99,19 @@ int bitmap_create(struct bmap *bmap, uint64_t size, uint8_t chunksize) int bitmap_set(struct bmap *bmap, uint64_t offset, uint8_t val) { - char *byte = NULL; - uint64_t b = offset; + static char *byte; + static uint64_t b; if(offset < bmap->size) { - byte = bmap->map + BITMAP_SIZE(offset, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(offset, bmap); - - *byte |= (val & BITMAP_MASK(bmap->chunksize)) << b; + if (bmap->chunksize == 1) { + byte = bmap->map + BITMAP_SIZE1(offset); + b = BITMAP_BYTE_OFFSET1(offset); + *byte |= (val & BITMAP_MASK1(bmap->chunksize)) << b; + } else { + byte = bmap->map + BITMAP_SIZE4(offset); + b = BITMAP_BYTE_OFFSET4(offset); + *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b; + } return 0; } log_debug("offset %d out of bounds\n", offset); @@ -87,14 +120,19 @@ int bitmap_set(struct bmap *bmap, uint64_t offset, uint8_t val) int bitmap_get(struct bmap *bmap, uint64_t bit, uint8_t *val) { - char *byte = NULL; - uint64_t b = bit; + static char *byte; + static uint64_t b; if(bit < bmap->size) { - byte = bmap->map + BITMAP_SIZE(bit, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(bit, bmap); - - *val = (*byte & (BITMAP_MASK(bmap->chunksize) << b )) >> b; + if (bmap->chunksize == 1) { + byte = bmap->map + BITMAP_SIZE1(bit); + b = BITMAP_BYTE_OFFSET1(bit); + *val = (*byte & (BITMAP_MASK1(bmap->chunksize) << b )) >> b; + } else { + byte = bmap->map + BITMAP_SIZE4(bit); + b = BITMAP_BYTE_OFFSET4(bit); + *val = (*byte & (BITMAP_MASK4(bmap->chunksize) << b )) >> b; + } return 0; } log_debug("offset %d out of bounds\n", bit); @@ -104,14 +142,19 @@ int bitmap_get(struct bmap *bmap, uint64_t bit, uint8_t *val) int bitmap_clear(struct bmap *bmap, uint64_t offset) { - char *byte = NULL; - uint64_t b = offset; + static char *byte; + static uint64_t b; if(offset < bmap->size) { - byte = bmap->map + BITMAP_SIZE(offset, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(offset, bmap); - - *byte &= ~(BITMAP_MASK(bmap->chunksize) << b); + if (bmap->chunksize == 1) { + byte = bmap->map + BITMAP_SIZE1(offset); + b = BITMAP_BYTE_OFFSET1(offset); + *byte &= ~(BITMAP_MASK1(bmap->chunksize) << b); + } else { + byte = bmap->map + BITMAP_SIZE4(offset); + b = BITMAP_BYTE_OFFSET4(offset); + *byte &= ~(BITMAP_MASK4(bmap->chunksize) << b); + } return 0; } log_debug("offset %d out of bounds\n", offset); diff --git a/gfs/gfs_fsck/block_list.c b/gfs/gfs_fsck/block_list.c index f44de6a..c1eadd1 100644 --- a/gfs/gfs_fsck/block_list.c +++ b/gfs/gfs_fsck/block_list.c @@ -24,11 +24,10 @@ static int mark_to_gbmap[16] = { block_free, block_used, indir_blk, inode_dir, inode_file, inode_lnk, inode_blk, inode_chr, inode_fifo, inode_sock, - leaf_blk, journal_blk, meta_other, meta_free, - meta_eattr, meta_inval + leaf_blk, meta_other, meta_free, meta_eattr, bad_block, meta_inval }; -struct block_list *block_list_create(uint64_t size, enum block_list_type type) +struct block_list *block_list_create(uint64_t size) { struct block_list *il; uint64_t addl_mem_needed = 0L; @@ -39,56 +38,43 @@ struct block_list *block_list_create(uint64_t size, enum block_list_type type) log_err("Cannot set block list to zero\n"); return NULL; } - il->type = type; - switch(type) { - case gbmap: - if(bitmap_create(&il->list.gbmap.group_map, size, 4)) { - /* Note on addl_mem_needed: We've tried to allocate ram */ - /* for our bitmaps, but we failed. The fs is too big. */ - /* We should tell them how much to allocate. This first */ - /* bitmap is the biggest, but we need three more smaller */ - /* for the code that immediately follows. I'm rounding */ - /* up to twice the memory for this bitmap, even though */ - /* it's actually 1 + 3/4. That will allow for future */ - /* mallocs that happen after this point in the code. */ - /* For the bad_map, we have two more to go (total of 3) */ - /* but again I'm rounding it up to 4 smaller ones. */ - /* For the dup_map, I'm rounding from 2 to 3, and for */ - /* eattr_map, I'm rounding up from 1 to 2. */ - addl_mem_needed = il->list.gbmap.group_map.mapsize * 2; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.bad_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 4; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.dup_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 3; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.eattr_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 2; - stack; - free(il); - il = NULL; - } - if (addl_mem_needed) { - log_err("This system doesn't have enough memory + swap space to fsck this file system.\n"); - log_err("Additional memory needed is approximately: %ldMB\n", addl_mem_needed / 1048576); - log_err("Please increase your swap space by that amount and run gfs_fsck again.\n"); - } - break; - default: - log_crit("Block list type %d not implemented\n", - type); - break; + if(bitmap_create(&il->group_map, size, 4)) { + /* Note on addl_mem_needed: We've tried to allocate + ram for our bitmaps, but we failed. The fs is too + big. We should tell them how much to allocate. + This first bitmap is the biggest, but we need three + more smaller for the code that immediately follows. + I'm rounding up to twice the memory for this bitmap, + even though it's actually 1 + 1/2. That will allow + for future mallocs that happen after this point in + the code. For the dup_map, I'm rounding from 2 + to 3, and for eattr_map, I'm rounding up from 1 to + 2. */ + addl_mem_needed = il->group_map.mapsize * 2; + stack; + free(il); + il = NULL; + } + else if(bitmap_create(&il->dup_map, size, 1)) { + addl_mem_needed = il->group_map.mapsize * 2; + stack; + free(il); + il = NULL; + } + else if(bitmap_create(&il->eattr_map, size, 1)) { + addl_mem_needed = il->group_map.mapsize; + stack; + free(il); + il = NULL; + } + if (addl_mem_needed) { + log_err("This system doesn't have enough memory + " + "swap space to fsck this file system.\n"); + log_err("Additional memory needed is approximately: " + "%ldMB\n", addl_mem_needed / 1048576); + log_err("Please increase your swap space by that " + "amount and run gfs_fsck again.\n"); } } @@ -97,37 +83,21 @@ struct block_list *block_list_create(uint64_t size, enum block_list_type type) int block_mark(struct block_list *il, uint64_t block, enum mark_block mark) { - int err = 0; - - switch(il->type) { - case gbmap: - if(mark == bad_block) { - err = bitmap_set(&il->list.gbmap.bad_map, block, 1); - } - else if(mark == dup_block) { - err = bitmap_set(&il->list.gbmap.dup_map, block, 1); - } - else if(mark == eattr_block) { - err = bitmap_set(&il->list.gbmap.eattr_map, block, 1); - } - else { - err = bitmap_set(&il->list.gbmap.group_map, block, - mark_to_gbmap[mark]); - } - - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } + int err; + + if(mark == dup_block) + err = bitmap_set(&il->dup_map, block, 1); + else if(mark == eattr_block) + err = bitmap_set(&il->eattr_map, block, 1); + else + err = bitmap_set(&il->group_map, block, mark_to_gbmap[mark]); return err; } int block_set(struct block_list *il, uint64_t block, enum mark_block mark) { - int err = 0; + int err; + err = block_clear(il, block); if(!err) err = block_mark(il, block, mark); @@ -136,31 +106,18 @@ int block_set(struct block_list *il, uint64_t block, enum mark_block mark) int block_unmark(struct block_list *il, uint64_t block, enum mark_block m) { - int err = 0; - - switch(il->type) { - case gbmap: - switch (m) { - case dup_block: - err = bitmap_clear(&il->list.gbmap.dup_map, block); - break; - case bad_block: - err = bitmap_clear(&il->list.gbmap.bad_map, block); - break; - case eattr_block: - err = bitmap_clear(&il->list.gbmap.eattr_map, block); - break; - default: - /* FIXME: check types */ - err = bitmap_clear(&il->list.gbmap.group_map, block); - break; - } + int err; + switch (m) { + case dup_block: + err = bitmap_clear(&il->dup_map, block); + break; + case eattr_block: + err = bitmap_clear(&il->eattr_map, block); break; default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; + /* FIXME: check types */ + err = bitmap_clear(&il->group_map, block); break; } return err; @@ -168,80 +125,40 @@ int block_unmark(struct block_list *il, uint64_t block, enum mark_block m) int block_clear(struct block_list *il, uint64_t block) { - int err = 0; + int err; - switch(il->type) { - case gbmap: - err = bitmap_clear(&il->list.gbmap.dup_map, block); - err = bitmap_clear(&il->list.gbmap.bad_map, block); - err = bitmap_clear(&il->list.gbmap.eattr_map, block); - err = bitmap_clear(&il->list.gbmap.group_map, block); - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } + err = bitmap_clear(&il->dup_map, block); + err = bitmap_clear(&il->eattr_map, block); + err = bitmap_clear(&il->group_map, block); return err; } int block_check(struct block_list *il, uint64_t block, struct block_query *val) { - int err = 0; + int err; + val->block_type = 0; - val->bad_block = 0; val->dup_block = 0; - switch(il->type) { - case gbmap: - if((err = bitmap_get(&il->list.gbmap.group_map, block, - &val->block_type))) { - log_err("Unable to get block type for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.bad_map, block, - &val->bad_block))) { - log_err("Unable to get bad block status for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.dup_map, block, - &val->dup_block))) { - log_err("Unable to get duplicate status for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.eattr_map, block, - &val->eattr_block))) { - log_err("Unable to get eattr status for block %" - PRIu64"\n", block); - break; - } - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } - + if((err = bitmap_get(&il->group_map, block, &val->block_type))) + log_err("Unable to get block type for block %" + PRIu64"\n", block); + else if((err = bitmap_get(&il->dup_map, block, + &val->dup_block))) + log_err("Unable to get duplicate status for block %" + PRIu64"\n", block); + else if((err = bitmap_get(&il->eattr_map, block, + &val->eattr_block))) + log_err("Unable to get eattr status for block %" + PRIu64"\n", block); return err; } void *block_list_destroy(struct block_list *il) { if(il) { - switch(il->type) { - case gbmap: - bitmap_destroy(&il->list.gbmap.group_map); - bitmap_destroy(&il->list.gbmap.bad_map); - bitmap_destroy(&il->list.gbmap.dup_map); - bitmap_destroy(&il->list.gbmap.eattr_map); - break; - default: - break; - } + bitmap_destroy(&il->group_map); + bitmap_destroy(&il->dup_map); + bitmap_destroy(&il->eattr_map); free(il); il = NULL; } @@ -255,40 +172,33 @@ int find_next_block_type(struct block_list *il, enum mark_block m, uint64_t *b) uint8_t val; int found = 0; for(i = *b; ; i++) { - switch(il->type) { - case gbmap: - if(i >= bitmap_size(&il->list.gbmap.dup_map)) - return -1; + if(i >= bitmap_size(&il->dup_map)) + return -1; - switch(m) { - case dup_block: - if(bitmap_get(&il->list.gbmap.dup_map, i, &val)) { - stack; - return -1; - } - - if(val) - found = 1; - break; - case eattr_block: - if(bitmap_get(&il->list.gbmap.eattr_map, i, &val)) { - stack; - return -1; - } - - if(val) - found = 1; - break; - default: - /* FIXME: add support for getting - * other types */ - log_err("Unhandled block type\n"); + switch(m) { + case dup_block: + if(bitmap_get(&il->dup_map, i, &val)) { + stack; + return -1; + } + if(val) + found = 1; + break; + case eattr_block: + if(bitmap_get(&il->eattr_map, i, &val)) { + stack; + return -1; } + + if(val) + found = 1; break; default: - log_err("Unhandled block list type\n"); + /* FIXME: add support for getting other types */ + log_err("Unhandled block type\n"); break; } + if(found) { *b = i; return 0; diff --git a/gfs/gfs_fsck/block_list.h b/gfs/gfs_fsck/block_list.h index 7fd02eb..00a2600 100644 --- a/gfs/gfs_fsck/block_list.h +++ b/gfs/gfs_fsck/block_list.h @@ -15,14 +15,6 @@ #include "bitmap.h" -#define BMAP_COUNT 13 - -enum block_list_type { - gbmap = 0, /* Grouped bitmap */ - dbmap, /* Ondisk bitmap - like grouped bitmap, but mmaps - * the bitmaps onto file(s) ondisk - not implemented */ -}; - /* Must be kept in sync with mark_to_bitmap array in block_list.c */ enum mark_block { block_free = 0, @@ -36,57 +28,31 @@ enum mark_block { inode_fifo = 8, inode_sock = 9, leaf_blk = 10, - journal_blk = 11, - meta_other = 12, - meta_free = 13, - meta_eattr = 14, + meta_other = 11, + meta_free = 12, + meta_eattr = 13, + bad_block = 14, /* Contains at least one bad block */ meta_inval = 15, /* above this are nibble-values 0x0-0xf */ - bad_block = 16, /* Contains at least one bad block */ - dup_block = 17, /* Contains at least one duplicate block */ - eattr_block = 18, /* Contains an eattr */ + /* A block can be both duplicate and one of the above. */ + dup_block = 16, /* Contains at least one duplicate block */ + eattr_block = 17, /* Contains an eattr */ }; struct block_query { uint8_t block_type; - uint8_t bad_block; uint8_t dup_block; uint8_t eattr_block; }; -struct gbmap { - struct bmap group_map; - struct bmap bad_map; - struct bmap dup_map; - struct bmap eattr_map; -}; - -struct dbmap { +/* bitmap implementation */ +struct block_list { struct bmap group_map; - char *group_file; - struct bmap bad_map; - char *bad_file; struct bmap dup_map; - char *dup_file; struct bmap eattr_map; - char *eattr_file; -}; - -union block_lists { - struct gbmap gbmap; - struct dbmap dbmap; }; - -/* bitmap implementation */ -struct block_list { - enum block_list_type type; - /* Union of bitmap, rle */ - union block_lists list; -}; - - -struct block_list *block_list_create(uint64_t size, enum block_list_type type); +struct block_list *block_list_create(uint64_t size); int block_mark(struct block_list *il, uint64_t block, enum mark_block mark); int block_set(struct block_list *il, uint64_t block, enum mark_block mark); int block_unmark(struct block_list *il, uint64_t block, enum mark_block m); diff --git a/gfs/gfs_fsck/file.c b/gfs/gfs_fsck/file.c index 5217e92..559a979 100644 --- a/gfs/gfs_fsck/file.c +++ b/gfs/gfs_fsck/file.c @@ -83,7 +83,7 @@ int readi(struct fsck_inode *ip, void *buf, uint64 offset, unsigned int size) } if (dblock){ - error = get_and_read_buf(ip->i_sbd, dblock, &bh, 0); + error = get_and_read_buf(ip->i_sbd, dblock, &bh); if (error){ log_err("readi: Unable to perform get_and_read_buf()\n"); goto out; @@ -184,7 +184,7 @@ int writei(struct fsck_inode *ip, void *buf, uint64_t offset, unsigned int size) } } - error = get_and_read_buf(ip->i_sbd, dblock, &bh, 0); + error = get_and_read_buf(ip->i_sbd, dblock, &bh); if (error) goto fail; @@ -206,7 +206,7 @@ int writei(struct fsck_inode *ip, void *buf, uint64_t offset, unsigned int size) out: - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh); if (error){ log_err("fs_writei: " "Unable to get inode buffer.\n"); diff --git a/gfs/gfs_fsck/fs_bits.c b/gfs/gfs_fsck/fs_bits.c index fce646a..ec12a9d 100644 --- a/gfs/gfs_fsck/fs_bits.c +++ b/gfs/gfs_fsck/fs_bits.c @@ -79,7 +79,6 @@ uint32_t fs_bitfit_core(struct fsck_sb *sbp, uint64_t goal, uint64_t start, uint case inode_sock: case indir_blk: case leaf_blk: - case journal_blk: case meta_other: case meta_eattr: return block - start; @@ -184,14 +183,13 @@ uint32_t fs_bitcount(unsigned char *buffer, unsigned int buflen, * @goal: the goal block in the RG * @old_state: the type of block to find * @new_state: the resulting block type - * @do_it: if FALSE, we just find the block we would allocate * * * Returns: returns the block allocated, or BFITNOENT on failure */ uint32_t fs_blkalloc_internal(struct fsck_rgrp *rgd, uint32_t goal, unsigned char old_state, - unsigned char new_state, int do_it) + unsigned char new_state) { struct fsck_sb *sdp = rgd->rd_sbd; uint32_t block = 0; @@ -251,56 +249,64 @@ uint32_t fs_blkalloc_internal(struct fsck_rgrp *rgd, uint32_t goal, * * Returns: state on success, -1 on error */ -int fs_get_bitmap(struct fsck_sb *sdp, uint64 blkno, struct fsck_rgrp *rgd){ +int fs_get_bitmap(struct fsck_sb *sdp, uint64 blkno, struct fsck_rgrp **rgd){ int buf, val; uint32_t rgrp_block; -/* struct fsck_rgrp *rgd;*/ fs_bitmap_t *bits = NULL; unsigned int bit; unsigned char *byte; - int local_rgd = 0; if(check_range(sdp, blkno)){ log_warn("Block #%"PRIu64" is out of range.\n", blkno); return -1; } - if(rgd == NULL) { - local_rgd = 1; - rgd = fs_blk2rgrpd(sdp, blkno); - } - if(rgd == NULL){ - log_err( "Unable to get rgrp for block #%"PRIu64"\n", blkno); - return -1; + /* If we had a previous rgd, see if the block is represented by it. */ + if (*rgd) { + struct gfs_rindex *ri; + + ri = &(*rgd)->rd_ri; + if (ri->ri_data1 > blkno || + blkno >= ri->ri_data1 + ri->ri_data) { /* outside range */ + fs_rgrp_relse(*rgd); /* release the previous */ + *rgd = NULL; /* zero out to read a new one in */ + } } - if(fs_rgrp_read(rgd, FALSE)){ /* FALSE:don't try to fix (done elsewhere) */ - log_err( "Unable to read rgrp.\n"); - return -1; + if(*rgd == NULL) { + *rgd = fs_blk2rgrpd(sdp, blkno); + if(*rgd == NULL){ + log_err( "Unable to get rgrp for block #%"PRIu64"\n", + blkno); + return -1; + } + if(fs_rgrp_read(*rgd, FALSE)){ /* FALSE:don't try to fix + (done elsewhere) */ + log_err( "Unable to read rgrp.\n"); + return -1; + } } - rgrp_block = (uint32_t)(blkno - rgd->rd_ri.ri_data1); + rgrp_block = (uint32_t)(blkno - (*rgd)->rd_ri.ri_data1); - for(buf= 0; buf < rgd->rd_ri.ri_length; buf++){ - bits = &(rgd->rd_bits[buf]); + for(buf= 0; buf < (*rgd)->rd_ri.ri_length; buf++){ + bits = &((*rgd)->rd_bits[buf]); if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS_NBBY)){ break; } } - if(buf >= rgd->rd_ri.ri_length){ + if(buf >= (*rgd)->rd_ri.ri_length){ log_err( "Unable to locate bitmap entry for block #%"PRIu64"\n", - blkno); - fs_rgrp_relse(rgd); + blkno); + fs_rgrp_relse(*rgd); return -1; } - byte = (BH_DATA(rgd->rd_bh[buf]) + bits->bi_offset) + - (rgrp_block/GFS_NBBY - bits->bi_start); + byte = (unsigned char *)((BH_DATA((*rgd)->rd_bh[buf]) + + bits->bi_offset) + + (rgrp_block/GFS_NBBY - bits->bi_start)); bit = (rgrp_block % GFS_NBBY) * GFS_BIT_SIZE; val = ((*byte >> bit) & GFS_BIT_MASK); - if(local_rgd) { - fs_rgrp_relse(rgd); - } return val; } diff --git a/gfs/gfs_fsck/fs_bits.h b/gfs/gfs_fsck/fs_bits.h index 43efe52..02a1df7 100644 --- a/gfs/gfs_fsck/fs_bits.h +++ b/gfs/gfs_fsck/fs_bits.h @@ -38,10 +38,10 @@ uint32_t fs_bitfit(unsigned char *buffer, unsigned int buflen, /* functions with blk #'s that are rgrp relative */ uint32_t fs_blkalloc_internal(struct fsck_rgrp *rgd, uint32_t goal, unsigned char old_state, - unsigned char new_state, int do_it); + unsigned char new_state); /* functions with blk #'s that are file system relative */ -int fs_get_bitmap(struct fsck_sb *sdp, uint64_t blkno, struct fsck_rgrp *rgd); +int fs_get_bitmap(struct fsck_sb *sdp, uint64_t blkno, struct fsck_rgrp **rgd); int fs_set_bitmap(struct fsck_sb *sdp, uint64_t blkno, int state); #endif /* __FS_BITS_H__ */ diff --git a/gfs/gfs_fsck/fs_bmap.c b/gfs/gfs_fsck/fs_bmap.c index e5243ef..4ca4308 100644 --- a/gfs/gfs_fsck/fs_bmap.c +++ b/gfs/gfs_fsck/fs_bmap.c @@ -50,7 +50,7 @@ int fs_unstuff_dinode(struct fsck_inode *ip) } - error = get_and_read_buf(sdp, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(sdp, ip->i_num.no_addr, &dibh); if (error) { stack; goto fail; @@ -89,9 +89,8 @@ int fs_unstuff_dinode(struct fsck_inode *ip) goto fail; } relse_buf(sdp, bh); - block_set(sdp->bl, block, journal_blk); - } - else{ + block_set(sdp->bl, block, meta_other); + } else { error = fs_blkalloc(ip, &block); if(error) { @@ -207,7 +206,7 @@ static int build_height(struct fsck_inode *ip, int height) int error; while (ip->i_di.di_height < height){ - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh); if (error) goto fail; @@ -226,7 +225,7 @@ static int build_height(struct fsck_inode *ip, int height) if (error) goto fail_drelse; - error = get_and_read_buf(sdp, block, &bh, 0); + error = get_and_read_buf(sdp, block, &bh); if (error) goto fail_drelse; @@ -469,7 +468,7 @@ int fs_block_map(struct fsck_inode *ip, uint64 lblock, int *new, } - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &bh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &bh); if (error) goto fail; @@ -485,7 +484,7 @@ int fs_block_map(struct fsck_inode *ip, uint64 lblock, int *new, if (!*dblock) goto out; - error = get_and_read_buf(ip->i_sbd, *dblock, &bh, 0); + error = get_and_read_buf(ip->i_sbd, *dblock, &bh); if (error) goto fail; } @@ -522,7 +521,7 @@ int fs_block_map(struct fsck_inode *ip, uint64 lblock, int *new, out: if (*new){ - error = get_and_read_buf(sdp, ip->i_num.no_addr, &bh, 0); + error = get_and_read_buf(sdp, ip->i_num.no_addr, &bh); if (error) goto fail; gfs_dinode_out(&ip->i_di, BH_DATA(bh)); diff --git a/gfs/gfs_fsck/fs_dir.c b/gfs/gfs_fsck/fs_dir.c index 3dcfcea..f5b9613 100644 --- a/gfs/gfs_fsck/fs_dir.c +++ b/gfs/gfs_fsck/fs_dir.c @@ -200,7 +200,7 @@ static int get_leaf(struct fsck_inode *dip, uint64 leaf_no, osi_buf_t **bhp) { int error; - error = get_and_read_buf(dip->i_sbd, leaf_no, bhp, 0); + error = get_and_read_buf(dip->i_sbd, leaf_no, bhp); if (error) { log_err("Unable to read leaf buffer #%"PRIu64"\n", leaf_no); @@ -547,7 +547,7 @@ static int dir_l_search(struct fsck_inode *dip, identifier_t *id, unsigned int * return -1; } - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh); if (error) goto out; @@ -619,7 +619,7 @@ static int dir_make_exhash(struct fsck_inode *dip) return -1; } - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh); if (error) goto fail; @@ -632,7 +632,7 @@ static int dir_make_exhash(struct fsck_inode *dip) /* Turn over a new leaf */ - error = get_and_read_buf(sdp, bn, &bh, 0); + error = get_and_read_buf(sdp, bn, &bh); if (error) goto fail_drelse; @@ -767,7 +767,7 @@ static int dir_split_leaf(struct fsck_inode *dip, uint32 index, uint64 leaf_no) /* Get the new leaf block */ - error = get_and_read_buf(sdp, bn, &nbh, 0); + error = get_and_read_buf(sdp, bn, &nbh); if (error) goto fail; @@ -916,7 +916,7 @@ static int dir_split_leaf(struct fsck_inode *dip, uint32 index, uint64 leaf_no) nleaf->lf_depth = oleaf->lf_depth; - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh); if(error){ log_err("dir_split_leaf: Unable to get inode buffer.\n"); goto fail_orelse; @@ -1042,7 +1042,7 @@ static int dir_double_exhash(struct fsck_inode *dip) free(buf); buf=NULL; - error = get_and_read_buf(sdp, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(sdp, dip->i_num.no_addr, &dibh); if(error){ log_err("dir_double_exhash: " "Unable to get inode buffer.\n"); @@ -1157,7 +1157,7 @@ static int dir_l_del(struct fsck_inode *dip, osi_buf_t *dibh, if(!dibh) { error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, - &dibh, 0); + &dibh); if (error){ log_err("dir_l_del: Failed to read in dinode buffer.\n"); return -1; @@ -1320,7 +1320,7 @@ static int dir_e_add(struct fsck_inode *dip, osi_filename_t *filename, return error; } - error = get_and_read_buf(sdp, bn, &nbh, 0); + error = get_and_read_buf(sdp, bn, &nbh); if (error){ relse_buf(sdp, bh); return error; @@ -1377,7 +1377,7 @@ static int dir_e_add(struct fsck_inode *dip, osi_filename_t *filename, write_buf(sdp, bh, 0); relse_buf(sdp, bh); - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh); if(error){ log_err("dir_e_add: Unable to get inode buffer.\n"); return error; @@ -1431,7 +1431,7 @@ static int dir_l_add(struct fsck_inode *dip, osi_filename_t *filename, return -1; } - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh); if (error) goto out; diff --git a/gfs/gfs_fsck/fs_inode.c b/gfs/gfs_fsck/fs_inode.c index fadc073..a2f6a10 100644 --- a/gfs/gfs_fsck/fs_inode.c +++ b/gfs/gfs_fsck/fs_inode.c @@ -86,7 +86,7 @@ int fs_copyin_dinode(struct fsck_inode *ip, osi_buf_t *dibh) if(!dibh) { error = get_and_read_buf(ip->i_sbd, - ip->i_num.no_addr, &dibh, 0); + ip->i_num.no_addr, &dibh); if (error) { stack; goto out; @@ -122,7 +122,7 @@ int fs_copyout_dinode(struct fsck_inode *ip){ osi_buf_t *dibh; int error; - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh); if(error){ log_err( "Unable to get a buffer to write dinode to disk.\n"); return -1; @@ -159,7 +159,7 @@ static int make_dinode(struct fsck_inode *dip, struct gfs_inum *inum, struct fsck_rgrp *rgd; int error; - error = get_and_read_buf(sdp, inum->no_addr, &dibh, 0); + error = get_and_read_buf(sdp, inum->no_addr, &dibh); if (error) goto out; @@ -258,7 +258,7 @@ static int fs_change_nlink(struct fsck_inode *ip, int diff) if(nlink >= ip->i_di.di_nlink) log_err( "fs_change_nlink: Bad link count detected in dinode.\n"); - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh); if (error) goto out; @@ -400,7 +400,7 @@ int fs_createi(struct fsck_inode *dip, osi_filename_t *name, if(rgd->rd_rg.rg_freemeta){ block = fs_blkalloc_internal(rgd, dip->i_num.no_addr, GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); + GFS_BLKST_USEDMETA); log_debug("Got block %"PRIu64"\n", block); if(block == BFITNOENT) { fs_rgrp_relse(rgd); @@ -429,7 +429,7 @@ int fs_createi(struct fsck_inode *dip, osi_filename_t *name, if(!clump_alloc(rgd, 0)){ block = fs_blkalloc_internal(rgd, dip->i_num.no_addr, GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); + GFS_BLKST_USEDMETA); log_debug("Got block %"PRIu64"\n", block); if(block == BFITNOENT) { @@ -544,7 +544,7 @@ int fs_mkdir(struct fsck_inode *dip, char *new_dir, int mode, struct fsck_inode ip->i_di.di_payload_format = GFS_FORMAT_DE; ip->i_di.di_entries = 2; - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); + error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh); if(error){ log_err( "fs_mkdir: Unable to aquire directory buffer.\n"); goto fail; diff --git a/gfs/gfs_fsck/initialize.c b/gfs/gfs_fsck/initialize.c index 8d029b8..2b278d1 100644 --- a/gfs/gfs_fsck/initialize.c +++ b/gfs/gfs_fsck/initialize.c @@ -348,7 +348,7 @@ static int fill_super_block(struct fsck_sb *sdp) goto fail; } - sdp->bl = block_list_create(sdp->last_fs_block+1, gbmap); + sdp->bl = block_list_create(sdp->last_fs_block+1); if (!sdp->bl) goto fail; diff --git a/gfs/gfs_fsck/inode.c b/gfs/gfs_fsck/inode.c index e180ba0..1d3790f 100644 --- a/gfs/gfs_fsck/inode.c +++ b/gfs/gfs_fsck/inode.c @@ -51,7 +51,7 @@ int load_inode(struct fsck_sb *sbp, uint64_t block, struct fsck_inode **inode) { osi_buf_t *bh; - if(get_and_read_buf(sbp, block, &bh, 0)){ + if(get_and_read_buf(sbp, block, &bh)){ stack; log_err("Unable to retrieve block %"PRIu64"\n", block); @@ -176,7 +176,7 @@ static int make_dinode(struct fsck_inode *dip, struct fsck_sb *sdp, struct fsck_rgrp *rgd; int error; - error = get_and_read_buf(sdp, inum->no_addr, &dibh, 0); + error = get_and_read_buf(sdp, inum->no_addr, &dibh); if (error) goto out; @@ -271,7 +271,7 @@ int create_inode(struct fsck_sb *sbp, unsigned int type, struct fsck_inode **ip) } if(rgd->rd_rg.rg_freemeta){ block = fs_blkalloc_internal(rgd, 0, - GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA, 1); + GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); log_debug("Got block %"PRIu64"\n", block); if(block == BFITNOENT) { fs_rgrp_relse(rgd); @@ -292,7 +292,7 @@ int create_inode(struct fsck_sb *sbp, unsigned int type, struct fsck_inode **ip) if(allocate && !clump_alloc(rgd, 0)){ block = fs_blkalloc_internal(rgd, 0, GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); + GFS_BLKST_USEDMETA); log_debug("Got block %"PRIu64"\n", block); if(block == BFITNOENT) { diff --git a/gfs/gfs_fsck/metawalk.c b/gfs/gfs_fsck/metawalk.c index 3475bb9..e28a1cc 100644 --- a/gfs/gfs_fsck/metawalk.c +++ b/gfs/gfs_fsck/metawalk.c @@ -214,7 +214,7 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update, if (first_leaf_ptr == -1) first_leaf_ptr = first_ok_leaf; if(check_range(sbp, first_ok_leaf) == 0) { - get_and_read_buf(sbp, first_ok_leaf, &lbh, 0); + get_and_read_buf(sbp, first_ok_leaf, &lbh); /* Make sure it's really a valid leaf block. */ if (check_meta(lbh, GFS_METATYPE_LF) == 0) { relse_buf(sbp, lbh); @@ -262,7 +262,7 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update, int factor = 0, divisor = ref_count; errors_corrected++; - get_and_read_buf(sbp, old_leaf, &lbh, 0); + get_and_read_buf(sbp, old_leaf, &lbh); while (divisor > 1) { factor++; divisor /= 2; @@ -295,7 +295,7 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update, } *update = 0; /* Try to read in the leaf block. */ - if(get_and_read_buf(sbp, leaf_no, &lbh, 0)){ + if(get_and_read_buf(sbp, leaf_no, &lbh)){ log_err("Unable to read leaf block #%" PRIu64" for " "directory #%"PRIu64".\n", @@ -353,7 +353,7 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update, if(update && (count != leaf.lf_entries)) { if(get_and_read_buf(sbp, leaf_no, - &lbh, 0)){ + &lbh)){ log_err("Unable to read leaf block #%" PRIu64" for " "directory #%"PRIu64".\n", @@ -665,7 +665,7 @@ static int build_metalist(struct fsck_inode *ip, osi_list_t *mlp, uint64 *ptr, block; int err; - if(get_and_read_buf(ip->i_sbd, ip->i_di.di_num.no_addr, &metabh, 0)) { + if(get_and_read_buf(ip->i_sbd, ip->i_di.di_num.no_addr, &metabh)) { stack; return -1; } @@ -716,7 +716,7 @@ static int build_metalist(struct fsck_inode *ip, osi_list_t *mlp, } if(!nbh) { if(get_and_read_buf(ip->i_sbd, block, - &nbh, 0)) { + &nbh)) { stack; goto fail; } @@ -759,6 +759,7 @@ int check_metatree(struct fsck_inode *ip, struct metawalk_fxns *pass) int i, head_size; int update = 0; int error = 0; + struct fsck_rgrp *rgd; if (!height) goto end; @@ -781,6 +782,7 @@ int check_metatree(struct fsck_inode *ip, struct metawalk_fxns *pass) /* check data blocks */ list = &metalist[height - 1]; + rgd = NULL; for (tmp = list->next; tmp != list; tmp = tmp->next) { bh = osi_list_entry(tmp, osi_buf_t, b_list); @@ -805,13 +807,17 @@ int check_metatree(struct fsck_inode *ip, struct metawalk_fxns *pass) block = gfs64_to_cpu(*ptr); if(pass->check_data && - (pass->check_data(ip, block, pass->private) < 0)) { + (pass->check_data(ip, block, &rgd, + pass->private) < 0)) { stack; return -1; } } } + if (rgd) + fs_rgrp_relse(rgd); + /* free metalists */ for (i = 0; i < GFS_MAX_META_HEIGHT; i++) { @@ -863,7 +869,7 @@ int check_dir(struct fsck_sb *sbp, uint64_t block, struct metawalk_fxns *pass) int update = 0; int error = 0; - if(get_and_read_buf(sbp, block, &bh, 0)){ + if(get_and_read_buf(sbp, block, &bh)){ log_err("Unable to retrieve block #%"PRIu64"\n", block); block_set(sbp->bl, block, meta_inval); @@ -1047,7 +1053,7 @@ void free_block(struct fsck_sb *sdp, uint64_t block) fs_set_bitmap(sdp, block, GFS_BLKST_FREE); /* Adjust the free space count for the freed block */ rgd = fs_blk2rgrpd(sdp, block); /* find the rg for indir block */ - get_and_read_buf(sdp, rgd->rd_ri.ri_addr, &bh, 0); + get_and_read_buf(sdp, rgd->rd_ri.ri_addr, &bh); rgd->rd_rg.rg_free++; /* adjust the free count */ gfs_rgrp_out(&rgd->rd_rg, bh->b_data); /* back to the buffer */ relse_buf(sdp, bh); /* release the buffer */ @@ -1081,7 +1087,8 @@ int delete_metadata(struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, return delete_blocks(ip, block, bh, "metadata", private); } -int delete_data(struct fsck_inode *ip, uint64_t block, void *private) +int delete_data(struct fsck_inode *ip, uint64_t block, struct fsck_rgrp **rgd, + void *private) { return delete_blocks(ip, block, NULL, "data", private); } diff --git a/gfs/gfs_fsck/metawalk.h b/gfs/gfs_fsck/metawalk.h index 3dc7aac..4aa9ff7 100644 --- a/gfs/gfs_fsck/metawalk.h +++ b/gfs/gfs_fsck/metawalk.h @@ -31,7 +31,8 @@ int delete_blocks(struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, const char *btype, void *private); int delete_metadata(struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, void *private); -int delete_data(struct fsck_inode *ip, uint64_t block, void *private); +int delete_data(struct fsck_inode *ip, uint64_t block, struct fsck_rgrp **rgd, + void *private); int delete_eattr_indir(struct fsck_inode *ip, uint64_t block, uint64_t parent, osi_buf_t **bh, void *private); int delete_eattr_leaf(struct fsck_inode *ip, uint64_t block, uint64_t parent, @@ -59,7 +60,7 @@ struct metawalk_fxns { int (*check_metalist) (struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, void *private); int (*check_data) (struct fsck_inode *ip, uint64_t block, - void *private); + struct fsck_rgrp **rgd, void *private); int (*check_eattr_indir) (struct fsck_inode *ip, uint64_t block, uint64_t parent, osi_buf_t **bh, void *private); diff --git a/gfs/gfs_fsck/pass1.c b/gfs/gfs_fsck/pass1.c index caa7660..4b9de02 100644 --- a/gfs/gfs_fsck/pass1.c +++ b/gfs/gfs_fsck/pass1.c @@ -45,7 +45,8 @@ static int leaf(struct fsck_inode *ip, uint64_t block, osi_buf_t *bh, void *private); static int check_metalist(struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, void *private); -static int check_data(struct fsck_inode *ip, uint64_t block, void *private); +static int check_data(struct fsck_inode *ip, uint64_t block, + struct fsck_rgrp **rgd, void *private); static int check_eattr_indir(struct fsck_inode *ip, uint64_t indirect, uint64_t parent, osi_buf_t **bh, void *private); @@ -116,7 +117,7 @@ static int check_metalist(struct fsck_inode *ip, uint64_t block, block_mark(sdp->bl, block, dup_block); found_dup = 1; } - get_and_read_buf(ip->i_sbd, block, &nbh, 0); + get_and_read_buf(ip->i_sbd, block, &nbh); if (check_meta(nbh, GFS_METATYPE_IN)){ log_debug("Bad indirect block pointer (points to " @@ -140,7 +141,8 @@ static int check_metalist(struct fsck_inode *ip, uint64_t block, return 0; } -static int check_data(struct fsck_inode *ip, uint64_t block, void *private) +static int check_data(struct fsck_inode *ip, uint64_t block, + struct fsck_rgrp **rgd, void *private) { struct fsck_sb *sdp = ip->i_sbd; struct block_query q = {0}; @@ -160,7 +162,7 @@ static int check_data(struct fsck_inode *ip, uint64_t block, void *private) return 1; } - if(get_and_read_buf(ip->i_sbd, block, &data_bh, 0)) { + if(get_and_read_buf(ip->i_sbd, block, &data_bh)) { stack; block_set(sdp->bl, ip->i_di.di_num.no_addr, meta_inval); return 1; @@ -216,7 +218,7 @@ static int check_data(struct fsck_inode *ip, uint64_t block, void *private) block_unmark(sdp->bl, block, meta_inval); block_mark(sdp->bl, block, dup_block); } - block_mark(sdp->bl, block, journal_blk); + block_mark(sdp->bl, block, meta_other); } else { if(q.block_type != block_free) { log_err("Found duplicate block referenced as data " @@ -251,7 +253,7 @@ static int check_data(struct fsck_inode *ip, uint64_t block, void *private) code in pass1b.c is better at resolving metadata referencing a data block than it is at resolving a data block referencing a metadata block. */ - btype = fs_get_bitmap(ip->i_sbd, block, NULL); + btype = fs_get_bitmap(ip->i_sbd, block, rgd); if (btype != GFS_BLKST_USED && btype != GFS_BLKST_USEDMETA) { const char *allocdesc[] = {"free space", "data", "free metadata", "metadata", @@ -305,7 +307,7 @@ static int remove_inode_eattr(struct fsck_inode *ip, struct block_count *bc, bc->ea_count = 0; ip->i_di.di_blocks = 1 + bc->indir_count + bc->data_count; ip->i_di.di_flags &= ~GFS_DIF_EA_INDIRECT; - if (get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0)) { + if (get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh)) { log_err("The bad Extended Attribute could not be fixed.\n"); bc->ea_count++; return 1; @@ -413,7 +415,7 @@ static int check_eattr_indir(struct fsck_inode *ip, uint64_t indirect, check if it really is an EA. If it is, let duplicate handling sort it out. If it isn't, clear it but don't count it as a duplicate. */ - if(get_and_read_buf(sdp, indirect, bh, 0)) { + if(get_and_read_buf(sdp, indirect, bh)) { log_warn("Unable to read Extended Attribute indirect block " "#%"PRIu64".\n", indirect); block_set(sdp->bl, indirect, meta_inval); @@ -496,7 +498,7 @@ static int check_leaf_block(struct fsck_inode *ip, uint64_t block, int btype, /* Special duplicate processing: If we have an EA block, check if it really is an EA. If it is, let duplicate handling sort it out. If it isn't, clear it but don't count it as a duplicate. */ - if(get_and_read_buf(sdp, block, &leaf_bh, 0)){ + if(get_and_read_buf(sdp, block, &leaf_bh)){ log_err("Unable to read leaf block %lld.\n", block); return -1; } @@ -661,7 +663,8 @@ static int clear_metalist(struct fsck_inode *ip, uint64_t block, return 0; } -static int clear_data(struct fsck_inode *ip, uint64_t block, void *private) +static int clear_data(struct fsck_inode *ip, uint64_t block, + struct fsck_rgrp **rgd, void *private) { struct fsck_sb *sdp = ip->i_sbd; struct block_query q = {0}; @@ -957,7 +960,7 @@ static int handle_di(struct fsck_sb *sdp, osi_buf_t *bh, uint64_t block, int mfr ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count + bc.ea_count; if(get_and_read_buf(sdp, ip->i_di.di_num.no_addr, - &di_bh, 0)){ + &di_bh)){ stack; log_crit("Bad block count remains\n"); } else { @@ -1060,7 +1063,7 @@ int pass1(struct fsck_sb *sbp) for(j = ji->ji_addr; j < ji->ji_addr + (ji->ji_nsegment * sbp->sb.sb_seg_size); j++) { - if(block_set(sbp->bl, j, journal_blk)) { + if(block_set(sbp->bl, j, meta_other)) { stack; return FSCK_ERROR; } @@ -1113,7 +1116,7 @@ int pass1(struct fsck_sb *sbp) skip_this_pass = FALSE; fflush(stdout); } - if(get_and_read_buf(sbp, block, &bh, 0)){ + if(get_and_read_buf(sbp, block, &bh)){ stack; log_crit("Unable to retrieve block %"PRIu64 "\n", block); diff --git a/gfs/gfs_fsck/pass1b.c b/gfs/gfs_fsck/pass1b.c index 9a348ed..17a5444 100644 --- a/gfs/gfs_fsck/pass1b.c +++ b/gfs/gfs_fsck/pass1b.c @@ -67,7 +67,8 @@ static int check_metalist(struct fsck_inode *ip, uint64_t block, return 0; } -static int check_data(struct fsck_inode *ip, uint64_t block, void *private) +static int check_data(struct fsck_inode *ip, uint64_t block, + struct fsck_rgrp **rgd, void *private) { inc_if_found(block, 1, private); @@ -81,7 +82,7 @@ static int check_eattr_indir(struct fsck_inode *ip, uint64_t block, osi_buf_t *indir_bh = NULL; inc_if_found(block, 0, private); - if(get_and_read_buf(sbp, block, &indir_bh, 0)){ + if(get_and_read_buf(sbp, block, &indir_bh)){ log_warn("Unable to read EA leaf block #%"PRIu64".\n", block); return 1; @@ -99,7 +100,7 @@ static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, osi_buf_t *leaf_bh = NULL; inc_if_found(block, 0, private); - if(get_and_read_buf(sbp, block, &leaf_bh, 0)){ + if(get_and_read_buf(sbp, block, &leaf_bh)){ log_err("Unable to read EA leaf block #%"PRIu64".\n", block); return 1; @@ -193,7 +194,8 @@ static int clear_dup_metalist(struct fsck_inode *ip, uint64_t block, } return 0; } -static int clear_dup_data(struct fsck_inode *ip, uint64_t block, void *private) +static int clear_dup_data(struct fsck_inode *ip, uint64_t block, + struct fsck_rgrp **rgd, void *private) { return clear_dup_metalist(ip, block, NULL, private); } @@ -425,7 +427,7 @@ static int handle_dup_blk(struct fsck_sb *sbp, struct blocks *b) osi_buf_t *bh; uint32_t cmagic; - get_and_read_buf(sbp, b->block_no, &bh, 0); + get_and_read_buf(sbp, b->block_no, &bh); cmagic = ((struct gfs_meta_header *)(bh->b_data))->mh_magic; relse_buf(sbp, bh); if (be32_to_cpu(cmagic) == GFS_MAGIC) { diff --git a/gfs/gfs_fsck/pass1c.c b/gfs/gfs_fsck/pass1c.c index 6bec08d..4760170 100644 --- a/gfs/gfs_fsck/pass1c.c +++ b/gfs/gfs_fsck/pass1c.c @@ -113,7 +113,7 @@ static int check_eattr_indir(struct fsck_inode *ip, uint64_t block, (unsigned long long)ip->i_num.no_addr); return ask_remove_eattr(ip); } - else if(get_and_read_buf(sbp, block, &indir_bh, 0)){ + else if(get_and_read_buf(sbp, block, &indir_bh)){ log_warn("Unable to read Extended Attribute leaf block " "#%"PRIu64".\n", block); return ask_remove_eattr(ip); @@ -146,7 +146,7 @@ static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, block, ip->i_num.no_addr); return ask_remove_eattr(ip); } - else if(get_and_read_buf(sbp, block, &leaf_bh, 0)){ + else if(get_and_read_buf(sbp, block, &leaf_bh)){ log_warn("Unable to read Extended attributes leaf block " "#%"PRIu64".\n", block); return ask_remove_eattr(ip); @@ -270,7 +270,7 @@ int pass1c(struct fsck_sb *sbp) if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; log_info("EA in inode %"PRIu64"\n", block_no); - if(get_and_read_buf(sbp, block_no, &bh, 0)) { + if(get_and_read_buf(sbp, block_no, &bh)) { stack; return FSCK_ERROR; } diff --git a/gfs/gfs_fsck/pass2.c b/gfs/gfs_fsck/pass2.c index b6845cf..ba3462d 100644 --- a/gfs/gfs_fsck/pass2.c +++ b/gfs/gfs_fsck/pass2.c @@ -99,7 +99,7 @@ static int check_eattr_indir(struct fsck_inode *ip, uint64_t block, osi_buf_t *indir_bh; - if(get_and_read_buf(ip->i_sbd, block, &indir_bh, 0)){ + if(get_and_read_buf(ip->i_sbd, block, &indir_bh)){ log_warn("Unable to read EA indir block #%"PRIu64".\n", block); block_set(ip->i_sbd->bl, block, meta_inval); @@ -114,7 +114,7 @@ static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, { osi_buf_t *leaf_bh = NULL; - if(get_and_read_buf(ip->i_sbd, block, &leaf_bh, 0)){ + if(get_and_read_buf(ip->i_sbd, block, &leaf_bh)){ log_warn("Unable to read EA leaf block #%"PRIu64".\n", block); block_set(ip->i_sbd->bl, block, meta_inval); @@ -258,7 +258,7 @@ static int check_dentry(struct fsck_inode *ip, struct gfs_dirent *dent, return -1; } /* Get the status of the directory inode */ - if(q.bad_block) { + if(q.block_type == bad_block) { /* This entry's inode has bad blocks in it */ /* Handle bad blocks */ @@ -320,7 +320,7 @@ static int check_dentry(struct fsck_inode *ip, struct gfs_dirent *dent, return 1; /* Now try to clear the dinode, if it is an dinode */ - get_and_read_buf(sbp, de->de_inum.no_addr, &bhi, 0); + get_and_read_buf(sbp, de->de_inum.no_addr, &bhi); error = check_meta(bhi, GFS_METATYPE_DI); relse_buf(sbp, bhi); if (error) @@ -573,7 +573,7 @@ static int build_rooti(struct fsck_sb *sbp) { struct fsck_inode *ip; osi_buf_t *bh; - get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh, 0); + get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh); /* Create a new inode ondisk */ create_inode(sbp, GFS_FILE_DIR, &ip); /* Attach it to the superblock's sb_root_di address */ @@ -673,7 +673,7 @@ static int check_root_dir(struct fsck_sb *sbp) rootblock = sbp->sb.sb_root_di.no_addr; pass2_fxns.private = (void *) &ds; - if(ds.q.bad_block) { + if(ds.q.block_type == bad_block) { /* First check that the directory's metatree is valid */ load_inode(sbp, rootblock, &ip); if(check_metatree(ip, &pass2_fxns)) { @@ -692,7 +692,7 @@ static int check_root_dir(struct fsck_sb *sbp) block_set(sbp->bl, rootblock, meta_inval); } - if(get_and_read_buf(sbp, rootblock, &bh, 0)){ + if(get_and_read_buf(sbp, rootblock, &bh)){ log_err("Unable to retrieve block #%"PRIu64"\n", rootblock); block_set(sbp->bl, rootblock, meta_inval); @@ -750,7 +750,7 @@ static int check_root_dir(struct fsck_sb *sbp) log_err("The directory was not fixed.\n"); } free_inode(&ip); - if(get_and_read_buf(sbp, rootblock, &bh, 0)){ + if(get_and_read_buf(sbp, rootblock, &bh)){ log_err("Unable to retrieve block #%"PRIu64"\n", rootblock); block_set(sbp->bl, rootblock, meta_inval); @@ -843,7 +843,7 @@ int pass2(struct fsck_sb *sbp, struct options *opts) memset(&ds, 0, sizeof(ds)); pass2_fxns.private = (void *) &ds; - if(ds.q.bad_block) { + if(ds.q.block_type == bad_block) { /* First check that the directory's metatree * is valid */ load_inode(sbp, i, &ip); @@ -892,7 +892,7 @@ int pass2(struct fsck_sb *sbp, struct options *opts) } block_set(sbp->bl, i, meta_inval); } - if(get_and_read_buf(sbp, i, &bh, 0)){ + if(get_and_read_buf(sbp, i, &bh)){ /* This shouldn't happen since we were able to * read it before */ log_err("Unable to retrieve block #%"PRIu64 diff --git a/gfs/gfs_fsck/pass3.c b/gfs/gfs_fsck/pass3.c index 0fafa18..409d5af 100644 --- a/gfs/gfs_fsck/pass3.c +++ b/gfs/gfs_fsck/pass3.c @@ -223,7 +223,7 @@ int pass3(struct fsck_sb *sbp, struct options *opts) stack; return FSCK_ERROR; } - if(q.bad_block) { + if(q.block_type == bad_block) { log_err("Found unlinked directory containing" "bad block\n"); errors_found++; diff --git a/gfs/gfs_fsck/pass4.c b/gfs/gfs_fsck/pass4.c index 1adb355..b90c8b5 100644 --- a/gfs/gfs_fsck/pass4.c +++ b/gfs/gfs_fsck/pass4.c @@ -79,9 +79,8 @@ static int scan_inode_list(struct fsck_sb *sbp, osi_list_t *list) { stack; return -1; } - if(q.bad_block) { - log_err("Unlinked inode contains" - "bad blocks\n", + if(q.block_type == bad_block) { + log_err("Unlinked inode contains bad blocks\n", ii->inode); errors_found++; if(query(sbp, "Delete unlinked inode with bad " diff --git a/gfs/gfs_fsck/pass5.c b/gfs/gfs_fsck/pass5.c index 2cc6425..2021ddd 100644 --- a/gfs/gfs_fsck/pass5.c +++ b/gfs/gfs_fsck/pass5.c @@ -84,7 +84,6 @@ int fsck_countbits(struct fsck_sb *sbp, uint64_t start_blk, uint64_t count, case inode_dir: case inode_file: case leaf_blk: - case journal_blk: case meta_other: case meta_eattr: bit_array[3]++; @@ -161,7 +160,6 @@ static int convert_mark(enum mark_block mark, uint32_t *count) case indir_blk: case leaf_blk: - case journal_blk: case meta_other: case meta_eattr: count[3]++; diff --git a/gfs/gfs_fsck/rgrp.c b/gfs/gfs_fsck/rgrp.c index 101e6e6..046679e 100644 --- a/gfs/gfs_fsck/rgrp.c +++ b/gfs/gfs_fsck/rgrp.c @@ -179,7 +179,7 @@ int fs_rgrp_read(struct fsck_rgrp *rgd, int repair_if_corrupted) exit(FSCK_ERROR); } error = get_and_read_buf(sdp, rgd->rd_ri.ri_addr + x, - &(rgd->rd_bh[x]), 0); + &(rgd->rd_bh[x])); if (error) { log_err("Unable to read rgrp from disk.\n"); goto fail; @@ -445,7 +445,7 @@ int clump_alloc(struct fsck_rgrp *rgd, uint32 goal) for (i = 0; i < GFS_META_CLUMP; i++){ block = fs_blkalloc_internal(rgd, goal, GFS_BLKST_FREE, - GFS_BLKST_FREEMETA, TRUE); + GFS_BLKST_FREEMETA); log_debug("Got block %u\n", block); if(block == BFITNOENT) { @@ -537,7 +537,7 @@ int fs_blkalloc(struct fsck_inode *ip, uint64 *block) *block = fs_blkalloc_internal(rgd, goal, GFS_BLKST_FREE, - GFS_BLKST_USED, TRUE); + GFS_BLKST_USED); log_debug("Got block %"PRIu64"\n", *block); if(*block == BFITNOENT) { @@ -618,7 +618,7 @@ int fs_metaalloc(struct fsck_inode *ip, uint64 *block) } *block = fs_blkalloc_internal(rgd, goal, GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, TRUE); + GFS_BLKST_USEDMETA); log_debug("Got block %"PRIu64"\n", *block); if(*block == BFITNOENT) { fs_rgrp_relse(rgd); diff --git a/gfs/gfs_fsck/super.c b/gfs/gfs_fsck/super.c index d5f5a58..30030d4 100644 --- a/gfs/gfs_fsck/super.c +++ b/gfs/gfs_fsck/super.c @@ -108,7 +108,7 @@ int read_sb(struct fsck_sb *sdp) uint64 space = 0; unsigned int x; int error; - error = get_and_read_buf(sdp, GFS_SB_ADDR >> sdp->fsb2bb_shift, &bh, 0); + error = get_and_read_buf(sdp, GFS_SB_ADDR >> sdp->fsb2bb_shift, &bh); if (error){ log_crit("Unable to read superblock\n"); goto out; @@ -506,7 +506,7 @@ int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, number_of_rgs = 0; shortest_dist_btwn_rgs[subd] = subdevice_size; for (blok = start_block; blok < fs_total_size; blok++) { - error = get_and_read_buf(sdp, blok, &bh, 0); + error = get_and_read_buf(sdp, blok, &bh); if (error){ log_crit("Unable to read block 0x%" PRIX64 "\n", blok); return -1; @@ -723,7 +723,7 @@ int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, /* blocks early. So we need to check for this special case. */ for (start_block = end_block - 2; start_block < end_block + 1; start_block++) { - error = get_and_read_buf(sdp, start_block, &bh, 0); + error = get_and_read_buf(sdp, start_block, &bh); rg_was_fnd = (!check_type(bh, GFS_METATYPE_RG)); relse_buf(sdp, bh); /* release the read buffer */ if (rg_was_fnd) @@ -740,7 +740,7 @@ int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, int bitmap_was_fnd; log_debug("Block 0x%" PRIx64 "\n", blok); - error = get_and_read_buf(sdp, blok, &bh, 0); + error = get_and_read_buf(sdp, blok, &bh); if (error) { log_crit("Unable to read block 0x%" PRIX64 "\n", blok); return -1; @@ -787,7 +787,7 @@ int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, bitmap_was_fnd = FALSE; for (fwd_block = blok + 1; fwd_block < fs_total_size; fwd_block++) { - error = get_and_read_buf(sdp, fwd_block, &bh, 0); + error = get_and_read_buf(sdp, fwd_block, &bh); if (error){ log_crit("Unable to read block 0x%" PRIX64 "\n", fwd_block); @@ -884,7 +884,7 @@ int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, if (block_bump == 1 && prev_rgd && subd == 2) { uint64_t last_distance = blok - prev_rgd->rd_ri.ri_addr; - error = get_and_read_buf(sdp, blok + last_distance, &bh, 0); + error = get_and_read_buf(sdp, blok + last_distance, &bh); rg_was_fnd = (!check_type(bh, GFS_METATYPE_RG)); relse_buf(sdp, bh); /* release the read buffer */ if (rg_was_fnd) @@ -1066,7 +1066,7 @@ int gfs_rgindex_calculate(struct fsck_sb *sdp, osi_list_t *ret_list, /* Read the first block of the subdevice and make sure it's an RG. */ /* ----------------------------------------------------------------- */ subdevice_start = dvice.subdev[sdp->journals + 1].start; - error = get_and_read_buf(sdp, subdevice_start, &bh, 0); + error = get_and_read_buf(sdp, subdevice_start, &bh); if (error){ log_crit("Unable to read start of last subdevice.\n"); return -1; @@ -1393,7 +1393,7 @@ int ri_update(struct fsck_sb *sdp) if (fix_grow_problems) { osi_buf_t *dibh; - get_and_read_buf(sdp, sdp->sb.sb_rindex_di.no_addr, &dibh, 0); + get_and_read_buf(sdp, sdp->sb.sb_rindex_di.no_addr, &dibh); sdp->riinode->i_di.di_size = rg * sizeof(struct gfs_rindex); gfs_dinode_out(&sdp->riinode->i_di, BH_DATA(dibh)); write_buf(sdp, dibh, 0); @@ -1425,7 +1425,7 @@ int write_sb(struct fsck_sb *sbp) int error = 0; osi_buf_t *bh; - error = get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh, 0); + error = get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh); if (error){ log_crit("Unable to read superblock\n"); goto out; diff --git a/gfs/gfs_fsck/util.c b/gfs/gfs_fsck/util.c index e81bc31..bb53d8c 100644 --- a/gfs/gfs_fsck/util.c +++ b/gfs/gfs_fsck/util.c @@ -268,7 +268,7 @@ int next_rg_metatype(struct fsck_rgrp *rgd, uint64 *block, uint32 type, int firs if(next_rg_meta(rgd, block, first)) return -1; - if(get_and_read_buf(sdp, *block, &bh, 0)){ + if(get_and_read_buf(sdp, *block, &bh)){ log_err("next_rg_metatype: Unable to read meta block " "#%"PRIu64" from disk\n", *block); exit(FSCK_ERROR);