[Cluster-devel] [fsck.gfs2 PATCH 06/30] fsck.gfs2: Change all fsck_blockmap_set to fsck_bitmap_set
Bob Peterson
rpeterso at redhat.com
Fri Apr 15 13:38:00 UTC 2016
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 bitmap after pass1.
Signed-off-by: Bob Peterson <rpeterso at 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;
}
--
2.5.5
More information about the Cluster-devel
mailing list