From: Bob Peterson <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [fsck.gfs2 PATCH] fsck.gfs2: soften the messages when reclaiming freemeta blocks
Date: Mon, 17 Sep 2012 16:25:32 -0400 (EDT) [thread overview]
Message-ID: <635645238.862993.1347913532139.JavaMail.root@redhat.com> (raw)
In-Reply-To: <1340672328.853136.1347913179774.JavaMail.root@redhat.com>
Hi,
Here is a patch to fsck.gfs2 that may hopefully make the reclaiming
of "free metadata blocks" seem less like an error.
Before the patch, fsck.gfs2 would reclaim "free metadata" blocks,
turning them all into truly "free" blocks, but then it would see
the discrepancy between the free space numbers in the rgrp and
complain bitterly. It gave users the impression that there was
a file system error when, in fact, there was none. The patch also
reports on how many rgrps were "cleaned" and reports on how many
blocks may need to be fixed in the gfs2 bitmap.
Regards,
Bob Peterson
Red Hat File Systems
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
gfs2/fsck/initialize.c | 120 ++++++++++++++++++++++++++++++++++++-----------
1 files changed, 92 insertions(+), 28 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 558fd03..a288ed2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -30,6 +30,7 @@
static int was_mounted_ro = 0;
static uint64_t possible_root = HIGHEST_BLOCK;
static struct master_dir fix_md;
+static unsigned long long blks_2free = 0;
/**
* block_mounters
@@ -189,18 +190,21 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
*/
static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
int *fixit, int *this_rg_fixed,
- int *this_rg_bad)
+ int *this_rg_bad, int *this_rg_cleaned)
{
uint32_t rg_free, rg_reclaimed, rg_unlinked;
int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0;
unsigned int state;
struct gfs_rgrp *gfs1rg = (struct gfs_rgrp *)&rgd->rg;
+ uint64_t diblock;
+ struct gfs2_buffer_head *bh;
rg_free = rg_reclaimed = rg_unlinked = 0;
total_bytes_to_check = rgd->ri.ri_bitbytes;
- *this_rg_fixed = *this_rg_bad = 0;
+ *this_rg_fixed = *this_rg_bad = *this_rg_cleaned = 0;
+ diblock = rgd->ri.ri_data0;
for (rgb = 0; rgb < rgd->ri.ri_length; rgb++){
/* Count up the free blocks in the bitmap */
off = (rgb) ? sizeof(struct gfs2_meta_header) :
@@ -214,32 +218,47 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
unsigned char *byte;
byte = (unsigned char *)&rgd->bh[rgb]->b_data[off + x];
- if (*byte == 0x55)
+ if (*byte == 0x55) {
+ diblock += GFS2_NBBY;
continue;
+ }
if (*byte == 0x00) {
+ diblock += GFS2_NBBY;
rg_free += GFS2_NBBY;
continue;
}
for (y = 0; y < GFS2_NBBY; y++) {
state = (*byte >>
(GFS2_BIT_SIZE * y)) & GFS2_BIT_MASK;
- if (state == GFS2_BLKST_USED)
+ if (state == GFS2_BLKST_USED) {
+ diblock++;
continue;
- if (state == GFS2_BLKST_DINODE)
+ }
+ if (state == GFS2_BLKST_DINODE) {
+ diblock++;
continue;
+ }
if (state == GFS2_BLKST_FREE) {
+ diblock++;
rg_free++;
continue;
}
/* GFS2_BLKST_UNLINKED */
- *this_rg_bad = 1;
+ if (sdp->gfs1)
+ log_info(_("Free metadata block 0x%llx"
+ " found.\n"),
+ (unsigned long long)diblock);
+ else
+ log_info(_("Unlinked dinode 0x%llx "
+ "found.\n"),
+ (unsigned long long)diblock);
if (!asked) {
char msg[256];
asked = 1;
sprintf(msg,
- _("Okay to reclaim unlinked "
- "inodes in resource group "
+ _("Okay to reclaim free "
+ "metadata in resource group "
"%lld (0x%llx)? (y/n)"),
(unsigned long long)rgd->ri.ri_addr,
(unsigned long long)rgd->ri.ri_addr);
@@ -248,6 +267,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
}
if (!(*fixit)) {
rg_unlinked++;
+ diblock++;
continue;
}
*byte &= ~(GFS2_BIT_MASK <<
@@ -255,20 +275,58 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
bmodified(rgd->bh[rgb]);
rg_reclaimed++;
rg_free++;
- *this_rg_fixed = 1;
+ rgd->rg.rg_free++;
+ if (sdp->gfs1 && gfs1rg->rg_freemeta)
+ gfs1rg->rg_freemeta--;
+ log_info(_("Free metadata block %lld (0x%llx) "
+ "reclaimed.\n"),
+ (unsigned long long)diblock,
+ (unsigned long long)diblock);
+ bh = bread(sdp, diblock);
+ if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ struct gfs2_inode *ip =
+ fsck_inode_get(sdp, bh);
+ if (ip->i_di.di_blocks > 1) {
+ blks_2free +=
+ ip->i_di.di_blocks - 1;
+ log_info(_("%lld blocks "
+ "(total) may need "
+ "to be freed in "
+ "pass 5.\n"),
+ blks_2free);
+ }
+ fsck_inode_put(&ip);
+ }
+ brelse(bh);
+ diblock++;
}
}
}
+ /* The unlinked blocks we reclaim shouldn't be considered errors,
+ since we're just reclaiming them as a courtesy. If we already
+ got permission to reclaim them, we adjust the rgrp counts
+ accordingly. That way, only "real" rgrp count inconsistencies
+ will be reported. */
+ if (rg_reclaimed && *fixit) {
+ if (sdp->gfs1)
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ else
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+ *this_rg_cleaned = 1;
+ log_info( _("The rgrp at %lld (0x%llx) was cleaned of %d "
+ "free metadata blocks.\n"),
+ (unsigned long long)rgd->ri.ri_addr,
+ (unsigned long long)rgd->ri.ri_addr,
+ rg_reclaimed);
+ }
if (rgd->rg.rg_free != rg_free) {
*this_rg_bad = 1;
+ *this_rg_cleaned = 0;
log_err( _("Error: resource group %lld (0x%llx): "
"free space (%d) does not match bitmap (%d)\n"),
(unsigned long long)rgd->ri.ri_addr,
(unsigned long long)rgd->ri.ri_addr,
rgd->rg.rg_free, rg_free);
- if (rg_reclaimed)
- log_err( _("(%d blocks were reclaimed)\n"),
- rg_reclaimed);
if (query( _("Fix the rgrp free blocks count? (y/n)"))) {
rgd->rg.rg_free = rg_free;
if (sdp->gfs1)
@@ -283,14 +341,12 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
}
if (sdp->gfs1 && gfs1rg->rg_freemeta != rg_unlinked) {
*this_rg_bad = 1;
+ *this_rg_cleaned = 0;
log_err( _("Error: resource group %lld (0x%llx): "
"free meta (%d) does not match bitmap (%d)\n"),
(unsigned long long)rgd->ri.ri_addr,
(unsigned long long)rgd->ri.ri_addr,
gfs1rg->rg_freemeta, rg_unlinked);
- if (rg_reclaimed)
- log_err( _("(%d blocks were reclaimed)\n"),
- rg_reclaimed);
if (query( _("Fix the rgrp free meta blocks count? (y/n)"))) {
gfs1rg->rg_freemeta = rg_unlinked;
gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
@@ -311,14 +367,16 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
/**
* check_rgrps_integrity - verify rgrp consistency
+ * Note: We consider an rgrp "cleaned" if the unlinked meta blocks are
+ * cleaned, so not quite "bad" and not quite "good" but rewritten anyway.
*
* Returns: 0 on success, 1 if errors were detected
*/
-static int check_rgrps_integrity(struct gfs2_sbd *sdp)
+static void check_rgrps_integrity(struct gfs2_sbd *sdp)
{
struct osi_node *n, *next = NULL;
- int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0;
- int was_bad = 0, was_fixed = 0, error = 0;
+ int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0, rgs_cleaned = 0;
+ int was_bad = 0, was_fixed = 0, was_cleaned = 0;
struct rgrp_tree *rgd;
int reclaim_unlinked = 0;
@@ -327,22 +385,28 @@ static int check_rgrps_integrity(struct gfs2_sbd *sdp)
next = osi_next(n);
rgd = (struct rgrp_tree *)n;
if (fsck_abort)
- return 0;
+ return;
check_rgrp_integrity(sdp, rgd, &reclaim_unlinked,
- &was_fixed, &was_bad);
+ &was_fixed, &was_bad, &was_cleaned);
if (was_fixed)
rgs_fixed++;
- if (was_bad) {
- error = 1;
+ if (was_cleaned)
+ rgs_cleaned++;
+ else if (was_bad)
rgs_bad++;
- } else
+ else
rgs_good++;
}
- if (rgs_bad)
- log_err( _("RGs: Consistent: %d Inconsistent: %d Fixed: %d"
- " Total: %d\n"),
- rgs_good, rgs_bad, rgs_fixed, rgs_good + rgs_bad);
- return error;
+ if (rgs_bad || rgs_cleaned) {
+ log_err( _("RGs: Consistent: %d Cleaned: %d Inconsistent: "
+ "%d Fixed: %d Total: %d\n"),
+ rgs_good, rgs_cleaned, rgs_bad, rgs_fixed,
+ rgs_good + rgs_bad + rgs_cleaned);
+ if (rgs_cleaned && blks_2free)
+ log_err(_("%lld blocks may need to be freed in pass 5 "
+ "due to the cleaned resource groups.\n"),
+ blks_2free);
+ }
}
/**
parent reply other threads:[~2012-09-17 20:25 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <1340672328.853136.1347913179774.JavaMail.root@redhat.com>]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=635645238.862993.1347913532139.JavaMail.root@redhat.com \
--to=rpeterso@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).