Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: a099128a0f504eca010cb7435a740830ce272153
Parent: 71fb85ae21db98d08128ff27ca4c17ac7dd4139d
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 19 15:05:52 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:28 2010 -0600
gfs2: Remove buf_lists
This patch removes once and for all the linked lists of buffer_heads
attached to the superblock. We should trust that the vfs layer of
the kernel is going to keep the blocks we most want in memory rather
than trying to do it in user space. While this was likely put in
place for performance reasons, it actually performs better with vfs
managing the buffers because we ended up spending too much time
searching through the linked lists for the buffer we need to use.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 22 ++---
gfs2/edit/gfs2hex.c | 2 +-
gfs2/edit/hexedit.c | 47 ++++-----
gfs2/edit/savemeta.c | 25 +++--
gfs2/fsck/fs_recovery.c | 8 +-
gfs2/fsck/initialize.c | 1 -
gfs2/fsck/main.c | 10 +--
gfs2/fsck/metawalk.c | 12 +--
gfs2/fsck/pass1.c | 8 +-
gfs2/fsck/pass1b.c | 6 +-
gfs2/fsck/pass1c.c | 6 +-
gfs2/fsck/pass2.c | 6 +-
gfs2/fsck/pass3.c | 1 -
gfs2/fsck/rgrepair.c | 10 +-
gfs2/libgfs2/buf.c | 229 +++++-------------------------------------
gfs2/libgfs2/fs_geometry.c | 2 +-
gfs2/libgfs2/fs_ops.c | 47 +++++-----
gfs2/libgfs2/gfs1.c | 8 +-
gfs2/libgfs2/libgfs2.h | 38 ++-----
gfs2/libgfs2/recovery.c | 4 +-
gfs2/libgfs2/rgrp.c | 2 +-
gfs2/libgfs2/structures.c | 6 +-
gfs2/libgfs2/super.c | 6 +-
gfs2/mkfs/main_grow.c | 3 +-
gfs2/mkfs/main_mkfs.c | 4 -
25 files changed, 152 insertions(+), 361 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 02bd9b9..2e10496 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -320,7 +320,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
if (!block)
break;
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (new)
memset(bh->b_data, 0, sbp->bsize);
gfs2_meta_header_out(&mh, bh);
@@ -493,7 +493,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct
gfs2_inode *ip)
osi_list_add_prev(&newblk->list, &blocks.list);
/* read the new metadata block's pointers */
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
memcpy(newblk->ptrbuf, bh->b_data +
sizeof(struct gfs_indirect), bufsize);
/* Zero the buffer so we can fill it in later */
@@ -721,7 +721,7 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t
root_inode_addr)
sbp->sd_sb.sb_root_dir.no_addr = block;
sbp->sd_sb.sb_root_dir.no_formal_ino = sbp->md.next_inum;
}
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) /* if it is an dinode */
error = adjust_inode(sbp, bh);
else { /* It's metadata, but not an inode, so fix the bitmap. */
@@ -1076,13 +1076,12 @@ 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, 1 << 20); /* only use 1MB of bufs */
if (compute_constants(sbp)) {
log_crit("Error: Bad constants (1)\n");
exit(-1);
}
- bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
+ bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
gfs2_sb_in(&sbp->sd_sb, bh);
@@ -1370,7 +1369,7 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
return -1;
}
for (x = 0; x < rgd->ri.ri_length; x++) {
- rgd->bh[x] = bget(&sdp->buf_list, rgd->ri.ri_addr + x);
+ rgd->bh[x] = bget(sdp, rgd->ri.ri_addr + x);
memset(rgd->bh[x]->b_data, 0, sdp->bsize);
}
if (gfs2_compute_bitstructs(sdp, rgd)) {
@@ -1527,7 +1526,7 @@ int main(int argc, char **argv)
if (error)
log_crit("%s: Unable to convert resource groups.\n",
device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Renumber the inodes consecutively. */
@@ -1536,7 +1535,7 @@ int main(int argc, char **argv)
error = inode_renumber(&sb2, sb2.sd_sb.sb_root_dir.no_addr);
if (error)
log_crit("\n%s: Error renumbering inodes.\n", device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Fix the directories to match the new numbers. */
@@ -1557,7 +1556,7 @@ int main(int argc, char **argv)
error = journ_space_to_rg(&sb2);
if (error)
log_crit("%s: Error converting journal space.\n", device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Create our system files and directories. */
@@ -1594,7 +1593,7 @@ int main(int argc, char **argv)
inode_put(&sb2.md.inum);
inode_put(&sb2.md.statfs);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
/* Now delete the now-obsolete gfs1 files: */
remove_obsolete_gfs1(&sb2);
@@ -1606,13 +1605,12 @@ int main(int argc, char **argv)
/* end because if the tool is interrupted in the middle, we want */
/* it to not reject the partially converted fs as already done */
/* when it's run a second time. */
- bh = bread(&sb2.buf_list, sb2.sb_addr);
+ bh = bread(&sb2, sb2.sb_addr);
sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS;
sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI;
gfs2_sb_out(&sb2.sd_sb, bh);
brelse(bh);
- bsync(&sb2.buf_list); /* write the buffers to disk */
error = fsync(sb2.device_fd);
if (error)
perror(device);
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 55f36db..cbf8dc0 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -335,7 +335,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct
gfs2_buffer_head *lbh)
if (last >= max_block)
break;
- tmp_bh = bread(&sbd.buf_list, last);
+ tmp_bh = bread(&sbd, last);
gfs2_leaf_in(&leaf, tmp_bh);
indirect->ii[indirect_blocks].dirents = 0;
for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index b3f31e6..0017a60 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -904,7 +904,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify,
int full)
uint64_t rgblk;
rgblk = get_rg_addr(rgnum);
- rbh = bread(&sbd.buf_list, rgblk);
+ rbh = bread(&sbd, rgblk);
if (gfs1)
gfs_rgrp_in(&rg.rg1, rbh);
else
@@ -936,7 +936,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify,
int full)
brelse(rbh);
}
if (modify)
- bsync(&sbd.buf_list);
+ fsync(sbd.device_fd);
}
/* ------------------------------------------------------------------------ */
@@ -988,7 +988,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
else {
struct gfs2_buffer_head *tmp_bh;
- tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
+ tmp_bh = bread(&sbd, ri.ri_addr);
if (gfs1) {
struct gfs_rgrp rg1;
gfs_rgrp_in(&rg1, tmp_bh);
@@ -1637,7 +1637,7 @@ static int display_extended(void)
/* Display any indirect pointers that we have. */
if (block_is_rindex()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, TRUE);
brelse(tmp_bh);
@@ -1649,34 +1649,34 @@ static int display_extended(void)
return -1;
else if (block_is_rglist()) {
if (gfs1)
- tmp_bh = bread(&sbd.buf_list,
+ tmp_bh = bread(&sbd,
sbd1->sb_rindex_di.no_addr);
else
- tmp_bh = bread(&sbd.buf_list, masterblock("rindex"));
+ tmp_bh = bread(&sbd, masterblock("rindex"));
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, FALSE);
brelse(tmp_bh);
}
else if (block_is_jindex()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_jindex(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_inum_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_inum(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_statfs_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_statfs(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_quota_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_quota(tmp_inode);
brelse(tmp_bh);
@@ -1696,14 +1696,13 @@ static void read_superblock(int fd)
memset(&sbd, 0, sizeof(struct gfs2_sbd));
sbd.bsize = GFS2_DEFAULT_BSIZE;
sbd.device_fd = fd;
- bh = bread(&sbd.buf_list, 0x10);
+ bh = bread(&sbd, 0x10);
sbd.jsize = GFS2_DEFAULT_JSIZE;
sbd.rgsize = GFS2_DEFAULT_RGSIZE;
sbd.utsize = GFS2_DEFAULT_UTSIZE;
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
sbd.time = time(NULL);
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
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 &&
@@ -1800,7 +1799,7 @@ int display(int identify_only)
if (block_in_mem != blk) { /* If we changed blocks from the last read */
dev_offset = blk * sbd.bsize;
ioctl(sbd.device_fd, BLKFLSBUF, 0);
- if (!(bh = bread(&sbd.buf_list, blk))) {
+ if (!(bh = bread(&sbd, blk))) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
strerror(errno), __FUNCTION__, __LINE__,
@@ -1953,7 +1952,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t
*j_size)
else
jindex_block = masterblock("jindex");
/* read in the block */
- jindex_bh = bread(&sbd.buf_list, jindex_block);
+ jindex_bh = bread(&sbd, jindex_block);
/* get the dinode data from it. */
gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
@@ -1978,7 +1977,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t
*j_size)
struct gfs2_dinode jdi;
jblock = indirect->ii[0].dirent[journal_num + 2].block;
- j_bh = bread(&sbd.buf_list, jblock);
+ j_bh = bread(&sbd, jblock);
j_inode = inode_get(&sbd, j_bh);
gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */
*j_size = jdi.di_size;
@@ -2001,7 +2000,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int
metatype, int p
last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
for (blk = startblk + 1; blk < last_fs_block; blk++) {
- lbh = bread(&sbd.buf_list, blk);
+ lbh = bread(&sbd, blk);
/* Can't use get_block_type here (returns false "none") */
if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 &&
lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 &&
@@ -2426,7 +2425,7 @@ static void find_print_block_type(void)
int type;
tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- lbh = bread(&sbd.buf_list, tblock);
+ lbh = bread(&sbd, tblock);
type = get_block_type(lbh);
print_block_type(tblock, type, "");
brelse(lbh);
@@ -2522,7 +2521,7 @@ static void find_change_block_alloc(int *newval)
}
gfs2_rgrp_free(&sbd.rglist);
if (newval)
- bcommit(&sbd.buf_list);
+ fsync(sbd.device_fd);
exit(0);
}
@@ -2537,7 +2536,7 @@ static void process_field(const char *field, uint64_t *newval, int
print_field)
struct gfs2_rgrp rg;
fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- rbh = bread(&sbd.buf_list, block);
+ rbh = bread(&sbd, block);
type = get_block_type(rbh);
switch (type) {
case GFS2_METATYPE_SB:
@@ -2589,10 +2588,8 @@ static void process_field(const char *field, uint64_t *newval, int
print_field)
" which is not implemented");
break;
}
- if (newval)
- bmodified(rbh);
brelse(rbh);
- bcommit(&sbd.buf_list);
+ fsync(sbd.device_fd);
}
/* ------------------------------------------------------------------------ */
@@ -2974,7 +2971,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t
roffset,
block_map(ip, lblock, ¬_new, &dblock, &extlen,
FALSE);
if (dblock) {
- lbh = bread(&sdp->buf_list, dblock);
+ lbh = bread(sdp, dblock);
if (*abs_block == 0)
*abs_block = lbh->b_blocknr;
dblock++;
@@ -3032,7 +3029,7 @@ static void dump_journal(const char *journal)
if (!jblock)
return;
if (!gfs1) {
- j_bh = bread(&sbd.buf_list, jblock);
+ j_bh = bread(&sbd, jblock);
j_inode = inode_get(&sbd, j_bh);
jbuf = malloc(sbd.bsize);
}
@@ -3041,7 +3038,7 @@ static void dump_journal(const char *journal)
if (gfs1) {
if (j_bh)
brelse(j_bh);
- j_bh = bread(&sbd.buf_list, jblock + jb);
+ j_bh = bread(&sbd, jblock + jb);
abs_block = jblock + jb;
dummy_bh.b_data = j_bh->b_data;
} else {
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 18a0798..1651a94 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -188,7 +188,7 @@ static int save_block(int fd, int out_fd, uint64_t blk)
return 0;
}
memset(savedata, 0, sizeof(struct saved_metablock));
- savebh = bread(&sbd.buf_list, blk);
+ savebh = bread(&sbd, blk);
memcpy(&savedata->buf, savebh->b_data, sbd.bsize);
/* If this isn't metadata and isn't a system file, we don't want it.
@@ -293,12 +293,12 @@ static void save_indirect_blocks(int out_fd, osi_list_t *cur_list,
old_block = indir_block;
blktype = save_block(sbd.device_fd, out_fd, indir_block);
if (blktype == GFS2_METATYPE_EA) {
- nbh = bread(&sbd.buf_list, indir_block);
+ nbh = bread(&sbd, indir_block);
save_ea_block(out_fd, nbh);
brelse(nbh);
}
if (height != hgt) { /* If not at max height */
- nbh = bread(&sbd.buf_list, indir_block);
+ nbh = bread(&sbd, indir_block);
osi_list_add_prev(&nbh->b_altlist,
cur_list);
brelse(nbh);
@@ -332,7 +332,7 @@ static void save_inode_data(int out_fd)
for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
osi_list_init(&metalist[i]);
- metabh = bread(&sbd.buf_list, block);
+ metabh = bread(&sbd, block);
if (gfs1)
inode = inode_get(&sbd, metabh);
else
@@ -383,7 +383,7 @@ static void save_inode_data(int out_fd)
struct gfs2_meta_header mh;
struct gfs2_buffer_head *lbh;
- lbh = bread(&sbd.buf_list, inode->i_di.di_eattr);
+ lbh = bread(&sbd, inode->i_di.di_eattr);
save_block(sbd.device_fd, out_fd, inode->i_di.di_eattr);
gfs2_meta_header_in(&mh, lbh);
if (mh.mh_magic == GFS2_MAGIC &&
@@ -477,8 +477,8 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list
*rgd,
}
for(; i < length; i++){
bits = &rgd->bits[i];
- lbh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
- blk = gfs2_bitfit((unsigned char *)bh->b_data +
+ lbh = bread(sdp, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)lbh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_UNLINKED);
brelse(lbh);
@@ -539,7 +539,6 @@ void savemeta(char *out_fn, int saveoption)
exit(-1);
}
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
if (!gfs1)
sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
if (compute_constants(&sbd)) {
@@ -584,7 +583,7 @@ void savemeta(char *out_fn, int saveoption)
&sbd.md.riinode);
jindex_block = masterblock("jindex");
}
- lbh = bread(&sbd.buf_list, jindex_block);
+ lbh = bread(&sbd, jindex_block);
gfs2_dinode_in(&di, lbh);
if (!gfs1)
do_dinode_extended(&di, lbh);
@@ -753,6 +752,8 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
blks_saved = total_out = 0;
last_fs_block = 0;
while (TRUE) {
+ struct gfs2_buffer_head dummy_bh;
+
memset(savedata, 0, sizeof(struct saved_metablock));
rs = read(in_fd, &buf64, sizeof(uint64_t));
if (!rs)
@@ -794,8 +795,9 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
if (first) {
struct gfs2_sb bufsb;
+ dummy_bh.b_data = (char *)&bufsb;
memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
+ gfs2_sb_in(&sbd.sd_sb, &dummy_bh);
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
sbd1->sb_header.mh_type ==
@@ -823,12 +825,13 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
}
first = 0;
}
+ bh = &dummy_bh;
+ bh->b_data = savedata->buf;
if (printblocksonly) {
block = savedata->blk;
if (block > highest_valid_block)
highest_valid_block = block;
if (printblocksonly > 1 && printblocksonly == block) {
- memcpy(bh->b_data, savedata->buf, sbd.bsize);
block_in_mem = block;
display(0);
return 0;
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 71f1544..893b622 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -118,7 +118,7 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int
start,
if (error)
return error;
- bh_ip = bget(&sdp->buf_list, blkno);
+ bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
check_magic = ((struct gfs2_meta_header *)
@@ -217,7 +217,7 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned
int start,
if (error)
return error;
- bh_ip = bget(&sdp->buf_list, blkno);
+ bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
/* Unescape */
@@ -372,7 +372,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip)
prev_seq = lh.lh_sequence;
log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence);
block_map(ip, blk, &new, &dblock, &extlen, FALSE);
- bh = bread(&ip->i_sbd->buf_list, dblock);
+ bh = bread(ip->i_sbd, dblock);
gfs2_log_header_out(&lh, bh);
brelse(bh);
}
@@ -581,6 +581,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
inode_put(&sdp->master_dir);
inode_put(&sdp->md.jiinode);
/* Sync the buffers to disk so we get a fresh start. */
- bsync(&sdp->buf_list);
+ fsync(sdp->device_fd);
return error;
}
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 9d3def5..0844187 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -276,7 +276,6 @@ 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, 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 fba0c42..ffd7530 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -333,8 +333,6 @@ int main(int argc, char **argv)
int j;
int error = 0;
int all_clean = 0;
- osi_list_t *tmp;
- struct rgrp_list *rgd;
setlocale(LC_ALL, "");
textdomain("gfs2-utils");
@@ -470,13 +468,7 @@ int main(int argc, char **argv)
if (!opts.no && errors_corrected)
log_notice( _("Writing changes to disk\n"));
-
- for (tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
- gfs2_rgrp_relse(rgd);
- }
-
- bsync(&sbp->buf_list);
+ fsync(sbp->device_fd);
destroy(sbp);
log_notice( _("gfs2_fsck complete \n"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index bdb8b80..75ad1e7 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -349,7 +349,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns
*pass)
if (first_leaf_ptr == -1)
first_leaf_ptr = first_ok_leaf;
if(gfs2_check_range(ip->i_sbd, first_ok_leaf) == 0) {
- lbh = bread(&sbp->buf_list, first_ok_leaf);
+ lbh = bread(sbp, first_ok_leaf);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
brelse(lbh);
@@ -393,7 +393,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns
*pass)
if (query( _("Attempt to fix it? (y/n) "))) {
int factor = 0, divisor = ref_count;
- lbh = bread(&sbp->buf_list, old_leaf);
+ lbh = bread(sbp, old_leaf);
while (divisor > 1) {
factor++;
divisor /= 2;
@@ -430,7 +430,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns
*pass)
}
/* Try to read in the leaf block. */
- lbh = bread(&sbp->buf_list, leaf_no);
+ lbh = bread(sbp, leaf_no);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
warn_and_patch(ip, &leaf_no, &bad_leaf,
@@ -496,7 +496,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns
*pass)
}
if(count != leaf.lf_entries) {
- lbh = bread(&sbp->buf_list, leaf_no);
+ lbh = bread(sbp, leaf_no);
gfs2_leaf_in(&leaf, lbh);
log_err( _("Leaf %llu (0x%llx) entry "
@@ -866,9 +866,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
continue;
}
if(!nbh)
- nbh = bread(&ip->i_sbd->buf_list,
- block);
-
+ nbh = bread(ip->i_sbd, block);
osi_list_add(&nbh->b_altlist, cur_list);
} /* for all data on the indirect block */
} /* for blocks at that height */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 40dc6e2..ca36e8d 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -107,7 +107,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
found_dup = 1;
}
- nbh = bread(&ip->i_sbd->buf_list, block);
+ nbh = bread(ip->i_sbd, block);
if (gfs2_check_meta(nbh, GFS2_METATYPE_IN)){
log_debug( _("Bad indirect block pointer (points to "
@@ -327,7 +327,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t
indirect,
check if it really is an EA. If it is, let duplicate
handling sort it out. If it isn't, clear it but don't
count it as a duplicate. */
- *bh = bread(&sdp->buf_list, indirect);
+ *bh = bread(sdp, indirect);
if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
if (!clear_eas(ip, bc, indirect, 1,
@@ -411,7 +411,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int
btype,
/* Special duplicate processing: If we have an EA block, check if it
really is an EA. If it is, let duplicate handling sort it out.
If it isn't, clear it but don't count it as a duplicate. */
- leaf_bh = bread(&sdp->buf_list, block);
+ leaf_bh = bread(sdp, block);
if(gfs2_check_meta(leaf_bh, btype)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
clear_eas(ip, bc, block, 1,
@@ -978,7 +978,7 @@ int pass1(struct gfs2_sbd *sbp)
skip_this_pass = FALSE;
fflush(stdout);
}
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (scan_meta(sbp, bh, block)) {
stack;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a1b327a..3d093ad 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -66,7 +66,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *indir_bh = NULL;
inc_if_found(block, 0, private);
- indir_bh = bread(&sbp->buf_list, block);
+ indir_bh = bread(sbp, block);
*bh = indir_bh;
return 0;
@@ -80,7 +80,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *leaf_bh = NULL;
inc_if_found(block, 0, private);
- leaf_bh = bread(&sbp->buf_list, block);
+ leaf_bh = bread(sbp, block);
*bh = leaf_bh;
return 0;
@@ -402,7 +402,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
struct gfs2_buffer_head *bh;
uint32_t cmagic;
- bh = bread(&sbp->buf_list, b->block_no);
+ bh = bread(sbp, b->block_no);
cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
brelse(bh);
if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 4d9c820..e3bd010 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -100,7 +100,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
return ask_remove_eattr(ip);
}
else
- indir_bh = bread(&sbp->buf_list, block);
+ indir_bh = bread(sbp, block);
*bh = indir_bh;
return 0;
@@ -132,7 +132,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
return ask_remove_eattr(ip);
}
else
- *bh = bread(&sbp->buf_list, block);
+ *bh = bread(sbp, block);
return 0;
}
@@ -252,7 +252,7 @@ int pass1c(struct gfs2_sbd *sbp)
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return FSCK_OK;
- bh = bread(&sbp->buf_list, block_no);
+ bh = bread(sbp, block_no);
if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */
log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"),
block_no, block_no);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 40256a5..147fd12 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -79,14 +79,14 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
{
- *bh = bread(&ip->i_sbd->buf_list, block);
+ *bh = bread(ip->i_sbd, block);
return 0;
}
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
{
- *bh = bread(&ip->i_sbd->buf_list, block);
+ *bh = bread(ip->i_sbd, block);
return 0;
}
@@ -295,7 +295,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
return 1;
/* Now try to clear the dinode, if it is an dinode */
- bhi = bread(&sbp->buf_list, de->de_inum.no_addr);
+ bhi = bread(sbp, de->de_inum.no_addr);
error = gfs2_check_meta(bhi, GFS2_METATYPE_DI);
bmodified(bhi);
brelse(bhi);
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index feeebdc..807ced2 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -53,7 +53,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
increment_link(sbp, newdotdot);
bmodified(ip->i_bh);
fsck_inode_put(&ip);
- bmodified(pip->i_bh);
fsck_inode_put(&pip);
return 0;
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 34c9149..0cb99d2 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -54,7 +54,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp)
block_map(ip, b, &new, &dblock, &extlen, 0);
if (!dblock)
break;
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
if (!gfs2_check_meta(bh, GFS2_METATYPE_RG)) {
log_debug( _("False RG found at block "
"0x%" PRIx64 "\n"), dblock);
@@ -128,7 +128,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->buf_list, blk);
+ bh = bread(sdp, blk);
if (((blk == sdp->sb_addr + 1) ||
(!gfs2_check_meta(bh, GFS2_METATYPE_RG))) &&
!is_false_rg(blk)) {
@@ -206,7 +206,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->buf_list, blk);
+ bh = bread(sdp, blk);
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
brelse(bh);
/* Allocate a new RG and index. */
@@ -240,7 +240,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->buf_list, fwd_block);
+ bh = bread(sdp, fwd_block);
bitmap_was_fnd =
(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
brelse(bh);
@@ -384,7 +384,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list
*rg,
(int)x+1, (int)rg->ri.ri_length);
if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
- rg->bh[x] = bread(&sdp->buf_list, rg->ri.ri_addr + x);
+ rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
if (x) {
struct gfs2_meta_header mh;
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 8997503..5b8d29d 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -12,120 +12,18 @@
#include "libgfs2.h"
-static __inline__ osi_list_t *
-blkno2head(struct buf_list *bl, uint64_t blkno)
-{
- return bl->buf_hash +
- (gfs2_disk_hash((char *)&blkno, sizeof(uint64_t)) & BUF_HASH_MASK);
-}
-
-static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
-{
- struct gfs2_sbd *sdp = bl->sbp;
-
- osi_list_del(&bh->b_list);
- osi_list_del(&bh->b_hash);
- bl->num_bufs--;
- if (bh->b_changed) {
- if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize,
- SEEK_SET) != bh->b_blocknr * sdp->bsize) {
- return -1;
- }
- if (write(sdp->device_fd, bh->b_data, sdp->bsize) !=
- sdp->bsize) {
- return -1;
- }
- sdp->writes++;
- }
- bh->b_blocknr = -1;
- bh->b_data = NULL;
- bh->b_count = -1;
- bh->b_changed = -1;
- free(bh);
- return 0;
-}
-
-void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit)
-{
- int i;
-
- bl->num_bufs = 0;
- bl->spills = 0;
- bl->limit = limit;
- bl->sbp = sdp;
- osi_list_init(&bl->list);
- for(i = 0; i < BUF_HASH_SIZE; i++)
- osi_list_init(&bl->buf_hash[i]);
-}
-
-static int add_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
-{
- osi_list_t *head = blkno2head(bl, bh->b_blocknr);
-
- osi_list_add(&bh->b_list, &bl->list);
- osi_list_add(&bh->b_hash, head);
- bl->num_bufs++;
-
- if (bl->num_bufs * bl->sbp->bsize > bl->limit) {
- int found = 0;
- osi_list_t *tmp, *x;
-
- for (tmp = bl->list.prev, x = tmp->prev; tmp != &bl->list;
- tmp = x, x = x->prev) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head,
- b_list);
- if (!bh->b_count) {
- if (write_buffer(bl, bh))
- return -1;
- found++;
- if (found >= 10)
- break;
- }
- }
- bl->spills++;
- }
- return 0;
-}
-
-struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num)
-{
- osi_list_t *head = blkno2head(bl, num);
- osi_list_t *tmp;
- struct gfs2_buffer_head *bh;
-
- for (tmp = head->next; tmp != head; tmp = tmp->next) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_hash);
- if (bh->b_blocknr == num) {
- osi_list_del(&bh->b_list);
- osi_list_add(&bh->b_list, &bl->list);
- osi_list_del(&bh->b_hash);
- osi_list_add(&bh->b_hash, head);
- bh->b_count++;
- return bh;
- }
- }
-
- return NULL;
-}
-
-struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, uint64_t num,
- int find_existing, int read_disk,
+struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, uint64_t num,
+ int read_disk,
int line, const char *caller)
{
struct gfs2_buffer_head *bh;
- struct gfs2_sbd *sdp = bl->sbp;
- if (find_existing) {
- bh = bfind(bl, num);
- if (bh)
- return bh;
- }
bh = calloc(1, sizeof(struct gfs2_buffer_head) + sdp->bsize);
if (bh == NULL)
return NULL;
- bh->b_count = 1;
bh->b_blocknr = num;
+ bh->sdp = sdp;
bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head);
if (read_disk) {
if (lseek(sdp->device_fd, num * sdp->bsize, SEEK_SET) !=
@@ -144,119 +42,48 @@ struct gfs2_buffer_head *__bget_generic(struct buf_list *bl,
uint64_t num,
exit(-1);
}
}
- if (add_buffer(bl, bh)) {
- fprintf(stderr, "bad write: %s from %s:%d: block "
- "%llu (0x%llx)\n", strerror(errno),
- caller, line, (unsigned long long)num,
- (unsigned long long)num);
- exit(-1);
- }
- bh->b_changed = FALSE;
return bh;
}
-struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, int line,
+struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num, int line,
const char *caller)
{
- return __bget_generic(bl, num, TRUE, FALSE, line, caller);
+ return __bget_generic(sdp, num, FALSE, line, caller);
}
-struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, int line,
+struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
const char *caller)
{
- return __bget_generic(bl, num, TRUE, TRUE, line, caller);
-}
-
-struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh)
-{
- if (!bh->b_count)
- return NULL;
- bh->b_count++;
- return bh;
-}
-
-void bmodified(struct gfs2_buffer_head *bh)
-{
- bh->b_changed = 1;
-}
-
-void brelse(struct gfs2_buffer_head *bh)
-{
- /* We can't just say b_changed = updated because we don't want to */
- /* set it FALSE if it's TRUE until we write the changed data to disk. */
- if (!bh->b_count) {
- fprintf(stderr, "buffer count underflow for block %" PRIu64
- " (0x%" PRIx64")\n", bh->b_blocknr, bh->b_blocknr);
- exit(-1);
- }
- bh->b_count--;
+ return __bget_generic(sdp, num, TRUE, line, caller);
}
-void __bsync(struct buf_list *bl, int line, const char *caller)
+int bwrite(struct gfs2_buffer_head *bh)
{
- struct gfs2_buffer_head *bh;
+ struct gfs2_sbd *sdp = bh->sdp;
- while (!osi_list_empty(&bl->list)) {
- bh = osi_list_entry(bl->list.prev, struct gfs2_buffer_head,
- b_list);
- if (bh->b_count) {
- fprintf(stderr, "buffer still held for block: %" PRIu64
- " (0x%" PRIx64")\n", bh->b_blocknr, bh->b_blocknr);
- exit(-1);
- }
- if (write_buffer(bl, bh)) {
- fprintf(stderr, "bad write: %s from %s:%d: block "
- "%lld (0x%llx)\n", strerror(errno),
- caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
+ if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize, SEEK_SET) !=
+ bh->b_blocknr * sdp->bsize) {
+ return -1;
}
+ if (write(sdp->device_fd, bh->b_data, sdp->bsize) != sdp->bsize)
+ return -1;
+ sdp->writes++;
+ bh->b_changed = 0;
+ return 0;
}
-/* commit buffers to disk but do not discard */
-void __bcommit(struct buf_list *bl, int line, const char *caller)
+int brelse(struct gfs2_buffer_head *bh)
{
- osi_list_t *tmp, *x;
- struct gfs2_buffer_head *bh;
- struct gfs2_sbd *sdp = bl->sbp;
+ int error = 0;
- osi_list_foreach_safe(tmp, &bl->list, x) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
- if (!bh->b_count) { /* if not reserved for later */
- if (write_buffer(bl, bh)) { /* write & free */
- fprintf(stderr, "bad write: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- } else if (bh->b_changed) { /* if buffer has changed */
- if (lseek(sdp->device_fd,
- bh->b_blocknr * sdp->bsize, SEEK_SET) !=
- bh->b_blocknr * sdp->bsize) {
- fprintf(stderr, "bad seek: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- if (write(sdp->device_fd, bh->b_data, sdp->bsize) !=
- sdp->bsize) {
- fprintf(stderr, "bad write: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- bh->b_changed = FALSE; /* no longer changed */
- }
- }
- fsync(sdp->device_fd);
+ if (bh->b_blocknr == -1)
+ printf("Double free!\n");
+ if (bh->b_changed)
+ error = bwrite(bh);
+ bh->b_blocknr = -1;
+ if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist))
+ osi_list_del(&bh->b_altlist);
+ free(bh);
+ return error;
}
-
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 6fbc10f..3fe26fa 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -214,7 +214,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
if (do_write) {
for (x = 0; x < bitblocks; x++) {
- bh = bget(&sdp->buf_list, rl->start + x);
+ bh = bget(sdp, rl->start + x);
if (x)
gfs2_meta_header_out(&mh, bh);
else
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 4279d99..b3b527f 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -53,7 +53,7 @@ struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
exit(-1);
}
- ip->i_bh = bread(&sdp->buf_list, di_addr);
+ ip->i_bh = bread(sdp, di_addr);
gfs2_dinode_in(&ip->i_di, ip->i_bh);
ip->i_sbd = sdp;
ip->bh_owned = 1; /* We did the bread so we own the bh */
@@ -235,7 +235,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
if (ip->i_di.di_size) {
if (isdir) {
block = meta_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -251,7 +251,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
brelse(bh);
} else {
block = data_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
buffer_copy_tail(sdp, bh, 0,
ip->i_bh, sizeof(struct gfs2_dinode));
@@ -313,7 +313,7 @@ void build_height(struct gfs2_inode *ip, int height)
if (new_block) {
block = meta_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -439,7 +439,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
if (*new) {
struct gfs2_meta_header mh;
- bh = bget(&sdp->buf_list, *dblock);
+ bh = bget(sdp, *dblock);
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
@@ -448,7 +448,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
if (*dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, *dblock);
+ bh = bread(sdp, *dblock);
}
}
@@ -547,7 +547,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
if (dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
dblock++;
extlen--;
} else
@@ -622,7 +622,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
}
if (new) {
- bh = bget(&sdp->buf_list, dblock);
+ bh = bget(sdp, dblock);
if (isdir) {
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -634,7 +634,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
if (dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
}
copy_from_mem(bh, &buf, o, amount);
if (bh != ip->i_bh)
@@ -676,12 +676,12 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip,
uint64_t lbn,
ip->i_di.di_size = (lbn + 1) << sdp->sd_sb.sb_bsize_shift;
}
if (new)
- return bget(&sdp->buf_list, dbn);
+ return bget(sdp, dbn);
else {
if (dbn == ip->i_di.di_num.no_addr)
return ip->i_bh;
else
- return bread(&sdp->buf_list, dbn);
+ return bread(sdp, dbn);
}
}
@@ -850,7 +850,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
uint64_t lea
int count;
bn = meta_alloc(dip);
- nbh = bget(&dip->i_sbd->buf_list, bn);
+ nbh = bget(dip->i_sbd, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -862,7 +862,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
uint64_t lea
nleaf = (struct gfs2_leaf *)nbh->b_data;
nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
- obh = bread(&dip->i_sbd->buf_list, leaf_no);
+ obh = bread(dip->i_sbd, leaf_no);
oleaf = (struct gfs2_leaf *)obh->b_data;
len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
@@ -1002,7 +1002,7 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
{
int error = 0;
- *bhp = bread(&dip->i_sbd->buf_list, leaf_no);
+ *bhp = bread(dip->i_sbd, leaf_no);
if (error)
return error;
error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF);
@@ -1026,7 +1026,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
uint64_t leaf_no;
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
- *bh_out = bread(&dip->i_sbd->buf_list, leaf_no);
+ *bh_out = bread(dip->i_sbd, leaf_no);
return 0;
}
@@ -1048,7 +1048,7 @@ static int get_next_leaf(struct gfs2_inode *dip,struct
gfs2_buffer_head *bh_in,
if (!leaf->lf_next)
return -1;
- *bh_out = bread(&dip->i_sbd->buf_list, be64_to_cpu(leaf->lf_next));
+ *bh_out = bread(dip->i_sbd, be64_to_cpu(leaf->lf_next));
return 0;
}
@@ -1073,7 +1073,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename,
int len,
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
for (;;) {
- bh = bread(&dip->i_sbd->buf_list, leaf_no);
+ bh = bread(dip->i_sbd, leaf_no);
leaf = (struct gfs2_leaf *)bh->b_data;
if (dirent_alloc(dip, bh, len, &dent)) {
@@ -1095,7 +1095,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename,
int len,
} else {
bn = meta_alloc(dip);
- nbh = bget(&dip->i_sbd->buf_list, bn);
+ nbh = bget(dip->i_sbd, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -1145,7 +1145,7 @@ static void dir_make_exhash(struct gfs2_inode *dip)
uint64_t *lp, bn;
bn = meta_alloc(dip);
- bh = bget(&sdp->buf_list, bn);
+ bh = bget(sdp, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -1195,6 +1195,7 @@ static void dir_make_exhash(struct gfs2_inode *dip)
dip->i_di.di_depth = y;
gfs2_dinode_out(&dip->i_di, dip->i_bh);
+ bwrite(dip->i_bh);
}
static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1231,7 +1232,7 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh;
struct gfs2_dinode di;
- bh = bget(&sdp->buf_list, inum->no_addr);
+ bh = bget(sdp, inum->no_addr);
memset(&di, 0, sizeof(struct gfs2_dinode));
di.di_header.mh_magic = GFS2_MAGIC;
@@ -1557,7 +1558,7 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename,
int len)
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
while(leaf_no && !found){
- bh = bread(&dip->i_sbd->buf_list, leaf_no);
+ bh = bread(dip->i_sbd, leaf_no);
error = leaf_search(dip, bh, filename, len, &cur, &prev);
if (error) {
if(error != -ENOENT){
@@ -1696,7 +1697,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
osi_list_init(&metalist[h]);
- bh = bread(&sdp->buf_list, diblock);
+ bh = bread(sdp, diblock);
ip = inode_get(sdp, bh);
height = ip->i_di.di_height;
osi_list_add(&bh->b_altlist, &metalist[0]);
@@ -1721,7 +1722,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
if (h == height - 1) /* if not metadata */
continue; /* don't queue it up */
/* Read the next metadata block in the chain */
- nbh = bread(&sdp->buf_list, block);
+ nbh = bread(sdp, block);
osi_list_add(&nbh->b_altlist, next_list);
brelse(nbh);
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5232c01..5cced66 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -110,13 +110,13 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int
*new,
if (*new) {
struct gfs2_meta_header mh;
- bh = bget(&sdp->buf_list, *dblock);
+ bh = bget(sdp, *dblock);
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
gfs2_meta_header_out(&mh, bh);
} else {
- bh = bread(&sdp->buf_list, *dblock);
+ bh = bread(sdp, *dblock);
}
}
@@ -199,7 +199,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
&extlen, FALSE);
if (dblock) {
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
dblock++;
extlen--;
} else
@@ -412,7 +412,7 @@ struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t
di_addr)
exit(-1);
}
- ip->i_bh = bread(&sdp->buf_list, di_addr);
+ ip->i_bh = bread(sdp, di_addr);
gfs_dinode_in(&gfs1_dinode, ip->i_bh);
memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
sizeof(struct gfs2_meta_header));
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 643c728..db1b38e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -105,15 +105,11 @@ struct rgrp_list {
};
struct gfs2_buffer_head {
- osi_list_t b_list;
- osi_list_t b_hash;
osi_list_t b_altlist; /* alternate list */
-
- unsigned int b_count;
uint64_t b_blocknr;
- char *b_data;
-
int b_changed;
+ char *b_data;
+ struct gfs2_sbd *sdp;
};
struct dup_blocks {
@@ -174,15 +170,6 @@ struct master_dir
struct per_node *pn; /* Array of per_node entries */
};
-struct buf_list {
- unsigned int num_bufs;
- unsigned int spills;
- uint32_t limit;
- osi_list_t list;
- struct gfs2_sbd *sbp;
- osi_list_t buf_hash[BUF_HASH_SIZE];
-};
-
struct gfs2_sbd {
struct gfs2_sb sd_sb; /* a copy of the ondisk structure */
char lockproto[GFS2_LOCKNAME_LEN];
@@ -243,8 +230,6 @@ struct gfs2_sbd {
unsigned int orig_journals;
- struct buf_list buf_list; /* transient buffer list */
-
struct gfs2_inode *master_dir;
struct master_dir md;
@@ -346,21 +331,18 @@ extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap
*il,
extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
-extern void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
-extern struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num);
-extern struct gfs2_buffer_head *__bget_generic(struct buf_list *bl,
- uint64_t num, int find_existing,
+extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp,
+ uint64_t num,
int read_disk, int line,
const char *caller);
-extern struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num,
+extern struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
-extern struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num,
+extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
-extern struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh);
-extern void bmodified(struct gfs2_buffer_head *bh);
-extern void brelse(struct gfs2_buffer_head *bh);
-extern void __bsync(struct buf_list *bl, int line, const char *caller);
-extern void __bcommit(struct buf_list *bl, int line, const char *caller);
+extern int bwrite(struct gfs2_buffer_head *bh);
+extern int brelse(struct gfs2_buffer_head *bh);
+
+#define bmodified(bh) do { bh->b_changed = 1; } while(0)
#define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \
__LINE__, \
diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c
index fee7ef2..74f896e 100644
--- a/gfs2/libgfs2/recovery.c
+++ b/gfs2/libgfs2/recovery.c
@@ -31,7 +31,7 @@ int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk,
if (!dblock)
return -EIO;
- *bh = bread(&ip->i_sbd->buf_list, dblock);
+ *bh = bread(ip->i_sbd, dblock);
return 0;
}
@@ -223,7 +223,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header
*head)
if (!dblock)
return -EIO;
- bh = bread(&ip->i_sbd->buf_list, dblock);
+ bh = bread(ip->i_sbd, dblock);
memset(bh->b_data, 0, ip->i_sbd->bsize);
lh = (struct gfs2_log_header *)bh->b_data;
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index ed1df78..f42fdaa 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -126,7 +126,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++){
- rgd->bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ rgd->bh[x] = bread(sdp, rgd->ri.ri_addr + x);
if(gfs2_check_meta(rgd->bh[x],
(x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 5343f88..b1dd4ff 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -42,7 +42,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
/* Zero out the beginning of the device up to the superblock */
for (x = 0; x < sdp->sb_addr; x++) {
- bh = bget(&sdp->buf_list, x);
+ bh = bget(sdp, x);
memset(bh->b_data, 0, sdp->bsize);
bmodified(bh);
brelse(bh);
@@ -63,7 +63,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
#ifdef GFS2_HAS_UUID
memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid));
#endif
- bh = bget(&sdp->buf_list, sdp->sb_addr);
+ bh = bget(sdp, sdp->sb_addr);
gfs2_sb_out(&sb, bh);
brelse(bh);
@@ -492,7 +492,7 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list
*rgd,
brelse(bh);
if (gfs2_next_rg_meta(rgd, block, first))
return -1;
- bh = bread(&sdp->buf_list, *block);
+ bh = bread(sdp, *block);
first = 0;
} while(gfs2_check_meta(bh, type));
brelse(bh);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 00a2ae7..0d65928 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -58,7 +58,7 @@ int read_sb(struct gfs2_sbd *sdp)
unsigned int x;
int error;
- bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
+ bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
gfs2_sb_in(&sdp->sd_sb, bh);
brelse(bh);
@@ -256,10 +256,10 @@ int write_sb(struct gfs2_sbd *sbp)
{
struct gfs2_buffer_head *bh;
- bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
+ bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
gfs2_sb_out(&sbp->sd_sb, bh);
brelse(bh);
- bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
+ fsync(sbp->device_fd); /* 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 2da353a..4245155 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -171,7 +171,7 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int
*old_rg_count)
inode_put(&sdp->master_dir);
/* We're done with the libgfs portion, so commit it to disk. */
- bsync(&sdp->buf_list);
+ fsync(sdp->device_fd);
}
/**
@@ -283,7 +283,6 @@ main_grow(int argc, char *argv[])
}
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- 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 3d3012f..ceff0dc 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -528,8 +528,6 @@ print_results(struct gfs2_sbd *sdp, uint64_t real_device_size,
if (sdp->debug) {
printf("\n");
- printf( _("Spills: %u\n"),
- sdp->buf_list.spills);
printf( _("Writes: %u\n"), sdp->writes);
}
@@ -561,7 +559,6 @@ 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, 1 << 20);
decode_arguments(argc, argv, sdp);
if (sdp->rgsize == -1) /* if rg size not specified */
@@ -641,7 +638,6 @@ void main_mkfs(int argc, char *argv[])
inode_put(&sdp->master_dir);
inode_put(&sdp->md.inum);
inode_put(&sdp->md.statfs);
- bsync(&sdp->buf_list);
error = fsync(sdp->device_fd);
if (error)