[Cluster-devel] [fsck.gfs2 PATCH 17/30] fsck.gfs2: make blockmap global variable only to pass1
Bob Peterson
rpeterso at redhat.com
Fri Apr 15 13:38:11 UTC 2016
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 at 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);
--
2.5.5
More information about the Cluster-devel
mailing list