gfs2-utils: master - fsck.gfs2: Move reprocess code to pass1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=c201ff82...
Commit: c201ff82ff58a1e04212badce010e00bd1def140
Parent: 4a1e4d8c2a9ab5eff3f3f54364c2d482a9e783c8
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Mar 15 15:44:07 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:48:39 2016 -0500
fsck.gfs2: Move reprocess code to pass1
Since all the passes after pass1 no longer care about the blockmap,
we only need to keep the blockmap in sync with the bitmap in pass1.
Therefore, we can safely move the "reprocess_inode" stuff to pass1.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/metawalk.c | 107 --------------------------------------------------
gfs2/fsck/metawalk.h | 1 -
gfs2/fsck/pass1.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 108 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index cbc73e9..7a77dc9 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1910,110 +1910,3 @@ int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
NULL, private);
}
-
-static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, int h, int *is_valid,
- int *was_duplicate, void *private)
-{
- int q;
- const char *desc = (const char *)private;
-
- /* No need to range_check here--if it was added, it's in range. */
- /* We can't check the bitmap here because this function is called
- after the bitmap has been set but before the blockmap has. */
- *is_valid = 1;
- *was_duplicate = 0;
- *bh = bread(ip->i_sbd, block);
- q = bitmap_type(ip->i_sbd, block);
- if (q == GFS2_BLKST_FREE) {
- log_debug(_("%s reference to new metadata block "
- "%lld (0x%llx) is now marked as indirect.\n"),
- desc, (unsigned long long)block,
- (unsigned long long)block);
- gfs2_blockmap_set(bl, block, ip->i_sbd->gfs1 ?
- GFS2_BLKST_DINODE : GFS2_BLKST_USED);
- }
- return meta_is_good;
-}
-
-static int alloc_data(struct gfs2_inode *ip, uint64_t metablock,
- uint64_t block, void *private,
- struct gfs2_buffer_head *bh, uint64_t *ptr)
-{
- int q;
- const char *desc = (const char *)private;
-
- /* No need to range_check here--if it was added, it's in range. */
- /* We can't check the bitmap here because this function is called
- after the bitmap has been set but before the blockmap has. */
- q = bitmap_type(ip->i_sbd, block);
- if (q == GFS2_BLKST_FREE) {
- log_debug(_("%s reference to new data block "
- "%lld (0x%llx) is now marked as data.\n"),
- desc, (unsigned long long)block,
- (unsigned long long)block);
- gfs2_blockmap_set(bl, block, GFS2_BLKST_USED);
- }
- return 0;
-}
-
-static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
-{
- int q;
-
- /* No need to range_check here--if it was added, it's in range. */
- /* We can't check the bitmap here because this function is called
- after the bitmap has been set but before the blockmap has. */
- q = bitmap_type(ip->i_sbd, block);
- if (q == GFS2_BLKST_FREE)
- fsck_blockmap_set(ip, block, _("newly allocated leaf"),
- ip->i_sbd->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
- return 0;
-}
-
-struct metawalk_fxns alloc_fxns = {
- .private = NULL,
- .check_leaf = alloc_leaf,
- .check_metalist = alloc_metalist,
- .check_data = alloc_data,
- .check_eattr_indir = NULL,
- .check_eattr_leaf = NULL,
- .check_dentry = NULL,
- .check_eattr_entry = NULL,
- .check_eattr_extentry = NULL,
- .finish_eattr_indir = NULL,
-};
-
-/*
- * reprocess_inode - fixes the blockmap to match the bitmap due to an
- * unexpected block allocation via libgfs2.
- *
- * The problem we're trying to overcome here is when a new block must be
- * added to a dinode because of a write. This will happen when lost+found
- * needs a new indirect block for its hash table. In that case, the write
- * causes a new block to be assigned in the bitmap but that block is not yet
- * accurately reflected in the fsck blockmap. We need to compensate here.
- *
- * We can't really use fsck_blockmap_set here because the new block
- * was already allocated by libgfs2 and therefore it took care of
- * the rgrp free space variable. fsck_blockmap_set adjusts the free space
- * in the rgrp according to the change, which has already been done.
- * So it's only our blockmap that now disagrees with the rgrp bitmap, so we
- * need to fix only that.
- */
-void reprocess_inode(struct gfs2_inode *ip, const char *desc)
-{
- int error;
-
- alloc_fxns.private = (void *)desc;
- log_info( _("%s inode %llu (0x%llx) had blocks added; reprocessing "
- "its metadata tree at height=%d.\n"), desc,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- ip->i_di.di_height);
- error = check_metatree(ip, &alloc_fxns);
- if (error)
- log_err( _("Error %d reprocessing the %s metadata tree.\n"),
- error, desc);
-}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 6d6c3ff..d505945 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -54,7 +54,6 @@ extern int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
const char *caller, int line);
extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
int error_on_dinode, int new_blockmap_state);
-extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
extern struct duptree *dupfind(uint64_t block);
extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
uint64_t block);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 8d68028..d12e03e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1180,6 +1180,113 @@ static int set_ip_blockmap(struct gfs2_inode *ip)
return 0;
}
+static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, int h, int *is_valid,
+ int *was_duplicate, void *private)
+{
+ int q;
+ const char *desc = (const char *)private;
+
+ /* No need to range_check here--if it was added, it's in range. */
+ /* We can't check the bitmap here because this function is called
+ after the bitmap has been set but before the blockmap has. */
+ *is_valid = 1;
+ *was_duplicate = 0;
+ *bh = bread(ip->i_sbd, block);
+ q = bitmap_type(ip->i_sbd, block);
+ if (q == GFS2_BLKST_FREE) {
+ log_debug(_("%s reference to new metadata block "
+ "%lld (0x%llx) is now marked as indirect.\n"),
+ desc, (unsigned long long)block,
+ (unsigned long long)block);
+ gfs2_blockmap_set(bl, block, ip->i_sbd->gfs1 ?
+ GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+ }
+ return meta_is_good;
+}
+
+static int alloc_data(struct gfs2_inode *ip, uint64_t metablock,
+ uint64_t block, void *private,
+ struct gfs2_buffer_head *bh, uint64_t *ptr)
+{
+ int q;
+ const char *desc = (const char *)private;
+
+ /* No need to range_check here--if it was added, it's in range. */
+ /* We can't check the bitmap here because this function is called
+ after the bitmap has been set but before the blockmap has. */
+ q = bitmap_type(ip->i_sbd, block);
+ if (q == GFS2_BLKST_FREE) {
+ log_debug(_("%s reference to new data block "
+ "%lld (0x%llx) is now marked as data.\n"),
+ desc, (unsigned long long)block,
+ (unsigned long long)block);
+ gfs2_blockmap_set(bl, block, GFS2_BLKST_USED);
+ }
+ return 0;
+}
+
+static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+{
+ int q;
+
+ /* No need to range_check here--if it was added, it's in range. */
+ /* We can't check the bitmap here because this function is called
+ after the bitmap has been set but before the blockmap has. */
+ q = bitmap_type(ip->i_sbd, block);
+ if (q == GFS2_BLKST_FREE)
+ fsck_blockmap_set(ip, block, _("newly allocated leaf"),
+ ip->i_sbd->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
+ return 0;
+}
+
+struct metawalk_fxns alloc_fxns = {
+ .private = NULL,
+ .check_leaf = alloc_leaf,
+ .check_metalist = alloc_metalist,
+ .check_data = alloc_data,
+ .check_eattr_indir = NULL,
+ .check_eattr_leaf = NULL,
+ .check_dentry = NULL,
+ .check_eattr_entry = NULL,
+ .check_eattr_extentry = NULL,
+ .finish_eattr_indir = NULL,
+};
+
+/*
+ * reprocess_inode - fixes the blockmap to match the bitmap due to an
+ * unexpected block allocation via libgfs2.
+ *
+ * The problem we're trying to overcome here is when a new block must be
+ * added to a dinode because of a write. This will happen when lost+found
+ * needs a new indirect block for its hash table. In that case, the write
+ * causes a new block to be assigned in the bitmap but that block is not yet
+ * accurately reflected in the fsck blockmap. We need to compensate here.
+ *
+ * We can't really use fsck_blockmap_set here because the new block
+ * was already allocated by libgfs2 and therefore it took care of
+ * the rgrp free space variable. fsck_blockmap_set adjusts the free space
+ * in the rgrp according to the change, which has already been done.
+ * So it's only our blockmap that now disagrees with the rgrp bitmap, so we
+ * need to fix only that.
+ */
+static void reprocess_inode(struct gfs2_inode *ip, const char *desc)
+{
+ int error;
+
+ alloc_fxns.private = (void *)desc;
+ log_info( _("%s inode %llu (0x%llx) had blocks added; reprocessing "
+ "its metadata tree at height=%d.\n"), desc,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ ip->i_di.di_height);
+ error = check_metatree(ip, &alloc_fxns);
+ if (error)
+ log_err( _("Error %d reprocessing the %s metadata tree.\n"),
+ error, desc);
+}
+
/*
* handle_ip - process an incore structure representing a dinode.
*/
8 years
gfs2-utils: master - fsck.gfs2: Eliminate astate code
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=4a1e4d8c...
Commit: 4a1e4d8c2a9ab5eff3f3f54364c2d482a9e783c8
Parent: e662521a03290bd5542a65b0191cdf75c0e46139
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Mar 15 14:54:34 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:48:39 2016 -0500
fsck.gfs2: Eliminate astate code
Since all the passes after pass1 now use the rgrp bitmaps for the
definitive state of a block, there's no more need to re-sync the
blockmap with the bitmap. Therefore, we can completely eliminate
the astate save/restore and reprocessing code.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/metawalk.c | 6 ------
gfs2/fsck/pass2.c | 21 ---------------------
gfs2/fsck/pass3.c | 18 ------------------
gfs2/fsck/pass4.c | 5 -----
gfs2/fsck/util.h | 20 --------------------
5 files changed, 0 insertions(+), 70 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index c37110f..cbc73e9 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1718,9 +1718,6 @@ int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
int check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
int error = 0;
- struct alloc_state as;
-
- astate_save(ip, &as);
if (ip->i_di.di_flags & GFS2_DIF_EXHASH)
error = check_leaf_blks(ip, pass);
@@ -1730,9 +1727,6 @@ int check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip, struct metawalk_fxns
if (error < 0)
stack;
- if (astate_changed(ip, &as))
- reprocess_inode(ip, _("Current"));
-
return error;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 96074d2..a215b3c 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -1837,7 +1837,6 @@ build_it:
return -1;
}
fsck_bitmap_set(ip, ip->i_di.di_num.no_addr, fn, GFS2_BLKST_DINODE);
- reprocess_inode(ip, fn);
log_err(_("System file %s rebuilt.\n"), fn);
goto out_good;
}
@@ -1848,7 +1847,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
int builder(struct gfs2_sbd *sdp))
{
uint64_t iblock = 0;
- struct alloc_state as;
struct dir_status ds = {0};
int error = 0;
@@ -1865,15 +1863,12 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
pass2_fxns.private = (void *) &ds;
if (ds.q == GFS2_BLKST_UNLINKED) {
- astate_save(sysinode, &as);
/* First check that the directory's metatree is valid */
error = check_metatree(sysinode, &pass2_fxns);
if (error < 0) {
stack;
return error;
}
- if (astate_changed(sysinode, &as))
- reprocess_inode(sysinode, _("System inode"));
}
error = check_dir(sysinode->i_sbd, sysinode, &pass2_fxns);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -1892,7 +1887,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
if (!ds.dotdir) {
log_err( _("No '.' entry found for %s directory.\n"), dirname);
if (query( _("Is it okay to add '.' entry? (y/n) "))) {
- astate_save(sysinode, &as);
log_warn( _("Adding '.' entry\n"));
error = dir_add(sysinode, ".", 1, &(sysinode->i_di.di_num),
(sysinode->i_sbd->gfs1 ? GFS_FILE_DIR : DT_DIR));
@@ -1901,8 +1895,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
strerror(errno));
return -errno;
}
- if (astate_changed(sysinode, &as))
- reprocess_inode(sysinode, dirname);
/* This system inode is linked to itself via '.' */
incr_link_count(sysinode->i_di.di_num, sysinode,
"sysinode \".\"");
@@ -1974,20 +1966,16 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
{
uint64_t dirblk = ip->i_di.di_num.no_addr;
struct dir_status ds = {0};
- struct alloc_state as;
int error;
pass2_fxns.private = &ds;
if (ds.q == GFS2_BLKST_UNLINKED) {
/* First check that the directory's metatree is valid */
- astate_save(ip, &as);
error = check_metatree(ip, &pass2_fxns);
if (error < 0) {
stack;
return error;
}
- if (astate_changed(ip, &as))
- reprocess_inode(ip, "current");
}
error = check_dir(sdp, ip, &pass2_fxns);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -2037,7 +2025,6 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
(unsigned long long)dirblk, (unsigned long long)dirblk);
if (query( _("Is it okay to add '.' entry? (y/n) "))) {
- astate_save(ip, &as);
error = dir_add(ip, ".", 1, &(ip->i_di.di_num),
(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
if (error) {
@@ -2045,14 +2032,6 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
strerror(errno));
return -errno;
}
- if (astate_changed(ip, &as)) {
- char dirname[80];
-
- sprintf(dirname, _("Directory at %lld (0x%llx)"),
- (unsigned long long)dirblk,
- (unsigned long long)dirblk);
- reprocess_inode(ip, dirname);
- }
/* directory links to itself via '.' */
incr_link_count(ip->i_di.di_num, ip, _("\". (itself)\""));
ds.entry_count++;
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index dad1f5c..0df427d 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -24,7 +24,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
int filename_len = 2;
int err;
struct gfs2_inode *ip, *pip;
- struct alloc_state as;
ip = fsck_load_inode(sdp, block);
pip = fsck_load_inode(sdp, newdotdot);
@@ -39,7 +38,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
log_warn( _("Unable to remove \"..\" directory entry.\n"));
else
decr_link_count(olddotdot, block, _("old \"..\""));
- astate_save(ip, &as);
err = dir_add(ip, filename, filename_len, &pip->i_di.di_num,
(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
if (err) {
@@ -47,14 +45,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
filename, strerror(errno));
exit(FSCK_ERROR);
}
- if (astate_changed(ip, &as)) {
- char dirname[80];
-
- sprintf(dirname, _("Directory at %lld (0x%llx)"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- reprocess_inode(ip, dirname);
- }
incr_link_count(pip->i_di.di_num, ip, _("new \"..\""));
fsck_inode_put(&ip);
fsck_inode_put(&pip);
@@ -182,7 +172,6 @@ int pass3(struct gfs2_sbd *sdp)
struct dir_info *di, *tdi;
struct gfs2_inode *ip;
int q;
- struct alloc_state lf_as = {.as_blocks = 0, .as_meta_goal = 0};
di = dirtree_find(sdp->md.rooti->i_di.di_num.no_addr);
if (di) {
@@ -229,8 +218,6 @@ int pass3(struct gfs2_sbd *sdp)
*/
log_info( _("Checking directory linkage.\n"));
for (tmp = osi_first(&dirtree); tmp; tmp = next) {
- if (lf_dip && lf_as.as_blocks == 0)
- astate_save(lf_dip, &lf_as);
next = osi_next(tmp);
di = (struct dir_info *)tmp;
while (!di->checked) {
@@ -328,11 +315,6 @@ int pass3(struct gfs2_sbd *sdp)
}
}
if (lf_dip) {
- /* If the lf directory had new blocks added we have to mark
- them properly in the blockmap so they're not freed. */
- if (astate_changed(lf_dip, &lf_as))
- reprocess_inode(lf_dip, "lost+found");
-
log_debug( _("At end of pass3, lost+found entries is %u\n"),
lf_dip->i_di.di_entries);
}
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 25c63b7..ba38e8c 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -48,15 +48,12 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
struct gfs2_inode *ip;
int lf_addition = 0;
int q;
- struct alloc_state lf_as = {.as_blocks = 0, .as_meta_goal = 0};
/* FIXME: should probably factor this out into a generic
* scanning fxn */
for (tmp = osi_first(&inodetree); tmp; tmp = next) {
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
- if (lf_dip && lf_as.as_blocks == 0)
- astate_save(lf_dip, &lf_as);
next = osi_next(tmp);
ii = (struct inode_info *)tmp;
/* Don't check reference counts on the special gfs files */
@@ -179,8 +176,6 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
if (lf_dip == NULL)
return 0;
- if (astate_changed(lf_dip, &lf_as))
- reprocess_inode(lf_dip, "lost+found");
if (lf_addition) {
if (!(ii = inodetree_find(lf_dip->i_di.di_num.no_addr))) {
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 45a9000..7753daf 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -12,11 +12,6 @@
#define INODE_VALID 1
#define INODE_INVALID 0
-struct alloc_state {
- uint64_t as_blocks;
- uint64_t as_meta_goal;
-};
-
struct di_info *search_list(osi_list_t *list, uint64_t addr);
void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
void warm_fuzzy_stuff(uint64_t block);
@@ -32,21 +27,6 @@ extern const char *reftypes[ref_types + 1];
#define BLOCKMAP_BYTE_OFFSET2(x) ((x & 0x0000000000000003) << 1)
#define BLOCKMAP_MASK2 (0x3)
-static inline void astate_save(struct gfs2_inode *ip, struct alloc_state *as)
-{
- as->as_blocks = ip->i_di.di_blocks;
- as->as_meta_goal = ip->i_di.di_goal_meta;
-}
-
-static inline int astate_changed(struct gfs2_inode *ip, struct alloc_state *as)
-{
- if (as->as_blocks != ip->i_di.di_blocks)
- return 1;
- if (as->as_meta_goal != ip->i_di.di_goal_meta)
- return 1;
- return 0;
-}
-
static inline int block_type(uint64_t bblock)
{
static unsigned char *byte;
8 years
gfs2-utils: master - fsck.gfs2: Move leaf repair to pass2
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=e662521a...
Commit: e662521a03290bd5542a65b0191cdf75c0e46139
Parent: 2744575f37549f1b73343e9196297b6a88f43bf9
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Mar 14 19:51:27 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:48:39 2016 -0500
fsck.gfs2: Move leaf repair to pass2
We don't want to try to repair directory leaf blocks from pass1
because we haven't verified the bitmap yet, so we cannot do
block allocations if necessary. Therefore, we postpone leaf
repair to pass2, where all the other directory integrity checks
are done. We also change fsck_blockmap_set to fsck_bitmap_set.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/metawalk.c | 179 +-------------------------------------------------
gfs2/fsck/metawalk.h | 8 +--
gfs2/fsck/pass1.c | 9 ---
gfs2/fsck/pass2.c | 147 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 146 insertions(+), 197 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index ce23220..c37110f 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -629,8 +629,7 @@ bad_leaf:
brelse(lbh);
if (pass->repair_leaf) {
/* The leaf we read in is bad so we need to repair it. */
- fix = pass->repair_leaf(ip, leaf_no, lindex, *ref_count, msg,
- pass->private);
+ fix = pass->repair_leaf(ip, leaf_no, lindex, *ref_count, msg);
if (fix < 0)
return fix;
@@ -2024,179 +2023,3 @@ void reprocess_inode(struct gfs2_inode *ip, const char *desc)
log_err( _("Error %d reprocessing the %s metadata tree.\n"),
error, desc);
}
-
-/*
- * write_new_leaf - allocate and write a new leaf to cover a gap in hash table
- * @dip: the directory inode
- * @start_lindex: where in the hash table to start writing
- * @num_copies: number of copies of the pointer to write into hash table
- * @before_or_after: desc. of whether this is being added before/after/etc.
- * @bn: pointer to return the newly allocated leaf's block number
- */
-int write_new_leaf(struct gfs2_inode *dip, int start_lindex, int num_copies,
- const char *before_or_after, uint64_t *bn)
-{
- struct gfs2_buffer_head *nbh;
- struct gfs2_leaf *leaf;
- struct gfs2_dirent *dent;
- int count, i;
- int factor = 0, pad_size;
- uint64_t *cpyptr;
- char *padbuf;
- int divisor = num_copies;
- int end_lindex = start_lindex + num_copies;
-
- padbuf = malloc(num_copies * sizeof(uint64_t));
- /* calculate the depth needed for the new leaf */
- while (divisor > 1) {
- factor++;
- divisor /= 2;
- }
- /* Make sure the number of copies is properly a factor of 2 */
- if ((1 << factor) != num_copies) {
- log_err(_("Program error: num_copies not a factor of 2.\n"));
- log_err(_("num_copies=%d, dinode = %lld (0x%llx)\n"),
- num_copies,
- (unsigned long long)dip->i_di.di_num.no_addr,
- (unsigned long long)dip->i_di.di_num.no_addr);
- log_err(_("lindex = %d (0x%x)\n"), start_lindex, start_lindex);
- stack;
- free(padbuf);
- return -1;
- }
-
- /* allocate and write out a new leaf block */
- if (lgfs2_meta_alloc(dip, bn)) {
- log_err( _("Error: allocation failed while fixing directory leaf "
- "pointers.\n"));
- free(padbuf);
- return -1;
- }
- fsck_blockmap_set(dip, *bn, _("directory leaf"), dip->i_sbd->gfs1 ?
- GFS2_BLKST_DINODE : GFS2_BLKST_USED);
- log_err(_("A new directory leaf was allocated at block %lld "
- "(0x%llx) to fill the %d (0x%x) pointer gap %s the existing "
- "pointer at index %d (0x%x).\n"), (unsigned long long)*bn,
- (unsigned long long)*bn, num_copies, num_copies,
- before_or_after, start_lindex, start_lindex);
- dip->i_di.di_blocks++;
- bmodified(dip->i_bh);
- nbh = bget(dip->i_sbd, *bn);
- memset(nbh->b_data, 0, dip->i_sbd->bsize);
- leaf = (struct gfs2_leaf *)nbh->b_data;
- leaf->lf_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
- leaf->lf_header.mh_type = cpu_to_be32(GFS2_METATYPE_LF);
- leaf->lf_header.mh_format = cpu_to_be32(GFS2_FORMAT_LF);
- leaf->lf_depth = cpu_to_be16(dip->i_di.di_depth - factor);
-
- /* initialize the first dirent on the new leaf block */
- dent = (struct gfs2_dirent *)(nbh->b_data + sizeof(struct gfs2_leaf));
- dent->de_rec_len = cpu_to_be16(dip->i_sbd->bsize -
- sizeof(struct gfs2_leaf));
- bmodified(nbh);
- brelse(nbh);
-
- /* pad the hash table with the new leaf block */
- cpyptr = (uint64_t *)padbuf;
- for (i = start_lindex; i < end_lindex; i++) {
- *cpyptr = cpu_to_be64(*bn);
- cpyptr++;
- }
- pad_size = num_copies * sizeof(uint64_t);
- log_err(_("Writing to the hash table of directory %lld "
- "(0x%llx) at index: 0x%x for 0x%lx pointers.\n"),
- (unsigned long long)dip->i_di.di_num.no_addr,
- (unsigned long long)dip->i_di.di_num.no_addr,
- start_lindex, (unsigned long)pad_size / sizeof(uint64_t));
- if (dip->i_sbd->gfs1)
- count = gfs1_writei(dip, padbuf, start_lindex *
- sizeof(uint64_t), pad_size);
- else
- count = gfs2_writei(dip, padbuf, start_lindex *
- sizeof(uint64_t), pad_size);
- free(padbuf);
- if (count != pad_size) {
- log_err( _("Error: bad write while fixing directory leaf "
- "pointers.\n"));
- return -1;
- }
- return 0;
-}
-
-/* repair_leaf - Warn the user of an error and ask permission to fix it
- * Process a bad leaf pointer and ask to repair the first time.
- * The repair process involves extending the previous leaf's entries
- * so that they replace the bad ones. We have to hack up the old
- * leaf a bit, but it's better than deleting the whole directory,
- * which is what used to happen before. */
-int repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no, int lindex,
- int ref_count, const char *msg, int allow_alloc)
-{
- int new_leaf_blks = 0, error, refs;
- uint64_t bn = 0;
-
- log_err( _("Directory Inode %llu (0x%llx) points to leaf %llu"
- " (0x%llx) %s.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)*leaf_no,
- (unsigned long long)*leaf_no, msg);
- if (!query( _("Attempt to patch around it? (y/n) "))) {
- log_err( _("Bad leaf left in place.\n"));
- goto out;
- }
- if (!allow_alloc) {
- uint64_t *cpyptr;
- char *padbuf;
- int pad_size, i;
-
- padbuf = malloc(ref_count * sizeof(uint64_t));
- cpyptr = (uint64_t *)padbuf;
- for (i = 0; i < ref_count; i++) {
- *cpyptr = 0;
- cpyptr++;
- }
- pad_size = ref_count * sizeof(uint64_t);
- log_err(_("Writing zeros to the hash table of directory %lld "
- "(0x%llx) at index: 0x%x for 0x%x pointers.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- lindex, ref_count);
- if (ip->i_sbd->gfs1)
- gfs1_writei(ip, padbuf, lindex * sizeof(uint64_t),
- pad_size);
- else
- gfs2_writei(ip, padbuf, lindex * sizeof(uint64_t),
- pad_size);
- free(padbuf);
- log_err( _("Directory Inode %llu (0x%llx) patched.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- goto out;
- }
- /* We can only write leafs in quantities that are factors of
- two, since leaves are doubled, not added sequentially.
- So if we have a hole that's not a factor of 2, we have to
- break it down into separate leaf blocks that are. */
- while (ref_count) {
- refs = 1;
- while (refs <= ref_count) {
- if (refs * 2 > ref_count)
- break;
- refs *= 2;
- }
- error = write_new_leaf(ip, lindex, refs, _("replacing"), &bn);
- if (error)
- return error;
-
- new_leaf_blks++;
- lindex += refs;
- ref_count -= refs;
- }
- log_err( _("Directory Inode %llu (0x%llx) repaired.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
-out:
- *leaf_no = bn;
- return new_leaf_blks;
-}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 90bd028..6d6c3ff 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -60,11 +60,6 @@ extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
uint64_t block);
extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
const char *btype);
-extern int write_new_leaf(struct gfs2_inode *dip, int start_lindex,
- int num_copies, const char *before_or_after,
- uint64_t *bn);
-extern int repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no, int lindex,
- int ref_count, const char *msg, int allow_alloc);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
@@ -155,8 +150,7 @@ struct metawalk_fxns {
int (*check_hash_tbl) (struct gfs2_inode *ip, uint64_t *tbl,
unsigned hsize, void *private);
int (*repair_leaf) (struct gfs2_inode *ip, uint64_t *leaf_no,
- int lindex, int ref_count, const char *msg,
- void *private);
+ int lindex, int ref_count, const char *msg);
int (*undo_check_meta) (struct gfs2_inode *ip, uint64_t block,
int h, void *private);
int (*undo_check_data) (struct gfs2_inode *ip, uint64_t block,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index e1653f1..8d68028 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -84,14 +84,6 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
void *private);
static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
-static int pass1_repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no,
- int lindex, int ref_count, const char *msg,
- void *private)
-{
- repair_leaf(ip, leaf_no, lindex, ref_count, msg, 0);
- return 0;
-}
-
struct metawalk_fxns pass1_fxns = {
.private = NULL,
.check_leaf = p1check_leaf,
@@ -103,7 +95,6 @@ struct metawalk_fxns pass1_fxns = {
.check_eattr_entry = check_eattr_entries,
.check_eattr_extentry = check_extended_leaf_eattr,
.big_file_msg = big_file_comfort,
- .repair_leaf = pass1_repair_leaf,
.undo_check_meta = undo_check_metalist,
.undo_check_data = undo_check_data,
};
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 214fa03..96074d2 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -853,6 +853,105 @@ nuke_dentry:
return 1;
}
+/*
+ * write_new_leaf - allocate and write a new leaf to cover a gap in hash table
+ * @dip: the directory inode
+ * @start_lindex: where in the hash table to start writing
+ * @num_copies: number of copies of the pointer to write into hash table
+ * @before_or_after: desc. of whether this is being added before/after/etc.
+ * @bn: pointer to return the newly allocated leaf's block number
+ */
+static int write_new_leaf(struct gfs2_inode *dip, int start_lindex,
+ int num_copies, const char *before_or_after,
+ uint64_t *bn)
+{
+ struct gfs2_buffer_head *nbh;
+ struct gfs2_leaf *leaf;
+ struct gfs2_dirent *dent;
+ int count, i;
+ int factor = 0, pad_size;
+ uint64_t *cpyptr;
+ char *padbuf;
+ int divisor = num_copies;
+ int end_lindex = start_lindex + num_copies;
+
+ padbuf = malloc(num_copies * sizeof(uint64_t));
+ /* calculate the depth needed for the new leaf */
+ while (divisor > 1) {
+ factor++;
+ divisor /= 2;
+ }
+ /* Make sure the number of copies is properly a factor of 2 */
+ if ((1 << factor) != num_copies) {
+ log_err(_("Program error: num_copies not a factor of 2.\n"));
+ log_err(_("num_copies=%d, dinode = %lld (0x%llx)\n"),
+ num_copies,
+ (unsigned long long)dip->i_di.di_num.no_addr,
+ (unsigned long long)dip->i_di.di_num.no_addr);
+ log_err(_("lindex = %d (0x%x)\n"), start_lindex, start_lindex);
+ stack;
+ free(padbuf);
+ return -1;
+ }
+
+ /* allocate and write out a new leaf block */
+ if (lgfs2_meta_alloc(dip, bn)) {
+ log_err( _("Error: allocation failed while fixing directory leaf "
+ "pointers.\n"));
+ free(padbuf);
+ return -1;
+ }
+ fsck_bitmap_set(dip, *bn, _("directory leaf"), dip->i_sbd->gfs1 ?
+ GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+ log_err(_("A new directory leaf was allocated at block %lld "
+ "(0x%llx) to fill the %d (0x%x) pointer gap %s the existing "
+ "pointer at index %d (0x%x).\n"), (unsigned long long)*bn,
+ (unsigned long long)*bn, num_copies, num_copies,
+ before_or_after, start_lindex, start_lindex);
+ dip->i_di.di_blocks++;
+ bmodified(dip->i_bh);
+ nbh = bget(dip->i_sbd, *bn);
+ memset(nbh->b_data, 0, dip->i_sbd->bsize);
+ leaf = (struct gfs2_leaf *)nbh->b_data;
+ leaf->lf_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
+ leaf->lf_header.mh_type = cpu_to_be32(GFS2_METATYPE_LF);
+ leaf->lf_header.mh_format = cpu_to_be32(GFS2_FORMAT_LF);
+ leaf->lf_depth = cpu_to_be16(dip->i_di.di_depth - factor);
+
+ /* initialize the first dirent on the new leaf block */
+ dent = (struct gfs2_dirent *)(nbh->b_data + sizeof(struct gfs2_leaf));
+ dent->de_rec_len = cpu_to_be16(dip->i_sbd->bsize -
+ sizeof(struct gfs2_leaf));
+ bmodified(nbh);
+ brelse(nbh);
+
+ /* pad the hash table with the new leaf block */
+ cpyptr = (uint64_t *)padbuf;
+ for (i = start_lindex; i < end_lindex; i++) {
+ *cpyptr = cpu_to_be64(*bn);
+ cpyptr++;
+ }
+ pad_size = num_copies * sizeof(uint64_t);
+ log_err(_("Writing to the hash table of directory %lld "
+ "(0x%llx) at index: 0x%x for 0x%lx pointers.\n"),
+ (unsigned long long)dip->i_di.di_num.no_addr,
+ (unsigned long long)dip->i_di.di_num.no_addr,
+ start_lindex, (unsigned long)pad_size / sizeof(uint64_t));
+ if (dip->i_sbd->gfs1)
+ count = gfs1_writei(dip, padbuf, start_lindex *
+ sizeof(uint64_t), pad_size);
+ else
+ count = gfs2_writei(dip, padbuf, start_lindex *
+ sizeof(uint64_t), pad_size);
+ free(padbuf);
+ if (count != pad_size) {
+ log_err( _("Error: bad write while fixing directory leaf "
+ "pointers.\n"));
+ return -1;
+ }
+ return 0;
+}
+
/* pad_with_leafblks - pad a hash table with pointers to new leaf blocks
*
* @ip: pointer to the dinode structure
@@ -1047,11 +1146,53 @@ static int basic_check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
}
+/* pass2_repair_leaf - Warn the user of an error and ask permission to fix it
+ * Process a bad leaf pointer and ask to repair the first time.
+ * The repair process involves extending the previous leaf's entries
+ * so that they replace the bad ones. We have to hack up the old
+ * leaf a bit, but it's better than deleting the whole directory,
+ * which is what used to happen before. */
static int pass2_repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no,
- int lindex, int ref_count, const char *msg,
- void *private)
+ int lindex, int ref_count, const char *msg)
{
- return repair_leaf(ip, leaf_no, lindex, ref_count, msg, 1);
+ int new_leaf_blks = 0, error, refs;
+ uint64_t bn = 0;
+
+ log_err( _("Directory Inode %llu (0x%llx) points to leaf %llu"
+ " (0x%llx) %s.\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)*leaf_no,
+ (unsigned long long)*leaf_no, msg);
+ if (!query( _("Attempt to patch around it? (y/n) "))) {
+ log_err( _("Bad leaf left in place.\n"));
+ goto out;
+ }
+ /* We can only write leafs in quantities that are factors of
+ two, since leaves are doubled, not added sequentially.
+ So if we have a hole that's not a factor of 2, we have to
+ break it down into separate leaf blocks that are. */
+ while (ref_count) {
+ refs = 1;
+ while (refs <= ref_count) {
+ if (refs * 2 > ref_count)
+ break;
+ refs *= 2;
+ }
+ error = write_new_leaf(ip, lindex, refs, _("replacing"), &bn);
+ if (error)
+ return error;
+
+ new_leaf_blks++;
+ lindex += refs;
+ ref_count -= refs;
+ }
+ log_err( _("Directory Inode %llu (0x%llx) repaired.\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+out:
+ *leaf_no = bn;
+ return new_leaf_blks;
}
/* The purpose of leafck_fxns is to provide a means for function fix_hashtable
8 years
gfs2-utils: master - fsck.gfs2: Remove unneeded parameter instree
from set_ip_blockmap
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=2744575f...
Commit: 2744575f37549f1b73343e9196297b6a88f43bf9
Parent: 3552c6b9eb77eabcd59fa22172f5209df0e6f900
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Mar 14 19:43:33 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:48:39 2016 -0500
fsck.gfs2: Remove unneeded parameter instree from set_ip_blockmap
This patch removes parameter instree from function set_ip_blockmap,
since it is only called in one place.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass1.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index e09bcb4..e1653f1 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1143,11 +1143,9 @@ struct metawalk_fxns eattr_undo_fxns = {
};
/* set_ip_blockmap - set the blockmap for a dinode
*
- * instree: Set to 1 if directories should be inserted into the directory tree
- * otherwise 0.
* returns: 0 if no error, -EINVAL if dinode has a bad mode, -EPERM on error
*/
-static int set_ip_blockmap(struct gfs2_inode *ip, int instree)
+static int set_ip_blockmap(struct gfs2_inode *ip)
{
uint64_t block = ip->i_bh->b_blocknr;
uint32_t mode;
@@ -1184,7 +1182,7 @@ static int set_ip_blockmap(struct gfs2_inode *ip, int instree)
return -EINVAL;
}
if (fsck_blockmap_set(ip, block, ty, GFS2_BLKST_DINODE) ||
- (mode == S_IFDIR && instree && !dirtree_insert(ip->i_di.di_num))) {
+ (mode == S_IFDIR && !dirtree_insert(ip->i_di.di_num))) {
stack;
return -EPERM;
}
@@ -1220,7 +1218,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
return 0;
}
- error = set_ip_blockmap(ip, 1);
+ error = set_ip_blockmap(ip);
if (error == -EINVAL) {
/* We found a dinode that has an invalid mode. At this point
set_ip_blockmap returned an error, which means it never
8 years
gfs2-utils: master - fsck.gfs2: Move set_ip_blockmap to pass1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=3552c6b9...
Commit: 3552c6b9eb77eabcd59fa22172f5209df0e6f900
Parent: 8a299130dbaa5f5a6c3120b426a21f1e235e1a72
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Mar 14 19:41:23 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:48:38 2016 -0500
fsck.gfs2: Move set_ip_blockmap to pass1
Since function set_ip_blockmap is now only called from pass1,
move it to pass1 and make it static.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass1.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/fsck/util.c | 50 --------------------------------------------------
gfs2/fsck/util.h | 1 -
3 files changed, 49 insertions(+), 51 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index cc70d5f..e09bcb4 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1141,6 +1141,55 @@ struct metawalk_fxns eattr_undo_fxns = {
.check_eattr_leaf = undo_eattr_indir_or_leaf,
.finish_eattr_indir = finish_eattr_indir,
};
+/* set_ip_blockmap - set the blockmap for a dinode
+ *
+ * instree: Set to 1 if directories should be inserted into the directory tree
+ * otherwise 0.
+ * returns: 0 if no error, -EINVAL if dinode has a bad mode, -EPERM on error
+ */
+static int set_ip_blockmap(struct gfs2_inode *ip, int instree)
+{
+ uint64_t block = ip->i_bh->b_blocknr;
+ uint32_t mode;
+ const char *ty;
+
+ if (ip->i_sbd->gfs1)
+ mode = gfs_to_gfs2_mode(ip);
+ else
+ mode = ip->i_di.di_mode & S_IFMT;
+
+ switch (mode) {
+ case S_IFDIR:
+ ty = _("directory");
+ break;
+ case S_IFREG:
+ ty = _("file");
+ break;
+ case S_IFLNK:
+ ty = _("symlink");
+ break;
+ case S_IFBLK:
+ ty = _("block device");
+ break;
+ case S_IFCHR:
+ ty = _("character device");
+ break;
+ case S_IFIFO:
+ ty = _("fifo");
+ break;
+ case S_IFSOCK:
+ ty = _("socket");
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (fsck_blockmap_set(ip, block, ty, GFS2_BLKST_DINODE) ||
+ (mode == S_IFDIR && instree && !dirtree_insert(ip->i_di.di_num))) {
+ stack;
+ return -EPERM;
+ }
+ return 0;
+}
/*
* handle_ip - process an incore structure representing a dinode.
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 55bd050..7ca7b91 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -591,56 +591,6 @@ void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
return il;
}
-/* set_ip_blockmap - set the blockmap for a dinode
- *
- * instree: Set to 1 if directories should be inserted into the directory tree
- * otherwise 0.
- * returns: 0 if no error, -EINVAL if dinode has a bad mode, -EPERM on error
- */
-int set_ip_blockmap(struct gfs2_inode *ip, int instree)
-{
- uint64_t block = ip->i_bh->b_blocknr;
- uint32_t mode;
- const char *ty;
-
- if (ip->i_sbd->gfs1)
- mode = gfs_to_gfs2_mode(ip);
- else
- mode = ip->i_di.di_mode & S_IFMT;
-
- switch (mode) {
- case S_IFDIR:
- ty = _("directory");
- break;
- case S_IFREG:
- ty = _("file");
- break;
- case S_IFLNK:
- ty = _("symlink");
- break;
- case S_IFBLK:
- ty = _("block device");
- break;
- case S_IFCHR:
- ty = _("character device");
- break;
- case S_IFIFO:
- ty = _("fifo");
- break;
- case S_IFSOCK:
- ty = _("socket");
- break;
- default:
- return -EINVAL;
- }
- if (fsck_blockmap_set(ip, block, ty, GFS2_BLKST_DINODE) ||
- (mode == S_IFDIR && instree && !dirtree_insert(ip->i_di.di_num))) {
- stack;
- return -EPERM;
- }
- return 0;
-}
-
uint64_t find_free_blk(struct gfs2_sbd *sdp)
{
struct osi_node *n, *next = NULL;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 8709193..45a9000 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -119,7 +119,6 @@ extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
uint64_t *addl_mem_needed);
extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block, int mark);
-extern int set_ip_blockmap(struct gfs2_inode *ip, int instree);
extern char generic_interrupt(const char *caller, const char *where,
const char *progress, const char *question,
const char *answers);
8 years
gfs2-utils: master - fsck.gfs2: Change all fsck_blockmap_set to
fsck_bitmap_set
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8a299130...
Commit: 8a299130dbaa5f5a6c3120b426a21f1e235e1a72
Parent: 5c3f62df970cefe922318223d7862389ec8e85e7
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Mar 14 17:33:10 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:46:36 2016 -0500
fsck.gfs2: Change all fsck_blockmap_set to fsck_bitmap_set
This patch changes all functions past pass1 so that they set the
bits in the bitmap rather than bits in the blockmap. This is a
step toward being able to free the blockmap after pass1.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/lost_n_found.c | 4 +-
gfs2/fsck/metawalk.c | 36 +++++++++++--------
gfs2/fsck/metawalk.h | 7 ++++
gfs2/fsck/pass1b.c | 90 ++++++++++++++++++++++++++++++++-------------
gfs2/fsck/pass2.c | 33 ++++++++---------
gfs2/fsck/pass3.c | 17 +++------
gfs2/fsck/pass4.c | 16 ++++----
7 files changed, 122 insertions(+), 81 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index cd847f8..9c85f52 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -139,8 +139,8 @@ void make_sure_lf_exists(struct gfs2_inode *ip)
/* FIXME: i'd feel better about this if fs_mkdir returned
whether it created a new directory or just found an old one,
and we used that instead of the bitmap_type to run this */
- fsck_blockmap_set(ip, lf_dip->i_di.di_num.no_addr,
- _("lost+found dinode"), GFS2_BLKST_DINODE);
+ fsck_bitmap_set(ip, lf_dip->i_di.di_num.no_addr,
+ _("lost+found dinode"), GFS2_BLKST_DINODE);
dirtree_insert(lf_dip->i_di.di_num);
/* root inode links to lost+found */
incr_link_count(sdp->md.rooti->i_di.di_num, lf_dip, _("root"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 3cb5a7a..ce23220 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -110,12 +110,11 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk, int error_on_dinode,
}
/*
- * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
- * bitmap, and adjust free space accordingly.
+ * _fsck_bitmap_set - Mark a block in the bitmap, and adjust free space.
*/
-int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
- const char *btype, int mark,
- int error_on_dinode, const char *caller, int fline)
+int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
+ const char *btype, int mark,
+ int error_on_dinode, const char *caller, int fline)
{
int error;
static int prev_ino_addr = 0;
@@ -172,19 +171,26 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
prev_mark = mark;
prev_caller = caller;
}
-
- /* First, check the rgrp bitmap against what we think it should be.
- If that fails, it's an invalid block--part of an rgrp. */
error = check_n_fix_bitmap(ip->i_sbd, bblock, error_on_dinode, mark);
- if (error) {
- if (error < 0)
- log_err( _("This block is not represented in the "
- "bitmap.\n"));
+ if (error < 0)
+ log_err(_("This block is not represented in the bitmap.\n"));
+ return error;
+}
+
+/*
+ * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
+ * bitmap, and adjust free space accordingly.
+ */
+int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
+ const char *btype, int mark,
+ int error_on_dinode, const char *caller, int fline)
+{
+ int error = _fsck_bitmap_set(ip, bblock, btype, mark, error_on_dinode,
+ caller, fline);
+ if (error)
return error;
- }
- error = gfs2_blockmap_set(bl, bblock, mark);
- return error;
+ return gfs2_blockmap_set(bl, bblock, mark);
}
struct duptree *dupfind(uint64_t block)
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 8ec38d0..90bd028 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -49,6 +49,9 @@ extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
extern int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
const char *btype, int mark, int error_on_dinode,
const char *caller, int line);
+extern int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
+ const char *btype, int mark, int error_on_dinode,
+ const char *caller, int line);
extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
int error_on_dinode, int new_blockmap_state);
extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
@@ -65,6 +68,10 @@ extern int repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no, int lindex,
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
+#define fsck_bitmap_set(ip, b, bt, m) \
+ _fsck_bitmap_set(ip, b, bt, m, 0, __FUNCTION__, __LINE__)
+#define fsck_bitmap_set_noino(ip, b, bt, m) \
+ _fsck_bitmap_set(ip, b, bt, m, 1, __FUNCTION__, __LINE__)
#define fsck_blockmap_set(ip, b, bt, m) \
_fsck_blockmap_set(ip, b, bt, m, 0, __FUNCTION__, __LINE__)
#define fsck_blkmap_set_noino(ip, b, bt, m) \
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index ee636fe..20b603c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -348,9 +348,9 @@ static void resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *dt,
ii = inodetree_find(ip->i_di.di_num.no_addr);
if (ii)
inodetree_delete(ii);
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
+ fsck_bitmap_set(ip, ip->i_di.di_num.no_addr,
_("duplicate referencing bad"),
- GFS2_BLKST_UNLINKED);
+ GFS2_BLKST_UNLINKED);
/* We delete the dup_handler inode count and
duplicate id BEFORE clearing the metadata,
because if this is the last reference to
@@ -428,8 +428,8 @@ static int clone_data(struct gfs2_inode *ip, uint64_t metablock,
if (!error) {
clone_bh = bread(ip->i_sbd, clonet->dup_block);
if (clone_bh) {
- fsck_blockmap_set(ip, cloneblock, _("data"),
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, cloneblock, _("data"),
+ GFS2_BLKST_USED);
clone_bh->b_blocknr = cloneblock;
bmodified(clone_bh);
brelse(clone_bh);
@@ -496,6 +496,46 @@ static void clone_dup_ref_in_inode(struct gfs2_inode *ip, struct duptree *dt)
}
}
+static int set_ip_bitmap(struct gfs2_inode *ip)
+{
+ uint64_t block = ip->i_bh->b_blocknr;
+ uint32_t mode;
+ const char *ty;
+
+ if (ip->i_sbd->gfs1)
+ mode = gfs_to_gfs2_mode(ip);
+ else
+ mode = ip->i_di.di_mode & S_IFMT;
+
+ switch (mode) {
+ case S_IFDIR:
+ ty = _("directory");
+ break;
+ case S_IFREG:
+ ty = _("file");
+ break;
+ case S_IFLNK:
+ ty = _("symlink");
+ break;
+ case S_IFBLK:
+ ty = _("block device");
+ break;
+ case S_IFCHR:
+ ty = _("character device");
+ break;
+ case S_IFIFO:
+ ty = _("fifo");
+ break;
+ case S_IFSOCK:
+ ty = _("socket");
+ break;
+ default:
+ return -EINVAL;
+ }
+ fsck_bitmap_set(ip, block, ty, GFS2_BLKST_DINODE);
+ return 0;
+}
+
static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
enum dup_ref_type acceptable_ref)
{
@@ -531,31 +571,31 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
"marked invalid: Marking the block as free.\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
- fsck_blockmap_set(ip, dt->block, _("reference-repaired leaf"),
+ fsck_bitmap_set(ip, dt->block, _("reference-repaired leaf"),
GFS2_BLKST_FREE);
} else if (id->reftypecount[ref_is_inode]) {
- set_ip_blockmap(ip, 0); /* 0=do not add to dirtree */
+ set_ip_bitmap(ip);
} else if (id->reftypecount[ref_as_data]) {
- fsck_blockmap_set(ip, dt->block, _("reference-repaired data"),
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, dt->block, _("reference-repaired data"),
+ GFS2_BLKST_USED);
} else if (id->reftypecount[ref_as_meta]) {
if (is_dir(&ip->i_di, sdp->gfs1))
- fsck_blockmap_set(ip, dt->block,
- _("reference-repaired leaf"),
- sdp->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, dt->block,
+ _("reference-repaired leaf"),
+ sdp->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
else
- fsck_blockmap_set(ip, dt->block,
- _("reference-repaired indirect"),
- sdp->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, dt->block,
+ _("reference-repaired indirect"),
+ sdp->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
} else {
if (acceptable_ref == ref_as_ea)
- fsck_blockmap_set(ip, dt->block,
- _("reference-repaired extended "
- "attribute"),
- sdp->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, dt->block,
+ _("reference-repaired extended "
+ "attribute"),
+ sdp->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
else {
log_err(_("Error: The remaining reference to block "
" %lld (0x%llx) is as extended attribute, "
@@ -574,9 +614,9 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT;
ip->i_di.di_blocks--;
bmodified(ip->i_bh);
- fsck_blockmap_set(ip, dt->block,
- _("reference-repaired EA"),
- GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, dt->block,
+ _("reference-repaired EA"),
+ GFS2_BLKST_FREE);
log_err(_("The bad extended attribute was "
"removed.\n"));
} else {
@@ -725,8 +765,6 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *dt)
(unsigned long long)dup_blk);
if (dh.dt)
dup_delete(dh.dt);
- /* Now fix the block type of the block in question. */
- gfs2_blockmap_set(bl, dup_blk, GFS2_BLKST_FREE);
check_n_fix_bitmap(sdp, dup_blk, 0, GFS2_BLKST_FREE);
}
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index f114d2b..214fa03 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -375,9 +375,9 @@ static int wrong_leaf(struct gfs2_inode *ip, struct gfs2_inum *entry,
(unsigned long long)real_leaf,
(unsigned long long)real_leaf,
(unsigned long long)ip->i_di.di_blocks);
- fsck_blockmap_set(ip, real_leaf, _("split leaf"),
- sdp->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, real_leaf, _("split leaf"),
+ sdp->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
}
/* If the misplaced dirent was supposed to be earlier in the
hash table, we need to adjust our counts for the blocks
@@ -475,9 +475,9 @@ static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 0;
}
/* Don't be tempted to do this:
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("corrupt directory entry"),
- GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, ip->i_di.di_num.no_addr,
+ _("corrupt directory entry"),
+ GFS2_BLKST_FREE);
We can't free it because another dir may have a valid reference
to it. Just return 1 so we can delete the bad dirent. */
log_err( _("Bad directory entry deleted.\n"));
@@ -893,9 +893,9 @@ static void pad_with_leafblks(struct gfs2_inode *ip, uint64_t *tbl,
(unsigned long long)new_leaf_blk,
(unsigned long long)new_leaf_blk,
lindex, lindex, new_len);
- fsck_blockmap_set(ip, new_leaf_blk, _("pad leaf"),
- ip->i_sbd->gfs1 ?
- GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, new_leaf_blk, _("pad leaf"),
+ ip->i_sbd->gfs1 ?
+ GFS2_BLKST_DINODE : GFS2_BLKST_USED);
/* Fix the hash table in memory to have the new leaf */
for (i = 0; i < new_len; i++)
tbl[lindex + i] = cpu_to_be64(new_leaf_blk);
@@ -997,7 +997,7 @@ static int lost_leaf(struct gfs2_inode *ip, uint64_t *tbl, uint64_t leafno,
log_err(_("Directory entries from misplaced leaf block were relocated "
"to lost+found.\n"));
/* Free the lost leaf. */
- fsck_blockmap_set(ip, leafno, _("lost leaf"), GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, leafno, _("lost leaf"), GFS2_BLKST_FREE);
ip->i_di.di_blocks--;
bmodified(ip->i_bh);
/* Now we have to deal with the bad hash table entries pointing to the
@@ -1228,9 +1228,9 @@ static int fix_hashtable(struct gfs2_inode *ip, uint64_t *tbl, unsigned hsize,
"(0x%llx) for index %d (0x%x)\n"),
(unsigned long long)new_leaf_blk,
(unsigned long long)new_leaf_blk, lindex, lindex);
- fsck_blockmap_set(ip, new_leaf_blk, _("split leaf"),
- ip->i_sbd->gfs1 ?
- GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+ fsck_bitmap_set(ip, new_leaf_blk, _("split leaf"),
+ ip->i_sbd->gfs1 ?
+ GFS2_BLKST_DINODE : GFS2_BLKST_USED);
log_err(_("Hash table repaired.\n"));
/* Fix up the hash table in memory to include the new leaf */
for (i = 0; i < *proper_len; i++)
@@ -1695,7 +1695,7 @@ build_it:
log_err(_("Error rebuilding %s.\n"), fn);
return -1;
}
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr, fn, GFS2_BLKST_DINODE);
+ fsck_bitmap_set(ip, ip->i_di.di_num.no_addr, fn, GFS2_BLKST_DINODE);
reprocess_inode(ip, fn);
log_err(_("System file %s rebuilt.\n"), fn);
goto out_good;
@@ -1742,7 +1742,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
return -1;
}
if (error > 0)
- fsck_blockmap_set(sysinode, iblock, dirname, GFS2_BLKST_FREE);
+ fsck_bitmap_set(sysinode, iblock, dirname, GFS2_BLKST_FREE);
if (check_inode_eattr(sysinode, &pass2_fxns)) {
stack;
@@ -1888,9 +1888,6 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
log_debug(_("Directory block %lld (0x%llx) is now marked as 'invalid'\n"),
(unsigned long long)dirblk, (unsigned long long)dirblk);
- /* Can't use fsck_blockmap_set here because we don't
- have an inode in memory. */
- gfs2_blockmap_set(bl, dirblk, GFS2_BLKST_FREE);
check_n_fix_bitmap(sdp, dirblk, 0, GFS2_BLKST_FREE);
}
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index a3c0a60..dad1f5c 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -250,6 +250,7 @@ int pass3(struct gfs2_sbd *sdp)
continue;
}
q = bitmap_type(sdp, di->dinode.no_addr);
+ ip = fsck_load_inode(sdp, di->dinode.no_addr);
if (q == GFS2_BLKST_UNLINKED) {
log_err( _("Found unlinked directory "
"containing bad block at block %llu"
@@ -264,12 +265,9 @@ int pass3(struct gfs2_sbd *sdp)
di->dinode.no_addr,
(unsigned long long)
di->dinode.no_addr);
- /* Can't use fsck_blockmap_set
- because we don't have ip */
- gfs2_blockmap_set(bl, di->dinode.no_addr,
- GFS2_BLKST_FREE);
check_n_fix_bitmap(sdp, di->dinode.no_addr,
0, GFS2_BLKST_FREE);
+ fsck_inode_put(&ip);
break;
} else
log_err( _("Unlinked directory with bad block remains\n"));
@@ -287,13 +285,10 @@ int pass3(struct gfs2_sbd *sdp)
"marked as free\n"),
(unsigned long long)di->dinode.no_addr,
(unsigned long long)di->dinode.no_addr);
- /* Can't use fsck_blockmap_set
- because we don't have ip */
- gfs2_blockmap_set(bl, di->dinode.no_addr,
- GFS2_BLKST_FREE);
check_n_fix_bitmap(sdp, di->dinode.no_addr, 0,
GFS2_BLKST_FREE);
log_err( _("The block was cleared\n"));
+ fsck_inode_put(&ip);
break;
}
@@ -301,17 +296,15 @@ int pass3(struct gfs2_sbd *sdp)
" (0x%llx)\n"),
(unsigned long long)di->dinode.no_addr,
(unsigned long long)di->dinode.no_addr);
- ip = fsck_load_inode(sdp, di->dinode.no_addr);
/* Don't skip zero size directories with eattrs */
if (!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked directory has zero "
"size.\n"));
if (query( _("Remove zero-size unlinked "
"directory? (y/n) "))) {
- fsck_blockmap_set(ip,
- di->dinode.no_addr,
+ fsck_bitmap_set(ip, di->dinode.no_addr,
_("zero-sized unlinked inode"),
- GFS2_BLKST_FREE);
+ GFS2_BLKST_FREE);
fsck_inode_put(&ip);
break;
} else {
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index dcd5ba7..25c63b7 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -82,9 +82,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
check_inode_eattr(ip,
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
- fsck_blockmap_set(ip, ii->di_num.no_addr,
- _("bad unlinked"),
- GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, ii->di_num.no_addr,
+ _("bad unlinked"),
+ GFS2_BLKST_FREE);
fsck_inode_put(&ip);
continue;
} else
@@ -101,9 +101,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
check_inode_eattr(ip,
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
- fsck_blockmap_set(ip, ii->di_num.no_addr,
- _("invalid unlinked"),
- GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, ii->di_num.no_addr,
+ _("invalid unlinked"),
+ GFS2_BLKST_FREE);
fsck_inode_put(&ip);
log_err( _("The inode was deleted\n"));
} else {
@@ -122,9 +122,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
log_err( _("Unlinked inode has zero size\n"));
if (query(_("Clear zero-size unlinked inode? "
"(y/n) "))) {
- fsck_blockmap_set(ip, ii->di_num.no_addr,
+ fsck_bitmap_set(ip, ii->di_num.no_addr,
_("unlinked zero-length"),
- GFS2_BLKST_FREE);
+ GFS2_BLKST_FREE);
fsck_inode_put(&ip);
continue;
}
8 years
gfs2-utils: master - fsck.gfs2: pass1b shouldn't complain about
non-bitmap blocks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=5c3f62df...
Commit: 5c3f62df970cefe922318223d7862389ec8e85e7
Parent: e352d9865ee230de00c12a03ba0d6a3b812abbda
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 23 12:26:30 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 15 08:57:43 2016 -0400
fsck.gfs2: pass1b shouldn't complain about non-bitmap blocks
One of the previous patches switched pass1b to stop using the
blockmap and start using the bitmap. One major difference between
them is that the blockmap has a value (0 - 3) for every block on
the device, whereas the bitmap has a value (0 - 3) for every block
in the file system. It does not have a value for blocks that are
on the device but aren't in the file system, such as the superblock
and the blocks preceding it, the blocks reserved for the rgrps
and their respective bitmaps.
That means the block_map function returned 0 for non-fs blocks,
but the bitmap function returned -1 (meaning invalid block).
The result was that pass1b complained about every non-fs block.
This patch makes pass1b check the return code from function
bitmap_type() and if it's a negative number, it skips over it.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass1b.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a7b3e42..ee636fe 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -885,7 +885,7 @@ int pass1b(struct gfs2_sbd *sdp)
}
q = bitmap_type(sdp, i);
- if (q == GFS2_BLKST_FREE || q == GFS2_BLKST_USED)
+ if (q == GFS2_BLKST_FREE || q == GFS2_BLKST_USED || q < 0)
continue;
if (q == GFS2_BLKST_UNLINKED)
8 years
gfs2-utils: master - fsck.gfs2: Use di_entries to determine if
lost+found was created
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=e352d986...
Commit: e352d9865ee230de00c12a03ba0d6a3b812abbda
Parent: 54d819d3eb39e2a2b4a519dc6d9366baf4efdd39
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Mar 29 14:42:05 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 15 08:57:35 2016 -0400
fsck.gfs2: Use di_entries to determine if lost+found was created
Before this patch, function make_sure_lf_exists compared the bitmap
to the blockmap to determine if the lost+found directory was created.
Since we're phasing out the blockmap, and only want to use the
bitmap, we need an alternative. This patch changes it to check the
number of directory entries in the root directory has increased.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/lost_n_found.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 0b57d21..cd847f8 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -99,14 +99,15 @@ static void add_dotdot(struct gfs2_inode *ip)
void make_sure_lf_exists(struct gfs2_inode *ip)
{
- int q;
struct dir_info *di;
struct gfs2_sbd *sdp = ip->i_sbd;
uint32_t mode;
+ int root_entries;
if (lf_dip)
return;
+ root_entries = sdp->md.rooti->i_di.di_entries;
log_info( _("Locating/Creating lost+found directory\n"));
/* if this is gfs1, we have to trick createi into using
@@ -131,8 +132,7 @@ void make_sure_lf_exists(struct gfs2_inode *ip)
them in sync so that pass4 can detect and fix any descrepancies. */
set_di_nlink(sdp->md.rooti);
- q = bitmap_type(sdp, lf_dip->i_di.di_num.no_addr);
- if (q != GFS2_BLKST_DINODE) {
+ if (sdp->md.rooti->i_di.di_entries > root_entries) {
lf_was_created = 1;
/* This is a new lost+found directory, so set its block type
and increment link counts for the directories */
8 years
gfs2-utils: master - fsck.gfs2: Change bitmap_type variables to int
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=54d819d3...
Commit: 54d819d3eb39e2a2b4a519dc6d9366baf4efdd39
Parent: faeebbcdc222b554ad066e704e0eea11bd2cdc27
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Mar 29 14:33:56 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 15 08:57:27 2016 -0400
fsck.gfs2: Change bitmap_type variables to int
This patch changes all references of "q" from a uint8_t to a normal
int. This will allow us to check for bad return codes at some point.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/lost_n_found.c | 2 +-
gfs2/fsck/metawalk.c | 12 ++++++------
gfs2/fsck/pass1.c | 18 +++++++++---------
gfs2/fsck/pass1b.c | 6 +++---
gfs2/fsck/pass2.c | 16 ++++++++--------
gfs2/fsck/pass3.c | 4 ++--
gfs2/fsck/pass4.c | 2 +-
gfs2/fsck/pass5.c | 2 +-
gfs2/fsck/util.c | 2 +-
gfs2/fsck/util.h | 10 +++++-----
11 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index a3c5f72..4cf4ce1 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -53,7 +53,7 @@ struct dir_info
struct dir_status {
uint8_t dotdir:1;
uint8_t dotdotdir:1;
- uint8_t q;
+ int q;
uint32_t entry_count;
};
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 4816b3c..0b57d21 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -99,7 +99,7 @@ static void add_dotdot(struct gfs2_inode *ip)
void make_sure_lf_exists(struct gfs2_inode *ip)
{
- uint8_t q;
+ int q;
struct dir_info *di;
struct gfs2_sbd *sdp = ip->i_sbd;
uint32_t mode;
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index f401f2c..3cb5a7a 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1040,7 +1040,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
const char *btype, int *was_duplicate,
void *private)
{
- uint8_t q;
+ int q;
if (!valid_block(ip->i_sbd, block))
return meta_error;
@@ -1760,7 +1760,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
{
struct metawalk_fxns remove_dentry_fxns = {0};
struct gfs2_inode *ip;
- uint8_t q;
+ int q;
int error;
log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
@@ -1822,7 +1822,7 @@ static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
{
int ret = 0;
int was_free = 0;
- uint8_t q;
+ int q;
if (valid_block(ip->i_sbd, block)) {
q = bitmap_type(ip->i_sbd, block);
@@ -1916,7 +1916,7 @@ static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h, int *is_valid,
int *was_duplicate, void *private)
{
- uint8_t q;
+ int q;
const char *desc = (const char *)private;
/* No need to range_check here--if it was added, it's in range. */
@@ -1941,7 +1941,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t metablock,
uint64_t block, void *private,
struct gfs2_buffer_head *bh, uint64_t *ptr)
{
- uint8_t q;
+ int q;
const char *desc = (const char *)private;
/* No need to range_check here--if it was added, it's in range. */
@@ -1960,7 +1960,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t metablock,
static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
{
- uint8_t q;
+ int q;
/* No need to range_check here--if it was added, it's in range. */
/* We can't check the bitmap here because this function is called
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 875f3d3..cc70d5f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -214,7 +214,7 @@ struct metawalk_fxns sysdir_fxns = {
static int p1check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
{
struct block_count *bc = (struct block_count *) private;
- uint8_t q;
+ int q;
/* Note if we've gotten this far, the block has already passed the
check in metawalk: gfs2_check_meta(lbh, GFS2_METATYPE_LF).
@@ -247,7 +247,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h, int *is_valid,
int *was_duplicate, void *private)
{
- uint8_t q;
+ int q;
int iblk_type;
struct gfs2_buffer_head *nbh;
struct block_count *bc = (struct block_count *)private;
@@ -445,7 +445,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t metablock,
uint64_t block, void *private,
struct gfs2_buffer_head *bbh, uint64_t *ptr)
{
- uint8_t q;
+ int q;
struct block_count *bc = (struct block_count *) private;
if (!valid_block(ip->i_sbd, block)) {
@@ -581,7 +581,7 @@ static int undo_eattr_indir_or_leaf(struct gfs2_inode *ip, uint64_t block,
void *private)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- uint8_t q;
+ int q;
int error;
struct block_count *bc = (struct block_count *) private;
@@ -629,7 +629,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
{
struct gfs2_sbd *sdp = ip->i_sbd;
int ret = 0;
- uint8_t q;
+ int q;
struct block_count *bc = (struct block_count *) private;
/* This inode contains an eattr - it may be invalid, but the
@@ -720,7 +720,7 @@ static int check_ealeaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
{
struct gfs2_buffer_head *leaf_bh = NULL;
struct gfs2_sbd *sdp = ip->i_sbd;
- uint8_t q;
+ int q;
struct block_count *bc = (struct block_count *) private;
q = block_type(block);
@@ -948,7 +948,7 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
enum dup_ref_type reftype, const char *btype,
int *is_valid, int *was_duplicate)
{
- uint8_t q;
+ int q;
/* If the block isn't valid, we obviously can't invalidate it.
* However, if we return an error, invalidating will stop, and
@@ -1051,7 +1051,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
void *private)
{
long *bad_pointers = (long *)private;
- uint8_t q;
+ int q;
if (!valid_block(ip->i_sbd, block)) {
(*bad_pointers)++;
@@ -1583,7 +1583,7 @@ static int pass1_process_bitmap(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, uin
unsigned i;
uint64_t block;
struct gfs2_inode *ip;
- uint8_t q;
+ int q;
/* Readahead numbers arrived at by experiment */
unsigned rawin = 50;
unsigned ralen = 100 * sdp->bsize;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 66dd0a8..a7b3e42 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -203,7 +203,7 @@ static void resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *dt,
enum dup_ref_type this_ref;
struct inode_info *ii;
int found_good_ref = 0;
- uint8_t q;
+ int q;
osi_list_foreach_safe(tmp, ref_list, x) {
if (skip_this_pass || fsck_abort)
@@ -502,7 +502,7 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
struct gfs2_inode *ip;
struct inode_with_dups *id;
osi_list_t *tmp;
- uint8_t q;
+ int q;
log_notice( _("Block %llu (0x%llx) has only one remaining "
"valid inode referencing it.\n"),
@@ -856,7 +856,7 @@ int pass1b(struct gfs2_sbd *sdp)
{
struct duptree *dt;
uint64_t i;
- uint8_t q;
+ int q;
struct osi_node *n;
int rc = FSCK_OK;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index afee8dc..f114d2b 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -135,7 +135,7 @@ static const char *de_type_string(uint8_t de_type)
return de_types[3]; /* invalid */
}
-static int check_file_type(uint64_t block, uint8_t de_type, uint8_t q,
+static int check_file_type(uint64_t block, uint8_t de_type, int q,
int gfs1, int *isdir)
{
struct dir_info *dt;
@@ -176,7 +176,7 @@ struct metawalk_fxns pass2_fxns_delete = {
*/
static int bad_formal_ino(struct gfs2_inode *ip, struct gfs2_dirent *dent,
struct gfs2_inum entry, const char *tmp_name,
- uint8_t q, struct gfs2_dirent *de,
+ int q, struct gfs2_dirent *de,
struct gfs2_buffer_head *bh)
{
struct inode_info *ii;
@@ -299,7 +299,7 @@ static int wrong_leaf(struct gfs2_inode *ip, struct gfs2_inum *entry,
int hash_index, struct gfs2_buffer_head *bh,
struct dir_status *ds, struct gfs2_dirent *dent,
struct gfs2_dirent *de, struct gfs2_dirent *prev_de,
- uint32_t *count, uint8_t q)
+ uint32_t *count, int q)
{
struct gfs2_sbd *sdp = ip->i_sbd;
struct gfs2_buffer_head *dest_lbh;
@@ -437,7 +437,7 @@ static int wrong_leaf(struct gfs2_inode *ip, struct gfs2_inum *entry,
static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
struct gfs2_inum *entry, const char *tmp_name,
uint32_t *count, struct gfs2_dirent *de,
- struct dir_status *ds, uint8_t *q,
+ struct dir_status *ds, int *q,
struct gfs2_buffer_head *bh, int *isdir)
{
struct gfs2_sbd *sdp = ip->i_sbd;
@@ -643,7 +643,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
uint32_t *count, int *lindex, void *priv)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- uint8_t q = 0;
+ int q = 0;
char tmp_name[MAX_FILENAME];
struct gfs2_inum entry;
struct dir_status *ds = (struct dir_status *) priv;
@@ -955,7 +955,7 @@ static int lost_leaf(struct gfs2_inode *ip, uint64_t *tbl, uint64_t leafno,
} else {
uint32_t count;
struct dir_status ds = {0};
- uint8_t q = 0;
+ int q = 0;
error = basic_dentry_checks(ip, dent, &de.de_inum,
tmp_name, &count, &de,
@@ -1013,7 +1013,7 @@ static int basic_check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
struct gfs2_buffer_head *bh, char *filename,
uint32_t *count, int *lindex, void *priv)
{
- uint8_t q = 0;
+ int q = 0;
char tmp_name[MAX_FILENAME];
struct gfs2_inum entry;
struct dir_status *ds = (struct dir_status *) priv;
@@ -1953,7 +1953,7 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
int pass2(struct gfs2_sbd *sdp)
{
uint64_t dirblk;
- uint8_t q;
+ int q;
/* Check all the system directory inodes. */
if (!sdp->gfs1 &&
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 7732178..a3c0a60 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -65,7 +65,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
struct dir_info *di)
{
struct dir_info *pdi;
- uint8_t q_dotdot, q_treewalk;
+ int q_dotdot, q_treewalk;
int error = 0;
struct dir_info *dt_dotdot, *dt_treewalk;
@@ -181,7 +181,7 @@ int pass3(struct gfs2_sbd *sdp)
struct osi_node *tmp, *next = NULL;
struct dir_info *di, *tdi;
struct gfs2_inode *ip;
- uint8_t q;
+ int q;
struct alloc_state lf_as = {.as_blocks = 0, .as_meta_goal = 0};
di = dirtree_find(sdp->md.rooti->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index c3fb30a..dcd5ba7 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -47,7 +47,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
struct inode_info *ii;
struct gfs2_inode *ip;
int lf_addition = 0;
- uint8_t q;
+ int q;
struct alloc_state lf_as = {.as_blocks = 0, .as_meta_goal = 0};
/* FIXME: should probably factor this out into a generic
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index fab3e5c..99ff0a1 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -19,7 +19,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
unsigned char *byte, *end;
unsigned int bit;
unsigned char rg_status;
- uint8_t q;
+ int q;
uint64_t block;
/* FIXME verify cast */
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 44a41ba..55bd050 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -364,7 +364,7 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
if (id == NULL) {
/* Check for the inode on the invalid inode reference list. */
- uint8_t q;
+ int q;
id = calloc(1, sizeof(*id));
if (!id) {
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 7d842e2..8709193 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -47,11 +47,11 @@ static inline int astate_changed(struct gfs2_inode *ip, struct alloc_state *as)
return 0;
}
-static inline uint8_t block_type(uint64_t bblock)
+static inline int block_type(uint64_t bblock)
{
static unsigned char *byte;
static uint64_t b;
- static uint8_t btype;
+ static int btype;
byte = bl->map + BLOCKMAP_SIZE2(bblock);
b = BLOCKMAP_BYTE_OFFSET2(bblock);
@@ -59,7 +59,7 @@ static inline uint8_t block_type(uint64_t bblock)
return btype;
}
-static inline uint8_t bitmap_type(struct gfs2_sbd *sdp, uint64_t bblock)
+static inline int bitmap_type(struct gfs2_sbd *sdp, uint64_t bblock)
{
struct rgrp_tree *rgd;
@@ -67,10 +67,10 @@ static inline uint8_t bitmap_type(struct gfs2_sbd *sdp, uint64_t bblock)
return lgfs2_get_bitmap(sdp, bblock, rgd);
}
-static const inline char *block_type_string(uint8_t q)
+static const inline char *block_type_string(int q)
{
const char *blktyp[] = {"free", "data", "other", "inode", "invalid"};
- if (q <= GFS2_BLKST_DINODE)
+ if (q >= GFS2_BLKST_FREE && q <= GFS2_BLKST_DINODE)
return (blktyp[q]);
return blktyp[4];
}
8 years
gfs2-utils: master - fsck.gfs2: Convert block_type to bitmap_type
after pass1 and 5
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=faeebbcd...
Commit: faeebbcdc222b554ad066e704e0eea11bd2cdc27
Parent: 4519c9ca6f8e85713989a4faf113f6468d5a1152
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Mar 14 15:53:22 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 15 08:57:14 2016 -0400
fsck.gfs2: Convert block_type to bitmap_type after pass1 and 5
This patch changes all the passes that happen after pass1 and 5
from using block_type to using bitmap_type. This is a step toward
eliminating the blockmap after pass1 and pass5 are complete.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/lost_n_found.c | 4 ++--
gfs2/fsck/metawalk.c | 12 ++++++------
gfs2/fsck/pass1b.c | 6 +++---
gfs2/fsck/pass2.c | 6 +++---
gfs2/fsck/pass3.c | 8 ++++----
gfs2/fsck/pass4.c | 2 +-
gfs2/fsck/util.c | 2 +-
gfs2/fsck/util.h | 8 ++++++++
8 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index ba3ae1d..4816b3c 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -131,14 +131,14 @@ void make_sure_lf_exists(struct gfs2_inode *ip)
them in sync so that pass4 can detect and fix any descrepancies. */
set_di_nlink(sdp->md.rooti);
- q = block_type(lf_dip->i_di.di_num.no_addr);
+ q = bitmap_type(sdp, lf_dip->i_di.di_num.no_addr);
if (q != GFS2_BLKST_DINODE) {
lf_was_created = 1;
/* This is a new lost+found directory, so set its block type
and increment link counts for the directories */
/* FIXME: i'd feel better about this if fs_mkdir returned
whether it created a new directory or just found an old one,
- and we used that instead of the block_type to run this */
+ and we used that instead of the bitmap_type to run this */
fsck_blockmap_set(ip, lf_dip->i_di.di_num.no_addr,
_("lost+found dinode"), GFS2_BLKST_DINODE);
dirtree_insert(lf_dip->i_di.di_num);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 8fcaea3..f401f2c 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1045,7 +1045,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
if (!valid_block(ip->i_sbd, block))
return meta_error;
- q = block_type(block);
+ q = bitmap_type(ip->i_sbd, block);
if (q == GFS2_BLKST_FREE) {
log_info( _("%s block %lld (0x%llx), part of inode "
"%lld (0x%llx), was already free.\n"),
@@ -1774,7 +1774,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
remove_dentry_fxns.private = &dentryblock;
remove_dentry_fxns.check_dentry = remove_dentry;
- q = block_type(dir);
+ q = bitmap_type(sdp, dir);
if (q != GFS2_BLKST_DINODE) {
log_info( _("Parent block is not an inode...ignoring\n"));
return 1;
@@ -1825,7 +1825,7 @@ static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
uint8_t q;
if (valid_block(ip->i_sbd, block)) {
- q = block_type(block);
+ q = bitmap_type(ip->i_sbd, block);
if (q == GFS2_BLKST_FREE)
was_free = 1;
ret = delete_block_if_notdup(ip, block, NULL, eatype,
@@ -1925,7 +1925,7 @@ static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
*is_valid = 1;
*was_duplicate = 0;
*bh = bread(ip->i_sbd, block);
- q = block_type(block);
+ q = bitmap_type(ip->i_sbd, block);
if (q == GFS2_BLKST_FREE) {
log_debug(_("%s reference to new metadata block "
"%lld (0x%llx) is now marked as indirect.\n"),
@@ -1947,7 +1947,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t metablock,
/* No need to range_check here--if it was added, it's in range. */
/* We can't check the bitmap here because this function is called
after the bitmap has been set but before the blockmap has. */
- q = block_type(block);
+ q = bitmap_type(ip->i_sbd, block);
if (q == GFS2_BLKST_FREE) {
log_debug(_("%s reference to new data block "
"%lld (0x%llx) is now marked as data.\n"),
@@ -1965,7 +1965,7 @@ static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
/* No need to range_check here--if it was added, it's in range. */
/* We can't check the bitmap here because this function is called
after the bitmap has been set but before the blockmap has. */
- q = block_type(block);
+ q = bitmap_type(ip->i_sbd, block);
if (q == GFS2_BLKST_FREE)
fsck_blockmap_set(ip, block, _("newly allocated leaf"),
ip->i_sbd->gfs1 ? GFS2_BLKST_DINODE :
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 16c0aec..66dd0a8 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -216,7 +216,7 @@ static void resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *dt,
return;
this_ref = get_ref_type(id);
- q = block_type(id->block_no);
+ q = bitmap_type(sdp, id->block_no);
if (inval)
log_warn( _("Invalid "));
/* FIXME: If we already found an acceptable reference to this
@@ -525,7 +525,7 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
if (dt->dup_flags & DUPFLAG_REF1_IS_DUPL)
clone_dup_ref_in_inode(ip, dt);
- q = block_type(id->block_no);
+ q = bitmap_type(sdp, id->block_no);
if (q == GFS2_BLKST_UNLINKED) {
log_debug( _("The remaining reference inode %lld (0x%llx) is "
"marked invalid: Marking the block as free.\n"),
@@ -883,7 +883,7 @@ int pass1b(struct gfs2_sbd *sdp)
"duplicates.\n"), dups_found);
break;
}
- q = block_type(i);
+ q = bitmap_type(sdp, i);
if (q == GFS2_BLKST_FREE || q == GFS2_BLKST_USED)
continue;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 11777eb..afee8dc 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -506,7 +506,7 @@ static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
tmp_name);
}
- *q = block_type(entry->no_addr);
+ *q = bitmap_type(sdp, entry->no_addr);
/* Get the status of the directory inode */
/**
* 1. Blocks marked "invalid" were invalidated due to duplicate
@@ -1720,7 +1720,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
}
iblock = sysinode->i_di.di_num.no_addr;
- ds.q = block_type(iblock);
+ ds.q = bitmap_type(sysinode->i_sbd, iblock);
pass2_fxns.private = (void *) &ds;
if (ds.q == GFS2_BLKST_UNLINKED) {
@@ -1998,7 +1998,7 @@ int pass2(struct gfs2_sbd *sdp)
if (is_system_dir(sdp, dirblk))
continue;
- q = block_type(dirblk);
+ q = bitmap_type(sdp, dirblk);
if (q != GFS2_BLKST_DINODE)
continue;
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 054953f..7732178 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -75,7 +75,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
return NULL;
if (di->dotdot_parent.no_addr == di->treewalk_parent) {
- q_dotdot = block_type(di->dotdot_parent.no_addr);
+ q_dotdot = bitmap_type(sdp, di->dotdot_parent.no_addr);
if (q_dotdot != GFS2_BLKST_DINODE) {
log_err( _("Orphaned directory at block %llu (0x%llx) "
"moved to lost+found\n"),
@@ -95,9 +95,9 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
(unsigned long long)di->dotdot_parent.no_addr,
(unsigned long long)di->treewalk_parent,
(unsigned long long)di->treewalk_parent);
- q_dotdot = block_type(di->dotdot_parent.no_addr);
+ q_dotdot = bitmap_type(sdp, di->dotdot_parent.no_addr);
dt_dotdot = dirtree_find(di->dotdot_parent.no_addr);
- q_treewalk = block_type(di->treewalk_parent);
+ q_treewalk = bitmap_type(sdp, di->treewalk_parent);
dt_treewalk = dirtree_find(di->treewalk_parent);
/* if the dotdot entry isn't a directory, but the
* treewalk is, treewalk is correct - if the treewalk
@@ -249,7 +249,7 @@ int pass3(struct gfs2_sbd *sdp)
di = tdi;
continue;
}
- q = block_type(di->dinode.no_addr);
+ q = bitmap_type(sdp, di->dinode.no_addr);
if (q == GFS2_BLKST_UNLINKED) {
log_err( _("Found unlinked directory "
"containing bad block at block %llu"
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 850a2fe..c3fb30a 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -70,7 +70,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
log_err( _("Found unlinked inode at %llu (0x%llx)\n"),
(unsigned long long)ii->di_num.no_addr,
(unsigned long long)ii->di_num.no_addr);
- q = block_type(ii->di_num.no_addr);
+ q = bitmap_type(sdp, ii->di_num.no_addr);
if (q == GFS2_BLKST_UNLINKED) {
log_err( _("Unlinked inode %llu (0x%llx) contains "
"bad blocks\n"),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 84402fc..44a41ba 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -372,7 +372,7 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
return meta_error;
}
id->block_no = ip->i_di.di_num.no_addr;
- q = block_type(ip->i_di.di_num.no_addr);
+ q = bitmap_type(ip->i_sbd, ip->i_di.di_num.no_addr);
/* If it's an invalid dinode, put it first on the invalid
inode reference list otherwise put it on the normal list. */
if (!inode_valid || q == GFS2_BLKST_UNLINKED)
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 62f8ca6..7d842e2 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -59,6 +59,14 @@ static inline uint8_t block_type(uint64_t bblock)
return btype;
}
+static inline uint8_t bitmap_type(struct gfs2_sbd *sdp, uint64_t bblock)
+{
+ struct rgrp_tree *rgd;
+
+ rgd = gfs2_blk2rgrpd(sdp, bblock);
+ return lgfs2_get_bitmap(sdp, bblock, rgd);
+}
+
static const inline char *block_type_string(uint8_t q)
{
const char *blktyp[] = {"free", "data", "other", "inode", "invalid"};
8 years