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"),