gfs2-utils: master - fsck.gfs2: More refactoring of pass4 function
scan_inode_list
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=14b459c3...
Commit: 14b459c35510ebf1b3ec5155d9f06d4439ddd169
Parent: 7505d11eff02c57d2ed4447aa599ce015cd29e62
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 30 13:55:54 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: More refactoring of pass4 function scan_inode_list
This patch also makes no changes to functionality. It just factors
more code out of function scan_inode_list in pass4 into a new
function called handle_inconsist.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass4.c | 60 ++++++++++++++++++++++++++++------------------------
1 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 8c11761..5dc6e73 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -125,10 +125,38 @@ static int handle_unlinked(struct gfs2_sbd *sdp, uint64_t no_addr,
return 0;
}
-static int scan_inode_list(struct gfs2_sbd *sdp) {
+static void handle_inconsist(struct gfs2_sbd *sdp, uint64_t no_addr,
+ uint32_t *di_nlink, uint32_t counted_links)
+{
+ log_err( _("Link count inconsistent for inode %llu"
+ " (0x%llx) has %u but fsck found %u.\n"),
+ (unsigned long long)no_addr, (unsigned long long)no_addr,
+ *di_nlink, counted_links);
+ /* Read in the inode, adjust the link count, and write it back out */
+ if (query( _("Update link count for inode %llu (0x%llx) ? (y/n) "),
+ (unsigned long long)no_addr, (unsigned long long)no_addr)) {
+ struct gfs2_inode *ip;
+
+ ip = fsck_load_inode(sdp, no_addr); /* bread, inode_get */
+ fix_link_count(counted_links, ip);
+ *di_nlink = counted_links;
+ fsck_inode_put(&ip); /* out, brelse, free */
+ log_warn(_("Link count updated to %d for inode %llu "
+ "(0x%llx)\n"), *di_nlink,
+ (unsigned long long)no_addr,
+ (unsigned long long)no_addr);
+ } else {
+ log_err( _("Link count for inode %llu (0x%llx) still "
+ "incorrect\n"),
+ (unsigned long long)no_addr,
+ (unsigned long long)no_addr);
+ }
+}
+
+static int scan_inode_list(struct gfs2_sbd *sdp)
+{
struct osi_node *tmp, *next = NULL;
struct inode_info *ii;
- struct gfs2_inode *ip;
int lf_addition = 0;
/* FIXME: should probably factor this out into a generic
@@ -151,32 +179,8 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
continue;
} /* if (ii->counted_links == 0) */
else if (ii->di_nlink != ii->counted_links) {
- log_err( _("Link count inconsistent for inode %llu"
- " (0x%llx) has %u but fsck found %u.\n"),
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr, ii->di_nlink,
- ii->counted_links);
- /* Read in the inode, adjust the link count,
- * and write it back out */
- if (query( _("Update link count for inode %llu"
- " (0x%llx) ? (y/n) "),
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr)) {
- ip = fsck_load_inode(sdp, ii->di_num.no_addr); /* bread, inode_get */
- fix_link_count(ii->counted_links, ip);
- ii->di_nlink = ii->counted_links;
- fsck_inode_put(&ip); /* out, brelse, free */
- log_warn( _("Link count updated to %d for "
- "inode %llu (0x%llx)\n"),
- ii->di_nlink,
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr);
- } else {
- log_err( _("Link count for inode %llu (0x%llx"
- ") still incorrect\n"),
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr);
- }
+ handle_inconsist(sdp, ii->di_num.no_addr,
+ &ii->di_nlink, ii->counted_links);
}
log_debug( _("block %llu (0x%llx) has link count %d\n"),
(unsigned long long)ii->di_num.no_addr,
8 years
gfs2-utils: master - fsck.gfs2: refactor pass4 function
scan_inode_list
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=7505d11e...
Commit: 7505d11eff02c57d2ed4447aa599ce015cd29e62
Parent: 994d97724a2214b3b13a1b47c5e34fcd98e49ce2
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 30 13:51:03 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: refactor pass4 function scan_inode_list
This patch makes no functional changes. It just cuts a large swath
of function scan_inode_list and puts it in a separate function,
handle_unlinked. This makes it more versatile for later in order
to save memory.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass4.c | 161 ++++++++++++++++++++++++++++-------------------------
1 files changed, 85 insertions(+), 76 deletions(-)
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 14cce55..8c11761 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -42,12 +42,94 @@ static int fix_link_count(uint32_t counted_links, struct gfs2_inode *ip)
return 0;
}
+/**
+ * handle_unlinked - handle an unlinked dinode
+ *
+ * Note: We need to pass in *counted_links here, not counted_links because
+ * add_inode_to_lf may be called here, and that might change the original
+ * value, whether that's in the dirtree or the inodetree.
+ *
+ * Returns: 1 if caller should do "continue", 0 if not.
+ */
+static int handle_unlinked(struct gfs2_sbd *sdp, uint64_t no_addr,
+ uint32_t *counted_links, int *lf_addition)
+{
+ struct gfs2_inode *ip;
+ int q;
+
+ log_err( _("Found unlinked inode at %llu (0x%llx)\n"),
+ (unsigned long long)no_addr, (unsigned long long)no_addr);
+ q = bitmap_type(sdp, no_addr);
+ if (q == GFS2_BLKST_UNLINKED) {
+ log_err( _("Unlinked inode %llu (0x%llx) contains bad "
+ "blocks\n"), (unsigned long long)no_addr,
+ (unsigned long long)no_addr);
+ if (query(_("Delete unlinked inode with bad blocks? "
+ "(y/n) "))) {
+ ip = fsck_load_inode(sdp, no_addr);
+ check_inode_eattr(ip, &pass4_fxns_delete);
+ check_metatree(ip, &pass4_fxns_delete);
+ fsck_bitmap_set(ip, no_addr, _("bad unlinked"),
+ GFS2_BLKST_FREE);
+ fsck_inode_put(&ip);
+ return 1;
+ } else {
+ log_err( _("Unlinked inode with bad blocks not "
+ "cleared\n"));
+ }
+ }
+ if (q != GFS2_BLKST_DINODE) {
+ log_err( _("Unlinked block %lld (0x%llx) marked as inode is "
+ "not an inode (%d)\n"),
+ (unsigned long long)no_addr,
+ (unsigned long long)no_addr, q);
+ ip = fsck_load_inode(sdp, no_addr);
+ if (query(_("Delete unlinked inode? (y/n) "))) {
+ check_inode_eattr(ip, &pass4_fxns_delete);
+ check_metatree(ip, &pass4_fxns_delete);
+ fsck_bitmap_set(ip, no_addr, _("invalid unlinked"),
+ GFS2_BLKST_FREE);
+ fsck_inode_put(&ip);
+ log_err( _("The inode was deleted\n"));
+ } else {
+ log_err( _("The inode was not deleted\n"));
+ fsck_inode_put(&ip);
+ }
+ return 1;
+ }
+ ip = fsck_load_inode(sdp, no_addr);
+
+ /* We don't want to clear zero-size files with eattrs - there might be
+ relevent info in them. */
+ if (!ip->i_di.di_size && !ip->i_di.di_eattr){
+ log_err( _("Unlinked inode has zero size\n"));
+ if (query(_("Clear zero-size unlinked inode? (y/n) "))) {
+ fsck_bitmap_set(ip, no_addr, _("unlinked zero-length"),
+ GFS2_BLKST_FREE);
+ fsck_inode_put(&ip);
+ return 1;
+ }
+ }
+ if (query( _("Add unlinked inode to lost+found? (y/n)"))) {
+ if (add_inode_to_lf(ip)) {
+ stack;
+ fsck_inode_put(&ip);
+ return -1;
+ } else {
+ fix_link_count(*counted_links, ip);
+ *lf_addition = 1;
+ }
+ } else
+ log_err( _("Unlinked inode left unlinked\n"));
+ fsck_inode_put(&ip);
+ return 0;
+}
+
static int scan_inode_list(struct gfs2_sbd *sdp) {
struct osi_node *tmp, *next = NULL;
struct inode_info *ii;
struct gfs2_inode *ip;
int lf_addition = 0;
- int q;
/* FIXME: should probably factor this out into a generic
* scanning fxn */
@@ -64,82 +146,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
(ii->di_num.no_addr == sdp->md.statfs->i_di.di_num.no_addr)))
continue;
if (ii->counted_links == 0) {
- 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 = bitmap_type(sdp, ii->di_num.no_addr);
- if (q == GFS2_BLKST_UNLINKED) {
- log_err( _("Unlinked inode %llu (0x%llx) contains "
- "bad blocks\n"),
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr);
- if (query( _("Delete unlinked inode with bad "
- "blocks? (y/n) "))) {
- ip = fsck_load_inode(sdp, ii->di_num.no_addr);
- check_inode_eattr(ip,
- &pass4_fxns_delete);
- check_metatree(ip, &pass4_fxns_delete);
- fsck_bitmap_set(ip, ii->di_num.no_addr,
- _("bad unlinked"),
- GFS2_BLKST_FREE);
- fsck_inode_put(&ip);
- continue;
- } else
- log_err( _("Unlinked inode with bad blocks not cleared\n"));
- }
- if (q != GFS2_BLKST_DINODE) {
- log_err( _("Unlinked block %lld (0x%llx) "
- "marked as inode is "
- "not an inode (%d)\n"),
- (unsigned long long)ii->di_num.no_addr,
- (unsigned long long)ii->di_num.no_addr, q);
- ip = fsck_load_inode(sdp, ii->di_num.no_addr);
- if (query(_("Delete unlinked inode? (y/n) "))) {
- check_inode_eattr(ip,
- &pass4_fxns_delete);
- check_metatree(ip, &pass4_fxns_delete);
- 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 {
- log_err( _("The inode was not "
- "deleted\n"));
- fsck_inode_put(&ip);
- }
+ if (handle_unlinked(sdp, ii->di_num.no_addr,
+ &ii->counted_links, &lf_addition))
continue;
- }
- ip = fsck_load_inode(sdp, ii->di_num.no_addr);
-
- /* We don't want to clear zero-size files with
- * eattrs - there might be relevent info in
- * them. */
- if (!ip->i_di.di_size && !ip->i_di.di_eattr){
- log_err( _("Unlinked inode has zero size\n"));
- if (query(_("Clear zero-size unlinked inode? "
- "(y/n) "))) {
- fsck_bitmap_set(ip, ii->di_num.no_addr,
- _("unlinked zero-length"),
- GFS2_BLKST_FREE);
- fsck_inode_put(&ip);
- continue;
- }
-
- }
- if (query( _("Add unlinked inode to lost+found? "
- "(y/n)"))) {
- if (add_inode_to_lf(ip)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- } else {
- fix_link_count(ii->counted_links, ip);
- lf_addition = 1;
- }
- } else
- log_err( _("Unlinked inode left unlinked\n"));
- fsck_inode_put(&ip);
} /* if (ii->counted_links == 0) */
else if (ii->di_nlink != ii->counted_links) {
log_err( _("Link count inconsistent for inode %llu"
8 years
gfs2-utils: master - fsck.gfs2: pass counted_links into
fix_link_count in pass4
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=994d9772...
Commit: 994d97724a2214b3b13a1b47c5e34fcd98e49ce2
Parent: 1dc0025223232470c871153319c53a05fca688dd
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 30 13:44:43 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: pass counted_links into fix_link_count in pass4
This patch changes function fix_link_count so that it accepts the
counted_links rather than a pointer to the inode info structure.
That makes it more versatile for future expansion.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass4.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0d6cc9d..14cce55 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -25,21 +25,20 @@ struct metawalk_fxns pass4_fxns_delete = {
/* Updates the link count of an inode to what the fsck has seen for
* link count */
-static int fix_link_count(struct inode_info *ii, struct gfs2_inode *ip)
+static int fix_link_count(uint32_t counted_links, struct gfs2_inode *ip)
{
log_info( _("Fixing inode link count (%d->%d) for %llu (0x%llx) \n"),
- ip->i_di.di_nlink, ii->counted_links,
+ ip->i_di.di_nlink, counted_links,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- if (ip->i_di.di_nlink == ii->counted_links)
+ if (ip->i_di.di_nlink == counted_links)
return 0;
- ip->i_di.di_nlink = ii->counted_links;
+ ip->i_di.di_nlink = counted_links;
bmodified(ip->i_bh);
log_debug( _("Changing inode %llu (0x%llx) to have %u links\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- ii->counted_links);
+ (unsigned long long)ip->i_di.di_num.no_addr, counted_links);
return 0;
}
@@ -135,7 +134,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
fsck_inode_put(&ip);
return -1;
} else {
- fix_link_count(ii, ip);
+ fix_link_count(ii->counted_links, ip);
lf_addition = 1;
}
} else
@@ -155,7 +154,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
(unsigned long long)ii->di_num.no_addr,
(unsigned long long)ii->di_num.no_addr)) {
ip = fsck_load_inode(sdp, ii->di_num.no_addr); /* bread, inode_get */
- fix_link_count(ii, ip);
+ fix_link_count(ii->counted_links, ip);
ii->di_nlink = ii->counted_links;
fsck_inode_put(&ip); /* out, brelse, free */
log_warn( _("Link count updated to %d for "
@@ -183,7 +182,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
log_crit( _("Unable to find lost+found inode in inode_hash!!\n"));
return -1;
} else {
- fix_link_count(ii, lf_dip);
+ fix_link_count(ii->counted_links, lf_dip);
}
}
8 years
gfs2-utils: master - fsck.gfs2: Add wrapper function
pass1_check_metatree
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=1dc00252...
Commit: 1dc0025223232470c871153319c53a05fca688dd
Parent: 8b3a83763bcbc35ff5ad6d9f1e1b7ee57aa9fdc2
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 23 12:16:47 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: Add wrapper function pass1_check_metatree
This patch adds a wrapper function pass1_check_metatree, which
simply calls the normal check_metatree. Since the regular function
now frees inodes from the bitmap but not the blockmap, pass1 needs
the wrapper function to keep its blockmap in sync with the bitmap.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/pass1.c | 35 +++++++++++++++++++++++++----------
1 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 49f6c6e..f4eea49 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1346,6 +1346,26 @@ struct metawalk_fxns alloc_fxns = {
};
/*
+ * pass1_check_metatree - wrapper function for check_metatree
+ *
+ * Generic function check_metatree sets the bitmap values, but not the
+ * corresponding values in the blockmap. If we get an error, the inode will
+ * have been freed in the bitmap. We need to set the inode address as free
+ * as well.
+ */
+static int pass1_check_metatree(struct gfs2_inode *ip,
+ struct metawalk_fxns *pass)
+{
+ int error;
+
+ error = check_metatree(ip, pass);
+ if (error)
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ GFS2_BLKST_FREE);
+ return error;
+}
+
+/*
* reprocess_inode - fixes the blockmap to match the bitmap due to an
* unexpected block allocation via libgfs2.
*
@@ -1372,15 +1392,10 @@ static void reprocess_inode(struct gfs2_inode *ip, const char *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) {
- /* check_metatree will have fixed the bitmap, but not the
- blockmap. */
- gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
- GFS2_BLKST_FREE);
+ error = pass1_check_metatree(ip, &alloc_fxns);
+ if (error)
log_err( _("Error %d reprocessing the %s metadata tree.\n"),
error, desc);
- }
}
/*
@@ -1400,7 +1415,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
so it's better to check it up front and delete the inode if
there is corruption. */
rangecheck_fxns.private = &bad_pointers;
- error = check_metatree(ip, &rangecheck_fxns);
+ error = pass1_check_metatree(ip, &rangecheck_fxns);
if (bad_pointers > BAD_POINTER_TOLERANCE) {
log_err( _("Error: inode %llu (0x%llx) has more than "
"%d bad pointers.\n"),
@@ -1433,7 +1448,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
lf_blks = lf_dip->i_di.di_blocks;
pass1_fxns.private = &bc;
- error = check_metatree(ip, &pass1_fxns);
+ error = pass1_check_metatree(ip, &pass1_fxns);
/* Pass1 may have added some blocks to lost+found by virtue of leafs
that were misplaced. If it did, we need to reprocess lost+found
@@ -1688,7 +1703,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
sysdir_fxns.private = &bc;
if ((*sysinode)->i_di.di_flags & GFS2_DIF_EXHASH)
- check_metatree(*sysinode, &sysdir_fxns);
+ pass1_check_metatree(*sysinode, &sysdir_fxns);
else {
err = check_linear_dir(*sysinode, (*sysinode)->i_bh,
&sysdir_fxns);
8 years
gfs2-utils: master - fsck.gfs2: make blockmap global variable only to
pass1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8b3a8376...
Commit: 8b3a83763bcbc35ff5ad6d9f1e1b7ee57aa9fdc2
Parent: eb83797b704666e7baba6fe8e3d61835cc63e096
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Mar 18 09:02:15 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: make blockmap global variable only to pass1
This patch changes the variable "bl" from being a global variable
to being global only to pass1. This is another step toward allowing
pass1 to free the blockmap when it's done.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/fsck.h | 3 +-
gfs2/fsck/initialize.c | 11 ----
gfs2/fsck/main.c | 1 -
gfs2/fsck/pass1.c | 120 ++++++++++++++++++++++++++++++++++++++++--------
gfs2/fsck/pass5.c | 17 ++++---
gfs2/fsck/util.c | 66 --------------------------
gfs2/fsck/util.h | 6 +--
7 files changed, 112 insertions(+), 112 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 4cf4ce1..d57ccfd 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -119,7 +119,7 @@ extern int pass1c(struct gfs2_sbd *sdp);
extern int pass2(struct gfs2_sbd *sdp);
extern int pass3(struct gfs2_sbd *sdp);
extern int pass4(struct gfs2_sbd *sdp);
-extern int pass5(struct gfs2_sbd *sdp);
+extern int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl);
extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
int *sane);
extern int fsck_query(const char *format, ...)
@@ -142,7 +142,6 @@ struct gfs2_options {
extern struct gfs2_options opts;
extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
extern int lf_was_created;
-extern struct gfs2_bmap *bl;
extern uint64_t last_fs_block, last_reported_block;
extern int64_t last_reported_fblock;
extern int skip_this_pass, fsck_abort;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 84d39cd..d54ab0d 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -115,8 +115,6 @@ static void empty_super_block(struct gfs2_sbd *sdp)
log_info( _("Freeing buffers.\n"));
gfs2_rgrp_free(&sdp->rgtree);
- if (bl)
- gfs2_bmap_destroy(sdp, bl);
gfs2_inodetree_free();
gfs2_dirtree_free();
gfs2_dup_free();
@@ -674,7 +672,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
uint64_t inumbuf = 0;
char *buf;
struct gfs2_statfs_change sc;
- uint64_t addl_mem_needed;
int err;
/*******************************************************************
@@ -841,14 +838,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
goto fail;
}
- bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
- if (!bl) {
- log_crit( _("This system doesn't have enough memory and swap space to fsck this file system.\n"));
- log_crit( _("Additional memory needed is approximately: %lluMB\n"),
- (unsigned long long)(addl_mem_needed / 1048576ULL));
- log_crit( _("Please increase your swap space by that amount and run gfs2_fsck again.\n"));
- goto fail;
- }
return 0;
fail:
empty_super_block(sdp);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 2cedb30..91ebe28 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -27,7 +27,6 @@
struct gfs2_options opts = {0};
struct gfs2_inode *lf_dip = NULL; /* Lost and found directory inode */
int lf_was_created = 0;
-struct gfs2_bmap *bl = NULL;
uint64_t last_fs_block, last_reported_block = -1;
int64_t last_reported_fblock = -1000000;
int skip_this_pass = FALSE, fsck_abort = FALSE;
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 876e565..49f6c6e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -30,6 +30,7 @@
#include "fs_recovery.h"
struct special_blocks gfs1_rindex_blks;
+struct gfs2_bmap *bl = NULL;
struct block_count {
uint64_t indir_count;
@@ -88,6 +89,24 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
static int delete_block(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, const char *btype,
void *private);
+
+static int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock, int mark)
+{
+ static unsigned char *byte;
+ static uint64_t b;
+
+ if (!bmap)
+ return 0;
+ if (bblock > bmap->size)
+ return -1;
+
+ byte = bmap->map + BLOCKMAP_SIZE2(bblock);
+ b = BLOCKMAP_BYTE_OFFSET2(bblock);
+ *byte &= ~(BLOCKMAP_MASK2 << b);
+ *byte |= (mark & BLOCKMAP_MASK2) << b;
+ return 0;
+}
+
/*
* _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
* bitmap, and adjust free space accordingly.
@@ -253,7 +272,7 @@ static int p1check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
check in metawalk: gfs2_check_meta(lbh, GFS2_METATYPE_LF).
So we know it's a leaf block. */
bc->indir_count++;
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
log_err( _("Found duplicate block #%llu (0x%llx) referenced "
"as a directory leaf in dinode "
@@ -311,7 +330,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
iblk_type = GFS2_METATYPE_IN;
blktypedesc = _("a journaled data block");
}
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
log_err( _("Found duplicate block #%llu (0x%llx) referenced "
"as metadata in indirect block for dinode "
@@ -502,7 +521,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t metablock,
return -1;
}
bc->data_count++; /* keep the count sane anyway */
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
struct gfs2_buffer_head *bh;
struct gfs2_meta_header mh;
@@ -623,7 +642,7 @@ static int undo_eattr_indir_or_leaf(struct gfs2_inode *ip, uint64_t block,
/* Need to check block_type before undoing the reference, which can
set it to free, which would cause the test below to fail. */
- q = block_type(block);
+ q = block_type(bl, block);
error = undo_reference(ip, block, 0, private);
if (error)
@@ -672,7 +691,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
* in pass1c */
return 1;
}
- q = block_type(indirect);
+ q = block_type(bl, indirect);
/* Special duplicate processing: If we have an EA block,
check if it really is an EA. If it is, let duplicate
@@ -756,7 +775,7 @@ static int check_ealeaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
int q;
struct block_count *bc = (struct block_count *) private;
- q = block_type(block);
+ q = block_type(bl, block);
/* Special duplicate processing: If we have an EA block, check if it
really is an EA. If it is, let duplicate handling sort it out.
If it isn't, clear it but don't count it as a duplicate. */
@@ -1027,7 +1046,7 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
return meta_is_good;
}
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
if (was_duplicate)
*was_duplicate = 1;
@@ -1126,7 +1145,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
return meta_error; /* Exits check_metatree quicker */
}
/* See how many duplicate blocks it has */
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
(*bad_pointers)++;
log_info( _("Duplicated %s block pointer (violation %ld, block"
@@ -1595,7 +1614,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
}
}
if (*sysinode) {
- ds.q = block_type(iblock);
+ ds.q = block_type(bl, iblock);
/* If the inode exists but the block is marked free, we might
be recovering from a corrupt bitmap. In that case, don't
rebuild the inode. Just reuse the inode and fix the
@@ -1858,7 +1877,7 @@ static int pass1_process_bitmap(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, uin
check_magic = ((struct gfs2_meta_header *)
(bh->b_data))->mh_magic;
- q = block_type(block);
+ q = block_type(bl, block);
if (q != GFS2_BLKST_FREE) {
if (be32_to_cpu(check_magic) == GFS2_MAGIC &&
sdp->gfs1 && !is_inode) {
@@ -1971,6 +1990,55 @@ out:
return ret;
}
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
+{
+ bmap->size = size;
+
+ /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
+ * must be 1-based */
+ bmap->mapsize = BLOCKMAP_SIZE2(size) + 1;
+
+ if (!(bmap->map = calloc(bmap->mapsize, sizeof(char))))
+ return -ENOMEM;
+ return 0;
+}
+
+static struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
+{
+ struct gfs2_bmap *il;
+
+ *addl_mem_needed = 0L;
+ il = calloc(1, sizeof(*il));
+ if (!il)
+ return NULL;
+
+ if (gfs2_blockmap_create(il, size)) {
+ *addl_mem_needed = il->mapsize;
+ free(il);
+ il = NULL;
+ }
+ return il;
+}
+
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
+{
+ if (bmap->map)
+ free(bmap->map);
+ bmap->size = 0;
+ bmap->mapsize = 0;
+}
+
+static void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
+{
+ if (il) {
+ gfs2_blockmap_destroy(il);
+ free(il);
+ il = NULL;
+ }
+ return il;
+}
+
/**
* pass1 - walk through inodes and check inode state
*
@@ -1990,9 +2058,18 @@ int pass1(struct gfs2_sbd *sdp)
struct rgrp_tree *rgd;
uint64_t i;
uint64_t rg_count = 0;
- int ret;
struct timeval timer;
-
+ int ret = FSCK_OK;
+ uint64_t addl_mem_needed;
+
+ bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
+ if (!bl) {
+ log_crit( _("This system doesn't have enough memory and swap space to fsck this file system.\n"));
+ log_crit( _("Additional memory needed is approximately: %lluMB\n"),
+ (unsigned long long)(addl_mem_needed / 1048576ULL));
+ log_crit( _("Please increase your swap space by that amount and run gfs2_fsck again.\n"));
+ return FSCK_ERROR;
+ }
osi_list_init(&gfs1_rindex_blks.list);
/* FIXME: In the gfs fsck, we had to mark things like the
@@ -2014,8 +2091,10 @@ int pass1(struct gfs2_sbd *sdp)
* things - we can change the method later if necessary.
*/
for (n = osi_first(&sdp->rgtree); n; n = next, rg_count++) {
- if (fsck_abort)
- return FSCK_CANCELED;
+ if (fsck_abort) {
+ ret = FSCK_CANCELED;
+ goto out;
+ }
next = osi_next(n);
log_debug( _("Checking metadata in Resource Group #%llu\n"),
(unsigned long long)rg_count);
@@ -2028,7 +2107,8 @@ int pass1(struct gfs2_sbd *sdp)
GFS2_BLKST_USED)) {
stack;
gfs2_special_free(&gfs1_rindex_blks);
- return FSCK_ERROR;
+ ret = FSCK_ERROR;
+ goto out;
}
/* rgrps and bitmaps don't have bits to represent
their blocks, so don't do this:
@@ -2038,13 +2118,15 @@ int pass1(struct gfs2_sbd *sdp)
ret = pass1_process_rgrp(sdp, rgd);
if (ret)
- return ret;
-
+ goto out;
}
log_notice(_("Reconciling bitmaps.\n"));
gettimeofday(&timer, NULL);
- pass5(sdp);
+ pass5(sdp, bl);
print_pass_duration("reconcile_bitmaps", &timer);
+out:
gfs2_special_free(&gfs1_rindex_blks);
- return FSCK_OK;
+ if (bl)
+ gfs2_bmap_destroy(sdp, bl);
+ return ret;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 99ff0a1..7d81bfa 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -12,9 +12,10 @@
#include "fsck.h"
#include "util.h"
-static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
- unsigned int buflen, uint64_t *rg_block,
- uint64_t rg_data, uint32_t *count)
+static int check_block_status(struct gfs2_sbd *sdp, struct gfs2_bmap *bl,
+ char *buffer, unsigned int buflen,
+ uint64_t *rg_block, uint64_t rg_data,
+ uint32_t *count)
{
unsigned char *byte, *end;
unsigned int bit;
@@ -34,7 +35,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
- q = block_type(block);
+ q = block_type(bl, block);
/* GFS1 file systems will have to suffer from slower fsck run
* times because in GFS, there's no 1:1 relationship between
* bits and counts. If a bit is marked "dinode" in GFS1, it
@@ -124,7 +125,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
}
static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
- uint32_t *count)
+ struct gfs2_bmap *bl, uint32_t *count)
{
uint32_t i;
struct gfs2_bitmap *bits;
@@ -136,7 +137,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
bits = &rgp->bits[i];
/* update the bitmaps */
- if (check_block_status(sdp, bits->bi_bh->b_data + bits->bi_offset,
+ if (check_block_status(sdp, bl, bits->bi_bh->b_data + bits->bi_offset,
bits->bi_len, &rg_block, rgp->ri.ri_data0, count))
return;
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -209,7 +210,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
* fix free block maps
* fix used inode maps
*/
-int pass5(struct gfs2_sbd *sdp)
+int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl)
{
struct osi_node *n, *next = NULL;
struct rgrp_tree *rgp = NULL;
@@ -227,7 +228,7 @@ int pass5(struct gfs2_sbd *sdp)
rg_count++;
/* Compare the bitmaps and report the differences */
- update_rgrp(sdp, rgp, count);
+ update_rgrp(sdp, rgp, bl, count);
}
/* Fix up superblock info based on this - don't think there's
* anything to do here... */
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index d6d664a..2e77000 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -525,72 +525,6 @@ void dirtree_delete(struct dir_info *b)
free(b);
}
-static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
-{
- bmap->size = size;
-
- /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
- * must be 1-based */
- bmap->mapsize = BLOCKMAP_SIZE2(size) + 1;
-
- if (!(bmap->map = calloc(bmap->mapsize, sizeof(char))))
- return -ENOMEM;
- return 0;
-}
-
-static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
-{
- if (bmap->map)
- free(bmap->map);
- bmap->size = 0;
- bmap->mapsize = 0;
-}
-
-struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
- uint64_t *addl_mem_needed)
-{
- struct gfs2_bmap *il;
-
- *addl_mem_needed = 0L;
- il = calloc(1, sizeof(*il));
- if (!il)
- return NULL;
-
- if (gfs2_blockmap_create(il, size)) {
- *addl_mem_needed = il->mapsize;
- free(il);
- il = NULL;
- }
- return il;
-}
-
-int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock, int mark)
-{
- static unsigned char *byte;
- static uint64_t b;
-
- if (!bmap)
- return 0;
- if (bblock > bmap->size)
- return -1;
-
- byte = bmap->map + BLOCKMAP_SIZE2(bblock);
- b = BLOCKMAP_BYTE_OFFSET2(bblock);
- *byte &= ~(BLOCKMAP_MASK2 << b);
- *byte |= (mark & BLOCKMAP_MASK2) << b;
- return 0;
-}
-
-void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
-{
- if (il) {
- gfs2_blockmap_destroy(il);
- free(il);
- il = NULL;
- }
- return il;
-}
-
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 50a3c8d..aa01552 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -32,7 +32,7 @@ struct fsck_pass {
int (*f)(struct gfs2_sbd *sdp);
};
-static inline int block_type(uint64_t bblock)
+static inline int block_type(struct gfs2_bmap *bl, uint64_t bblock)
{
static unsigned char *byte;
static uint64_t b;
@@ -100,10 +100,6 @@ static inline uint32_t gfs_to_gfs2_mode(struct gfs2_inode *ip)
}
extern enum dup_ref_type get_ref_type(struct inode_with_dups *id);
-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 char generic_interrupt(const char *caller, const char *where,
const char *progress, const char *question,
const char *answers);
8 years
gfs2-utils: master - fsck: make pass1 call bitmap reconciliation AKA
pass5
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=eb83797b...
Commit: eb83797b704666e7baba6fe8e3d61835cc63e096
Parent: 97696af431be9682f16dd0f73d2ace62af77eac6
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Mar 18 09:24:16 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck: make pass1 call bitmap reconciliation AKA pass5
This patch makes pass1 call what used to be pass5. That enables
pass1 to pass its private blockmap in as a private variable.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/main.c | 34 ----------------------------------
gfs2/fsck/pass1.c | 5 +++++
gfs2/fsck/util.c | 29 +++++++++++++++++++++++++++++
gfs2/fsck/util.h | 6 ++++++
4 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 8f2c733..2cedb30 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -229,14 +229,8 @@ static int check_statfs(struct gfs2_sbd *sdp)
return 0;
}
-struct fsck_pass {
- const char *name;
- int (*f)(struct gfs2_sbd *sdp);
-};
-
static const struct fsck_pass passes[] = {
{ .name = "pass1", .f = pass1 },
- { .name = "reconcile_bitmaps", .f = pass5 },
{ .name = "pass1b", .f = pass1b },
{ .name = "pass2", .f = pass2 },
{ .name = "pass3", .f = pass3 },
@@ -245,34 +239,6 @@ static const struct fsck_pass passes[] = {
{ .name = NULL, }
};
-static void print_pass_duration(const char *name, struct timeval *start)
-{
- char duration[17] = ""; /* strlen("XXdXXhXXmXX.XXXs") + 1 */
- struct timeval end, diff;
- unsigned d, h, m, s;
- char *p = duration;
-
- gettimeofday(&end, NULL);
- timersub(&end, start, &diff);
-
- s = diff.tv_sec % 60;
- diff.tv_sec /= 60;
- m = diff.tv_sec % 60;
- diff.tv_sec /= 60;
- h = diff.tv_sec % 24;
- d = diff.tv_sec / 24;
-
- if (d)
- p += snprintf(p, 4, "%ud", d > 99 ? 99U : d);
- if (h)
- p += snprintf(p, 4, "%uh", h);
- if (m)
- p += snprintf(p, 4, "%um", m);
-
- snprintf(p, 8, "%u.%03lus", s, diff.tv_usec / 1000);
- log_notice(_("%s completed in %s\n"), name, duration);
-}
-
static int fsck_pass(const struct fsck_pass *p, struct gfs2_sbd *sdp)
{
int ret;
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ca6f25f..876e565 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1991,6 +1991,7 @@ int pass1(struct gfs2_sbd *sdp)
uint64_t i;
uint64_t rg_count = 0;
int ret;
+ struct timeval timer;
osi_list_init(&gfs1_rindex_blks.list);
@@ -2040,6 +2041,10 @@ int pass1(struct gfs2_sbd *sdp)
return ret;
}
+ log_notice(_("Reconciling bitmaps.\n"));
+ gettimeofday(&timer, NULL);
+ pass5(sdp);
+ print_pass_duration("reconcile_bitmaps", &timer);
gfs2_special_free(&gfs1_rindex_blks);
return FSCK_OK;
}
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 7ca7b91..d6d664a 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -707,3 +707,32 @@ void delete_all_dups(struct gfs2_inode *ip)
}
}
}
+
+void print_pass_duration(const char *name, struct timeval *start)
+{
+ char duration[17] = ""; /* strlen("XXdXXhXXmXX.XXXs") + 1 */
+ struct timeval end, diff;
+ unsigned d, h, m, s;
+ char *p = duration;
+
+ gettimeofday(&end, NULL);
+ timersub(&end, start, &diff);
+
+ s = diff.tv_sec % 60;
+ diff.tv_sec /= 60;
+ m = diff.tv_sec % 60;
+ diff.tv_sec /= 60;
+ h = diff.tv_sec % 24;
+ d = diff.tv_sec / 24;
+
+ if (d)
+ p += snprintf(p, 4, "%ud", d > 99 ? 99U : d);
+ if (h)
+ p += snprintf(p, 4, "%uh", h);
+ if (m)
+ p += snprintf(p, 4, "%um", m);
+
+ snprintf(p, 8, "%u.%03lus", s, diff.tv_usec / 1000);
+ log_notice(_("%s completed in %s\n"), name, duration);
+}
+
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 7753daf..50a3c8d 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -27,6 +27,11 @@ extern const char *reftypes[ref_types + 1];
#define BLOCKMAP_BYTE_OFFSET2(x) ((x & 0x0000000000000003) << 1)
#define BLOCKMAP_MASK2 (0x3)
+struct fsck_pass {
+ const char *name;
+ int (*f)(struct gfs2_sbd *sdp);
+};
+
static inline int block_type(uint64_t bblock)
{
static unsigned char *byte;
@@ -106,6 +111,7 @@ extern char gfs2_getch(void);
extern uint64_t find_free_blk(struct gfs2_sbd *sdp);
extern uint64_t *get_dir_hash(struct gfs2_inode *ip);
extern void delete_all_dups(struct gfs2_inode *ip);
+extern void print_pass_duration(const char *name, struct timeval *start);
#define stack log_debug("<backtrace> - %s()\n", __func__)
8 years
gfs2-utils: master - fsck.gfs2: Move blockmap stuff to pass1.c
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=97696af4...
Commit: 97696af431be9682f16dd0f73d2ace62af77eac6
Parent: f8203271fac38964850c36f7bb8fb363faeb75f9
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Mar 18 08:36:34 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: Move blockmap stuff to pass1.c
Now that we've eliminated all blockmap dependencies from the
other passes, we can move the blockmap-related functions from
metawalk to pass1.c. This will ensure there won't be new calls
added.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/metawalk.c | 16 ----------------
gfs2/fsck/metawalk.h | 8 --------
gfs2/fsck/pass1.c | 21 +++++++++++++++++++++
3 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index ac345f2..3217711 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -177,22 +177,6 @@ int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
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;
-
- return gfs2_blockmap_set(bl, bblock, mark);
-}
-
struct duptree *dupfind(uint64_t block)
{
struct osi_node *node = dup_blocks.osi_node;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index e47a871..813736a 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -19,9 +19,6 @@ extern int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
extern int check_leaf(struct gfs2_inode *ip, int lindex,
struct metawalk_fxns *pass, uint64_t *leaf_no,
struct gfs2_leaf *leaf, int *ref_count);
-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);
@@ -37,11 +34,6 @@ extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
_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) \
- _fsck_blockmap_set(ip, b, bt, m, 1, __FUNCTION__, __LINE__)
-
enum meta_check_rc {
meta_error = -1,
meta_is_good = 0,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index aae5a06..ca6f25f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -88,6 +88,27 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
static int delete_block(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, const char *btype,
void *private);
+/*
+ * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
+ * bitmap, and adjust free space accordingly.
+ */
+static 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;
+
+ return gfs2_blockmap_set(bl, bblock, mark);
+}
+
+#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) \
+ _fsck_blockmap_set(ip, b, bt, m, 1, __FUNCTION__, __LINE__)
+
/**
* delete_block - delete a block associated with an inode
*/
8 years
gfs2-utils: master - fsck.gfs2: eliminate fsck_blockmap_set from
check_eattr_entries
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f8203271...
Commit: f8203271fac38964850c36f7bb8fb363faeb75f9
Parent: b605ea0036696513db3b377f23576c3bbda5e611
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Mar 17 15:36:46 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: eliminate fsck_blockmap_set from check_eattr_entries
Before this patch, metawalk function check_eattr_entries was calling
function fsck_blockmap_set, but only on error conditions.
This patch makes it the caller's responsibility. Since pass1 called
check_eattr_entries, it needed to set the blockmap and bitmap, so
that's now included in the pass1->check_eattr_extentry caller.
Subsequent passes don't need to set the blockmap, but they do need
to set the bitmap. That's also moved to the pass->check_eattr_extentry
but in reality, it's only delete_eattr_extentry that needs to do this.
The only other caller is check_eattr_extentry_refs in pass1b, but
that's a special case in which we don't want to delete the eattrs.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/afterpass1_common.c | 32 ++++++++++++++++++++++++++---
gfs2/fsck/afterpass1_common.h | 4 ++-
gfs2/fsck/metawalk.c | 43 ++++++----------------------------------
gfs2/fsck/metawalk.h | 3 +-
gfs2/fsck/pass1.c | 39 ++++++++++++++++++++++++++++++++----
gfs2/fsck/pass1b.c | 9 +++++++-
6 files changed, 82 insertions(+), 48 deletions(-)
diff --git a/gfs2/fsck/afterpass1_common.c b/gfs2/fsck/afterpass1_common.c
index 36646f8..bdea242 100644
--- a/gfs2/fsck/afterpass1_common.c
+++ b/gfs2/fsck/afterpass1_common.c
@@ -260,13 +260,37 @@ int delete_eattr_entry(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh,
return 0;
}
-int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
- struct gfs2_buffer_head *leaf_bh,
+int delete_eattr_extentry(struct gfs2_inode *ip, int i, uint64_t *ea_data_ptr,
+ struct gfs2_buffer_head *leaf_bh, uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev, void *private)
{
uint64_t block = be64_to_cpu(*ea_data_ptr);
+ int error;
- return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
- NULL, private);
+ error = delete_block_if_notdup(ip, block, NULL,
+ _("extended attribute"), NULL, private);
+ if (error) {
+ log_err(_("Bad extended attribute found at block %lld "
+ "(0x%llx)"),
+ (unsigned long long)be64_to_cpu(*ea_data_ptr),
+ (unsigned long long)be64_to_cpu(*ea_data_ptr));
+ if (query( _("Repair the bad Extended Attribute? (y/n) "))) {
+ ea_hdr->ea_num_ptrs = i;
+ ea_hdr->ea_data_len = cpu_to_be32(tot_ealen);
+ *ea_data_ptr = 0;
+ bmodified(leaf_bh);
+ /* Endianness doesn't matter in this case because it's
+ a single byte. */
+ fsck_bitmap_set(ip, ip->i_di.di_eattr,
+ _("extended attribute"),
+ ip->i_sbd->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
+ log_err( _("The EA was fixed.\n"));
+ } else {
+ error = 1;
+ log_err( _("The bad EA was not fixed.\n"));
+ }
+ }
+ return error;
}
diff --git a/gfs2/fsck/afterpass1_common.h b/gfs2/fsck/afterpass1_common.h
index 2a422c7..8b345ee 100644
--- a/gfs2/fsck/afterpass1_common.h
+++ b/gfs2/fsck/afterpass1_common.h
@@ -19,8 +19,10 @@ extern int delete_eattr_entry(struct gfs2_inode *ip,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
-extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+extern int delete_eattr_extentry(struct gfs2_inode *ip, int i,
+ uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
+ uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 529c86d..ac345f2 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -854,7 +854,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
struct gfs2_ea_header *ea_hdr, *ea_hdr_prev = NULL;
uint64_t *ea_data_ptr = NULL;
int i;
- int error = 0;
+ int error = 0, err;
uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header);
if (!pass->check_eattr_entry)
@@ -891,41 +891,12 @@ static int check_eattr_entries(struct gfs2_inode *ip,
** reuse........... */
for(i = 0; i < ea_hdr->ea_num_ptrs; i++){
- if (pass->check_eattr_extentry(ip,
- ea_data_ptr,
- bh, ea_hdr,
- ea_hdr_prev,
- pass->private)) {
- log_err(_("Bad extended attribute "
- "found at block %lld "
- "(0x%llx)"),
- (unsigned long long)
- be64_to_cpu(*ea_data_ptr),
- (unsigned long long)
- be64_to_cpu(*ea_data_ptr));
- if (query( _("Repair the bad Extended "
- "Attribute? (y/n) "))) {
- ea_hdr->ea_num_ptrs = i;
- ea_hdr->ea_data_len =
- cpu_to_be32(tot_ealen);
- *ea_data_ptr = 0;
- bmodified(bh);
- /* Endianness doesn't matter
- in this case because it's
- a single byte. */
- fsck_blockmap_set(ip,
- ip->i_di.di_eattr,
- _("extended attribute"),
- sdp->gfs1 ? GFS2_BLKST_DINODE :
- GFS2_BLKST_USED);
- log_err( _("The EA was "
- "fixed.\n"));
- } else {
- error = 1;
- log_err( _("The bad EA was "
- "not fixed.\n"));
- }
- }
+ err = pass->check_eattr_extentry(ip, i,
+ ea_data_ptr, bh, tot_ealen,
+ ea_hdr, ea_hdr_prev,
+ pass->private);
+ if (err)
+ error = err;
tot_ealen += sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_meta_header);
ea_data_ptr++;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index d2f0d97..e47a871 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -108,9 +108,10 @@ struct metawalk_fxns {
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
- int (*check_eattr_extentry) (struct gfs2_inode *ip,
+ int (*check_eattr_extentry) (struct gfs2_inode *ip, int i,
uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
+ uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 0ae842e..aae5a06 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -59,8 +59,10 @@ static int check_eattr_entries(struct gfs2_inode *ip,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
-static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
+static int check_extended_leaf_eattr(struct gfs2_inode *ip, int i,
+ uint64_t *data_ptr,
struct gfs2_buffer_head *leaf_bh,
+ uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
@@ -789,8 +791,10 @@ static int check_ealeaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
*
* Returns: 0 if correct[able], -1 if removal is needed
*/
-static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
+static int check_extended_leaf_eattr(struct gfs2_inode *ip, int i,
+ uint64_t *data_ptr,
struct gfs2_buffer_head *leaf_bh,
+ uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private)
@@ -798,7 +802,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
uint64_t el_blk = be64_to_cpu(*data_ptr);
struct gfs2_sbd *sdp = ip->i_sbd;
struct gfs2_buffer_head *bh = NULL;
- int error;
+ int error = 0;
if (!valid_block(sdp, el_blk)) {
log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
@@ -813,11 +817,36 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
fsck_blockmap_set(ip, ip->i_di.di_eattr,
_("bad (out of range) Extended Attribute "),
GFS2_BLKST_UNLINKED);
- return 1;
+ error = 1;
+ } else {
+ error = check_ealeaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh,
+ private);
}
- error = check_ealeaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
if (bh)
brelse(bh);
+ if (error) {
+ log_err(_("Bad extended attribute found at block %lld "
+ "(0x%llx)"),
+ (unsigned long long)be64_to_cpu(*data_ptr),
+ (unsigned long long)be64_to_cpu(*data_ptr));
+ if (query( _("Repair the bad Extended Attribute? (y/n) "))) {
+ ea_hdr->ea_num_ptrs = i;
+ ea_hdr->ea_data_len = cpu_to_be32(tot_ealen);
+ *data_ptr = 0;
+ bmodified(leaf_bh);
+ /* Endianness doesn't matter in this case because it's
+ a single byte. */
+ fsck_blockmap_set(ip, ip->i_di.di_eattr,
+ _("extended attribute"),
+ sdp->gfs1 ? GFS2_BLKST_DINODE :
+ GFS2_BLKST_USED);
+ log_err( _("The EA was fixed.\n"));
+ error = 0;
+ } else {
+ error = 1;
+ log_err( _("The bad EA was not fixed.\n"));
+ }
+ }
return error;
}
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a9632d8..182c6cb 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -831,15 +831,22 @@ static int check_eattr_entry_refs(struct gfs2_inode *ip,
return 0;
}
-static int check_eattr_extentry_refs(struct gfs2_inode *ip,
+static int check_eattr_extentry_refs(struct gfs2_inode *ip, int i,
uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
+ uint32_t tot_ealen,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private)
{
uint64_t block = be64_to_cpu(*ea_data_ptr);
+ /* This is a case where a bad return code may be sent back, and
+ behavior has changed. Before, if add_duplicate_ref returned a
+ non-zero return code, the caller would delete the eattr from
+ the blockmap. In this case, we should be okay because the only
+ error possible is a malloc that fails, in which case we don't
+ want to delete the eattr anyway. */
return add_duplicate_ref(ip, block, ref_as_ea, 1, INODE_VALID);
}
8 years
gfs2-utils: master - fsck.gfs2: Divest check_metatree from
fsck_blockmap_set
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=b605ea00...
Commit: b605ea0036696513db3b377f23576c3bbda5e611
Parent: 7b8d1b6e050cec8634dc23136beebdbef8e18bf4
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Mar 17 14:50:48 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:50:12 2016 -0500
fsck.gfs2: Divest check_metatree from fsck_blockmap_set
This patch replaces the call to function fsck_blockmap_set in
function check_metatree (which is used in all passes) to a
corresponding call to fsck_bitmap_set. This is another step to
having pass1 be the only function to manipulate the blockmap.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/metawalk.c | 4 ++--
gfs2/fsck/pass1.c | 7 ++++++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 1f2bc10..529c86d 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1604,8 +1604,8 @@ undo_metalist:
to undo. */
delete_all_dups(ip);
/* Set the dinode as "bad" so it gets deleted */
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("corrupt"), GFS2_BLKST_FREE);
+ fsck_bitmap_set(ip, ip->i_di.di_num.no_addr, _("corrupt"),
+ GFS2_BLKST_FREE);
log_err(_("The corrupt inode was invalidated.\n"));
out:
free_metalist(ip, &metalist[0]);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index fbacfea..0ae842e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1304,9 +1304,14 @@ static void reprocess_inode(struct gfs2_inode *ip, const char *desc)
(unsigned long long)ip->i_di.di_num.no_addr,
ip->i_di.di_height);
error = check_metatree(ip, &alloc_fxns);
- if (error)
+ if (error) {
+ /* check_metatree will have fixed the bitmap, but not the
+ blockmap. */
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ GFS2_BLKST_FREE);
log_err( _("Error %d reprocessing the %s metadata tree.\n"),
error, desc);
+ }
}
/*
8 years
gfs2-utils: master - fsck.gfs2: Separate out functions that may only
be done after pass1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=7b8d1b6e...
Commit: 7b8d1b6e050cec8634dc23136beebdbef8e18bf4
Parent: c201ff82ff58a1e04212badce010e00bd1def140
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Mar 15 16:10:54 2016 -0400
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon May 9 10:49:43 2016 -0500
fsck.gfs2: Separate out functions that may only be done after pass1
This patch adds a new header file and source file which has the
purpose of separating out the functions that may only be called
after pass1 from the functions that pass1 may call. This is to
ensure that there will never be inconsistencies between blockmap
(which pass1 uses) and bitmap (which subsequent passes use).
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/fsck/Makefile.am | 2 +
gfs2/fsck/afterpass1_common.c | 272 +++++++++++++++++++++++++++++++++++++++++
gfs2/fsck/afterpass1_common.h | 31 +++++
gfs2/fsck/metawalk.c | 272 +----------------------------------------
gfs2/fsck/metawalk.h | 32 +-----
gfs2/fsck/pass1.c | 22 ++++
gfs2/fsck/pass1b.c | 1 +
gfs2/fsck/pass2.c | 1 +
gfs2/fsck/pass3.c | 1 +
gfs2/fsck/pass4.c | 1 +
10 files changed, 336 insertions(+), 299 deletions(-)
diff --git a/gfs2/fsck/Makefile.am b/gfs2/fsck/Makefile.am
index 73d957e..4c3498b 100644
--- a/gfs2/fsck/Makefile.am
+++ b/gfs2/fsck/Makefile.am
@@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in
sbin_PROGRAMS = fsck.gfs2
noinst_HEADERS = \
+ afterpass1_common.h \
fsck.h \
fs_recovery.h \
inode_hash.h \
@@ -19,6 +20,7 @@ fsck_gfs2_SOURCES = \
lost_n_found.c \
main.c \
metawalk.c \
+ afterpass1_common.c \
pass1b.c \
pass1.c \
pass2.c \
diff --git a/gfs2/fsck/afterpass1_common.c b/gfs2/fsck/afterpass1_common.c
new file mode 100644
index 0000000..36646f8
--- /dev/null
+++ b/gfs2/fsck/afterpass1_common.c
@@ -0,0 +1,272 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <ctype.h>
+#include <fcntl.h>
+#define _(String) gettext(String)
+
+#include <logging.h>
+#include "libgfs2.h"
+#include "fsck.h"
+#include "afterpass1_common.h"
+#include "metawalk.h"
+#include "util.h"
+
+/**
+ * find_remove_dup - find out if this is a duplicate ref. If so, remove it.
+ *
+ * Returns: 1 if there are any remaining references to this block, else 0.
+ */
+int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
+{
+ struct duptree *dt;
+ struct inode_with_dups *id;
+
+ dt = dupfind(block);
+ if (!dt)
+ return 0;
+
+ /* remove the inode reference id structure for this reference. */
+ id = find_dup_ref_inode(dt, ip);
+ if (!id)
+ goto more_refs;
+
+ dup_listent_delete(dt, id);
+ if (dt->refs == 0) {
+ log_info( _("This was the last reference: it's no longer a "
+ "duplicate.\n"));
+ dup_delete(dt); /* not duplicate now */
+ return 0;
+ }
+more_refs:
+ log_info( _("%d block reference(s) remain.\n"), dt->refs);
+ return 1; /* references still exist so do not free the block. */
+}
+
+/**
+ * delete_block_if_notdup - delete blocks associated with an inode
+ *
+ * Ignore blocks that are already marked free.
+ * If it has been identified as duplicate, remove the duplicate reference.
+ * If all duplicate references have been removed, delete the block.
+ */
+static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh,
+ const char *btype, int *was_duplicate,
+ void *private)
+{
+ int q;
+
+ if (!valid_block(ip->i_sbd, block))
+ return meta_error;
+
+ 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"),
+ btype, (unsigned long long)block,
+ (unsigned long long)block,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ return meta_is_good;
+ }
+ if (find_remove_dup(ip, block, btype)) { /* a dup */
+ if (was_duplicate)
+ *was_duplicate = 1;
+ log_err( _("Not clearing duplicate reference in inode "
+ "at block #%llu (0x%llx) to block #%llu (0x%llx) "
+ "because it's referenced by another inode.\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)block, (unsigned long long)block);
+ } else {
+ check_n_fix_bitmap(ip->i_sbd, block, 0, GFS2_BLKST_FREE);
+ }
+ return meta_is_good;
+}
+
+static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
+ struct gfs2_dirent *prev_de,
+ struct gfs2_buffer_head *bh,
+ char *filename, uint32_t *count, int *lindex,
+ void *private)
+{
+ /* the metawalk_fxn's private field must be set to the dentry
+ * block we want to clear */
+ uint64_t *dentryblock = (uint64_t *) private;
+ struct gfs2_dirent dentry, *de;
+
+ memset(&dentry, 0, sizeof(struct gfs2_dirent));
+ gfs2_dirent_in(&dentry, (char *)dent);
+ de = &dentry;
+
+ if (de->de_inum.no_addr == *dentryblock)
+ dirent2_del(ip, bh, prev_de, dent);
+ else
+ (*count)++;
+
+ return 0;
+
+}
+
+int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
+ uint64_t dentryblock)
+{
+ struct metawalk_fxns remove_dentry_fxns = {0};
+ struct gfs2_inode *ip;
+ int q;
+ int error;
+
+ log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
+ " (0x%llx)\n"), (unsigned long long)dentryblock,
+ (unsigned long long)dentryblock,
+ (unsigned long long)dir, (unsigned long long)dir);
+ if (!valid_block(sdp, dir)) {
+ log_err( _("Parent directory is invalid\n"));
+ return 1;
+ }
+ remove_dentry_fxns.private = &dentryblock;
+ remove_dentry_fxns.check_dentry = remove_dentry;
+
+ q = bitmap_type(sdp, dir);
+ if (q != GFS2_BLKST_DINODE) {
+ log_info( _("Parent block is not an inode...ignoring\n"));
+ return 1;
+ }
+
+ ip = fsck_load_inode(sdp, dir);
+ if (ip == NULL) {
+ stack;
+ return -1;
+ }
+ /* Need to run check_dir with a private var of dentryblock,
+ * and fxns that remove that dentry if found */
+ error = check_dir(sdp, ip, &remove_dentry_fxns);
+ fsck_inode_put(&ip);
+ return error;
+}
+
+int delete_metadata(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, int h, int *is_valid,
+ int *was_duplicate, void *private)
+{
+ *is_valid = 1;
+ *was_duplicate = 0;
+ return delete_block_if_notdup(ip, block, bh, _("metadata"),
+ was_duplicate, private);
+}
+
+int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+{
+ return delete_block_if_notdup(ip, block, NULL, _("leaf"), NULL,
+ private);
+}
+
+int delete_data(struct gfs2_inode *ip, uint64_t metablock,
+ uint64_t block, void *private, struct gfs2_buffer_head *bh,
+ uint64_t *ptr)
+{
+ return delete_block_if_notdup(ip, block, NULL, _("data"), NULL,
+ private);
+}
+
+static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
+ uint64_t parent, struct gfs2_buffer_head **bh,
+ void *private, const char *eatype)
+{
+ int ret = 0;
+ int was_free = 0;
+ int q;
+
+ if (valid_block(ip->i_sbd, 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,
+ NULL, private);
+ if (!ret) {
+ *bh = bread(ip->i_sbd, block);
+ if (!was_free)
+ ip->i_di.di_blocks--;
+ bmodified(ip->i_bh);
+ }
+ }
+ /* Even if it's a duplicate reference, we want to eliminate the
+ reference itself, and adjust di_blocks accordingly. */
+ if (ip->i_di.di_eattr) {
+ if (block == ip->i_di.di_eattr)
+ ip->i_di.di_eattr = 0;
+ bmodified(ip->i_bh);
+ }
+ return ret;
+}
+
+int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+ struct gfs2_buffer_head **bh, void *private)
+{
+ return del_eattr_generic(ip, block, parent, bh, private,
+ _("extended attribute"));
+}
+
+int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+ struct gfs2_buffer_head **bh, void *private)
+{
+ return del_eattr_generic(ip, block, parent, bh, private,
+ _("indirect extended attribute"));
+}
+
+int delete_eattr_entry(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev, void *private)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ char ea_name[256];
+ uint32_t avail_size;
+ int max_ptrs;
+
+ if (!ea_hdr->ea_name_len){
+ /* Skip this entry for now */
+ return 1;
+ }
+
+ memset(ea_name, 0, sizeof(ea_name));
+ strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
+ ea_hdr->ea_name_len);
+
+ if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+ ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
+ /* Skip invalid entry */
+ return 1;
+ }
+
+ if (!ea_hdr->ea_num_ptrs)
+ return 0;
+
+ avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+ max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
+ avail_size;
+
+ if (max_ptrs > ea_hdr->ea_num_ptrs)
+ return 1;
+
+ log_debug( _(" Pointers Required: %d\n Pointers Reported: %d\n"),
+ max_ptrs, ea_hdr->ea_num_ptrs);
+
+ return 0;
+}
+
+int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+ struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev, void *private)
+{
+ uint64_t block = be64_to_cpu(*ea_data_ptr);
+
+ return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
+ NULL, private);
+}
diff --git a/gfs2/fsck/afterpass1_common.h b/gfs2/fsck/afterpass1_common.h
new file mode 100644
index 0000000..2a422c7
--- /dev/null
+++ b/gfs2/fsck/afterpass1_common.h
@@ -0,0 +1,31 @@
+#ifndef _AFTERPASS1_H
+#define _AFTERPASS1_H
+
+#include "util.h"
+
+extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, int h, int *is_valid,
+ int *was_duplicate, void *private);
+extern int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
+extern int delete_data(struct gfs2_inode *ip, uint64_t metablock,
+ uint64_t block, void *private,
+ struct gfs2_buffer_head *bh, uint64_t *ptr);
+extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+ struct gfs2_buffer_head **bh, void *private);
+extern int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
+ struct gfs2_buffer_head **bh, void *private);
+extern int delete_eattr_entry(struct gfs2_inode *ip,
+ struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev,
+ void *private);
+extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+ struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev,
+ void *private);
+extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype);
+extern int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
+ uint64_t dentryblock);
+#endif
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 7a77dc9..1f2bc10 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -989,93 +989,6 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
}
/**
- * delete_block - delete a block associated with an inode
- */
-int delete_block(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, const char *btype,
- void *private)
-{
- if (valid_block(ip->i_sbd, block)) {
- fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
- return 0;
- }
- return -1;
-}
-
-/**
- * find_remove_dup - find out if this is a duplicate ref. If so, remove it.
- *
- * Returns: 1 if there are any remaining references to this block, else 0.
- */
-int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
-{
- struct duptree *dt;
- struct inode_with_dups *id;
-
- dt = dupfind(block);
- if (!dt)
- return 0;
-
- /* remove the inode reference id structure for this reference. */
- id = find_dup_ref_inode(dt, ip);
- if (!id)
- goto more_refs;
-
- dup_listent_delete(dt, id);
- if (dt->refs == 0) {
- log_info( _("This was the last reference: it's no longer a "
- "duplicate.\n"));
- dup_delete(dt); /* not duplicate now */
- return 0;
- }
-more_refs:
- log_info( _("%d block reference(s) remain.\n"), dt->refs);
- return 1; /* references still exist so do not free the block. */
-}
-
-/**
- * delete_block_if_notdup - delete blocks associated with an inode
- *
- * Ignore blocks that are already marked free.
- * If it has been identified as duplicate, remove the duplicate reference.
- * If all duplicate references have been removed, delete the block.
- */
-static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh,
- const char *btype, int *was_duplicate,
- void *private)
-{
- int q;
-
- if (!valid_block(ip->i_sbd, block))
- return meta_error;
-
- 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"),
- btype, (unsigned long long)block,
- (unsigned long long)block,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- return meta_is_good;
- }
- if (find_remove_dup(ip, block, btype)) { /* a dup */
- if (was_duplicate)
- *was_duplicate = 1;
- log_err( _("Not clearing duplicate reference in inode "
- "at block #%llu (0x%llx) to block #%llu (0x%llx) "
- "because it's referenced by another inode.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)block, (unsigned long long)block);
- } else {
- fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
- }
- return meta_is_good;
-}
-
-/**
* check_indirect_eattr
* @ip: the inode the eattr comes from
* @indirect_block
@@ -1159,9 +1072,9 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
leaf_pointer_errors,
pass->private);
}
- if (leaf_pointer_errors &&
+ if (pass->delete_block && leaf_pointer_errors &&
leaf_pointer_errors == leaf_pointers) {
- delete_block(ip, indirect, NULL, "leaf", NULL);
+ pass->delete_block(ip, indirect, NULL, "leaf", NULL);
error = 1;
}
}
@@ -1729,184 +1642,3 @@ int check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip, struct metawalk_fxns
return error;
}
-
-static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
- struct gfs2_dirent *prev_de,
- struct gfs2_buffer_head *bh,
- char *filename, uint32_t *count, int *lindex,
- void *private)
-{
- /* the metawalk_fxn's private field must be set to the dentry
- * block we want to clear */
- uint64_t *dentryblock = (uint64_t *) private;
- struct gfs2_dirent dentry, *de;
-
- memset(&dentry, 0, sizeof(struct gfs2_dirent));
- gfs2_dirent_in(&dentry, (char *)dent);
- de = &dentry;
-
- if (de->de_inum.no_addr == *dentryblock)
- dirent2_del(ip, bh, prev_de, dent);
- else
- (*count)++;
-
- return 0;
-
-}
-
-int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
- uint64_t dentryblock)
-{
- struct metawalk_fxns remove_dentry_fxns = {0};
- struct gfs2_inode *ip;
- int q;
- int error;
-
- log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
- " (0x%llx)\n"), (unsigned long long)dentryblock,
- (unsigned long long)dentryblock,
- (unsigned long long)dir, (unsigned long long)dir);
- if (!valid_block(sdp, dir)) {
- log_err( _("Parent directory is invalid\n"));
- return 1;
- }
- remove_dentry_fxns.private = &dentryblock;
- remove_dentry_fxns.check_dentry = remove_dentry;
-
- q = bitmap_type(sdp, dir);
- if (q != GFS2_BLKST_DINODE) {
- log_info( _("Parent block is not an inode...ignoring\n"));
- return 1;
- }
-
- ip = fsck_load_inode(sdp, dir);
- if (ip == NULL) {
- stack;
- return -1;
- }
- /* Need to run check_dir with a private var of dentryblock,
- * and fxns that remove that dentry if found */
- error = check_dir(sdp, ip, &remove_dentry_fxns);
- fsck_inode_put(&ip);
- return error;
-}
-
-int delete_metadata(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, int h, int *is_valid,
- int *was_duplicate, void *private)
-{
- *is_valid = 1;
- *was_duplicate = 0;
- return delete_block_if_notdup(ip, block, bh, _("metadata"),
- was_duplicate, private);
-}
-
-int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
-{
- return delete_block_if_notdup(ip, block, NULL, _("leaf"), NULL,
- private);
-}
-
-int delete_data(struct gfs2_inode *ip, uint64_t metablock,
- uint64_t block, void *private, struct gfs2_buffer_head *bh,
- uint64_t *ptr)
-{
- return delete_block_if_notdup(ip, block, NULL, _("data"), NULL,
- private);
-}
-
-static int del_eattr_generic(struct gfs2_inode *ip, uint64_t block,
- uint64_t parent, struct gfs2_buffer_head **bh,
- void *private, const char *eatype)
-{
- int ret = 0;
- int was_free = 0;
- int q;
-
- if (valid_block(ip->i_sbd, 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,
- NULL, private);
- if (!ret) {
- *bh = bread(ip->i_sbd, block);
- if (!was_free)
- ip->i_di.di_blocks--;
- bmodified(ip->i_bh);
- }
- }
- /* Even if it's a duplicate reference, we want to eliminate the
- reference itself, and adjust di_blocks accordingly. */
- if (ip->i_di.di_eattr) {
- if (block == ip->i_di.di_eattr)
- ip->i_di.di_eattr = 0;
- bmodified(ip->i_bh);
- }
- return ret;
-}
-
-int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh, void *private)
-{
- return del_eattr_generic(ip, block, parent, bh, private,
- _("extended attribute"));
-}
-
-int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh, void *private)
-{
- return del_eattr_generic(ip, block, parent, bh, private,
- _("indirect extended attribute"));
-}
-
-int delete_eattr_entry(struct gfs2_inode *ip, struct gfs2_buffer_head *leaf_bh,
- struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev, void *private)
-{
- struct gfs2_sbd *sdp = ip->i_sbd;
- char ea_name[256];
- uint32_t avail_size;
- int max_ptrs;
-
- if (!ea_hdr->ea_name_len){
- /* Skip this entry for now */
- return 1;
- }
-
- memset(ea_name, 0, sizeof(ea_name));
- strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
- ea_hdr->ea_name_len);
-
- if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
- ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
- /* Skip invalid entry */
- return 1;
- }
-
- if (!ea_hdr->ea_num_ptrs)
- return 0;
-
- avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
- max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
- avail_size;
-
- if (max_ptrs > ea_hdr->ea_num_ptrs)
- return 1;
-
- log_debug( _(" Pointers Required: %d\n Pointers Reported: %d\n"),
- max_ptrs, ea_hdr->ea_num_ptrs);
-
- return 0;
-}
-
-int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
- struct gfs2_buffer_head *leaf_bh,
- struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev, void *private)
-{
- uint64_t block = be64_to_cpu(*ea_data_ptr);
-
- return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
- NULL, private);
-}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index d505945..d2f0d97 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -19,33 +19,6 @@ extern int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
extern int check_leaf(struct gfs2_inode *ip, int lindex,
struct metawalk_fxns *pass, uint64_t *leaf_no,
struct gfs2_leaf *leaf, int *ref_count);
-extern int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
- uint64_t dentryblock);
-extern int delete_block(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, const char *btype,
- void *private);
-extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, int h, int *is_valid,
- int *was_duplicate, void *private);
-extern int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
-extern int delete_data(struct gfs2_inode *ip, uint64_t metablock,
- uint64_t block, void *private,
- struct gfs2_buffer_head *bh, uint64_t *ptr);
-extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh, void *private);
-extern int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh, void *private);
-extern int delete_eattr_entry(struct gfs2_inode *ip,
- struct gfs2_buffer_head *leaf_bh,
- struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev,
- void *private);
-extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
- struct gfs2_buffer_head *leaf_bh,
- struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev,
- void *private);
-
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);
@@ -57,8 +30,6 @@ extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
extern struct duptree *dupfind(uint64_t block);
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);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
@@ -154,6 +125,9 @@ struct metawalk_fxns {
int h, void *private);
int (*undo_check_data) (struct gfs2_inode *ip, uint64_t block,
void *private);
+ int (*delete_block) (struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, const char *btype,
+ void *private);
};
#endif /* _METAWALK_H */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index d12e03e..fbacfea 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -83,6 +83,22 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private);
static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
+static int delete_block(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, const char *btype,
+ void *private);
+/**
+ * delete_block - delete a block associated with an inode
+ */
+static int delete_block(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, const char *btype,
+ void *private)
+{
+ if (valid_block(ip->i_sbd, block)) {
+ fsck_blockmap_set(ip, block, btype, GFS2_BLKST_FREE);
+ return 0;
+ }
+ return -1;
+}
struct metawalk_fxns pass1_fxns = {
.private = NULL,
@@ -97,6 +113,7 @@ struct metawalk_fxns pass1_fxns = {
.big_file_msg = big_file_comfort,
.undo_check_meta = undo_check_metalist,
.undo_check_data = undo_check_data,
+ .delete_block = delete_block,
};
struct metawalk_fxns invalidate_fxns = {
@@ -106,6 +123,7 @@ struct metawalk_fxns invalidate_fxns = {
.check_leaf = invalidate_leaf,
.check_eattr_indir = invalidate_eattr_indir,
.check_eattr_leaf = invalidate_eattr_leaf,
+ .delete_block = delete_block,
};
/*
@@ -200,6 +218,7 @@ struct metawalk_fxns sysdir_fxns = {
.private = NULL,
.check_metalist = resuscitate_metalist,
.check_dentry = resuscitate_dentry,
+ .delete_block = delete_block,
};
static int p1check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
@@ -1124,6 +1143,7 @@ struct metawalk_fxns rangecheck_fxns = {
.check_leaf = rangecheck_leaf,
.check_eattr_indir = rangecheck_eattr_indir,
.check_eattr_leaf = rangecheck_eattr_leaf,
+ .delete_block = delete_block,
};
struct metawalk_fxns eattr_undo_fxns = {
@@ -1131,6 +1151,7 @@ struct metawalk_fxns eattr_undo_fxns = {
.check_eattr_indir = undo_eattr_indir_or_leaf,
.check_eattr_leaf = undo_eattr_indir_or_leaf,
.finish_eattr_indir = finish_eattr_indir,
+ .delete_block = delete_block,
};
/* set_ip_blockmap - set the blockmap for a dinode
*
@@ -1252,6 +1273,7 @@ struct metawalk_fxns alloc_fxns = {
.check_eattr_entry = NULL,
.check_eattr_extentry = NULL,
.finish_eattr_indir = NULL,
+ .delete_block = delete_block,
};
/*
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 20b603c..a9632d8 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -15,6 +15,7 @@
#include "util.h"
#include "metawalk.h"
#include "inode_hash.h"
+#include "afterpass1_common.h"
struct fxn_info {
uint64_t block;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index a215b3c..02d82e4 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -17,6 +17,7 @@
#include "link.h"
#include "lost_n_found.h"
#include "inode_hash.h"
+#include "afterpass1_common.h"
#define MAX_FILENAME 256
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 0df427d..d5f4ea2 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -16,6 +16,7 @@
#include "link.h"
#include "metawalk.h"
#include "util.h"
+#include "afterpass1_common.h"
static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
uint64_t olddotdot, uint64_t block)
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index ba38e8c..0d6cc9d 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -13,6 +13,7 @@
#include "inode_hash.h"
#include "metawalk.h"
#include "util.h"
+#include "afterpass1_common.h"
struct metawalk_fxns pass4_fxns_delete = {
.private = NULL,
8 years