cluster: RHEL6 - fsck.gfs2: Don't use strerror for libgfs2 errors
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 44ccc7c3c3ec6439bbdae51873c5e180fdb72d10
Parent: f6c1b3a38d2b0824d6a7fbe888852835000add96
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Jan 12 14:29:19 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Don't use strerror for libgfs2 errors
This patch removes the calls to strerror from initialize.c.
The errors returned by libgfs2 currently don't conform to system
errors. For example, they can return positive or negative numbers.
Therefore, strerror could segfault or give nonsense messages.
I hate numeric error messages as much as the next guy, but using
strerror won't work until we systematically go through libgfs2 and
make all the return codes conform to the rules strerror lives by.
rhbz#675723
---
gfs2/fsck/initialize.c | 14 ++++++--------
gfs2/fsck/lost_n_found.c | 4 ++--
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 7171cdd..7b47374 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -464,8 +464,8 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
err = build_per_node(sdp);
if (err) {
- log_crit(_("Error rebuilding per_node directory: %s\n"),
- strerror(err));
+ log_crit(_("Error %d rebuilding per_node directory\n"),
+ err);
exit(FSCK_ERROR);
}
}
@@ -577,8 +577,8 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
err = build_inum(sdp);
if (err) {
- log_crit(_("Error rebuilding inum inode: %s\n"),
- strerror(err));
+ log_crit(_("Error %d rebuilding inum inode\n"),
+ err);
exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "inum", 4,
@@ -609,8 +609,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
err = build_statfs(sdp);
if (err) {
- log_crit(_("Error rebuilding statfs inode: %s\n"),
- strerror(err));
+ log_crit(_("Error %d rebuilding statfs inode\n"), err);
exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
@@ -646,8 +645,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
err = build_quota(sdp);
if (err) {
- log_crit(_("Error rebuilding quota inode: %s\n"),
- strerror(err));
+ log_crit(_("Error %d rebuilding quota inode\n"), err);
exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index d109283..70a9181 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -153,8 +153,8 @@ int add_inode_to_lf(struct gfs2_inode *ip){
lf_dip = createi(sdp->md.rooti, "lost+found",
S_IFDIR | 0700, 0);
if (lf_dip == NULL) {
- log_crit(_("Error creating lost+found: %s\n"),
- strerror(errno));
+ log_crit(_("Error %d creating lost+found: %s\n"),
+ errno);
exit(FSCK_ERROR);
}
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: Fix initialization error return codes
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f6c1b3a38d2b0824d6a7fbe888852835000add96
Parent: 5726ffe21e9e5acb228891af0f9bc83dc5e9b82d
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Jan 12 14:18:13 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Fix initialization error return codes
In initialize.c there are several places where it can exit with an error.
These places return with -1 where they should return the standard fsck
error FSCK_ERROR.
rhbz#675723
---
gfs2/fsck/initialize.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 608eb32..7171cdd 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -466,13 +466,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
if (err) {
log_crit(_("Error rebuilding per_node directory: %s\n"),
strerror(err));
- exit(-1);
+ exit(FSCK_ERROR);
}
}
gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
if (!sdp->md.pinode) {
log_err( _("Unable to rebuild per_node; aborting.\n"));
- exit(-1);
+ exit(FSCK_ERROR);
}
}
@@ -579,7 +579,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
if (err) {
log_crit(_("Error rebuilding inum inode: %s\n"),
strerror(err));
- exit(-1);
+ exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "inum", 4,
&sdp->md.inum);
@@ -611,7 +611,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
if (err) {
log_crit(_("Error rebuilding statfs inode: %s\n"),
strerror(err));
- exit(-1);
+ exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
if (!sdp->md.statfs) {
@@ -648,7 +648,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
if (err) {
log_crit(_("Error rebuilding quota inode: %s\n"),
strerror(err));
- exit(-1);
+ exit(FSCK_ERROR);
}
gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
if (!sdp->md.qinode) {
@@ -1156,7 +1156,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
if (compute_constants(sdp)) {
log_crit(_("Bad constants (1)\n"));
- exit(-1);
+ exit(FSCK_ERROR);
}
ret = read_sb(sdp, 1);
if (ret < 0) {
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: Rearrange block types to group all inode types
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 5726ffe21e9e5acb228891af0f9bc83dc5e9b82d
Parent: 180b154c556288e8a3649fef9d830c7453a22437
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Jan 12 13:55:59 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Rearrange block types to group all inode types
This patch rearranges the declares in util.h such that all the inode
types are grouped together. There's a place in fsck.gfs2 that checks
whether a block is an inode by checking the range of block types.
But that's only valid if they are all grouped together. Since a
previous patch put GFS journaled data blocks in the range, they could
mistakenly pass that test and be treated as an inode for that test.
I never saw an error resulting from this mistake, but I'm fixing it
anyway.
rhbz#675723
---
gfs2/fsck/util.h | 22 ++++++++++++----------
1 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 2f74af3..b56fe69 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -40,16 +40,18 @@ enum gfs2_mark_block {
gfs2_block_free = (0x0),
gfs2_block_used = (0x1),
gfs2_indir_blk = (0x2),
+ /* These are inode block types (only): */
gfs2_inode_dir = (0x3),
gfs2_inode_file = (0x4),
gfs2_inode_lnk = (0x5),
gfs2_inode_device = (0x6), /* char or block device */
- gfs2_jdata = (0x7), /* gfs journaled data blocks */
- gfs2_inode_fifo = (0x8),
- gfs2_inode_sock = (0x9),
+ gfs2_inode_fifo = (0x7),
+ gfs2_inode_sock = (0x8),
+ gfs2_inode_invalid = (0x9),
- gfs2_inode_invalid = (0xa),
+ /* misc block types: */
+ gfs2_jdata = (0xa), /* gfs journaled data blocks */
gfs2_meta_inval = (0xb),
gfs2_leaf_blk = (0xc),
gfs2_freemeta = (0xd), /* was: gfs2_meta_rgrp */
@@ -69,11 +71,11 @@ static const inline char *block_type_string(uint8_t q)
"symlink",
"device",
- "journaled data",
"fifo",
"socket",
-
"invalid inode",
+
+ "journaled data",
"invalid meta",
"dir leaf",
"free metadata",
@@ -99,11 +101,11 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
GFS2_BLKST_DINODE, /* symlink */
GFS2_BLKST_DINODE, /* block or char device */
- GFS2_BLKST_USED, /* journaled data */
GFS2_BLKST_DINODE, /* fifo */
GFS2_BLKST_DINODE, /* socket */
-
GFS2_BLKST_FREE, /* invalid inode */
+
+ GFS2_BLKST_USED, /* journaled data */
GFS2_BLKST_FREE, /* invalid meta */
GFS2_BLKST_USED, /* dir leaf */
GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
@@ -119,11 +121,11 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
GFS2_BLKST_DINODE, /* symlink */
GFS2_BLKST_DINODE, /* block or char device */
- GFS2_BLKST_DINODE, /* journaled data */
GFS2_BLKST_DINODE, /* fifo */
GFS2_BLKST_DINODE, /* socket */
-
GFS2_BLKST_FREE, /* invalid inode */
+
+ GFS2_BLKST_DINODE, /* journaled data */
GFS2_BLKST_FREE, /* invalid meta */
GFS2_BLKST_DINODE, /* dir leaf */
GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: Journals not properly checked
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 180b154c556288e8a3649fef9d830c7453a22437
Parent: b3279aedde9440e5fd006981542db2bc91f9d15b
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 17:19:25 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Journals not properly checked
The coverity tool found a problem with the previous set of patches that
led me to discover a problem with how journals were being processed
under the new code. The problem was that the journal index was read
in after journal replay. But journal replay relies upon information
in the jindex. This patch rearranges the initializeation sequence
of fsck.gfs2 so that the journal index and rindex are read in and
processed prior to journal recovery.
rhbz#675723
---
gfs2/fsck/fs_recovery.c | 12 ---
gfs2/fsck/initialize.c | 183 +++++++++++++++++++++++++++++++----------------
2 files changed, 122 insertions(+), 73 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index d3c742a..52303dd 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -572,14 +572,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
sdp->jsize = GFS2_DEFAULT_JSIZE;
- /* Get master dinode */
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
- /* read in the journal index data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
for(i = 0; i < sdp->md.journals; i++) {
if (!sdp->md.journal[i]) {
@@ -608,11 +600,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
*clean_journals += clean;
}
- inode_put(&sdp->md.journal[i]);
}
- inode_put(&sdp->md.jiinode);
- free(sdp->md.journal);
- sdp->md.journal = NULL;
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 95a6a65..608eb32 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -477,18 +477,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
}
/**
- * init_system_inodes
- *
- * Returns: 0 on success, -1 on failure
+ * fetch_rgrps - fetch the resource groups from disk, and check their integrity
*/
-static int init_system_inodes(struct gfs2_sbd *sdp)
+static int fetch_rgrps(struct gfs2_sbd *sdp)
{
- uint64_t inumbuf;
- char *buf;
- struct gfs2_statfs_change sc;
- int rgcount, sane = 1, err = 0;
enum rgindex_trust_level trust_lvl;
- uint64_t addl_mem_needed;
+ int rgcount, sane = 1;
+
const char *level_desc[] = {
_("Checking if all rgrp and rindex values are good"),
_("Checking if rindex values may be easily repaired"),
@@ -503,48 +498,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
_("Too many rgrp misses: rgrps must be unevenly spaced"),
_("Too much damage found: we cannot rebuild this rindex"),
};
-
- /*******************************************************************
- ****************** Initialize important inodes ******************
- *******************************************************************/
-
- log_info( _("Initializing special inodes...\n"));
-
- /* Get root dinode */
- sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
-
- if (sdp->gfs1)
- sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
- if (!sdp->md.riinode) {
- if (query( _("The gfs2 system rindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_rindex(sdp);
- }
-
- /*******************************************************************
- ****************** Fill in journal information ******************
- *******************************************************************/
-
- /* rgrepair requires the journals be read in in order to distinguish
- "real" rgrps from rgrps that are just copies left in journals. */
- if (sdp->gfs1)
- sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
- if (!sdp->md.jiinode) {
- if (query( _("The gfs2 system jindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_jindex(sdp);
- }
-
- /* read in the ji data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
-
/*******************************************************************
******** Validate and read in resource group information ********
*******************************************************************/
@@ -580,6 +533,34 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("%u resource groups found.\n"), rgcount);
check_rgrps_integrity(sdp);
+ return 0;
+}
+
+/**
+ * init_system_inodes
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int init_system_inodes(struct gfs2_sbd *sdp)
+{
+ uint64_t inumbuf = 0;
+ char *buf;
+ struct gfs2_statfs_change sc;
+ uint64_t addl_mem_needed;
+ int err;
+
+ /*******************************************************************
+ ****************** Initialize important inodes ******************
+ *******************************************************************/
+
+ log_info( _("Initializing special inodes...\n"));
+
+ /* Get root dinode */
+ sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
+
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
/*******************************************************************
***************** Initialize more system inodes *****************
@@ -1232,8 +1213,6 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
log_info("Clearing journal %d\n", jnum);
for (seg = 0; seg < ji_nsegment; seg++){
- bh = bget(sdp, lh.lh_first * sdp->bsize);
- memset(bh->b_data, 0, sdp->bsize);
memset(&lh, 0, sizeof(struct gfs_log_header));
lh.lh_header.mh_magic = GFS2_MAGIC;
@@ -1245,6 +1224,8 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
(seg * sbd1->sb_seg_size);
lh.lh_sequence = sequence;
+ bh = bget(sdp, lh.lh_first * sdp->bsize);
+ memset(bh->b_data, 0, sdp->bsize);
gfs_log_header_out(&lh, bh->b_data);
gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK -
sizeof(struct gfs_log_header));
@@ -1269,7 +1250,7 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
- log_err("Clearing GFS journals (this may take a while)");
+ log_err("Clearing GFS journals (this may take a while)\n");
for (i = 0; i < sdp->md.journals; i++) {
gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
sizeof(struct gfs_jindex));
@@ -1284,6 +1265,81 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
}
/**
+ * init_rindex - read in the rindex file
+ */
+static int init_rindex(struct gfs2_sbd *sdp)
+{
+ int err;
+
+ if (sdp->gfs1)
+ sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+
+ if (sdp->md.riinode)
+ return 0;
+
+ if (!query( _("The gfs2 system rindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid rindex.\n"));
+ return -1;
+ }
+ if ((err = build_rindex(sdp))) {
+ log_crit(_("Error %d rebuilding rindex\n"), err);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * init_jindex - read in the rindex file
+ */
+static int init_jindex(struct gfs2_sbd *sdp)
+{
+ /*******************************************************************
+ ****************** Fill in journal information ******************
+ *******************************************************************/
+
+ /* rgrepair requires the journals be read in in order to distinguish
+ "real" rgrps from rgrps that are just copies left in journals. */
+ if (sdp->gfs1)
+ sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+
+ if (!sdp->md.jiinode) {
+ int err;
+
+ if (!query( _("The gfs2 system jindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: cannot proceed without a valid "
+ "jindex file.\n"));
+ return -1;
+ }
+ /* In order to rebuild jindex, we need some valid
+ rgrps in memory. Temporarily read those in. */
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
+
+ err = build_jindex(sdp);
+ /* Free rgrps read in earlier (re-read them later) */
+ gfs2_rgrp_free(&sdp->rgtree);
+ if (err) {
+ log_crit(_("Error %d rebuilding jindex\n"), err);
+ return err;
+ }
+ }
+
+ /* read in the ji data */
+ if (ji_update(sdp)){
+ log_err( _("Unable to read in jindex inode.\n"));
+ return -1;
+ }
+ return 0;
+}
+
+/**
* initialize - initialize superblock pointer
*
*/
@@ -1372,7 +1428,17 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
if (!sdp->gfs1)
lookup_per_node(sdp, 0);
- /* verify various things */
+ /* We need rindex first in case jindex is missing and needs to read
+ in the rgrps before rebuilding it. */
+ if (init_rindex(sdp))
+ return FSCK_ERROR;
+
+ /* We need to read in jindex in order to replay the journals */
+ if (init_jindex(sdp))
+ return FSCK_ERROR;
+
+ /* If GFS, rebuild the journals. If GFS2, replay them. We don't have
+ the smarts to replay GFS1 journals (neither did gfs_fsck). */
if (sdp->gfs1) {
if (reconstruct_journals(sdp))
@@ -1403,7 +1469,7 @@ mount_fail:
return FSCK_USAGE;
}
-static void destroy_sdp(struct gfs2_sbd *sdp)
+void destroy(struct gfs2_sbd *sdp)
{
if (!opts.no) {
if (block_mounters(sdp, 0)) {
@@ -1425,8 +1491,3 @@ static void destroy_sdp(struct gfs2_sbd *sdp)
"caches.\n"));
}
}
-
-void destroy(struct gfs2_sbd *sdp)
-{
- destroy_sdp(sdp);
-}
12 years, 4 months
cluster: RHEL6 - gfs2_edit: Fix memory leaks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: b3279aedde9440e5fd006981542db2bc91f9d15b
Parent: c31b42c143250be89c6fc9817bf52d3293a28a05
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 17:04:36 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
gfs2_edit: Fix memory leaks
This patch plugs a couple memory leaks found by valgrind.
rhbz#675723
---
gfs2/edit/savemeta.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 33f2970..1b9d0a8 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -132,6 +132,7 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
*gstruct_len = sizeof(struct gfs2_dinode);
else
*gstruct_len = sbd.bsize;
+ inode_put(&inode);
break;
case GFS2_METATYPE_IN: /* 5 (indir inode blklst) */
*gstruct_len = sbd.bsize; /*sizeof(struct gfs_indirect);*/
@@ -490,7 +491,10 @@ static void save_inode_data(struct metafd *mfd)
mybh = osi_list_entry(cur_list->next,
struct gfs2_buffer_head,
b_altlist);
- osi_list_del(&mybh->b_altlist);
+ if (mybh == inode->i_bh)
+ osi_list_del(&mybh->b_altlist);
+ else
+ brelse(mybh);
}
}
/* Process directory exhash inodes */
@@ -808,6 +812,8 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
free(savedata);
savemetaclose(&mfd);
close(sbd.device_fd);
+ free(indirect);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(0);
}
@@ -1032,6 +1038,6 @@ void restoremeta(const char *in_fn, const char *out_device,
gzclose(gzfd);
if (!printblocksonly)
close(sbd.device_fd);
-
+ free(indirect);
exit(error);
}
12 years, 4 months
cluster: RHEL6 - libgfs2: Make in-core rgrps use rbtree
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: d0761931cad0ee047d0419edfdf2f1f1b8f9b12b
Parent: 2ad623efab476ba37e24ab014e2a1a7f22262606
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 16:02:26 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
libgfs2: Make in-core rgrps use rbtree
This patch changes the in-core structure used for resource groups
from a linked list to an rbtree.
rhbz#675723
---
gfs2/convert/gfs2_convert.c | 61 ++++++------
gfs2/edit/extended.c | 2 +-
gfs2/edit/hexedit.c | 56 ++++++-----
gfs2/edit/hexedit.h | 4 +-
gfs2/edit/savemeta.c | 26 +++---
gfs2/fsck/initialize.c | 26 +++---
gfs2/fsck/lost_n_found.c | 12 +-
gfs2/fsck/main.c | 9 +-
gfs2/fsck/metawalk.c | 2 +-
gfs2/fsck/pass1.c | 14 ++--
gfs2/fsck/pass5.c | 11 +-
gfs2/fsck/rgrepair.c | 220 ++++++++++++++++---------------------------
gfs2/libgfs2/fs_bits.c | 4 +-
gfs2/libgfs2/fs_geometry.c | 58 ++++++------
gfs2/libgfs2/fs_ops.c | 16 ++--
gfs2/libgfs2/libgfs2.h | 34 ++++---
gfs2/libgfs2/rgrp.c | 78 ++++++++++------
gfs2/libgfs2/structures.c | 26 +++---
gfs2/libgfs2/super.c | 27 ++---
gfs2/mkfs/main_grow.c | 62 +++++++------
gfs2/mkfs/main_mkfs.c | 6 +-
21 files changed, 365 insertions(+), 389 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 43d0093..8ed2c1a 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -168,7 +168,7 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
/* Fixes all unallocated metadata bitmap states (which are */
/* valid in gfs1 but invalid in gfs2). */
/* ------------------------------------------------------------------------- */
-static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
+static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_tree *rg)
{
uint32_t blk;
int x, y;
@@ -196,16 +196,18 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
/* ------------------------------------------------------------------------- */
static int convert_rgs(struct gfs2_sbd *sbp)
{
- struct rgrp_list *rgd;
- osi_list_t *tmp;
+ struct rgrp_tree *rgd;
+ struct osi_node *n, *next = NULL;
struct gfs1_rgrp *rgd1;
int rgs = 0;
/* --------------------------------- */
/* Now convert its rgs into gfs2 rgs */
/* --------------------------------- */
- osi_list_foreach(tmp, &sbp->rglist) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sbp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
+
rgd1 = (struct gfs1_rgrp *)&rgd->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. */
@@ -978,8 +980,8 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
/* ------------------------------------------------------------------------- */
static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_list_t *cdpn_to_fix)
{
- struct rgrp_list *rgd;
- osi_list_t *tmp;
+ struct rgrp_tree *rgd;
+ struct osi_node *n, *next = NULL;
uint64_t block;
struct gfs2_buffer_head *bh;
int first;
@@ -994,9 +996,10 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
/* ---------------------------------------------------------------- */
/* Traverse the resource groups to figure out where the inodes are. */
/* ---------------------------------------------------------------- */
- osi_list_foreach(tmp, &sbp->rglist) {
+ for (n = osi_first(&sbp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
rgs_processed++;
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
first = 1;
while (1) { /* for all inodes in the resource group */
gettimeofday(&tv, NULL);
@@ -1498,7 +1501,7 @@ static int init(struct gfs2_sbd *sbp)
sbp->dinodes_alloced = 0; /* dinodes allocated - total them up later */
sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sbp->bsize = sbp->sd_sb.sb_bsize;
- osi_list_init(&sbp->rglist);
+ sbp->rgtree.osi_node = NULL;
if (compute_constants(sbp)) {
log_crit("Error: Bad constants (1)\n");
exit(-1);
@@ -1726,9 +1729,10 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
int error = 0;
int j, x;
struct gfs1_jindex *jndx;
- struct rgrp_list *rgd, *rgdhigh;
- osi_list_t *tmp;
+ struct rgrp_tree *rgd, *rgdhigh;
+ struct osi_node *n, *next = NULL;
struct gfs2_meta_header mh;
+ uint64_t ri_addr;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
@@ -1746,8 +1750,9 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
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);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
if (rgd->ri.ri_addr < jndx->ji_addr &&
((rgdhigh == NULL) ||
(rgd->ri.ri_addr > rgdhigh->ri.ri_addr)))
@@ -1760,15 +1765,12 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
log_crit("Error: No suitable rg found for journal.\n");
return -1;
}
+ ri_addr = jndx->ji_addr;
/* Allocate a new rgd entry which includes rg and ri. */
+ rgd = rgrp_insert(&sdp->rgtree, ri_addr);
/* convert the gfs1 rgrp into a new gfs2 rgrp */
- rgd = malloc(sizeof(struct rgrp_list));
- if (!rgd) {
- log_crit("Error: unable to allocate memory for rg conversion.\n");
- return -1;
- }
- memset(rgd, 0, sizeof(struct rgrp_list));
- size = jndx->ji_nsegment * be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size);
+ 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;
@@ -1811,9 +1813,6 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
else
gfs2_rgrp_out(&rgd->rg, rgd->bh[x]);
}
- /* 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);
} /* for each journal */
return error;
}/* journ_space_to_rg */
@@ -1989,16 +1988,17 @@ static int check_fit(struct gfs2_sbd *sdp)
/* build_rindex() */
{
- osi_list_t *tmp, *head;
+ struct osi_node *n, *next = NULL;
unsigned int rg_count = 0;
blks_need++; /* creationg of 'rindex' disk inode */
/* find the total # of rindex entries, gives size of rindex inode */
- for (head = &sdp->rglist, tmp = head->next; tmp != head;
- tmp = tmp->next)
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
rg_count++;
- blks_need +=
- total_file_blocks(sdp, rg_count * sizeof(struct gfs2_rindex), 1);
+ }
+ blks_need += total_file_blocks(sdp, rg_count *
+ sizeof(struct gfs2_rindex), 1);
}
/* build_quota() */
blks_need++; /* quota inode block and uid=gid=0 quota - total 1 block */
@@ -2133,6 +2133,7 @@ int main(int argc, char **argv)
/* ---------------------------------------------- */
if (!error) {
int jreduce = 0;
+
/* Now we've got to treat it as a gfs2 file system */
if (compute_constants(&sb2)) {
log_crit("Error: Bad constants (1)\n");
@@ -2191,7 +2192,7 @@ int main(int argc, char **argv)
fsync(sb2.device_fd); /* write the buffers to disk */
/* Now free all the in memory */
- gfs2_rgrp_free(&sb2.rglist);
+ gfs2_rgrp_free(&sb2.rgtree);
log_notice("Committing changes to disk.\n");
fflush(stdout);
/* Set filesystem type in superblock to gfs2. We do this at the */
diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 6326ec3..07c6421 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -661,7 +661,7 @@ int display_extended(void)
return -1;
else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
return -1;
- else if (block_is_rglist()) {
+ else if (block_is_rgtree()) {
if (sbd.gfs1)
tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr);
else
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index a2ccc60..a36f9a3 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1148,7 +1148,7 @@ int display_block_type(int from_restore)
return ret_type;
if (termlines && dmode == HEX_MODE) {
int type;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
rgd = gfs2_blk2rgrpd(&sbd, block);
if (rgd) {
@@ -1467,7 +1467,7 @@ static void rgcount(void)
(unsigned long long)sbd.md.riinode->i_di.di_size /
sizeof(struct gfs2_rindex));
inode_put(&sbd.md.riinode);
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_SUCCESS);
}
@@ -1695,7 +1695,7 @@ static int block_has_extended_info(void)
{
if (has_indirect_blocks() ||
block_is_rindex() ||
- block_is_rglist() ||
+ block_is_rgtree() ||
block_is_jindex() ||
block_is_inum_file() ||
block_is_statfs_file() ||
@@ -1722,7 +1722,7 @@ static void read_superblock(int fd)
sbd.utsize = GFS2_DEFAULT_UTSIZE;
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
sbd.time = time(NULL);
- osi_list_init(&sbd.rglist);
+ sbd.rgtree.osi_node = NULL;
gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */
/* Check to see if this is really gfs1 */
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -2039,7 +2039,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);
+ gfs2_rgrp_free(&sbd.rgtree);
if (print)
exit(0);
return blk;
@@ -2054,16 +2054,17 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
/* ------------------------------------------------------------------------ */
static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int print)
{
+ struct osi_node *n, *next = NULL;
uint64_t blk;
int first = 1, found = 0;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
struct gfs2_rindex *ri;
- osi_list_t *tmp;
blk = 0;
/* Skip the rgs prior to the block we've been given */
- for(tmp = sbd.rglist.next; tmp != &sbd.rglist; tmp = tmp->next){
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sbd.rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
ri = &rgd->ri;
if (first && startblk <= ri->ri_data0) {
startblk = ri->ri_data0;
@@ -2078,12 +2079,13 @@ 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);
+ gfs2_rgrp_free(&sbd.rgtree);
if (print)
exit(-1);
}
- for(; !found && tmp != &sbd.rglist; tmp = tmp->next){
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (; !found && n; n = next){
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
first = 1;
do {
if (gfs2_next_rg_metatype(&sbd, rgd, &blk, metatype,
@@ -2104,7 +2106,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);
+ gfs2_rgrp_free(&sbd.rgtree);
if (print)
exit(0);
return blk;
@@ -2138,7 +2140,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(-1);
}
return blk;
@@ -2439,7 +2441,7 @@ static void find_print_block_type(void)
type = get_block_type(lbh);
print_block_type(tblock, type, "");
brelse(lbh);
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(0);
}
@@ -2450,7 +2452,7 @@ static void find_print_block_rg(int bitmap)
{
uint64_t rblock, rgblock;
int i;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
rblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
if (rblock == sbd.sb_addr)
@@ -2482,7 +2484,7 @@ static void find_print_block_rg(int bitmap)
printf("-1 (block invalid or part of an rgrp).\n");
}
}
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(0);
}
@@ -2493,7 +2495,7 @@ static void find_change_block_alloc(int *newval)
{
uint64_t ablock;
int type;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
if (newval &&
(*newval < GFS2_BLKST_FREE || *newval > GFS2_BLKST_DINODE)) {
@@ -2503,7 +2505,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[sbd.gfs1][i]);
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(-1);
}
ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
@@ -2529,12 +2531,12 @@ static void find_change_block_alloc(int *newval)
}
gfs2_rgrp_relse(rgd);
} else {
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
printf("-1 (block invalid or part of an rgrp).\n");
exit(-1);
}
}
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
if (newval)
fsync(sbd.device_fd);
exit(0);
@@ -3461,7 +3463,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_FAILURE);
}
process_field(argv[i], argv[i + 1]);
@@ -3494,7 +3496,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_FAILURE);
}
if (argv[i][0]=='0' && argv[i][1]=='x')
@@ -3511,7 +3513,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_SUCCESS);
} else if (!strcmp(argv[i], "rg")) {
int rg;
@@ -3520,7 +3522,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_FAILURE);
}
rg = atoi(argv[i]);
@@ -3529,7 +3531,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);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_SUCCESS);
}
}
@@ -3639,6 +3641,6 @@ int main(int argc, char *argv[])
close(fd);
if (indirect)
free(indirect);
- gfs2_rgrp_free(&sbd.rglist);
+ gfs2_rgrp_free(&sbd.rgtree);
exit(EXIT_SUCCESS);
}
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 07125bd..02281cf 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -111,11 +111,11 @@ extern int indirect_blocks; /* count of indirect blocks */
extern enum dsp_mode dmode;
/* ------------------------------------------------------------------------ */
-/* block_is_rglist - there's no such block as the rglist. This is a */
+/* block_is_rgtree - there's no such block as the rglist. This is a */
/* special case meant to parse the rindex and follow the */
/* blocks to the real rgs. */
/* ------------------------------------------------------------------------ */
-static inline int block_is_rglist(void)
+static inline int block_is_rgtree(void)
{
if (block == RGLIST_DUMMY_BLOCK)
return TRUE;
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 8ccbf8a..33f2970 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -587,7 +587,7 @@ static void get_journal_inode_blocks(void)
}
}
-static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
uint64_t *nrfblock, int first)
{
struct gfs2_bitmap *bits = NULL;
@@ -629,11 +629,10 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
void savemeta(char *out_fn, int saveoption, int gziplevel)
{
int slow, ret;
- osi_list_t *tmp;
int rgcount;
uint64_t jindex_block;
struct gfs2_buffer_head *lbh;
- struct rgrp_list *last_rgd, *prev_rgd;
+ struct rgrp_tree *last_rgd, *prev_rgd;
struct metafd mfd;
slow = (saveoption == 1);
@@ -659,7 +658,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
sbd.device.length << GFS2_BASIC_BLOCK_SHIFT);
exit(-1);
}
- osi_list_init(&sbd.rglist);
+ sbd.rgtree.osi_node = NULL;
if (!sbd.gfs1)
sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
if (compute_constants(&sbd)) {
@@ -700,6 +699,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
if (!slow) {
int sane;
uint64_t fssize;
+ struct osi_node *n;
printf("Reading resource groups...");
fflush(stdout);
@@ -707,10 +707,10 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
slow = gfs1_ri_update(&sbd, 0, &rgcount, 0);
else
slow = ri_update(&sbd, 0, &rgcount, &sane);
- last_rgd = osi_list_entry(sbd.rglist.prev,
- struct rgrp_list, list);
- prev_rgd = osi_list_entry(last_rgd->list.prev,
- struct rgrp_list, list);
+ n = osi_last(&sbd.rgtree);
+ last_rgd = (struct rgrp_tree *)n;
+ n = osi_prev(n);
+ prev_rgd = (struct rgrp_tree *)n;
fssize = last_rgd->ri.ri_addr +
(last_rgd->ri.ri_addr - prev_rgd->ri.ri_addr);
last_fs_block = fssize;
@@ -721,6 +721,8 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
}
get_journal_inode_blocks();
if (!slow) {
+ struct osi_node *n, *next = NULL;
+
/* Save off the superblock */
save_block(sbd.device_fd, &mfd, 0x10 * (4096 / sbd.bsize));
/* If this is gfs1, save off the rindex because it's not
@@ -742,12 +744,12 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
}
}
/* Walk through the resource groups saving everything within */
- for (tmp = sbd.rglist.next; tmp != &sbd.rglist;
- tmp = tmp->next){
- struct rgrp_list *rgd;
+ for (n = osi_first(&sbd.rgtree); n; n = next) {
int first;
+ struct rgrp_tree *rgd;
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
slow = gfs2_rgrp_read(&sbd, rgd);
if (slow)
continue;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 75b363b..06121bc 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -108,7 +108,7 @@ static void gfs2_inodetree_free(void)
static void empty_super_block(struct gfs2_sbd *sdp)
{
log_info( _("Freeing buffers.\n"));
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
if (bl)
gfs2_bmap_destroy(sdp, bl);
@@ -129,10 +129,9 @@ static void empty_super_block(struct gfs2_sbd *sdp)
*/
static int set_block_ranges(struct gfs2_sbd *sdp)
{
-
- struct rgrp_list *rgd;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rgd;
struct gfs2_rindex *ri;
- osi_list_t *tmp;
char buf[sdp->sd_sb.sb_bsize];
uint64_t rmax = 0;
uint64_t rmin = 0;
@@ -140,9 +139,9 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
log_info( _("Setting block ranges...\n"));
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next)
- {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
ri = &rgd->ri;
if (ri->ri_data0 + ri->ri_data &&
ri->ri_data0 + ri->ri_data - 1 > rmax)
@@ -188,7 +187,7 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
/**
* check_rgrp_integrity - verify a rgrp free block count against the bitmap
*/
-static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
int *fixit, int *this_rg_fixed,
int *this_rg_bad)
{
@@ -317,17 +316,18 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
*/
static int check_rgrps_integrity(struct gfs2_sbd *sdp)
{
+ struct osi_node *n, *next = NULL;
int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0;
int was_bad = 0, was_fixed = 0, error = 0;
- osi_list_t *tmp;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
int reclaim_unlinked = 0;
log_info( _("Checking the integrity of all resource groups.\n"));
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
if (fsck_abort)
return 0;
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
check_rgrp_integrity(sdp, rgd, &reclaim_unlinked,
&was_fixed, &was_bad);
if (was_fixed)
@@ -1155,7 +1155,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
***************** First, initialize all lists **********************
********************************************************************/
log_info( _("Initializing lists...\n"));
- osi_list_init(&sdp->rglist);
+ sdp->rgtree.osi_node = NULL;
/********************************************************************
************ next, read in on-disk SB and set constants **********
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 16afb11..d109283 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -81,8 +81,8 @@ static void add_dotdot(struct gfs2_inode *ip)
static uint64_t find_free_blk(struct gfs2_sbd *sdp)
{
- osi_list_t *tmp, *head;
- struct rgrp_list *rl = NULL;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rl = NULL;
struct gfs2_rindex *ri;
struct gfs2_rgrp *rg;
unsigned int block, bn = 0, x = 0, y = 0;
@@ -90,14 +90,14 @@ static uint64_t find_free_blk(struct gfs2_sbd *sdp)
struct gfs2_buffer_head *bh;
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);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
if (rl->rg.rg_free)
break;
}
- if (tmp == head)
+ if (n == NULL)
return 0;
ri = &rl->ri;
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 75ccc11..7b768b0 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -147,8 +147,8 @@ static void interrupt(int sig)
static void check_statfs(struct gfs2_sbd *sdp)
{
- osi_list_t *tmp;
- struct rgrp_list *rgd;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rgd;
struct gfs2_rindex *ri;
struct gfs2_statfs_change sc;
char buf[sizeof(struct gfs2_statfs_change)];
@@ -169,8 +169,9 @@ static void check_statfs(struct gfs2_sbd *sdp)
sdp->blks_alloced = 0;
sdp->dinodes_alloced = 0;
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
ri = &rgd->ri;
sdp->blks_total += ri->ri_data;
sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 6ddc936..c313c3b 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -29,7 +29,7 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
enum gfs2_mark_block new_blockmap_state)
{
int old_bitmap_state, new_bitmap_state;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
rgd = gfs2_blk2rgrpd(sdp, blk);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 60e7cce..de5de2b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1531,10 +1531,10 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
*/
int pass1(struct gfs2_sbd *sdp)
{
+ struct osi_node *n, *next = NULL;
struct gfs2_buffer_head *bh;
- osi_list_t *tmp;
uint64_t block;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
int first;
uint64_t i;
uint64_t blk_count;
@@ -1561,11 +1561,11 @@ int pass1(struct gfs2_sbd *sdp)
* uses the rg bitmaps, so maybe that's the best way to start
* things - we can change the method later if necessary.
*/
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist;
- tmp = tmp->next, rg_count++) {
- log_debug( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
- rg_count);
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next, rg_count++) {
+ next = osi_next(n);
+ log_debug( _("Checking metadata in Resource Group #%llu\n"),
+ (unsigned long long)rg_count);
+ rgd = (struct rgrp_tree *)n;
for (i = 0; i < rgd->ri.ri_length; i++) {
log_debug( _("rgrp block %lld (0x%llx) "
"is now marked as 'rgrp data'\n"),
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 3cf420b..ea033a0 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -191,7 +191,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
return 0;
}
-static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
+static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
uint32_t *count)
{
uint32_t i;
@@ -276,18 +276,19 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
*/
int pass5(struct gfs2_sbd *sdp)
{
- osi_list_t *tmp;
- struct rgrp_list *rgp = NULL;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rgp = NULL;
uint32_t count[5];
uint64_t rg_count = 0;
/* Reconcile RG bitmaps with fsck bitmap */
- for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
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);
+ rgp = (struct rgrp_tree *)n;
rg_count++;
/* Compare the bitmaps and report the differences */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 28ed451..c3015b7 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -228,25 +228,25 @@ static uint64_t count_usedspace(struct gfs2_sbd *sdp, int first,
* This function finds the distance to the next rgrp for these cases.
*/
static uint64_t find_next_rgrp_dist(struct gfs2_sbd *sdp, uint64_t blk,
- struct rgrp_list *prevrgd)
+ struct rgrp_tree *prevrgd)
{
+ struct osi_node *n, *next = NULL;
uint64_t rgrp_dist = 0, used_blocks, block, next_block, twogigs;
- osi_list_t *tmp;
- struct rgrp_list *rgd = NULL, *next_rgd;
+ struct rgrp_tree *rgd = NULL, *next_rgd;
struct gfs2_buffer_head *bh;
struct gfs2_meta_header mh;
int first, length, b, found, mega_in_blocks;
uint32_t free_blocks;
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
if (rgd->ri.ri_addr == blk)
break;
}
- if (rgd && tmp && tmp != &sdp->rglist && tmp->next &&
- rgd->ri.ri_addr == blk) {
- tmp = tmp->next;
- next_rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ if (rgd && n && osi_next(n) && rgd->ri.ri_addr == blk) {
+ n = osi_next(n);
+ next_rgd = (struct rgrp_tree *)n;
rgrp_dist = next_rgd->ri.ri_addr - rgd->ri.ri_addr;
return rgrp_dist;
}
@@ -343,7 +343,7 @@ static uint64_t find_next_rgrp_dist(struct gfs2_sbd *sdp, uint64_t blk,
* boundaries, and also corrupt. So we have to go out searching for one.
*/
static uint64_t hunt_and_peck(struct gfs2_sbd *sdp, uint64_t blk,
- struct rgrp_list *prevrgd, uint64_t last_bump)
+ struct rgrp_tree *prevrgd, uint64_t last_bump)
{
uint64_t rgrp_dist = 0, block, twogigs, last_block, last_meg;
struct gfs2_buffer_head *bh;
@@ -428,20 +428,20 @@ static uint64_t hunt_and_peck(struct gfs2_sbd *sdp, uint64_t blk,
* from gfs1 to gfs2 after a gfs_grow operation. In that case, the rgrps
* will not be on predictable boundaries.
*/
-static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
- int *num_rgs, int gfs_grow)
+static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs,
+ int gfs_grow)
{
+ struct osi_node *n, *next = NULL;
struct gfs2_buffer_head *bh;
uint64_t shortest_dist_btwn_rgs;
uint64_t blk;
uint64_t fwd_block, block_bump;
uint64_t first_rg_dist, initial_first_rg_dist;
- struct rgrp_list *calc_rgd, *prev_rgd;
+ struct rgrp_tree *calc_rgd, *prev_rgd;
int number_of_rgs, rgi;
int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd;
- osi_list_t *tmp;
- osi_list_init(ret_list);
+ sdp->rgcalc.osi_node = NULL;
initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1;
shortest_dist_btwn_rgs = find_shortest_rgdist(sdp,
&initial_first_rg_dist,
@@ -460,15 +460,12 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
brelse(bh);
/* Allocate a new RG and index. */
- calc_rgd = malloc(sizeof(struct rgrp_list));
+ calc_rgd = rgrp_insert(&sdp->rgcalc, blk);
if (!calc_rgd) {
log_crit( _("Can't allocate memory for rgrp repair.\n"));
return -1;
}
- memset(calc_rgd, 0, sizeof(struct rgrp_list));
- osi_list_add_prev(&calc_rgd->list, ret_list);
calc_rgd->ri.ri_length = 1;
- calc_rgd->ri.ri_addr = blk;
if (!rg_was_fnd) { /* if not an RG */
/* ------------------------------------------------- */
/* This SHOULD be an RG but isn't. */
@@ -584,9 +581,9 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
/* Now dump out the information (if verbose mode) */
/* ---------------------------------------------- */
log_debug( _("rindex rebuilt as follows:\n"));
- for (tmp = ret_list->next, rgi = 0; tmp != ret_list;
- tmp = tmp->next, rgi++) {
- calc_rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgcalc), rgi = 0; n; n = next, rgi++) {
+ next = osi_next(n);
+ calc_rgd = (struct rgrp_tree *)n;
log_debug("%d: 0x%llx / %x / 0x%llx"
" / 0x%x / 0x%x\n", rgi + 1,
(unsigned long long)calc_rgd->ri.ri_addr,
@@ -611,8 +608,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
* Sets: sdp->rglist to a linked list of fsck_rgrp structs representing
* what we think the rindex should really look like.
*/
-static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
- int *num_rgs)
+static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, int *num_rgs)
{
uint64_t num_rgrps = 0;
@@ -625,7 +621,7 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
/* ----------------------------------------------------------------- */
*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
- osi_list_init(ret_list);
+ sdp->rgcalc.osi_node = NULL;
if (device_geometry(sdp)) {
fprintf(stderr, _("Geometry error\n"));
exit(-1);
@@ -648,16 +644,11 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
}
}
/* Compute the default resource group layout as mkfs would have done */
- compute_rgrp_layout(sdp, TRUE);
+ compute_rgrp_layout(sdp, &sdp->rgcalc, TRUE);
build_rgrps(sdp, FALSE); /* FALSE = calc but don't write to disk. */
log_debug( _("fs_total_size = 0x%" PRIX64 " blocks.\n"),
sdp->device.length);
log_warn( _("L3: number of rgs in the index = %d.\n"), *num_rgs);
- /* Move the rg list to the return list */
- ret_list->next = sdp->rglist.next;
- ret_list->prev = sdp->rglist.prev;
- ret_list->next->prev = ret_list;
- ret_list->prev->next = ret_list;
return 0;
}
@@ -665,8 +656,8 @@ 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_tree *rg,
+ uint64_t errblock)
{
int x = errblock - rg->ri.ri_addr;
const char *typedesc = x ? "GFS2_METATYPE_RB" : "GFS2_METATYPE_RG";
@@ -712,18 +703,16 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
* values as our expected values and assume the
* damage is only to the rgrps themselves.
*/
-static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
- int *num_rgs)
+static int expect_rindex_sanity(struct gfs2_sbd *sdp, int *num_rgs)
{
- osi_list_t *tmp;
- struct rgrp_list *exp, *rgd; /* expected, actual */
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rgd, *exp;
*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex) ;
- osi_list_init(ret_list);
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
-
- exp = calloc(1, sizeof(struct rgrp_list));
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
+ exp = rgrp_insert(&sdp->rgcalc, rgd->ri.ri_addr);
if (exp == NULL) {
fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
exit(-1);
@@ -735,45 +724,12 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
exp->bits = NULL;
exp->bh = NULL;
gfs2_compute_bitstructs(sdp, exp);
- osi_list_add_prev(&exp->list, ret_list);
}
sdp->rgrps = *num_rgs;
return 0;
}
/*
- * sort_rgrp_list - sort the rgrp list
- *
- * A bit crude, perhaps, but we're talking about thousands, not millions of
- * entries to sort, and the list will be almost sorted anyway, so there
- * should be very few swaps.
- */
-static void sort_rgrp_list(osi_list_t *head)
-{
- struct rgrp_list *thisr, *nextr;
- osi_list_t *tmp, *x, *next;
- int swaps;
-
- while (1) {
- swaps = 0;
- osi_list_foreach_safe(tmp, head, x) {
- next = tmp->next;
- if (next == head) /* at the end */
- break;
- thisr = osi_list_entry(tmp, struct rgrp_list, list);
- nextr = osi_list_entry(next, struct rgrp_list, list);
- if (thisr->ri.ri_addr > nextr->ri.ri_addr) {
- osi_list_del(next);
- osi_list_add_prev(next, tmp);
- swaps++;
- }
- }
- if (!swaps)
- break;
- }
-}
-
-/*
* rg_repair - try to repair a damaged rg index (rindex)
* trust_lvl - This is how much we trust the rindex file.
* blind_faith means we take the rindex at face value.
@@ -786,10 +742,9 @@ static void sort_rgrp_list(osi_list_t *head)
*/
int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
{
+ struct osi_node *n, *next = NULL, *e, *enext;
int error, discrepancies, percent;
- osi_list_t expected_rglist;
int calc_rg_count = 0, rgcount_from_index, rg;
- osi_list_t *exp, *act; /* expected, actual */
struct gfs2_rindex buf;
if (trust_lvl == blind_faith)
@@ -803,57 +758,53 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
"expectations.\n"));
return -1;
}
- error = expect_rindex_sanity(sdp, &expected_rglist,
- &calc_rg_count);
+ error = expect_rindex_sanity(sdp, &calc_rg_count);
if (error) {
- gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
return error;
}
} else if (trust_lvl == open_minded) { /* If we can't trust RG index */
/* Free previous incarnations in memory, if any. */
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
/* Calculate our own RG index for comparison */
- error = gfs2_rindex_calculate(sdp, &expected_rglist,
- &calc_rg_count);
+ error = gfs2_rindex_calculate(sdp, &calc_rg_count);
if (error) { /* If calculated RGs don't match the fs */
- gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
return -1;
}
}
else if (trust_lvl == distrust) { /* If we can't trust RG index */
/* Free previous incarnations in memory, if any. */
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
- error = gfs2_rindex_rebuild(sdp, &expected_rglist,
- &calc_rg_count, 0);
+ error = gfs2_rindex_rebuild(sdp, &calc_rg_count, 0);
if (error) {
log_crit( _("Error rebuilding rgrp list.\n"));
- gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
return -1;
}
sdp->rgrps = calc_rg_count;
}
else if (trust_lvl == indignation) { /* If we can't trust anything */
/* Free previous incarnations in memory, if any. */
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
- error = gfs2_rindex_rebuild(sdp, &expected_rglist,
- &calc_rg_count, 1);
+ error = gfs2_rindex_rebuild(sdp, &calc_rg_count, 1);
if (error) {
log_crit( _("Error rebuilding rgrp list.\n"));
- gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
return -1;
}
sdp->rgrps = calc_rg_count;
}
/* Read in the rindex */
- osi_list_init(&sdp->rglist); /* Just to be safe */
+ sdp->rgtree.osi_node = NULL; /* Just to be safe */
rindex_read(sdp, 0, &rgcount_from_index, sane);
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);
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
+ gfs2_rgrp_free(&sdp->rgtree);
return -1;
}
log_warn( _("L%d: number of rgs expected = %lld.\n"), trust_lvl + 1,
@@ -863,20 +814,11 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
"extended, (2) an odd\n"), trust_lvl + 1);
log_warn( _("L%d: rgrp size was used, or (3) we have a corrupt "
"rg index.\n"), trust_lvl + 1);
- gfs2_rgrp_free(&expected_rglist);
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
+ gfs2_rgrp_free(&sdp->rgtree);
return -1;
}
/* ------------------------------------------------------------- */
- /* Sort the rindex list. Older versions of gfs_grow got the */
- /* rindex out of sorted order. But rebuilding the rindex from */
- /* scratch will rebuild it in sorted order. */
- /* The gfs2_grow program should, in theory, drop new rgrps into */
- /* the rindex in sorted order, so this should only matter for */
- /* gfs1 converted file systems. */
- /* ------------------------------------------------------------- */
- sort_rgrp_list(&sdp->rglist);
- /* ------------------------------------------------------------- */
/* Now compare the rindex to what we think it should be. */
/* See how far off our expected values are. If too much, abort. */
/* The theory is: if we calculated the index to have 32 RGs and */
@@ -884,22 +826,24 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
/* abandon this method of recovery and try a better one. */
/* ------------------------------------------------------------- */
discrepancies = 0;
- for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next;
- act != &sdp->rglist && exp != &expected_rglist && !fsck_abort;
- rg++) {
- struct rgrp_list *expected, *actual;
+ for (rg = 0, n = osi_first(&sdp->rgtree), e = osi_first(&sdp->rgcalc);
+ n && e && !fsck_abort; rg++) {
+ struct rgrp_tree *expected, *actual;
+
+ next = osi_next(n);
+ enext = osi_next(e);
- expected = osi_list_entry(exp, struct rgrp_list, list);
- actual = osi_list_entry(act, struct rgrp_list, list);
+ expected = (struct rgrp_tree *)e;
+ actual = (struct rgrp_tree *)n;
if (actual->ri.ri_addr < expected->ri.ri_addr) {
- act = act->next;
+ n = next;
discrepancies++;
log_info(_("%d addr: 0x%llx < 0x%llx * mismatch\n"),
rg + 1, actual->ri.ri_addr,
expected->ri.ri_addr);
continue;
} else if (expected->ri.ri_addr < actual->ri.ri_addr) {
- exp = exp->next;
+ e = enext;
discrepancies++;
log_info(_("%d addr: 0x%llx > 0x%llx * mismatch\n"),
rg + 1, actual->ri.ri_addr,
@@ -915,8 +859,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
rg + 1, actual->ri.ri_addr,
expected->ri.ri_addr);
}
- act = act->next;
- exp = exp->next;
+ n = next;
+ e = enext;
}
if (rg) {
/* Check to see if more than 2% of the rgrps are wrong. */
@@ -927,8 +871,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
log_warn( _("%d out of %d rgrps (%d percent) did not "
"match what was expected.\n"),
discrepancies, rg, percent);
- gfs2_rgrp_free(&expected_rglist);
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
+ gfs2_rgrp_free(&sdp->rgtree);
return -1;
}
}
@@ -937,28 +881,29 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
/* Our rindex should be pretty predictable unless we've grown */
/* so look for index problems first before looking at the rgs. */
/* ------------------------------------------------------------- */
- for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next;
- exp != &expected_rglist && !fsck_abort; rg++) {
- struct rgrp_list *expected, *actual;
+ for (rg = 0, n = osi_first(&sdp->rgtree), e = osi_first(&sdp->rgcalc);
+ e && !fsck_abort; rg++) {
+ struct rgrp_tree *expected, *actual;
- expected = osi_list_entry(exp, struct rgrp_list, list);
+ if (n)
+ next = osi_next(n);
+ enext = osi_next(e);
+ expected = (struct rgrp_tree *)e;
/* If we ran out of actual rindex entries due to rindex
damage, fill in a new one with the expected values. */
- if (act == &sdp->rglist) { /* end of actual rindex */
+ if (!n) { /* end of actual rindex */
log_err( _("Entry missing from rindex: 0x%llx\n"),
(unsigned long long)expected->ri.ri_addr);
- actual = (struct rgrp_list *)
- malloc(sizeof(struct rgrp_list));
+ actual = rgrp_insert(&sdp->rgtree,
+ expected->ri.ri_addr);
if (!actual) {
log_err(_("Out of memory!\n"));
break;
}
- memset(actual, 0, sizeof(struct rgrp_list));
- osi_list_add_prev(&actual->list, &sdp->rglist);
rindex_modified = 1;
} else {
- actual = osi_list_entry(act, struct rgrp_list, list);
+ actual = (struct rgrp_tree *)n;
ri_compare(rg, actual->ri, expected->ri, ri_addr,
"llx");
ri_compare(rg, actual->ri, expected->ri, ri_length,
@@ -997,26 +942,27 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
gfs2_compute_bitstructs(sdp, actual);
rindex_modified = FALSE;
}
- exp = exp->next;
- if (act != &sdp->rglist)
- act = act->next;
+ e = enext;
+ if (n)
+ n = next;
}
/* ------------------------------------------------------------- */
/* Read the real RGs and check their integrity. */
/* Now we can somewhat trust the rindex and the RG addresses, */
/* so let's read them in, check them and optionally fix them. */
/* ------------------------------------------------------------- */
- for (rg = 0, act = sdp->rglist.next; act != &sdp->rglist &&
- !fsck_abort; act = act->next, rg++) {
- struct rgrp_list *rgd;
+ for (rg = 0, n = osi_first(&sdp->rgtree); n && !fsck_abort;
+ n = next, rg++) {
+ struct rgrp_tree *rgd;
uint64_t prev_err = 0, errblock;
int i;
+ next = osi_next(n);
/* 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);
+ rgd = (struct rgrp_tree *)n;
errblock = gfs2_rgrp_read(sdp, rgd);
if (errblock) {
if (errblock == prev_err)
@@ -1031,7 +977,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
} while (i < rgd->ri.ri_length);
}
*rg_count = rg;
- gfs2_rgrp_free(&expected_rglist);
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgcalc);
+ gfs2_rgrp_free(&sdp->rgtree);
return 0;
}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index b39effe..f45aabe 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -175,7 +175,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
int buf;
uint32_t rgrp_block;
struct gfs2_bitmap *bits = NULL;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
unsigned char *byte, cur_state;
unsigned int bit;
@@ -223,7 +223,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
* Returns: state on success, -1 on error
*/
int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
- struct rgrp_list *rgd)
+ struct rgrp_tree *rgd)
{
int i, val;
uint32_t rgrp_block;
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 7c07891..067c5f3 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -72,13 +72,14 @@ uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev, int rgsize_spe
* Returns: a list of rgrp_list_t structures
*/
-void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
+void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
+ int rgsize_specified)
{
struct device *dev;
- struct rgrp_list *rl, *rlast = NULL, *rlast2 = NULL;
- osi_list_t *tmp, *head = &sdp->rglist;
- unsigned int rgrp = 0, nrgrp;
- uint64_t rglength;
+ struct rgrp_tree *rl, *rlast = NULL, *rlast2 = NULL;
+ struct osi_node *n, *next = NULL;
+ unsigned int rgrp = 0, nrgrp, rglength;
+ uint64_t rgaddr;
sdp->new_rgrps = 0;
dev = &sdp->device;
@@ -89,7 +90,7 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
/* If this is a new file system, compute the length and number */
/* of rgs based on the size of the device. */
/* If we have existing RGs (i.e. gfs2_grow) find the last one. */
- if (osi_list_empty(&sdp->rglist)) {
+ if (!rgtree->osi_node) {
dev->length -= sdp->sb_addr + 1;
nrgrp = how_many_rgrps(sdp, dev, rgsize_specified);
rglength = dev->length / nrgrp;
@@ -98,9 +99,10 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
uint64_t old_length, new_chunk;
log_info("Existing resource groups:\n");
- for (rgrp = 0, tmp = head->next; tmp != head;
- tmp = tmp->next, rgrp++) {
- rl = osi_list_entry(tmp, struct rgrp_list, list);
+ for (rgrp = 0, n = osi_first(rgtree); n; n = next, rgrp++) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
+
log_info("%d: start: %" PRIu64 " (0x%"
PRIx64 "), length = %"PRIu64" (0x%"
PRIx64 ")\n", rgrp + 1, rl->start, rl->start,
@@ -120,36 +122,31 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
if (rgrp < nrgrp)
log_info("\nNew resource groups:\n");
for (; rgrp < nrgrp; rgrp++) {
- rl = calloc(1, sizeof(struct rgrp_list));
- if (rl == NULL) {
- fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
- exit(-1);
- }
-
if (rgrp) {
- rl->start = rlast->start + rlast->length;
+ rgaddr = rlast->start + rlast->length;
+ rl = rgrp_insert(rgtree, rgaddr);
rl->length = rglength;
} else {
- rl->start = dev->start;
+ rgaddr = dev->start;
+ rl = rgrp_insert(rgtree, rgaddr);
rl->length = dev->length -
(nrgrp - 1) * (dev->length / nrgrp);
}
-
+ rl->start = rgaddr;
log_info("%d: start: %" PRIu64 " (0x%"
PRIx64 "), length = %"PRIu64" (0x%"
PRIx64 ")\n", rgrp + 1, rl->start, rl->start,
rl->length, rl->length);
- osi_list_add_prev(&rl->list, head);
rlast = rl;
}
sdp->rgrps = nrgrp;
-
if (sdp->debug) {
log_info("\n");
- for (tmp = head->next; tmp != head; tmp = tmp->next) {
- rl = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(rgtree); n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
log_info("rg_o = %llu, rg_l = %llu\n",
(unsigned long long)rl->start,
(unsigned long long)rl->length);
@@ -200,8 +197,8 @@ void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks, uint32_t *bitblo
*/
void build_rgrps(struct gfs2_sbd *sdp, int do_write)
{
- osi_list_t *tmp, *head;
- struct rgrp_list *rl;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rl;
uint32_t rgblocks, bitblocks;
struct gfs2_rindex *ri;
struct gfs2_meta_header mh;
@@ -210,11 +207,14 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
mh.mh_format = GFS2_FORMAT_RB;
-
- for (head = &sdp->rglist, tmp = head->next;
- tmp != head;
- tmp = tmp->next) {
- rl = osi_list_entry(tmp, struct rgrp_list, list);
+ if (do_write)
+ n = osi_first(&sdp->rgtree);
+ else
+ n = osi_first(&sdp->rgcalc);
+
+ for (; n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
ri = &rl->ri;
rgblocks = rl->length;
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 0163371..5053c90 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -114,8 +114,8 @@ void inode_put(struct gfs2_inode **ip_in)
static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
{
- osi_list_t *tmp, *head;
- struct rgrp_list *rl = NULL;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rl = NULL;
struct gfs2_rindex *ri;
struct gfs2_rgrp *rg;
unsigned int block, bn = 0, x = 0, y = 0;
@@ -123,14 +123,14 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
struct gfs2_buffer_head *bh;
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);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
if (rl->rg.rg_free)
break;
}
- if (tmp == head)
+ if (n == NULL)
die("out of space\n");
ri = &rl->ri;
@@ -1742,7 +1742,7 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
*/
void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
{
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
/* Adjust the free space count for the freed block */
rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */
@@ -1767,7 +1767,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
struct gfs2_buffer_head *bh, *nbh;
int h, head_size;
uint64_t *ptr, block;
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
uint32_t height;
osi_list_t metalist[GFS2_MAX_META_HEIGHT];
osi_list_t *cur_list, *next_list, *tmp;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b1574fb..bb47580 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -17,6 +17,7 @@
#include <linux/gfs2_ondisk.h>
#include "osi_list.h"
+#include "osi_tree.h"
__BEGIN_DECLS
@@ -96,8 +97,8 @@ struct gfs2_bitmap
uint32_t bi_len; /* The number of bytes in this block */
};
-struct rgrp_list {
- osi_list_t list;
+struct rgrp_tree {
+ struct osi_node node;
uint64_t start; /* The offset of the beginning of this resource group */
uint64_t length; /* The length of this resource group */
@@ -223,7 +224,8 @@ struct gfs2_sbd {
uint64_t orig_rgrps;
uint64_t rgrps;
uint64_t new_rgrps;
- osi_list_t rglist;
+ struct osi_root rgtree;
+ struct osi_root rgcalc;
unsigned int orig_journals;
@@ -318,7 +320,7 @@ extern unsigned long gfs2_bitfit(const unsigned char *buffer,
unsigned long goal, unsigned char old_state);
/* functions with blk #'s that are rgrp relative */
-extern uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
+extern uint32_t gfs2_blkalloc_internal(struct rgrp_tree *rgd, uint32_t goal,
unsigned char old_state,
unsigned char new_state, int do_it);
extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
@@ -326,7 +328,7 @@ extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
/* functions with blk #'s that are file system relative */
extern int valid_block(struct gfs2_sbd *sdp, uint64_t blkno);
extern int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
- struct rgrp_list *rgd);
+ struct rgrp_tree *rgd);
extern int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state);
/* fs_geometry.c */
@@ -334,7 +336,8 @@ extern void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks,
uint32_t *bitblocks);
extern uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev,
int rgsize_specified);
-extern void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified);
+extern void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
+ int rgsize_specified);
extern void build_rgrps(struct gfs2_sbd *sdp, int write);
/* fs_ops.c */
@@ -697,12 +700,13 @@ extern int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head);
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 uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern void gfs2_rgrp_relse(struct rgrp_list *rgd);
-extern void gfs2_rgrp_free(osi_list_t *rglist);
+extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_tree *rgd);
+extern struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
+extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd);
+extern void gfs2_rgrp_relse(struct rgrp_tree *rgd);
+extern struct rgrp_tree *rgrp_insert(struct osi_root *rgtree,
+ uint64_t rgblock);
+extern void gfs2_rgrp_free(struct osi_root *rgrp_tree);
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
@@ -719,11 +723,11 @@ 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,
+extern int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block,
int first);
-extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
uint64_t *block, uint32_t type, int first);
-extern int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block,
+extern int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block,
int first);
/* super.c */
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index cd3667f..0fcea3c 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -13,7 +13,7 @@
*
* Returns: 0 on success, -1 on error
*/
-int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
+int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
{
struct gfs2_bitmap *bits;
uint32_t length = rgd->ri.ri_length;
@@ -93,33 +93,21 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
*
* Returns: Ths resource group, or NULL if not found
*/
-struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
+struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
{
- osi_list_t *tmp;
- struct rgrp_list *rgd;
- static struct rgrp_list *prev_rgd = NULL;
+ struct osi_node *node = sdp->rgtree.osi_node;
struct gfs2_rindex *ri;
- if (prev_rgd) {
- ri = &prev_rgd->ri;
- if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data)
- return prev_rgd;
- if (blk >= ri->ri_addr && blk < ri->ri_addr + ri->ri_length)
- return prev_rgd;
- }
-
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ while (node) {
+ struct rgrp_tree *rgd = (struct rgrp_tree *)node;
ri = &rgd->ri;
- if (blk >= ri->ri_addr && blk < ri->ri_addr + ri->ri_length) {
- prev_rgd = rgd;
- return rgd;
- }
- if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) {
- prev_rgd = rgd;
+ if (blk < ri->ri_addr)
+ node = node->osi_left;
+ else if (blk > ri->ri_data0 + ri->ri_data)
+ node = node->osi_right;
+ else
return rgd;
- }
}
return NULL;
}
@@ -129,7 +117,7 @@ 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_tree *rgd)
{
int x, length = rgd->ri.ri_length;
uint64_t max_rgrp_bitbytes, max_rgrp_len;
@@ -165,7 +153,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
return 0;
}
-void gfs2_rgrp_relse(struct rgrp_list *rgd)
+void gfs2_rgrp_relse(struct rgrp_tree *rgd)
{
int x, length = rgd->ri.ri_length;
@@ -178,14 +166,46 @@ void gfs2_rgrp_relse(struct rgrp_list *rgd)
}
}
-void gfs2_rgrp_free(osi_list_t *rglist)
+struct rgrp_tree *rgrp_insert(struct osi_root *rgtree, uint64_t rgblock)
+{
+ struct osi_node **newn = &rgtree->osi_node, *parent = NULL;
+ struct rgrp_tree *data;
+
+ /* Figure out where to put new node */
+ while (*newn) {
+ struct rgrp_tree *cur = (struct rgrp_tree *)*newn;
+
+ parent = *newn;
+ if (rgblock < cur->ri.ri_addr)
+ newn = &((*newn)->osi_left);
+ else if (rgblock > cur->ri.ri_addr)
+ newn = &((*newn)->osi_right);
+ else
+ return cur;
+ }
+
+ data = malloc(sizeof(struct rgrp_tree));
+ if (!data)
+ return NULL;
+ if (!memset(data, 0, sizeof(struct rgrp_tree)))
+ return NULL;
+ /* Add new node and rebalance tree. */
+ data->ri.ri_addr = rgblock;
+ osi_link_node(&data->node, parent, newn);
+ osi_insert_color(&data->node, rgtree);
+
+ return data;
+}
+
+void gfs2_rgrp_free(struct osi_root *rgrp_tree)
{
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
int rgs_since_sync = 0;
+ struct osi_node *n;
struct gfs2_sbd *sdp = NULL;
- while(!osi_list_empty(rglist->next)){
- rgd = osi_list_entry(rglist->next, struct rgrp_list, list);
+ while ((n = osi_first(rgrp_tree))) {
+ rgd = (struct rgrp_tree *)n;
if (rgd->bh && rgd->bh[0]) { /* if a buffer exists */
rgs_since_sync++;
if (rgs_since_sync >= RG_SYNC_TOLERANCE) {
@@ -202,7 +222,7 @@ void gfs2_rgrp_free(osi_list_t *rglist)
free(rgd->bh);
rgd->bh = NULL;
}
- osi_list_del(&rgd->list);
+ osi_erase(&rgd->node, rgrp_tree);
free(rgd);
}
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index b998f2d..9024353 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -307,8 +307,8 @@ int build_statfs(struct gfs2_sbd *sdp)
int build_rindex(struct gfs2_sbd *sdp)
{
struct gfs2_inode *ip;
- osi_list_t *tmp, *head;
- struct rgrp_list *rl;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rl;
char buf[sizeof(struct gfs2_rindex)];
int count;
@@ -317,9 +317,9 @@ int build_rindex(struct gfs2_sbd *sdp)
ip->i_di.di_payload_format = GFS2_FORMAT_RI;
bmodified(ip->i_bh);
- for (head = &sdp->rglist, tmp = head->next; tmp != head;
- tmp = tmp->next) {
- rl = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
gfs2_rindex_out(&rl->ri, buf);
@@ -459,7 +459,7 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
*
* Returns: 0 on success, -1 when finished
*/
-static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
+static int __gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block,
int first, unsigned char state)
{
struct gfs2_bitmap *bits = NULL;
@@ -467,17 +467,17 @@ static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
uint32_t blk = (first)? 0: (uint32_t)((*block + 1) - rgd->ri.ri_data0);
int i;
- if(!first && (*block < rgd->ri.ri_data0)) {
+ if (!first && (*block < rgd->ri.ri_data0)) {
log_err("next_rg_meta: Start block is outside rgrp bounds.\n");
exit(1);
}
- for(i = 0; i < length; i++){
+ for (i = 0; i < length; i++){
bits = &rgd->bits[i];
if (blk < bits->bi_len * GFS2_NBBY)
break;
blk -= bits->bi_len * GFS2_NBBY;
}
- for(; i < length; i++){
+ for (; i < length; i++){
bits = &rgd->bits[i];
blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
bits->bi_offset, bits->bi_len, blk, state);
@@ -488,17 +488,17 @@ static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
}
blk = 0;
}
- if(i == length)
+ if (i == length)
return -1;
return 0;
}
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first)
{
return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_DINODE);
}
-int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block, int first)
{
return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_UNLINKED);
}
@@ -512,7 +512,7 @@ int gfs2_next_rg_freemeta(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,
+int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
uint64_t *block, uint32_t type, int first)
{
struct gfs2_buffer_head *bh = NULL;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 27f6c2c..2cac1c3 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -147,12 +147,12 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
struct gfs_rindex bufgfs1;
struct gfs2_rindex bufgfs2;
} buf;
- struct rgrp_list *rgd, *prev_rgd;
+ struct gfs2_rindex ri;
+ struct rgrp_tree *rgd = NULL, *prev_rgd = NULL;
uint64_t prev_length = 0;
*sane = 1;
*count1 = 0;
- prev_rgd = NULL;
if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex))
*sane = 0; /* rindex file size must be a multiple of 96 */
for (rg = 0; ; rg++) {
@@ -168,15 +168,9 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
if (error != sizeof(struct gfs2_rindex))
return -1;
- rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list));
- if (!rgd) {
- log_crit("Cannot allocate memory for rindex.\n");
- exit(-1);
- }
- memset(rgd, 0, sizeof(struct rgrp_list));
- osi_list_add_prev(&rgd->list, &sdp->rglist);
-
- gfs2_rindex_in(&rgd->ri, (char *)&buf.bufgfs2);
+ gfs2_rindex_in(&ri, (char *)&buf.bufgfs2);
+ rgd = rgrp_insert(&sdp->rgtree, ri.ri_addr);
+ memcpy(&rgd->ri, &ri, sizeof(struct gfs2_rindex));
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
@@ -226,17 +220,18 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
int quiet)
{
- struct rgrp_list *rgd;
+ struct rgrp_tree *rgd;
struct gfs2_rindex *ri;
- osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
uint64_t rmax = 0;
+ struct osi_node *n, *next = NULL;
if (rindex_read(sdp, fd, &count1, sane))
goto fail;
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgd = (struct rgrp_tree *)n;
errblock = gfs2_rgrp_read(sdp, rgd);
if (errblock)
return errblock;
@@ -258,7 +253,7 @@ static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
return 0;
fail:
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
return -1;
}
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index a28bdc3..d2d5e05 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -125,12 +125,14 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
*/
static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
{
- osi_list_t *head = &sdp->rglist;
- struct rgrp_list *r1, *r2;
+ struct osi_node *n = osi_first(&sdp->rgtree), *next = NULL;
+ struct rgrp_tree *r1, *r2;
sdp->rgsize = GFS2_DEFAULT_RGSIZE;
- r1 = osi_list_entry(head->next->next, struct rgrp_list, list);
- r2 = osi_list_entry(head->next->next->next, struct rgrp_list, list);
+ next = osi_next(n);
+ r1 = (struct rgrp_tree *)next;
+ next = osi_next(next);
+ r2 = (struct rgrp_tree *)next;
*orgsize = r2->ri.ri_addr - r1->ri.ri_addr;
}
@@ -146,16 +148,13 @@ static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
static uint64_t filesystem_size(struct gfs2_sbd *sdp)
{
- osi_list_t *tmp;
- struct rgrp_list *rgl;
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rgl;
uint64_t size = 0, extent;
- tmp = &sdp->rglist;
- for (;;) {
- tmp = tmp->next;
- if (tmp == &sdp->rglist)
- break;
- rgl = osi_list_entry(tmp, struct rgrp_list, list);
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rgl = (struct rgrp_tree *)n;
extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data;
if (extent > size)
size = extent;
@@ -168,19 +167,22 @@ static uint64_t filesystem_size(struct gfs2_sbd *sdp)
*/
static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
{
+ struct osi_node *n, *next = NULL;
uint64_t rgrp = 0;
- osi_list_t *head = &sdp->rglist;
- struct rgrp_list *rl;
+ struct rgrp_tree *rl;
*old_rg_count = 0;
/* Delete the old RGs from the rglist */
- for (rgrp = 0; !osi_list_empty(head) &&
- rgrp < (sdp->rgrps - sdp->new_rgrps); rgrp++) {
+ for (rgrp = 0, n = osi_first(&sdp->rgtree);
+ n && rgrp < (sdp->rgrps - sdp->new_rgrps); n = next, rgrp++) {
+ next = osi_next(n);
(*old_rg_count)++;
- osi_list_del(head->next);
+ rl = (struct rgrp_tree *)n;
+ osi_erase(&rl->node, &sdp->rgtree);
+ free(rl);
}
/* Issue a discard ioctl for the new portion */
- rl = osi_list_entry(sdp->rglist.next, struct rgrp_list, list);
+ rl = (struct rgrp_tree *)n;
discard_blocks(sdp->device_fd, rl->start * sdp->bsize,
(sdp->device.length - rl->start) * sdp->bsize);
/* Build the remaining resource groups */
@@ -198,17 +200,19 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
*/
static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
{
+ struct osi_node *n, *next = NULL;
int count, rg;
- struct rgrp_list *rl;
+ struct rgrp_tree *rl;
char *buf, *bufptr;
- osi_list_t *tmp;
ssize_t writelen;
struct stat statbuf;
/* Count the number of new RGs. */
rg = 0;
- osi_list_foreach(tmp, &sdp->rglist)
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
rg++;
+ }
log_info( _("%d new rindex entries.\n"), rg);
writelen = rg * sizeof(struct gfs2_rindex);
buf = calloc(1, writelen);
@@ -220,13 +224,14 @@ static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
/* need to use the gfs2 kernel code rather than the libgfs2 */
/* code so we have a live update while mounted. */
bufptr = buf;
- osi_list_foreach(tmp, &sdp->rglist) {
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
rg++;
- rl = osi_list_entry(tmp, struct rgrp_list, list);
+ rl = (struct rgrp_tree *)n;
gfs2_rindex_out(&rl->ri, bufptr);
bufptr += sizeof(struct gfs2_rindex);
}
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
fsync(sdp->device_fd);
if (!test) {
if (fstat(rindex_fd, &statbuf) != 0) {
@@ -306,7 +311,6 @@ main_grow(int argc, char *argv[])
struct gfs2_sbd sbd, *sdp = &sbd;
int rgcount, rindex_fd;
char rindex_name[PATH_MAX];
- osi_list_t *head = &sdp->rglist;
memset(sdp, 0, sizeof(struct gfs2_sbd));
sdp->bsize = GFS2_DEFAULT_BSIZE;
@@ -344,7 +348,8 @@ main_grow(int argc, char *argv[])
exit(-1);
}
log_info( _("Initializing lists...\n"));
- osi_list_init(&sdp->rglist);
+ sdp->rgtree.osi_node = NULL;
+ sdp->rgcalc.osi_node = NULL;
sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sdp->bsize = sdp->sd_sb.sb_bsize;
@@ -397,14 +402,13 @@ main_grow(int argc, char *argv[])
else {
int old_rg_count;
- compute_rgrp_layout(sdp, TRUE);
+ compute_rgrp_layout(sdp, &sdp->rgtree, TRUE);
print_info(sdp);
initialize_new_portion(sdp, &old_rg_count);
fix_rindex(sdp, rindex_fd, old_rg_count);
}
/* Delete the remaining RGs from the rglist */
- while (!osi_list_empty(head))
- osi_list_del(head->next);
+ gfs2_rgrp_free(&sdp->rgtree);
close(rindex_fd);
cleanup_metafs(sdp);
close(sdp->device_fd);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index ee2a5da..bcc60e4 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -550,7 +550,7 @@ void main_mkfs(int argc, char *argv[])
sdp->qcsize = GFS2_DEFAULT_QCSIZE;
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
sdp->time = time(NULL);
- osi_list_init(&sdp->rglist);
+ sdp->rgtree.osi_node = NULL;
decode_arguments(argc, argv, sdp);
if (sdp->rgsize == -1) /* if rg size not specified */
@@ -636,7 +636,7 @@ void main_mkfs(int argc, char *argv[])
/* Compute the resource group layouts */
- compute_rgrp_layout(sdp, rgsize_specified);
+ compute_rgrp_layout(sdp, &sdp->rgtree, rgsize_specified);
/* Generate a random uuid */
get_random_bytes(uuid, sizeof(uuid));
@@ -666,7 +666,7 @@ void main_mkfs(int argc, char *argv[])
inode_put(&sdp->md.inum);
inode_put(&sdp->md.statfs);
- gfs2_rgrp_free(&sdp->rglist);
+ gfs2_rgrp_free(&sdp->rgtree);
error = fsync(sdp->device_fd);
if (error)
die( _("can't fsync device (%d): %s\n"),
12 years, 4 months
cluster: RHEL6 - Change man pages and gfs2_convert messages to include GFS
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c31b42c143250be89c6fc9817bf52d3293a28a05
Parent: 4768e3497c96f80f2776489ea5c65dba4dcd3681
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 17:01:57 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
Change man pages and gfs2_convert messages to include GFS
Since fsck.gfs2 can now handle GFS1 file systems, this patch changes
the message in gfs2_convert and the man pages to reflect that.
rhbz#675723
---
gfs2/convert/gfs2_convert.c | 2 +-
gfs2/man/fsck.gfs2.8 | 9 +++++----
gfs2/man/gfs2_convert.8 | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 8ed2c1a..fa6461f 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1604,7 +1604,7 @@ static void give_warning(void)
printf("WARNING: This can't be undone. It is strongly advised " \
"that you:\n\n");
printf(" 1. Back up your entire filesystem first.\n");
- printf(" 2. Run gfs_fsck first to ensure filesystem integrity.\n");
+ printf(" 2. Run fsck.gfs2 first to ensure filesystem integrity.\n");
printf(" 3. Make sure the filesystem is NOT mounted from any node.\n");
printf(" 4. Make sure you have the latest software versions.\n");
}/* give_warning */
diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8
index 462e918..3ecfbe3 100644
--- a/gfs2/man/fsck.gfs2.8
+++ b/gfs2/man/fsck.gfs2.8
@@ -1,18 +1,19 @@
.TH fsck.gfs2 8
.SH NAME
-fsck.gfs2 - Offline GFS2 file system checker
+fsck.gfs2 - Offline GFS and GFS2 file system checker
.SH SYNOPSIS
.B fsck.gfs2
[\fIOPTION\fR]... \fIDEVICE\fR
.SH WARNING
-All GFS2 nodes \fImust\fP have the GFS2 filesystem unmounted before running
-fsck.gfs2. Failure to unmount all nodes may result in filesystem corruption.
+All computers \fImust\fP have the filesystem unmounted before running
+fsck.gfs2. Failure to unmount from all nodes in a cluster will likely result
+in filesystem corruption.
.SH DESCRIPTION
-fsck.gfs2 will check that the GFS2 file system on a device is structurally valid.
+fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid.
It should not be run on a mounted file system. If file system corruption is
detected, it will attempt to repair the file system. There is a limit to what
fsck.gfs2 can do. If important file system structures are destroyed, such that
diff --git a/gfs2/man/gfs2_convert.8 b/gfs2/man/gfs2_convert.8
index 5969432..ca0f64f 100644
--- a/gfs2/man/gfs2_convert.8
+++ b/gfs2/man/gfs2_convert.8
@@ -10,7 +10,7 @@ gfs2_convert - Convert a GFS1 filesystem to GFS2
.SH DESCRIPTION
gfs2_convert is used to convert a filesystem from GFS1 to GFS2. It is
required that the GFS1 filesystem be checked and fixed for errors using
-\fBgfs_fsck\fP and that the filesystem be backed up before
+\fBfsck.gfs2\fP and that the filesystem be backed up before
attempting to convert it. The convert process is irreversible and any
error encountered during the conversion can result in the abrupt
termination of the program and consequently an unusable filesystem.
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: Fix memory leaks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4768e3497c96f80f2776489ea5c65dba4dcd3681
Parent: d0761931cad0ee047d0419edfdf2f1f1b8f9b12b
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 16:30:30 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Fix memory leaks
This patch fixes some memory leaks in fsck.gfs2 that I discovered
by using valgrind.
rhbz#675723
---
gfs2/fsck/fs_recovery.c | 2 ++
gfs2/fsck/initialize.c | 16 ++++++++++------
gfs2/fsck/main.c | 2 ++
gfs2/fsck/metawalk.c | 10 ++++++++--
gfs2/fsck/pass1.c | 6 +++++-
5 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 907e37f..d3c742a 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -611,6 +611,8 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
inode_put(&sdp->md.journal[i]);
}
inode_put(&sdp->md.jiinode);
+ free(sdp->md.journal);
+ sdp->md.journal = NULL;
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 06121bc..95a6a65 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -641,12 +641,16 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
do_init_statfs(sdp);
}
- buf = malloc(sdp->md.statfs->i_di.di_size);
- // FIXME: handle failed malloc
- gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
- /* call gfs2_inum_range_in() to retrieve range */
- gfs2_statfs_change_in(&sc, buf);
- free(buf);
+ if (sdp->md.statfs->i_di.di_size) {
+ buf = malloc(sdp->md.statfs->i_di.di_size);
+ if (buf) {
+ gfs2_readi(sdp->md.statfs, buf, 0,
+ sdp->md.statfs->i_di.di_size);
+ /* call gfs2_inum_range_in() to retrieve range */
+ gfs2_statfs_change_in(&sc, buf);
+ free(buf);
+ }
+ }
if (sdp->gfs1)
sdp->md.qinode = inode_read(sdp, sbd1->sb_quota_di.no_addr);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 7b768b0..676b676 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -349,6 +349,8 @@ int main(int argc, char **argv)
inode_put(&sdp->md.statfs);
for (j = 0; j < sdp->md.journals; j++)
inode_put(&sdp->md.journal[j]);
+ free(sdp->md.journal);
+ sdp->md.journal = NULL;
inode_put(&sdp->md.jiinode);
inode_put(&sdp->md.riinode);
inode_put(&sdp->md.qinode);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index c313c3b..8723adc 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1168,8 +1168,10 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
for (ptr = (uint64_t *)(bh->b_data + head_size);
(char *)ptr < (bh->b_data + ip->i_sbd->bsize);
ptr++) {
- if (skip_this_pass || fsck_abort)
+ if (skip_this_pass || fsck_abort) {
+ free_metalist(ip, mlp);
return FSCK_OK;
+ }
nbh = NULL;
if (!*ptr)
@@ -1281,6 +1283,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
error = build_and_check_metalist(ip, &metalist[0], pass);
if (error) {
stack;
+ free_metalist(ip, &metalist[0]);
return error;
}
@@ -1317,8 +1320,10 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
last_reported_fblock = -10000000;
while (error >= 0 && !osi_list_empty(list)) {
- if (fsck_abort)
+ if (fsck_abort) {
+ free_metalist(ip, &metalist[0]);
return 0;
+ }
bh = osi_list_entry(list->next, struct gfs2_buffer_head,
b_altlist);
@@ -1371,6 +1376,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)ip->i_di.di_num.no_addr);
fflush(stdout);
}
+ free_metalist(ip, &metalist[0]);
return error;
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index de5de2b..b3ef7d4 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -430,6 +430,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
fsck_blockmap_set(ip, block, _("bad indirect"),
gfs2_meta_inval);
brelse(nbh);
+ nbh = NULL;
return 1;
}
brelse(nbh);
@@ -439,8 +440,11 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
bc->indir_count++;
if (found_dup) {
- if (nbh)
+ if (nbh) {
brelse(nbh);
+ nbh = NULL;
+ *bh = NULL;
+ }
return 1; /* don't process the metadata again */
} else
fsck_blockmap_set(ip, block, _("indirect"),
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: Speed up rangecheck functions
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 2ad623efab476ba37e24ab014e2a1a7f22262606
Parent: 68b32af3f105ca6a373328e66029ea80b8e8630b
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:21:35 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Speed up rangecheck functions
This patch speeds up the block rangecheck functions by passing
the block type in as an integer rather than a translated string
constant. The translation functions were a bit costly.
rhbz#675723
---
gfs2/fsck/pass1.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3e6b816..60e7cce 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1052,9 +1052,14 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
* be trusted. Thus it needs to be in a separate loop.
* Returns: 0 if good range, otherwise != 0
*/
+enum b_types { btype_meta, btype_leaf, btype_data, btype_ieattr, btype_eattr};
+const char *btypes[5] = {
+ "metadata", "leaf", "data", "indirect extended attribute",
+ "extended attribute" };
+
static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh,
- const char *btype, void *private)
+ struct gfs2_buffer_head **bh, enum b_types btype,
+ void *private)
{
long *bad_pointers = (long *)private;
uint8_t q;
@@ -1063,7 +1068,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
(*bad_pointers)++;
log_info( _("Bad %s block pointer (invalid or out of range "
"#%ld) found in inode %lld (0x%llx).\n"),
- btype, *bad_pointers,
+ btypes[btype], *bad_pointers,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
@@ -1077,7 +1082,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
(*bad_pointers)++;
log_info( _("Duplicated %s block pointer (violation %ld, block"
" %lld (0x%llx)) found in inode %lld (0x%llx).\n"),
- btype, *bad_pointers,
+ btypes[btype], *bad_pointers,
(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);
@@ -1093,36 +1098,33 @@ static int rangecheck_metadata(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h,
void *private)
{
- return rangecheck_block(ip, block, bh, _("metadata"), private);
+ return rangecheck_block(ip, block, bh, btype_meta, private);
}
static int rangecheck_leaf(struct gfs2_inode *ip, uint64_t block,
void *private)
{
- return rangecheck_block(ip, block, NULL, _("leaf"), private);
+ return rangecheck_block(ip, block, NULL, btype_leaf, private);
}
static int rangecheck_data(struct gfs2_inode *ip, uint64_t block,
void *private)
{
- return rangecheck_block(ip, block, NULL, _("data"), private);
+ return rangecheck_block(ip, block, NULL, btype_data, private);
}
static int rangecheck_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent,
struct gfs2_buffer_head **bh, void *private)
{
- return rangecheck_block(ip, block, NULL,
- _("indirect extended attribute"),
- private);
+ return rangecheck_block(ip, block, NULL, btype_ieattr, private);
}
static int rangecheck_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
{
- return rangecheck_block(ip, block, NULL, _("extended attribute"),
- private);
+ return rangecheck_block(ip, block, NULL, btype_eattr, private);
}
struct metawalk_fxns rangecheck_fxns = {
12 years, 4 months
cluster: RHEL6 - fsck.gfs2: pass1c counts percentage backward
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 68b32af3f105ca6a373328e66029ea80b8e8630b
Parent: 165021e9be8503dd8ffc37edd2da71d1aa994df0
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:20:26 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: pass1c counts percentage backward
In testing I noticed that pass1c, which checks all extended
attributes, counted percent-complete backwards. It's better to
count forward because disk block seeks will be more efficient.
This patch changes the special_list functions of block_list to
add items as "prev" so that they're processed in block order.
rhbz#675723
---
gfs2/libgfs2/block_list.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 65003b0..554a1ef 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -42,7 +42,7 @@ void gfs2_special_add(struct special_blocks *blocklist, uint64_t block)
if (b) {
memset(b, 0, sizeof(*b));
b->block = block;
- osi_list_add(&b->list, &blocklist->list);
+ osi_list_add_prev(&b->list, &blocklist->list);
}
}
12 years, 4 months