Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 312404 Details for
Bug 404611
GFS2: gfs2_fsck dupl. blocks between EA and data
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
addendum patch
404611.memory.plus.patch (text/plain), 68.89 KB, created by
Robert Peterson
on 2008-07-22 23:06:03 UTC
(
hide
)
Description:
addendum patch
Filename:
MIME Type:
Creator:
Robert Peterson
Created:
2008-07-22 23:06:03 UTC
Size:
68.89 KB
patch
obsolete
> gfs2/edit/savemeta.c | 9 +- > gfs2/fsck/eattr.c | 4 +- > gfs2/fsck/fs_recovery.c | 4 +- > gfs2/fsck/fsck.h | 5 +- > gfs2/fsck/initialize.c | 8 +- > gfs2/fsck/lost_n_found.c | 5 +- > gfs2/fsck/main.c | 33 +----- > gfs2/fsck/metawalk.c | 21 ++-- > gfs2/fsck/pass1.c | 105 ++++++++++--------- > gfs2/fsck/pass1b.c | 58 +++-------- > gfs2/fsck/pass1c.c | 15 ++- > gfs2/fsck/pass2.c | 16 ++-- > gfs2/fsck/pass3.c | 20 +++-- > gfs2/fsck/pass4.c | 11 ++- > gfs2/fsck/pass5.c | 2 +- > gfs2/fsck/rgrepair.c | 71 +++++++++++++- > gfs2/libgfs2/bitmap.c | 79 +++++++++++---- > gfs2/libgfs2/block_list.c | 249 ++++++++++++++++++++++----------------------- > gfs2/libgfs2/buf.c | 1 - > gfs2/libgfs2/fs_bits.c | 2 +- > gfs2/libgfs2/fs_ops.c | 38 ++++---- > gfs2/libgfs2/libgfs2.h | 86 ++++++++++------ > gfs2/libgfs2/recovery.c | 2 +- > gfs2/libgfs2/rgrp.c | 10 ++ > 24 files changed, 486 insertions(+), 368 deletions(-) > >diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c >index c73dc09..db5d219 100644 >--- a/gfs2/edit/savemeta.c >+++ b/gfs2/edit/savemeta.c >@@ -553,7 +553,7 @@ void save_indirect_blocks(int out_fd, osi_list_t *cur_list, > sizeof(struct gfs2_dinode)); > > for (ptr = (uint64_t *)(mybh->b_data + head_size); >- (char *)ptr < (mybh->b_data + mybh->b_size); ptr++) { >+ (char *)ptr < (mybh->b_data + sbd.bsize); ptr++) { > if (!*ptr) > continue; > indir_block = be64_to_cpu(*ptr); >@@ -800,7 +800,8 @@ void savemeta(const char *out_fn, int slow) > fflush(stdout); > } > if (!slow) { >- blocklist = gfs2_block_list_create(last_fs_block + 1, &memreq); >+ blocklist = gfs2_block_list_create(&sbd, last_fs_block + 1, >+ &memreq); > if (!blocklist) > slow = TRUE; > } >@@ -821,7 +822,7 @@ void savemeta(const char *out_fn, int slow) > log_debug("RG at %"PRIu64" is %u long\n", > rgd->ri.ri_addr, rgd->ri.ri_length); > for (i = 0; i < rgd->ri.ri_length; i++) { >- if(gfs2_block_set(blocklist, >+ if(gfs2_block_set(&sbd, blocklist, > rgd->ri.ri_addr + i, > gfs2_meta_other)) > break; >@@ -854,7 +855,7 @@ void savemeta(const char *out_fn, int slow) > } > /* Clean up */ > if (blocklist) >- gfs2_block_list_destroy(blocklist); >+ gfs2_block_list_destroy(&sbd, blocklist); > /* There may be a gap between end of file system and end of device */ > /* so we tell the user that we've processed everything. */ > block = last_fs_block; >diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c >index 42753ca..5d66483 100644 >--- a/gfs2/fsck/eattr.c >+++ b/gfs2/fsck/eattr.c >@@ -21,7 +21,7 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block) > { > struct gfs2_block_query q; > >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(sbp, bl, block, &q)) { > stack; > return -1; > } >@@ -31,7 +31,7 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block) > return 1; > } > >- gfs2_block_set(bl, block, gfs2_block_free); >+ gfs2_block_set(sbp, bl, block, gfs2_block_free); > > return 0; > >diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c >index 3b25dc6..b21760b 100644 >--- a/gfs2/fsck/fs_recovery.c >+++ b/gfs2/fsck/fs_recovery.c >@@ -134,7 +134,7 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, > return error; > > bh_ip = bget(sdp, blkno); >- memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size); >+ memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize); > > check_magic = ((struct gfs2_meta_header *) > (bh_ip->b_data))->mh_magic; >@@ -231,7 +231,7 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start, > return error; > > bh_ip = bget(sdp, blkno); >- memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size); >+ memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize); > > /* Unescape */ > if (esc) { >diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h >index 6220963..e36c3b8 100644 >--- a/gfs2/fsck/fsck.h >+++ b/gfs2/fsck/fsck.h >@@ -25,9 +25,9 @@ struct inode_info > { > osi_list_t list; > uint64_t inode; >- uint32_t link_count; /* the number of links the inode >+ uint16_t link_count; /* the number of links the inode > * thinks it has */ >- uint32_t counted_links; /* the number of links we've found */ >+ uint16_t counted_links; /* the number of links we've found */ > }; > > struct dir_info >@@ -89,6 +89,5 @@ extern uint64_t last_fs_block, last_reported_block; > extern int skip_this_pass, fsck_abort, fsck_query; > extern uint64_t last_data_block; > extern uint64_t first_data_block; >-extern osi_list_t dup_list; > > #endif /* _FSCK_H */ >diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c >index d759b09..458055f 100644 >--- a/gfs2/fsck/initialize.c >+++ b/gfs2/fsck/initialize.c >@@ -122,7 +122,7 @@ static void empty_super_block(struct gfs2_sbd *sdp) > } > } > >- gfs2_block_list_destroy(bl); >+ gfs2_block_list_destroy(sdp, bl); > } > > >@@ -277,11 +277,11 @@ static int init_system_inodes(struct gfs2_sbd *sdp) > goto fail; > } > >- bl = gfs2_block_list_create(last_fs_block+1, &addl_mem_needed); >+ bl = gfs2_block_list_create(sdp, last_fs_block+1, &addl_mem_needed); > if (!bl) { > log_crit("This system doesn't have enough memory + swap space to fsck this file system.\n"); > log_crit("Additional memory needed is approximately: %ldMB\n", addl_mem_needed / 1048576); >- log_crit("Please increase your swap space by that amount and run gfs_fsck again.\n"); >+ log_crit("Please increase your swap space by that amount and run gfs2_fsck again.\n"); > goto fail; > } > return 0; >@@ -386,7 +386,7 @@ static void destroy_sbp(struct gfs2_sbd *sbp) > if(!opts.no) { > if(block_mounters(sbp, 0)) { > log_warn("Unable to unblock other mounters - manual intevention required\n"); >- log_warn("Use 'gfs_tool sb <device> proto' to fix\n"); >+ log_warn("Use 'gfs2_tool sb <device> proto' to fix\n"); > } > log_info("Syncing the device.\n"); > fsync(sbp->device_fd); >diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c >index e836539..3990e44 100644 >--- a/gfs2/fsck/lost_n_found.c >+++ b/gfs2/fsck/lost_n_found.c >@@ -45,7 +45,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){ > log_info("Locating/Creating lost and found directory\n"); > > lf_dip = createi(ip->i_sbd->md.rooti, "lost+found", S_IFDIR | 0700, 0); >- if(gfs2_block_check(bl, lf_dip->i_di.di_num.no_addr, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, lf_dip->i_di.di_num.no_addr, &q)) { > stack; > return -1; > } >@@ -58,7 +58,8 @@ int add_inode_to_lf(struct gfs2_inode *ip){ > * directory or just found an old one, and we > * used that instead of the block_type to run > * this */ >- gfs2_block_set(bl, lf_dip->i_di.di_num.no_addr, gfs2_inode_dir); >+ gfs2_block_set(ip->i_sbd, bl, >+ lf_dip->i_di.di_num.no_addr, gfs2_inode_dir); > increment_link(ip->i_sbd, > ip->i_sbd->md.rooti->i_di.di_num.no_addr); > increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr); >diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c >index 8ee1de3..b79bdf9 100644 >--- a/gfs2/fsck/main.c >+++ b/gfs2/fsck/main.c >@@ -49,29 +49,6 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...) > va_end(args); > } > >-void print_map(struct gfs2_block_list *il, int count) >-{ >- int i, j; >- struct gfs2_block_query k; >- >- log_info("Printing map of blocks - 80 blocks per row\n"); >- j = 0; >- for(i = 0; i < count; i++) { >- if(j > 79) { >- log_info("\n"); >- j = 0; >- } >- else if(!(j %10) && j != 0) { >- log_info(" "); >- } >- j++; >- gfs2_block_check(il, i, &k); >- log_info("%X", k.block_type); >- >- } >- log_info("\n"); >-} >- > void usage(char *name) > { > printf("Usage: %s [-hnqvVy] <device> \n", basename(name)); >@@ -149,7 +126,7 @@ void interrupt(int sig) > PRIu64 "\n", last_reported_block, last_fs_block); > > response = generic_interrupt("gfs2_fsck", pass, progress, >- "Do you want to abort gfs_fsck, skip " \ >+ "Do you want to abort gfs2_fsck, skip " \ > "the rest of this pass or continue " \ > "(a/s/c)?", "asc"); > if(tolower(response) == 's') { >@@ -182,7 +159,7 @@ int check_system_inode(struct gfs2_inode *sysinode, const char *filename, > > /* FIXME: check this block's validity */ > >- if(gfs2_block_check(bl, iblock, &ds.q)) { >+ if(gfs2_block_check(sysinode->i_sbd, bl, iblock, &ds.q)) { > log_crit("Can't get %s inode block %" PRIu64 " (0x%" > PRIx64 ") from block list\n", filename, > iblock, iblock); >@@ -194,7 +171,8 @@ int check_system_inode(struct gfs2_inode *sysinode, const char *filename, > /* Just reuse the inode and fix the bitmap. */ > if (ds.q.block_type == gfs2_block_free) { > log_info("The inode exists but the block is not marked 'in use'; fixing it.\n"); >- gfs2_block_set(bl, sysinode->i_di.di_num.no_addr, >+ gfs2_block_set(sysinode->i_sbd, bl, >+ sysinode->i_di.di_num.no_addr, > mark); > ds.q.block_type = mark; > if (mark == gfs2_inode_dir) >@@ -213,7 +191,8 @@ int check_system_inode(struct gfs2_inode *sysinode, const char *filename, > if (query(&opts, "Create new %s system inode? (y/n) ", > filename)) { > builder(sysinode->i_sbd); >- gfs2_block_set(bl, sysinode->i_di.di_num.no_addr, >+ gfs2_block_set(sysinode->i_sbd, bl, >+ sysinode->i_di.di_num.no_addr, > mark); > ds.q.block_type = mark; > if (mark == gfs2_inode_dir) >diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c >index e3804de..ab07055 100644 >--- a/gfs2/fsck/metawalk.c >+++ b/gfs2/fsck/metawalk.c >@@ -113,13 +113,14 @@ int dirent_repair(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, > /* If this is a sentinel, just fix the length and move on */ > if (first && !de->de_inum.no_formal_ino) { /* Is it a sentinel? */ > if (type == DIR_LINEAR) >- de->de_rec_len = bh->b_size - >+ de->de_rec_len = ip->i_sbd->bsize - > sizeof(struct gfs2_dinode); > else >- de->de_rec_len = bh->b_size - sizeof(struct gfs2_leaf); >+ de->de_rec_len = ip->i_sbd->bsize - >+ sizeof(struct gfs2_leaf); > } > else { >- bh_end = bh->b_data + bh->b_size; >+ bh_end = bh->b_data + ip->i_sbd->bsize; > /* first, figure out a probable name length */ > p = (char *)dent + sizeof(struct gfs2_dirent); > while (*p && /* while there's a non-zero char and */ >@@ -153,7 +154,7 @@ int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, > char *filename; > int first = 1; > >- bh_end = bh->b_data + bh->b_size; >+ bh_end = bh->b_data + ip->i_sbd->bsize; > > if(type == DIR_LINEAR) { > dent = (struct gfs2_dirent *)(bh->b_data + sizeof(struct gfs2_dinode)); >@@ -617,8 +618,10 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect, > if (!indir_ok) { > gfs2_set_bitmap(sdp, indirect, > GFS2_BLKST_FREE); >- gfs2_block_clear(bl, indirect, gfs2_indir_blk); >- gfs2_block_set(bl, indirect, gfs2_block_free); >+ gfs2_block_clear(sdp, bl, indirect, >+ gfs2_indir_blk); >+ gfs2_block_set(sdp, bl, indirect, >+ gfs2_block_free); > error = 1; > } > } >@@ -695,7 +698,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, > sizeof(struct gfs2_dinode)); > > for (ptr = (uint64_t *)(bh->b_data + head_size); >- (char *)ptr < (bh->b_data + bh->b_size); >+ (char *)ptr < (bh->b_data + ip->i_sbd->bsize); > ptr++) { > nbh = NULL; > >@@ -785,7 +788,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass) > sizeof(struct gfs2_dinode)); > ptr = (uint64_t *)(bh->b_data + head_size); > >- for ( ; (char *)ptr < (bh->b_data + bh->b_size); ptr++) { >+ for ( ; (char *)ptr < (bh->b_data + ip->i_sbd->bsize); ptr++) { > if (!*ptr) > continue; > >@@ -916,7 +919,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir, > remove_dentry_fxns.private = &dentryblock; > remove_dentry_fxns.check_dentry = remove_dentry; > >- if(gfs2_block_check(bl, dir, &q)) { >+ if(gfs2_block_check(sbp, bl, dir, &q)) { > stack; > return -1; > } >diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c >index c802158..8956e72 100644 >--- a/gfs2/fsck/pass1.c >+++ b/gfs2/fsck/pass1.c >@@ -87,7 +87,7 @@ static int leaf(struct gfs2_inode *ip, uint64_t block, > > log_debug("\tLeaf block at %15" PRIu64 " (0x%" PRIx64 ")\n", > block, block); >- gfs2_block_set(bl, block, gfs2_leaf_blk); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_leaf_blk); > bc->indir_count++; > return 0; > } >@@ -103,19 +103,20 @@ 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 */ >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_bad_block); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, >+ gfs2_bad_block); > log_debug("Bad indirect block pointer (out of range).\n"); > > return 1; > } >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, block, &q)) { > stack; > return -1; > } > if(q.block_type != gfs2_block_free) { > log_debug("Found duplicate block in indirect block -" > " was marked %d\n", q.block_type); >- gfs2_block_mark(bl, block, gfs2_dup_block); >+ gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block); > found_dup = 1; > } > nbh = bread(ip->i_sbd, block); >@@ -124,7 +125,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block, > log_debug("Bad indirect block pointer " > "(points to something that is not an indirect block).\n"); > if(!found_dup) { >- gfs2_block_set(bl, block, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_meta_inval); > brelse(nbh, not_updated); > return 1; > } >@@ -133,7 +134,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block, > > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to indirect block.\n", > block, block); >- gfs2_block_set(bl, block, gfs2_indir_blk); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_indir_blk); > bc->indir_count++; > > return 0; >@@ -148,23 +149,24 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private) > log_err( "Bad data block pointer (out of range)\n"); > /* Mark the owner of this block with the bad_block > * designator so we know to check it for out of range blocks later */ >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_bad_block); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, >+ gfs2_bad_block); > return 1; > } >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, block, &q)) { > stack; > return -1; > } > if(q.block_type != gfs2_block_free) { > log_debug("Found duplicate block at %" PRIu64 " (0x%"PRIx64 ")\n", > block, block); >- gfs2_block_mark(bl, block, gfs2_dup_block); >+ gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block); > bc->data_count++; > return 1; > } > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to data block\n", block, > block); >- gfs2_block_set(bl, block, gfs2_block_used); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_used); > bc->data_count++; > return 0; > } >@@ -192,10 +194,10 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc, > if (query(&opts, "Clear the bad EA? (y/n) ")) { > if (block == 0) > block = ip->i_di.di_eattr; >- gfs2_block_clear(bl, block, gfs2_eattr_block); >+ gfs2_block_clear(sdp, bl, block, gfs2_eattr_block); > if (!duplicate) { >- gfs2_block_clear(bl, block, gfs2_indir_blk); >- gfs2_block_set(bl, block, gfs2_block_free); >+ gfs2_block_clear(sdp, bl, block, gfs2_indir_blk); >+ gfs2_block_set(sdp, bl, block, gfs2_block_free); > gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE); > } > ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT; >@@ -226,12 +228,12 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, > if(gfs2_check_range(sdp, indirect)) { > /*log_warn("EA indirect block #%"PRIu64" is out of range.\n", > indirect); >- gfs2_block_set(bl, parent, bad_block);*/ >+ gfs2_block_set(sdp, bl, parent, bad_block);*/ > /* Doesn't help to mark this here - this gets checked > * in pass1c */ > return 1; > } >- if(gfs2_block_check(bl, indirect, &q)) { >+ if(gfs2_block_check(sdp, bl, indirect, &q)) { > stack; > return -1; > } >@@ -245,7 +247,8 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, > if(q.block_type != gfs2_block_free) { /* Duplicate? */ > if (!clear_eas(ip, bc, indirect, 1, > "Bad indirect EA duplicate found")) >- gfs2_block_set(bl, indirect, gfs2_dup_block); >+ gfs2_block_set(sdp, bl, indirect, >+ gfs2_dup_block); > return 1; > } > clear_eas(ip, bc, indirect, 0, >@@ -258,13 +261,13 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect, > " (0x%" PRIx64 ").\n", > ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr, > indirect, indirect); >- gfs2_block_set(bl, indirect, gfs2_dup_block); >+ gfs2_block_set(sdp, bl, indirect, gfs2_dup_block); > bc->ea_count++; > ret = 1; > } else { > log_debug("Setting #%" PRIu64 " (0x%" PRIx64 > ") to indirect EA block\n", indirect, indirect); >- gfs2_block_set(bl, indirect, gfs2_indir_blk); >+ gfs2_block_set(sdp, bl, indirect, gfs2_indir_blk); > bc->ea_count++; > } > return ret; >@@ -279,7 +282,8 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int indir_ok, > ip->i_di.di_num.no_addr, 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(bl, ip->i_di.di_num.no_addr, gfs2_eattr_block); >+ gfs2_block_mark(ip->i_sbd, bl, ip->i_di.di_num.no_addr, >+ gfs2_eattr_block); > return 0; > } > clear_eas(ip, (struct block_count *)private, 0, 0, >@@ -317,11 +321,11 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr, > ") is out of range.\n", > ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr, > el_blk, el_blk); >- gfs2_block_set(bl, ip->i_di.di_eattr, gfs2_bad_block); >+ gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block); > return 1; > } > >- if(gfs2_block_check(bl, el_blk, &q)) { >+ if(gfs2_block_check(sdp, bl, el_blk, &q)) { > stack; > return -1; > } >@@ -344,14 +348,14 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr, > log_debug("Duplicate block found at #%" PRIu64 > " (0x%" PRIx64 ").\n", > el_blk, el_blk); >- gfs2_block_set(bl, el_blk, gfs2_dup_block); >+ gfs2_block_set(sdp, bl, el_blk, gfs2_dup_block); > bc->ea_count++; > ret = 1; > } else { > log_debug("Setting block #%" PRIu64 > " (0x%" PRIx64 ") to eattr block\n", > el_blk, el_blk); >- gfs2_block_set(bl, el_blk, gfs2_meta_eattr); >+ gfs2_block_set(sdp, bl, el_blk, gfs2_meta_eattr); > bc->ea_count++; > } > } >@@ -375,17 +379,17 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, > if (parent != ip->i_di.di_num.no_addr) { /* if parent isn't the inode */ > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\n", > parent, parent); >- gfs2_block_set(bl, parent, gfs2_eattr_block); >+ gfs2_block_set(sdp, bl, parent, gfs2_eattr_block); > } > if(gfs2_check_range(sdp, block)){ > log_warn("Inode #%" PRIu64 " (0x%" PRIx64 "): EA leaf block " > "#%" PRIu64 " (0x%" PRIx64 ") is out of range.\n", > ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr, > block, block); >- gfs2_block_set(bl, ip->i_di.di_eattr, gfs2_bad_block); >+ gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block); > ret = 1; > } >- else if(gfs2_block_check(bl, block, &q)) { >+ else if(gfs2_block_check(sdp, bl, block, &q)) { > stack; > return -1; > } >@@ -410,7 +414,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, > log_debug("Duplicate block found at #%" PRIu64 > " (0x%" PRIx64 ").\n", > block, block); >- gfs2_block_set(bl, block, gfs2_dup_block); >+ gfs2_block_set(sdp, bl, block, gfs2_dup_block); > bc->ea_count++; > ret = 1; > brelse(leaf_bh, not_updated); >@@ -418,7 +422,8 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, > log_debug("Setting block #%" PRIu64 > " (0x%" PRIx64 ") to eattr block\n", > block, block); >- gfs2_block_set(bl, block, gfs2_meta_eattr); >+ gfs2_block_set(sdp, bl, block, >+ gfs2_meta_eattr); > bc->ea_count++; > } > } >@@ -477,12 +482,12 @@ int clear_metalist(struct gfs2_inode *ip, uint64_t block, > > *bh = NULL; > >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, block, &q)) { > stack; > return -1; > } > if(!q.dup_block) { >- gfs2_block_set(bl, block, gfs2_block_free); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free); > return 0; > } > return 0; >@@ -492,12 +497,12 @@ int clear_data(struct gfs2_inode *ip, uint64_t block, void *private) > { > struct gfs2_block_query q = {0}; > >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, block, &q)) { > stack; > return -1; > } > if(!q.dup_block) { >- gfs2_block_set(bl, block, gfs2_block_free); >+ gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free); > return 0; > } > return 0; >@@ -510,14 +515,14 @@ int clear_leaf(struct gfs2_inode *ip, uint64_t block, > struct gfs2_block_query q = {0}; > log_crit("Clearing leaf #%" PRIu64 " (0x%" PRIx64 ")\n", block, block); > >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(ip->i_sbd, bl, block, &q)) { > stack; > return -1; > } > if(!q.dup_block) { > log_crit("Setting leaf #%" PRIu64 " (0x%" PRIx64 ") invalid\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_block_free)) { >+ if(gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free)) { > stack; > return -1; > } >@@ -588,7 +593,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > " (0x%" PRIx64 ") not fixed\n", block, block); > } > >- if(gfs2_block_check(bl, block, &q)) { >+ if(gfs2_block_check(sdp, bl, block, &q)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -596,7 +601,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > if(q.block_type != gfs2_block_free) { > log_debug("Found duplicate block at #%" PRIu64 " (0x%" PRIx64 ")\n", > block, block); >- if(gfs2_block_mark(bl, block, gfs2_dup_block)) { >+ if(gfs2_block_mark(sdp, bl, block, gfs2_dup_block)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -610,7 +615,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFDIR: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to directory inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_dir)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_dir)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -624,7 +629,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFREG: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to file inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_file)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_file)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -633,7 +638,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFLNK: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to symlink inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_lnk)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_lnk)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -642,7 +647,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFBLK: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to block dev inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_blk)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_blk)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -651,7 +656,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFCHR: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to char dev inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_chr)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_chr)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -660,7 +665,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFIFO: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to fifo inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_fifo)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_fifo)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -669,7 +674,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > case S_IFSOCK: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to socket inode.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_inode_sock)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_inode_sock)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -678,7 +683,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > default: > log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to invalid.\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_meta_inval)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -702,7 +707,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > compute_height(sdp, ip->i_di.di_size)); > /* once implemented, remove continue statement */ > log_warn("Marking inode invalid\n"); >- if(gfs2_block_set(bl, block, gfs2_meta_inval)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -722,7 +727,7 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > (1 >> (ip->i_di.di_size/sizeof(uint64_t)))); > /* once implemented, remove continue statement */ > log_warn("Marking inode invalid\n"); >- if(gfs2_block_set(bl, block, gfs2_meta_inval)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { > stack; > fsck_inode_put(ip, f); > return -1; >@@ -745,7 +750,8 @@ int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr); > /* FIXME: Must set all leaves invalid as well */ > check_metatree(ip, &invalidate_metatree); >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); >+ gfs2_block_set(sdp, bl, ip->i_di.di_num.no_addr, >+ gfs2_meta_inval); > gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE); > fsck_inode_put(ip, f); > return 0; >@@ -782,7 +788,7 @@ int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh, > if (gfs2_check_meta(bh, 0)) { > log_debug("Found invalid metadata at #%" PRIu64 " (0x%" PRIx64 ")\n", > block, block); >- if(gfs2_block_set(bl, block, gfs2_meta_inval)) { >+ if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) { > stack; > return -1; > } >@@ -864,7 +870,8 @@ int pass1(struct gfs2_sbd *sbp) > log_debug("RG at %" PRIu64 " (0x%" PRIx64 ") is %u long\n", > rgd->ri.ri_addr, rgd->ri.ri_addr, rgd->ri.ri_length); > for (i = 0; i < rgd->ri.ri_length; i++) { >- if(gfs2_block_set(bl, rgd->ri.ri_addr + i, gfs2_meta_other)){ >+ if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i, >+ gfs2_meta_other)){ > stack; > return -1; > } >diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c >index 2b0ab50..e9be169 100644 >--- a/gfs2/fsck/pass1b.c >+++ b/gfs2/fsck/pass1b.c >@@ -134,7 +134,7 @@ static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de, > struct inode_with_dups *id; > struct gfs2_leaf leaf; > >- osi_list_foreach(tmp1, &dup_list) { >+ osi_list_foreach(tmp1, &ip->i_sbd->dup_blocks.list) { > b = osi_list_entry(tmp1, struct blocks, list); > osi_list_foreach(tmp2, &b->ref_inode_list) { > id = osi_list_entry(tmp2, struct inode_with_dups, >@@ -184,7 +184,8 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block, > inode_hash_remove(inode_hash, ip->i_di.di_num.no_addr); > /* Setting the block to invalid means the inode is > * cleared in pass2 */ >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, >+ gfs2_meta_inval); > } > return 0; > } >@@ -208,7 +209,8 @@ static int clear_dup_data(struct gfs2_inode *ip, uint64_t block, void *private) > inode_hash_remove(inode_hash, ip->i_di.di_num.no_addr); > /* Setting the block to invalid means the inode is > * cleared in pass2 */ >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr, >+ gfs2_meta_inval); > } > > return 0; >@@ -232,7 +234,8 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block, > log_err("Inode %s is in directory %" PRIu64 " (0x%" PRIx64 ")\n", > dh->id->name ? dh->id->name : "", > dh->id->parent, dh->id->parent); >- gfs2_block_set(bl, ip->i_di.di_eattr, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr, >+ gfs2_meta_inval); > } > > return 0; >@@ -254,7 +257,8 @@ static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block, > dh->id->name ? dh->id->name : "", > dh->id->parent, dh->id->parent); > /* mark the main eattr block invalid */ >- gfs2_block_set(bl, ip->i_di.di_eattr, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr, >+ gfs2_meta_inval); > } > > return 0; >@@ -320,7 +324,8 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, > dh->id->name ? dh->id->name : "", > dh->id->parent, dh->id->parent); > /* mark the main eattr block invalid */ >- gfs2_block_set(bl, ip->i_di.di_eattr, gfs2_meta_inval); >+ gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr, >+ gfs2_meta_inval); > } > > return 0; >@@ -382,33 +387,6 @@ int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct blocks *b) > return 0; > } > >-/* Finds all blocks marked in the duplicate block bitmap */ >-int find_dup_blocks(struct gfs2_sbd *sbp) >-{ >- uint64_t block_no = 0; >- struct blocks *b; >- >- while (!gfs2_find_next_block_type(bl, gfs2_dup_block, &block_no)) { >- if(!(b = malloc(sizeof(*b)))) { >- log_crit("Unable to allocate blocks structure\n"); >- return -1; >- } >- if(!memset(b, 0, sizeof(*b))) { >- log_crit("Unable to zero blocks structure\n"); >- return -1; >- } >- b->block_no = block_no; >- osi_list_init(&b->ref_inode_list); >- log_notice("Found dup block at %"PRIu64" (0x%" PRIx64 ")\n", block_no, >- block_no); >- osi_list_add(&b->list, &dup_list); >- block_no++; >- } >- return 0; >-} >- >- >- > int handle_dup_blk(struct gfs2_sbd *sbp, struct blocks *b) > { > osi_list_t *tmp; >@@ -480,13 +458,10 @@ int pass1b(struct gfs2_sbd *sbp) > find_dirents.check_dentry = &find_dentry; > int rc = 0; > >- osi_list_init(&dup_list); >- /* Shove all blocks marked as duplicated into a list */ > log_info("Looking for duplicate blocks...\n"); >- find_dup_blocks(sbp); > > /* If there were no dups in the bitmap, we don't need to do anymore */ >- if(osi_list_empty(&dup_list)) { >+ if(osi_list_empty(&sbp->dup_blocks.list)) { > log_info("No duplicate blocks found\n"); > return 0; > } >@@ -502,7 +477,7 @@ int pass1b(struct gfs2_sbd *sbp) > goto out; > log_debug("Scanning block %" PRIu64 " (0x%" PRIx64 ") for inodes\n", > i, i); >- if(gfs2_block_check(bl, i, &q)) { >+ if(gfs2_block_check(sbp, bl, i, &q)) { > stack; > rc = -1; > goto out; >@@ -514,7 +489,7 @@ int pass1b(struct gfs2_sbd *sbp) > (q.block_type == gfs2_inode_chr) || > (q.block_type == gfs2_inode_fifo) || > (q.block_type == gfs2_inode_sock)) { >- osi_list_foreach(tmp, &dup_list) { >+ osi_list_foreach(tmp, &sbp->dup_blocks.list) { > b = osi_list_entry(tmp, struct blocks, list); > if(find_block_ref(sbp, i, b)) { > stack; >@@ -532,8 +507,9 @@ int pass1b(struct gfs2_sbd *sbp) > * it later */ > log_info("Handling duplicate blocks\n"); > out: >- while (!osi_list_empty(&dup_list)) { >- b = osi_list_entry(dup_list.next, struct blocks, list); >+ while (!osi_list_empty(&sbp->dup_blocks.list)) { >+ b = osi_list_entry(&sbp->dup_blocks.list.next, struct blocks, >+ list); > if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */ > handle_dup_blk(sbp, b); > osi_list_del(&b->list); >diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c >index 5ea49b6..3595f39 100644 >--- a/gfs2/fsck/pass1c.c >+++ b/gfs2/fsck/pass1c.c >@@ -59,7 +59,7 @@ int check_eattr_indir(struct gfs2_inode *ip, uint64_t block, > *update = (opts.no ? not_updated : updated); > return 1; > } >- else if (gfs2_block_check(bl, block, &q)) { >+ else if (gfs2_block_check(sbp, bl, block, &q)) { > stack; > return -1; > } >@@ -94,7 +94,7 @@ int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block, > *update = (opts.no ? not_updated : updated); > return 1; > } >- else if (gfs2_block_check(bl, block, &q)) { >+ else if (gfs2_block_check(sbp, bl, block, &q)) { > stack; > return -1; > } >@@ -211,7 +211,7 @@ int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr, > { > struct gfs2_block_query q; > struct gfs2_sbd *sbp = ip->i_sbd; >- if(gfs2_block_check(bl, be64_to_cpu(*ea_ptr), &q)) { >+ if(gfs2_block_check(sbp, bl, be64_to_cpu(*ea_ptr), &q)) { > stack; > return -1; > } >@@ -235,6 +235,8 @@ int pass1c(struct gfs2_sbd *sbp) > int update = 0; > struct metawalk_fxns pass1c_fxns = { 0 }; > int error = 0; >+ osi_list_t *tmp; >+ struct special_blocks *ea_block; > > pass1c_fxns.check_eattr_indir = &check_eattr_indir; > pass1c_fxns.check_eattr_leaf = &check_eattr_leaf; >@@ -243,7 +245,9 @@ int pass1c(struct gfs2_sbd *sbp) > pass1c_fxns.private = (void *) &update; > > log_info("Looking for inodes containing ea blocks...\n"); >- while (!gfs2_find_next_block_type(bl, gfs2_eattr_block, &block_no)) { >+ osi_list_foreach(tmp, &sbp->eattr_blocks.list) { >+ ea_block = osi_list_entry(tmp, struct special_blocks, list); >+ block_no = ea_block->block; > > if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ > return 0; >@@ -251,7 +255,7 @@ int pass1c(struct gfs2_sbd *sbp) > if (gfs2_check_meta(bh, GFS2_METATYPE_IN)) { /* if a dinode */ > log_info("EA in inode %"PRIu64" (0x%" PRIx64 ")\n", > block_no, block_no); >- gfs2_block_clear(bl, block_no, gfs2_eattr_block); >+ gfs2_block_clear(sbp, bl, block_no, gfs2_eattr_block); > ip = fsck_inode_get(sbp, bh); > > log_debug("Found eattr at %"PRIu64" (0x%" PRIx64 ")\n", >@@ -268,7 +272,6 @@ int pass1c(struct gfs2_sbd *sbp) > } else { > brelse(bh, update); > } >- block_no++; > } > return 0; > } >diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c >index c15b0a8..8f22663 100644 >--- a/gfs2/fsck/pass2.c >+++ b/gfs2/fsck/pass2.c >@@ -185,7 +185,8 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > "\tName length = %u\n", > de->de_rec_len, > de->de_name_len); >- gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_meta_inval); >+ gfs2_block_set(sbp, bl, ip->i_di.di_num.no_addr, >+ gfs2_meta_inval); > return 1; > /* FIXME: should probably delete the entry here at the > * very least - maybe look at attempting to fix it */ >@@ -235,7 +236,7 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > return 0; > } > } >- if(gfs2_block_check(bl, de->de_inum.no_addr, &q)) { >+ if(gfs2_block_check(sbp, bl, de->de_inum.no_addr, &q)) { > stack; > return -1; > } >@@ -259,7 +260,8 @@ int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > > dirent2_del(ip, bh, prev_de, dent); > >- gfs2_block_set(bl, de->de_inum.no_addr, gfs2_meta_inval); >+ gfs2_block_set(sbp, bl, de->de_inum.no_addr, >+ gfs2_meta_inval); > *update = 1; > return 1; > } else { >@@ -530,7 +532,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, > > if (sysinode) { > iblock = sysinode->i_di.di_num.no_addr; >- if(gfs2_block_check(bl, iblock, &ds.q)) { >+ if(gfs2_block_check(sysinode->i_sbd, bl, iblock, &ds.q)) { > iblock = sysinode->i_di.di_num.no_addr; > } > } >@@ -548,7 +550,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, > return -1; > } > if (error > 0) >- gfs2_block_set(bl, iblock, gfs2_meta_inval); >+ gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval); > > bh = bhold(sysinode->i_bh); > if(check_inode_eattr(sysinode, &pass2_fxns)) { >@@ -668,7 +670,7 @@ int pass2(struct gfs2_sbd *sbp) > if (is_system_dir(sbp, i)) > continue; > >- if(gfs2_block_check(bl, i, &q)) { >+ if(gfs2_block_check(sbp, bl, i, &q)) { > log_err("Can't get block %"PRIu64 " (0x%" PRIx64 > ") from block list\n", i, i); > return -1; >@@ -727,7 +729,7 @@ int pass2(struct gfs2_sbd *sbp) > } else > log_err("Directory entry to invalid inode remains.\n"); > } >- gfs2_block_set(bl, i, gfs2_meta_inval); >+ gfs2_block_set(sbp, bl, i, gfs2_meta_inval); > } > bh = bread(sbp, i); > ip = fsck_inode_get(sbp, bh); >diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c >index 58e0009..719d0b1 100644 >--- a/gfs2/fsck/pass3.c >+++ b/gfs2/fsck/pass3.c >@@ -85,13 +85,14 @@ struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp, > PRIu64" (0x%" PRIx64 ")\n", di->dotdot_parent, > di->dotdot_parent, di->treewalk_parent, > di->treewalk_parent); >- if(gfs2_block_check(bl, di->dotdot_parent, &q_dotdot)) { >+ if(gfs2_block_check(sbp, bl, di->dotdot_parent, &q_dotdot)) { > log_err("Unable to find block %"PRIu64 > " (0x%" PRIx64 ") in block map.\n", > di->dotdot_parent, di->dotdot_parent); > return NULL; > } >- if(gfs2_block_check(bl, di->treewalk_parent, &q_treewalk)) { >+ if(gfs2_block_check(sbp, bl, di->treewalk_parent, >+ &q_treewalk)) { > log_err("Unable to find block %"PRIu64 > " (0x%" PRIx64 ") in block map\n", > di->treewalk_parent, di->treewalk_parent); >@@ -160,7 +161,7 @@ struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp, > } > } > else { >- if(gfs2_block_check(bl, di->dotdot_parent, &q_dotdot)) { >+ if(gfs2_block_check(sbp, bl, di->dotdot_parent, &q_dotdot)) { > log_err("Unable to find parent block %"PRIu64 > " (0x%" PRIx64 ") in block map\n", > di->dotdot_parent, di->dotdot_parent); >@@ -220,7 +221,7 @@ int pass3(struct gfs2_sbd *sbp) > > /* FIXME: Factor this ? */ > if(!tdi) { >- if(gfs2_block_check(bl, di->dinode, &q)) { >+ if(gfs2_block_check(sbp, bl, di->dinode, &q)) { > stack; > return -1; > } >@@ -228,7 +229,9 @@ int pass3(struct gfs2_sbd *sbp) > log_err("Found unlinked directory containing bad block\n"); > if(query(&opts, > "Clear unlinked directory with bad blocks? (y/n) ")) { >- gfs2_block_set(bl, di->dinode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, >+ di->dinode, >+ gfs2_block_free); > break; > } else > log_err("Unlinked directory with bad block remains\n"); >@@ -241,7 +244,8 @@ int pass3(struct gfs2_sbd *sbp) > q.block_type != gfs2_inode_fifo && > q.block_type != gfs2_inode_sock) { > log_err("Unlinked block marked as inode not an inode\n"); >- gfs2_block_set(bl, di->dinode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, di->dinode, >+ gfs2_block_free); > log_err("Cleared\n"); > break; > } >@@ -254,7 +258,9 @@ int pass3(struct gfs2_sbd *sbp) > if(!ip->i_di.di_size && !ip->i_di.di_eattr){ > log_err("Unlinked directory has zero size.\n"); > if(query(&opts, "Remove zero-size unlinked directory? (y/n) ")) { >- gfs2_block_set(bl, di->dinode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, >+ di->dinode, >+ gfs2_block_free); > fsck_inode_put(ip, not_updated); > break; > } else { >diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c >index 8a9e733..583a266 100644 >--- a/gfs2/fsck/pass4.c >+++ b/gfs2/fsck/pass4.c >@@ -60,7 +60,7 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { > if(ii->counted_links == 0) { > log_err("Found unlinked inode at %" PRIu64 " (0x%" PRIx64 ")\n", > ii->inode, ii->inode); >- if(gfs2_block_check(bl, ii->inode, &q)) { >+ if(gfs2_block_check(sbp, bl, ii->inode, &q)) { > stack; > return -1; > } >@@ -68,7 +68,8 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { > log_err("Unlinked inode contains bad blocks\n", ii->inode); > if(query(&opts, > "Clear unlinked inode with bad blocks? (y/n) ")) { >- gfs2_block_set(bl, ii->inode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, ii->inode, >+ gfs2_block_free); > continue; > } else > log_err("Unlinked inode with bad blocks not cleared\n"); >@@ -81,7 +82,8 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { > q.block_type != gfs2_inode_fifo && > q.block_type != gfs2_inode_sock) { > log_err("Unlinked block marked as inode not an inode\n"); >- gfs2_block_set(bl, ii->inode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, ii->inode, >+ gfs2_block_free); > log_err("Cleared\n"); > continue; > } >@@ -93,7 +95,8 @@ int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) { > if(!ip->i_di.di_size && !ip->i_di.di_eattr){ > log_err("Unlinked inode has zero size\n"); > if(query(&opts, "Clear zero-size unlinked inode? (y/n) ")) { >- gfs2_block_set(bl, ii->inode, gfs2_block_free); >+ gfs2_block_set(sbp, bl, ii->inode, >+ gfs2_block_free); > fsck_inode_put(ip, not_updated); > continue; > } >diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c >index 8db2ca7..bc4b859 100644 >--- a/gfs2/fsck/pass5.c >+++ b/gfs2/fsck/pass5.c >@@ -84,7 +84,7 @@ int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int buflen, > warm_fuzzy_stuff(block); > if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ > return 0; >- gfs2_block_check(bl, block, &q); >+ gfs2_block_check(sbp, bl, block, &q); > > block_status = convert_mark(&q, count); > >diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c >index 8ba16bf..24fd6d9 100644 >--- a/gfs2/fsck/rgrepair.c >+++ b/gfs2/fsck/rgrepair.c >@@ -24,6 +24,7 @@ > #include "fsck.h" > > int rindex_modified = FALSE; >+struct special_blocks false_rgrps; > > #define ri_equal(ondisk, expected, field) (ondisk.field == expected.field) > >@@ -37,6 +38,66 @@ int rindex_modified = FALSE; > } > > /* >+ * find_journal_entry_rgs - find all RG blocks within all journals >+ * >+ * Since Resource Groups (RGs) are journaled, it is not uncommon for them >+ * to appear inside a journal. But if there is severe damage to the rindex >+ * file or some of the RGs, we may need to hunt and peck for RGs and in that >+ * case, we don't want to mistake these blocks that look just a real RG >+ * for a real RG block. These are "fake" RGs that need to be ignored for >+ * the purposes of finding where things are. >+ */ >+void find_journaled_rgs(struct gfs2_sbd *sdp) >+{ >+ int j, new = 0; >+ unsigned int jblocks; >+ uint64_t b, dblock; >+ uint32_t extlen; >+ struct gfs2_inode *ip; >+ struct gfs2_buffer_head *bh; >+ >+ osi_list_init(&false_rgrps.list); >+ for (j = 0; j < sdp->md.journals; j++) { >+ log_debug("Checking for RGs in journal%d.\n", j); >+ ip = sdp->md.journal[j]; >+ jblocks = ip->i_di.di_size / sdp->sd_sb.sb_bsize; >+ for (b = 0; b < jblocks; b++) { >+ block_map(ip, b, &new, &dblock, &extlen, 0, >+ not_updated); >+ if (!dblock) >+ break; >+ bh = bread(sdp, dblock); >+ if (!gfs2_check_meta(bh, GFS2_METATYPE_RG)) { >+ log_debug("False RG found at block " >+ "0x%" PRIx64 "\n", dblock); >+ gfs2_special_set(&false_rgrps, dblock); >+ } >+ brelse(bh, not_updated); >+ } >+ } >+} >+ >+int is_false_rg(uint64_t block) >+{ >+ if (blockfind(&false_rgrps, block)) >+ return 1; >+ return 0; >+} >+ >+void free_journaled_rgs(sdp) >+{ >+ struct special_blocks *f; >+ >+ /* We don't need the list of false rgrps anymore, so delete it. */ >+ while(!osi_list_empty(&false_rgrps.list)) { >+ f = osi_list_entry(false_rgrps.list.next, >+ struct special_blocks, list); >+ osi_list_del(&f->list); >+ free(f); >+ } >+} >+ >+/* > * gfs2_rindex_rebuild - rebuild a corrupt Resource Group (RG) index manually > * where trust_lvl == distrust > * >@@ -75,6 +136,9 @@ int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, > int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd; > osi_list_t *tmp; > >+ /* Figure out if there are any RG-looking blocks in the journal we >+ need to ignore. */ >+ find_journaled_rgs(sdp); > osi_list_init(ret_list); > number_of_rgs = 0; > initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1; >@@ -90,8 +154,9 @@ int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, > blk < sdp->device.length && number_of_rgs < 6; > blk++) { > bh = bread(sdp, blk); >- if ((blk == sdp->sb_addr + 1) || >- (!gfs2_check_meta(bh, GFS2_METATYPE_RG))) { >+ if (((blk == sdp->sb_addr + 1) || >+ (!gfs2_check_meta(bh, GFS2_METATYPE_RG))) && >+ !is_false_rg(blk)) { > log_debug("RG found at block 0x%" PRIx64 "\n", blk); > if (blk > sdp->sb_addr + 1) { > uint64_t rgdist; >@@ -124,6 +189,8 @@ int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, > brelse(bh, not_updated); > } > number_of_rgs = 0; >+ free_journaled_rgs(sdp); >+ > /* -------------------------------------------------------------- */ > /* Sanity-check our first_rg_dist. If RG #2 got nuked, the */ > /* first_rg_dist would measure from #1 to #3, which would be bad. */ >diff --git a/gfs2/libgfs2/bitmap.c b/gfs2/libgfs2/bitmap.c >index c8ba4ec..d198fe2 100644 >--- a/gfs2/libgfs2/bitmap.c >+++ b/gfs2/libgfs2/bitmap.c >@@ -21,11 +21,39 @@ > #include "libgfs2.h" > > #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 gfs2_bitmap_size(struct gfs2_bmap *bmap) { > return bmap->size; >@@ -59,14 +87,19 @@ int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size, > > int gfs2_bitmap_set(struct gfs2_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)); >+ } else { >+ byte = bmap->map + BITMAP_SIZE4(offset); >+ b = BITMAP_BYTE_OFFSET4(offset); >+ *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b; >+ } > return 0; > } > return -1; >@@ -74,14 +107,19 @@ int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val) > > int gfs2_bitmap_get(struct gfs2_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; > } > return -1; >@@ -89,14 +127,19 @@ int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val) > > int gfs2_bitmap_clear(struct gfs2_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; > } > return -1; >diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c >index 0c7ddd9..7c5f302 100644 >--- a/gfs2/libgfs2/block_list.c >+++ b/gfs2/libgfs2/block_list.c >@@ -20,23 +20,6 @@ > > #include "libgfs2.h" > >-#define FREE (0x0) /* 0000 */ >-#define BLOCK_IN_USE (0x1) /* 0001 */ >-#define DIR_INDIR_BLK (0x2) /* 0010 */ >-#define DIR_INODE (0x3) /* 0011 */ >-#define FILE_INODE (0x4) /* 0100 */ >-#define LNK_INODE (0x5) >-#define BLK_INODE (0x6) >-#define CHR_INODE (0x7) >-#define FIFO_INODE (0x8) >-#define SOCK_INODE (0x9) >-#define DIR_LEAF_INODE (0xA) /* 1010 */ >-#define JOURNAL_BLK (0xB) /* 1011 */ >-#define OTHER_META (0xC) /* 1100 */ >-#define EATTR_META (0xD) /* 1101 */ >-#define UNUSED1 (0xE) /* 1110 */ >-#define INVALID_META (0xF) /* 1111 */ >- > /* Must be kept in sync with mark_block enum in block_list.h */ > /* FIXME: Fragile */ > static int mark_to_gbmap[16] = { >@@ -46,93 +29,110 @@ static int mark_to_gbmap[16] = { > INVALID_META, INVALID_META > }; > >-struct gfs2_block_list *gfs2_block_list_create(uint64_t size, >- uint64_t *addl_mem_needed) >+struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp, >+ uint64_t size, >+ uint64_t *addl_mem_needed) > { > struct gfs2_block_list *il; > > *addl_mem_needed = 0L; >- if ((il = malloc(sizeof(*il)))) { >- if(!memset(il, 0, sizeof(*il))) >- return NULL; >- >- if(gfs2_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; >- free(il); >- il = NULL; >- } >- else if(gfs2_bitmap_create(&il->list.gbmap.bad_map, size, 1)) { >- *addl_mem_needed = il->list.gbmap.group_map.mapsize * 4; >- free(il); >- il = NULL; >- } >- else if(gfs2_bitmap_create(&il->list.gbmap.dup_map, size, 1)) { >- *addl_mem_needed = il->list.gbmap.group_map.mapsize * 3; >- free(il); >- il = NULL; >- } >- else if(gfs2_bitmap_create(&il->list.gbmap.eattr_map, size, 1)) { >- *addl_mem_needed = il->list.gbmap.group_map.mapsize * 2; >- free(il); >- il = NULL; >- } >+ il = malloc(sizeof(*il)); >+ if (!il || !memset(il, 0, sizeof(*il))) >+ return NULL; >+ >+ if(gfs2_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; >+ free(il); >+ il = NULL; > } >+ osi_list_init(&sdp->bad_blocks.list); >+ osi_list_init(&sdp->dup_blocks.list); >+ osi_list_init(&sdp->eattr_blocks.list); > return il; > } > >-int gfs2_block_mark(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block mark) >+struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num) >+{ >+ osi_list_t *head = &blist->list; >+ osi_list_t *tmp; >+ struct special_blocks *b; >+ >+ for (tmp = head->next; tmp != head; tmp = tmp->next) { >+ b = osi_list_entry(tmp, struct special_blocks, list); >+ if (b->block == num) >+ return b; >+ } >+ return NULL; >+} >+ >+void gfs2_special_set(struct special_blocks *blocklist, uint64_t block) >+{ >+ struct special_blocks *b; >+ >+ if (blockfind(blocklist, block)) >+ return; >+ b = malloc(sizeof(struct special_blocks)); >+ if (b) { >+ b->block = block; >+ osi_list_add(&b->list, &blocklist->list); >+ } >+ return; >+} >+ >+void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block) >+{ >+ struct special_blocks *b; >+ >+ b = blockfind(blocklist, block); >+ if (b) { >+ osi_list_del(&b->list); >+ free(b); >+ } >+} >+ >+int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block mark) > { > int err = 0; > > if(mark == gfs2_bad_block) >- err = gfs2_bitmap_set(&il->list.gbmap.bad_map, block, 1); >+ gfs2_special_set(&sdp->bad_blocks, block); > else if(mark == gfs2_dup_block) >- err = gfs2_bitmap_set(&il->list.gbmap.dup_map, block, 1); >+ gfs2_special_set(&sdp->dup_blocks, block); > else if(mark == gfs2_eattr_block) >- err = gfs2_bitmap_set(&il->list.gbmap.eattr_map, block, 1); >+ gfs2_special_set(&sdp->eattr_blocks, block); > else > err = gfs2_bitmap_set(&il->list.gbmap.group_map, block, >- mark_to_gbmap[mark]); >- return err; >-} >- >-int gfs2_block_set(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block mark) >-{ >- int err = 0; >- err = gfs2_block_clear(il, block, mark); >- if(!err) >- err = gfs2_block_mark(il, block, mark); >+ mark_to_gbmap[mark]); > return err; > } > >-int gfs2_block_clear(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block m) >+int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block m) > { > int err = 0; > > switch (m) { > case gfs2_dup_block: >- err = gfs2_bitmap_clear(&il->list.gbmap.dup_map, block); >+ gfs2_special_clear(&sdp->dup_blocks, block); > break; > case gfs2_bad_block: >- err = gfs2_bitmap_clear(&il->list.gbmap.bad_map, block); >+ gfs2_special_clear(&sdp->bad_blocks, block); > break; > case gfs2_eattr_block: >- err = gfs2_bitmap_clear(&il->list.gbmap.eattr_map, block); >+ gfs2_special_clear(&sdp->eattr_blocks, block); > break; > default: > /* FIXME: check types */ >@@ -142,72 +142,63 @@ int gfs2_block_clear(struct gfs2_block_list *il, uint64_t block, > return err; > } > >-int gfs2_block_check(struct gfs2_block_list *il, uint64_t block, >- struct gfs2_block_query *val) >+int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block mark) >+{ >+ int err; >+ >+ err = gfs2_block_clear(sdp, il, block, mark); >+ if(!err) >+ err = gfs2_block_mark(sdp, il, block, mark); >+ return err; >+} >+ >+int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, struct gfs2_block_query *val) > { > int err = 0; >+ > val->bad_block = 0; > val->dup_block = 0; >+ val->eattr_block = 0; > if((err = gfs2_bitmap_get(&il->list.gbmap.group_map, block, >- &val->block_type))) >- return err; >- if((err = gfs2_bitmap_get(&il->list.gbmap.bad_map, block, >- &val->bad_block))) >- return err; >- if((err = gfs2_bitmap_get(&il->list.gbmap.dup_map, block, >- &val->dup_block))) >- return err; >- if((err = gfs2_bitmap_get(&il->list.gbmap.eattr_map, block, >- &val->eattr_block))) >+ &val->block_type))) > return err; >- return err; >+ if (blockfind(&sdp->bad_blocks, block)) >+ val->bad_block = 1; >+ if (blockfind(&sdp->dup_blocks, block)) >+ val->dup_block = 1; >+ if (blockfind(&sdp->eattr_blocks, block)) >+ val->eattr_block = 1; >+ return 0; > } > >-void *gfs2_block_list_destroy(struct gfs2_block_list *il) >+void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il) > { >+ struct special_blocks *b; >+ > if(il) { > gfs2_bitmap_destroy(&il->list.gbmap.group_map); >- gfs2_bitmap_destroy(&il->list.gbmap.bad_map); >- gfs2_bitmap_destroy(&il->list.gbmap.dup_map); >- gfs2_bitmap_destroy(&il->list.gbmap.eattr_map); > free(il); > il = NULL; > } >- return il; >-} >- >- >-int gfs2_find_next_block_type(struct gfs2_block_list *il, >- enum gfs2_mark_block m, uint64_t *b) >-{ >- uint64_t i; >- uint8_t val; >- int found = 0; >- for(i = *b; ; i++) { >- if(i >= gfs2_bitmap_size(&il->list.gbmap.dup_map)) >- return -1; >- >- switch(m) { >- case gfs2_dup_block: >- if(gfs2_bitmap_get(&il->list.gbmap.dup_map, i, &val)) >- return -1; >- if(val) >- found = 1; >- break; >- case gfs2_eattr_block: >- if(gfs2_bitmap_get(&il->list.gbmap.eattr_map, i, &val)) >- return -1; >- if(val) >- found = 1; >- break; >- default: >- /* FIXME: add support for getting other types */ >- break; >- } >- if(found) { >- *b = i; >- return 0; >- } >+ while(!osi_list_empty(&sdp->bad_blocks.list)) { >+ b = osi_list_entry(&sdp->bad_blocks.list.next, >+ struct special_blocks, list); >+ osi_list_del(&b->list); >+ free(b); >+ } >+ while(!osi_list_empty(&sdp->dup_blocks.list)) { >+ b = osi_list_entry(&sdp->dup_blocks.list.next, >+ struct special_blocks, list); >+ osi_list_del(&b->list); >+ free(b); > } >- return -1; >+ while(!osi_list_empty(&sdp->eattr_blocks.list)) { >+ b = osi_list_entry(&sdp->eattr_blocks.list.next, >+ struct special_blocks, list); >+ osi_list_del(&b->list); >+ free(b); >+ } >+ return il; > } >diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c >index 562e965..7985945 100644 >--- a/gfs2/libgfs2/buf.c >+++ b/gfs2/libgfs2/buf.c >@@ -103,7 +103,6 @@ struct gfs2_buffer_head *bget_generic(struct gfs2_sbd *sdp, uint64_t num, > bh->b_count = 1; > bh->b_blocknr = num; > bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head); >- bh->b_size = sdp->bsize; > if (read_disk) { > do_lseek(sdp->device_fd, num * sdp->bsize); > do_read(sdp->device_fd, bh->b_data, sdp->bsize); >diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c >index 6e74747..024426f 100644 >--- a/gfs2/libgfs2/fs_bits.c >+++ b/gfs2/libgfs2/fs_bits.c >@@ -51,7 +51,7 @@ uint32_t gfs2_bitfit_core(struct gfs2_sbd *sbp, uint64_t goal, uint64_t start, > struct gfs2_block_query q; > > for(block = start+goal; block < start+len; block++) { >- gfs2_block_check(bl, block, &q); >+ gfs2_block_check(sbp, bl, block, &q); > switch(old_state) { > /* FIXME Make sure these are handled correctly */ > case GFS2_BLKST_FREE: >diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c >index a48d2ff..e5fc959 100644 >--- a/gfs2/libgfs2/fs_ops.c >+++ b/gfs2/libgfs2/fs_ops.c >@@ -148,20 +148,20 @@ uint64_t dinode_alloc(struct gfs2_sbd *sdp) > return blk_alloc_i(sdp, DINODE); > } > >-static __inline__ void buffer_clear_tail(struct gfs2_buffer_head *bh, int head) >+static __inline__ void buffer_clear_tail(struct gfs2_sbd *sdp, >+ struct gfs2_buffer_head *bh, int head) > { >- memset(bh->b_data + head, 0, bh->b_size - head); >+ memset(bh->b_data + head, 0, sdp->bsize - head); > } > > static __inline__ void >-buffer_copy_tail(struct gfs2_buffer_head *to_bh, int to_head, >- struct gfs2_buffer_head *from_bh, int from_head) >+buffer_copy_tail(struct gfs2_sbd *sdp, >+ struct gfs2_buffer_head *to_bh, int to_head, >+ struct gfs2_buffer_head *from_bh, int from_head) > { >- memcpy(to_bh->b_data + to_head, >- from_bh->b_data + from_head, >- from_bh->b_size - from_head); >- memset(to_bh->b_data + to_bh->b_size + to_head - from_head, >- 0, >+ memcpy(to_bh->b_data + to_head, from_bh->b_data + from_head, >+ sdp->bsize - from_head); >+ memset(to_bh->b_data + sdp->bsize + to_head - from_head, 0, > from_head - to_head); > } > >@@ -184,7 +184,8 @@ static void unstuff_dinode(struct gfs2_inode *ip) > gfs2_meta_header_out(&mh, bh->b_data); > } > >- buffer_copy_tail(bh, sizeof(struct gfs2_meta_header), >+ buffer_copy_tail(sdp, bh, >+ sizeof(struct gfs2_meta_header), > ip->i_bh, sizeof(struct gfs2_dinode)); > > brelse(bh, updated); >@@ -192,14 +193,14 @@ static void unstuff_dinode(struct gfs2_inode *ip) > block = data_alloc(ip); > bh = bget(sdp, block); > >- buffer_copy_tail(bh, 0, >+ buffer_copy_tail(sdp, bh, 0, > ip->i_bh, sizeof(struct gfs2_dinode)); > > brelse(bh, updated); > } > } > >- buffer_clear_tail(ip->i_bh, sizeof(struct gfs2_dinode)); >+ buffer_clear_tail(sdp, ip->i_bh, sizeof(struct gfs2_dinode)); > > if (ip->i_di.di_size) { > *(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block); >@@ -260,13 +261,14 @@ void build_height(struct gfs2_inode *ip, int height) > mh.mh_format = GFS2_FORMAT_IN; > gfs2_meta_header_out(&mh, bh->b_data); > } >- buffer_copy_tail(bh, sizeof(struct gfs2_meta_header), >+ buffer_copy_tail(sdp, bh, >+ sizeof(struct gfs2_meta_header), > ip->i_bh, sizeof(struct gfs2_dinode)); > > brelse(bh, updated); > } > >- buffer_clear_tail(ip->i_bh, sizeof(struct gfs2_dinode)); >+ buffer_clear_tail(sdp, ip->i_bh, sizeof(struct gfs2_dinode)); > > if (new_block) { > *(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block); >@@ -628,7 +630,7 @@ int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, > char *bh_end; > uint16_t cur_rec_len; > >- bh_end = bh->b_data + bh->b_size; >+ bh_end = bh->b_data + dip->i_sbd->bsize; > cur_rec_len = be16_to_cpu((*dent)->de_rec_len); > > if ((char *)(*dent) + cur_rec_len >= bh_end) >@@ -661,7 +663,7 @@ dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, int name_len, > } > > if (!entries) { >- dent->de_rec_len = cpu_to_be16(bh->b_size - offset); >+ dent->de_rec_len = cpu_to_be16(dip->i_sbd->bsize - offset); > dent->de_name_len = cpu_to_be16(name_len); > > *dent_out = dent; >@@ -1060,7 +1062,7 @@ dir_make_exhash(struct gfs2_inode *dip) > leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE); > leaf->lf_entries = cpu_to_be16(dip->i_di.di_entries); > >- buffer_copy_tail(bh, sizeof(struct gfs2_leaf), >+ buffer_copy_tail(sdp, bh, sizeof(struct gfs2_leaf), > dip->i_bh, sizeof(struct gfs2_dinode)); > > x = 0; >@@ -1078,7 +1080,7 @@ dir_make_exhash(struct gfs2_inode *dip) > > brelse(bh, updated); > >- buffer_clear_tail(dip->i_bh, sizeof(struct gfs2_dinode)); >+ buffer_clear_tail(sdp, dip->i_bh, sizeof(struct gfs2_dinode)); > > lp = (uint64_t *)(dip->i_bh->b_data + sizeof(struct gfs2_dinode)); > >diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h >index 7f8e393..0a98a47 100644 >--- a/gfs2/libgfs2/libgfs2.h >+++ b/gfs2/libgfs2/libgfs2.h >@@ -119,11 +119,15 @@ struct gfs2_buffer_head { > unsigned int b_count; > uint64_t b_blocknr; > char *b_data; >- unsigned int b_size; > > int b_changed; > }; > >+struct special_blocks { >+ osi_list_t list; >+ uint64_t block; >+}; >+ > struct gfs2_sbd; > struct gfs2_inode { > struct gfs2_dinode i_di; >@@ -242,6 +246,9 @@ struct gfs2_sbd { > int metafs_fd; > int metafs_mounted; /* If metafs was already mounted */ > char metafs_path[PATH_MAX]; /* where metafs is mounted */ >+ struct special_blocks bad_blocks; >+ struct special_blocks dup_blocks; >+ struct special_blocks eattr_blocks; > }; > > extern char *prog_name; >@@ -290,23 +297,41 @@ void gfs2_bitmap_destroy(struct gfs2_bmap *bmap); > uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap); > > /* block_list.c */ >+#define FREE (0x0) /* 0000 */ >+#define BLOCK_IN_USE (0x1) /* 0001 */ >+#define DIR_INDIR_BLK (0x2) /* 0010 */ >+#define DIR_INODE (0x3) /* 0011 */ >+#define FILE_INODE (0x4) /* 0100 */ >+#define LNK_INODE (0x5) >+#define BLK_INODE (0x6) >+#define CHR_INODE (0x7) >+#define FIFO_INODE (0x8) >+#define SOCK_INODE (0x9) >+#define DIR_LEAF_INODE (0xA) /* 1010 */ >+#define JOURNAL_BLK (0xB) /* 1011 */ >+#define OTHER_META (0xC) /* 1100 */ >+#define EATTR_META (0xD) /* 1101 */ >+#define UNUSED1 (0xE) /* 1110 */ >+#define INVALID_META (0xF) /* 1111 */ >+ > /* Must be kept in sync with mark_to_bitmap array in block_list.c */ > enum gfs2_mark_block { >- gfs2_block_free = 0, >- gfs2_block_used, >- gfs2_indir_blk, >- gfs2_inode_dir, >- gfs2_inode_file, >- gfs2_inode_lnk, >- gfs2_inode_blk, >- gfs2_inode_chr, >- gfs2_inode_fifo, >- gfs2_inode_sock, >- gfs2_leaf_blk, >- gfs2_journal_blk, >- gfs2_meta_other, >- gfs2_meta_eattr, >- gfs2_meta_inval = 15, >+ gfs2_block_free = FREE, >+ gfs2_block_used = BLOCK_IN_USE, >+ gfs2_indir_blk = DIR_INDIR_BLK, >+ gfs2_inode_dir = DIR_INODE, >+ gfs2_inode_file = FILE_INODE, >+ gfs2_inode_lnk = LNK_INODE, >+ gfs2_inode_blk = BLK_INODE, >+ gfs2_inode_chr = CHR_INODE, >+ gfs2_inode_fifo = FIFO_INODE, >+ gfs2_inode_sock = SOCK_INODE, >+ gfs2_leaf_blk = DIR_LEAF_INODE, >+ gfs2_journal_blk = JOURNAL_BLK, >+ gfs2_meta_other = OTHER_META, >+ gfs2_meta_eattr = EATTR_META, >+ gfs2_meta_unused = UNUSED1, >+ gfs2_meta_inval = INVALID_META, > gfs2_bad_block, /* Contains at least one bad block */ > gfs2_dup_block, /* Contains at least one duplicate block */ > gfs2_eattr_block, /* Contains an eattr */ >@@ -335,21 +360,22 @@ struct gfs2_block_list { > union gfs2_block_lists list; > }; > >-struct gfs2_block_list *gfs2_block_list_create(uint64_t size, >+struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp, >+ uint64_t size, > uint64_t *addl_mem_needed); >-int gfs2_block_mark(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block mark); >-int gfs2_block_set(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block mark); >-int gfs2_block_clear(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block m); >-int gfs2_block_check(struct gfs2_block_list *il, uint64_t block, >- struct gfs2_block_query *val); >-int gfs2_block_check_for_mark(struct gfs2_block_list *il, uint64_t block, >- enum gfs2_mark_block mark); >-void *gfs2_block_list_destroy(struct gfs2_block_list *il); >-int gfs2_find_next_block_type(struct gfs2_block_list *il, >- enum gfs2_mark_block m, uint64_t *b); >+struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num); >+void gfs2_special_set(struct special_blocks *blocklist, uint64_t block); >+void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block); >+int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block mark); >+int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block mark); >+int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, enum gfs2_mark_block m); >+int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il, >+ uint64_t block, struct gfs2_block_query *val); >+void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, >+ struct gfs2_block_list *il); > > /* buf.c */ > struct gfs2_buffer_head *bget_generic(struct gfs2_sbd *sdp, uint64_t num, >diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c >index 387d4fa..c789078 100644 >--- a/gfs2/libgfs2/recovery.c >+++ b/gfs2/libgfs2/recovery.c >@@ -233,7 +233,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) > return -EIO; > > bh = bread(ip->i_sbd, dblock); >- memset(bh->b_data, 0, bh->b_size); >+ memset(bh->b_data, 0, ip->i_sbd->bsize); > > lh = (struct gfs2_log_header *)bh->b_data; > memset(lh, 0, sizeof(struct gfs2_log_header)); >diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c >index 5728144..9b8e2be 100644 >--- a/gfs2/libgfs2/rgrp.c >+++ b/gfs2/libgfs2/rgrp.c >@@ -31,6 +31,16 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd) > uint32_t bytes_left, bytes; > int x; > >+ /* Max size of an rg is 2GB. A 2GB RG with (minimum) 512-byte blocks >+ has 4194304 blocks. We can represent 4 blocks in one bitmap byte. >+ Therefore, all 4194304 blocks can be represented in 1048576 bytes. >+ Subtract a metadata header for each 512-byte block and we get >+ 488 bytes of bitmap per block. Divide 1048576 by 488 and we can >+ be assured we should never have more than 2149 of them. */ >+ if (length > 2149 || length == 0) { >+ log_err("Invalid length %u found in rindex.\n", length); >+ return -1; >+ } > if(!(rgd->bits = (struct gfs2_bitmap *) > malloc(length * sizeof(struct gfs2_bitmap)))) > return -1;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 404611
:
272991
|
273071
|
311604
|
311988
|
312174
|
312404
|
312571