commit e9316e5043402ba0cdc66fe70e90538fd88a4797 Author: Bob Peterson <bob@ganesha.peterson> Date: Wed Nov 25 14:36:14 2009 -0600 Separate eattr_block list from the rest for efficiency There were only a few rare places where the eattr special list was being used in fsck.gfs2. By moving those places outside the general bitmap functions the general case is faster. rhbz#455300 diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c index f011c64..80f253f 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -405,8 +405,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers, (unsigned long long)ip->i_di.di_num.no_addr); /* Mark the inode as having an eattr in the block map so pass1c can check it. */ - gfs2_block_mark(ip->i_sbd, bl, ip->i_di.di_num.no_addr, - gfs2_eattr_block); + gfs2_special_set(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr); if (!leaf_pointer_errors) return 0; log_err( _("Inode %lld (0x%llx) has recoverable indirect " @@ -544,7 +543,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, "block(s) attached.\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); - gfs2_block_mark(sdp, bl, ip->i_di.di_num.no_addr, gfs2_eattr_block); + gfs2_special_set(&sdp->eattr_blocks, ip->i_di.di_num.no_addr); if(gfs2_check_range(sdp, block)) { log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf " "block #%llu (0x%llx) is out of range.\n"), diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c index f707efc..c1cc623 100644 --- a/gfs2/fsck/pass1c.c +++ b/gfs2/fsck/pass1c.c @@ -277,7 +277,7 @@ int pass1c(struct gfs2_sbd *sbp) if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */ log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"), block_no, block_no); - gfs2_block_unmark(sbp, bl, block_no, gfs2_eattr_block); + gfs2_special_clear(&sbp->eattr_blocks, block_no); ip = fsck_inode_get(sbp, bh); log_debug( _("Found eattr at %llu (0x%llx)\n"), diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index 98cdeef..6e16235 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -25,10 +25,6 @@ static int convert_mark(struct gfs2_block_query *q, uint32_t *count) { - if (q->eattr_block) { - count[2]++; - return GFS2_BLKST_USED; - } switch(q->block_type) { case gfs2_meta_inval: diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c index 7fec19d..5a23351 100644 --- a/gfs2/libgfs2/block_list.c +++ b/gfs2/libgfs2/block_list.c @@ -192,22 +192,22 @@ static void gfs2_dup_set(struct dup_blocks *blocklist, uint64_t block) return; } -static void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block) +static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block) { - struct special_blocks *b; + struct dup_blocks *b; - b = blockfind(blocklist, block); + b = dupfind(blocklist, block); if (b) { osi_list_del(&b->list); free(b); } } -static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block) +void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block) { - struct dup_blocks *b; + struct special_blocks *b; - b = dupfind(blocklist, block); + b = blockfind(blocklist, block); if (b) { osi_list_del(&b->list); free(b); @@ -221,8 +221,6 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, if(mark == gfs2_dup_block) gfs2_dup_set(&sdp->dup_blocks, block); - else if(mark == gfs2_eattr_block) - gfs2_special_set(&sdp->eattr_blocks, block); else err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]); return err; @@ -234,18 +232,10 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, { int err = 0; - switch (mark) { - case gfs2_dup_block: + if (mark == gfs2_dup_block) gfs2_dup_clear(&sdp->dup_blocks, block); - break; - case gfs2_eattr_block: - gfs2_special_clear(&sdp->eattr_blocks, block); - break; - default: - /* FIXME: check types */ + else err = gfs2_bitmap_clear(il, block); - break; - } return err; } @@ -253,12 +243,8 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block) { - int err; - gfs2_dup_clear(&sdp->dup_blocks, block); - gfs2_special_clear(&sdp->eattr_blocks, block); - err = gfs2_bitmap_clear(il, block); - return err; + return gfs2_bitmap_clear(il, block); } int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il, @@ -282,7 +268,6 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il, return -1; val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0); - val->eattr_block = (blockfind(&sdp->eattr_blocks, block) ? 1 : 0); byte = il->map + BITMAP_SIZE4(block); b = BITMAP_BYTE_OFFSET4(block); val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index fc8af3f..3310044 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -340,13 +340,11 @@ enum gfs2_mark_block { gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */ gfs2_meta_inval = INVALID_META, gfs2_dup_block, /* Contains at least one duplicate block */ - gfs2_eattr_block, /* Contains an eattr */ }; struct gfs2_block_query { uint8_t block_type; uint8_t dup_block; - uint8_t eattr_block; }; extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size, @@ -358,6 +356,8 @@ extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block mark); extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block mark); +extern void gfs2_special_clear(struct special_blocks *blocklist, + uint64_t block); /* gfs2_block_unmark clears ONE mark for the given block */ extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il, uint64_t block, enum gfs2_mark_block m);