Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cdb69478a8101a710a3a52ffb5412f4376e39437
Parent: c6df45775f8a255b928b839a8c0201c631c8c811
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:31:51 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:26 2010 -0600
Remove nvbuf_list and use fewer buffers
This preliminary patch is a starting point for disentangling the
issues fsck has with libgfs2/buf.c. Rather than read in all the
rgrp bitmaps into memory, all in a non-volatile linked list, this
patch keeps the same linked list of rgrps, but only reads in the
bitmaps on an as-needed basis, and only for short-term. This is
also an attempt to eliminate the fairly new non-volatile linked
buffer list and change all the code in gfs2-utils so that they
should not depend on the list being non-volatile. The whole
non-volatile thing was a stop-gap temporary solution so that we
could minimize the possibility of regression. In addition to
getting rid of the non-volatile linked list, it also reduces the
remaining linked list of buffers from 128MB to 1MB so that much
fewer buffers will be kept in memory. That could drive a lot of
bugs out of their hiding places.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 125 +++++++++++++++++++++++++++----------------
gfs2/edit/hexedit.c | 57 ++++++++++----------
gfs2/edit/savemeta.c | 33 +++++++++---
gfs2/fsck/fs_recovery.c | 1 -
gfs2/fsck/initialize.c | 3 +-
gfs2/fsck/main.c | 1 -
gfs2/fsck/pass1.c | 26 +++++++--
gfs2/fsck/pass5.c | 42 ++++++++++-----
gfs2/fsck/rgrepair.c | 93 ++++++++++++++++++--------------
gfs2/libgfs2/block_list.c | 15 +++---
gfs2/libgfs2/buf.c | 4 ++
gfs2/libgfs2/fs_bits.c | 44 ++++++++++++---
gfs2/libgfs2/fs_geometry.c | 19 +++----
gfs2/libgfs2/fs_ops.c | 82 ++++++++++++++++------------
gfs2/libgfs2/gfs1.c | 30 +++++++++--
gfs2/libgfs2/libgfs2.h | 32 +++++------
gfs2/libgfs2/rgrp.c | 34 ++++--------
gfs2/libgfs2/structures.c | 13 +++--
gfs2/libgfs2/super.c | 34 +++++++++---
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 4 +-
21 files changed, 424 insertions(+), 272 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 4034e74..020b4e5 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -157,34 +157,29 @@ void print_it(const char *label, const char *fmt, const char *fmt2,
...)
/* valid in gfs1 but invalid in gfs2). */
/* ------------------------------------------------------------------------- */
static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
- int read_disk)
+ struct gfs2_buffer_head **rgbh)
{
uint32_t blk;
int x, y;
struct gfs2_rindex *ri;
unsigned char state;
- struct gfs2_buffer_head *bh;
ri = &rgd2->ri;
- if (gfs2_compute_bitstructs(sdp, rgd2)) { /* mallocs bh as array */
+ if (gfs2_compute_bitstructs(sdp, rgd2)) {
log_crit("gfs2_convert: Error converting bitmaps.\n");
exit(-1);
}
for (blk = 0; blk < ri->ri_length; blk++) {
- bh = bget_generic(&sdp->nvbuf_list, ri->ri_addr + blk,
- read_disk, read_disk);
- if (!rgd2->bh[blk])
- rgd2->bh[blk] = bh;
- x = (blk) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+ x = (blk) ? sizeof(struct gfs2_meta_header) :
+ sizeof(struct gfs2_rgrp);
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (rgd2->bh[blk]->b_data[x] >>
- (GFS2_BIT_SIZE * y)) & 0x03;
+ state = (rgbh[blk]->b_data[x] >>
+ (GFS2_BIT_SIZE * y)) & 0x03;
if (state == 0x02) /* unallocated metadata state invalid */
- rgd2->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+ rgbh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
}
- brelse(bh, updated);
}
}/* convert_bitmaps */
@@ -195,38 +190,49 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list
*rgd2,
static int convert_rgs(struct gfs2_sbd *sbp)
{
struct rgrp_list *rgd;
+ struct gfs2_rgrp rg;
osi_list_t *tmp;
- struct gfs2_buffer_head *bh;
struct gfs1_rgrp *rgd1;
int rgs = 0;
+ struct gfs2_buffer_head **rgbh;
/* --------------------------------- */
/* Now convert its rgs into gfs2 rgs */
/* --------------------------------- */
osi_list_foreach(tmp, &sbp->rglist) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ gfs2_rgrp_read(sbp, rgd, rgbh, &rg);
+ rgd1 = (struct gfs1_rgrp *)&rg; /* recast as gfs1 structure */
/* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */
/* convert from be to cpu. We must do it now. */
- rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+ rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+ rgd->rg_free = rg.rg_free;
/* Zero it out so we don't add it again in case something breaks */
/* later on in the process and we have to re-run convert */
rgd1->rg_freemeta = 0;
sbp->blks_total += rgd->ri.ri_data;
- sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free);
+ sbp->blks_alloced += (rgd->ri.ri_data - rg.rg_free);
sbp->dinodes_alloced += rgd1->rg_useddi;
- convert_bitmaps(sbp, rgd, TRUE);
+ convert_bitmaps(sbp, rgd, rgbh);
/* Write the updated rgrp to the gfs2 buffer */
- bh = bget(&sbp->nvbuf_list,
- rgd->ri.ri_addr); /* get a gfs2 buffer for the rg */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
- brelse(bh, updated); /* release the buffer */
+ gfs2_rgrp_out(&rg, rgbh[0]->b_data);
rgs++;
if (rgs % 100 == 0) {
printf(".");
fflush(stdout);
}
+ free(rgbh);
}
return 0;
}/* superblock_cvt */
@@ -694,6 +700,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t
root_inode_addr)
int first;
int error = 0;
int rgs_processed = 0;
+ struct gfs2_buffer_head **rgbh;
+ struct gfs2_rgrp rg;
log_notice("Converting inodes.\n");
sbp->md.next_inum = 1; /* starting inode numbering */
@@ -707,8 +715,18 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t
root_inode_addr)
rgs_processed++;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
first = 1;
- if (gfs2_rgrp_read(sbp, rgd)) {
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+ if (gfs2_rgrp_read(sbp, rgd, rgbh, &rg)) {
log_crit("Unable to read rgrp.\n");
+ free(rgbh);
return -1;
}
while (1) { /* for all inodes in the resource group */
@@ -753,9 +771,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t
root_inode_addr)
sizeof(struct gfs2_rgrp);
/* if it's on this page */
if (buf_offset + bitmap_byte < sbp->bsize) {
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &=
+ rgbh[blk]->b_data[buf_offset + bitmap_byte] &=
~(0x03 << (GFS2_BIT_SIZE * byte_bit));
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
+ rgbh[blk]->b_data[buf_offset + bitmap_byte] |=
(0x01 << (GFS2_BIT_SIZE * byte_bit));
break;
}
@@ -765,7 +783,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t
root_inode_addr)
brelse(bh, updated);
first = 0;
} /* while 1 */
- gfs2_rgrp_relse(rgd, updated);
+ gfs2_rgrp_relse(rgd, updated, rgbh);
+ free(rgbh);
} /* for all rgs */
log_notice("\r%" PRIu64" inodes from %d rgs converted.",
sbp->md.next_inum, rgs_processed);
@@ -1091,8 +1110,7 @@ static int init(struct gfs2_sbd *sbp)
sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sbp->bsize = sbp->sd_sb.sb_bsize;
osi_list_init(&sbp->rglist);
- init_buf_list(sbp, &sbp->buf_list, 128 << 20);
- init_buf_list(sbp, &sbp->nvbuf_list, 0xffffffff);
+ init_buf_list(sbp, &sbp->buf_list, 1 << 20); /* only use 1MB of bufs */
if (compute_constants(sbp)) {
log_crit("Error: Bad constants (1)\n");
exit(-1);
@@ -1319,6 +1337,8 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
struct rgrp_list *rgd, *rgdhigh;
osi_list_t *tmp;
struct gfs2_meta_header mh;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
@@ -1329,12 +1349,12 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
uint64_t size;
jndx = &sd_jindex[j];
- /* go through all rg index entries, keeping track of the highest */
- /* that's still in the first subdevice. */
- /* Note: we really should go through all of the rgindex because */
- /* we might have had rg's added by gfs_grow, and journals added */
- /* by jadd. gfs_grow adds rgs out of order, so we can't count */
- /* on them being in ascending order. */
+ /* go through all rg index entries, keeping track of the
+ highest that's still in the first subdevice.
+ Note: we really should go through all of the rgindex because
+ we might have had rg's added by gfs_grow, and journals added
+ by jadd. gfs_grow adds rgs out of order, so we can't count
+ on them being in ascending order. */
rgdhigh = NULL;
osi_list_foreach(tmp, &sdp->rglist) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
@@ -1359,11 +1379,11 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
}
memset(rgd, 0, sizeof(struct rgrp_list));
size = jndx->ji_nsegment * be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size);
- rgd->rg.rg_header.mh_magic = GFS2_MAGIC;
- rgd->rg.rg_header.mh_type = GFS2_METATYPE_RG;
- rgd->rg.rg_header.mh_format = GFS2_FORMAT_RG;
- rgd->rg.rg_flags = 0;
- rgd->rg.rg_dinodes = 0;
+ rg.rg_header.mh_magic = GFS2_MAGIC;
+ rg.rg_header.mh_type = GFS2_METATYPE_RG;
+ rg.rg_header.mh_format = GFS2_FORMAT_RG;
+ rg.rg_flags = 0;
+ rg.rg_dinodes = 0;
rgd->ri.ri_addr = jndx->ji_addr; /* new rg addr becomes ji addr */
rgd->ri.ri_length = rgrp_length(size, sdp); /* aka bitblocks */
@@ -1374,19 +1394,32 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
/* Round down to nearest multiple of GFS2_NBBY */
while (rgd->ri.ri_data & 0x03)
rgd->ri.ri_data--;
- rgd->rg.rg_free = rgd->ri.ri_data;
+ rg.rg_free = rgd->ri.ri_data;
+ rgd->rg_free = rg.rg_free;
rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
- convert_bitmaps(sdp, rgd, FALSE); /* allocates rgd->bh */
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ convert_bitmaps(sdp, rgd, rgbh);
for (x = 0; x < rgd->ri.ri_length; x++) {
- rgd->bh[x]->b_count++;
+ rgbh[x]->b_count++;
if (x)
- gfs2_meta_header_out(&mh, rgd->bh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgbh[x]->b_data);
else
- gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data);
+ gfs2_rgrp_out(&rg, rgbh[x]->b_data);
}
/* Add the new gfs2 rg to our list: We'll output the rg index later. */
osi_list_add_prev((osi_list_t *)&rgd->list,
(osi_list_t *)&sdp->rglist);
+ free(rgbh);
} /* for each journal */
return error;
}/* journ_space_to_rg */
@@ -1527,7 +1560,7 @@ int main(int argc, char **argv)
if (error)
log_crit("%s: Unable to convert resource groups.\n",
device);
- bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
+ bcommit(&sb2.buf_list); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Renumber the inodes consecutively. */
@@ -1595,12 +1628,11 @@ int main(int argc, char **argv)
inode_put(sb2.md.statfs, updated);
bcommit(&sb2.buf_list); /* write the buffers to disk */
- bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
/* Now delete the now-obsolete gfs1 files: */
remove_obsolete_gfs1(&sb2);
/* Now free all the in memory */
- gfs2_rgrp_free(&sb2.rglist, updated);
+ gfs2_rgrp_free(&sb2.rglist);
log_notice("Committing changes to disk.\n");
fflush(stdout);
/* Set filesystem type in superblock to gfs2. We do this at the */
@@ -1614,7 +1646,6 @@ int main(int argc, char **argv)
brelse(bh, updated);
bsync(&sb2.buf_list); /* write the buffers to disk */
- bsync(&sb2.nvbuf_list); /* write the buffers to disk */
error = fsync(sb2.device_fd);
if (error)
perror(device);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index b6b8fe9..6a052b2 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -563,10 +563,9 @@ int display_block_type(const char *lpBuffer, int from_restore)
struct rgrp_list *rgd;
rgd = gfs2_blk2rgrpd(&sbd, block);
- if (rgd) {
+ if (rgd)
type = gfs2_get_bitmap(&sbd, block, rgd);
- gfs2_rgrp_relse(rgd, not_updated);
- } else
+ else
type = 4;
screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
if (!screen_chunk_size)
@@ -784,7 +783,7 @@ static void rgcount(void)
printf("%lld RGs in this file system.\n",
(unsigned long long)sbd.md.riinode->i_di.di_size / risize());
inode_put(sbd.md.riinode, not_updated);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
@@ -987,7 +986,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
else {
struct gfs2_buffer_head *tmp_bh;
- tmp_bh = bread(&sbd.nvbuf_list, ri.ri_addr);
+ tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
if (gfs1) {
struct gfs_rgrp rg1;
gfs_rgrp_in(&rg1, tmp_bh->b_data);
@@ -1690,7 +1689,7 @@ static int display_extended(void)
/* ------------------------------------------------------------------------ */
static void read_superblock(int fd)
{
- int count;
+ int count, bitmap_blocks = 0;
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
ioctl(fd, BLKFLSBUF, 0);
@@ -1709,8 +1708,7 @@ static void read_superblock(int fd)
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
sbd.time = time(NULL);
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
- init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+ init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
/* Check to see if this is really gfs1 */
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -1750,7 +1748,8 @@ static void read_superblock(int fd)
sbd.md.riinode = gfs2_load_inode(&sbd,
sbd1->sb_rindex_di.no_addr);
sbd.fssize = sbd.device.length;
- gfs1_ri_update(&sbd, 0, &count, 1);
+ gfs1_rindex_read(&sbd, fd, &count, &bitmap_blocks);
+ /*gfs1_ri_update(&sbd, 0, &count, 1);*/
} else {
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
@@ -1760,7 +1759,8 @@ static void read_superblock(int fd)
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
sbd.fssize = sbd.device.length;
- ri_update(&sbd, 0, &count);
+ rindex_read(&sbd, fd, &count, &bitmap_blocks);
+ /*ri_update(&sbd, 0, &count);*/
}
}
@@ -2030,7 +2030,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int
metatype, int p
else
printf("%llu\n", (unsigned long long)blk);
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(0);
return blk;
@@ -2069,7 +2069,7 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int
metatype, int pri
if (!rgd) {
if (print)
printf("0\n");
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(-1);
}
@@ -2095,7 +2095,7 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int
metatype, int pri
else
printf("%llu\n", (unsigned long long)blk);
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(0);
return blk;
@@ -2129,7 +2129,7 @@ static uint64_t find_metablockoftype(const char *strtype, int
print)
"specified: must be one of:\n");
fprintf(stderr, "sb rg rb di in lf jd lh ld"
" ea ed lb 13 qc\n");
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(-1);
}
return blk;
@@ -2438,7 +2438,7 @@ static void find_print_block_type(void)
type = get_block_type(bh->b_data);
print_block_type(tblock, type, "");
brelse(bh, NOT_UPDATED);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2481,7 +2481,7 @@ static void find_print_block_rg(int bitmap)
printf("-1 (block invalid or part of an rgrp).\n");
}
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2502,7 +2502,7 @@ static void find_change_block_alloc(int *newval)
*newval);
for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
printf("%d - %s\n", i, allocdesc[gfs1][i]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(-1);
}
ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
@@ -2519,17 +2519,16 @@ static void find_change_block_alloc(int *newval)
if (rgd) {
type = gfs2_get_bitmap(&sbd, ablock, rgd);
printf("%d (%s)\n", type, allocdesc[gfs1][type]);
- gfs2_rgrp_relse(rgd, not_updated);
} else {
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
printf("-1 (block invalid or part of an rgrp).\n");
exit(-1);
}
}
}
- gfs2_rgrp_free(&sbd.rglist, (newval) ? updated : not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (newval)
- bcommit(&sbd.nvbuf_list);
+ bcommit(&sbd.buf_list);
exit(0);
}
@@ -3332,7 +3331,7 @@ static void process_parameters(int argc, char *argv[], int pass)
printf("Error: field not specified.\n");
printf("Format is: %s -p <block> field "
"<field> [newvalue]\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
if (isdigit(argv[i + 1][0])) {
@@ -3342,11 +3341,11 @@ static void process_parameters(int argc, char *argv[], int pass)
else
newval = (uint64_t)atoll(argv[i + 1]);
process_field(argv[i], &newval, 1);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
} else {
process_field(argv[i], NULL, 1);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
} else if (!strcmp(argv[i], "blocktype")) {
@@ -3378,7 +3377,7 @@ static void process_parameters(int argc, char *argv[], int pass)
printf("Error: rg # not specified.\n");
printf("Format is: %s rgflags rgnum"
"[newvalue]\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
if (argv[i][0]=='0' && argv[i][1]=='x')
@@ -3395,7 +3394,7 @@ static void process_parameters(int argc, char *argv[], int pass)
new_flags = atoi(argv[i]);
}
set_rgrp_flags(rg, new_flags, set, FALSE);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
} else if (!strcmp(argv[i], "rg")) {
int rg;
@@ -3404,7 +3403,7 @@ static void process_parameters(int argc, char *argv[], int pass)
if (i >= argc - 1) {
printf("Error: rg # not specified.\n");
printf("Format is: %s rg rgnum\n", argv[0]);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_FAILURE);
}
rg = atoi(argv[i]);
@@ -3413,7 +3412,7 @@ static void process_parameters(int argc, char *argv[], int pass)
push_block(temp_blk);
} else {
set_rgrp_flags(rg, 0, FALSE, TRUE);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
}
@@ -3523,6 +3522,6 @@ int main(int argc, char *argv[])
free(buf);
if (indirect)
free(indirect);
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 85fcde7..3a11332 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -471,12 +471,14 @@ static void get_journal_inode_blocks(void)
}
}
-static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t *nrfblock, int first)
+static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *nrfblock, int first)
{
struct gfs2_bitmap *bits = NULL;
uint32_t length = rgd->ri.ri_length;
uint32_t blk = (first)? 0: (uint32_t)((*nrfblock+1)-rgd->ri.ri_data0);
int i;
+ struct gfs2_buffer_head *bh;
if(!first && (*nrfblock < rgd->ri.ri_data0)) {
log_err("next_rg_freemeta: Start block is outside rgrp "
@@ -491,9 +493,11 @@ static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t
*nrfblock, int first
}
for(; i < length; i++){
bits = &rgd->bits[i];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)bh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_UNLINKED);
+ brelse(bh, not_updated);
if(blk != BFITNOENT){
*nrfblock = blk + (bits->bi_start * GFS2_NBBY) +
rgd->ri.ri_data0;
@@ -515,6 +519,8 @@ void savemeta(char *out_fn, int saveoption)
int rgcount;
uint64_t jindex_block;
struct gfs2_buffer_head *bh;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
slow = (saveoption == 1);
sbd.md.journals = 1;
@@ -551,8 +557,7 @@ void savemeta(char *out_fn, int saveoption)
exit(-1);
}
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
- init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+ init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
if (!gfs1)
sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
if (compute_constants(&sbd)) {
@@ -649,7 +654,16 @@ void savemeta(char *out_fn, int saveoption)
int i, first;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- slow = gfs2_rgrp_read(&sbd, rgd);
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ break;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ break;
+ }
+ slow = gfs2_rgrp_read(&sbd, rgd, rgbh, &rg);
if (slow)
continue;
log_debug("RG at %lld (0x%llx) is %u long\n",
@@ -673,7 +687,8 @@ void savemeta(char *out_fn, int saveoption)
if (saveoption != 2) {
int blktype;
- while (!gfs2_next_rg_meta(rgd, &block, first)) {
+ while (!gfs2_next_rg_meta(&sbd, rgd, &block,
+ first)) {
warm_fuzzy_stuff(block, FALSE, TRUE);
blktype = save_block(sbd.device_fd,
out_fd, block);
@@ -684,13 +699,15 @@ void savemeta(char *out_fn, int saveoption)
/* Save off the free/unlinked meta blocks too.
If we don't, we may run into metadata
allocation issues. */
- while (!next_rg_freemeta(rgd, &block, first)) {
+ while (!next_rg_freemeta(&sbd, rgd, &block,
+ first)) {
blktype = save_block(sbd.device_fd,
out_fd, block);
first = 0;
}
}
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
}
}
if (slow) {
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 16480be..763190e 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -576,6 +576,5 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
inode_put(sdp->md.jiinode, not_updated);
/* Sync the buffers to disk so we get a fresh start. */
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
return error;
}
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f9f82fa..11558b0 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -287,8 +287,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
********************************************************************/
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
for(i = 0; i < FSCK_HASH_SIZE; i++) {
osi_list_init(&dir_hash[i]);
osi_list_init(&inode_hash[i]);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 68e8428..0e9ccfe 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -469,7 +469,6 @@ int main(int argc, char **argv)
log_notice( _("Writing changes to disk\n"));
bsync(&sbp->buf_list);
- bsync(&sbp->nvbuf_list);
destroy(sbp);
log_notice( _("gfs2_fsck complete \n"));
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 17c4bfc..7a59e13 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -962,6 +962,8 @@ int pass1(struct gfs2_sbd *sbp)
uint64_t blk_count;
uint64_t offset;
uint64_t rg_count = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* FIXME: In the gfs fsck, we had to mark things like the
* journals and indices and such as 'other_meta' - in gfs2,
@@ -984,8 +986,18 @@ int pass1(struct gfs2_sbd *sbp)
log_info( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
rg_count);
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- if(gfs2_rgrp_read(sbp, rgd)){
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return FSCK_ERROR;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return FSCK_ERROR;
+ }
+ if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
log_debug( _("RG at %llu (0x%llx) is %u long\n"),
@@ -996,6 +1008,7 @@ int pass1(struct gfs2_sbd *sbp)
if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
gfs2_meta_other)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
}
@@ -1006,11 +1019,12 @@ int pass1(struct gfs2_sbd *sbp)
while (1) {
/* "block" is relative to the entire file system */
- if (gfs2_next_rg_meta(rgd, &block, first))
+ if (gfs2_next_rg_meta(sbp, rgd, &block, first))
break;
warm_fuzzy_stuff(block);
if (fsck_abort) { /* if asked to abort */
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
return FSCK_OK;
}
if (skip_this_pass) {
@@ -1023,13 +1037,15 @@ int pass1(struct gfs2_sbd *sbp)
if (scan_meta(sbp, bh, block)) {
stack;
brelse(bh, not_updated);
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
return FSCK_ERROR;
}
brelse(bh, not_updated);
first = 0;
}
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
}
return FSCK_OK;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 53aef44..925e8cc 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -153,7 +153,8 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer,
unsigned int b
}
static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
- uint32_t *count)
+ uint32_t *count, struct gfs2_buffer_head **rgbh,
+ struct gfs2_rgrp *rg)
{
uint32_t i;
struct gfs2_bitmap *bits;
@@ -164,26 +165,26 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct
rgrp_list *rgp
bits = &rgp->bits[i];
/* update the bitmaps */
- check_block_status(sbp, rgp->bh[i]->b_data + bits->bi_offset,
+ check_block_status(sbp, rgbh[i]->b_data + bits->bi_offset,
bits->bi_len, &rg_block, rgp->ri.ri_data0, count);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
}
/* actually adjust counters and write out to disk */
- if(rgp->rg.rg_free != count[0]) {
+ if(rgp->rg_free != count[0]) {
log_err( _("RG #%llu (0x%llx) free count inconsistent: "
"is %u should be %u\n"),
(unsigned long long)rgp->ri.ri_addr,
(unsigned long long)rgp->ri.ri_addr,
- rgp->rg.rg_free, count[0]);
- rgp->rg.rg_free = count[0];
+ rgp->rg_free, count[0]);
+ rgp->rg_free = count[0];
update = 1;
}
- if(rgp->rg.rg_dinodes != count[1]) {
+ if(rg->rg_dinodes != count[1]) {
log_err( _("Inode count inconsistent: is %u should be %u\n"),
- rgp->rg.rg_dinodes, count[1]);
- rgp->rg.rg_dinodes = count[1];
+ rg->rg_dinodes, count[1]);
+ rg->rg_dinodes = count[1];
update = 1;
}
if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
@@ -199,7 +200,7 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct
rgrp_list *rgp
errors_corrected++;
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
- gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
+ gfs2_rgrp_out(rg, rgbh[0]->b_data);
return updated;
} else
log_err( _("Resource group counts left inconsistent\n"));
@@ -216,9 +217,11 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct
rgrp_list *rgp
int pass5(struct gfs2_sbd *sbp)
{
osi_list_t *tmp;
- struct rgrp_list *rgp = NULL;
+ struct rgrp_list *rgd = NULL;
uint32_t count[3];
uint64_t rg_count = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* Reconcile RG bitmaps with fsck bitmap */
for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){
@@ -228,16 +231,27 @@ int pass5(struct gfs2_sbd *sbp)
return FSCK_OK;
log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
memset(count, 0, sizeof(count));
- rgp = osi_list_entry(tmp, struct rgrp_list, list);
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
- if(gfs2_rgrp_read(sbp, rgp)){
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return FSCK_ERROR;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return FSCK_ERROR;
+ }
+ if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
stack;
+ free(rgbh);
return FSCK_ERROR;
}
rg_count++;
/* Compare the bitmaps and report the differences */
- f = update_rgrp(sbp, rgp, count);
- gfs2_rgrp_relse(rgp, f);
+ f = update_rgrp(sbp, rgd, count, rgbh, &rg);
+ gfs2_rgrp_relse(rgd, f, rgbh);
+ free(rgbh);
}
/* Fix up superblock info based on this - don't think there's
* anything to do here... */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index d0b8f33..a4c8cf7 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -129,7 +129,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t
*ret_list,
for (blk = sdp->sb_addr + 1;
blk < sdp->device.length && number_of_rgs < 6;
blk++) {
- bh = bread(&sdp->nvbuf_list, blk);
+ bh = bread(&sdp->buf_list, blk);
if (((blk == sdp->sb_addr + 1) ||
(!gfs2_check_meta(bh, GFS2_METATYPE_RG))) &&
!is_false_rg(blk)) {
@@ -207,7 +207,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t
*ret_list,
for (blk = sdp->sb_addr + 1; blk <= sdp->device.length;
blk += block_bump) {
log_debug( _("Block 0x%" PRIx64 "\n"), blk);
- bh = bread(&sdp->nvbuf_list, blk);
+ bh = bread(&sdp->buf_list, blk);
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
brelse(bh, not_updated);
/* Allocate a new RG and index. */
@@ -241,7 +241,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t
*ret_list,
for (fwd_block = blk + 1;
fwd_block < sdp->device.length;
fwd_block++) {
- bh = bread(&sdp->nvbuf_list, fwd_block);
+ bh = bread(&sdp->buf_list, fwd_block);
bitmap_was_fnd =
(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
brelse(bh, not_updated);
@@ -252,13 +252,6 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t
*ret_list,
} /* for subsequent bitmaps */
gfs2_compute_bitstructs(sdp, calc_rgd);
- log_debug( _("Memory allocated for rg at 0x%llx, bh: %p\n"),
- (unsigned long long)calc_rgd->ri.ri_addr,
- calc_rgd->bh);
- if (!calc_rgd->bh) {
- log_crit( _("Can't allocate memory for bitmap repair.\n"));
- return -1;
- }
calc_rgd->ri.ri_data0 = calc_rgd->ri.ri_addr +
calc_rgd->ri.ri_length;
if (prev_rgd) {
@@ -381,37 +374,38 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t
*ret_list,
* rewrite_rg_block - rewrite ("fix") a buffer with rg or bitmap data
* returns: 0 if the rg was repaired, otherwise 1
*/
-static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
- uint64_t errblock)
+static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t errblock, struct gfs2_buffer_head **rgbh,
+ struct gfs2_rgrp *rg)
{
- int x = errblock - rg->ri.ri_addr;
+ int x = errblock - rgd->ri.ri_addr;
log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is
neither"
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
- rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
- (int)x+1, (int)rg->ri.ri_length);
+ rgbh[x]->b_blocknr, rgbh[x]->b_blocknr,
+ (int)x+1, (int)rgd->ri.ri_length);
errors_found++;
if (query(&opts, "Fix the RG? (y/n)")) {
errors_corrected++;
log_err( _("Attempting to repair the RG.\n"));
- rg->bh[x] = bread(&sdp->nvbuf_list, rg->ri.ri_addr + x);
+ rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
if (x) {
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
mh.mh_format = GFS2_FORMAT_RB;
- gfs2_meta_header_out(&mh, rg->bh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgbh[x]->b_data);
} else {
- memset(&rg->rg, 0, sizeof(struct gfs2_rgrp));
- rg->rg.rg_header.mh_magic = GFS2_MAGIC;
- rg->rg.rg_header.mh_type = GFS2_METATYPE_RG;
- rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
- rg->rg.rg_free = rg->ri.ri_data;
- gfs2_rgrp_out(&rg->rg, rg->bh[x]->b_data);
+ memset(rg, 0, sizeof(struct gfs2_rgrp));
+ rg->rg_header.mh_magic = GFS2_MAGIC;
+ rg->rg_header.mh_type = GFS2_METATYPE_RG;
+ rg->rg_header.mh_format = GFS2_FORMAT_RG;
+ rg->rg_free = rgd->ri.ri_data;
+ gfs2_rgrp_out(rg, rgbh[x]->b_data);
}
- brelse(rg->bh[x], updated);
+ brelse(rgbh[x], updated);
return 0;
}
return 1;
@@ -432,6 +426,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
int calc_rg_count = 0, rgcount_from_index, rg;
osi_list_t *exp, *act; /* expected, actual */
struct gfs2_rindex buf;
+ int bitmap_blocks;
if (trust_lvl == blind_faith)
return 0;
@@ -440,7 +435,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
error = gfs2_rindex_calculate(sdp, &expected_rglist,
&calc_rg_count);
if (error) { /* If calculated RGs don't match the fs */
- gfs2_rgrp_free(&expected_rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
return -1;
}
}
@@ -449,18 +444,18 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
&calc_rg_count);
if (error) {
log_crit( _("Error rebuilding rg list.\n"));
- gfs2_rgrp_free(&expected_rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
return -1;
}
sdp->rgrps = calc_rg_count;
}
/* Read in the rindex */
osi_list_init(&sdp->rglist); /* Just to be safe */
- rindex_read(sdp, 0, &rgcount_from_index);
+ rindex_read(sdp, 0, &rgcount_from_index, &bitmap_blocks);
if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
log_warn( _("WARNING: rindex file is corrupt.\n"));
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
log_warn( _("L%d: number of rgs expected = %lld.\n"), trust_lvl + 1,
@@ -468,8 +463,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
if (calc_rg_count != sdp->rgrps) {
log_warn( _("L%d: They don't match; either (1) the fs was extended, (2) an
odd\n"), trust_lvl + 1);
log_warn( _("L%d: rg size was used, or (3) we have a corrupt rg index.\n"),
trust_lvl + 1);
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
/* ------------------------------------------------------------- */
@@ -500,8 +495,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
trust_lvl + 1);
log_warn( _("%d out of %d RGs did not match what was expected.\n"),
descrepencies, rg);
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return -1;
}
/* ------------------------------------------------------------- */
@@ -540,8 +535,6 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
/* Therefore, gfs2_compute_bitstructs might */
/* have malloced the wrong length for bitmap */
/* buffers. So we have to redo it. */
- if (actual->bh)
- free(actual->bh);
if (actual->bits)
free(actual->bits);
}
@@ -561,28 +554,46 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
struct rgrp_list *rgd;
uint64_t prev_err = 0, errblock;
int i;
+ struct gfs2_rgrp rgrp;
+ struct gfs2_buffer_head **rgbh;
/* Now we try repeatedly to read in the rg. For every block */
/* we encounter that has errors, repair it and try again. */
i = 0;
do {
rgd = osi_list_entry(act, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rgrp);
if (errblock) {
- if (errblock == prev_err)
+ if (errblock == prev_err) {
+ free(rgbh);
break;
+ }
prev_err = errblock;
- rewrite_rg_block(sdp, rgd, errblock);
+ rewrite_rg_block(sdp, rgd, errblock, rgbh,
+ &rgrp);
}
else {
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
break;
}
+ free(rgbh);
i++;
} while (i < rgd->ri.ri_length);
}
*rg_count = rg;
- gfs2_rgrp_free(&expected_rglist, not_updated);
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&expected_rglist);
+ gfs2_rgrp_free(&sdp->rglist);
return 0;
}
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 571c737..75e2747 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -159,8 +159,8 @@ struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(&il->list.gbmap.group_map, size, 4)) {
- *addl_mem_needed = il->list.gbmap.group_map.mapsize;
+ if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
+ *addl_mem_needed = il->list.gbmap.mapsize;
free(il);
il = NULL;
}
@@ -288,7 +288,7 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
else
- err = gfs2_bitmap_set(&il->list.gbmap.group_map, block,
+ err = gfs2_bitmap_set(&il->list.gbmap, block,
mark_to_gbmap[mark]);
return err;
}
@@ -311,7 +311,7 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list
*il,
break;
default:
/* FIXME: check types */
- err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+ err = gfs2_bitmap_clear(&il->list.gbmap, block);
break;
}
return err;
@@ -326,7 +326,7 @@ int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list
*il,
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->bad_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+ err = gfs2_bitmap_clear(&il->list.gbmap, block);
return err;
}
@@ -355,8 +355,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list
*il,
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
val->eattr_block = 1;
- if((err = gfs2_bitmap_get(&il->list.gbmap.group_map, block,
- &val->block_type)))
+ if((err = gfs2_bitmap_get(&il->list.gbmap, block, &val->block_type)))
return err;
return 0;
}
@@ -364,7 +363,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list
*il,
void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
{
if(il) {
- gfs2_bitmap_destroy(&il->list.gbmap.group_map);
+ gfs2_bitmap_destroy(&il->list.gbmap);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index f0164b4..a12c19c 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -37,6 +37,10 @@ static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head
*bh)
}
sdp->writes++;
}
+ bh->b_blocknr = -1;
+ bh->b_data = NULL;
+ bh->b_count = -1;
+ bh->b_changed = -1;
free(bh);
return 0;
}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index ed459af..1f197b1 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -1,5 +1,6 @@
#include <inttypes.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "libgfs2.h"
@@ -112,6 +113,8 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
struct rgrp_list *rgd;
unsigned char *byte, cur_state;
unsigned int bit;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
/* FIXME: should GFS2_BLKST_INVALID be allowed */
if ((state < GFS2_BLKST_FREE) || (state > GFS2_BLKST_DINODE))
@@ -122,8 +125,20 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
if(!rgd)
return -1;
- if(gfs2_rgrp_read(sdp, rgd))
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
return -1;
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg)) {
+ free(rgbh);
+ return -1;
+ }
rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
for(buf= 0; buf < rgd->ri.ri_length; buf++){
bits = &(rgd->bits[buf]);
@@ -131,7 +146,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
break;
}
- byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgbh[buf]->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
@@ -139,12 +154,13 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int
state)
*byte ^= cur_state << bit;
*byte |= state << bit;
- gfs2_rgrp_relse(rgd, updated);
+ gfs2_rgrp_relse(rgd, updated, rgbh);
+ free(rgbh);
return 0;
}
/*
- * fs_get_bitmap - get value of FS bitmap
+ * gfs2_get_bitmap - get value of FS bitmap
* @sdp: super block
* @blkno: block number relative to file system
*
@@ -167,6 +183,9 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
unsigned int bit;
unsigned char *byte;
int local_rgd = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
+ int bitmap_blocks = rgd->length;
if(gfs2_check_range(sdp, blkno))
return -1;
@@ -176,7 +195,16 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
}
if(rgd == NULL)
return -1;
- if(gfs2_rgrp_read(sdp, rgd))
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
+ if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg))
return -1;
rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
@@ -189,17 +217,17 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
}
if(i >= rgd->ri.ri_length){
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
return -1;
}
- byte = (unsigned char *)(rgd->bh[i]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgbh[i]->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
val = ((*byte >> bit) & GFS2_BIT_MASK);
if(local_rgd)
- gfs2_rgrp_relse(rgd, not_updated);
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
return val;
}
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 9c5daf1..dfdd7e7 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -112,7 +112,6 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
rl->length = dev->length -
(nrgrp - 1) * (dev->length / nrgrp);
}
- rl->rgf_flags = dev->rgf_flags;
log_info("%d: start: %" PRIu64 " (0x%"
PRIx64 "), length = %"PRIu64" (0x%"
@@ -183,7 +182,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
struct rgrp_list *rl;
uint32_t rgblocks, bitblocks;
struct gfs2_rindex *ri;
- struct gfs2_rgrp *rg;
+ struct gfs2_rgrp rg;
struct gfs2_meta_header mh;
unsigned int x;
struct gfs2_buffer_head *bh;
@@ -197,7 +196,6 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
tmp = tmp->next) {
rl = osi_list_entry(tmp, struct rgrp_list, list);
ri = &rl->ri;
- rg = &rl->rg;
rgblocks = rl->length;
rgblocks2bitblocks(sdp->bsize, &rgblocks, &bitblocks);
@@ -208,19 +206,20 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
ri->ri_data = rgblocks;
ri->ri_bitbytes = rgblocks / GFS2_NBBY;
- rg->rg_header.mh_magic = GFS2_MAGIC;
- rg->rg_header.mh_type = GFS2_METATYPE_RG;
- rg->rg_header.mh_format = GFS2_FORMAT_RG;
- rg->rg_flags = rl->rgf_flags;
- rg->rg_free = rgblocks;
+ memset(&rg, 0, sizeof(rg));
+ rg.rg_header.mh_magic = GFS2_MAGIC;
+ rg.rg_header.mh_type = GFS2_METATYPE_RG;
+ rg.rg_header.mh_format = GFS2_FORMAT_RG;
+ rg.rg_free = rgblocks;
+ rl->rg_free = rgblocks;
if (do_write) {
for (x = 0; x < bitblocks; x++) {
- bh = bget(&sdp->nvbuf_list, rl->start + x);
+ bh = bget(&sdp->buf_list, rl->start + x);
if (x)
gfs2_meta_header_out(&mh, bh->b_data);
else
- gfs2_rgrp_out(rg, bh->b_data);
+ gfs2_rgrp_out(&rg, bh->b_data);
brelse(bh, updated);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index fc898ce..7c44a8c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -56,16 +56,17 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
osi_list_t *tmp, *head;
struct rgrp_list *rl = NULL;
struct gfs2_rindex *ri;
- struct gfs2_rgrp *rg;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh;
unsigned int block, bn = 0, x = 0, y = 0;
- struct gfs2_buffer_head *bh;
unsigned int state;
+ memset(&rg, 0, sizeof(rg));
for (head = &sdp->rglist, tmp = head->next;
tmp != head;
tmp = tmp->next) {
rl = osi_list_entry(tmp, struct rgrp_list, list);
- if (rl->rg.rg_free)
+ if (rl->rg_free)
break;
}
@@ -73,31 +74,43 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
die("out of space\n");
ri = &rl->ri;
- rg = &rl->rg;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rl->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, rl->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
for (block = 0; block < ri->ri_length; block++) {
- bh = bread(&sdp->nvbuf_list, ri->ri_addr + block);
+ rgbh[block] = bread(&sdp->buf_list, ri->ri_addr + block);
x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+ if (!block)
+ gfs2_rgrp_in(&rg, rgbh[0]->b_data);
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
+ state = (rgbh[block]->b_data[x] >>
+ (GFS2_BIT_SIZE * y)) & 0x03;
if (state == GFS2_BLKST_FREE)
goto found;
bn++;
}
- brelse(bh, FALSE);
+ brelse(rgbh[block], FALSE);
}
die("allocation is broken (1): %"PRIu64" %u\n",
- (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg_free);
found:
if (bn >= ri->ri_bitbytes * GFS2_NBBY)
die("allocation is broken (2): %u %u %"PRIu64" %u\n",
bn, ri->ri_bitbytes * GFS2_NBBY,
- (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg_free);
switch (type) {
case DATA:
@@ -106,24 +119,25 @@ found:
break;
case DINODE:
state = GFS2_BLKST_DINODE;
- rg->rg_dinodes++;
+ rg.rg_dinodes++;
break;
default:
die("bad state\n");
}
- bh->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
- bh->b_data[x] |= state << (GFS2_BIT_SIZE * y);
- rg->rg_free--;
+ rgbh[block]->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
+ rgbh[block]->b_data[x] |= state << (GFS2_BIT_SIZE * y);
+ rg.rg_free--;
+ rl->rg_free--;
- brelse(bh, updated);
+ brelse(rgbh[block], updated);
- bh = bread(&sdp->nvbuf_list, ri->ri_addr);
- gfs2_rgrp_out(rg, bh->b_data);
- brelse(bh, updated);
+ rgbh[0] = bread(&sdp->buf_list, ri->ri_addr);
+ gfs2_rgrp_out(&rg, rgbh[0]->b_data);
+ brelse(rgbh[0], updated);
sdp->blks_alloced++;
-
+ free(rgbh);
return ri->ri_data0 + bn;
}
@@ -945,7 +959,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
*/
static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in,
- struct gfs2_buffer_head **bh_out)
+ struct gfs2_buffer_head **bh_out)
{
struct gfs2_leaf *leaf;
@@ -1581,13 +1595,16 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
{
struct gfs2_buffer_head *bh;
struct rgrp_list *rgd;
+ struct gfs2_rgrp rg;
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
/* Adjust the free space count for the freed block */
rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */
- bh = bget(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the rg buffer */
- rgd->rg.rg_free++; /* adjust the free count */
- gfs2_rgrp_out(&rgd->rg, bh->b_data); /* back to the buffer */
+ bh = bget(&sdp->buf_list, rgd->ri.ri_addr); /* get the rg buffer */
+ gfs2_rgrp_in(&rg, bh->b_data); /* back to the buffer */
+ rg.rg_free++; /* adjust the free count */
+ rgd->rg_free++;
+ gfs2_rgrp_out(&rg, bh->b_data); /* back to the buffer */
brelse(bh, updated); /* release the buffer */
}
@@ -1605,6 +1622,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
uint32_t height;
osi_list_t metalist[GFS2_MAX_META_HEIGHT];
osi_list_t *cur_list, *next_list, *tmp;
+ struct gfs2_rgrp rg;
for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
osi_list_init(&metalist[h]);
@@ -1633,11 +1651,8 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
gfs2_free_block(sdp, block);
if (h == height - 1) /* if not metadata */
continue; /* don't queue it up */
- /* Read the next metadata block in the chain.
- First see if it's on the nvbuf_list. */
- nbh = bfind(&sdp->nvbuf_list, block);
- if (!nbh)
- nbh = bread(&sdp->buf_list, block);
+ /* Read the next metadata block in the chain */
+ nbh = bread(&sdp->buf_list, block);
osi_list_add(&nbh->b_altlist, next_list);
brelse(nbh, not_updated);
}
@@ -1648,13 +1663,12 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
inode_put(ip, updated);
/* Now we have to adjust the rg freespace count and inode count: */
rgd = gfs2_blk2rgrpd(sdp, diblock);
- /* The rg itself is in memory as rgd->rg, but there's most likely a */
- /* buffer in memory for the rg on disk because we used it to fix the */
- /* bitmaps, some of which are on the same block on disk. */
- bh = bread(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the buffer */
- rgd->rg.rg_free++;
- rgd->rg.rg_dinodes--; /* one less inode in use */
- gfs2_rgrp_out(&rgd->rg, bh->b_data);
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr); /* get the buffer */
+ gfs2_rgrp_in(&rg, bh->b_data);
+ rg.rg_free++;
+ rgd->rg_free++;
+ rg.rg_dinodes--; /* one less inode in use */
+ gfs2_rgrp_out(&rg, bh->b_data);
brelse(bh, updated); /* release the buffer */
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 59c4f8f..eb266a5 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -232,7 +232,8 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
*
* Returns: 0 on success, -1 on failure
*/
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks)
{
unsigned int rg;
int error;
@@ -242,6 +243,7 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*count1 = 0;
prev_rgd = NULL;
+ *bitmap_blocks = 0;
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -264,6 +266,8 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
gfs2_rindex_in(&rgd->ri, (char *)&buf);
+ if (rgd->ri.ri_length > *bitmap_blocks)
+ *bitmap_blocks = rgd->ri.ri_length;
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
prev_length = rgd->start - prev_rgd->start;
@@ -297,14 +301,28 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int
quiet)
osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh = NULL;
+ int bitmap_blocks;
- if (gfs1_rindex_read(sdp, fd, &count1))
+ if (gfs1_rindex_read(sdp, fd, &count1, &bitmap_blocks))
goto fail;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
- if (errblock)
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+ if (errblock) {
+ free(rgbh);
return errblock;
+ }
count2++;
if (!quiet && count2 % 100 == 0) {
printf(".");
@@ -316,10 +334,12 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int
quiet)
if (count1 != count2)
goto fail;
+ free(rgbh);
return 0;
fail:
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&sdp->rglist);
+ free(rgbh);
return -1;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index bc2507e..e1a984f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -97,12 +97,10 @@ struct rgrp_list {
osi_list_t list;
uint64_t start; /* The offset of the beginning of this resource group */
uint64_t length; /* The length of this resource group */
- uint32_t rgf_flags;
+ uint32_t rg_free; /* Free blocks */
struct gfs2_rindex ri;
- struct gfs2_rgrp rg;
struct gfs2_bitmap *bits;
- struct gfs2_buffer_head **bh;
};
struct gfs2_buffer_head {
@@ -244,7 +242,6 @@ struct gfs2_sbd {
unsigned int orig_journals;
struct buf_list buf_list; /* transient buffer list */
- struct buf_list nvbuf_list; /* non-volatile buffer list */
struct gfs2_inode *master_dir;
struct master_dir md;
@@ -346,15 +343,8 @@ struct gfs2_block_query {
uint8_t eattr_block;
};
-struct gfs2_gbmap {
- struct gfs2_bmap group_map;
- struct gfs2_bmap bad_map;
- struct gfs2_bmap dup_map;
- struct gfs2_bmap eattr_map;
-};
-
union gfs2_block_lists {
- struct gfs2_gbmap gbmap;
+ struct gfs2_bmap gbmap;
};
/* bitmap implementation */
@@ -564,7 +554,8 @@ extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int
*new,
uint64_t *dblock, uint32_t *extlen, int prealloc);
extern int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
-extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks);
extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
@@ -673,9 +664,12 @@ extern int clean_journal(struct gfs2_inode *ip, struct
gfs2_log_header *head);
/* rgrp.c */
extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated);
-extern void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags updated);
+extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ struct gfs2_buffer_head **bh,
+ struct gfs2_rgrp *rg);
+extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated,
+ struct gfs2_buffer_head **bh);
+extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
@@ -690,14 +684,16 @@ extern int build_root(struct gfs2_sbd *sdp);
extern int do_init_inum(struct gfs2_sbd *sdp);
extern int do_init_statfs(struct gfs2_sbd *sdp);
extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
-extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
+extern int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *block, int first);
extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
uint64_t *block, uint32_t type, int first);
/* super.c */
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
extern int ji_update(struct gfs2_sbd *sdp);
-extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+ int *bitmap_blocks);
extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index fc548d1..21c7033 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -72,14 +72,6 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list
*rgd)
rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
return -1;
- if (rgd->bh) /* If we already have a bh allocated */
- return 0; /* don't want to allocate another */
- if(!(rgd->bh = (struct gfs2_buffer_head **)
- malloc(length * sizeof(struct gfs2_buffer_head *))))
- return -1;
- if(!memset(rgd->bh, 0, length * sizeof(struct gfs2_buffer_head *)))
- return -1;
-
return 0;
}
@@ -114,51 +106,47 @@ struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t
blk)
* @rgd - resource group structure
* returns: 0 if no error, otherwise the block number that failed
*/
-uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
+uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++){
- rgd->bh[x] = bread(&sdp->nvbuf_list, rgd->ri.ri_addr + x);
- if(gfs2_check_meta(rgd->bh[x],
+ bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ if(gfs2_check_meta(bh[x],
(x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
uint64_t error;
error = rgd->ri.ri_addr + x;
for (; x >= 0; x--)
- brelse(rgd->bh[x], not_updated);
+ brelse(bh[x], not_updated);
return error;
}
}
- gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data);
+ gfs2_rgrp_in(rg, bh[0]->b_data);
+ rgd->rg_free = rg->rg_free;
return 0;
}
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated)
+void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated,
+ struct gfs2_buffer_head **bh)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++)
- brelse(rgd->bh[x], is_updated);
+ brelse(bh[x], is_updated);
}
-void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags is_updated)
+void gfs2_rgrp_free(osi_list_t *rglist)
{
struct rgrp_list *rgd;
while(!osi_list_empty(rglist->next)){
rgd = osi_list_entry(rglist->next, struct rgrp_list, list);
- if (rgd->bh && rgd->bh[0] && /* if a buffer exists and */
- rgd->bh[0]->b_count) /* the 1st buffer is allocated */
- gfs2_rgrp_relse(rgd, is_updated); /* free them all. */
if(rgd->bits)
free(rgd->bits);
- if(rgd->bh) {
- free(rgd->bh);
- rgd->bh = NULL;
- }
osi_list_del(&rgd->list);
free(rgd);
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 8e9ad86..97c56b8 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -441,12 +441,14 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
*
* Returns: 0 on success, -1 when finished
*/
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ uint64_t *block, int first)
{
struct gfs2_bitmap *bits = NULL;
uint32_t length = rgd->ri.ri_length;
uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0);
int i;
+ struct gfs2_buffer_head *bh;
if(!first && (*block < rgd->ri.ri_data0)) {
log_err("next_rg_meta: Start block is outside rgrp bounds.\n");
@@ -460,14 +462,17 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int
first)
}
for(; i < length; i++){
bits = &rgd->bits[i];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+ bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)bh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_DINODE);
if(blk != BFITNOENT){
*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+ brelse(bh, not_updated);
break;
}
blk=0;
+ brelse(bh, not_updated);
}
if(i == length)
return -1;
@@ -484,14 +489,14 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int
first)
* Returns: 0 on success, -1 on error or finished
*/
int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
- uint64_t *block, uint32_t type, int first)
+ uint64_t *block, uint32_t type, int first)
{
struct gfs2_buffer_head *bh = NULL;
do{
if (bh)
brelse(bh, not_updated);
- if (gfs2_next_rg_meta(rgd, block, first))
+ if (gfs2_next_rg_meta(sdp, rgd, block, first))
return -1;
bh = bread(&sdp->buf_list, *block);
first = 0;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index ba3af34..7aeeaa7 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -162,7 +162,7 @@ int ji_update(struct gfs2_sbd *sdp)
*
* Returns: 0 on success, -1 on failure
*/
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
{
unsigned int rg;
int error;
@@ -172,6 +172,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
*count1 = 0;
prev_rgd = NULL;
+ *bitmap_blocks = 0;
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -194,6 +195,8 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
gfs2_rindex_in(&rgd->ri, (char *)&buf);
+ if (rgd->ri.ri_length > *bitmap_blocks)
+ *bitmap_blocks = rgd->ri.ri_length;
rgd->start = rgd->ri.ri_addr;
if (prev_rgd) {
prev_length = rgd->start - prev_rgd->start;
@@ -228,19 +231,33 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
+ struct gfs2_rgrp rg;
+ struct gfs2_buffer_head **rgbh = NULL;
+ int bitmap_blocks;
- if (rindex_read(sdp, fd, &count1))
+ if (rindex_read(sdp, fd, &count1, &bitmap_blocks))
goto fail;
+
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+ return -1;
+ if(!memset(rgbh, 0, bitmap_blocks *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ return -1;
+ }
+
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
enum update_flags f;
f = not_updated;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
- if (errblock)
+ errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+ if (errblock) {
+ free(rgbh);
return errblock;
- else
- gfs2_rgrp_relse(rgd, f);
+ } else
+ gfs2_rgrp_relse(rgd, f, rgbh);
count2++;
}
@@ -248,10 +265,12 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
if (count1 != count2)
goto fail;
+ free(rgbh);
return 0;
fail:
- gfs2_rgrp_free(&sdp->rglist, not_updated);
+ gfs2_rgrp_free(&sdp->rglist);
+ free(rgbh);
return -1;
}
@@ -263,7 +282,6 @@ int write_sb(struct gfs2_sbd *sbp)
gfs2_sb_out(&sbp->sd_sb, bh->b_data);
brelse(bh, updated);
bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
- bcommit(&sbp->nvbuf_list); /* make sure the change gets to disk ASAP */
return 0;
}
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index a3f6e47..10d9731 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -175,7 +175,6 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int
*old_rg_count)
/* We're done with the libgfs portion, so commit it to disk. */
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
}
/**
@@ -287,8 +286,7 @@ main_grow(int argc, char *argv[])
}
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sdp->bsize = sdp->sd_sb.sb_bsize;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 4c1d94f..cb6a3cc 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -561,8 +561,7 @@ void main_mkfs(int argc, char *argv[])
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
sdp->time = time(NULL);
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 128 << 20);
- init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+ init_buf_list(sdp, &sdp->buf_list, 1 << 20);
decode_arguments(argc, argv, sdp);
if (sdp->rgsize == -1) /* if rg size not specified */
@@ -643,7 +642,6 @@ void main_mkfs(int argc, char *argv[])
inode_put(sdp->md.inum, updated);
inode_put(sdp->md.statfs, updated);
bsync(&sdp->buf_list);
- bsync(&sdp->nvbuf_list);
error = fsync(sdp->device_fd);
if (error)