Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=a472edcae35302... Commit: a472edcae35302d0abc4bf9ca0e5183b27ca715d Parent: 737668db7dec805e3bcddd32c1e03b7ddf2eecb2 Author: Bob Peterson rpeterso@redhat.com AuthorDate: Fri Jan 6 16:02:26 2012 -0600 Committer: Bob Peterson rpeterso@redhat.com CommitterDate: Fri Apr 5 06:25:01 2013 -0700
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#877150 --- 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 | 27 ++++--- gfs2/fsck/fs_recovery.c | 1 + gfs2/fsck/initialize.c | 32 ++++---- gfs2/fsck/main.c | 9 +- gfs2/fsck/metawalk.c | 2 +- gfs2/fsck/pass1.c | 14 ++-- gfs2/fsck/pass5.c | 11 ++- gfs2/fsck/rgrepair.c | 205 +++++++++++++++++++++++++------------------ gfs2/fsck/util.c | 1 - gfs2/libgfs2/fs_bits.c | 4 +- gfs2/libgfs2/fs_geometry.c | 52 ++++++----- gfs2/libgfs2/fs_ops.c | 16 ++-- gfs2/libgfs2/gfs1.c | 31 +++---- gfs2/libgfs2/libgfs2.h | 45 +++++---- gfs2/libgfs2/rgrp.c | 78 ++++++++++------ gfs2/libgfs2/structures.c | 22 +++--- gfs2/libgfs2/super.c | 29 +++---- gfs2/mkfs/main_grow.c | 55 ++++++------ gfs2/mkfs/main_mkfs.c | 6 +- gfs2/tool/df.c | 2 +- 24 files changed, 417 insertions(+), 348 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index d887838..2300e63 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -178,7 +178,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; @@ -206,16 +206,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. */ @@ -990,8 +992,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; @@ -1006,9 +1008,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); @@ -1510,7 +1513,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; compute_constants(sbp);
bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); @@ -1726,9 +1729,10 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) int error = 0; int j, x; struct gfs1_jindex *jndx; - struct rgrp_list *rgd, *rgdhigh; - osi_list_t *tmp; + struct rgrp_tree *rgd, *rgdhigh; + struct osi_node *n, *next = NULL; struct gfs2_meta_header mh; + uint64_t ri_addr;
mh.mh_magic = GFS2_MAGIC; mh.mh_type = GFS2_METATYPE_RB; @@ -1746,8 +1750,9 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) by jadd. gfs_grow adds rgs out of order, so we can't count on them being in ascending order. */ rgdhigh = NULL; - osi_list_foreach(tmp, &sdp->rglist) { - rgd = osi_list_entry(tmp, struct rgrp_list, list); + for (n = osi_first(&sdp->rgtree); n; n = next) { + next = osi_next(n); + rgd = (struct rgrp_tree *)n; if (rgd->ri.ri_addr < jndx->ji_addr && ((rgdhigh == NULL) || (rgd->ri.ri_addr > rgdhigh->ri.ri_addr))) @@ -1759,15 +1764,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; @@ -1810,9 +1812,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 */ @@ -1988,16 +1987,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 */ @@ -2132,6 +2132,7 @@ int main(int argc, char **argv) /* ---------------------------------------------- */ if (!error) { int jreduce = 0; + /* Now we've got to treat it as a gfs2 file system */ compute_constants(&sb2);
@@ -2187,7 +2188,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 3c45060..b615b19 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 (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 3cc05f4..d3b1f24 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -1166,7 +1166,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) { @@ -1484,7 +1484,7 @@ static void rgcount(void) printf("%lld RGs in this file system.\n", (unsigned long long)sbd.md.riinode->i_di.di_size / risize()); inode_put(&sbd.md.riinode); - gfs2_rgrp_free(&sbd.rglist); + gfs2_rgrp_free(&sbd.rgtree); exit(EXIT_SUCCESS); }
@@ -1757,7 +1757,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() || @@ -1784,7 +1784,7 @@ static void read_superblock(int fd) sbd.utsize = GFS2_DEFAULT_UTSIZE; sbd.qcsize = GFS2_DEFAULT_QCSIZE; sbd.time = time(NULL); - osi_list_init(&sbd.rglist); + sbd.rgtree.osi_node = NULL; gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */ /* Check to see if this is really gfs1 */ if (sbd1->sb_fs_format == GFS_FORMAT_FS && @@ -2102,7 +2102,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; @@ -2117,16 +2117,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; @@ -2141,12 +2142,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, @@ -2167,7 +2169,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; @@ -2201,7 +2203,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; @@ -2502,7 +2504,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); }
@@ -2513,7 +2515,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) @@ -2545,7 +2547,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); }
@@ -2556,7 +2558,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)) { @@ -2566,7 +2568,7 @@ static void find_change_block_alloc(int *newval) *newval); for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++) printf("%d - %s\n", i, allocdesc[gfs1][i]); - gfs2_rgrp_free(&sbd.rglist); + gfs2_rgrp_free(&sbd.rgtree); exit(-1); } ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block; @@ -2592,12 +2594,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); @@ -3525,7 +3527,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]); @@ -3558,7 +3560,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') @@ -3575,7 +3577,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; @@ -3584,7 +3586,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]); @@ -3593,7 +3595,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); } } @@ -3705,6 +3707,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 8732c27..d90b4c5 100644 --- a/gfs2/edit/hexedit.h +++ b/gfs2/edit/hexedit.h @@ -262,11 +262,11 @@ static inline int risize(void) }
/* ------------------------------------------------------------------------ */ -/* 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 fd0e1e4..337d98a 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -600,7 +600,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; @@ -642,11 +642,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; - osi_list_t *tmp; int rgcount; uint64_t jindex_block; struct gfs2_buffer_head *lbh; - struct rgrp_list *last_rgd; + struct rgrp_tree *last_rgd, *prev_rgd; struct metafd mfd;
slow = (saveoption == 1); @@ -665,7 +664,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel) if (!slow) { device_geometry(&sbd); fix_device_geometry(&sbd); - osi_list_init(&sbd.rglist); + sbd.rgtree.osi_node = NULL; if (!gfs1) sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; compute_constants(&sbd); @@ -716,6 +715,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); @@ -723,9 +723,12 @@ 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); - fssize = last_rgd->ri.ri_addr + rgrp_size(last_rgd); + 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; fssize *= sbd.bsize; printf("Done. File system size: %s\n\n", @@ -734,6 +737,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 @@ -755,12 +760,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/fs_recovery.c b/gfs2/fsck/fs_recovery.c index 214aa18..da80f5c 100644 --- a/gfs2/fsck/fs_recovery.c +++ b/gfs2/fsck/fs_recovery.c @@ -14,6 +14,7 @@ #include <errno.h> #include <inttypes.h> #include <linux_endian.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index 75f81f5..7855db4 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -121,7 +121,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); @@ -142,10 +142,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; @@ -153,9 +152,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 - 1 > rmax) rmax = ri->ri_data0 + ri->ri_data - 1; @@ -200,7 +199,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) { @@ -305,17 +304,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) @@ -542,7 +542,7 @@ static int fetch_rgrps(struct gfs2_sbd *sdp) *******************************************************************/ log_warn( _("Validating Resource Group index.\n")); for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) { - int ret; + int ret = 0;
log_warn( _("Level %d rgrp check: %s.\n"), trust_lvl + 1, level_desc[trust_lvl]); @@ -749,7 +749,7 @@ static int get_lockproto_table(struct gfs2_sbd *sdp) { FILE *fp; char line[PATH_MAX]; - char *cluname, *end; + char *cluname = NULL, *end = NULL; const char *fsname, *cfgfile = "/etc/cluster/cluster.conf";
memset(sdp->lockproto, 0, sizeof(sdp->lockproto)); @@ -1218,7 +1218,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 ********** @@ -1298,7 +1298,7 @@ static int init_jindex(struct gfs2_sbd *sdp)
err = build_jindex(sdp); /* Free rgrps read in earlier (re-read them later) */ - gfs2_rgrp_free(&sdp->rglist); + gfs2_rgrp_free(&sdp->rgtree); if (err) { log_crit(_("Error %d rebuilding jindex\n"), err); return err; diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c index 4e556f1..40aaaab 100644 --- a/gfs2/fsck/main.c +++ b/gfs2/fsck/main.c @@ -159,8 +159,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)]; @@ -177,8 +177,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 a61971c..035fb34 100644 --- a/gfs2/fsck/metawalk.c +++ b/gfs2/fsck/metawalk.c @@ -43,7 +43,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 6075ac5..c0369c5 100644 --- a/gfs2/fsck/pass1.c +++ b/gfs2/fsck/pass1.c @@ -1505,10 +1505,10 @@ static int check_system_inodes(struct gfs2_sbd *sdp) */ int pass1(struct gfs2_sbd *sdp) { + struct osi_node *n, *next = NULL; struct gfs2_buffer_head *bh; - osi_list_t *tmp; uint64_t block; - struct rgrp_list *rgd; + struct rgrp_tree *rgd; int first; uint64_t i; uint64_t blk_count; @@ -1533,11 +1533,11 @@ int pass1(struct gfs2_sbd *sdp) * uses the rg bitmaps, so maybe that's the best way to start * things - we can change the method later if necessary. */ - for (tmp = sdp->rglist.next; tmp != &sdp->rglist; - tmp = tmp->next, rg_count++) { - log_debug( _("Checking metadata in Resource Group #%" PRIu64 "\n"), - rg_count); - rgd = osi_list_entry(tmp, struct rgrp_list, list); + for (n = osi_first(&sdp->rgtree); n; n = next, rg_count++) { + next = osi_next(n); + log_debug( _("Checking metadata in Resource Group #%llu\n"), + (unsigned long long)rg_count); + rgd = (struct rgrp_tree *)n; for (i = 0; i < rgd->ri.ri_length; i++) { log_debug( _("rgrp block %lld (0x%llx) " "is now marked as 'rgrp data'\n"), diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c index f2d23cd..a811cdb 100644 --- a/gfs2/fsck/pass5.c +++ b/gfs2/fsck/pass5.c @@ -157,7 +157,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; @@ -221,18 +221,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[3]; uint64_t rg_count = 0;
/* Reconcile RG bitmaps with fsck bitmap */ - for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ + for (n = osi_first(&sdp->rgtree); n; n = next) { + next = osi_next(n); if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ return FSCK_OK; log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count); memset(count, 0, sizeof(count)); - rgp = osi_list_entry(tmp, struct rgrp_list, list); + rgp = (struct rgrp_tree *)n;
rg_count++; /* Compare the bitmaps and report the differences */ diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c index 2afa4ce..fb4d092 100644 --- a/gfs2/fsck/rgrepair.c +++ b/gfs2/fsck/rgrepair.c @@ -110,24 +110,22 @@ static int is_false_rg(uint64_t block) * same RG size determined by the original mkfs, so recovery is easier. * */ -static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, - int *num_rgs) +static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs) { + struct osi_node *n, *next = NULL; struct gfs2_buffer_head *bh; uint64_t shortest_dist_btwn_rgs; uint64_t blk, block_of_last_rg; 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; struct gfs2_rindex buf, tmpndx; int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd; - osi_list_t *tmp;
/* Figure out if there are any RG-looking blocks in the journal we need to ignore. */ find_journaled_rgs(sdp); - osi_list_init(ret_list); number_of_rgs = 0; initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1; block_of_last_rg = sdp->sb_addr + 1; @@ -210,6 +208,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, log_debug( _("Adjusted first RG distance: 0x%" PRIx64 "\n"), first_rg_dist); } /* if first RG distance is within tolerance */ + /* -------------------------------------------------------------- */ /* Now go through the RGs and verify their integrity, fixing as */ /* needed when corruption is encountered. */ @@ -223,15 +222,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 rg 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. */ @@ -316,10 +312,10 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list, /* ---------------------------------------------- */ /* Now dump out the information (if verbose mode) */ /* ---------------------------------------------- */ - log_debug( _("RG index rebuilt as follows:\n")); - for (tmp = ret_list, rgi = 0; tmp != ret_list; - tmp = tmp->next, rgi++) { - calc_rgd = osi_list_entry(tmp, struct rgrp_list, list); + log_debug( _("rindex rebuilt as follows:\n")); + 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, @@ -344,15 +340,13 @@ 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) { - osi_list_init(ret_list); sdp->rgsize = GFS2_DEFAULT_RGSIZE; /* compute_rgrp_layout adjusts */ device_geometry(sdp); fix_device_geometry(sdp); /* Compute the default resource group layout as mkfs would have done */ - compute_rgrp_layout(sdp, FALSE); + compute_rgrp_layout(sdp, &sdp->rgcalc, FALSE); build_rgrps(sdp, FALSE); /* FALSE = calc but don't write to disk. */ *num_rgs = 0; log_debug( _("fs_total_size = 0x%" PRIX64 " blocks.\n"), @@ -365,12 +359,8 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list, /* the index. */ /* ----------------------------------------------------------------- */ *num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex); - log_warn( _("L2: 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; + + sdp->rgcalc.osi_node = NULL; return 0; }
@@ -378,8 +368,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;
@@ -418,18 +408,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); @@ -440,7 +428,6 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list, memcpy(&exp->rg, &rgd->rg, sizeof(exp->rg)); exp->bits = NULL; gfs2_compute_bitstructs(sdp, exp); - osi_list_add_prev(&exp->list, ret_list); } sdp->rgrps = *num_rgs; return 0; @@ -456,10 +443,9 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list, */ 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; - 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) @@ -470,45 +456,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); - if (error) + error = expect_rindex_sanity(sdp, &calc_rg_count); + if (error) { + 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->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 */ - error = gfs2_rindex_rebuild(sdp, &expected_rglist, - &calc_rg_count); + /* Free previous incarnations in memory, if any. */ + gfs2_rgrp_free(&sdp->rgtree); + + error = gfs2_rindex_rebuild(sdp, &calc_rg_count); if (error) { - log_crit( _("Error rebuilding rg list.\n")); - gfs2_rgrp_free(&expected_rglist); + log_crit( _("Error rebuilding rgrp list.\n")); + 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, (unsigned long long)sdp->rgrps); if (calc_rg_count != sdp->rgrps) { - log_warn( _("L%d: They don't match; either (1) the fs was extended, (2) an odd\n"), trust_lvl + 1); - log_warn( _("L%d: rg size was used, or (3) we have a corrupt rg index.\n"), trust_lvl + 1); - gfs2_rgrp_free(&expected_rglist); - gfs2_rgrp_free(&sdp->rglist); + log_warn( _("L%d: They don't match; either (1) the fs was " + "extended, (2) an odd\n"), trust_lvl + 1); + log_warn( _("L%d: rgrp size was used, or (3) we have a corrupt " + "rg index.\n"), trust_lvl + 1); + gfs2_rgrp_free(&sdp->rgcalc); + gfs2_rgrp_free(&sdp->rgtree); return -1; } /* ------------------------------------------------------------- */ @@ -519,28 +513,46 @@ 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; - act = act->next, exp = exp->next, rg++) { - struct rgrp_list *expected, *actual; - - expected = osi_list_entry(exp, struct rgrp_list, list); - actual = osi_list_entry(act, struct rgrp_list, list); - if (!ri_equal(actual->ri, expected->ri, ri_addr) || - !ri_equal(actual->ri, expected->ri, ri_length) || + 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 = (struct rgrp_tree *)e; + actual = (struct rgrp_tree *)n; + if (actual->ri.ri_addr < expected->ri.ri_addr) { + 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) { + e = enext; + discrepancies++; + log_info(_("%d addr: 0x%llx > 0x%llx * mismatch\n"), + rg + 1, actual->ri.ri_addr, + expected->ri.ri_addr); + continue; + } + if (!ri_equal(actual->ri, expected->ri, ri_length) || !ri_equal(actual->ri, expected->ri, ri_data0) || !ri_equal(actual->ri, expected->ri, ri_data) || !ri_equal(actual->ri, expected->ri, ri_bitbytes)) { discrepancies++; } + n = next; + e = enext; } if (trust_lvl < distrust && discrepancies > (trust_lvl * 8)) { log_warn( _("Level %d didn't work. Too many descepencies.\n"), trust_lvl + 1); log_warn( _("%d out of %d RGs did not match what was expected.\n"), discrepancies, rg); - gfs2_rgrp_free(&expected_rglist); - gfs2_rgrp_free(&sdp->rglist); + gfs2_rgrp_free(&sdp->rgcalc); + gfs2_rgrp_free(&sdp->rgtree); return -1; } /* ------------------------------------------------------------- */ @@ -548,19 +560,40 @@ 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; - act != &sdp->rglist && exp != &expected_rglist; - act = act->next, exp = exp->next, rg++) { - struct rgrp_list *expected, *actual; - - expected = osi_list_entry(exp, struct rgrp_list, list); - actual = osi_list_entry(act, struct rgrp_list, list); - ri_compare(rg, actual->ri, expected->ri, ri_addr, PRIx64); - ri_compare(rg, actual->ri, expected->ri, ri_length, PRIx32); - ri_compare(rg, actual->ri, expected->ri, ri_data0, PRIx64); - ri_compare(rg, actual->ri, expected->ri, ri_data, PRIx32); - ri_compare(rg, actual->ri, expected->ri, ri_bitbytes, - PRIx32); + for (rg = 0, n = osi_first(&sdp->rgtree), e = osi_first(&sdp->rgcalc); + e && !fsck_abort; rg++) { + struct rgrp_tree *expected, *actual; + + 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 (!n) { /* end of actual rindex */ + log_err( _("Entry missing from rindex: 0x%llx\n"), + (unsigned long long)expected->ri.ri_addr); + actual = rgrp_insert(&sdp->rgtree, + expected->ri.ri_addr); + if (!actual) { + log_err(_("Out of memory!\n")); + break; + } + rindex_modified = 1; + } else { + actual = (struct rgrp_tree *)n; + ri_compare(rg, actual->ri, expected->ri, ri_addr, + "llx"); + ri_compare(rg, actual->ri, expected->ri, ri_length, + PRIx32); + ri_compare(rg, actual->ri, expected->ri, ri_data0, + "llx"); + ri_compare(rg, actual->ri, expected->ri, ri_data, + PRIx32); + ri_compare(rg, actual->ri, expected->ri, ri_bitbytes, + PRIx32); + } /* If we modified the index, write it back to disk. */ if (rindex_modified) { if (query( _("Fix the index? (y/n)"))) { @@ -586,23 +619,27 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane) gfs2_compute_bitstructs(sdp, actual); rindex_modified = FALSE; } + 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; - 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) @@ -617,7 +654,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/fsck/util.c b/gfs2/fsck/util.c index 79d76cf..d95461b 100644 --- a/gfs2/fsck/util.c +++ b/gfs2/fsck/util.c @@ -492,7 +492,6 @@ void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il) int set_ip_blockmap(struct gfs2_inode *ip, int instree) { uint64_t block = ip->i_bh->b_blocknr; - struct gfs2_sbd *sdp = ip->i_sbd; uint32_t mode;
mode = ip->i_di.di_mode & S_IFMT; diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c index 11b6fb2..4834a2a 100644 --- a/gfs2/libgfs2/fs_bits.c +++ b/gfs2/libgfs2/fs_bits.c @@ -188,7 +188,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;
@@ -236,7 +236,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 9969577..58c1c89 100644 --- a/gfs2/libgfs2/fs_geometry.c +++ b/gfs2/libgfs2/fs_geometry.c @@ -62,12 +62,14 @@ static uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev, int rgs * 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, rglength; + uint64_t rgaddr;
sdp->new_rgrps = 0; dev = &sdp->device; @@ -78,7 +80,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; @@ -87,10 +89,10 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified) uint64_t old_length, new_chunk;
log_info("Existing resource groups:\n"); - rgsize_specified = TRUE; /* consistently use existing size */ - 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, @@ -109,32 +111,31 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
log_info("\nNew resource groups:\n"); for (; rgrp < nrgrp; rgrp++) { - zalloc(rl, sizeof(struct rgrp_list)); - if (rgrp) { - rl->start = rlast->start + rlast->length; + rgaddr = rlast->start + rlast->length; + rl = rgrp_insert(rgtree, rgaddr); rl->length = rglength; } else { - rl->start = dev->start; + rgaddr = dev->start; + rl = rgrp_insert(rgtree, rgaddr); rl->length = dev->length - (nrgrp - 1) * (dev->length / nrgrp); } - + rl->start = rgaddr; log_info("%d: start: %" PRIu64 " (0x%" PRIx64 "), length = %"PRIu64" (0x%" PRIx64 ")\n", rgrp + 1, rl->start, rl->start, rl->length, rl->length); - osi_list_add_prev(&rl->list, head); rlast = rl; }
sdp->rgrps = nrgrp; - if (sdp->debug) { log_info("\n");
- for (tmp = head->next; tmp != head; tmp = tmp->next) { - rl = osi_list_entry(tmp, struct rgrp_list, list); + for (n = osi_first(rgtree); n; n = next) { + next = osi_next(n); + rl = (struct rgrp_tree *)n; log_info("rg_o = %llu, rg_l = %llu\n", rl->start, rl->length); } @@ -185,8 +186,8 @@ rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks, uint32_t *bitblocks) */ 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; @@ -195,11 +196,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 1c20e61..78b3a8d 100644 --- a/gfs2/libgfs2/fs_ops.c +++ b/gfs2/libgfs2/fs_ops.c @@ -117,8 +117,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; @@ -126,14 +126,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; @@ -1676,7 +1676,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 */ @@ -1698,7 +1698,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/gfs1.c b/gfs2/libgfs2/gfs1.c index 5018334..41edf16 100644 --- a/gfs2/libgfs2/gfs1.c +++ b/gfs2/libgfs2/gfs1.c @@ -234,8 +234,8 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) { unsigned int rg; int error; - struct gfs2_rindex buf; - struct rgrp_list *rgd, *prev_rgd; + struct gfs2_rindex buf, ri; + struct rgrp_tree *rgd = NULL, *prev_rgd = NULL; uint64_t prev_length = 0;
*count1 = 0; @@ -252,20 +252,14 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) 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); + gfs2_rindex_in(&ri, (char *)&buf); + 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) { prev_length = rgd->start - prev_rgd->start; - prev_rgd->length = prev_length; + prev_rgd->length = rgrp_size(prev_rgd); }
if(gfs2_compute_bitstructs(sdp, rgd)) @@ -275,7 +269,7 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) prev_rgd = rgd; } if (prev_rgd) - prev_rgd->length = prev_length; + prev_rgd->length = rgrp_size(prev_rgd); return 0; }
@@ -291,17 +285,18 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1) */ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, 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 (gfs1_rindex_read(sdp, fd, &count1)) 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; @@ -323,7 +318,7 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet) return 0;
fail: - gfs2_rgrp_free(&sdp->rglist); + gfs2_rgrp_free(&sdp->rgtree); return -1; }
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 87c65c6..95a4ddb 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -23,6 +23,7 @@ #include <linux/gfs2_ondisk.h> #include "osi_list.h" #include "copyright.cf" +#include "osi_tree.h"
#ifndef TRUE #define TRUE (1) @@ -94,8 +95,8 @@ struct gfs2_bitmap }; typedef struct gfs2_bitmap gfs2_bitmap_t;
-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 */
@@ -221,7 +222,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;
@@ -307,22 +309,23 @@ unsigned long gfs2_bitfit(const unsigned char *buf, const unsigned int len, unsigned long goal, unsigned char state);
/* functions with blk #'s that are rgrp relative */ -uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal, - unsigned char old_state, - unsigned char new_state, int do_it); -int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno); +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);
/* 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 */ -void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks, - uint32_t *bitblocks); -void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified); -void build_rgrps(struct gfs2_sbd *sdp, int write); +extern void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks, + uint32_t *bitblocks); +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 */ #define IS_LEAF (1) @@ -583,13 +586,15 @@ int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head); int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
/* rgrp.c */ -extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd); -extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk); -extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd); -extern void gfs2_rgrp_relse(struct rgrp_list *rgd); -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); /* figure out the size of the given resource group, in blocks */ -static inline unsigned int rgrp_size(struct rgrp_list *rgrp) +static inline unsigned int rgrp_size(struct rgrp_tree *rgrp) { return rgrp->ri.ri_data + rgrp->ri.ri_length; } @@ -609,9 +614,9 @@ 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); /* super.c */ extern int check_sb(struct gfs2_sb *sb); diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index 438d320..e9addeb 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -24,7 +24,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; @@ -104,33 +104,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; + 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; - } - if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) { - prev_rgd = rgd; - return rgd; - } } return NULL; } @@ -140,7 +128,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;
@@ -164,7 +152,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;
@@ -177,12 +165,44 @@ 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; + struct osi_node *n;
- 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 */ gfs2_rgrp_relse(rgd); /* free them all. */ if(rgd->bits) @@ -191,7 +211,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 b7851e8..8a19afe 100644 --- a/gfs2/libgfs2/structures.c +++ b/gfs2/libgfs2/structures.c @@ -320,8 +320,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;
@@ -330,9 +330,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);
@@ -498,24 +498,24 @@ int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format) * * Returns: 0 on success, -1 when finished */ -int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first) +int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first) { struct gfs2_bitmap *bits = NULL; uint32_t length = rgd->ri.ri_length; uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0); int i;
- 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, @@ -526,7 +526,7 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first) } blk=0; } - if(i == length) + if (i == length) return -1; return 0; } @@ -540,7 +540,7 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first) * * Returns: 0 on success, -1 on error or finished */ -int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, +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 51a8047..3a51eb4 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -144,12 +144,12 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane) unsigned int rg; int error; struct gfs2_rindex 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++) { @@ -164,15 +164,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); + gfs2_rindex_in(&ri, (char *)&buf); + 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) { @@ -219,17 +213,18 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane) */ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane) { - 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); + goto fail; + 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; @@ -247,7 +242,7 @@ 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 252bcb2..9aba5da 100644 --- a/gfs2/mkfs/main_grow.c +++ b/gfs2/mkfs/main_grow.c @@ -129,16 +129,13 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
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; @@ -151,15 +148,19 @@ 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_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); } /* Build the remaining resource groups */ build_rgrps(sdp, !test); @@ -176,17 +177,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); zalloc(buf, writelen); @@ -196,13 +199,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) { @@ -284,7 +288,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; @@ -296,7 +299,7 @@ main_grow(int argc, char *argv[]) while ((argc - optind) > 0) { int sane; - struct rgrp_list *last_rgrp; + struct rgrp_tree *last_rgrp;
sdp->path_name = argv[optind++]; sdp->path_fd = open(sdp->path_name, O_RDONLY); @@ -312,7 +315,8 @@ main_grow(int argc, char *argv[]) sdp->device_name, strerror(errno)); device_geometry(sdp); 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; @@ -340,11 +344,11 @@ main_grow(int argc, char *argv[]) /* the existing RGs, and only write to the index at EOF. */ ri_update(sdp, rindex_fd, &rgcount, &sane); fssize = filesystem_size(sdp); - if (osi_list_empty(head)) { + if (!sdp->rgtree.osi_node) { log_err(_("Error: No resource groups found.\n")); goto out; } - last_rgrp = osi_list_entry(head->prev, struct rgrp_list, list); + last_rgrp = (struct rgrp_tree *)osi_last(&sdp->rgtree); sdp->rgsize = GFS2_DEFAULT_RGSIZE; rgsize = rgrp_size(last_rgrp); fsgrowth = ((sdp->device.length - fssize) * sdp->bsize); @@ -359,15 +363,14 @@ 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); } out: /* 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 bfe6c45..a2ed1be 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -361,7 +361,7 @@ 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 */ @@ -408,7 +408,7 @@ 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)); @@ -438,7 +438,7 @@ 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"), diff --git a/gfs2/tool/df.c b/gfs2/tool/df.c index 26299ff..c4a6d93 100644 --- a/gfs2/tool/df.c +++ b/gfs2/tool/df.c @@ -112,7 +112,7 @@ do_df_one(char *path) sbd.rgsize = GFS2_DEFAULT_RGSIZE; sbd.utsize = GFS2_DEFAULT_UTSIZE; sbd.qcsize = GFS2_DEFAULT_QCSIZE; - osi_list_init(&sbd.rglist); + sbd.rgtree.osi_node = NULL;
do_lseek(sbd.device_fd, 0x10 * sbd.bsize); do_read(sbd.device_fd, buf, sbd.bsize); /* read in the superblock */
cluster-commits@lists.fedorahosted.org