gfs2-utils: master - Change man pages and gfs2_convert messages to include GFS
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 7c005938ea27cde2877cd284862e9082ccaa2aea
Parent: 02adf68abe793100cf123cb83989200500331340
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 31 08:02:09 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Wed Aug 31 08:02:09 2011 -0500
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 78a87dd..396e899 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1615,7 +1615,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, 8 months
cluster: STABLE31 - rgmanager: fix init script status return code to not overwrite global var
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: b694e7ab032697280ed330423b5200ae92b1c8db
Parent: b843e89a54d9bdc9750b529f59405040b4b780db
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Wed Aug 31 11:11:15 2011 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Wed Aug 31 11:11:15 2011 +0200
rgmanager: fix init script status return code to not overwrite global var
Reported by Dietmar Maurer <dietmar at proxmox.com>
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
rgmanager/init.d/rgmanager.in | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rgmanager/init.d/rgmanager.in b/rgmanager/init.d/rgmanager.in
index 9e5a050..5b7219c 100644
--- a/rgmanager/init.d/rgmanager.in
+++ b/rgmanager/init.d/rgmanager.in
@@ -33,13 +33,13 @@ failure()
status()
{
pid=$(pidof $1 2>/dev/null)
- rtrn=$?
- if [ $rtrn -ne 0 ]; then
+ statusrtrn=$?
+ if [ $statusrtrn -ne 0 ]; then
echo "$1 is stopped"
else
echo "$1 (pid $pid) is running..."
fi
- return $rtrn
+ return $statusrtrn
}
# rpm based distros
12 years, 8 months
gfs2-utils: master - gfs2_edit: Fix memory leaks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 02adf68abe793100cf123cb83989200500331340
Parent: b1cda3608ee07e70665a0ac6ce3689bfced1439a
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 30 13:00:42 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Aug 30 14:08:06 2011 -0500
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 02bd629..3a0e45e 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -134,6 +134,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);*/
@@ -492,7 +493,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 */
@@ -810,6 +814,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);
}
@@ -1034,6 +1040,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, 8 months
gfs2-utils: master - fsck.gfs2: Fix memory leaks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: b1cda3608ee07e70665a0ac6ce3689bfced1439a
Parent: a0764715dba98da9e7e110d5094460951b5a5745
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 30 08:57:17 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Aug 30 08:57:17 2011 -0500
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 67aa441..8f410b1 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -613,6 +613,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 443e644..eb3d507 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -710,12 +710,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 6c11075..d2a0965 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -351,6 +351,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 1fc1214..7adf73d 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1172,8 +1172,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)
@@ -1285,6 +1287,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;
}
@@ -1321,8 +1324,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);
@@ -1375,6 +1380,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 729d138..0ed4e24 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, 8 months
gfs2-utils: master - libgfs2: Make in-core rgrps use rbtree
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: a0764715dba98da9e7e110d5094460951b5a5745
Parent: 68f7f4867f02a29433c3ccdf39664a29d624ff43
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 25 11:09:25 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:58:10 2011 -0500
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 | 10 +-
gfs2/fsck/pass5.c | 11 +-
gfs2/fsck/rgrepair.c | 220 ++++++++++++++++---------------------------
gfs2/libgfs2/fs_bits.c | 4 +-
gfs2/libgfs2/fs_geometry.c | 55 ++++++-----
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, 362 insertions(+), 385 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index bef2ccd..78a87dd 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -174,7 +174,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;
@@ -202,16 +202,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. */
@@ -986,8 +988,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;
@@ -1002,9 +1004,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);
@@ -1509,7 +1512,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);
@@ -1737,9 +1740,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;
@@ -1757,8 +1761,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)))
@@ -1771,15 +1776,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;
@@ -1822,9 +1824,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 */
@@ -2001,16 +2000,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 */
@@ -2207,6 +2207,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"));
@@ -2294,7 +2295,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 071f589..a6e4139 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -662,7 +662,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 7d966a6..2182704 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1150,7 +1150,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) {
@@ -1469,7 +1469,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);
}
@@ -1697,7 +1697,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() ||
@@ -1723,7 +1723,7 @@ static void read_superblock(int fd)
sbd.rgsize = GFS2_DEFAULT_RGSIZE;
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 &&
@@ -2040,7 +2040,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;
@@ -2055,16 +2055,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;
@@ -2079,12 +2080,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,
@@ -2105,7 +2107,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;
@@ -2139,7 +2141,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;
@@ -2440,7 +2442,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);
}
@@ -2451,7 +2453,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)
@@ -2483,7 +2485,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);
}
@@ -2494,7 +2496,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)) {
@@ -2504,7 +2506,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;
@@ -2530,12 +2532,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);
@@ -3463,7 +3465,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]);
@@ -3496,7 +3498,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')
@@ -3513,7 +3515,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;
@@ -3522,7 +3524,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]);
@@ -3531,7 +3533,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);
}
}
@@ -3641,6 +3643,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 3423eae..02bd629 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -589,7 +589,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;
@@ -631,11 +631,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);
@@ -661,7 +660,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
(unsigned long long)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)) {
@@ -702,6 +701,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);
@@ -709,10 +709,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;
@@ -723,6 +723,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
@@ -744,12 +746,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 8910103..443e644 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -110,7 +110,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);
@@ -131,10 +131,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;
@@ -142,9 +141,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)
@@ -191,7 +190,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)
{
@@ -320,17 +319,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)
@@ -1224,7 +1224,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 87cb01f..e4fccd5 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -89,8 +89,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;
@@ -98,14 +98,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 448f3b3..6c11075 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -149,8 +149,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)];
@@ -171,8 +171,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 590f7ec..1fc1214 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -31,7 +31,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 9929301..729d138 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1534,10 +1534,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 rg_count = 0;
@@ -1562,11 +1562,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++) {
+ 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 = osi_list_entry(tmp, struct rgrp_list, list);
+ 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 2a4ffbc..340df20 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -195,7 +195,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;
@@ -280,18 +280,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 #%llu\n"), (unsigned long long)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 cba1f7d..6394546 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -231,25 +231,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;
}
@@ -346,7 +346,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;
@@ -431,20 +431,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,
@@ -463,15 +463,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. */
@@ -588,9 +585,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,
@@ -615,8 +612,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;
@@ -629,7 +625,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);
@@ -652,16 +648,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%llx blocks.\n"),
(unsigned long long)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;
}
@@ -669,8 +660,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";
@@ -716,18 +707,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);
@@ -739,45 +728,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.
@@ -790,10 +746,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)
@@ -807,57 +762,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,
@@ -867,20 +818,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 */
@@ -888,22 +830,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,
@@ -919,8 +863,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. */
@@ -931,8 +875,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;
}
}
@@ -941,28 +885,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", unsigned long long);
ri_compare(rg, actual->ri, expected->ri, ri_length,
@@ -1001,26 +946,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)
@@ -1035,7 +981,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 9f71471..d3ac048 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -177,7 +177,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;
@@ -225,7 +225,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 caffeb7..2b70f11 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -74,13 +74,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;
+ struct rgrp_tree *rl, *rlast = NULL, *rlast2 = NULL;
+ struct osi_node *n, *next = NULL;
unsigned int rgrp = 0, nrgrp;
- uint64_t rglength;
+ uint64_t rglength, rgaddr;
sdp->new_rgrps = 0;
dev = &sdp->device;
@@ -91,7 +92,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;
@@ -100,9 +101,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,
@@ -122,26 +124,21 @@ 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;
}
@@ -150,8 +147,9 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
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);
@@ -202,8 +200,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;
@@ -212,11 +210,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 84cd895..c778564 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -116,8 +116,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;
@@ -125,14 +125,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;
@@ -1753,7 +1753,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 */
@@ -1778,7 +1778,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 b0c722f..53df6cd 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
@@ -97,8 +98,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 */
@@ -224,7 +225,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;
@@ -324,7 +326,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);
@@ -332,7 +334,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 */
@@ -340,7 +342,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 */
@@ -698,12 +701,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);
@@ -720,11 +724,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 97f22bb..e7b5f72 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -15,7 +15,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;
@@ -95,33 +95,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;
}
@@ -131,7 +119,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;
@@ -167,7 +155,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;
@@ -180,14 +168,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) {
@@ -204,7 +224,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 7f21ad6..8733444 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -344,8 +344,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;
@@ -357,9 +357,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);
@@ -502,7 +502,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;
@@ -510,17 +510,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);
@@ -531,17 +531,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);
}
@@ -555,7 +555,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 277daf8..c354b07 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -149,12 +149,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++) {
@@ -170,15 +170,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) {
@@ -228,17 +222,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;
@@ -260,7 +255,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 48e6377..dc092ee 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -126,12 +126,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;
}
@@ -147,16 +149,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;
@@ -169,19 +168,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 */
@@ -199,17 +201,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);
@@ -221,13 +225,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) {
@@ -308,7 +313,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;
@@ -346,7 +350,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;
@@ -399,14 +404,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 d841daa..4751f19 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -540,7 +540,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 */
@@ -626,7 +626,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));
@@ -680,7 +680,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, 8 months
gfs2-utils: master - fsck.gfs2: Speed up rangecheck functions
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 68f7f4867f02a29433c3ccdf39664a29d624ff43
Parent: d39dde5bacd8e8c11d4d202b04236b520bf6a660
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 25 10:49:36 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:56:29 2011 -0500
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 8db8579..9929301 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, 8 months
gfs2-utils: master - fsck.gfs2: pass1c counts percentage backward
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: d39dde5bacd8e8c11d4d202b04236b520bf6a660
Parent: a0af8c8c1b1c58258f2d5f91e5dca72e80ca41ca
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 23 22:11:24 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:56:29 2011 -0500
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 4fb7f4b..9d99845 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -44,7 +44,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, 8 months
gfs2-utils: master - fsck.gfs2: Print step 2 duplicate debug msg first
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: a0af8c8c1b1c58258f2d5f91e5dca72e80ca41ca
Parent: c7c7ef6bf3f2bc2f0f09e285085a20fb17ef6aad
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 23 10:30:20 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:56:29 2011 -0500
fsck.gfs2: Print step 2 duplicate debug msg first
In testing fsck.gfs2 I noticed that when duplicates were resolved,
the "step 2" debug message was printed after step 2 was actually
done. That's misleading, so this patch changes it.
rhbz#675723
---
gfs2/fsck/pass1b.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a56ea31..ae6d45c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -645,15 +645,15 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
* directory inode referencing a data block as a leaf block.
*/
if (!last_reference) {
- last_reference = resolve_dup_references(sdp, b,
- &b->ref_inode_list,
- &dh, 0,
- acceptable_ref);
log_debug( _("----------------------------------------------\n"
"Step 2: Eliminate references to block %llu "
"(0x%llx) that need the wrong block type.\n"),
(unsigned long long)b->block,
(unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0,
+ acceptable_ref);
}
/* Step 3 - We have multiple dinodes referencing it as the correct
* type. Just blast one of them.
12 years, 8 months
gfs2-utils: master - fsck.gfs2: Recognize partially gfs2-converted dinodes
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: c7c7ef6bf3f2bc2f0f09e285085a20fb17ef6aad
Parent: 0f8375827cfbed2ea189fb9a05004456103c0989
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 23 10:02:02 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:56:29 2011 -0500
fsck.gfs2: Recognize partially gfs2-converted dinodes
In testing fsck.gfs2 I noticed that if a file system had some
leftover gfs2 dinodes (due to an interrupted gfs2_convert or
in my case, because I had previously loaded gfs2 metadata that
left gfs2 blocks laying around the gfs1 file system) those gfs2
dinodes were not properly processed. In particular, it would not
recognize gfs2-style directories as directories because of the
difference in where dinode mode information is kept. This patch
gives fsck.gfs2 the ability to correctly identify gfs2 dinodes
when checking a gfs1 file system.
rhbz#675723
---
gfs2/fsck/lost_n_found.c | 4 ++--
gfs2/fsck/util.c | 2 +-
gfs2/fsck/util.h | 11 +++++++++--
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 625de0d..87cb01f 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -216,7 +216,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
lf_blocks = lf_dip->i_di.di_blocks;
if (sdp->gfs1)
- mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+ mode = gfs_to_gfs2_mode(ip);
else
mode = ip->i_di.di_mode & S_IFMT;
@@ -280,7 +280,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
incr_link_count(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
_("from lost+found"));
/* If it's a directory, lost+found is back-linked to it via .. */
- if (is_dir(&ip->i_di, sdp->gfs1))
+ if (mode == S_IFDIR)
incr_link_count(lf_dip->i_di.di_num.no_addr,
ip->i_di.di_num.no_addr, _("to lost+found"));
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index aa3e4ff..0d243e0 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -482,7 +482,7 @@ int set_ip_blockmap(struct gfs2_inode *ip, int instree)
uint32_t mode;
if (sdp->gfs1)
- mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+ mode = gfs_to_gfs2_mode(ip);
else
mode = ip->i_di.di_mode & S_IFMT;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 6581cb1..2f74af3 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -143,8 +143,10 @@ static inline int is_dir(struct gfs2_dinode *dinode, int gfs1)
return 0;
}
-static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
+static inline uint32_t gfs_to_gfs2_mode(struct gfs2_inode *ip)
{
+ uint16_t gfs1mode = ip->i_di.__pad1;
+
switch (gfs1mode) {
case GFS_FILE_DIR:
return S_IFDIR;
@@ -161,7 +163,12 @@ static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
case GFS_FILE_SOCK:
return S_IFSOCK;
default:
- return S_IFREG;
+ /* This could be an aborted gfs2_convert so look for both. */
+ if (ip->i_di.di_entries ||
+ (ip->i_di.di_mode & S_IFMT) == S_IFDIR)
+ return S_IFDIR;
+ else
+ return S_IFREG;
}
}
12 years, 8 months
gfs2-utils: master - fsck.gfs2: system dinodes take priority over user dinodes
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: 0f8375827cfbed2ea189fb9a05004456103c0989
Parent: 60140c2ba6be8bf7836c5b1baae7c7a9ea3a71e7
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 23 09:31:40 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Aug 29 12:56:29 2011 -0500
fsck.gfs2: system dinodes take priority over user dinodes
In testing fsck.gfs2 I noticed some incorrect behavior: If a block
was referenced incorrectly by two dinodes, fsck deleted which
ever reference it found first. Therefore, if a system dinode
and a user dinode referenced the same block, fsck.gfs2 could
mistakenly delete the system dinode. For example, a journal could
get deleted because a user dinode improperly referenced one of its
blocks. This patch gives priority to system dinodes when resolving
duplicates.
rhbz#675723
---
gfs2/fsck/pass1b.c | 9 ++++++++-
gfs2/fsck/util.c | 14 ++++++++++++--
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 67e878c..a56ea31 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -486,7 +486,14 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
continue; /* don't delete the dinode */
}
}
-
+ /* If this reference is from a system inode, for example, if
+ it's data or metadata inside a journal, the reference
+ should take priority over user dinodes that reference the
+ block. */
+ if (!found_good_ref && fsck_system_inode(sdp, id->block_no)) {
+ found_good_ref = 1;
+ continue; /* don't delete the dinode */
+ }
log_warn( _("Inode %s (%lld/0x%llx) references block "
"%llu (0x%llx) as '%s', but the block is "
"really %s.\n"),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index ae9213f..aa3e4ff 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -283,8 +283,18 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
inode reference list otherwise put it on the normal list. */
if (!inode_valid || q == gfs2_inode_invalid)
osi_list_add_prev(&id->list, &dt->ref_invinode_list);
- else
- osi_list_add_prev(&id->list, &dt->ref_inode_list);
+ else {
+ /* If this is a system dinode, we want the duplicate
+ processing to find it first. That way references
+ from inside journals, et al, will take priority.
+ We don't want to delete journals in favor of dinodes
+ that reference a block inside a journal. */
+ if (fsck_system_inode(ip->i_sbd, id->block_no))
+ osi_list_add(&id->list, &dt->ref_inode_list);
+ else
+ osi_list_add_prev(&id->list,
+ &dt->ref_inode_list);
+ }
}
id->reftypecount[reftype]++;
id->dup_count++;
12 years, 8 months