cluster: STABLE3 - Simplify bitmap/block list structures
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c779e31178fa82f5b7d2e7f80e871dadfac0bb1b
Parent: c7f8a0e194283bdd54d180cceda3377561ab0787
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:34:08 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:26 2010 -0600
Simplify bitmap/block list structures
This patch eliminates structures within structures to simplify the
code and improve performance.
rhbz#455300
---
gfs2/edit/savemeta.c | 8 ++++----
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/initialize.c | 4 ++--
gfs2/fsck/main.c | 2 +-
gfs2/libgfs2/block_list.c | 34 ++++++++++++++++------------------
gfs2/libgfs2/libgfs2.h | 27 ++++++++-------------------
6 files changed, 32 insertions(+), 45 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 3a11332..1bdadbe 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -34,7 +34,7 @@ struct saved_metablock {
struct saved_metablock *savedata;
uint64_t last_fs_block, last_reported_block, blks_saved, total_out, pct;
-struct gfs2_block_list *blocklist = NULL;
+struct gfs2_bmap *blocklist = NULL;
uint64_t journal_blocks[MAX_JOURNALS_SAVED];
uint64_t gfs1_journal_size = 0; /* in blocks */
int journals_found = 0;
@@ -620,8 +620,8 @@ void savemeta(char *out_fn, int saveoption)
fflush(stdout);
}
if (!slow) {
- blocklist = gfs2_block_list_create(&sbd, last_fs_block + 1,
- &memreq);
+ blocklist = gfs2_bmap_create(&sbd, last_fs_block + 1,
+ &memreq);
if (!blocklist)
slow = TRUE;
}
@@ -717,7 +717,7 @@ void savemeta(char *out_fn, int saveoption)
}
/* Clean up */
if (blocklist)
- gfs2_block_list_destroy(&sbd, blocklist);
+ gfs2_bmap_destroy(&sbd, blocklist);
/* There may be a gap between end of file system and end of device */
/* so we tell the user that we've processed everything. */
block = last_fs_block;
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 1b479e9..0431e4b 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -85,7 +85,7 @@ extern struct gfs2_options opts;
extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
extern osi_list_t dir_hash[FSCK_HASH_SIZE];
extern osi_list_t inode_hash[FSCK_HASH_SIZE];
-extern struct gfs2_block_list *bl;
+extern struct gfs2_bmap *bl;
extern uint64_t last_fs_block, last_reported_block;
extern int skip_this_pass, fsck_abort;
extern int errors_found, errors_corrected;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 11558b0..2241df2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -98,7 +98,7 @@ static void empty_super_block(struct gfs2_sbd *sdp)
}
if (bl)
- gfs2_block_list_destroy(sdp, bl);
+ gfs2_bmap_destroy(sdp, bl);
}
@@ -255,7 +255,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
goto fail;
}
- bl = gfs2_block_list_create(sdp, last_fs_block+1, &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 + swap space to fsck this file system.\n"));
log_crit( _("Additional memory needed is approximately: %lluMB\n"),
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 0e9ccfe..aa14f98 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -20,7 +20,7 @@ struct gfs2_options opts = {0};
struct gfs2_inode *lf_dip; /* Lost and found directory inode */
osi_list_t dir_hash[FSCK_HASH_SIZE];
osi_list_t inode_hash[FSCK_HASH_SIZE];
-struct gfs2_block_list *bl = NULL;
+struct gfs2_bmap *bl = NULL;
uint64_t last_fs_block, last_reported_block = -1;
int skip_this_pass = FALSE, fsck_abort = FALSE;
int errors_found = 0, errors_corrected = 0;
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 39de646..65df23f 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -148,19 +148,18 @@ static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap)
bmap->chunks_per_byte = 0;
}
-struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed)
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
{
- struct gfs2_block_list *il;
+ struct gfs2_bmap *il;
*addl_mem_needed = 0L;
il = malloc(sizeof(*il));
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
- *addl_mem_needed = il->list.gbmap.mapsize;
+ if(gfs2_bitmap_create(il, size, 4)) {
+ *addl_mem_needed = il->mapsize;
free(il);
il = NULL;
}
@@ -275,7 +274,7 @@ static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
}
}
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -285,13 +284,12 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
else
- err = gfs2_bitmap_set(&il->list.gbmap, block,
- mark_to_gbmap[mark]);
+ err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]);
return err;
}
/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -305,25 +303,25 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
break;
default:
/* FIXME: check types */
- err = gfs2_bitmap_clear(&il->list.gbmap, block);
+ err = gfs2_bitmap_clear(il, block);
break;
}
return err;
}
/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block)
{
int err = 0;
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(&il->list.gbmap, block);
+ err = gfs2_bitmap_clear(il, block);
return err;
}
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err;
@@ -334,7 +332,7 @@ int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
return err;
}
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val)
{
int err = 0;
@@ -345,15 +343,15 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
val->eattr_block = 1;
- if((err = gfs2_bitmap_get(&il->list.gbmap, block, &val->block_type)))
+ if((err = gfs2_bitmap_get(il, block, &val->block_type)))
return err;
return 0;
}
-void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
{
if(il) {
- gfs2_bitmap_destroy(&il->list.gbmap);
+ gfs2_bitmap_destroy(il);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b1fe8ea..38100d3 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -340,35 +340,24 @@ struct gfs2_block_query {
uint8_t eattr_block;
};
-union gfs2_block_lists {
- struct gfs2_bmap gbmap;
-};
-
-/* bitmap implementation */
-struct gfs2_block_list {
- union gfs2_block_lists list;
-};
-
-extern struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed);
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed);
extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
extern void gfs2_special_free(struct special_blocks *blist);
-extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark);
-extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark);
/* gfs2_block_unmark clears ONE mark for the given block */
-extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block m);
/* gfs2_block_clear clears all the marks for the given block */
-extern int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+extern int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block);
-extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val);
-extern void *gfs2_block_list_destroy(struct gfs2_sbd *sdp,
- struct gfs2_block_list *il);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
extern void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
14 years, 3 months
cluster: STABLE3 - Eliminate bad_block linked block list
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c7f8a0e194283bdd54d180cceda3377561ab0787
Parent: cdb69478a8101a710a3a52ffb5412f4376e39437
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:32:56 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:26 2010 -0600
Eliminate bad_block linked block list
This patch eliminates the special linked list designated for bad
blocks in fsck.gfs2 in lieu of a bad block designation in the
block list bitmap.
rhbz#455300
---
gfs2/fsck/pass2.c | 6 +++---
gfs2/fsck/pass3.c | 2 +-
gfs2/fsck/pass4.c | 2 +-
gfs2/libgfs2/block_list.c | 13 +------------
gfs2/libgfs2/libgfs2.h | 7 ++-----
5 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 55944b6..15b7594 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -246,7 +246,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return -1;
}
/* Get the status of the directory inode */
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
@@ -591,7 +591,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
}
}
pass2_fxns.private = (void *) &ds;
- if(ds.q.bad_block) {
+ if(ds.q.block_type == gfs2_bad_block) {
/* First check that the directory's metatree is valid */
if(check_metatree(sysinode, &pass2_fxns)) {
stack;
@@ -751,7 +751,7 @@ int pass2(struct gfs2_sbd *sbp)
memset(&ds, 0, sizeof(ds));
pass2_fxns.private = (void *) &ds;
- if(ds.q.bad_block) {
+ if(ds.q.block_type == gfs2_bad_block) {
/* First check that the directory's metatree
* is valid */
ip = fsck_load_inode(sbp, i);
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 9bb7cb4..d119915 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -217,7 +217,7 @@ int pass3(struct gfs2_sbd *sbp)
stack;
return FSCK_ERROR;
}
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
log_err( _("Found unlinked directory containing bad block\n"));
errors_found++;
if(query(&opts,
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 7ece88a..09a11a6 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -64,7 +64,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
stack;
return -1;
}
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
log_err( _("Unlinked inode %llu (0x%llx) contains"
"bad blocks\n"),
(unsigned long long)ii->inode,
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 75e2747..39de646 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -164,7 +164,6 @@ struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
free(il);
il = NULL;
}
- osi_list_init(&sdp->bad_blocks.list);
osi_list_init(&sdp->dup_blocks.list);
osi_list_init(&sdp->eattr_blocks.list);
return il;
@@ -281,9 +280,7 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
{
int err = 0;
- if(mark == gfs2_bad_block)
- gfs2_special_set(&sdp->bad_blocks, block);
- else if(mark == gfs2_dup_block)
+ if(mark == gfs2_dup_block)
gfs2_dup_set(&sdp->dup_blocks, block);
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
@@ -303,9 +300,6 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
case gfs2_dup_block:
gfs2_dup_clear(&sdp->dup_blocks, block);
break;
- case gfs2_bad_block:
- gfs2_special_clear(&sdp->bad_blocks, block);
- break;
case gfs2_eattr_block:
gfs2_special_clear(&sdp->eattr_blocks, block);
break;
@@ -324,7 +318,6 @@ int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
int err = 0;
gfs2_dup_clear(&sdp->dup_blocks, block);
- gfs2_special_clear(&sdp->bad_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
err = gfs2_bitmap_clear(&il->list.gbmap, block);
return err;
@@ -346,11 +339,8 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
{
int err = 0;
- val->bad_block = 0;
val->dup_block = 0;
val->eattr_block = 0;
- if (blockfind(&sdp->bad_blocks, block))
- val->bad_block = 1;
if (dupfind(&sdp->dup_blocks, block))
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
@@ -367,7 +357,6 @@ void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
free(il);
il = NULL;
}
- gfs2_special_free(&sdp->bad_blocks);
gfs2_dup_free(&sdp->dup_blocks);
gfs2_special_free(&sdp->eattr_blocks);
return il;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index e1a984f..b1fe8ea 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -249,7 +249,6 @@ struct gfs2_sbd {
unsigned int writes;
int metafs_fd;
char metafs_path[PATH_MAX]; /* where metafs is mounted */
- struct special_blocks bad_blocks;
struct dup_blocks dup_blocks;
struct special_blocks eattr_blocks;
};
@@ -310,7 +309,7 @@ struct gfs2_bmap {
#define JOURNAL_BLK (0xB) /* 1011 */
#define OTHER_META (0xC) /* 1100 */
#define EATTR_META (0xD) /* 1101 */
-#define UNUSED1 (0xE) /* 1110 */
+#define BAD_BLOCK (0xE) /* 1110 */
#define INVALID_META (0xF) /* 1111 */
/* Must be kept in sync with mark_to_bitmap array in block_list.c */
@@ -329,16 +328,14 @@ enum gfs2_mark_block {
gfs2_journal_blk = JOURNAL_BLK,
gfs2_meta_other = OTHER_META,
gfs2_meta_eattr = EATTR_META,
- gfs2_meta_unused = UNUSED1,
+ gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */
gfs2_meta_inval = INVALID_META,
- gfs2_bad_block, /* Contains at least one bad block */
gfs2_dup_block, /* Contains at least one duplicate block */
gfs2_eattr_block, /* Contains an eattr */
};
struct gfs2_block_query {
uint8_t block_type;
- uint8_t bad_block;
uint8_t dup_block;
uint8_t eattr_block;
};
14 years, 3 months
cluster: STABLE3 - Remove nvbuf_list and use fewer buffers
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cdb69478a8101a710a3a52ffb5412f4376e39437
Parent: c6df45775f8a255b928b839a8c0201c631c8c811
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:31:51 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:26 2010 -0600
Remove nvbuf_list and use fewer buffers
This preliminary patch is a starting point for disentangling the
issues fsck has with libgfs2/buf.c. Rather than read in all the
rgrp bitmaps into memory, all in a non-volatile linked list, this
patch keeps the same linked list of rgrps, but only reads in the
bitmaps on an as-needed basis, and only for short-term. This is
also an attempt to eliminate the fairly new non-volatile linked
buffer list and change all the code in gfs2-utils so that they
should not depend on the list being non-volatile. The whole
non-volatile thing was a stop-gap temporary solution so that we
could minimize the possibility of regression. In addition to
getting rid of the non-volatile linked list, it also reduces the
remaining linked list of buffers from 128MB to 1MB so that much
fewer buffers will be kept in memory. That could drive a lot of
bugs out of their hiding places.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 125 +++++++++++++++++++++++++++----------------
gfs2/edit/hexedit.c | 57 ++++++++++----------
gfs2/edit/savemeta.c | 33 +++++++++---
gfs2/fsck/fs_recovery.c | 1 -
gfs2/fsck/initialize.c | 3 +-
gfs2/fsck/main.c | 1 -
gfs2/fsck/pass1.c | 26 +++++++--
gfs2/fsck/pass5.c | 42 ++++++++++-----
gfs2/fsck/rgrepair.c | 93 ++++++++++++++++++--------------
gfs2/libgfs2/block_list.c | 15 +++---
gfs2/libgfs2/buf.c | 4 ++
gfs2/libgfs2/fs_bits.c | 44 ++++++++++++---
gfs2/libgfs2/fs_geometry.c | 19 +++----
gfs2/libgfs2/fs_ops.c | 82 ++++++++++++++++------------
gfs2/libgfs2/gfs1.c | 30 +++++++++--
gfs2/libgfs2/libgfs2.h | 32 +++++------
gfs2/libgfs2/rgrp.c | 34 ++++--------
gfs2/libgfs2/structures.c | 13 +++--
gfs2/libgfs2/super.c | 34 +++++++++---
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 4 +-
21 files changed, 424 insertions(+), 272 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 4034e74..020b4e5 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -157,34 +157,29 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
/* valid in gfs1 but invalid in gfs2). */
/* ------------------------------------------------------------------------- */
static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
- int read_disk)
+ struct gfs2_buffer_head **rgbh)
{
uint32_t blk;
int x, y;
struct gfs2_rindex *ri;
unsigned char state;
- struct gfs2_buffer_head *bh;
ri = &rgd2->ri;
- if (gfs2_compute_bitstructs(sdp, rgd2)) { /* mallocs bh as array */
+ if (gfs2_compute_bitstructs(sdp, rgd2)) {
log_crit("gfs2_convert: Error converting bitmaps.\n");
exit(-1);
}
for (blk = 0; blk < ri->ri_length; blk++) {
- bh = bget_generic(&sdp->nvbuf_list, ri->ri_addr + blk,
- read_disk, read_disk);
- if (!rgd2->bh[blk])
- rgd2->bh[blk] = bh;
- x = (blk) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+ x = (blk) ? sizeof(struct gfs2_meta_header) :
+ sizeof(struct gfs2_rgrp);
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (rgd2->bh[blk]->b_data[x] >>
- (GFS2_BIT_SIZE * y)) & 0x03;
+ state = (rgbh[blk]->b_data[x] >>
+ (GFS2_BIT_SIZE * y)) & 0x03;
if (state == 0x02) /* unallocated metadata state invalid */
- rgd2->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+ rgbh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
}
- brelse(bh, updated);
}
}/* convert_bitmaps */
@@ -195,38 +190,49 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
static int convert_rgs(struct gfs2_sbd *sbp)
{
struct rgrp_list *rgd;
+ struct gfs2_rgrp rg;
osi_list_t *tmp;
- struct gfs2_buffer_head *bh;
struct gfs1_rgrp *rgd1;
int rgs = 0;
+ struct gfs2_buffer_head **rgbh;
/* --------------------------------- */
/* Now convert its rgs into gfs2 rgs */
/* --------------------------------- */
osi_list_foreach(tmp, &sbp->rglist) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ gfs2_rgrp_read(sbp, rgd, rgbh, &rg);
+ rgd1 = (struct gfs1_rgrp *)&rg; /* recast as gfs1 structure */
/* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */
/* convert from be to cpu. We must do it now. */
- rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+ rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+ rgd->rg_free = rg.rg_free;
/* Zero it out so we don't add it again in case something breaks */
/* later on in the process and we have to re-run convert */
rgd1->rg_freemeta = 0;
sbp->blks_total += rgd->ri.ri_data;
- sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free);
+ sbp->blks_alloced += (rgd->ri.ri_data - rg.rg_free);
sbp->dinodes_alloced += rgd1->rg_useddi;
- convert_bitmaps(sbp, rgd, TRUE);
+ convert_bitmaps(sbp, rgd, rgbh);
/* Write the updated rgrp to the gfs2 buffer */
- bh = bget(&sbp->nvbuf_list,
- rgd->ri.ri_addr); /* get a gfs2 buffer for the rg */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
- brelse(bh, updated); /* release the buffer */
+ gfs2_rgrp_out(&rg, rgbh[0]->b_data);
rgs++;
if (rgs % 100 == 0) {
printf(".");
fflush(stdout);
}
+ free(rgbh);
}
return 0;
}/* superblock_cvt */
@@ -694,6 +700,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
int first;
int error = 0;
int rgs_processed = 0;
+ struct gfs2_buffer_head **rgbh;
+ struct gfs2_rgrp rg;
log_notice("Converting inodes.\n");
sbp->md.next_inum = 1; /* starting inode numbering */
@@ -707,8 +715,18 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
rgs_processed++;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
first = 1;
- if (gfs2_rgrp_read(sbp, rgd)) {
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+ if (gfs2_rgrp_read(sbp, rgd, rgbh, &rg)) {
log_crit("Unable to read rgrp.\n");
+ free(rgbh);
return -1;
}
while (1) { /* for all inodes in the resource group */
@@ -753,9 +771,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
sizeof(struct gfs2_rgrp);
/* if it's on this page */
if (buf_offset + bitmap_byte < sbp->bsize) {
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &=
+ rgbh[blk]->b_data[buf_offset + bitmap_byte] &=
~(0x03 << (GFS2_BIT_SIZE * byte_bit));
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
+ rgbh[blk]->b_data[buf_offset + bitmap_byte] |=
(0x01 << (GFS2_BIT_SIZE * byte_bit));
break;
}
@@ -765,7 +783,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
brelse(bh, updated);
first = 0;
} /* while 1 */
- gfs2_rgrp_relse(rgd, updated);
+ gfs2_rgrp_relse(rgd, updated, rgbh);
+ free(rgbh);
} /* for all rgs */
log_notice("\r%" PRIu64" inodes from %d rgs converted.",
sbp->md.next_inum, rgs_processed);
@@ -1091,8 +1110,7 @@ static int init(struct gfs2_sbd *sbp)
sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sbp->bsize = sbp->sd_sb.sb_bsize;
osi_list_init(&sbp->rglist);
- init_buf_list(sbp, &sbp->buf_list, 128 << 20);
- init_buf_list(sbp, &sbp->nvbuf_list, 0xffffffff);
+ init_buf_list(sbp, &sbp->buf_list, 1 << 20); /* only use 1MB of bufs */
if (compute_constants(sbp)) {
log_crit("Error: Bad constants (1)\n");
exit(-1);
@@ -1319,6 +1337,8 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
struct rgrp_list *rgd, *rgdhigh;
osi_list_t *tmp;
struct gfs2_meta_header mh;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
@@ -1329,12 +1349,12 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
uint64_t size;
jndx = &sd_jindex[j];
- /* go through all rg index entries, keeping track of the highest */
- /* that's still in the first subdevice. */
- /* Note: we really should go through all of the rgindex because */
- /* we might have had rg's added by gfs_grow, and journals added */
- /* by jadd. gfs_grow adds rgs out of order, so we can't count */
- /* on them being in ascending order. */
+ /* go through all rg index entries, keeping track of the
+ highest that's still in the first subdevice.
+ Note: we really should go through all of the rgindex because
+ we might have had rg's added by gfs_grow, and journals added
+ by jadd. gfs_grow adds rgs out of order, so we can't count
+ on them being in ascending order. */
rgdhigh = NULL;
osi_list_foreach(tmp, &sdp->rglist) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
@@ -1359,11 +1379,11 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
}
memset(rgd, 0, sizeof(struct rgrp_list));
size = jndx->ji_nsegment * be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size);
- rgd->rg.rg_header.mh_magic = GFS2_MAGIC;
- rgd->rg.rg_header.mh_type = GFS2_METATYPE_RG;
- rgd->rg.rg_header.mh_format = GFS2_FORMAT_RG;
- rgd->rg.rg_flags = 0;
- rgd->rg.rg_dinodes = 0;
+ rg.rg_header.mh_magic = GFS2_MAGIC;
+ rg.rg_header.mh_type = GFS2_METATYPE_RG;
+ rg.rg_header.mh_format = GFS2_FORMAT_RG;
+ rg.rg_flags = 0;
+ rg.rg_dinodes = 0;
rgd->ri.ri_addr = jndx->ji_addr; /* new rg addr becomes ji addr */
rgd->ri.ri_length = rgrp_length(size, sdp); /* aka bitblocks */
@@ -1374,19 +1394,32 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
/* Round down to nearest multiple of GFS2_NBBY */
while (rgd->ri.ri_data & 0x03)
rgd->ri.ri_data--;
- rgd->rg.rg_free = rgd->ri.ri_data;
+ rg.rg_free = rgd->ri.ri_data;
+ rgd->rg_free = rg.rg_free;
rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
- convert_bitmaps(sdp, rgd, FALSE); /* allocates rgd->bh */
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ convert_bitmaps(sdp, rgd, rgbh);
for (x = 0; x < rgd->ri.ri_length; x++) {
- rgd->bh[x]->b_count++;
+ rgbh[x]->b_count++;
if (x)
- gfs2_meta_header_out(&mh, rgd->bh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgbh[x]->b_data);
else
- gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data);
+ gfs2_rgrp_out(&rg, rgbh[x]->b_data);
}
/* Add the new gfs2 rg to our list: We'll output the rg index later. */
osi_list_add_prev((osi_list_t *)&rgd->list,
(osi_list_t *)&sdp->rglist);
+ free(rgbh);
} /* for each journal */
return error;
}/* journ_space_to_rg */
@@ -1527,7 +1560,7 @@ int main(int argc, char **argv)
if (error)
log_crit("%s: Unable to convert resource groups.\n",
device);
- bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
+ bcommit(&sb2.buf_list); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Renumber the inodes consecutively. */
@@ -1595,12 +1628,11 @@ int main(int argc, char **argv)
inode_put(sb2.md.statfs, updated);
bcommit(&sb2.buf_list); /* write the buffers to disk */
- bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
/* Now delete the now-obsolete gfs1 files: */
remove_obsolete_gfs1(&sb2);
/* Now free all the in memory */
- gfs2_rgrp_free(&sb2.rglist, updated);
+ gfs2_rgrp_free(&sb2.rglist);
log_notice("Committing changes to disk.\n");
fflush(stdout);
/* Set filesystem type in superblock to gfs2. We do this at the */
@@ -1614,7 +1646,6 @@ int main(int argc, char **argv)
brelse(bh, updated);
bsync(&sb2.buf_list); /* write the buffers to disk */
- bsync(&sb2.nvbuf_list); /* write the buffers to disk */
error = fsync(sb2.device_fd);
if (error)
perror(device);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index b6b8fe9..6a052b2 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -563,10 +563,9 @@ int display_block_type(const char *lpBuffer, int from_restore)
struct rgrp_list *rgd;
rgd = gfs2_blk2rgrpd(&sbd, block);
- if (rgd) {
+ if (rgd)
type = gfs2_get_bitmap(&sbd, block, rgd);
- gfs2_rgrp_relse(rgd, not_updated);
- } else
+ else
type = 4;
screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
if (!screen_chunk_size)
@@ -784,7 +783,7 @@ static void rgcount(void)
printf("%lld RGs in this file system.\n",
(unsigned long long)sbd.md.riinode->i_di.di_size / risize());
inode_put(sbd.md.riinode, not_updated);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
@@ -987,7 +986,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
else {
struct gfs2_buffer_head *tmp_bh;
- tmp_bh = bread(&sbd.nvbuf_list, ri.ri_addr);
+ tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
if (gfs1) {
struct gfs_rgrp rg1;
gfs_rgrp_in(&rg1, tmp_bh->b_data);
@@ -1690,7 +1689,7 @@ static int display_extended(void)
/* ------------------------------------------------------------------------ */
static void read_superblock(int fd)
{
- int count;
+ int count, bitmap_blocks = 0;
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
ioctl(fd, BLKFLSBUF, 0);
@@ -1709,8 +1708,7 @@ static void read_superblock(int fd)
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
sbd.time = time(NULL);
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
- init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+ init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
/* Check to see if this is really gfs1 */
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -1750,7 +1748,8 @@ static void read_superblock(int fd)
sbd.md.riinode = gfs2_load_inode(&sbd,
sbd1->sb_rindex_di.no_addr);
sbd.fssize = sbd.device.length;
- gfs1_ri_update(&sbd, 0, &count, 1);
+ gfs1_rindex_read(&sbd, fd, &count, &bitmap_blocks);
+ /*gfs1_ri_update(&sbd, 0, &count, 1);*/
} else {
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
@@ -1760,7 +1759,8 @@ static void read_superblock(int fd)
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
sbd.fssize = sbd.device.length;
- ri_update(&sbd, 0, &count);
+ rindex_read(&sbd, fd, &count, &bitmap_blocks);
+ /*ri_update(&sbd, 0, &count);*/
}
}
@@ -2030,7 +2030,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
else
printf("%llu\n", (unsigned long long)blk);
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(0);
return blk;
@@ -2069,7 +2069,7 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri
if (!rgd) {
if (print)
printf("0\n");
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(-1);
}
@@ -2095,7 +2095,7 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri
else
printf("%llu\n", (unsigned long long)blk);
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(0);
return blk;
@@ -2129,7 +2129,7 @@ static uint64_t find_metablockoftype(const char *strtype, int print)
"specified: must be one of:\n");
fprintf(stderr, "sb rg rb di in lf jd lh ld"
" ea ed lb 13 qc\n");
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(-1);
}
return blk;
@@ -2438,7 +2438,7 @@ static void find_print_block_type(void)
type = get_block_type(bh->b_data);
print_block_type(tblock, type, "");
brelse(bh, NOT_UPDATED);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2481,7 +2481,7 @@ static void find_print_block_rg(int bitmap)
printf("-1 (block invalid or part of an rgrp).\n");
}
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2502,7 +2502,7 @@ static void find_change_block_alloc(int *newval)
*newval);
for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
printf("%d - %s\n", i, allocdesc[gfs1][i]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(-1);
}
ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
@@ -2519,17 +2519,16 @@ static void find_change_block_alloc(int *newval)
if (rgd) {
type = gfs2_get_bitmap(&sbd, ablock, rgd);
printf("%d (%s)\n", type, allocdesc[gfs1][type]);
- gfs2_rgrp_relse(rgd, not_updated);
} else {
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
printf("-1 (block invalid or part of an rgrp).\n");
exit(-1);
}
}
}
- gfs2_rgrp_free(&sbd.rglist, (newval) ? updated : not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (newval)
- bcommit(&sbd.nvbuf_list);
+ bcommit(&sbd.buf_list);
exit(0);
}
@@ -3332,7 +3331,7 @@ static void process_parameters(int argc, char *argv[], int pass)
printf("Error: field not specified.\n");
printf("Format is: %s -p <block> field "
"<field> [newvalue]\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
if (isdigit(argv[i + 1][0])) {
@@ -3342,11 +3341,11 @@ static void process_parameters(int argc, char *argv[], int pass)
else
newval = (uint64_t)atoll(argv[i + 1]);
process_field(argv[i], &newval, 1);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
} else {
process_field(argv[i], NULL, 1);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
} else if (!strcmp(argv[i], "blocktype")) {
@@ -3378,7 +3377,7 @@ static void process_parameters(int argc, char *argv[], int pass)
printf("Error: rg # not specified.\n");
printf("Format is: %s rgflags rgnum"
"[newvalue]\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
if (argv[i][0]=='0' && argv[i][1]=='x')
@@ -3395,7 +3394,7 @@ static void process_parameters(int argc, char *argv[], int pass)
new_flags = atoi(argv[i]);
}
set_rgrp_flags(rg, new_flags, set, FALSE);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
} else if (!strcmp(argv[i], "rg")) {
int rg;
@@ -3404,7 +3403,7 @@ static void process_parameters(int argc, char *argv[], int pass)
if (i >= argc - 1) {
printf("Error: rg # not specified.\n");
printf("Format is: %s rg rgnum\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
rg = atoi(argv[i]);
@@ -3413,7 +3412,7 @@ static void process_parameters(int argc, char *argv[], int pass)
push_block(temp_blk);
} else {
set_rgrp_flags(rg, 0, FALSE, TRUE);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
}
@@ -3523,6 +3522,6 @@ int main(int argc, char *argv[])
free(buf);
if (indirect)
free(indirect);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 85fcde7..3a11332 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -471,12 +471,14 @@ static void get_journal_inode_blocks(void)
}
}
-static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t *nrfblock, int first)
+static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *nrfblock, int first)
{
struct gfs2_bitmap *bits = NULL;
uint32_t length = rgd->ri.ri_length;
uint32_t blk = (first)? 0: (uint32_t)((*nrfblock+1)-rgd->ri.ri_data0);
int i;
+ struct gfs2_buffer_head *bh;
if(!first && (*nrfblock < rgd->ri.ri_data0)) {
log_err("next_rg_freemeta: Start block is outside rgrp "
@@ -491,9 +493,11 @@ static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t *nrfblock, int first
}
for(; i < length; i++){
bits = &rgd->bits[i];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)bh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_UNLINKED);
+ brelse(bh, not_updated);
if(blk != BFITNOENT){
*nrfblock = blk + (bits->bi_start * GFS2_NBBY) +
rgd->ri.ri_data0;
@@ -515,6 +519,8 @@ void savemeta(char *out_fn, int saveoption)
int rgcount;
uint64_t jindex_block;
struct gfs2_buffer_head *bh;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
slow = (saveoption == 1);
sbd.md.journals = 1;
@@ -551,8 +557,7 @@ void savemeta(char *out_fn, int saveoption)
exit(-1);
}
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
- init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+ init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
if (!gfs1)
sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
if (compute_constants(&sbd)) {
@@ -649,7 +654,16 @@ void savemeta(char *out_fn, int saveoption)
int i, first;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- slow = gfs2_rgrp_read(&sbd, rgd);
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ break;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ break;
+ }
+ slow = gfs2_rgrp_read(&sbd, rgd, rgbh, &rg);
if (slow)
continue;
log_debug("RG at %lld (0x%llx) is %u long\n",
@@ -673,7 +687,8 @@ void savemeta(char *out_fn, int saveoption)
if (saveoption != 2) {
int blktype;
- while (!gfs2_next_rg_meta(rgd, &block, first)) {
+ while (!gfs2_next_rg_meta(&sbd, rgd, &block,
+ first)) {
warm_fuzzy_stuff(block, FALSE, TRUE);
blktype = save_block(sbd.device_fd,
out_fd, block);
@@ -684,13 +699,15 @@ void savemeta(char *out_fn, int saveoption)
/* Save off the free/unlinked meta blocks too.
If we don't, we may run into metadata
allocation issues. */
- while (!next_rg_freemeta(rgd, &block, first)) {
+ while (!next_rg_freemeta(&sbd, rgd, &block,
+ first)) {
blktype = save_block(sbd.device_fd,
out_fd, block);
first = 0;
}
}
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
}
}
if (slow) {
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 16480be..763190e 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -576,6 +576,5 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
inode_put(sdp->md.jiinode, not_updated);
/* Sync the buffers to disk so we get a fresh start. */
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
return error;
}
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f9f82fa..11558b0 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -287,8 +287,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
********************************************************************/
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
for(i = 0; i < FSCK_HASH_SIZE; i++) {
osi_list_init(&dir_hash[i]);
osi_list_init(&inode_hash[i]);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 68e8428..0e9ccfe 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -469,7 +469,6 @@ int main(int argc, char **argv)
log_notice( _("Writing changes to disk\n"));
bsync(&sbp->buf_list);
- bsync(&sbp->nvbuf_list);
destroy(sbp);
log_notice( _("gfs2_fsck complete \n"));
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 17c4bfc..7a59e13 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -962,6 +962,8 @@ int pass1(struct gfs2_sbd *sbp)
uint64_t blk_count;
uint64_t offset;
uint64_t rg_count = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* FIXME: In the gfs fsck, we had to mark things like the
* journals and indices and such as 'other_meta' - in gfs2,
@@ -984,8 +986,18 @@ int pass1(struct gfs2_sbd *sbp)
log_info( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
rg_count);
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- if(gfs2_rgrp_read(sbp, rgd)){
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return FSCK_ERROR;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return FSCK_ERROR;
+ }
+ if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
log_debug( _("RG at %llu (0x%llx) is %u long\n"),
@@ -996,6 +1008,7 @@ int pass1(struct gfs2_sbd *sbp)
if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
gfs2_meta_other)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
}
@@ -1006,11 +1019,12 @@ int pass1(struct gfs2_sbd *sbp)
while (1) {
/* "block" is relative to the entire file system */
- if (gfs2_next_rg_meta(rgd, &block, first))
+ if (gfs2_next_rg_meta(sbp, rgd, &block, first))
break;
warm_fuzzy_stuff(block);
if (fsck_abort) { /* if asked to abort */
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
return FSCK_OK;
}
if (skip_this_pass) {
@@ -1023,13 +1037,15 @@ int pass1(struct gfs2_sbd *sbp)
if (scan_meta(sbp, bh, block)) {
stack;
brelse(bh, not_updated);
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
return FSCK_ERROR;
}
brelse(bh, not_updated);
first = 0;
}
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
}
return FSCK_OK;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 53aef44..925e8cc 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -153,7 +153,8 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
}
static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
- uint32_t *count)
+ uint32_t *count, struct gfs2_buffer_head **rgbh,
+ struct gfs2_rgrp *rg)
{
uint32_t i;
struct gfs2_bitmap *bits;
@@ -164,26 +165,26 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
bits = &rgp->bits[i];
/* update the bitmaps */
- check_block_status(sbp, rgp->bh[i]->b_data + bits->bi_offset,
+ check_block_status(sbp, rgbh[i]->b_data + bits->bi_offset,
bits->bi_len, &rg_block, rgp->ri.ri_data0, count);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
}
/* actually adjust counters and write out to disk */
- if(rgp->rg.rg_free != count[0]) {
+ if(rgp->rg_free != count[0]) {
log_err( _("RG #%llu (0x%llx) free count inconsistent: "
"is %u should be %u\n"),
(unsigned long long)rgp->ri.ri_addr,
(unsigned long long)rgp->ri.ri_addr,
- rgp->rg.rg_free, count[0]);
- rgp->rg.rg_free = count[0];
+ rgp->rg_free, count[0]);
+ rgp->rg_free = count[0];
update = 1;
}
- if(rgp->rg.rg_dinodes != count[1]) {
+ if(rg->rg_dinodes != count[1]) {
log_err( _("Inode count inconsistent: is %u should be %u\n"),
- rgp->rg.rg_dinodes, count[1]);
- rgp->rg.rg_dinodes = count[1];
+ rg->rg_dinodes, count[1]);
+ rg->rg_dinodes = count[1];
update = 1;
}
if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
@@ -199,7 +200,7 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
errors_corrected++;
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
- gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
+ gfs2_rgrp_out(rg, rgbh[0]->b_data);
return updated;
} else
log_err( _("Resource group counts left inconsistent\n"));
@@ -216,9 +217,11 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
int pass5(struct gfs2_sbd *sbp)
{
osi_list_t *tmp;
- struct rgrp_list *rgp = NULL;
+ struct rgrp_list *rgd = NULL;
uint32_t count[3];
uint64_t rg_count = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* Reconcile RG bitmaps with fsck bitmap */
for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){
@@ -228,16 +231,27 @@ int pass5(struct gfs2_sbd *sbp)
return FSCK_OK;
log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
memset(count, 0, sizeof(count));
- rgp = osi_list_entry(tmp, struct rgrp_list, list);
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
- if(gfs2_rgrp_read(sbp, rgp)){
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return FSCK_ERROR;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return FSCK_ERROR;
+ }
+ if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
rg_count++;
/* Compare the bitmaps and report the differences */
- f = update_rgrp(sbp, rgp, count);
- gfs2_rgrp_relse(rgp, f);
+ f = update_rgrp(sbp, rgd, count, rgbh, &rg);
+ gfs2_rgrp_relse(rgd, f, rgbh);
+ free(rgbh);
}
/* Fix up superblock info based on this - don't think there's
* anything to do here... */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index d0b8f33..a4c8cf7 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -129,7 +129,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (blk = sdp->sb_addr + 1;
blk < sdp->device.length && number_of_rgs < 6;
blk++) {
- bh = bread(&sdp->nvbuf_list, blk);
+ bh = bread(&sdp->buf_list, blk);
if (((blk == sdp->sb_addr + 1) ||
(!gfs2_check_meta(bh, GFS2_METATYPE_RG))) &&
!is_false_rg(blk)) {
@@ -207,7 +207,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (blk = sdp->sb_addr + 1; blk <= sdp->device.length;
blk += block_bump) {
log_debug( _("Block 0x%" PRIx64 "\n"), blk);
- bh = bread(&sdp->nvbuf_list, blk);
+ bh = bread(&sdp->buf_list, blk);
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
brelse(bh, not_updated);
/* Allocate a new RG and index. */
@@ -241,7 +241,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (fwd_block = blk + 1;
fwd_block < sdp->device.length;
fwd_block++) {
- bh = bread(&sdp->nvbuf_list, fwd_block);
+ bh = bread(&sdp->buf_list, fwd_block);
bitmap_was_fnd =
(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
brelse(bh, not_updated);
@@ -252,13 +252,6 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
} /* for subsequent bitmaps */
gfs2_compute_bitstructs(sdp, calc_rgd);
- log_debug( _("Memory allocated for rg at 0x%llx, bh: %p\n"),
- (unsigned long long)calc_rgd->ri.ri_addr,
- calc_rgd->bh);
- if (!calc_rgd->bh) {
- log_crit( _("Can't allocate memory for bitmap repair.\n"));
- return -1;
- }
calc_rgd->ri.ri_data0 = calc_rgd->ri.ri_addr +
calc_rgd->ri.ri_length;
if (prev_rgd) {
@@ -381,37 +374,38 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
* rewrite_rg_block - rewrite ("fix") a buffer with rg or bitmap data
* returns: 0 if the rg was repaired, otherwise 1
*/
-static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
- uint64_t errblock)
+static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t errblock, struct gfs2_buffer_head **rgbh,
+ struct gfs2_rgrp *rg)
{
- int x = errblock - rg->ri.ri_addr;
+ int x = errblock - rgd->ri.ri_addr;
log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither"
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
- rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
- (int)x+1, (int)rg->ri.ri_length);
+ rgbh[x]->b_blocknr, rgbh[x]->b_blocknr,
+ (int)x+1, (int)rgd->ri.ri_length);
errors_found++;
if (query(&opts, "Fix the RG? (y/n)")) {
errors_corrected++;
log_err( _("Attempting to repair the RG.\n"));
- rg->bh[x] = bread(&sdp->nvbuf_list, rg->ri.ri_addr + x);
+ rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
if (x) {
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
mh.mh_format = GFS2_FORMAT_RB;
- gfs2_meta_header_out(&mh, rg->bh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgbh[x]->b_data);
} else {
- memset(&rg->rg, 0, sizeof(struct gfs2_rgrp));
- rg->rg.rg_header.mh_magic = GFS2_MAGIC;
- rg->rg.rg_header.mh_type = GFS2_METATYPE_RG;
- rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
- rg->rg.rg_free = rg->ri.ri_data;
- gfs2_rgrp_out(&rg->rg, rg->bh[x]->b_data);
+ memset(rg, 0, sizeof(struct gfs2_rgrp));
+ rg->rg_header.mh_magic = GFS2_MAGIC;
+ rg->rg_header.mh_type = GFS2_METATYPE_RG;
+ rg->rg_header.mh_format = GFS2_FORMAT_RG;
+ rg->rg_free = rgd->ri.ri_data;
+ gfs2_rgrp_out(rg, rgbh[x]->b_data);
}
- brelse(rg->bh[x], updated);
+ brelse(rgbh[x], updated);
return 0;
}
return 1;
@@ -432,6 +426,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
int calc_rg_count = 0, rgcount_from_index, rg;
osi_list_t *exp, *act; /* expected, actual */
struct gfs2_rindex buf;
+ int bitmap_blocks;
if (trust_lvl == blind_faith)
return 0;
@@ -440,7 +435,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
error = gfs2_rindex_calculate(sdp, &expected_rglist,
&calc_rg_count);
if (error) { /* If calculated RGs don't match the fs */
- gfs2_rgrp_free(&expected_rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
return -1;
}
}
@@ -449,18 +444,18 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
&calc_rg_count);
if (error) {
log_crit( _("Error rebuilding rg list.\n"));
- gfs2_rgrp_free(&expected_rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
return -1;
}
sdp->rgrps = calc_rg_count;
}
/* Read in the rindex */
osi_list_init(&sdp->rglist); /* Just to be safe */
- rindex_read(sdp, 0, &rgcount_from_index);
+ rindex_read(sdp, 0, &rgcount_from_index, &bitmap_blocks);
if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
log_warn( _("WARNING: rindex file is corrupt.\n"));
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
log_warn( _("L%d: number of rgs expected = %lld.\n"), trust_lvl + 1,
@@ -468,8 +463,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
if (calc_rg_count != sdp->rgrps) {
log_warn( _("L%d: They don't match; either (1) the fs was extended, (2) an odd\n"), trust_lvl + 1);
log_warn( _("L%d: rg size was used, or (3) we have a corrupt rg index.\n"), trust_lvl + 1);
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
/* ------------------------------------------------------------- */
@@ -500,8 +495,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
trust_lvl + 1);
log_warn( _("%d out of %d RGs did not match what was expected.\n"),
descrepencies, rg);
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
/* ------------------------------------------------------------- */
@@ -540,8 +535,6 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
/* Therefore, gfs2_compute_bitstructs might */
/* have malloced the wrong length for bitmap */
/* buffers. So we have to redo it. */
- if (actual->bh)
- free(actual->bh);
if (actual->bits)
free(actual->bits);
}
@@ -561,28 +554,46 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
struct rgrp_list *rgd;
uint64_t prev_err = 0, errblock;
int i;
+ struct gfs2_rgrp rgrp;
+ struct gfs2_buffer_head **rgbh;
/* Now we try repeatedly to read in the rg. For every block */
/* we encounter that has errors, repair it and try again. */
i = 0;
do {
rgd = osi_list_entry(act, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rgrp);
if (errblock) {
- if (errblock == prev_err)
+ if (errblock == prev_err) {
+ free(rgbh);
break;
+ }
prev_err = errblock;
- rewrite_rg_block(sdp, rgd, errblock);
+ rewrite_rg_block(sdp, rgd, errblock, rgbh,
+ &rgrp);
}
else {
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
break;
}
+ free(rgbh);
i++;
} while (i < rgd->ri.ri_length);
}
*rg_count = rg;
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return 0;
}
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 571c737..75e2747 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -159,8 +159,8 @@ struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(&il->list.gbmap.group_map, size, 4)) {
- *addl_mem_needed = il->list.gbmap.group_map.mapsize;
+ if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
+ *addl_mem_needed = il->list.gbmap.mapsize;
free(il);
il = NULL;
}
@@ -288,7 +288,7 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
else
- err = gfs2_bitmap_set(&il->list.gbmap.group_map, block,
+ err = gfs2_bitmap_set(&il->list.gbmap, block,
mark_to_gbmap[mark]);
return err;
}
@@ -311,7 +311,7 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
break;
default:
/* FIXME: check types */
- err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+ err = gfs2_bitmap_clear(&il->list.gbmap, block);
break;
}
return err;
@@ -326,7 +326,7 @@ int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->bad_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+ err = gfs2_bitmap_clear(&il->list.gbmap, block);
return err;
}
@@ -355,8 +355,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
val->eattr_block = 1;
- if((err = gfs2_bitmap_get(&il->list.gbmap.group_map, block,
- &val->block_type)))
+ if((err = gfs2_bitmap_get(&il->list.gbmap, block, &val->block_type)))
return err;
return 0;
}
@@ -364,7 +363,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
{
if(il) {
- gfs2_bitmap_destroy(&il->list.gbmap.group_map);
+ gfs2_bitmap_destroy(&il->list.gbmap);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index f0164b4..a12c19c 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -37,6 +37,10 @@ static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
}
sdp->writes++;
}
+ bh->b_blocknr = -1;
+ bh->b_data = NULL;
+ bh->b_count = -1;
+ bh->b_changed = -1;
free(bh);
return 0;
}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index ed459af..1f197b1 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -1,5 +1,6 @@
#include <inttypes.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "libgfs2.h"
@@ -112,6 +113,8 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
struct rgrp_list *rgd;
unsigned char *byte, cur_state;
unsigned int bit;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* FIXME: should GFS2_BLKST_INVALID be allowed */
if ((state < GFS2_BLKST_FREE) || (state > GFS2_BLKST_DINODE))
@@ -122,8 +125,20 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
if(!rgd)
return -1;
- if(gfs2_rgrp_read(sdp, rgd))
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg)) {
+ free(rgbh);
+ return -1;
+ }
rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
for(buf= 0; buf < rgd->ri.ri_length; buf++){
bits = &(rgd->bits[buf]);
@@ -131,7 +146,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
break;
}
- byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgbh[buf]->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
@@ -139,12 +154,13 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
*byte ^= cur_state << bit;
*byte |= state << bit;
- gfs2_rgrp_relse(rgd, updated);
+ gfs2_rgrp_relse(rgd, updated, rgbh);
+ free(rgbh);
return 0;
}
/*
- * fs_get_bitmap - get value of FS bitmap
+ * gfs2_get_bitmap - get value of FS bitmap
* @sdp: super block
* @blkno: block number relative to file system
*
@@ -167,6 +183,9 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
unsigned int bit;
unsigned char *byte;
int local_rgd = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
+ int bitmap_blocks = rgd->length;
if(gfs2_check_range(sdp, blkno))
return -1;
@@ -176,7 +195,16 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
}
if(rgd == NULL)
return -1;
- if(gfs2_rgrp_read(sdp, rgd))
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg))
return -1;
rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
@@ -189,17 +217,17 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
}
if(i >= rgd->ri.ri_length){
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
return -1;
}
- byte = (unsigned char *)(rgd->bh[i]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgbh[i]->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
val = ((*byte >> bit) & GFS2_BIT_MASK);
if(local_rgd)
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
return val;
}
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 9c5daf1..dfdd7e7 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -112,7 +112,6 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
rl->length = dev->length -
(nrgrp - 1) * (dev->length / nrgrp);
}
- rl->rgf_flags = dev->rgf_flags;
log_info("%d: start: %" PRIu64 " (0x%"
PRIx64 "), length = %"PRIu64" (0x%"
@@ -183,7 +182,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
struct rgrp_list *rl;
uint32_t rgblocks, bitblocks;
struct gfs2_rindex *ri;
- struct gfs2_rgrp *rg;
+ struct gfs2_rgrp rg;
struct gfs2_meta_header mh;
unsigned int x;
struct gfs2_buffer_head *bh;
@@ -197,7 +196,6 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
tmp = tmp->next) {
rl = osi_list_entry(tmp, struct rgrp_list, list);
ri = &rl->ri;
- rg = &rl->rg;
rgblocks = rl->length;
rgblocks2bitblocks(sdp->bsize, &rgblocks, &bitblocks);
@@ -208,19 +206,20 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
ri->ri_data = rgblocks;
ri->ri_bitbytes = rgblocks / GFS2_NBBY;
- rg->rg_header.mh_magic = GFS2_MAGIC;
- rg->rg_header.mh_type = GFS2_METATYPE_RG;
- rg->rg_header.mh_format = GFS2_FORMAT_RG;
- rg->rg_flags = rl->rgf_flags;
- rg->rg_free = rgblocks;
+ memset(&rg, 0, sizeof(rg));
+ rg.rg_header.mh_magic = GFS2_MAGIC;
+ rg.rg_header.mh_type = GFS2_METATYPE_RG;
+ rg.rg_header.mh_format = GFS2_FORMAT_RG;
+ rg.rg_free = rgblocks;
+ rl->rg_free = rgblocks;
if (do_write) {
for (x = 0; x < bitblocks; x++) {
- bh = bget(&sdp->nvbuf_list, rl->start + x);
+ bh = bget(&sdp->buf_list, rl->start + x);
if (x)
gfs2_meta_header_out(&mh, bh->b_data);
else
- gfs2_rgrp_out(rg, bh->b_data);
+ gfs2_rgrp_out(&rg, bh->b_data);
brelse(bh, updated);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index fc898ce..7c44a8c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -56,16 +56,17 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
osi_list_t *tmp, *head;
struct rgrp_list *rl = NULL;
struct gfs2_rindex *ri;
- struct gfs2_rgrp *rg;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
unsigned int block, bn = 0, x = 0, y = 0;
- struct gfs2_buffer_head *bh;
unsigned int state;
+ memset(&rg, 0, sizeof(rg));
for (head = &sdp->rglist, tmp = head->next;
tmp != head;
tmp = tmp->next) {
rl = osi_list_entry(tmp, struct rgrp_list, list);
- if (rl->rg.rg_free)
+ if (rl->rg_free)
break;
}
@@ -73,31 +74,43 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
die("out of space\n");
ri = &rl->ri;
- rg = &rl->rg;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rl->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rl->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
for (block = 0; block < ri->ri_length; block++) {
- bh = bread(&sdp->nvbuf_list, ri->ri_addr + block);
+ rgbh[block] = bread(&sdp->buf_list, ri->ri_addr + block);
x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+ if (!block)
+ gfs2_rgrp_in(&rg, rgbh[0]->b_data);
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
+ state = (rgbh[block]->b_data[x] >>
+ (GFS2_BIT_SIZE * y)) & 0x03;
if (state == GFS2_BLKST_FREE)
goto found;
bn++;
}
- brelse(bh, FALSE);
+ brelse(rgbh[block], FALSE);
}
die("allocation is broken (1): %"PRIu64" %u\n",
- (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg_free);
found:
if (bn >= ri->ri_bitbytes * GFS2_NBBY)
die("allocation is broken (2): %u %u %"PRIu64" %u\n",
bn, ri->ri_bitbytes * GFS2_NBBY,
- (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg_free);
switch (type) {
case DATA:
@@ -106,24 +119,25 @@ found:
break;
case DINODE:
state = GFS2_BLKST_DINODE;
- rg->rg_dinodes++;
+ rg.rg_dinodes++;
break;
default:
die("bad state\n");
}
- bh->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
- bh->b_data[x] |= state << (GFS2_BIT_SIZE * y);
- rg->rg_free--;
+ rgbh[block]->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
+ rgbh[block]->b_data[x] |= state << (GFS2_BIT_SIZE * y);
+ rg.rg_free--;
+ rl->rg_free--;
- brelse(bh, updated);
+ brelse(rgbh[block], updated);
- bh = bread(&sdp->nvbuf_list, ri->ri_addr);
- gfs2_rgrp_out(rg, bh->b_data);
- brelse(bh, updated);
+ rgbh[0] = bread(&sdp->buf_list, ri->ri_addr);
+ gfs2_rgrp_out(&rg, rgbh[0]->b_data);
+ brelse(rgbh[0], updated);
sdp->blks_alloced++;
-
+ free(rgbh);
return ri->ri_data0 + bn;
}
@@ -945,7 +959,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
*/
static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in,
- struct gfs2_buffer_head **bh_out)
+ struct gfs2_buffer_head **bh_out)
{
struct gfs2_leaf *leaf;
@@ -1581,13 +1595,16 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
{
struct gfs2_buffer_head *bh;
struct rgrp_list *rgd;
+ struct gfs2_rgrp rg;
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
/* Adjust the free space count for the freed block */
rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */
- bh = bget(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the rg buffer */
- rgd->rg.rg_free++; /* adjust the free count */
- gfs2_rgrp_out(&rgd->rg, bh->b_data); /* back to the buffer */
+ bh = bget(&sdp->buf_list, rgd->ri.ri_addr); /* get the rg buffer */
+ gfs2_rgrp_in(&rg, bh->b_data); /* back to the buffer */
+ rg.rg_free++; /* adjust the free count */
+ rgd->rg_free++;
+ gfs2_rgrp_out(&rg, bh->b_data); /* back to the buffer */
brelse(bh, updated); /* release the buffer */
}
@@ -1605,6 +1622,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
uint32_t height;
osi_list_t metalist[GFS2_MAX_META_HEIGHT];
osi_list_t *cur_list, *next_list, *tmp;
+ struct gfs2_rgrp rg;
for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
osi_list_init(&metalist[h]);
@@ -1633,11 +1651,8 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
gfs2_free_block(sdp, block);
if (h == height - 1) /* if not metadata */
continue; /* don't queue it up */
- /* Read the next metadata block in the chain.
- First see if it's on the nvbuf_list. */
- nbh = bfind(&sdp->nvbuf_list, block);
- if (!nbh)
- nbh = bread(&sdp->buf_list, block);
+ /* Read the next metadata block in the chain */
+ nbh = bread(&sdp->buf_list, block);
osi_list_add(&nbh->b_altlist, next_list);
brelse(nbh, not_updated);
}
@@ -1648,13 +1663,12 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
inode_put(ip, updated);
/* Now we have to adjust the rg freespace count and inode count: */
rgd = gfs2_blk2rgrpd(sdp, diblock);
- /* The rg itself is in memory as rgd->rg, but there's most likely a */
- /* buffer in memory for the rg on disk because we used it to fix the */
- /* bitmaps, some of which are on the same block on disk. */
- bh = bread(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the buffer */
- rgd->rg.rg_free++;
- rgd->rg.rg_dinodes--; /* one less inode in use */
- gfs2_rgrp_out(&rgd->rg, bh->b_data);
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr); /* get the buffer */
+ gfs2_rgrp_in(&rg, bh->b_data);
+ rg.rg_free++;
+ rgd->rg_free++;
+ rg.rg_dinodes--; /* one less inode in use */
+ gfs2_rgrp_out(&rg, bh->b_data);
brelse(bh, updated); /* release the buffer */
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 59c4f8f..eb266a5 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -232,7 +232,8 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
*
* Returns: 0 on success, -1 on failure
*/
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks)
{
unsigned int rg;
int error;
@@ -242,6 +243,7 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*count1 = 0;
prev_rgd = NULL;
+ *bitmap_blocks = 0;
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -264,6 +266,8 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
gfs2_rindex_in(&rgd->ri, (char *)&buf);
+ if (rgd->ri.ri_length > *bitmap_blocks)
+ *bitmap_blocks = rgd->ri.ri_length;
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
prev_length = rgd->start - prev_rgd->start;
@@ -297,14 +301,28 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh = NULL;
+ int bitmap_blocks;
- if (gfs1_rindex_read(sdp, fd, &count1))
+ if (gfs1_rindex_read(sdp, fd, &count1, &bitmap_blocks))
goto fail;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
- if (errblock)
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+ if (errblock) {
+ free(rgbh);
return errblock;
+ }
count2++;
if (!quiet && count2 % 100 == 0) {
printf(".");
@@ -316,10 +334,12 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
if (count1 != count2)
goto fail;
+ free(rgbh);
return 0;
fail:
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&sdp->rglist);
+ free(rgbh);
return -1;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index bc2507e..e1a984f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -97,12 +97,10 @@ struct rgrp_list {
osi_list_t list;
uint64_t start; /* The offset of the beginning of this resource group */
uint64_t length; /* The length of this resource group */
- uint32_t rgf_flags;
+ uint32_t rg_free; /* Free blocks */
struct gfs2_rindex ri;
- struct gfs2_rgrp rg;
struct gfs2_bitmap *bits;
- struct gfs2_buffer_head **bh;
};
struct gfs2_buffer_head {
@@ -244,7 +242,6 @@ struct gfs2_sbd {
unsigned int orig_journals;
struct buf_list buf_list; /* transient buffer list */
- struct buf_list nvbuf_list; /* non-volatile buffer list */
struct gfs2_inode *master_dir;
struct master_dir md;
@@ -346,15 +343,8 @@ struct gfs2_block_query {
uint8_t eattr_block;
};
-struct gfs2_gbmap {
- struct gfs2_bmap group_map;
- struct gfs2_bmap bad_map;
- struct gfs2_bmap dup_map;
- struct gfs2_bmap eattr_map;
-};
-
union gfs2_block_lists {
- struct gfs2_gbmap gbmap;
+ struct gfs2_bmap gbmap;
};
/* bitmap implementation */
@@ -564,7 +554,8 @@ extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
uint64_t *dblock, uint32_t *extlen, int prealloc);
extern int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
-extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks);
extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
@@ -673,9 +664,12 @@ extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
/* rgrp.c */
extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated);
-extern void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags updated);
+extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ struct gfs2_buffer_head **bh,
+ struct gfs2_rgrp *rg);
+extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated,
+ struct gfs2_buffer_head **bh);
+extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
@@ -690,14 +684,16 @@ extern int build_root(struct gfs2_sbd *sdp);
extern int do_init_inum(struct gfs2_sbd *sdp);
extern int do_init_statfs(struct gfs2_sbd *sdp);
extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
-extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
+extern int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *block, int first);
extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
uint64_t *block, uint32_t type, int first);
/* super.c */
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
extern int ji_update(struct gfs2_sbd *sdp);
-extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks);
extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index fc548d1..21c7033 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -72,14 +72,6 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
return -1;
- if (rgd->bh) /* If we already have a bh allocated */
- return 0; /* don't want to allocate another */
- if(!(rgd->bh = (struct gfs2_buffer_head **)
- malloc(length * sizeof(struct gfs2_buffer_head *))))
- return -1;
- if(!memset(rgd->bh, 0, length * sizeof(struct gfs2_buffer_head *)))
- return -1;
-
return 0;
}
@@ -114,51 +106,47 @@ struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
* @rgd - resource group structure
* returns: 0 if no error, otherwise the block number that failed
*/
-uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
+uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++){
- rgd->bh[x] = bread(&sdp->nvbuf_list, rgd->ri.ri_addr + x);
- if(gfs2_check_meta(rgd->bh[x],
+ bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ if(gfs2_check_meta(bh[x],
(x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
uint64_t error;
error = rgd->ri.ri_addr + x;
for (; x >= 0; x--)
- brelse(rgd->bh[x], not_updated);
+ brelse(bh[x], not_updated);
return error;
}
}
- gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data);
+ gfs2_rgrp_in(rg, bh[0]->b_data);
+ rgd->rg_free = rg->rg_free;
return 0;
}
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated)
+void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated,
+ struct gfs2_buffer_head **bh)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++)
- brelse(rgd->bh[x], is_updated);
+ brelse(bh[x], is_updated);
}
-void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags is_updated)
+void gfs2_rgrp_free(osi_list_t *rglist)
{
struct rgrp_list *rgd;
while(!osi_list_empty(rglist->next)){
rgd = osi_list_entry(rglist->next, struct rgrp_list, list);
- if (rgd->bh && rgd->bh[0] && /* if a buffer exists and */
- rgd->bh[0]->b_count) /* the 1st buffer is allocated */
- gfs2_rgrp_relse(rgd, is_updated); /* free them all. */
if(rgd->bits)
free(rgd->bits);
- if(rgd->bh) {
- free(rgd->bh);
- rgd->bh = NULL;
- }
osi_list_del(&rgd->list);
free(rgd);
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 8e9ad86..97c56b8 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -441,12 +441,14 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
*
* Returns: 0 on success, -1 when finished
*/
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *block, int first)
{
struct gfs2_bitmap *bits = NULL;
uint32_t length = rgd->ri.ri_length;
uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0);
int i;
+ struct gfs2_buffer_head *bh;
if(!first && (*block < rgd->ri.ri_data0)) {
log_err("next_rg_meta: Start block is outside rgrp bounds.\n");
@@ -460,14 +462,17 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
}
for(; i < length; i++){
bits = &rgd->bits[i];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)bh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_DINODE);
if(blk != BFITNOENT){
*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+ brelse(bh, not_updated);
break;
}
blk=0;
+ brelse(bh, not_updated);
}
if(i == length)
return -1;
@@ -484,14 +489,14 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
* Returns: 0 on success, -1 on error or finished
*/
int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
- uint64_t *block, uint32_t type, int first)
+ uint64_t *block, uint32_t type, int first)
{
struct gfs2_buffer_head *bh = NULL;
do{
if (bh)
brelse(bh, not_updated);
- if (gfs2_next_rg_meta(rgd, block, first))
+ if (gfs2_next_rg_meta(sdp, rgd, block, first))
return -1;
bh = bread(&sdp->buf_list, *block);
first = 0;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index ba3af34..7aeeaa7 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -162,7 +162,7 @@ int ji_update(struct gfs2_sbd *sdp)
*
* Returns: 0 on success, -1 on failure
*/
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
{
unsigned int rg;
int error;
@@ -172,6 +172,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*count1 = 0;
prev_rgd = NULL;
+ *bitmap_blocks = 0;
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -194,6 +195,8 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
gfs2_rindex_in(&rgd->ri, (char *)&buf);
+ if (rgd->ri.ri_length > *bitmap_blocks)
+ *bitmap_blocks = rgd->ri.ri_length;
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
prev_length = rgd->start - prev_rgd->start;
@@ -228,19 +231,33 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh = NULL;
+ int bitmap_blocks;
- if (rindex_read(sdp, fd, &count1))
+ if (rindex_read(sdp, fd, &count1, &bitmap_blocks))
goto fail;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
enum update_flags f;
f = not_updated;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
- if (errblock)
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+ if (errblock) {
+ free(rgbh);
return errblock;
- else
- gfs2_rgrp_relse(rgd, f);
+ } else
+ gfs2_rgrp_relse(rgd, f, rgbh);
count2++;
}
@@ -248,10 +265,12 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
if (count1 != count2)
goto fail;
+ free(rgbh);
return 0;
fail:
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&sdp->rglist);
+ free(rgbh);
return -1;
}
@@ -263,7 +282,6 @@ int write_sb(struct gfs2_sbd *sbp)
gfs2_sb_out(&sbp->sd_sb, bh->b_data);
brelse(bh, updated);
bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
- bcommit(&sbp->nvbuf_list); /* make sure the change gets to disk ASAP */
return 0;
}
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index a3f6e47..10d9731 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -175,7 +175,6 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
/* We're done with the libgfs portion, so commit it to disk. */
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
}
/**
@@ -287,8 +286,7 @@ main_grow(int argc, char *argv[])
}
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sdp->bsize = sdp->sd_sb.sb_bsize;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 4c1d94f..cb6a3cc 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -561,8 +561,7 @@ void main_mkfs(int argc, char *argv[])
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
sdp->time = time(NULL);
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
decode_arguments(argc, argv, sdp);
if (sdp->rgsize == -1) /* if rg size not specified */
@@ -643,7 +642,6 @@ void main_mkfs(int argc, char *argv[])
inode_put(sdp->md.inum, updated);
inode_put(sdp->md.statfs, updated);
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
error = fsync(sdp->device_fd);
if (error)
14 years, 3 months
gfs2-utils: master - Fix white space errors
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 19090ba9509385c218366d01465174a27d543466
Parent: af5fb68fd577aa089a343c75c46387b2b33abe6e
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 26 14:11:52 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:53 2010 -0600
Fix white space errors
This patch cleans up some whitespace issues with the previous 57 patches.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 2 +-
gfs2/fsck/lost_n_found.c | 2 +-
gfs2/fsck/metawalk.c | 4 ++--
gfs2/fsck/pass1.c | 4 ++--
gfs2/fsck/pass1b.c | 3 +--
gfs2/fsck/pass2.c | 2 +-
gfs2/fsck/util.c | 2 +-
gfs2/include/osi_tree.h | 4 ++--
gfs2/libgfs2/gfs2_log.c | 6 +++---
9 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 7d4e5d9..046c9da 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -418,7 +418,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_inode *ip)
int error = 0, di_height;
struct blocklist blocks, *blk, *newblk;
struct metapath gfs2mp;
- struct gfs2_buffer_head *dibh = ip->i_bh;
+ struct gfs2_buffer_head *dibh = ip->i_bh;
/* if there are no indirect blocks to check */
if (ip->i_di.di_height <= 1)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 28e5ca1..991c289 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -175,7 +175,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
reprocess_inode(lf_dip, "lost+found");
/* This inode is linked from lost+found */
- increment_link(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
+ increment_link(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
_("from lost+found"));
/* If it's a directory, lost+found is back-linked to it via .. */
if(S_ISDIR(ip->i_di.di_mode))
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index da37f61..d6ec4c5 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1221,8 +1221,8 @@ fail:
* This does not include "data" blocks that are really
* hash table blocks for directories.
*
- * @ip:
- *
+ * @ip:
+ *
* returns: +ENOENT if there are too many bad pointers
* -1 if a more serious error occurred.
* 0 if no errors occurred
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3ac0c06..a2a2188 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -146,7 +146,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
log_err( _("Found duplicate block %llu (0x%llx) referenced "
"as metadata in indirect block for dinode "
"%llu (0x%llx) - was marked %d (%s)\n"),
- (unsigned long long)block,
+ (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, q,
@@ -209,7 +209,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
log_err( _("Reversing duplicate status of block %llu (0x%llx) "
"referenced as metadata in indirect block for "
"dinode %llu (0x%llx)\n"),
- (unsigned long long)block,
+ (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);
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 8b81d24..29f98e0 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -535,7 +535,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
log_inode_reference(b, tmp, 1);
osi_list_foreach(tmp, &b->ref_inode_list)
log_inode_reference(b, tmp, 0);
-
+
last_reference = clear_a_reference(sbp, b, &b->ref_invinode_list,
&dh, 1);
if (!last_reference)
@@ -592,7 +592,6 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
log_debug( _("All duplicate references were resolved.\n"));
}
return 0;
-
}
/* Pass 1b handles finding the previous inode for a duplicate block
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index f98b007..dc7c91d 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -229,7 +229,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Bad directory entry deleted.\n"));
return 1;
}
-
+
calculated_hash = gfs2_disk_hash(tmp_name, de->de_name_len);
if (de->de_hash != calculated_hash){
log_err( _("Dir entry with bad hash or name length\n"
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 8bd1728..577dba9 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -129,7 +129,7 @@ int fsck_query(const char *format, ...)
errors_corrected++;
ret = 1;
break;
- } else if (tolower(response) == 'n') {
+ } else if (tolower(response) == 'n') {
ret = 0;
break;
} else {
diff --git a/gfs2/include/osi_tree.h b/gfs2/include/osi_tree.h
index 4ffae94..f0d0768 100644
--- a/gfs2/include/osi_tree.h
+++ b/gfs2/include/osi_tree.h
@@ -329,7 +329,7 @@ static inline struct osi_node *osi_next(struct osi_node *node)
/* If we have a right-hand child, go down and then left as far
as we can. */
if (node->osi_right) {
- node = node->osi_right;
+ node = node->osi_right;
while (node->osi_left)
node=node->osi_left;
return node;
@@ -354,7 +354,7 @@ static inline struct osi_node *osi_prev(struct osi_node *node)
/* If we have a left-hand child, go down and then right as far
as we can. */
if (node->osi_left) {
- node = node->osi_left;
+ node = node->osi_left;
while (node->osi_right)
node=node->osi_right;
return node;
diff --git a/gfs2/libgfs2/gfs2_log.c b/gfs2/libgfs2/gfs2_log.c
index caa08a3..a693e82 100644
--- a/gfs2/libgfs2/gfs2_log.c
+++ b/gfs2/libgfs2/gfs2_log.c
@@ -178,9 +178,9 @@ int gfs2_query(int *setonabort, struct gfs2_options *opts,
}
printf("Continuing.\n");
} else if(tolower(response) == 'y') {
- ret = 1;
- break;
- } else if (tolower(response) == 'n') {
+ ret = 1;
+ break;
+ } else if (tolower(response) == 'n') {
ret = 0;
break;
} else {
14 years, 3 months
gfs2-utils: master - fsck.gfs2: If journal replay fails, give option to reinitialize journal
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: af5fb68fd577aa089a343c75c46387b2b33abe6e
Parent: ceef74fb4c29ffa8d8ec48a7d5122ca8f07d2a57
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 17:07:34 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:53 2010 -0600
fsck.gfs2: If journal replay fails, give option to reinitialize journal
When fsck.gfs2 finds a dirty journal, it tries (with permission) to
replay the journal. However, if replaying the journal fails, the
user is left with no recourse. Their file system is now useless.
This patch gives them the option to reinitialize the journal that
failed, thereby allowing them the ability to mount it again.
rhbz#455300
---
gfs2/fsck/fs_recovery.c | 67 +++++++++++++++++++++++++---------------------
1 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 5b9c1b1..89e43be 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -506,42 +506,47 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
error = FSCK_ERROR;
goto out;
}
- if (query( _("\nJournal #%d (\"journal%d\") is dirty. Okay to "
- "replay it? (y/n)"), j+1, j)) {
- log_info( _("jid=%u: Replaying journal...\n"), j);
-
- sd_found_jblocks = sd_replayed_jblocks = 0;
- sd_found_metablocks = sd_replayed_metablocks = 0;
- sd_found_revokes = 0;
- sd_replay_tail = head.lh_tail;
- for (pass = 0; pass < 2; pass++) {
- error = foreach_descriptor(ip, head.lh_tail,
- head.lh_blkno, pass);
- if (error)
- goto out;
- }
- log_info( _("jid=%u: Found %u revoke tags\n"), j,
- sd_found_revokes);
- gfs2_revoke_clean(sdp);
- error = clean_journal(ip, &head);
+ if (!query( _("\nJournal #%d (\"journal%d\") is dirty. Okay to "
+ "replay it? (y/n)"), j+1, j))
+ goto reinit;
+
+ log_info( _("jid=%u: Replaying journal...\n"), j);
+
+ sd_found_jblocks = sd_replayed_jblocks = 0;
+ sd_found_metablocks = sd_replayed_metablocks = 0;
+ sd_found_revokes = 0;
+ sd_replay_tail = head.lh_tail;
+ for (pass = 0; pass < 2; pass++) {
+ error = foreach_descriptor(ip, head.lh_tail,
+ head.lh_blkno, pass);
if (error)
goto out;
- log_err( _("jid=%u: Replayed %u of %u journaled data blocks\n"),
- j, sd_replayed_jblocks, sd_found_jblocks);
- log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
- j, sd_replayed_metablocks, sd_found_metablocks);
- } else {
- if (query( _("Do you want to clear the dirty journal instead? (y/n)"))) {
- write_journal(sdp, sdp->md.journal[j], j,
- sdp->md.journal[j]->i_di.di_size /
- sdp->sd_sb.sb_bsize);
-
- } else
- log_err( _("jid=%u: Dirty journal not replayed or cleared.\n"), j);
}
+ log_info( _("jid=%u: Found %u revoke tags\n"), j, sd_found_revokes);
+ gfs2_revoke_clean(sdp);
+ error = clean_journal(ip, &head);
+ if (error)
+ goto out;
+ log_err( _("jid=%u: Replayed %u of %u journaled data blocks\n"),
+ j, sd_replayed_jblocks, sd_found_jblocks);
+ log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
+ j, sd_replayed_metablocks, sd_found_metablocks);
+ /* Check for errors and give them the option to reinitialize the
+ journal. */
out:
- log_info( _("jid=%u: %s\n"), j, (error) ? _("Failed") : _("Done"));
+ if (!error) {
+ log_info( _("jid=%u: Done\n"), j);
+ return 0;
+ }
+ log_info( _("jid=%u: Failed\n"), j);
+reinit:
+ if (query( _("Do you want to clear the journal instead? (y/n)")))
+ error = write_journal(sdp, sdp->md.journal[j], j,
+ sdp->md.journal[j]->i_di.di_size /
+ sdp->sd_sb.sb_bsize);
+ else
+ log_err( _("jid=%u: journal not cleared.\n"), j);
return error;
}
14 years, 3 months
gfs2-utils: master - Misc cleanups
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: ceef74fb4c29ffa8d8ec48a7d5122ca8f07d2a57
Parent: 1aed3a973bb72e29e9d9d6cc0d1c26060db8080a
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 17:02:45 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600
Misc cleanups
This is a collection of benign cleanups.
rhbz#455300
---
gfs2/fsck/pass1.c | 8 ++++----
gfs2/fsck/pass2.c | 4 ++--
gfs2/libgfs2/block_list.c | 16 ----------------
gfs2/libgfs2/fs_ops.c | 9 ++++-----
gfs2/libgfs2/libgfs2.h | 6 ------
5 files changed, 10 insertions(+), 33 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3343fed..3ac0c06 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -445,7 +445,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
if(gfs2_check_range(sdp, indirect)) {
/*log_warn("EA indirect block #%"PRIu64" is out of range.\n",
indirect);
- gfs2_blockmap_set(bl, parent, bad_block);*/
+ fsck_blockmap_set(parent, "bad", bad_block);*/
/* Doesn't help to mark this here - this gets checked
* in pass1c */
return 1;
@@ -1016,7 +1016,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
if (S_ISDIR(ip->i_di.di_mode) &&
(ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
if (((1 << ip->i_di.di_depth) * sizeof(uint64_t)) != ip->i_di.di_size){
- log_warn( _("Directory dinode #%llu (0x%llx"
+ log_warn( _("Directory dinode block #%llu (0x%llx"
") has bad depth. Found %u, Expected %u\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -1144,8 +1144,8 @@ int pass1(struct gfs2_sbd *sbp)
log_debug( _("rgrp block %lld (0x%llx) "
"is now marked as 'rgrp data'\n"),
rgd->ri.ri_addr + i, rgd->ri.ri_addr + i);
- if(gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
- gfs2_meta_rgrp)){
+ if (gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
+ gfs2_meta_rgrp)) {
stack;
return FSCK_ERROR;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 53422e8..f98b007 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -286,8 +286,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
q, q == gfs2_inode_invalid ?
- _("previously marked invalid") :
- _("is not an inode"));
+ _("was previously marked invalid") :
+ _("was deleted or is not an inode"));
if(!query( _("Clear directory entry to non-inode block? "
"(y/n) "))) {
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 9d2d08a..9c5ad3b 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -111,22 +111,6 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
}
}
-/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
- uint64_t block, enum gfs2_mark_block mark)
-{
- static unsigned char *byte;
- static uint64_t b;
-
- if(block > bmap->size)
- return -1;
-
- byte = bmap->map + BLOCKMAP_SIZE4(block);
- b = BLOCKMAP_BYTE_OFFSET4(block);
- *byte &= ~(BLOCKMAP_MASK4 << b);
- return 0;
-}
-
int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
enum gfs2_mark_block mark)
{
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 81637c2..56cd4c4 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -709,7 +709,7 @@ int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
bh_end = bh->b_data + dip->i_sbd->bsize;
cur_rec_len = be16_to_cpu((*dent)->de_rec_len);
- if ((char *)(*dent) + cur_rec_len >= bh_end)
+ if (cur_rec_len == 0 || (char *)(*dent) + cur_rec_len >= bh_end)
return -ENOENT;
*dent = (struct gfs2_dirent *)((char *)(*dent) + cur_rec_len);
@@ -1407,7 +1407,6 @@ static int leaf_search(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
int len, struct gfs2_dirent **dent_out,
- struct gfs2_dirent **dent_prev,
struct gfs2_buffer_head **bh_out)
{
struct gfs2_buffer_head *bh = NULL, *bh_next;
@@ -1434,8 +1433,8 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
brelse(bh);
bh = bh_next;
-
- error = leaf_search(dip, bh, filename, len, dent_out, dent_prev);
+
+ error = leaf_search(dip, bh, filename, len, dent_out, NULL);
switch (error){
case 0:
*bh_out = bh;
@@ -1474,7 +1473,7 @@ static int dir_e_search(struct gfs2_inode *dip, const char *filename,
struct gfs2_dirent *dent;
int error;
- error = linked_leaf_search(dip, filename, len, &dent, NULL, &bh);
+ error = linked_leaf_search(dip, filename, len, &dent, &bh);
if (error)
return error;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 0e7e1b4..c4675f7 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -351,12 +351,6 @@ extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
enum gfs2_mark_block mark);
extern void gfs2_special_clear(struct special_blocks *blocklist,
uint64_t block);
-/* gfs2_block_unmark clears ONE mark for the given block */
-extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, enum gfs2_mark_block m);
-/* gfs2_block_clear clears all the marks for the given block */
-extern int gfs2_blockmap_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block);
extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
14 years, 3 months
gfs2-utils: master - fsck.gfs2: Free, don't invalidate, dinodes with bad depth
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 1aed3a973bb72e29e9d9d6cc0d1c26060db8080a
Parent: c73635bba7d4f1aab558dab181b311f1cc32a475
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 14:58:36 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600
fsck.gfs2: Free, don't invalidate, dinodes with bad depth
This patch makes fsck.gfs2 free up dinodes with an invalid depth
rather than marking them invalid. If we mark them invalid, the
invalid depth itself will confuse the code that later tries to free
the metadata associated with the bad dinode.
rhbz#455300
---
gfs2/fsck/pass1.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 1d33bd3..3343fed 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1023,7 +1023,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
ip->i_di.di_depth,
(1 >> (ip->i_di.di_size/sizeof(uint64_t))));
if(fsck_blockmap_set(ip, block, _("bad depth"),
- gfs2_meta_inval)) {
+ gfs2_block_free)) {
stack;
fsck_inode_put(&ip);
return -1;
14 years, 3 months
gfs2-utils: master - fsck.gfs2: small parameter passing optimization
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: c73635bba7d4f1aab558dab181b311f1cc32a475
Parent: 966e6ce68492ca770a73171db2f97e246dacb959
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 14:54:39 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600
fsck.gfs2: small parameter passing optimization
This patch is a small optimization in a very often-used function,
done for performance purposes. Function handle_di in pass1 derives
the block number from the buffer already passed in rather than
having the block number passed in as well, and wasting time
pushing it to the stack and off the stack.
rhbz#455300
---
gfs2/fsck/pass1.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index bb56487..1d33bd3 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -867,13 +867,13 @@ struct metawalk_fxns rangecheck_fxns = {
.check_eattr_leaf = rangecheck_eattr_leaf,
};
-static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
- uint64_t block)
+static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
{
uint8_t q;
struct gfs2_inode *ip;
int error;
struct block_count bc = {0};
+ uint64_t block = bh->b_blocknr;
long bad_pointers;
q = block_type(block);
@@ -1192,7 +1192,7 @@ int pass1(struct gfs2_sbd *sbp)
}
check_n_fix_bitmap(sbp, block,
gfs2_block_free);
- } else if (handle_di(sbp, bh, block) < 0) {
+ } else if (handle_di(sbp, bh) < 0) {
stack;
brelse(bh);
return FSCK_ERROR;
14 years, 3 months
gfs2-utils: master - fsck.gfs2: Don't add extended attrib blocks to list twice
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 966e6ce68492ca770a73171db2f97e246dacb959
Parent: 5ae8a4155e3a4d19b2e9f46367d855ca998396fb
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 14:43:14 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600
fsck.gfs2: Don't add extended attrib blocks to list twice
This patch adds a simple check to pass1 where it is adding a
block to the list of blocks that contain an extended attribute.
If the block is already on the list, no need to add it again.
This can sometimes happen in duplicate reference situations and
other obscure code paths.
Since pass1 processes the file system sequentially by block number
it's enough to check against the block most recently added to the
list. This is a performance increase; early versions of this
code ran the entire linked list of special blocks. If the file
system was labelled for selinux, it could have millions of entries
on the linked list, causing an enormous slowdown.
rhbz#455300
---
gfs2/fsck/pass1.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ee6a1fc..bb56487 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -496,6 +496,8 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private)
{
struct block_count *bc = (struct block_count *) private;
+ osi_list_t *head;
+ struct special_blocks *b = NULL;
if (leaf_pointer_errors == leaf_pointers) /* All eas were bad */
return ask_remove_inode_eattr(ip, bc);
@@ -504,8 +506,17 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
/* Mark the inode as having an eattr in the block map
- so pass1c can check it. */
- gfs2_special_add(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr);
+ so pass1c can check it. We may have previously added this inode
+ to the eattr_blocks list and if we did, it would be the first
+ one on the list. So check that one only (to save time) and
+ if that one matches, no need to add it again. */
+ if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
+ head = &ip->i_sbd->eattr_blocks.list;
+ b = osi_list_entry(head->next, struct special_blocks, list);
+ }
+ if (!b || b->block != ip->i_di.di_num.no_addr)
+ gfs2_special_add(&ip->i_sbd->eattr_blocks,
+ ip->i_di.di_num.no_addr);
if (!leaf_pointer_errors)
return 0;
log_err( _("Inode %lld (0x%llx) has recoverable indirect "
@@ -626,6 +637,8 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
void *private)
{
struct gfs2_sbd *sdp = ip->i_sbd;
+ osi_list_t *head;
+ struct special_blocks *b = NULL;
/* This inode contains an eattr - it may be invalid, but the
* eattr attributes points to a non-zero block.
@@ -636,8 +649,13 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
"block(s) attached.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
- if(gfs2_check_range(sdp, block)) {
+ if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
+ head = &ip->i_sbd->eattr_blocks.list;
+ b = osi_list_entry(head->next, struct special_blocks, list);
+ }
+ if (!b || b->block != ip->i_di.di_num.no_addr)
+ gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
+ if (gfs2_check_range(sdp, block)) {
log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
"block #%llu (0x%llx) is out of range.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
14 years, 3 months
gfs2-utils: master - fsck.gfs2: Free metadata list memory we don't need
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 5ae8a4155e3a4d19b2e9f46367d855ca998396fb
Parent: 068146012317eb0d34488c59bd36b9218b91eb1b
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Jan 25 14:34:16 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 15:09:52 2010 -0600
fsck.gfs2: Free metadata list memory we don't need
This patch modifies function check_metatree so that it frees up
metadata from memory for heights it's no longer interested in.
This patches a memory leak.
rhbz#455300
---
gfs2/fsck/metawalk.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index a7871f1..da37f61 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1300,6 +1300,21 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
return error;
}
+ /* Free the metalist buffers from heights we don't need to check.
+ For the rest we'll free as we check them to save time.
+ metalist[0] will only have the dinode bh, so we can skip it. */
+ for (i = 1; i < height - 1; i++) {
+ list = &metalist[i];
+ while (!osi_list_empty(list)) {
+ bh = osi_list_entry(list->next,
+ struct gfs2_buffer_head, b_altlist);
+ if (bh == ip->i_bh)
+ osi_list_del(&bh->b_altlist);
+ else
+ brelse(bh);
+ }
+ }
+
/* check data blocks */
list = &metalist[height - 1];
if (ip->i_di.di_blocks > COMFORTABLE_BLKS)
14 years, 3 months