cluster: RHEL56 - fsck.gfs2: make query() count errors_found, errors_fixed
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 965554a2d3d18d877bb4ce3f1cf369775b882e7a
Parent: bf0822c4fd7bd701f36ddaef045fb8d587b47f96
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Dec 2 14:42:55 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:09:45 2010 -0500
fsck.gfs2: make query() count errors_found, errors_fixed
This patch changes the query() function so that it keeps track
of errors_found and errors_corrected. This enforces a consistent
count of errors found and corrected so that the return code from
fsck.gfs2 is correct and future code changes that require calls
to query don't have to code it. It also makes the calls a tiny
bit faster because they no longer have to pass the opt variable.
rhbz#455300
---
gfs2/fsck/fs_recovery.c | 12 +++---
gfs2/fsck/fsck.h | 4 ++-
gfs2/fsck/main.c | 5 +--
gfs2/fsck/metawalk.c | 34 +++++--------------
gfs2/fsck/pass1.c | 34 +++++--------------
gfs2/fsck/pass1b.c | 19 ++++-------
gfs2/fsck/pass1c.c | 9 +----
gfs2/fsck/pass2.c | 80 +++++++++++++---------------------------------
gfs2/fsck/pass3.c | 23 +++++---------
gfs2/fsck/pass4.c | 24 +++++---------
gfs2/fsck/pass5.c | 22 +++++--------
gfs2/fsck/rgrepair.c | 9 +----
gfs2/fsck/util.c | 62 ++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/gfs2_log.c | 2 +-
gfs2/libgfs2/libgfs2.h | 16 +++++++--
15 files changed, 161 insertions(+), 194 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 46a1084..29e7d2e 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -460,9 +460,9 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
"without -a or -p.\n"));
goto out;
}
- if (!query(&opts, _("\nJournal #%d (\"journal%d\") is "
- "corrupt. Okay to repair it? (y/n)"),
- j+1, j)) {
+ if (!query( _("\nJournal #%d (\"journal%d\") is "
+ "corrupt. Okay to repair it? (y/n)"),
+ j+1, j)) {
log_err( _("jid=%u: The journal was not repaired.\n"),
j);
goto out;
@@ -505,8 +505,8 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
error = FSCK_ERROR;
goto out;
}
- if (query(&opts, _("\nJournal #%d (\"journal%d\") is dirty. Okay to "
- "replay it? (y/n)"), j+1, j)) {
+ if (query( _("\nJournal #%d (\"journal%d\") is dirty. Okay to "
+ "replay it? (y/n)"), j+1, j)) {
log_info( _("jid=%u: Replaying journal...\n"), j);
sd_found_jblocks = sd_replayed_jblocks = 0;
@@ -530,7 +530,7 @@ static int gfs2_recover_journal(struct gfs2_inode *ip, int j, int preen,
log_err( _("jid=%u: Replayed %u of %u metadata blocks\n"),
j, sd_replayed_metablocks, sd_found_metablocks);
} else {
- if (query(&opts, _("Do you want to clear the dirty journal instead? (y/n)"))) {
+ if (query( _("Do you want to clear the dirty journal instead? (y/n)"))) {
write_journal(sdp, sdp->md.journal[j], j,
sdp->md.journal[j]->i_di.di_size /
sdp->sd_sb.sb_bsize);
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 754b409..6bba989 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -19,7 +19,7 @@
#define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT)
#define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1)
-#define query(opts, fmt, args...) gfs2_query(&fsck_abort, opts, fmt, ##args)
+#define query(fmt, args...) fsck_query(fmt, ##args)
/*
* Exit codes used by fsck-type programs
@@ -87,6 +87,8 @@ int pass3(struct gfs2_sbd *sbp);
int pass4(struct gfs2_sbd *sbp);
int pass5(struct gfs2_sbd *sbp);
int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count);
+int fsck_query(const char *format, ...)
+ __attribute__((format(printf,1,2)));
/* FIXME: Hack to get this going for pass2 - this should be pulled out
* of pass1 and put somewhere else... */
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 6af2759..841d351 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -202,10 +202,7 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
* system inodes before we can do any of that. */
if(!sysinode || ds.q.block_type != mark) {
log_err( _("Invalid or missing %s system inode.\n"), filename);
- errors_found++;
- if (query(&opts, _("Create new %s system inode? (y/n) "),
- filename)) {
- errors_corrected++;
+ if (query(_("Create new %s system inode? (y/n) "), filename)) {
builder(sysinode->i_sbd);
gfs2_block_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 00d5a4a..5052eb6 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -238,8 +238,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
(*count) + 1,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if (query(&opts, _("Attempt to repair it? (y/n) "))) {
+ if (query( _("Attempt to repair it? (y/n) "))) {
if (dirent_repair(ip, bh, &de, dent, type,
first)) {
if (first) /* make a new sentinel */
@@ -254,7 +253,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
} else {
log_err( _("Corrupt directory entry "
"repaired.\n"));
- errors_corrected++;
bmodified(bh);
/* keep looping through dentries */
}
@@ -277,8 +275,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
(unsigned long long)bh->b_blocknr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- if (query(&opts,
- _("Attempt to remove it? (y/n) "))) {
+ if (query(_("Attempt to remove it? (y/n) "))) {
dirblk_truncate(ip, prev, bh);
log_err(_("The corrupt directory "
"entry was removed.\n"));
@@ -344,10 +341,8 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
(unsigned long long)*leaf_no,
(unsigned long long)*leaf_no, msg);
}
- errors_found++;
if (*leaf_no == *bad_leaf ||
- query(&opts, _("Attempt to patch around it? (y/n) "))) {
- errors_corrected++;
+ query( _("Attempt to patch around it? (y/n) "))) {
if (gfs2_check_range(ip->i_sbd, old_leaf) == 0)
gfs2_put_leaf_nr(ip, pindex, old_leaf);
else
@@ -425,11 +420,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)old_leaf,
(unsigned long long)old_leaf,
ref_count, exp_count);
- errors_found++;
- if (query(&opts, _("Attempt to fix it? (y/n) "))) {
+ if (query( _("Attempt to fix it? (y/n) "))) {
int factor = 0, divisor = ref_count;
- errors_corrected++;
lbh = bread(&sbp->buf_list, old_leaf);
while (divisor > 1) {
factor++;
@@ -550,9 +543,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)
ip->i_di.di_num.no_addr,
leaf.lf_entries, count);
- errors_found++;
- if(query(&opts, _("Update leaf entry count? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Update leaf entry count? (y/n) "))) {
leaf.lf_entries = count;
gfs2_leaf_out(&leaf, lbh->b_data);
log_warn( _("Leaf entry count updated\n"));
@@ -628,11 +619,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
bh, ea_hdr,
ea_hdr_prev,
pass->private)) {
- errors_found++;
- if (query(&opts, _("Repair the bad "
- "Extended Attribute? "
- "(y/n) "))) {
- errors_corrected++;
+ if (query( _("Repair the bad Extended "
+ "Attribute? (y/n) "))) {
ea_hdr->ea_num_ptrs = i;
ea_hdr->ea_data_len =
cpu_to_be32(tot_ealen);
@@ -748,13 +736,9 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
error = check_leaf_eattr(ip, block, indirect, pass);
if (error) {
leaf_pointer_errors++;
- errors_found++;
- if (query(&opts, _("Fix the indirect "
- "block too? (y/n) "))) {
- bmodified(indirect_buf);
- errors_corrected++;
+ if (query( _("Fix the indirect "
+ "block too? (y/n) ")))
*ea_leaf_ptr = 0;
- }
}
/* If the first eattr lead is bad, we can't have
a hole, so we have to treat this as an unrecoverable
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3b73048..f61164c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -219,12 +219,10 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
const char *allocdesc[] = {"free space", "data", "unlinked",
"metadata", "reserved"};
- errors_found++;
log_err( _("Block %llu (0x%llx) seems to be data, but is "
"marked as %s.\n"), (unsigned long long)block,
(unsigned long long)block, allocdesc[btype]);
- if(query(&opts, _("Okay to mark it as 'data'? (y/n)"))) {
- errors_corrected++;
+ if(query( _("Okay to mark it as 'data'? (y/n)"))) {
gfs2_set_bitmap(ip->i_sbd, block, GFS2_BLKST_USED);
log_err( _("The block was reassigned as data.\n"));
} else {
@@ -258,12 +256,10 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute "
"errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if (query(&opts, _("Clear all Extended Attributes from the "
- "inode? (y/n) "))) {
+ if (query( _("Clear all Extended Attributes from the "
+ "inode? (y/n) "))) {
struct gfs2_block_query q;
- errors_corrected++;
if(gfs2_block_check(ip->i_sbd, bl, ip->i_di.di_eattr, &q)) {
stack;
return -1;
@@ -298,9 +294,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
(unsigned long long)ip->i_di.di_num.no_addr, emsg);
log_err( _(" at block #%lld (0x%llx).\n"),
(unsigned long long)block, (unsigned long long)block);
- errors_found++;
- if (query(&opts, _("Clear the bad Extended Attribute? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Clear the bad Extended Attribute? (y/n) "))) {
if (block == ip->i_di.di_eattr) {
remove_inode_eattr(ip, bc, duplicate);
log_err( _("The bad extended attribute was "
@@ -405,10 +399,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
"Extended Attribute errors.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if (query(&opts, _("Okay to fix the block count for the inode? "
- "(y/n) "))) {
- errors_corrected++;
+ if (query( _("Okay to fix the block count for the inode? (y/n) "))) {
ip->i_di.di_blocks = 1 + bc->indir_count +
bc->data_count + bc->ea_count;
bmodified(ip->i_bh);
@@ -697,11 +688,9 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(unsigned long long)block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if(query(&opts, _("Fix address in inode at block #%"
- PRIu64 " (0x%" PRIx64 ")? (y/n) "),
+ if(query( _("Fix address in inode at block #%"
+ PRIu64 " (0x%" PRIx64 ")? (y/n) "),
block, block)) {
- errors_corrected++;
ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
bmodified(ip->i_bh);
@@ -897,9 +886,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(unsigned long long)bc.indir_count,
(unsigned long long)bc.data_count,
(unsigned long long)bc.ea_count);
- errors_found++;
- if (query(&opts, _("Fix ondisk block count? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Fix ondisk block count? (y/n) "))) {
ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count +
bc.ea_count;
bmodified(ip->i_bh);
@@ -919,8 +906,6 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
uint64_t block)
{
if (gfs2_check_meta(bh, 0)) {
- errors_found++;
-
log_info( _("Found invalid metadata at #%llu (0x%llx)\n"),
(unsigned long long)block,
(unsigned long long)block);
@@ -928,8 +913,7 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
stack;
return -1;
}
- if(query(&opts, _("Okay to free the invalid block? (y/n)"))) {
- errors_corrected++;
+ if(query( _("Okay to free the invalid block? (y/n)"))) {
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
log_err( _("The invalid block was freed.\n"));
} else {
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 6eb40f5..e0b7ab3 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -430,9 +430,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
(unsigned long long)id->block_no,
(unsigned long long)b->block_no,
(unsigned long long)b->block_no);
- errors_found++;
- if (query(&opts, _("Clear the inode? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Clear the inode? (y/n) "))) {
log_warn( _("Clearing inode %lld (0x%llx)...\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
@@ -470,18 +468,15 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
}
osi_list_foreach(tmp, &b->ref_inode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
- errors_found++;
- if (!(query(&opts, _("Okay to clear inode %lld (0x%llx)? "
- "(y/n) "),
- (unsigned long long)id->block_no,
- (unsigned long long)id->block_no))) {
+ if (!(query( _("Okay to clear inode %lld (0x%llx)? (y/n) "),
+ (unsigned long long)id->block_no,
+ (unsigned long long)id->block_no))) {
log_warn( _("The bad inode was not cleared...\n"));
continue;
}
- errors_corrected++;
- log_warn( _("Clearing inode %lld (0x%llx)...\n"),
- (unsigned long long)id->block_no,
- (unsigned long long)id->block_no);
+ log_warn( _("Clearing inode %lld (0x%llx)...\n"),
+ (unsigned long long)id->block_no,
+ (unsigned long long)id->block_no);
ip = fsck_load_inode(sbp, id->block_no);
dh.b = b;
dh.id = id;
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 4cf2c44..a00ce2d 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -50,10 +50,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
struct gfs2_ea_header *prev,
int fix_curr, int fix_curr_len)
{
- errors_found++;
- if (query(&opts, _("Remove the bad Extended Attribute entry? "
- "(y/n) "))) {
- errors_corrected++;
+ if (query( _("Remove the bad Extended Attribute entry? (y/n) "))) {
if (fix_curr)
curr->ea_flags |= GFS2_EAFLAG_LAST;
if (fix_curr_len) {
@@ -74,9 +71,7 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
static int ask_remove_eattr(struct gfs2_inode *ip)
{
- errors_found++;
- if (query(&opts, _("Remove the bad Extended Attribute? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Remove the bad Extended Attribute? (y/n) "))) {
ip->i_di.di_eattr = 0;
bmodified(ip->i_bh);
log_err( _("Bad Extended Attribute removed.\n"));
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 1827c67..6509171 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -213,10 +213,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("\tName length found = %u\n"
"\tHash expected = %u (0x%x)\n"),
de->de_name_len, calculated_hash, calculated_hash);
- errors_found++;
- if(query(&opts, _("Fix directory hash for %s? (y/n) "),
- filename)) {
- errors_corrected++;
+ if(query( _("Fix directory hash for %s? (y/n) "),
+ filename)) {
de->de_hash = calculated_hash;
gfs2_dirent_out(de, (char *)dent);
log_err( _("Directory entry hash for %s fixed.\n"), filename);
@@ -237,10 +235,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(gfs2_check_range(ip->i_sbd, entryblock)) {
log_err( _("Block # referenced by directory entry %s is out of range\n"),
tmp_name);
- errors_found++;
- if(query(&opts,
- _("Clear directory entry tp out of range block? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Clear directory entry tp out of range block? (y/n) "))) {
log_err( _("Clearing %s\n"), tmp_name);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -263,9 +258,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* Handle bad blocks */
log_err( _("Found a bad directory entry: %s\n"), filename);
- errors_found++;
- if(query(&opts, _("Delete inode containing bad blocks? (y/n)"))) {
- errors_corrected++;
+ if(query( _("Delete inode containing bad blocks? (y/n)"))) {
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
@@ -301,12 +294,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
_("previously marked invalid") :
_("is not an inode"));
- errors_found++;
- if(query(&opts, _("Clear directory entry to non-inode block? "
- "(y/n) "))) {
+ if(query( _("Clear directory entry to non-inode block? "
+ "(y/n) "))) {
struct gfs2_buffer_head *bhi;
- errors_corrected++;
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
log_warn( _("Directory entry '%s' cleared\n"), tmp_name);
@@ -353,9 +344,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)de->de_inum.no_addr,
(unsigned long long)de->de_inum.no_addr,
block_type_string(&q));
- errors_found++;
- if(query(&opts, _("Clear stale directory entry? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Clear stale directory entry? (y/n) "))) {
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(entry_ip);
@@ -380,10 +369,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
" (0x%llx)\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if(query(&opts, _("Clear duplicate '.' entry? (y/n) "))) {
-
- errors_corrected++;
+ if(query( _("Clear duplicate '.' entry? (y/n) "))) {
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(entry_ip);
@@ -418,9 +404,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)de->de_inum.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if(query(&opts, _("Remove '.' reference? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Remove '.' reference? (y/n) "))) {
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(entry_ip);
@@ -454,10 +438,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
"(0x%llx)\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if(query(&opts, _("Clear duplicate '..' entry? (y/n) "))) {
+ if(query( _("Clear duplicate '..' entry? (y/n) "))) {
- errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(entry_ip);
@@ -482,9 +464,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
"pointing to something that's not a directory"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if(query(&opts, _("Clear bad '..' directory entry? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Clear bad '..' directory entry? (y/n) "))) {
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(entry_ip);
@@ -534,9 +514,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64
") detected.\n"), filename, entryblock, entryblock);
- errors_found++;
- if(query(&opts, _("Clear hard link to directory? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Clear hard link to directory? (y/n) "))) {
bmodified(bh);
dirent2_del(ip, bh, prev_de, dent);
log_warn( _("Directory entry %s cleared\n"), filename);
@@ -616,9 +594,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
}
if(!ds.dotdir) {
log_err( _("No '.' entry found for %s directory.\n"), dirname);
- errors_found++;
- if (query(&opts, _("Is it okay to add '.' entry? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Is it okay to add '.' entry? (y/n) "))) {
sprintf(tmp_name, ".");
filename_len = strlen(tmp_name); /* no trailing NULL */
if(!(filename = malloc(sizeof(char) * filename_len))) {
@@ -650,12 +626,10 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
(unsigned long long)sysinode->i_di.di_num.no_addr,
(unsigned long long)sysinode->i_di.di_num.no_addr,
sysinode->i_di.di_entries, ds.entry_count);
- errors_found++;
- if(query(&opts, _("Fix entries for %s inode %llu (0x%llx"
- ")? (y/n) "), dirname,
- (unsigned long long)sysinode->i_di.di_num.no_addr,
- (unsigned long long)sysinode->i_di.di_num.no_addr)) {
- errors_corrected++;
+ if(query( _("Fix entries for %s inode %llu (0x%llx)? (y/n) "),
+ dirname,
+ (unsigned long long)sysinode->i_di.di_num.no_addr,
+ (unsigned long long)sysinode->i_di.di_num.no_addr)) {
sysinode->i_di.di_entries = ds.entry_count;
bmodified(sysinode->i_bh);
log_warn( _("Entries updated\n"));
@@ -779,12 +753,10 @@ int pass2(struct gfs2_sbd *sbp)
}
if(error == 0) {
/* FIXME: factor */
- errors_found++;
- if(query(&opts, _("Remove directory entry for bad"
- " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
- " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent,
- di->treewalk_parent)) {
- errors_corrected++;
+ if(query( _("Remove directory entry for bad"
+ " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
+ " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent,
+ di->treewalk_parent)) {
error = remove_dentry_from_dir(sbp, di->treewalk_parent,
i);
if(error < 0) {
@@ -809,10 +781,7 @@ int pass2(struct gfs2_sbd *sbp)
log_err(_("No '.' entry found for directory inode at "
"block %"PRIu64" (0x%" PRIx64 ")\n"), i, i);
- errors_found++;
- if (query(&opts,
- _("Is it okay to add '.' entry? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Is it okay to add '.' entry? (y/n) "))) {
sprintf(tmp_name, ".");
filename_len = strlen(tmp_name); /* no trailing
NULL */
@@ -849,10 +818,7 @@ int pass2(struct gfs2_sbd *sbp)
ip->i_di.di_entries, ds.entry_count,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- errors_found++;
- if (query(&opts,
- _("Fix the entry count? (y/n) "))) {
- errors_corrected++;
+ if (query( _("Fix the entry count? (y/n) "))) {
ip->i_di.di_entries = ds.entry_count;
bmodified(ip->i_bh);
} else {
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 64da3a9..910ecf3 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -131,12 +131,10 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
/* FIXME: add a dinode for this entry instead? */
- errors_found++;
- if(query(&opts, _("Remove directory entry for bad"
- " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
- " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode,
- di->treewalk_parent, di->treewalk_parent)) {
- errors_corrected++;
+ if(query( _("Remove directory entry for bad"
+ " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
+ " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode,
+ di->treewalk_parent, di->treewalk_parent)) {
error = remove_dentry_from_dir(sbp, di->treewalk_parent,
di->dinode);
if(error < 0) {
@@ -234,10 +232,8 @@ int pass3(struct gfs2_sbd *sbp)
}
if(q.block_type == gfs2_bad_block) {
log_err( _("Found unlinked directory containing bad block\n"));
- errors_found++;
- if(query(&opts,
+ if(query(
_("Clear unlinked directory with bad blocks? (y/n) "))) {
- errors_corrected++;
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
@@ -266,9 +262,7 @@ int pass3(struct gfs2_sbd *sbp)
* with eattrs */
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked directory has zero size.\n"));
- errors_found++;
- if(query(&opts, _("Remove zero-size unlinked directory? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Remove zero-size unlinked directory? (y/n) "))) {
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
@@ -278,9 +272,8 @@ int pass3(struct gfs2_sbd *sbp)
log_err( _("Zero-size unlinked directory remains\n"));
}
}
- errors_found++;
- if(query(&opts, _("Add unlinked directory to lost+found? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Add unlinked directory to "
+ "lost+found? (y/n) "))) {
if(add_inode_to_lf(ip)) {
fsck_inode_put(ip);
stack;
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index d7dd16d..0d590d5 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -81,10 +81,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
"bad blocks\n"),
(unsigned long long)ii->inode,
(unsigned long long)ii->inode);
- errors_found++;
- if(query(&opts,
- _("Delete unlinked inode with bad blocks? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Delete unlinked inode with bad "
+ "blocks? (y/n) "))) {
ip = fsck_load_inode(sbp, ii->inode);
check_inode_eattr(ip,
&pass4_fxns_delete);
@@ -108,8 +106,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
"not an inode (%d)\n"),
q.block_type);
ip = fsck_load_inode(sbp, ii->inode);
- if(query(&opts, _("Delete unlinked inode "
- "? (y/n) "))) {
+ if(query(_("Delete unlinked inode? (y/n) "))) {
check_inode_eattr(ip,
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
@@ -131,9 +128,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
* them. */
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked inode has zero size\n"));
- errors_found++;
- if(query(&opts, _("Clear zero-size unlinked inode? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Clear zero-size unlinked inode? (y/n) "))) {
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
fsck_inode_put(ip);
@@ -141,9 +136,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
}
}
- errors_found++;
- if(query(&opts, _("Add unlinked inode to lost+found? (y/n)"))) {
- errors_corrected++;
+ if(query( _("Add unlinked inode to lost+found? (y/n)"))) {
bmodified(ip->i_bh);
if(add_inode_to_lf(ip)) {
stack;
@@ -164,10 +157,9 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
ii->inode, ii->link_count, ii->counted_links);
/* Read in the inode, adjust the link count,
* and write it back out */
- errors_found++;
- if(query(&opts, _("Update link count for inode %"
- PRIu64 " (0x%" PRIx64 ") ? (y/n) "), ii->inode, ii->inode)) {
- errors_corrected++;
+ if(query( _("Update link count for inode %" PRIu64
+ " (0x%" PRIx64 ") ? (y/n) "),
+ ii->inode, ii->inode)) {
ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
fix_inode_count(sbp, ii, ip);
bmodified(ip->i_bh);
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index a65483f..f36eb7d 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -94,15 +94,14 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
So we ignore it. */
if (rg_status == GFS2_BLKST_UNLINKED &&
block_status == GFS2_BLKST_FREE) {
- errors_found++;
if (free_unlinked == -1) {
log_err( _("Unlinked inode block found at "
"block %llu (0x%llx).\n"),
(unsigned long long)block,
(unsigned long long)block);
- if(query(&opts, _("Do you want me to fix the "
- "bitmap for all unlinked "
- "blocks? (y/n) ")))
+ if(query( _("Do you want me to fix the "
+ "bitmap for all unlinked "
+ "blocks? (y/n) ")))
free_unlinked = 1;
else
free_unlinked = 0;
@@ -114,13 +113,11 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
"\n"),
(unsigned long long)block,
(unsigned long long)block);
- else {
+ else
log_err(_("Unlinked block %llu "
"(0x%llx) bitmap fixed.\n"),
(unsigned long long)block,
(unsigned long long)block);
- errors_corrected++;
- }
} else {
log_info( _("Unlinked block found at block %"
PRIu64" (0x%" PRIx64 "), left "
@@ -138,10 +135,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
log_err( _("Metadata type is %u (%s)\n"), q.block_type,
block_type_string(&q));
- errors_found++;
- if(query(&opts, _("Fix bitmap for block %"
- PRIu64" (0x%" PRIx64 ") ? (y/n) "), block, block)) {
- errors_corrected++;
+ if(query( _("Fix bitmap for block %" PRIu64
+ " (0x%" PRIx64 ") ? (y/n) "),
+ block, block)) {
if(gfs2_set_bitmap(sbp, block, block_status))
log_err( _("Failed.\n"));
else
@@ -204,9 +200,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
exit(FSCK_ERROR);
}
if(update) {
- errors_found++;
- if(query(&opts, _("Update resource group counts? (y/n) "))) {
- errors_corrected++;
+ if(query( _("Update resource group counts? (y/n) "))) {
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
gfs2_rgrp_out(rg, rgbh[0]->b_data);
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index e3aebda..06603b1 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -388,10 +388,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
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++;
+ if (query( _("Fix the RG? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
if (x) {
@@ -524,9 +521,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
PRIx32);
/* If we modified the index, write it back to disk. */
if (rindex_modified) {
- errors_found++;
- if (query(&opts, _("Fix the index? (y/n)"))) {
- errors_corrected++;
+ if (query( _("Fix the index? (y/n)"))) {
gfs2_rindex_out(&expected->ri, (char *)&buf);
gfs2_writei(sdp->md.riinode, (char *)&buf,
rg * sizeof(struct gfs2_rindex),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index e396b85..3d3707c 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include <linux_endian.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -117,6 +118,7 @@ void warm_fuzzy_stuff(uint64_t block)
if (last_fs_block) {
percent = (block * 100) / last_fs_block;
log_notice( _("\r%" PRIu64 " percent complete.\r"), percent);
+ fflush(stdout);
}
}
}
@@ -133,3 +135,63 @@ const char *block_type_string(struct gfs2_block_query *q)
return (blktyp[q->block_type]);
return blktyp[15];
}
+
+/* fsck_query: Same as gfs2_query except it adjusts errors_found and
+ errors_corrected. */
+int fsck_query(const char *format, ...)
+{
+ va_list args;
+ const char *transform;
+ char response;
+ int ret = 0;
+
+ errors_found++;
+ fsck_abort = 0;
+ if(opts.yes) {
+ errors_corrected++;
+ return 1;
+ }
+ if(opts.no)
+ return 0;
+
+ opts.query = TRUE;
+ while (1) {
+ va_start(args, format);
+ transform = _(format);
+ vprintf(transform, args);
+ va_end(args);
+
+ /* Make sure query is printed out */
+ fflush(NULL);
+ response = gfs2_getch();
+
+ printf("\n");
+ fflush(NULL);
+ if (response == 0x3) { /* if interrupted, by ctrl-c */
+ response = generic_interrupt("Question", "response",
+ NULL,
+ "Do you want to abort " \
+ "or continue (a/c)?",
+ "ac");
+ if (response == 'a') {
+ ret = 0;
+ fsck_abort = 1;
+ break;
+ }
+ printf("Continuing.\n");
+ } else if(tolower(response) == 'y') {
+ errors_corrected++;
+ ret = 1;
+ break;
+ } else if (tolower(response) == 'n') {
+ ret = 0;
+ break;
+ } else {
+ printf("Bad response %d, please type 'y' or 'n'.\n",
+ response);
+ }
+ }
+
+ opts.query = FALSE;
+ return ret;
+}
diff --git a/gfs2/libgfs2/gfs2_log.c b/gfs2/libgfs2/gfs2_log.c
index f9f61b2..fbb30e0 100644
--- a/gfs2/libgfs2/gfs2_log.c
+++ b/gfs2/libgfs2/gfs2_log.c
@@ -83,7 +83,7 @@ void print_fsck_log(int iif, int priority, const char *file, int line,
va_end(args);
}
-static char gfs2_getch(void)
+char gfs2_getch(void)
{
struct termios termattr, savetermattr;
char ch;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a5ef41c..16bd1db 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -616,10 +616,18 @@ do { print_log(1, MSG_ERROR, format); } while(0)
#define log_at_crit(format...) \
do { print_log(1, MSG_CRITICAL, format); } while(0)
-void increase_verbosity(void);
-void decrease_verbosity(void);
-void print_fsck_log(int iif, int priority, const char *file, int line,
- const char *format, ...);
+extern char gfs2_getch(void);
+extern void increase_verbosity(void);
+extern void decrease_verbosity(void);
+extern void print_fsck_log(int iif, int priority, const char *file, int line,
+ const char *format, ...)
+ __attribute__((format(printf,5,6)));
+extern char generic_interrupt(const char *caller, const char *where,
+ const char *progress, const char *question,
+ const char *answers);
+extern int gfs2_query(int *setonabort, struct gfs2_options *opts,
+ const char *format, ...)
+ __attribute__((format(printf,3,4)));
char generic_interrupt(const char *caller, const char *where,
const char *progress, const char *question,
14 years, 1 month
cluster: RHEL56 - fsck.gfs2: give comfort when processing lots of data blocks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: bf0822c4fd7bd701f36ddaef045fb8d587b47f96
Parent: 6c6638cd6055c03ef74351dc7a179c5a178b0b16
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Nov 30 16:03:10 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:00:33 2010 -0500
fsck.gfs2: give comfort when processing lots of data blocks
When fsck.gfs2 is running, it can seem to silently hang when it is
processing a large number of data blocks. This is noticeable when
files get over 20GB in size. This patch periodically prints
status messages when big files are being checked so customers
know it's still doing something valid.
rhbz#455300
---
gfs2/fsck/fsck.h | 1 +
gfs2/fsck/main.c | 1 +
gfs2/fsck/metawalk.c | 17 +++++++++++++++++
gfs2/fsck/util.c | 39 +++++++++++++++++++++++++++++++++++++++
gfs2/fsck/util.h | 1 +
5 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 6c8eed1..754b409 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -98,6 +98,7 @@ extern osi_list_t dir_hash[FSCK_HASH_SIZE];
extern osi_list_t inode_hash[FSCK_HASH_SIZE];
extern struct gfs2_bmap *bl;
extern uint64_t last_fs_block, last_reported_block;
+extern int64_t last_reported_fblock;
extern int skip_this_pass, fsck_abort;
extern int errors_found, errors_corrected;
extern uint64_t last_data_block;
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 756487f..6af2759 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -34,6 +34,7 @@ osi_list_t dir_hash[FSCK_HASH_SIZE];
osi_list_t inode_hash[FSCK_HASH_SIZE];
struct gfs2_bmap *bl = NULL;
uint64_t last_fs_block, last_reported_block = -1;
+int64_t last_reported_fblock = -1000000;
int skip_this_pass = FALSE, fsck_abort = FALSE;
int errors_found = 0, errors_corrected = 0;
const char *pass = "";
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 19e187e..00d5a4a 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -27,6 +27,8 @@
#include "metawalk.h"
#include "hash.h"
+#define COMFORTABLE_BLKS 5242880 /* 20GB in 4K blocks */
+
static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
uint64_t block)
{
@@ -945,6 +947,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
uint64_t block, *ptr;
uint32_t height = ip->i_di.di_height;
int i, head_size;
+ uint64_t blks_checked = 0;
int error = 0;
if (!height)
@@ -968,6 +971,8 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
/* check data blocks */
list = &metalist[height - 1];
+ if (ip->i_di.di_blocks > COMFORTABLE_BLKS)
+ last_reported_fblock = -10000000;
for (tmp = list->next; tmp != list; tmp = tmp->next) {
bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_altlist);
@@ -996,9 +1001,21 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
stack;
return -1;
}
+ blks_checked++;
+ if (ip->i_di.di_blocks > COMFORTABLE_BLKS)
+ big_file_comfort(ip, blks_checked);
}
}
+ if (ip->i_di.di_blocks > COMFORTABLE_BLKS) {
+ log_notice( _("\rLarge file at %lld (0x%llx) - 100 percent "
+ "complete. "
+ "\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ fflush(stdout);
+ }
+
/* free metalists */
for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
{
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index ac609cb..e396b85 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -19,6 +19,7 @@
#include <sys/time.h>
#include <stdio.h>
#include <libintl.h>
+#include <ctype.h>
#define _(String) gettext(String)
#include "libgfs2.h"
@@ -56,6 +57,44 @@ int compute_height(struct gfs2_sbd *sdp, uint64_t sz)
return height;
}
+void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked)
+{
+ static struct timeval tv;
+ static uint32_t seconds = 0;
+ static uint64_t percent, fsize, chksize;
+ uint64_t one_percent = 0;
+ int i, cs;
+ const char *human_abbrev = " KMGTPE";
+
+ one_percent = ip->i_di.di_blocks / 100;
+ if (blks_checked - last_reported_fblock < one_percent)
+ return;
+
+ last_reported_block = blks_checked;
+ gettimeofday(&tv, NULL);
+ if (!seconds)
+ seconds = tv.tv_sec;
+ if (tv.tv_sec == seconds)
+ return;
+
+ fsize = ip->i_di.di_size;
+ for (i = 0; i < 6 && fsize > 1024; i++)
+ fsize /= 1024;
+ chksize = blks_checked * ip->i_sbd->bsize;
+ for (cs = 0; cs < 6 && chksize > 1024; cs++)
+ chksize /= 1024;
+ seconds = tv.tv_sec;
+ percent = (blks_checked * 100) / ip->i_di.di_blocks;
+ log_notice( _("\rChecking %lld%c of %lld%c of file at %lld (0x%llx)"
+ "- %llu percent complete. \r"),
+ (long long)chksize, human_abbrev[cs],
+ (unsigned long long)fsize, human_abbrev[i],
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)percent);
+ fflush(stdout);
+}
+
/* Put out a warm, fuzzy message every second so the user */
/* doesn't think we hung. (This may take a long time). */
void warm_fuzzy_stuff(uint64_t block)
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index c112b60..ffbe975 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -21,6 +21,7 @@
int compute_height(struct gfs2_sbd *sdp, uint64_t sz);
struct di_info *search_list(osi_list_t *list, uint64_t addr);
+void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
void warm_fuzzy_stuff(uint64_t block);
const char *block_type_string(struct gfs2_block_query *q);
14 years, 1 month
cluster: RHEL56 - gfs2: remove update_flags everywhere
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 6c6638cd6055c03ef74351dc7a179c5a178b0b16
Parent: e7282c8a25ee830c068b3598814bc285d4398e24
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Nov 30 15:16:07 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:59:22 2010 -0500
gfs2: remove update_flags everywhere
This patch removes the update_flags from all the gfs2-utils code.
This help to untangle the buffer_head mess and helps solve
issues where file systems were being updated even when no errors
are found.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 207838b..f27b25f 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -676,7 +676,7 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
/* First, build up the metatree */
for (h = 0; h < blk->height; h++) {
lookup_block(ip, bh, h, &blk->mp, 1, &new, &block);
- brelse(bh, updated);
+ brelse(bh);
if (!block)
break;
@@ -693,7 +693,7 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
memcpy(bh->b_data + ptramt,
(char *)srcptr, amount);
srcptr += amount;
- brelse(bh, updated);
+ brelse(bh);
copied += amount;
@@ -825,7 +825,7 @@ int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *dibh,
memset(bh->b_data + sizeof(struct gfs_indirect), 0,
sbp->bsize - sizeof(struct gfs_indirect));
}
- brelse(bh, updated);
+ brelse(bh);
/* Free the block so we can reuse it. This allows us to
convert a "full" file system. */
ip->i_di.di_blocks--;
14 years, 1 month
cluster: RHEL56 - gfs2: remove update_flags everywhere
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: e7282c8a25ee830c068b3598814bc285d4398e24
Parent: e9316e5043402ba0cdc66fe70e90538fd88a4797
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Mon Nov 30 15:16:07 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:52:43 2010 -0500
gfs2: remove update_flags everywhere
This patch removes the update_flags from all the gfs2-utils code.
This help to untangle the buffer_head mess and helps solve
issues where file systems were being updated even when no errors
are found.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 47 ++++++++------
gfs2/edit/gfs2hex.c | 2 +-
gfs2/edit/hexedit.c | 47 +++++++------
gfs2/edit/savemeta.c | 18 +++---
gfs2/fsck/eattr.c | 10 +--
gfs2/fsck/eattr.h | 9 +--
gfs2/fsck/fs_recovery.c | 56 +++++++++-------
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/main.c | 24 +++----
gfs2/fsck/metawalk.c | 152 ++++++++++++++++---------------------------
gfs2/fsck/metawalk.h | 19 ++----
gfs2/fsck/pass1.c | 133 +++++++++++++++++--------------------
gfs2/fsck/pass1b.c | 37 ++++-------
gfs2/fsck/pass1c.c | 34 ++++------
gfs2/fsck/pass2.c | 95 ++++++++++++---------------
gfs2/fsck/pass3.c | 23 ++++---
gfs2/fsck/pass4.c | 25 ++++----
gfs2/fsck/pass5.c | 16 ++---
gfs2/fsck/rgrepair.c | 16 ++--
gfs2/libgfs2/buf.c | 127 ++++++++++++++++++++++++------------
gfs2/libgfs2/fs_bits.c | 8 +-
gfs2/libgfs2/fs_geometry.c | 3 +-
gfs2/libgfs2/fs_ops.c | 129 ++++++++++++++++++++++---------------
gfs2/libgfs2/gfs1.c | 11 +--
gfs2/libgfs2/libgfs2.h | 146 +++++++++++++++++++++--------------------
gfs2/libgfs2/recovery.c | 10 ++--
gfs2/libgfs2/rgrp.c | 7 +-
gfs2/libgfs2/structures.c | 47 +++++++++-----
gfs2/libgfs2/super.c | 10 +--
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 12 ++-
31 files changed, 644 insertions(+), 635 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 028913b..207838b 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -345,7 +345,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
/* First, build up the metatree */
for (h = 0; h < blk->height; h++) {
lookup_block(ip, bh, h, &blk->mp, 1, &new, &block);
- brelse(bh, updated);
+ brelse(bh);
if (!block)
break;
@@ -363,7 +363,8 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
memcpy(bh->b_data + hdrsize + ptramt,
(char *)srcptr, amount);
srcptr += amount;
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
copied += amount;
@@ -526,7 +527,8 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head
/* Zero the buffer so we can fill it in later */
memset(bh->b_data + sizeof(struct gfs_indirect), 0,
bufsize);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
/* Free the metadata block so we can reuse it.
This allows us to convert a "full" file system. */
ip->i_di.di_blocks--;
@@ -1067,12 +1069,13 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
break;
}
bitmap_byte -= (sbp->bsize - buf_offset);
+ bmodified(bh);
}
}
- brelse(bh, updated);
+ brelse(bh);
first = 0;
} /* while 1 */
- gfs2_rgrp_relse(rgd, updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
} /* for all rgs */
log_notice("\r%" PRIu64" inodes from %d rgs converted.",
@@ -1094,7 +1097,8 @@ static int fetch_inum(struct gfs2_sbd *sbp, uint64_t iblock,
fix_inode = inode_get(sbp, bh_fix);
inum->no_formal_ino = fix_inode->i_di.di_num.no_formal_ino;
inum->no_addr = fix_inode->i_di.di_num.no_addr;
- brelse(bh_fix, updated);
+ bmodified(bh_fix);
+ brelse(bh_fix);
return 0;
}/* fetch_inum */
@@ -1232,7 +1236,8 @@ static int fix_one_directory_exhash(struct gfs2_sbd *sbp, struct gfs2_inode *dip
}
gfs2_leaf_in(&leaf, (char *)bh_leaf->b_data); /* buffer to structure */
error = process_dirent_info(dip, sbp, bh_leaf, leaf.lf_entries);
- brelse(bh_leaf, updated);
+ bmodified(bh_leaf);
+ brelse(bh_leaf);
} /* for leaf_num */
return 0;
}/* fix_one_directory_exhash */
@@ -1275,18 +1280,21 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix)
if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
if (fix_one_directory_exhash(sbp, dip)) {
log_crit("Error fixing exhash directory.\n");
- brelse(bh_dir, updated);
+ bmodified(bh_dir);
+ brelse(bh_dir);
return -1;
}
}
else {
if (process_dirent_info(dip, sbp, bh_dir, dip->i_di.di_entries)) {
log_crit("Error fixing linear directory.\n");
- brelse(bh_dir, updated);
+ bmodified(bh_dir);
+ brelse(bh_dir);
return -1;
}
}
- brelse(bh_dir, updated);
+ bmodified(bh_dir);
+ brelse(bh_dir);
}
/* Free the last entry in memory: */
if (tmp) {
@@ -1411,7 +1419,7 @@ static int init(struct gfs2_sbd *sbp)
sbp->sd_diptrs = (sbp->bsize - sizeof(struct gfs_dinode)) /
sizeof(uint64_t);
sbp->sd_jbsize = sbp->bsize - sizeof(struct gfs2_meta_header);
- brelse(bh, not_updated);
+ brelse(bh);
sbp->sd_max_height = compute_heightsize(sbp, sbp->sd_heightsize,
sbp->bsize, sbp->sd_diptrs,
sbp->sd_inptrs);
@@ -1470,8 +1478,8 @@ static int init(struct gfs2_sbd *sbp)
}
printf("\n");
fflush(stdout);
- inode_put(sbp->md.riinode, updated);
- inode_put(sbp->md.jiinode, updated);
+ inode_put(sbp->md.riinode);
+ inode_put(sbp->md.jiinode);
log_debug("%d rgs found.\n", rgcount);
return 0;
}/* fill_super_block */
@@ -1783,7 +1791,7 @@ static void conv_build_jindex(struct gfs2_sbd *sdp)
ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
write_journal(sdp, ip, j,
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
- inode_put(ip, updated);
+ inode_put(ip);
printf("done.\n");
fflush(stdout);
}
@@ -1793,7 +1801,7 @@ static void conv_build_jindex(struct gfs2_sbd *sdp)
gfs2_dinode_print(&jindex->i_di);
}
- inode_put(jindex, updated);
+ inode_put(jindex);
}
/* ------------------------------------------------------------------------- */
@@ -1897,9 +1905,9 @@ int main(int argc, char **argv)
write_statfs_file(&sb2);
- inode_put(sb2.master_dir, updated);
- inode_put(sb2.md.inum, updated);
- inode_put(sb2.md.statfs, updated);
+ inode_put(sb2.master_dir);
+ inode_put(sb2.md.inum);
+ inode_put(sb2.md.statfs);
bcommit(&sb2.buf_list); /* write the buffers to disk */
@@ -1915,7 +1923,8 @@ int main(int argc, char **argv)
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->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
bsync(&sb2.buf_list); /* write the buffers to disk */
error = fsync(sb2.device_fd);
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 055e227..0cf36ef 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -324,7 +324,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
if (skip <= 0)
break;
}
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
indirect->ii[indirect_blocks].block = last;
indirect_blocks++;
last = p;
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index d6fb7fe..ef0bc50 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -799,7 +799,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);
+ inode_put(sbd.md.riinode);
gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
@@ -898,7 +898,7 @@ static uint64_t get_rg_addr(int rgnum)
else
fprintf(stderr, "Error: File system only has %lld RGs.\n",
(unsigned long long)riinode->i_di.di_size / risize());
- inode_put(riinode, not_updated);
+ inode_put(riinode);
return rgblk;
}
@@ -933,7 +933,8 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
gfs_rgrp_out(&rg.rg1, bh->b_data);
else
gfs2_rgrp_out(&rg.rg2, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
} else {
if (full) {
print_gfs2("RG #%d", rgnum);
@@ -948,7 +949,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
printf("RG #%d (block %llu / 0x%llx) rg_flags = 0x%08x\n",
rgnum, (unsigned long long)rgblk,
(unsigned long long)rgblk, rg.rg2.rg_flags);
- brelse(bh, not_updated);
+ brelse(bh);
}
if (modify)
bsync(&sbd.buf_list);
@@ -1013,7 +1014,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
gfs2_rgrp_in(&rg, tmp_bh->b_data);
gfs2_rgrp_print(&rg);
}
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
last_entry_onscreen[dmode] = print_entry_ndx;
}
@@ -1619,7 +1620,7 @@ int block_is_in_per_node(void)
gfs2_dinode_in(&per_node_di, per_node_bh->b_data);
do_dinode_extended(&per_node_di, per_node_bh->b_data);
- brelse(per_node_bh, not_updated);
+ brelse(per_node_bh);
for (d = 0; d < indirect->ii[0].dirents; d++) {
if (block == indirect->ii[0].dirent[d].block)
@@ -1657,7 +1658,7 @@ static int display_extended(void)
tmp_bh = bread(&sbd.buf_list, block);
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, TRUE);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
else if (has_indirect_blocks() && !indirect_blocks &&
!display_leaf(indirect))
@@ -1672,31 +1673,31 @@ static int display_extended(void)
tmp_bh = bread(&sbd.buf_list, masterblock("rindex"));
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, FALSE);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
else if (block_is_jindex()) {
tmp_bh = bread(&sbd.buf_list, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_jindex(tmp_inode);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
else if (block_is_inum_file()) {
tmp_bh = bread(&sbd.buf_list, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_inum(tmp_inode);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
else if (block_is_statfs_file()) {
tmp_bh = bread(&sbd.buf_list, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_statfs(tmp_inode);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
else if (block_is_quota_file()) {
tmp_bh = bread(&sbd.buf_list, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_quota(tmp_inode);
- brelse(tmp_bh, not_updated);
+ brelse(tmp_bh);
}
return 0;
}
@@ -1978,7 +1979,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
if (!gfs1)
do_dinode_extended(&di, jindex_bh->b_data); /* parse dir. */
- brelse(jindex_bh, not_updated);
+ brelse(jindex_bh);
if (gfs1) {
struct gfs2_inode *jiinode;
@@ -2001,7 +2002,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
j_inode = inode_get(&sbd, j_bh);
gfs2_dinode_in(&jdi, j_bh->b_data);/* parse dinode to struct */
*j_size = jdi.di_size;
- brelse(j_bh, not_updated);
+ brelse(j_bh);
}
return jblock;
}
@@ -2027,10 +2028,10 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
bh->b_data[4] == 0x00 && bh->b_data[5] == 0x00 &&
bh->b_data[6] == 0x00 && bh->b_data[7] == metatype) {
found = 1;
- brelse(bh, not_updated);
+ brelse(bh);
break;
}
- brelse(bh, not_updated);
+ brelse(bh);
}
if (!found)
blk = 0;
@@ -2447,7 +2448,7 @@ static void find_print_block_type(void)
bh = bread(&sbd.buf_list, tblock);
type = get_block_type(bh->b_data);
print_block_type(tblock, type, "");
- brelse(bh, NOT_UPDATED);
+ brelse(bh);
gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2605,7 +2606,9 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
" which is not implemented");
break;
}
- brelse(bh, newval ? UPDATED : NOT_UPDATED);
+ if (newval)
+ bmodified(bh);
+ brelse(bh);
bcommit(&sbd.buf_list);
}
@@ -2985,7 +2988,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
amount = sdp->bsize - o;
if (!extlen)
block_map(ip, lblock, ¬_new, &dblock, &extlen,
- FALSE, not_updated);
+ FALSE);
if (dblock) {
bh = bread(&sdp->buf_list, dblock);
if (*abs_block == 0)
@@ -2996,7 +2999,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
bh = NULL;
if (bh) {
memcpy(rbuf, bh->b_data + o, amount);
- brelse(bh, not_updated);
+ brelse(bh);
} else {
memset(rbuf, 0, amount);
}
@@ -3052,7 +3055,7 @@ static void dump_journal(const char *journal)
for (jb = 0; jb < j_size; jb += (gfs1 ? 1:sbd.bsize)) {
if (gfs1) {
if (j_bh)
- brelse(j_bh, not_updated);
+ brelse(j_bh);
j_bh = bread(&sbd.buf_list, jblock + jb);
abs_block = jblock + jb;
memcpy(jbuf, j_bh->b_data, sbd.bsize);
@@ -3143,7 +3146,7 @@ static void dump_journal(const char *journal)
start_line);
}
}
- brelse(j_bh, not_updated);
+ brelse(j_bh);
blockhist = -1; /* So we don't print anything else */
}
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 50c9e2a..51ea37a 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -285,13 +285,13 @@ static void save_indirect_blocks(int out_fd, osi_list_t *cur_list,
if (blktype == GFS2_METATYPE_EA) {
nbh = bread(&sbd.buf_list, indir_block);
save_ea_block(out_fd, nbh);
- brelse(nbh, not_updated);
+ brelse(nbh);
}
if (height != hgt) { /* If not at max height */
nbh = bread(&sbd.buf_list, indir_block);
osi_list_add_prev(&nbh->b_altlist,
cur_list);
- brelse(nbh, not_updated);
+ brelse(nbh);
}
} /* for all data on the indirect block */
}
@@ -394,9 +394,9 @@ static void save_inode_data(int out_fd)
(unsigned long long)block,
(unsigned long long)block);
}
- brelse(metabh, not_updated);
+ brelse(metabh);
}
- inode_put(inode, not_updated);
+ inode_put(inode);
}
static void get_journal_inode_blocks(void)
@@ -430,7 +430,7 @@ static void get_journal_inode_blocks(void)
amt = gfs2_readi(j_inode, (void *)&jbuf,
journal * sizeof(struct gfs_jindex),
sizeof(struct gfs_jindex));
- brelse(bh, not_updated);
+ brelse(bh);
if (!amt)
break;
gfs_jindex_in(&ji, jbuf);
@@ -443,7 +443,7 @@ static void get_journal_inode_blocks(void)
bh = bread(&sbd.buf_list, jblock);
j_inode = inode_get(&sbd, bh);
gfs2_dinode_in(&jdi, bh->b_data);
- inode_put(j_inode, not_updated);
+ inode_put(j_inode);
}
journal_blocks[journals_found++] = jblock;
}
@@ -475,7 +475,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
blk = gfs2_bitfit((unsigned char *)bh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_UNLINKED);
- brelse(bh, not_updated);
+ brelse(bh);
if(blk != BFITNOENT){
*nrfblock = blk + (bits->bi_start * GFS2_NBBY) +
rgd->ri.ri_data0;
@@ -575,7 +575,7 @@ void savemeta(char *out_fn, int saveoption)
gfs2_dinode_in(&di, bh->b_data);
if (!gfs1)
do_dinode_extended(&di, bh->b_data);
- brelse(bh, not_updated);
+ brelse(bh);
}
if (!slow) {
printf("Reading resource groups...");
@@ -672,7 +672,7 @@ void savemeta(char *out_fn, int saveoption)
first = 0;
}
}
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
}
}
diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index 675a2fc..af9d474 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -40,17 +40,15 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block)
int clear_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
- *want_updated = not_updated;
return clear_blk_nodup(ip->i_sbd, block);
}
int clear_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
- *want_updated = not_updated;
return clear_blk_nodup(ip->i_sbd, block);
}
@@ -102,12 +100,10 @@ int clear_eattr_entry (struct gfs2_inode *ip,
int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated, void *private)
+ struct gfs2_ea_header *ea_hdr_prev, void *private)
{
uint64_t block = be64_to_cpu(*ea_data_ptr);
- *want_updated = not_updated;
return clear_blk_nodup(ip->i_sbd, block);
}
diff --git a/gfs2/fsck/eattr.h b/gfs2/fsck/eattr.h
index 674ee27..fac8240 100644
--- a/gfs2/fsck/eattr.h
+++ b/gfs2/fsck/eattr.h
@@ -14,11 +14,9 @@
#define _EATTR_H
int clear_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ struct gfs2_buffer_head **bh, void *private);
int clear_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ struct gfs2_buffer_head **bh, void *private);
int clear_eattr_entry (struct gfs2_inode *ip,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
@@ -27,7 +25,6 @@ int clear_eattr_entry (struct gfs2_inode *ip,
int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated, void *private);
+ struct gfs2_ea_header *ea_hdr_prev, void *private);
#endif /* _EATTR_H */
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 3225c26..46a1084 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -114,7 +114,6 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
struct gfs2_buffer_head *bh_log, *bh_ip;
uint64_t blkno;
int error = 0;
- enum update_flags if_modified;
if (pass != 1 || be32_to_cpu(ld->ld_type) != GFS2_LOG_DESC_METADATA)
return 0;
@@ -140,14 +139,13 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
check_magic = ((struct gfs2_meta_header *)
(bh_ip->b_data))->mh_magic;
check_magic = be32_to_cpu(check_magic);
- if (check_magic != GFS2_MAGIC) {
- if_modified = not_updated;
+ if (check_magic != GFS2_MAGIC)
error = -EIO;
- } else
- if_modified = updated;
+ else
+ bmodified(bh_ip);
- brelse(bh_log, not_updated);
- brelse(bh_ip, if_modified);
+ brelse(bh_log);
+ brelse(bh_ip);
if (error)
break;
@@ -196,7 +194,8 @@ static int revoke_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
offset += sizeof(uint64_t);
}
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
offset = sizeof(struct gfs2_meta_header);
first = 0;
}
@@ -240,8 +239,9 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
*eptr = cpu_to_be32(GFS2_MAGIC);
}
- brelse(bh_log, not_updated);
- brelse(bh_ip, updated);
+ brelse(bh_log);
+ bmodified(bh_ip);
+ brelse(bh_ip);
sd_replayed_jblocks++;
}
@@ -282,7 +282,8 @@ static int foreach_descriptor(struct gfs2_inode *ip, unsigned int start,
(bh->b_data))->mh_magic;
check_magic = be32_to_cpu(check_magic);
if (check_magic != GFS2_MAGIC) {
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return -EIO;
}
ld = (struct gfs2_log_descriptor *)bh->b_data;
@@ -294,38 +295,45 @@ static int foreach_descriptor(struct gfs2_inode *ip, unsigned int start,
error = get_log_header(ip, start, &lh);
if (!error) {
gfs2_replay_incr_blk(ip, &start);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
continue;
}
if (error == 1)
error = -EIO;
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return error;
} else if (gfs2_check_meta(bh, GFS2_METATYPE_LD)) {
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return -EIO;
}
ptr = (__be64 *)(bh->b_data + offset);
error = databuf_lo_scan_elements(ip, start, ld, ptr, pass);
if (error) {
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return error;
}
error = buf_lo_scan_elements(ip, start, ld, ptr, pass);
if (error) {
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return error;
}
error = revoke_lo_scan_elements(ip, start, ld, ptr, pass);
if (error) {
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return error;
}
while (length--)
gfs2_replay_incr_blk(ip, &start);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
return 0;
@@ -376,10 +384,11 @@ static int fix_journal_seq_no(struct gfs2_inode *ip)
lh.lh_sequence = highest_seq;
prev_seq = lh.lh_sequence;
log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence);
- block_map(ip, blk, &new, &dblock, &extlen, FALSE, not_updated);
+ block_map(ip, blk, &new, &dblock, &extlen, FALSE);
bh = bread(&ip->i_sbd->buf_list, dblock);
gfs2_log_header_out(&lh, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
return 0;
}
@@ -582,11 +591,10 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
*clean_journals += clean;
}
- inode_put(sdp->md.journal[i],
- (opts.no ? not_updated : updated));
+ inode_put(sdp->md.journal[i]);
}
- inode_put(sdp->master_dir, not_updated);
- inode_put(sdp->md.jiinode, not_updated);
+ 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);
return error;
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 497be3a..6c8eed1 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -74,7 +74,7 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
-void fsck_inode_put(struct gfs2_inode *ip, enum update_flags update);
+void fsck_inode_put(struct gfs2_inode *ip);
int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
int *all_clean);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 9da8dd2..756487f 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -313,7 +313,7 @@ void check_statfs(struct gfs2_sbd *sdp)
sdp->blks_total += ri->ri_data;
sdp->blks_alloced += (ri->ri_data - rg.rg_free);
sdp->dinodes_alloced += rg.rg_dinodes;
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
}
@@ -358,7 +358,6 @@ int main(int argc, char **argv)
struct gfs2_sbd sb;
struct gfs2_sbd *sbp = &sb;
int j;
- enum update_flags update_sys_files;
int error = 0;
int all_clean = 0;
@@ -477,23 +476,22 @@ int main(int argc, char **argv)
} else {
error = FSCK_CANCELED;
}
- update_sys_files = (opts.no ? not_updated : updated);
check_statfs(sbp);
/* Free up our system inodes */
- inode_put(sbp->md.inum, update_sys_files);
- inode_put(sbp->md.statfs, update_sys_files);
+ inode_put(sbp->md.inum);
+ inode_put(sbp->md.statfs);
for (j = 0; j < sbp->md.journals; j++)
- inode_put(sbp->md.journal[j], update_sys_files);
- inode_put(sbp->md.jiinode, update_sys_files);
- inode_put(sbp->md.riinode, update_sys_files);
- inode_put(sbp->md.qinode, update_sys_files);
- inode_put(sbp->md.pinode, update_sys_files);
- inode_put(sbp->md.rooti, update_sys_files);
- inode_put(sbp->master_dir, update_sys_files);
+ inode_put(sbp->md.journal[j]);
+ inode_put(sbp->md.jiinode);
+ inode_put(sbp->md.riinode);
+ inode_put(sbp->md.qinode);
+ inode_put(sbp->md.pinode);
+ inode_put(sbp->md.rooti);
+ inode_put(sbp->master_dir);
if (lf_dip)
- inode_put(lf_dip, update_sys_files);
+ inode_put(lf_dip);
if (!opts.no && errors_corrected)
log_notice( _("Writing changes to disk\n"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 38e1c00..19e187e 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -92,17 +92,17 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
/* fsck_inode_put - same as inode_put() in libgfs2 but system inodes
get special treatment. */
-void fsck_inode_put(struct gfs2_inode *ip, enum update_flags update)
+void fsck_inode_put(struct gfs2_inode *ip)
{
struct gfs2_inode *sysip;
sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr);
if (sysip) {
- if (update)
+ if (ip->i_bh->b_changed)
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
- brelse(ip->i_bh, update);
+ brelse(ip->i_bh);
} else {
- inode_put(ip, update);
+ inode_put(ip);
}
}
@@ -172,6 +172,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb,
old_rec_len = de.de_rec_len;
de.de_rec_len = bh_end - (char *)fixb;
gfs2_dirent_out(&de, (char *)fixb);
+ bmodified(bh);
}
/*
@@ -180,7 +181,6 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb,
* @ip - dinode associated with this leaf block
* bh - buffer for the leaf block
* type - type of block this is (linear or exhash)
- * @update - set to 1 if the block was updated
* @count - set to the count entries
* @pass - structure pointing to pass-specific functions
*
@@ -188,8 +188,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb,
* -1 - error occurred
*/
static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
- int type, enum update_flags *update,
- uint16_t *count, struct metawalk_fxns *pass)
+ int type, uint16_t *count, struct metawalk_fxns *pass)
{
struct gfs2_leaf *leaf = NULL;
struct gfs2_dirent *dent;
@@ -245,7 +244,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
dirblk_truncate(ip, dent, bh);
else
dirblk_truncate(ip, prev, bh);
- *update = updated;
log_err( _("Unable to repair corrupt "
"directory entry; the "
"entry was removed "
@@ -255,7 +253,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
log_err( _("Corrupt directory entry "
"repaired.\n"));
errors_corrected++;
- *update = updated;
+ bmodified(bh);
/* keep looping through dentries */
}
} else {
@@ -280,7 +278,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
if (query(&opts,
_("Attempt to remove it? (y/n) "))) {
dirblk_truncate(ip, prev, bh);
- *update = 1;
log_err(_("The corrupt directory "
"entry was removed.\n"));
} else {
@@ -298,14 +295,13 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
de.de_inum.no_addr = de.de_inum.no_formal_ino;
de.de_inum.no_formal_ino = 0;
gfs2_dirent_out(&de, (char *)dent);
- *update = (opts.no ? not_updated : updated);
+ bmodified(bh);
/* Mark dirent buffer as modified */
first = 0;
}
else {
error = pass->check_dentry(ip, dent, prev, bh,
- filename, update,
- count,
+ filename, count,
pass->private);
if(error < 0) {
stack;
@@ -365,8 +361,7 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
}
/* Checks exhash directory entries */
-static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
- struct metawalk_fxns *pass)
+static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
int error;
struct gfs2_leaf leaf, oldleaf;
@@ -390,10 +385,10 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
lbh = bread(&sbp->buf_list, first_ok_leaf);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
- brelse(lbh, not_updated);
+ brelse(lbh);
break;
}
- brelse(lbh, not_updated);
+ brelse(lbh);
}
}
old_leaf = -1;
@@ -441,7 +436,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
gfs2_leaf_in(&oldleaf, lbh->b_data);
oldleaf.lf_depth = ip->i_di.di_depth - factor;
gfs2_leaf_out(&oldleaf, lbh->b_data);
- brelse(lbh, updated);
+ bmodified(lbh);
+ brelse(lbh);
}
else
return 1;
@@ -469,7 +465,6 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
break;
}
- *update = not_updated;
/* Try to read in the leaf block. */
lbh = bread(&sbp->buf_list, leaf_no);
/* Make sure it's really a valid leaf block. */
@@ -478,7 +473,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
old_leaf, first_ok_leaf, lindex,
_("that is not really a leaf"));
memcpy(&leaf, &oldleaf, sizeof(oldleaf));
- brelse(lbh, not_updated);
+ bmodified(lbh);
+ brelse(lbh);
break;
}
gfs2_leaf_in(&leaf, lbh->b_data);
@@ -499,7 +495,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
leaf.lf_dirent_format = GFS2_FORMAT_DE;
gfs2_leaf_out(&leaf, lbh->b_data);
log_debug( _("Fixing lf_dirent_format.\n"));
- *update = (opts.no ? not_updated : updated);
+ bmodified(lbh);
}
/* Make sure it's really a leaf. */
@@ -513,7 +509,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
ip->i_di.di_num.no_addr,
(unsigned long long)leaf_no,
(unsigned long long)leaf_no);
- brelse(lbh, *update);
+ brelse(lbh);
break;
}
exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth));
@@ -523,22 +519,20 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
if(pass->check_dentry &&
S_ISDIR(ip->i_di.di_mode)) {
error = check_entries(ip, lbh, DIR_EXHASH,
- update, &count, pass);
+ &count, pass);
/* Since the buffer possibly got
* updated directly, release it now,
* and grab it again later if we need it. */
- brelse(lbh, *update);
+ brelse(lbh);
if(error < 0) {
stack;
return -1;
}
- if(update && (count != leaf.lf_entries)) {
- enum update_flags f = not_updated;
-
+ if(count != leaf.lf_entries) {
lbh = bread(&sbp->buf_list, leaf_no);
gfs2_leaf_in(&leaf, lbh->b_data);
@@ -560,16 +554,16 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
leaf.lf_entries = count;
gfs2_leaf_out(&leaf, lbh->b_data);
log_warn( _("Leaf entry count updated\n"));
- f = updated;
+ bmodified(lbh);
} else
log_err( _("Leaf entry count left in inconsistant state\n"));
- brelse(lbh, f);
+ brelse(lbh);
}
/* FIXME: Need to get entry count and
* compare it against leaf->lf_entries */
break; /* not a chain; go back to outer loop */
} else {
- brelse(lbh, *update);
+ brelse(lbh);
if(!leaf.lf_next)
break;
leaf_no = leaf.lf_next;
@@ -584,8 +578,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, enum update_flags *update,
static int check_eattr_entries(struct gfs2_inode *ip,
struct gfs2_buffer_head *bh,
- struct metawalk_fxns *pass,
- enum update_flags *update_it)
+ struct metawalk_fxns *pass)
{
struct gfs2_ea_header *ea_hdr, *ea_hdr_prev = NULL;
uint64_t *ea_data_ptr = NULL;
@@ -593,7 +586,6 @@ static int check_eattr_entries(struct gfs2_inode *ip,
int error = 0;
uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header);
- *update_it = 0;
if(!pass->check_eattr_entry) {
return 0;
}
@@ -612,8 +604,6 @@ static int check_eattr_entries(struct gfs2_inode *ip,
stack;
return -1;
}
- if (error > 0)
- *update_it = updated;
if(error == 0 && pass->check_eattr_extentry &&
ea_hdr->ea_num_ptrs) {
uint32_t tot_ealen = 0;
@@ -635,7 +625,6 @@ static int check_eattr_entries(struct gfs2_inode *ip,
ea_data_ptr,
bh, ea_hdr,
ea_hdr_prev,
- update_it,
pass->private)) {
errors_found++;
if (query(&opts, _("Repair the bad "
@@ -646,7 +635,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
ea_hdr->ea_data_len =
cpu_to_be32(tot_ealen);
*ea_data_ptr = 0;
- *update_it = 1;
+ bmodified(bh);
/* Endianness doesn't matter
in this case because it's
a single byte. */
@@ -688,38 +677,29 @@ static int check_eattr_entries(struct gfs2_inode *ip,
* Returns: 0 on success, 1 if removal is needed, -1 on error
*/
static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
- uint64_t parent, enum update_flags *want_updated,
- struct metawalk_fxns *pass)
+ uint64_t parent, struct metawalk_fxns *pass)
{
struct gfs2_buffer_head *bh = NULL;
int error = 0;
- enum update_flags updated_this_leaf = not_updated;
log_debug( _("Checking EA leaf block #%"PRIu64" (0x%" PRIx64 ").\n"),
block, block);
if(pass->check_eattr_leaf) {
error = pass->check_eattr_leaf(ip, block, parent, &bh,
- &updated_this_leaf,
pass->private);
- if (updated_this_leaf) /* if this leaf was updated */
- *want_updated = updated; /* signal it for the parent */
if(error < 0) {
stack;
return -1;
}
if(error > 0) {
if (bh)
- brelse(bh, updated_this_leaf);
+ brelse(bh);
return 1;
}
if (bh) {
- error = check_eattr_entries(ip, bh, pass,
- &updated_this_leaf);
- brelse(bh, updated_this_leaf);
- if (updated_this_leaf) /* if this leaf was updated */
- *want_updated = updated; /* signal it for
- the parent */
+ error = check_eattr_entries(ip, bh, pass);
+ brelse(bh);
}
return error;
}
@@ -735,7 +715,6 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
* Returns: 0 on success -1 on error
*/
static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
- enum update_flags *want_updated,
struct metawalk_fxns *pass)
{
int error = 0;
@@ -743,19 +722,16 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
uint64_t block;
struct gfs2_buffer_head *indirect_buf = NULL;
struct gfs2_sbd *sdp = ip->i_sbd;
- enum update_flags update_indir_block = not_updated;
int first_ea_is_bad = 0;
uint64_t di_eattr_save = ip->i_di.di_eattr;
- *want_updated = not_updated;
log_debug( _("Checking EA indirect block #%"PRIu64" (0x%" PRIx64 ").\n"),
indirect, indirect);
if (!pass->check_eattr_indir)
return 0;
error = pass->check_eattr_indir(ip, indirect, ip->i_di.di_num.no_addr,
- &indirect_buf, want_updated,
- pass->private);
+ &indirect_buf, pass->private);
if (!error) {
int leaf_pointers = 0, leaf_pointer_errors = 0;
@@ -767,20 +743,16 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
while(*ea_leaf_ptr && (ea_leaf_ptr < end)){
block = be64_to_cpu(*ea_leaf_ptr);
leaf_pointers++;
- error = check_leaf_eattr(ip, block, indirect,
- want_updated, pass);
+ error = check_leaf_eattr(ip, block, indirect, pass);
if (error) {
leaf_pointer_errors++;
- if (update_indir_block == not_updated) {
- errors_found++;
- if (query(&opts, _("Fix the indirect "
- "block too? (y/n) "))) {
- update_indir_block = updated;
- errors_corrected++;
- *ea_leaf_ptr = 0;
- }
- } else
+ errors_found++;
+ if (query(&opts, _("Fix the indirect "
+ "block too? (y/n) "))) {
+ bmodified(indirect_buf);
+ errors_corrected++;
*ea_leaf_ptr = 0;
+ }
}
/* If the first eattr lead is bad, we can't have
a hole, so we have to treat this as an unrecoverable
@@ -796,7 +768,6 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
pass->finish_eattr_indir(ip,
leaf_pointers,
leaf_pointer_errors,
- want_updated,
pass->private);
} else if (leaf_pointer_errors) {
/* This is a bit tricky. We can't have eattr
@@ -819,11 +790,10 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
ip->i_di.di_eattr = di_eattr_save;
pass->finish_eattr_indir(ip, leaf_pointers,
leaf_pointer_errors,
- want_updated,
pass->private);
}
if (leaf_pointer_errors == leaf_pointers) {
- if (*want_updated)
+ if (indirect_buf->b_changed)
gfs2_set_bitmap(sdp, indirect,
GFS2_BLKST_FREE);
gfs2_block_set(sdp, bl, indirect,
@@ -833,7 +803,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
}
}
if (indirect_buf)
- brelse(indirect_buf, update_indir_block);
+ brelse(indirect_buf);
return error;
}
@@ -844,8 +814,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
*
* Returns: 0 on success, -1 on error
*/
-int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated,
- struct metawalk_fxns *pass)
+int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
int error = 0;
@@ -858,12 +827,11 @@ int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated,
if(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT){
if((error = check_indirect_eattr(ip, ip->i_di.di_eattr,
- want_updated, pass)))
+ pass)))
stack;
} else {
error = check_leaf_eattr(ip, ip->i_di.di_eattr,
- ip->i_di.di_num.no_addr,
- want_updated, pass);
+ ip->i_di.di_num.no_addr, pass);
if (error)
stack;
}
@@ -954,12 +922,12 @@ fail:
while (!osi_list_empty(list)) {
nbh = osi_list_entry(list->next,
struct gfs2_buffer_head, b_altlist);
- brelse(nbh, not_updated);
+ brelse(nbh);
osi_list_del(&nbh->b_altlist);
}
}
/* This is an error path, so we need to release the buffer here: */
- brelse(metabh, not_updated);
+ brelse(metabh);
return -1;
}
@@ -977,7 +945,6 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
uint64_t block, *ptr;
uint32_t height = ip->i_di.di_height;
int i, head_size;
- enum update_flags update = not_updated;
int error = 0;
if (!height)
@@ -1040,7 +1007,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
bh = osi_list_entry(list->next,
struct gfs2_buffer_head, b_altlist);
- brelse(bh, not_updated);
+ brelse(bh);
osi_list_del(&bh->b_altlist);
}
}
@@ -1049,7 +1016,7 @@ end:
if (S_ISDIR(ip->i_di.di_mode)) {
/* check validity of leaf blocks and leaf chains */
if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
- error = check_leaf_blks(ip, &update, pass);
+ error = check_leaf_blks(ip, pass);
if(error < 0)
return -1;
if(error > 0)
@@ -1062,12 +1029,12 @@ end:
/* Checks stuffed inode directories */
static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
- enum update_flags *update, struct metawalk_fxns *pass)
+ struct metawalk_fxns *pass)
{
int error = 0;
uint16_t count = 0;
- error = check_entries(ip, bh, DIR_LINEAR, update, &count, pass);
+ error = check_entries(ip, bh, DIR_LINEAR, &count, pass);
if(error < 0) {
stack;
return -1;
@@ -1081,38 +1048,36 @@ int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass)
{
struct gfs2_buffer_head *bh;
struct gfs2_inode *ip;
- enum update_flags update = not_updated;
int error = 0;
bh = bread(&sbp->buf_list, block);
ip = fsck_inode_get(sbp, bh);
if(ip->i_di.di_flags & GFS2_DIF_EXHASH) {
- error = check_leaf_blks(ip, &update, pass);
+ error = check_leaf_blks(ip, pass);
if(error < 0) {
stack;
- fsck_inode_put(ip, not_updated); /* does brelse(bh); */
+ fsck_inode_put(ip); /* does brelse(bh); */
return -1;
}
}
else {
- error = check_linear_dir(ip, bh, &update, pass);
+ error = check_linear_dir(ip, bh, pass);
if(error < 0) {
stack;
- fsck_inode_put(ip, not_updated); /* does brelse(bh); */
+ fsck_inode_put(ip); /* does brelse(bh); */
return -1;
}
}
- fsck_inode_put(ip, opts.no ? not_updated : update); /* does a brelse */
+ fsck_inode_put(ip); /* does a brelse */
return error;
}
static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
struct gfs2_dirent *prev_de,
struct gfs2_buffer_head *bh,
- char *filename, enum update_flags *update,
- uint16_t *count, void *private)
+ char *filename, uint16_t *count, void *private)
{
/* the metawalk_fxn's private field must be set to the dentry
* block we want to clear */
@@ -1122,7 +1087,6 @@ static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
memset(&dentry, 0, sizeof(struct gfs2_dirent));
gfs2_dirent_in(&dentry, (char *)dent);
de = &dentry;
- *update = (opts.no ? not_updated : updated);
if(de->de_inum.no_addr == *dentryblock)
dirent2_del(ip, bh, prev_de, dent);
@@ -1275,16 +1239,14 @@ int delete_data(struct gfs2_inode *ip, uint64_t block, void *private)
}
int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ struct gfs2_buffer_head **bh, void *private)
{
return delete_blocks(ip, block, NULL, _("indirect extended attribute"),
private);
}
int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ struct gfs2_buffer_head **bh, void *private)
{
return delete_blocks(ip, block, NULL, _("extended attribute"),
private);
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 6568bba..2b83229 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -18,8 +18,7 @@
struct metawalk_fxns;
-int check_inode_eattr(struct gfs2_inode *ip, enum update_flags *want_updated,
- struct metawalk_fxns *pass);
+int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass);
int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass);
int check_dir(struct gfs2_sbd *sbp, uint64_t block,
struct metawalk_fxns *pass);
@@ -35,11 +34,9 @@ int delete_metadata(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, void *private);
int delete_data(struct gfs2_inode *ip, uint64_t block, void *private);
int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ struct gfs2_buffer_head **bh, void *private);
int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ struct gfs2_buffer_head **bh, void *private);
/* metawalk_fxns: function pointers to check various parts of the fs
*
@@ -66,18 +63,14 @@ struct metawalk_fxns {
void *private);
int (*check_eattr_indir) (struct gfs2_inode *ip, uint64_t block,
uint64_t parent,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated,
- void *private);
+ struct gfs2_buffer_head **bh, void *private);
int (*check_eattr_leaf) (struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated,
void *private);
int (*check_dentry) (struct gfs2_inode *ip, struct gfs2_dirent *de,
struct gfs2_dirent *prev,
struct gfs2_buffer_head *bh,
- char *filename, enum update_flags *update,
- uint16_t *count, void *private);
+ char *filename, uint16_t *count, void *private);
int (*check_eattr_entry) (struct gfs2_inode *ip,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
@@ -88,11 +81,9 @@ struct metawalk_fxns {
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated,
void *private);
int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors,
- enum update_flags *want_updated,
void *private);
};
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 80f253f..3b73048 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -52,10 +52,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
static int check_data(struct gfs2_inode *ip, uint64_t block, void *private);
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ void *private);
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private);
+ void *private);
static int check_eattr_entries(struct gfs2_inode *ip,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
@@ -65,11 +65,9 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated,
void *private);
static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
- int leaf_pointer_errors,
- enum update_flags *want_updated, void *private);
+ int leaf_pointer_errors, void *private);
struct metawalk_fxns pass1_fxns = {
.private = NULL,
@@ -130,10 +128,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
"something that is not an indirect block).\n"));
if(!found_dup) {
gfs2_block_set(ip->i_sbd, bl, block, gfs2_meta_inval);
- brelse(nbh, not_updated);
+ brelse(nbh);
return 1;
}
- brelse(nbh, not_updated);
+ brelse(nbh);
} else /* blk check ok */
*bh = nbh;
@@ -238,7 +236,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
}
static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc,
- int duplicate, enum update_flags *want_updated)
+ int duplicate)
{
if (!duplicate) {
gfs2_set_bitmap(ip->i_sbd, ip->i_di.di_eattr,
@@ -250,13 +248,12 @@ static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc,
bc->ea_count = 0;
ip->i_di.di_blocks = 1 + bc->indir_count + bc->data_count;
ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT;
- *want_updated = updated;
+ bmodified(ip->i_bh);
return 0;
}
static int ask_remove_inode_eattr(struct gfs2_inode *ip,
- struct block_count *bc,
- enum update_flags *want_updated)
+ struct block_count *bc)
{
log_err( _("Inode %lld (0x%llx) has unrecoverable Extended Attribute "
"errors.\n"), (unsigned long long)ip->i_di.di_num.no_addr,
@@ -271,7 +268,7 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
stack;
return -1;
}
- if (!remove_inode_eattr(ip, bc, q.dup_block, want_updated))
+ if (!remove_inode_eattr(ip, bc, q.dup_block))
log_err( _("Extended attributes were removed.\n"));
else
log_err( _("Unable to remove inode eattr pointer; "
@@ -292,12 +289,10 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
* Returns: 1 if the EA is fixed, else 0 if it was not fixed.
*/
static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
- uint64_t block, int duplicate,
- enum update_flags *want_updated, const char *emsg)
+ uint64_t block, int duplicate, const char *emsg)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- *want_updated = not_updated;
log_err( _("Inode #%llu (0x%llx): %s"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr, emsg);
@@ -307,7 +302,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
if (query(&opts, _("Clear the bad Extended Attribute? (y/n) "))) {
errors_corrected++;
if (block == ip->i_di.di_eattr) {
- remove_inode_eattr(ip, bc, duplicate, want_updated);
+ remove_inode_eattr(ip, bc, duplicate);
log_err( _("The bad extended attribute was "
"removed.\n"));
} else if (!duplicate) {
@@ -316,7 +311,6 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
log_err( _("The bad Extended Attribute was "
"removed.\n"));
}
- *want_updated = updated;
return 1;
} else {
log_err( _("The bad Extended Attribute was not fixed.\n"));
@@ -327,7 +321,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
struct gfs2_sbd *sdp = ip->i_sbd;
int ret = 0;
@@ -356,7 +350,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
*bh = bread(&sdp->buf_list, indirect);
if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
- if (!clear_eas(ip, bc, indirect, 1, want_updated,
+ if (!clear_eas(ip, bc, indirect, 1,
_("Bad indirect Extended Attribute "
"duplicate found"))) {
gfs2_block_mark(sdp, bl, indirect,
@@ -365,7 +359,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
}
return 1;
}
- clear_eas(ip, bc, indirect, 0, want_updated,
+ clear_eas(ip, bc, indirect, 0,
_("Extended Attribute indirect block has incorrect "
"type"));
return 1;
@@ -392,13 +386,12 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
}
static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
- int leaf_pointer_errors,
- enum update_flags *want_updated, void *private)
+ int leaf_pointer_errors, void *private)
{
struct block_count *bc = (struct block_count *) private;
if (leaf_pointer_errors == leaf_pointers) /* All eas were bad */
- return ask_remove_inode_eattr(ip, bc, want_updated);
+ return ask_remove_inode_eattr(ip, bc);
log_debug( _("Marking inode #%llu (0x%llx) with extended "
"attribute block\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -418,7 +411,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
errors_corrected++;
ip->i_di.di_blocks = 1 + bc->indir_count +
bc->data_count + bc->ea_count;
- *want_updated = updated;
+ bmodified(ip->i_bh);
log_err( _("Block count fixed.\n"));
return 1;
}
@@ -427,8 +420,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
}
static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
- struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ struct gfs2_buffer_head **bh, void *private)
{
struct gfs2_buffer_head *leaf_bh = NULL;
struct gfs2_sbd *sdp = ip->i_sbd;
@@ -445,14 +437,15 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
leaf_bh = bread(&sdp->buf_list, block);
if(gfs2_check_meta(leaf_bh, btype)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
- clear_eas(ip, bc, block, 1, want_updated,
+ clear_eas(ip, bc, block, 1,
_("Bad Extended Attribute duplicate found"));
} else {
- clear_eas(ip, bc, block, 0, want_updated,
+ clear_eas(ip, bc, block, 0,
_("Extended Attribute leaf block "
"has incorrect type"));
}
- brelse(leaf_bh, *want_updated);
+ bmodified(leaf_bh);
+ brelse(leaf_bh);
return 1;
}
if(q.block_type != gfs2_block_free) { /* Duplicate? */
@@ -461,17 +454,18 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
(unsigned long long)block);
gfs2_block_mark(sdp, bl, block, gfs2_dup_block);
bc->ea_count++;
- brelse(leaf_bh, not_updated);
+ brelse(leaf_bh);
return 1;
}
if (ip->i_di.di_eattr == 0) {
/* Can only get in here if there were unrecoverable ea
errors that caused clear_eas to be called. What we
need to do here is remove the subsequent ea blocks. */
- clear_eas(ip, bc, block, 0, want_updated,
+ clear_eas(ip, bc, block, 0,
_("Extended Attribute block removed due to "
"previous errors.\n"));
- brelse(leaf_bh, *want_updated);
+ bmodified(leaf_bh);
+ brelse(leaf_bh);
return 1;
}
log_debug( _("Setting block #%lld (0x%llx) to eattr block\n"),
@@ -500,7 +494,6 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated,
void *private)
{
uint64_t el_blk = be64_to_cpu(*data_ptr);
@@ -521,16 +514,15 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
- error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh,
- want_updated, private);
+ error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
if (bh)
- brelse(bh, not_updated);
+ brelse(bh);
return error;
}
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
struct gfs2_sbd *sdp = ip->i_sbd;
@@ -553,8 +545,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
- return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, want_updated,
- private);
+ return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
}
static int check_eattr_entries(struct gfs2_inode *ip,
@@ -694,9 +685,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
int error;
struct block_count bc = {0};
struct metawalk_fxns invalidate_metatree = {0};
- enum update_flags f;
- f = not_updated;
invalidate_metatree.check_metalist = clear_metalist;
invalidate_metatree.check_data = clear_data;
invalidate_metatree.check_leaf = clear_leaf;
@@ -715,7 +704,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
errors_corrected++;
ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
- f = updated;
+ bmodified(ip->i_bh);
} else
log_err( _("Address in inode at block #%" PRIu64
" (0x%" PRIx64 ") not fixed\n"), block, block);
@@ -723,7 +712,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
if(gfs2_block_check(sdp, bl, block, &q)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
if(q.block_type != gfs2_block_free) {
@@ -731,10 +720,10 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
"#%" PRIu64 " (0x%" PRIx64 ")\n"), block, block);
if(gfs2_block_mark(sdp, bl, block, gfs2_dup_block)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
@@ -745,12 +734,12 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_dir)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
if(add_to_dir_list(sdp, block)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -759,7 +748,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_file)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -768,7 +757,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_lnk)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -777,7 +766,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_blk)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -786,7 +775,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_chr)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -795,7 +784,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_fifo)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -804,7 +793,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_inode_sock)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
break;
@@ -813,16 +802,16 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
block, block);
if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
if(set_link_count(ip->i_sbd, ip->i_di.di_num.no_addr, ip->i_di.di_nlink)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
@@ -837,11 +826,11 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
log_warn( _("Marking inode invalid\n"));
if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
@@ -858,11 +847,11 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
log_warn( _("Marking inode invalid\n"));
if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
}
@@ -871,7 +860,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
error = check_metatree(ip, &pass1_fxns);
if (fsck_abort || error < 0) {
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
if(error > 0) {
@@ -883,15 +872,15 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
gfs2_block_set(sdp, bl, ip->i_di.di_num.no_addr,
gfs2_meta_inval);
gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE);
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
- error = check_inode_eattr(ip, &f, &pass1_fxns);
+ error = check_inode_eattr(ip, &pass1_fxns);
- if (error && f == updated &&
+ if (error &&
!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
- ask_remove_inode_eattr(ip, &bc, &f);
+ ask_remove_inode_eattr(ip, &bc);
if (ip->i_di.di_blocks !=
(1 + bc.indir_count + bc.data_count + bc.ea_count)) {
@@ -913,8 +902,8 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
errors_corrected++;
ip->i_di.di_blocks = 1 + bc.indir_count + bc.data_count +
bc.ea_count;
+ bmodified(ip->i_bh);
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
- f = updated;
} else
log_err( _("Bad block count for #%llu (0x%llx"
") not fixed\n"),
@@ -922,7 +911,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(unsigned long long)ip->i_di.di_num.no_addr);
}
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
return 0;
}
@@ -1055,7 +1044,7 @@ int pass1(struct gfs2_sbd *sbp)
break;
warm_fuzzy_stuff(block);
if (fsck_abort) { /* if asked to abort */
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
return FSCK_OK;
}
@@ -1068,15 +1057,15 @@ int pass1(struct gfs2_sbd *sbp)
if (scan_meta(sbp, bh, block)) {
stack;
- brelse(bh, not_updated);
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ brelse(bh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
return FSCK_ERROR;
}
- brelse(bh, not_updated);
+ brelse(bh);
first = 0;
}
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
}
return FSCK_OK;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 5e75ae3..6eb40f5 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -74,12 +74,11 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
struct gfs2_buffer_head *indir_bh = NULL;
- *want_updated = not_updated;
inc_if_found(block, 0, private);
indir_bh = bread(&sbp->buf_list, block);
*bh = indir_bh;
@@ -89,12 +88,11 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
struct gfs2_buffer_head *leaf_bh = NULL;
- *want_updated = not_updated;
inc_if_found(block, 0, private);
leaf_bh = bread(&sbp->buf_list, block);
@@ -115,11 +113,10 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated, void *private)
+ void *private)
{
uint64_t block = be64_to_cpu(*ea_data_ptr);
- *want_updated = not_updated;
inc_if_found(block, 0, private);
return 0;
@@ -128,7 +125,7 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
struct gfs2_dirent *prev,
struct gfs2_buffer_head *bh, char *filename,
- enum update_flags *update, uint16_t *count, void *priv)
+ uint16_t *count, void *priv)
{
osi_list_t *tmp1, *tmp2;
struct dup_blocks *b;
@@ -205,14 +202,12 @@ static int clear_dup_data(struct gfs2_inode *ip, uint64_t block, void *private)
static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated,
void *private)
{
struct dup_handler *dh = (struct dup_handler *) private;
/* Can't use fxns from eattr.c since we need to check the ref
* count */
*bh = NULL;
- *want_updated = not_updated;
if(dh->ref_count == 1)
return 1;
if(block == dh->b->block_no) {
@@ -235,11 +230,10 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
struct dup_handler *dh = (struct dup_handler *) private;
- *want_updated = not_updated;
if(dh->ref_count == 1)
return 1;
if(block == dh->b->block_no) {
@@ -307,13 +301,11 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated,
void *private)
{
uint64_t block = be64_to_cpu(*ea_data_ptr);
struct dup_handler *dh = (struct dup_handler *) private;
- *want_updated = not_updated;
if(dh->ref_count == 1)
return 1;
if(block == dh->b->block_no) {
@@ -352,7 +344,6 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block
.check_eattr_entry = check_eattr_entry,
.check_eattr_extentry = check_eattr_extentry,
};
- enum update_flags update;
ip = fsck_load_inode(sbp, inode); /* bread, inode_get */
log_debug( _("Checking inode %" PRIu64 " (0x%" PRIx64 ")'s "
@@ -360,14 +351,14 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block
")\n"), inode, inode, b->block_no, b->block_no);
if(check_metatree(ip, &find_refs)) {
stack;
- fsck_inode_put(ip, not_updated); /* out, brelse, free */
+ fsck_inode_put(ip); /* out, brelse, free */
return -1;
}
log_debug( _("Done checking metatree\n"));
/* Check for ea references in the inode */
- if(check_inode_eattr(ip, &update, &find_refs) < 0){
+ if(check_inode_eattr(ip, &find_refs) < 0){
stack;
- fsck_inode_put(ip, not_updated); /* out, brelse, free */
+ fsck_inode_put(ip); /* out, brelse, free */
return -1;
}
if (myfi.found) {
@@ -387,7 +378,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block
id->ea_only = myfi.ea_only;
osi_list_add_prev(&id->list, &b->ref_inode_list);
}
- fsck_inode_put(ip, (opts.no ? not_updated : updated)); /* out, brelse, free */
+ fsck_inode_put(ip); /* out, brelse, free */
return 0;
}
@@ -408,7 +399,6 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
};
struct gfs2_inode *ip;
struct dup_handler dh = {0};
- enum update_flags update;
osi_list_foreach(tmp, &b->ref_inode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
@@ -429,7 +419,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
bh = bread(&sbp->buf_list, b->block_no);
cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
- brelse(bh, not_updated);
+ brelse(bh);
if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
tmp = b->ref_inode_list.next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
@@ -454,7 +444,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
gfs2_block_set(ip->i_sbd, bl,
ip->i_di.di_num.no_addr,
gfs2_meta_inval);
- fsck_inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ fsck_inode_put(ip);
} else {
log_warn( _("The bad inode was not cleared."));
}
@@ -496,14 +487,14 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
dh.id = id;
clear_dup_fxns.private = (void *) &dh;
/* Clear the EAs for the inode first */
- check_inode_eattr(ip, &update, &clear_dup_fxns);
+ check_inode_eattr(ip, &clear_dup_fxns);
/* If the dup wasn't only in the EA, clear the inode */
if(!id->ea_only)
check_metatree(ip, &clear_dup_fxns);
gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
gfs2_meta_inval);
- fsck_inode_put(ip, updated); /* out, brelse, free */
+ fsck_inode_put(ip); /* out, brelse, free */
dh.ref_inode_count--;
if(dh.ref_inode_count == 1)
break;
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index c1cc623..4cf2c44 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -40,6 +40,7 @@ static int remove_eattr_entry(struct gfs2_sbd *sdp,
log_err( _("Bad Extended Attribute at block #%"PRIu64
" (0x%" PRIx64 ") removed.\n"),
leaf_bh->b_blocknr, leaf_bh->b_blocknr);
+ bmodified(leaf_bh);
return 0;
}
@@ -71,14 +72,13 @@ static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
return 1;
}
-static int ask_remove_eattr(struct gfs2_inode *ip,
- enum update_flags *need_update)
+static int ask_remove_eattr(struct gfs2_inode *ip)
{
errors_found++;
if (query(&opts, _("Remove the bad Extended Attribute? (y/n) "))) {
errors_corrected++;
ip->i_di.di_eattr = 0;
- *need_update = updated;
+ bmodified(ip->i_bh);
log_err( _("Bad Extended Attribute removed.\n"));
} else
log_err( _("Bad Extended Attribute not removed.\n"));
@@ -87,13 +87,12 @@ static int ask_remove_eattr(struct gfs2_inode *ip,
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *need_update, void *private)
+ void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
struct gfs2_block_query q;
struct gfs2_buffer_head *indir_bh = NULL;
- *need_update = not_updated;
if(gfs2_check_range(sbp, block)) {
log_err( _("Extended attributes indirect block #%llu"
" (0x%llx) for inode #%llu"
@@ -102,7 +101,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- return ask_remove_eattr(ip, need_update);
+ return ask_remove_eattr(ip);
}
else if (gfs2_block_check(sbp, bl, block, &q)) {
stack;
@@ -116,7 +115,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- return ask_remove_eattr(ip, need_update);
+ return ask_remove_eattr(ip);
}
else
indir_bh = bread(&sbp->buf_list, block);
@@ -127,7 +126,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *need_update, void *private)
+ void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
struct gfs2_block_query q;
@@ -137,7 +136,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
" (0x%llx) out of range.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- return ask_remove_eattr(ip, need_update);
+ return ask_remove_eattr(ip);
}
else if (gfs2_block_check(sbp, bl, block, &q)) {
stack;
@@ -148,7 +147,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
" (0x%llx) invalid.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- return ask_remove_eattr(ip, need_update);
+ return ask_remove_eattr(ip);
}
else
*bh = bread(&sbp->buf_list, block);
@@ -226,8 +225,7 @@ static int check_eattr_entry(struct gfs2_inode *ip,
static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
struct gfs2_buffer_head *leaf_bh,
struct gfs2_ea_header *ea_hdr,
- struct gfs2_ea_header *ea_hdr_prev,
- enum update_flags *want_updated, void *private)
+ struct gfs2_ea_header *ea_hdr_prev, void *private)
{
struct gfs2_block_query q;
struct gfs2_sbd *sbp = ip->i_sbd;
@@ -257,7 +255,6 @@ int pass1c(struct gfs2_sbd *sbp)
int error = 0;
osi_list_t *tmp, *x;
struct special_blocks *ea_block;
- enum update_flags want_updated = not_updated;
pass1c_fxns.check_eattr_indir = &check_eattr_indir;
pass1c_fxns.check_eattr_leaf = &check_eattr_leaf;
@@ -284,18 +281,15 @@ int pass1c(struct gfs2_sbd *sbp)
(unsigned long long)ip->i_di.di_eattr,
(unsigned long long)ip->i_di.di_eattr);
/* FIXME: Handle walking the eattr here */
- error = check_inode_eattr(ip, &want_updated,
- &pass1c_fxns);
+ error = check_inode_eattr(ip, &pass1c_fxns);
if(error < 0) {
stack;
- brelse(bh, not_updated);
+ brelse(bh);
return FSCK_ERROR;
}
-
- fsck_inode_put(ip, want_updated); /* dinode_out,
- brelse, free */
+ fsck_inode_put(ip); /* dinode_out, brelse, free */
} else {
- brelse(bh, want_updated);
+ brelse(bh);
}
}
return FSCK_OK;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 05e73b9..1827c67 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -89,18 +89,16 @@ static int set_dotdot_dir(struct gfs2_sbd *sbp, uint64_t childblock,
}
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
- uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ uint64_t parent, struct gfs2_buffer_head **bh,
+ void *private)
{
- *want_updated = not_updated;
*bh = bread(&ip->i_sbd->buf_list, block);
return 0;
}
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
- enum update_flags *want_updated, void *private)
+ void *private)
{
- *want_updated = not_updated;
*bh = bread(&ip->i_sbd->buf_list, block);
return 0;
}
@@ -168,7 +166,7 @@ struct metawalk_fxns pass2_fxns_delete = {
static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
struct gfs2_dirent *prev_de,
struct gfs2_buffer_head *bh, char *filename,
- enum update_flags *update, uint16_t *count, void *priv)
+ uint16_t *count, void *priv)
{
struct gfs2_sbd *sbp = ip->i_sbd;
struct gfs2_block_query q = {0};
@@ -245,7 +243,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
errors_corrected++;
log_err( _("Clearing %s\n"), tmp_name);
dirent2_del(ip, bh, prev_de, dent);
- *update = updated;
+ bmodified(bh);
return 1;
} else {
log_err( _("Directory entry to out of range block remains\n"));
@@ -269,14 +267,14 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(query(&opts, _("Delete inode containing bad blocks? (y/n)"))) {
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &pass2_fxns_delete);
+ check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
- fsck_inode_put(entry_ip, updated);
+ bmodified(entry_ip->i_bh);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
gfs2_block_set(sbp, bl, de->de_inum.no_addr,
gfs2_block_free);
- *update = updated;
+ bmodified(bh);
log_warn( _("The inode containing bad blocks was "
"deleted.\n"));
return 1;
@@ -310,7 +308,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
errors_corrected++;
dirent2_del(ip, bh, prev_de, dent);
- *update = updated;
+ bmodified(bh);
log_warn( _("Directory entry '%s' cleared\n"), tmp_name);
/* If it was previously marked invalid (i.e. known
to be bad, not just a free block, etc.) then
@@ -321,15 +319,16 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* Now try to clear the dinode, if it is an dinode */
bhi = bread(&sbp->buf_list, de->de_inum.no_addr);
error = gfs2_check_meta(bhi, GFS2_METATYPE_DI);
- brelse(bhi, updated);
+ bmodified(bhi);
+ brelse(bhi);
if (error)
return 1; /* not a dinode: nothing to delete */
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &pass2_fxns_delete);
+ check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
- fsck_inode_put(entry_ip, updated);
+ bmodified(entry_ip->i_bh);
+ fsck_inode_put(entry_ip);
gfs2_block_set(sbp, bl, de->de_inum.no_addr,
gfs2_block_free);
@@ -358,11 +357,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(query(&opts, _("Clear stale directory entry? (y/n) "))) {
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update, &clear_eattrs);
- fsck_inode_put(entry_ip, not_updated);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- *update = updated;
+ bmodified(bh);
log_err( _("Stale directory entry deleted\n"));
return 1;
} else {
@@ -386,12 +385,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &clear_eattrs);
- fsck_inode_put(entry_ip, not_updated);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- *update = updated;
+ bmodified(bh);
return 1;
} else {
log_err( _("Duplicate '.' entry remains\n"));
@@ -424,12 +422,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(query(&opts, _("Remove '.' reference? (y/n) "))) {
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &clear_eattrs);
- fsck_inode_put(entry_ip, not_updated);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- *update = updated;
+ bmodified(bh);
return 1;
} else {
@@ -462,12 +459,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &clear_eattrs);
- fsck_inode_put(entry_ip, not_updated);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- *update = 1;
+ bmodified(bh);
return 1;
} else {
log_err( _("Duplicate '..' entry remains\n"));
@@ -490,12 +486,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(query(&opts, _("Clear bad '..' directory entry? (y/n) "))) {
errors_corrected++;
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
- check_inode_eattr(entry_ip, update,
- &clear_eattrs);
- fsck_inode_put(entry_ip, not_updated);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ fsck_inode_put(entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- *update = 1;
+ bmodified(bh);
return 1;
} else {
log_err( _("Bad '..' directory entry remains\n"));
@@ -518,7 +513,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
ds->dotdotdir = 1;
increment_link(sbp, de->de_inum.no_addr);
- *update = (opts.no ? not_updated : updated);
(*count)++;
ds->entry_count++;
return 0;
@@ -529,7 +523,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
if(q.block_type != gfs2_inode_dir) {
log_debug( _("Found non-dir inode dentry\n"));
increment_link(sbp, de->de_inum.no_addr);
- *update = (opts.no ? not_updated : updated);
(*count)++;
ds->entry_count++;
return 0;
@@ -544,8 +537,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
errors_found++;
if(query(&opts, _("Clear hard link to directory? (y/n) "))) {
errors_corrected++;
- *update = 1;
-
+ bmodified(bh);
dirent2_del(ip, bh, prev_de, dent);
log_warn( _("Directory entry %s cleared\n"), filename);
@@ -562,7 +554,6 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return -1;
}
increment_link(sbp, de->de_inum.no_addr);
- *update = (opts.no ? not_updated : updated);
(*count)++;
ds->entry_count++;
/* End of checks */
@@ -592,7 +583,6 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
char *filename;
int filename_len;
char tmp_name[256];
- enum update_flags update = not_updated;
int error = 0;
log_info( _("Checking system directory inode '%s'\n"), dirname);
@@ -620,7 +610,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval);
bh = bhold(sysinode->i_bh);
- if(check_inode_eattr(sysinode, &update, &pass2_fxns)) {
+ if(check_inode_eattr(sysinode, &pass2_fxns)) {
stack;
return -1;
}
@@ -650,7 +640,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
sysinode->i_di.di_num.no_addr);
ds.entry_count++;
free(filename);
- update = 1;
+ bmodified(sysinode->i_bh);
} else
log_err( _("The directory was not fixed.\n"));
}
@@ -667,8 +657,8 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
(unsigned long long)sysinode->i_di.di_num.no_addr)) {
errors_corrected++;
sysinode->i_di.di_entries = ds.entry_count;
+ bmodified(sysinode->i_bh);
log_warn( _("Entries updated\n"));
- update = 1;
} else {
log_err( _("Entries for inode %llu (0x%llx"
") left out of sync\n"),
@@ -679,7 +669,9 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
}
}
- brelse(bh, opts.no ? not_updated : update);
+ if (!opts.no)
+ bmodified(bh);
+ brelse(bh);
return 0;
}
@@ -718,7 +710,6 @@ int pass2(struct gfs2_sbd *sbp)
int filename_len;
char tmp_name[256];
int error = 0;
- enum update_flags need_update = NOT_UPDATED;
struct dup_blocks *b;
/* Check all the system directory inodes. */
@@ -741,7 +732,6 @@ int pass2(struct gfs2_sbd *sbp)
log_info( _("Checking directory inodes.\n"));
/* Grab each directory inode, and run checks on it */
for(i = 0; i < last_fs_block; i++) {
- need_update = 0;
warm_fuzzy_stuff(i);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return FSCK_OK;
@@ -769,11 +759,11 @@ int pass2(struct gfs2_sbd *sbp)
* is valid */
ip = fsck_load_inode(sbp, i);
if(check_metatree(ip, &pass2_fxns)) {
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
stack;
return FSCK_ERROR;
}
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
}
error = check_dir(sbp, i, &pass2_fxns);
if(error < 0) {
@@ -847,7 +837,7 @@ int pass2(struct gfs2_sbd *sbp)
ds.entry_count++;
free(filename);
log_err( _("The directory was fixed.\n"));
- need_update = UPDATED;
+ bmodified(ip->i_bh);
} else {
log_err( _("The directory was not fixed.\n"));
}
@@ -864,13 +854,12 @@ int pass2(struct gfs2_sbd *sbp)
_("Fix the entry count? (y/n) "))) {
errors_corrected++;
ip->i_di.di_entries = ds.entry_count;
- need_update = UPDATED;
+ bmodified(ip->i_bh);
} else {
log_err( _("The entry count was not fixed.\n"));
}
}
- fsck_inode_put(ip, need_update); /* does a gfs2_dinode_out,
- brelse */
+ fsck_inode_put(ip); /* does a gfs2_dinode_out, brelse */
}
/* Now that we've deleted the inodes marked "bad" we can safely
get rid of the duplicate block list. If we do it any sooner,
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index bb71e47..64da3a9 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -45,15 +45,15 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
filename_len = strlen("..");
if(!(filename = malloc((sizeof(char) * filename_len) + 1))) {
log_err( _("Unable to allocate name\n"));
- fsck_inode_put(ip, not_updated);
- fsck_inode_put(pip, not_updated);
+ fsck_inode_put(ip);
+ fsck_inode_put(pip);
stack;
return -1;
}
if(!memset(filename, 0, (sizeof(char) * filename_len) + 1)) {
log_err( _("Unable to zero name\n"));
- fsck_inode_put(ip, not_updated);
- fsck_inode_put(pip, not_updated);
+ fsck_inode_put(ip);
+ fsck_inode_put(pip);
stack;
return -1;
}
@@ -64,8 +64,10 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
decrement_link(sbp, olddotdot);
dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
increment_link(sbp, newdotdot);
- fsck_inode_put(ip, updated);
- fsck_inode_put(pip, updated);
+ bmodified(ip->i_bh);
+ fsck_inode_put(ip);
+ bmodified(pip->i_bh);
+ fsck_inode_put(pip);
return 0;
}
@@ -270,7 +272,7 @@ int pass3(struct gfs2_sbd *sbp)
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
break;
} else {
log_err( _("Zero-size unlinked directory remains\n"));
@@ -280,15 +282,16 @@ int pass3(struct gfs2_sbd *sbp)
if(query(&opts, _("Add unlinked directory to lost+found? (y/n) "))) {
errors_corrected++;
if(add_inode_to_lf(ip)) {
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
stack;
return FSCK_ERROR;
}
log_warn( _("Directory relinked to lost+found\n"));
- fsck_inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ fsck_inode_put(ip);
} else {
log_err( _("Unlinked directory remains unlinked\n"));
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
}
break;
}
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index b5ea674..d7dd16d 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -42,6 +42,7 @@ static int fix_inode_count(struct gfs2_sbd *sbp, struct inode_info *ii,
if(ip->i_di.di_nlink == ii->counted_links)
return 0;
ip->i_di.di_nlink = ii->counted_links;
+ bmodified(ip->i_bh);
log_debug( _("Changing inode %llu (0x%llx) to have %u links\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -56,14 +57,12 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
struct gfs2_inode *ip;
int lf_addition = 0;
struct gfs2_block_query q;
- enum update_flags f;
/* FIXME: should probably factor this out into a generic
* scanning fxn */
osi_list_foreach(tmp, list) {
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
- f = not_updated;
if(!(ii = osi_list_entry(tmp, struct inode_info, list))) {
log_crit( _("osi_list_foreach broken in scan_info_list!!\n"));
exit(FSCK_ERROR);
@@ -87,10 +86,11 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
_("Delete unlinked inode with bad blocks? (y/n) "))) {
errors_corrected++;
ip = fsck_load_inode(sbp, ii->inode);
- check_inode_eattr(ip, &f,
+ check_inode_eattr(ip,
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
- fsck_inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ fsck_inode_put(ip);
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
continue;
@@ -110,17 +110,17 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
ip = fsck_load_inode(sbp, ii->inode);
if(query(&opts, _("Delete unlinked inode "
"? (y/n) "))) {
- check_inode_eattr(ip, &f,
+ check_inode_eattr(ip,
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
- fsck_inode_put(ip, updated);
+ bmodified(ip->i_bh);
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
log_err( _("The inode was deleted\n"));
} else {
log_err( _("The inode was not "
"deleted\n"));
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
}
continue;
}
@@ -136,7 +136,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
errors_corrected++;
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
continue;
}
@@ -144,10 +144,10 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
errors_found++;
if(query(&opts, _("Add unlinked inode to lost+found? (y/n)"))) {
errors_corrected++;
- f = updated;
+ bmodified(ip->i_bh);
if(add_inode_to_lf(ip)) {
stack;
- fsck_inode_put(ip, not_updated);
+ fsck_inode_put(ip);
return -1;
}
else {
@@ -156,7 +156,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
}
} else
log_err( _("Unlinked inode left unlinked\n"));
- fsck_inode_put(ip, f);
+ fsck_inode_put(ip);
} /* if(ii->counted_links == 0) */
else if(ii->link_count != ii->counted_links) {
log_err( _("Link count inconsistent for inode %" PRIu64
@@ -170,7 +170,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
errors_corrected++;
ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
fix_inode_count(sbp, ii, ip);
- fsck_inode_put(ip, updated); /* out, brelse, free */
+ bmodified(ip->i_bh);
+ fsck_inode_put(ip); /* out, brelse, free */
log_warn( _("Link count updated for inode %"
PRIu64 " (0x%" PRIx64 ") \n"), ii->inode, ii->inode);
} else {
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 6e16235..a65483f 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -161,9 +161,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
return 0;
}
-static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
- uint32_t *count, struct gfs2_buffer_head **rgbh,
- struct gfs2_rgrp *rg)
+static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
+ uint32_t *count, struct gfs2_buffer_head **rgbh,
+ struct gfs2_rgrp *rg)
{
uint32_t i;
struct gfs2_bitmap *bits;
@@ -177,7 +177,7 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
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;
+ return;
}
/* actually adjust counters and write out to disk */
@@ -210,11 +210,9 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
gfs2_rgrp_out(rg, rgbh[0]->b_data);
- return updated;
} else
log_err( _("Resource group counts left inconsistent\n"));
}
- return not_updated;
}
/**
@@ -234,8 +232,6 @@ int pass5(struct gfs2_sbd *sbp)
/* Reconcile RG bitmaps with fsck bitmap */
for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){
- enum update_flags f;
-
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return FSCK_OK;
log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
@@ -258,8 +254,8 @@ int pass5(struct gfs2_sbd *sbp)
}
rg_count++;
/* Compare the bitmaps and report the differences */
- f = update_rgrp(sbp, rgd, count, rgbh, &rg);
- gfs2_rgrp_relse(rgd, f, rgbh);
+ update_rgrp(sbp, rgd, count, rgbh, &rg);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
}
/* Fix up superblock info based on this - don't think there's
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index cc5b2ca..e3aebda 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -64,8 +64,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp)
ip = sdp->md.journal[j];
jblocks = ip->i_di.di_size / sdp->sd_sb.sb_bsize;
for (b = 0; b < jblocks; b++) {
- block_map(ip, b, &new, &dblock, &extlen, 0,
- not_updated);
+ block_map(ip, b, &new, &dblock, &extlen, 0);
if (!dblock)
break;
bh = bread(&sdp->buf_list, dblock);
@@ -74,7 +73,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp)
"0x%" PRIx64 "\n"), dblock);
gfs2_special_set(&false_rgrps, dblock);
}
- brelse(bh, not_updated);
+ brelse(bh);
}
}
}
@@ -176,7 +175,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
number_of_rgs++;
blk += 250; /* skip ahead for performance */
}
- brelse(bh, not_updated);
+ brelse(bh);
}
number_of_rgs = 0;
gfs2_special_free(&false_rgrps);
@@ -222,7 +221,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
log_debug( _("Block 0x%" PRIx64 "\n"), blk);
bh = bread(&sdp->buf_list, blk);
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
- brelse(bh, not_updated);
+ brelse(bh);
/* Allocate a new RG and index. */
calc_rgd = malloc(sizeof(struct rgrp_list));
if (!calc_rgd) {
@@ -257,7 +256,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
bh = bread(&sdp->buf_list, fwd_block);
bitmap_was_fnd =
(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
- brelse(bh, not_updated);
+ brelse(bh);
if (bitmap_was_fnd) /* if a bitmap */
calc_rgd->ri.ri_length++;
else
@@ -410,7 +409,8 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
rg->rg_free = rgd->ri.ri_data;
gfs2_rgrp_out(rg, rgbh[x]->b_data);
}
- brelse(rgbh[x], updated);
+ bmodified(rgbh[x]);
+ brelse(rgbh[x]);
return 0;
}
return 1;
@@ -590,7 +590,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
&rgrp);
}
else {
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
break;
}
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 48b1f5c..65136f2 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -32,7 +32,7 @@ blkno2head(struct buf_list *bl, uint64_t blkno)
(gfs2_disk_hash((char *)&blkno, sizeof(uint64_t)) & BUF_HASH_MASK);
}
-static void write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
+static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
{
struct gfs2_sbd *sdp = bl->sbp;
@@ -40,8 +40,14 @@ static void write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
osi_list_del(&bh->b_hash);
bl->num_bufs--;
if (bh->b_changed) {
- do_lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize);
- do_write(sdp->device_fd, bh->b_data, sdp->bsize);
+ 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;
@@ -49,6 +55,7 @@ static void write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
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)
@@ -113,8 +120,9 @@ struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num)
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 buf_list *bl, uint64_t num,
+ int find_existing, int read_disk,
+ int line, const char *caller)
{
struct gfs2_buffer_head *bh;
struct gfs2_sbd *sdp = bl->sbp;
@@ -130,8 +138,21 @@ struct gfs2_buffer_head *bget_generic(struct buf_list *bl, uint64_t num,
bh->b_blocknr = num;
bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head);
if (read_disk) {
- do_lseek(sdp->device_fd, num * sdp->bsize);
- do_read(sdp->device_fd, bh->b_data, sdp->bsize);
+ if (lseek(sdp->device_fd, num * sdp->bsize, SEEK_SET) !=
+ num * sdp->bsize) {
+ fprintf(stderr, "bad seek: %s from %s:%d: block "
+ "%llu (0x%llx)\n", strerror(errno),
+ caller, line, (unsigned long long)num,
+ (unsigned long long)num);
+ exit(-1);
+ }
+ if (read(sdp->device_fd, bh->b_data, sdp->bsize) < 0) {
+ fprintf(stderr, "bad read: %s from %s:%d: block "
+ "%llu (0x%llx)\n", strerror(errno),
+ caller, line, (unsigned long long)num,
+ (unsigned long long)num);
+ exit(-1);
+ }
}
add_buffer(bl, bh);
bh->b_changed = FALSE;
@@ -139,19 +160,16 @@ struct gfs2_buffer_head *bget_generic(struct buf_list *bl, uint64_t num,
return bh;
}
-struct gfs2_buffer_head *bget(struct buf_list *bl, uint64_t num)
-{
- return bget_generic(bl, num, TRUE, FALSE);
-}
-
-struct gfs2_buffer_head *bread(struct buf_list *bl, uint64_t num)
+struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, int line,
+ const char *caller)
{
- return bget_generic(bl, num, TRUE, TRUE);
+ return __bget_generic(bl, num, TRUE, FALSE, line, caller);
}
-struct gfs2_buffer_head *bget_zero(struct buf_list *bl, uint64_t num)
+struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, int line,
+ const char *caller)
{
- return bget_generic(bl, num, FALSE, FALSE);
+ return __bget_generic(bl, num, TRUE, TRUE, line, caller);
}
struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh)
@@ -165,12 +183,15 @@ struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh)
return bh;
}
-void brelse(struct gfs2_buffer_head *bh, enum update_flags is_updated)
+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 (is_updated)
- bh->b_changed = TRUE;
if (!bh->b_count) {
stack;
die("buffer count underflow for block %" PRIu64 " (0x%" PRIx64")\n",
@@ -179,23 +200,32 @@ void brelse(struct gfs2_buffer_head *bh, enum update_flags is_updated)
bh->b_count--;
}
-void bsync(struct buf_list *bl)
+void __bsync(struct buf_list *bl, int line, const char *caller)
{
struct gfs2_buffer_head *bh;
while (!osi_list_empty(&bl->list)) {
bh = osi_list_entry(bl->list.prev, struct gfs2_buffer_head,
b_list);
- if (bh->b_count)
- die("buffer still held for block: %" PRIu64 " (0x%" PRIx64")\n",
- bh->b_blocknr, bh->b_blocknr);
- write_buffer(bl, bh);
+ 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);
+ }
}
fsync(bl->sbp->device_fd);
}
/* commit buffers to disk but do not discard */
-void bcommit(struct buf_list *bl)
+void __bcommit(struct buf_list *bl, int line, const char *caller)
{
osi_list_t *tmp, *x;
struct gfs2_buffer_head *bh;
@@ -203,26 +233,37 @@ void bcommit(struct buf_list *bl)
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 */
- write_buffer(bl, bh);/* write the data & free memory */
- else if (bh->b_changed) { /* if buffer has changed */
- do_lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize);
- do_write(sdp->device_fd, bh->b_data, sdp->bsize);
+ 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);
}
-
-/* Check for unreleased buffers */
-void bcheck(struct buf_list *bl)
-{
- osi_list_t *tmp;
- struct gfs2_buffer_head *bh;
-
- osi_list_foreach(tmp, &bl->list) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
- if (bh->b_count)
- die("buffer still held: %"PRIu64"\n", bh->b_blocknr);
- }
-}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 2183aa5..73499c8 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -213,7 +213,8 @@ 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, rgbh);
+ bmodified(rgbh[buf]);
+ gfs2_rgrp_relse(rgd, rgbh);
free(rgbh);
return 0;
}
@@ -276,7 +277,7 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
}
if(i >= rgd->ri.ri_length){
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
return -1;
}
@@ -286,7 +287,6 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
val = ((*byte >> bit) & GFS2_BIT_MASK);
if(local_rgd)
- gfs2_rgrp_relse(rgd, not_updated, rgbh);
-
+ gfs2_rgrp_relse(rgd, rgbh);
return val;
}
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 86e50f9..0c8c169 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -228,7 +228,8 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
gfs2_meta_header_out(&mh, bh->b_data);
else
gfs2_rgrp_out(&rg, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 4b13d5c..63c190c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -42,11 +42,11 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
return ip;
}
-void inode_put(struct gfs2_inode *ip, enum update_flags is_updated)
+void inode_put(struct gfs2_inode *ip)
{
- if (is_updated)
+ if (ip->i_bh->b_changed)
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
- brelse(ip->i_bh, is_updated);
+ brelse(ip->i_bh);
free(ip);
}
@@ -99,7 +99,7 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
bn++;
}
- brelse(rgbh[block], FALSE);
+ brelse(rgbh[block]);
}
die("allocation is broken (1): %"PRIu64" %u\n",
@@ -129,11 +129,13 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
rg.rg_free--;
rl->rg_free--;
- brelse(rgbh[block], updated);
+ bmodified(rgbh[block]);
+ brelse(rgbh[block]);
rgbh[0] = bread(&sdp->buf_list, ri->ri_addr);
gfs2_rgrp_out(&rg, rgbh[0]->b_data);
- brelse(rgbh[0], updated);
+ bmodified(rgbh[0]);
+ brelse(rgbh[0]);
sdp->blks_alloced++;
free(rgbh);
@@ -166,6 +168,7 @@ static __inline__ void buffer_clear_tail(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh, int head)
{
memset(bh->b_data + head, 0, sdp->bsize - head);
+ bmodified(bh);
}
static __inline__ void
@@ -177,6 +180,7 @@ buffer_copy_tail(struct gfs2_sbd *sdp,
sdp->bsize - from_head);
memset(to_bh->b_data + sdp->bsize + to_head - from_head, 0,
from_head - to_head);
+ bmodified(to_bh);
}
void unstuff_dinode(struct gfs2_inode *ip)
@@ -202,7 +206,8 @@ void unstuff_dinode(struct gfs2_inode *ip)
sizeof(struct gfs2_meta_header),
ip->i_bh, sizeof(struct gfs2_dinode));
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
} else {
block = data_alloc(ip);
bh = bget(&sdp->buf_list, block);
@@ -210,7 +215,8 @@ void unstuff_dinode(struct gfs2_inode *ip)
buffer_copy_tail(sdp, bh, 0,
ip->i_bh, sizeof(struct gfs2_dinode));
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
}
@@ -279,7 +285,8 @@ void build_height(struct gfs2_inode *ip, int height)
sizeof(struct gfs2_meta_header),
ip->i_bh, sizeof(struct gfs2_dinode));
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
buffer_clear_tail(sdp, ip->i_bh, sizeof(struct gfs2_dinode));
@@ -331,14 +338,14 @@ void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
*block = meta_alloc(ip);
*ptr = cpu_to_be64(*block);
+ bmodified(bh);
ip->i_di.di_blocks++;
*new = 1;
}
void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
- uint64_t *dblock, uint32_t *extlen, int prealloc,
- enum update_flags if_changed)
+ uint64_t *dblock, uint32_t *extlen, int prealloc)
{
struct gfs2_sbd *sdp = ip->i_sbd;
struct gfs2_buffer_head *bh;
@@ -380,7 +387,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, bh, x, mp, create, new, dblock);
- brelse(bh, if_changed);
+ brelse(bh);
if (!*dblock)
goto out;
@@ -390,6 +397,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
+ bmodified(bh);
gfs2_meta_header_out(&mh, bh->b_data);
} else
bh = bread(&sdp->buf_list, *dblock);
@@ -420,7 +428,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
}
}
- brelse(bh, if_changed);
+ brelse(bh);
out:
free(mp);
@@ -482,7 +490,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
if (!extlen)
block_map(ip, lblock, ¬_new, &dblock, &extlen,
- FALSE, not_updated);
+ FALSE);
if (dblock) {
bh = bread(&sdp->buf_list, dblock);
@@ -493,7 +501,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
copy2mem(bh, &buf, o, amount);
if (bh)
- brelse(bh, not_updated);
+ brelse(bh);
copied += amount;
lblock++;
@@ -510,6 +518,7 @@ static void copy_from_mem(struct gfs2_buffer_head *bh, void **buf,
char **p = (char **)buf;
memcpy(bh->b_data + offset, *p, size);
+ bmodified(bh);
*p += size;
}
@@ -554,8 +563,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
if (!extlen) {
new = TRUE;
- block_map(ip, lblock, &new, &dblock, &extlen, FALSE,
- updated);
+ block_map(ip, lblock, &new, &dblock, &extlen, FALSE);
}
if (new) {
@@ -570,7 +578,8 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
} else
bh = bread(&sdp->buf_list, dblock);
copy_from_mem(bh, &buf, o, amount);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
copied += amount;
lblock++;
@@ -596,7 +605,7 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn,
if (inode_is_stuffed(ip))
unstuff_dinode(ip);
- block_map(ip, lbn, &new, &dbn, NULL, prealloc, updated);
+ block_map(ip, lbn, &new, &dbn, NULL, prealloc);
if (!dbn)
die("get_file_buf\n");
@@ -664,7 +673,7 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
if (!entries) {
dent->de_rec_len = cpu_to_be16(dip->i_sbd->bsize - offset);
dent->de_name_len = cpu_to_be16(name_len);
-
+ bmodified(bh);
*dent_out = dent;
return 0;
}
@@ -690,12 +699,14 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
dent->de_rec_len = cpu_to_be16(cur_rec_len -
be16_to_cpu(new->de_rec_len));
*dent_out = new;
+ bmodified(bh);
return 0;
}
dent->de_name_len = cpu_to_be16(name_len);
*dent_out = dent;
+ bmodified(bh);
return 0;
}
} while (gfs2_dirent_next(dip, bh, &dent) == 0);
@@ -708,6 +719,8 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
{
uint16_t cur_rec_len, prev_rec_len;
+ bmodified(bh);
+ bmodified(dip->i_bh);
if (dip->i_di.di_entries)
dip->i_di.di_entries--;
if (!prev) {
@@ -847,8 +860,9 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
dip->i_di.di_blocks++;
- brelse(obh, not_updated);
- brelse(nbh, updated);
+ brelse(obh);
+ bmodified(nbh);
+ brelse(nbh);
}
static void dir_double_exhash(struct gfs2_inode *dip)
@@ -908,7 +922,7 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
return error;
error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF);
if(error)
- brelse(*bhp, not_updated);
+ brelse(*bhp);
return error;
}
@@ -980,18 +994,18 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
if (dirent_alloc(dip, bh, len, &dent)) {
if (be16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) {
- brelse(bh, not_updated);
+ brelse(bh);
dir_split_leaf(dip, lindex, leaf_no);
goto restart;
} else if (dip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) {
- brelse(bh, not_updated);
+ brelse(bh);
dir_double_exhash(dip);
goto restart;
} else if (leaf->lf_next) {
leaf_no = be64_to_cpu(leaf->lf_next);
- brelse(bh, not_updated);
+ brelse(bh);
continue;
} else {
@@ -1013,7 +1027,8 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
dirent_alloc(dip, nbh, len, &dent);
dip->i_di.di_blocks++;
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
bh = nbh;
leaf = nleaf;
}
@@ -1027,10 +1042,11 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
leaf->lf_entries = be16_to_cpu(leaf->lf_entries) + 1;
leaf->lf_entries = cpu_to_be16(leaf->lf_entries);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
dip->i_di.di_entries++;
-
+ bmodified(dip->i_bh);
return;
}
}
@@ -1075,7 +1091,8 @@ static void dir_make_exhash(struct gfs2_inode *dip)
dent->de_rec_len = cpu_to_be16(be16_to_cpu(dent->de_rec_len) +
sizeof(struct gfs2_dinode) - sizeof(struct gfs2_leaf));
- brelse(bh, updated);
+ /* no need to: bmodified(bh); (buffer_copy_tail does it) */
+ brelse(bh);
buffer_clear_tail(sdp, dip->i_bh, sizeof(struct gfs2_dinode));
@@ -1088,12 +1105,13 @@ static void dir_make_exhash(struct gfs2_inode *dip)
dip->i_di.di_blocks++;
dip->i_di.di_flags |= GFS2_DIF_EXHASH;
dip->i_di.di_payload_format = 0;
+ /* no need: bmodified(dip->i_bh); buffer_clear_tail does it. */
for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
dip->i_di.di_depth = y;
}
-static void dir_l_add(struct gfs2_inode *dip, char *filename, int len,
+static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_inum *inum, unsigned int type)
{
struct gfs2_dirent *dent;
@@ -1111,9 +1129,10 @@ static void dir_l_add(struct gfs2_inode *dip, char *filename, int len,
memcpy((char *)(dent + 1), filename, len);
dip->i_di.di_entries++;
+ bmodified(dip->i_bh);
}
-void dir_add(struct gfs2_inode *dip, char *filename, int len,
+void dir_add(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_inum *inum, unsigned int type)
{
if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
@@ -1185,8 +1204,8 @@ init_dinode(struct gfs2_sbd *sdp, struct gfs2_inum *inum,
return bh;
}
-struct gfs2_inode *createi(struct gfs2_inode *dip, char *filename,
- unsigned int mode, uint32_t flags)
+struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
+ unsigned int mode, uint32_t flags)
{
struct gfs2_sbd *sdp = dip->i_sbd;
uint64_t bn;
@@ -1208,6 +1227,7 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, char *filename,
bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num);
ip = inode_get(sdp, bh);
+ bmodified(bh);
}
return ip;
}
@@ -1325,7 +1345,7 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
/* Find the entry */
do{
if (bh)
- brelse(bh, not_updated);
+ brelse(bh);
bh = bh_next;
@@ -1339,14 +1359,14 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
break;
default:
- brelse(bh, not_updated);
+ brelse(bh);
return error;
}
error = get_next_leaf(dip, bh, &bh_next);
} while (!error);
- brelse(bh, not_updated);
+ brelse(bh);
return error;
}
@@ -1374,7 +1394,7 @@ static int dir_e_search(struct gfs2_inode *dip, const char *filename,
if (type)
*type = be16_to_cpu(dent->de_type);
- brelse(bh, not_updated);
+ brelse(bh);
return 0;
}
@@ -1405,7 +1425,7 @@ static int dir_l_search(struct gfs2_inode *dip, const char *filename,
if(type)
*type = be16_to_cpu(dent->de_type);
}
- brelse(dibh, not_updated);
+ brelse(dibh);
return error;
}
@@ -1457,11 +1477,11 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len)
error = leaf_search(dip, bh, filename, len, &cur, &prev);
if (error) {
if(error != -ENOENT){
- brelse(bh, updated);
+ brelse(bh);
return -1;
}
leaf_no = be64_to_cpu(((struct gfs2_leaf *)bh->b_data)->lf_next);
- brelse(bh, updated);
+ brelse(bh);
} else
found = 1;
}
@@ -1472,7 +1492,7 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len)
if (bh) {
dirent2_del(dip, bh, prev, cur);
- brelse(bh, updated);
+ brelse(bh);
}
return 0;
}
@@ -1496,7 +1516,7 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh,
error = leaf_search(dip, dibh, filename, len, &cur, &prev);
if (error) {
if (got_buf)
- brelse(dibh, not_updated);
+ brelse(dibh);
if (error == -ENOENT)
return 1;
else
@@ -1504,8 +1524,10 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh,
}
dirent2_del(dip, dibh, prev, cur);
- if (got_buf)
- brelse(dibh, updated);
+ if (got_buf) {
+ bmodified(dibh);
+ brelse(dibh);
+ }
return 0;
}
@@ -1532,7 +1554,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
error = dir_e_del(dip, filename, len);
else
error = dir_l_del(dip, bh, filename, len);
-
+ bmodified(dip->i_bh);
return error;
}
@@ -1587,7 +1609,8 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
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 */
+ bmodified(bh);
+ brelse(bh); /* release the buffer */
sdp->blks_alloced--;
}
@@ -1637,15 +1660,16 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
/* 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);
+ brelse(nbh);
}
}
}
/* Set the bitmap type for inode to free space: */
gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE);
- inode_put(ip, updated);
- /* inode_put deallocated the extra block used by the disk inode, */
- /* so adjust it in the superblock struct */
+ bmodified(ip->i_bh);
+ inode_put(ip);
+ /* inode_put deallocated the extra block used by the disk inode, */
+ /* so adjust it in the superblock struct */
sdp->blks_alloced--;
/* Now we have to adjust the rg freespace count and inode count: */
rgd = gfs2_blk2rgrpd(sdp, diblock);
@@ -1655,7 +1679,8 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
rgd->rg_free++;
rg.rg_dinodes--; /* one less inode in use */
gfs2_rgrp_out(&rg, bh->b_data);
- brelse(bh, updated); /* release the buffer */
+ bmodified(bh);
+ brelse(bh); /* release the buffer */
sdp->dinodes_alloced--;
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index e783fdd..428ba70 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -70,9 +70,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
unsigned int height;
unsigned int end_of_metadata;
unsigned int x;
- enum update_flags f;
- f = not_updated;
*new = 0;
*dblock = 0;
if (extlen)
@@ -104,7 +102,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
for (x = 0; x < end_of_metadata; x++) {
gfs1_lookup_block(ip, bh, x, mp, create, new, dblock);
- brelse(bh, f);
+ brelse(bh);
if (!*dblock)
goto out;
@@ -116,10 +114,9 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
gfs2_meta_header_out(&mh, bh->b_data);
- f = updated;
+ bmodified(bh);
} else {
bh = bread(&sdp->buf_list, *dblock);
- f = not_updated;
}
}
@@ -150,7 +147,7 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
}
}
- brelse(bh, f);
+ brelse(bh);
out:
free(mp);
@@ -210,7 +207,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
if (bh) {
memcpy(buf+copied, bh->b_data + offset, amount);
- brelse(bh, not_updated);
+ brelse(bh);
} else
memset(buf+copied, 0, amount);
copied += amount;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3310044..a5ef41c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -278,20 +278,6 @@ extern const char *prog_name;
#define META (2)
#define DINODE (3)
-#define NOT_UPDATED (0)
-#define UPDATED (1)
-
-/* A bit of explanation is in order: */
-/* updated flag means the buffer was updated from THIS function before */
-/* brelse was called. */
-/* not_updated flag means the buffer may or may not have been updated */
-/* by a function called within this one, but it wasn't updated */
-/* by this function. */
-enum update_flags {
- not_updated = NOT_UPDATED,
- updated = UPDATED
-};
-
/* bitmap.c */
struct gfs2_bmap {
uint64_t size;
@@ -369,18 +355,29 @@ 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 */
-void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
-struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num);
-struct gfs2_buffer_head *bget_generic(struct buf_list *bl, uint64_t num,
- int find_existing, int read_disk);
-struct gfs2_buffer_head *bget(struct buf_list *bl, uint64_t num);
-struct gfs2_buffer_head *bread(struct buf_list *bl, uint64_t num);
-struct gfs2_buffer_head *bget_zero(struct buf_list *bl, uint64_t num);
-struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh);
-void brelse(struct gfs2_buffer_head *bh, enum update_flags updated);
-void bsync(struct buf_list *bl);
-void bcommit(struct buf_list *bl);
-void bcheck(struct buf_list *bl);
+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,
+ int read_disk, int line,
+ const char *caller);
+extern struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num,
+ int line, const char *caller);
+extern struct gfs2_buffer_head *__bread(struct buf_list *bl, 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);
+
+#define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \
+ __LINE__, \
+ __FUNCTION__)
+#define bget(bl, num) __bget(bl, num, __LINE__, __FUNCTION__)
+#define bread(bl, num) __bread(bl, num, __LINE__, __FUNCTION__)
+#define bsync(bl) do { __bsync(bl, __LINE__, __FUNCTION__); } while(0)
+#define bcommit(bl) do { __bcommit(bl, __LINE__, __FUNCTION__); } while(0)
/* device_geometry.c */
void device_geometry(struct gfs2_sbd *sdp);
@@ -426,58 +423,65 @@ metapointer(struct gfs2_buffer_head *bh, unsigned int height,
return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height];
}
-struct metapath *find_metapath(struct gfs2_inode *ip, uint64_t block);
-void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
- unsigned int height, struct metapath *mp,
- int create, int *new, uint64_t *block);
-struct gfs2_inode *inode_get(struct gfs2_sbd *sdp,
- struct gfs2_buffer_head *bh);
-void inode_put(struct gfs2_inode *ip, enum update_flags updated);
-uint64_t data_alloc(struct gfs2_inode *ip);
-uint64_t meta_alloc(struct gfs2_inode *ip);
-uint64_t dinode_alloc(struct gfs2_sbd *sdp);
-int gfs2_readi(struct gfs2_inode *ip, void *buf,
- uint64_t offset, unsigned int size);
-int gfs2_writei(struct gfs2_inode *ip, void *buf,
- uint64_t offset, unsigned int size);
-struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn,
- int prealloc);
struct gfs2_buffer_head *get_sysfile_buf(struct gfs2_inode *ip, uint64_t lbn,
int prealloc);
struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
struct gfs2_inum *inum,
unsigned int mode, uint32_t flags,
struct gfs2_inum *parent);
-struct gfs2_inode *createi(struct gfs2_inode *dip, char *filename,
- unsigned int mode, uint32_t flags);
-void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
- struct gfs2_dirent *prev, struct gfs2_dirent *cur);
struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block);
int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_inode **ipp);
-void dir_add(struct gfs2_inode *dip, char *filename, int len,
- struct gfs2_inum *inum, unsigned int type);
-int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
- const char *filename, int filename_len);
-void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
- uint64_t *dblock, uint32_t *extlen, int prealloc,
- enum update_flags if_changed);
-void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
- uint64_t *leaf_out);
-void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
-void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
-int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
-int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
- struct gfs2_buffer_head **bhp);
-int gfs2_dirent_first(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
- struct gfs2_dirent **dent);
-int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
- struct gfs2_dirent **dent);
-void build_height(struct gfs2_inode *ip, int height);
-void unstuff_dinode(struct gfs2_inode *ip);
-unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size);
-void write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
- unsigned int blocks);
+extern struct metapath *find_metapath(struct gfs2_inode *ip, uint64_t block);
+extern void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
+ unsigned int height, struct metapath *mp,
+ int create, int *new, uint64_t *block);
+extern struct gfs2_inode *inode_get(struct gfs2_sbd *sdp,
+ struct gfs2_buffer_head *bh);
+extern void inode_put(struct gfs2_inode *ip);
+extern uint64_t data_alloc(struct gfs2_inode *ip);
+extern uint64_t meta_alloc(struct gfs2_inode *ip);
+extern uint64_t dinode_alloc(struct gfs2_sbd *sdp);
+extern int gfs2_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
+ unsigned int size);
+extern int gfs2_writei(struct gfs2_inode *ip, void *buf, uint64_t offset,
+ unsigned int size);
+extern struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip,
+ uint64_t lbn, int prealloc);
+extern struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
+ struct gfs2_inum *inum,
+ unsigned int mode, uint32_t flags,
+ struct gfs2_inum *parent);
+extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
+ unsigned int mode, uint32_t flags);
+extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
+ struct gfs2_dirent *prev, struct gfs2_dirent *cur);
+extern struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block);
+extern int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
+ struct gfs2_inode **ipp);
+extern void dir_add(struct gfs2_inode *dip, const char *filename, int len,
+ struct gfs2_inum *inum, unsigned int type);
+extern int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
+ const char *filename, int filename_len);
+extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
+ uint64_t *dblock, uint32_t *extlen, int prealloc);
+extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
+ uint64_t *leaf_out);
+extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
+extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
+extern int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
+extern int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
+ struct gfs2_buffer_head **bhp);
+extern int gfs2_dirent_first(struct gfs2_inode *dip,
+ struct gfs2_buffer_head *bh,
+ struct gfs2_dirent **dent);
+extern int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
+ struct gfs2_dirent **dent);
+extern void build_height(struct gfs2_inode *ip, int height);
+extern void unstuff_dinode(struct gfs2_inode *ip);
+extern unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size);
+extern void write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip,
+ unsigned int j, unsigned int blocks);
/**
* device_size - figure out a device's size
@@ -671,8 +675,8 @@ 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,
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_relse(struct rgrp_list *rgd,
+ struct gfs2_buffer_head **bh);
extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c
index 0d2ba7d..f0f119d 100644
--- a/gfs2/libgfs2/recovery.c
+++ b/gfs2/libgfs2/recovery.c
@@ -36,7 +36,7 @@ int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk,
uint64_t dblock;
uint32_t extlen;
- block_map(ip, blk, &new, &dblock, &extlen, FALSE, not_updated);
+ block_map(ip, blk, &new, &dblock, &extlen, FALSE);
if (!dblock)
return -EIO;
@@ -76,7 +76,7 @@ int get_log_header(struct gfs2_inode *ip, unsigned int blk,
hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
tmp->lh_hash = saved_hash;
gfs2_log_header_in(&lh, bh->b_data);
- brelse(bh, not_updated);
+ brelse(bh);
if (error || lh.lh_blkno != blk || lh.lh_hash != hash)
return 1;
@@ -228,7 +228,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head)
lblock = head->lh_blkno;
gfs2_replay_incr_blk(ip, &lblock);
- block_map(ip, lblock, &new, &dblock, &extlen, 0, not_updated);
+ block_map(ip, lblock, &new, &dblock, &extlen, 0);
if (!dblock)
return -EIO;
@@ -245,8 +245,8 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head)
lh->lh_blkno = cpu_to_be32(lblock);
hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header));
lh->lh_hash = cpu_to_be32(hash);
-
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
return 0;
}
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 9027909..f4da1a0 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -133,7 +133,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
error = rgd->ri.ri_addr + x;
for (; x >= 0; x--)
- brelse(bh[x], not_updated);
+ brelse(bh[x]);
return error;
}
}
@@ -143,13 +143,12 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
return 0;
}
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated,
- struct gfs2_buffer_head **bh)
+void gfs2_rgrp_relse(struct rgrp_list *rgd, struct gfs2_buffer_head **bh)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++)
- brelse(bh[x], is_updated);
+ brelse(bh[x]);
}
void gfs2_rgrp_free(osi_list_t *rglist)
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 2b63ad2..b3e884d 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -56,7 +56,8 @@ build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
for (x = 0; x < sdp->sb_addr; x++) {
bh = bget(&sdp->buf_list, x);
memset(bh->b_data, 0, sdp->bsize);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
memset(&sb, 0, sizeof(struct gfs2_sb));
@@ -76,7 +77,8 @@ build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
#endif
bh = bget(&sdp->buf_list, sdp->sb_addr);
gfs2_sb_out(&sb, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
if (sdp->debug) {
printf("\nSuper Block:\n");
@@ -108,7 +110,8 @@ void write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
struct gfs2_buffer_head *bh = get_file_buf(ip, x, TRUE);
if (!bh)
die("write_journal\n");
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
for (x = 0; x < blocks; x++) {
struct gfs2_buffer_head *bh = get_file_buf(ip, x, FALSE);
@@ -121,7 +124,8 @@ void write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
((struct gfs2_log_header *)bh->b_data)->lh_hash = cpu_to_be32(hash);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
if (++seq == blocks)
seq = 0;
@@ -150,7 +154,8 @@ build_jindex(struct gfs2_sbd *sdp)
ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
write_journal(sdp, ip, j,
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
if (sdp->debug) {
@@ -158,7 +163,8 @@ build_jindex(struct gfs2_sbd *sdp)
gfs2_dinode_print(&jindex->i_di);
}
- inode_put(jindex, updated);
+ bmodified(jindex->i_bh);
+ inode_put(jindex);
}
static void
@@ -178,7 +184,8 @@ build_inum_range(struct gfs2_inode *per_node, unsigned int j)
gfs2_dinode_print(&ip->i_di);
}
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
static void
@@ -198,7 +205,8 @@ build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
gfs2_dinode_print(&ip->i_di);
}
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
static void
@@ -227,7 +235,8 @@ build_quota_change(struct gfs2_inode *per_node, unsigned int j)
gfs2_meta_header_out(&mh, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
}
if (sdp->debug) {
@@ -235,7 +244,8 @@ build_quota_change(struct gfs2_inode *per_node, unsigned int j)
gfs2_dinode_print(&ip->i_di);
}
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
void
@@ -258,7 +268,8 @@ build_per_node(struct gfs2_sbd *sdp)
gfs2_dinode_print(&per_node->i_di);
}
- inode_put(per_node, updated);
+ bmodified(per_node->i_bh);
+ inode_put(per_node);
}
void
@@ -324,7 +335,8 @@ build_rindex(struct gfs2_sbd *sdp)
gfs2_dinode_print(&ip->i_di);
}
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
void
@@ -355,7 +367,8 @@ build_quota(struct gfs2_sbd *sdp)
gfs2_quota_print(&qu);
}
- inode_put(ip, updated);
+ bmodified(ip->i_bh);
+ inode_put(ip);
}
void
@@ -502,11 +515,11 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
GFS2_BLKST_DINODE);
if(blk != BFITNOENT){
*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
- brelse(bh, not_updated);
+ brelse(bh);
break;
}
blk=0;
- brelse(bh, not_updated);
+ brelse(bh);
}
if(i == length)
return -1;
@@ -529,12 +542,12 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
do{
if (bh)
- brelse(bh, not_updated);
+ brelse(bh);
if (gfs2_next_rg_meta(sdp, rgd, block, first))
return -1;
bh = bread(&sdp->buf_list, *block);
first = 0;
} while(gfs2_check_meta(bh, type));
- brelse(bh, not_updated);
+ brelse(bh);
return 0;
}
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index e31268e..32407bc 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -73,7 +73,7 @@ int read_sb(struct gfs2_sbd *sdp)
bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
gfs2_sb_in(&sdp->sd_sb, bh->b_data);
- brelse(bh, not_updated);
+ brelse(bh);
error = check_sb(&sdp->sd_sb);
if (error)
@@ -261,16 +261,13 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
}
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, rgbh, &rg);
if (errblock) {
free(rgbh);
return errblock;
} else
- gfs2_rgrp_relse(rgd, f, rgbh);
+ gfs2_rgrp_relse(rgd, rgbh);
count2++;
}
@@ -293,7 +290,8 @@ int write_sb(struct gfs2_sbd *sbp)
bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
gfs2_sb_out(&sbp->sd_sb, bh->b_data);
- brelse(bh, updated);
+ bmodified(bh);
+ brelse(bh);
bcommit(&sbp->buf_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 60082a9..345babe 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -182,8 +182,8 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
/* Note: We do inode_put with not_updated because we only updated */
/* the new RGs/bitmaps themselves on disk. The rindex file must */
/* be updated through the meta_fs so the gfs2 kernel is informed. */
- inode_put(sdp->md.riinode, not_updated);
- inode_put(sdp->master_dir, not_updated);
+ inode_put(sdp->md.riinode);
+ inode_put(sdp->master_dir);
/* We're done with the libgfs portion, so commit it to disk. */
bsync(&sdp->buf_list);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 67b552b..c33f216 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -503,10 +503,14 @@ main_mkfs(int argc, char *argv[])
/* Cleanup */
- inode_put(sdp->md.rooti, updated);
- inode_put(sdp->master_dir, updated);
- inode_put(sdp->md.inum, updated);
- inode_put(sdp->md.statfs, updated);
+ bmodified(sdp->md.rooti->i_bh);
+ inode_put(sdp->md.rooti);
+ bmodified(sdp->master_dir->i_bh);
+ inode_put(sdp->master_dir);
+ bmodified(sdp->md.inum->i_bh);
+ inode_put(sdp->md.inum);
+ bmodified(sdp->md.statfs->i_bh);
+ inode_put(sdp->md.statfs);
bsync(&sdp->buf_list);
error = fsync(sdp->device_fd);
14 years, 1 month
cluster: RHEL56 - Separate eattr_block list from the rest for efficiency
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: e9316e5043402ba0cdc66fe70e90538fd88a4797
Parent: f6cdc874f5caa267d13f0f6741765bfaa2c24284
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:36:14 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:51:20 2010 -0500
Separate eattr_block list from the rest for efficiency
There were only a few rare places where the eattr special list was
being used in fsck.gfs2. By moving those places outside the general
bitmap functions the general case is faster.
rhbz#455300
---
gfs2/fsck/pass1.c | 5 ++---
gfs2/fsck/pass1c.c | 2 +-
gfs2/fsck/pass5.c | 4 ----
gfs2/libgfs2/block_list.c | 33 +++++++++------------------------
gfs2/libgfs2/libgfs2.h | 4 ++--
5 files changed, 14 insertions(+), 34 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f011c64..80f253f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -405,8 +405,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
(unsigned long long)ip->i_di.di_num.no_addr);
/* Mark the inode as having an eattr in the block map
so pass1c can check it. */
- gfs2_block_mark(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
- gfs2_eattr_block);
+ gfs2_special_set(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr);
if (!leaf_pointer_errors)
return 0;
log_err( _("Inode %lld (0x%llx) has recoverable indirect "
@@ -544,7 +543,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
"block(s) attached.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- gfs2_block_mark(sdp, bl, ip->i_di.di_num.no_addr, gfs2_eattr_block);
+ gfs2_special_set(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
if(gfs2_check_range(sdp, block)) {
log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
"block #%llu (0x%llx) is out of range.\n"),
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index f707efc..c1cc623 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -277,7 +277,7 @@ int pass1c(struct gfs2_sbd *sbp)
if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */
log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"),
block_no, block_no);
- gfs2_block_unmark(sbp, bl, block_no, gfs2_eattr_block);
+ gfs2_special_clear(&sbp->eattr_blocks, block_no);
ip = fsck_inode_get(sbp, bh);
log_debug( _("Found eattr at %llu (0x%llx)\n"),
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 98cdeef..6e16235 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -25,10 +25,6 @@
static int convert_mark(struct gfs2_block_query *q, uint32_t *count)
{
- if (q->eattr_block) {
- count[2]++;
- return GFS2_BLKST_USED;
- }
switch(q->block_type) {
case gfs2_meta_inval:
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 7fec19d..5a23351 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -192,22 +192,22 @@ static void gfs2_dup_set(struct dup_blocks *blocklist, uint64_t block)
return;
}
-static void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
+static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
{
- struct special_blocks *b;
+ struct dup_blocks *b;
- b = blockfind(blocklist, block);
+ b = dupfind(blocklist, block);
if (b) {
osi_list_del(&b->list);
free(b);
}
}
-static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
+void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
{
- struct dup_blocks *b;
+ struct special_blocks *b;
- b = dupfind(blocklist, block);
+ b = blockfind(blocklist, block);
if (b) {
osi_list_del(&b->list);
free(b);
@@ -221,8 +221,6 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
if(mark == gfs2_dup_block)
gfs2_dup_set(&sdp->dup_blocks, block);
- else if(mark == gfs2_eattr_block)
- gfs2_special_set(&sdp->eattr_blocks, block);
else
err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]);
return err;
@@ -234,18 +232,10 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
{
int err = 0;
- switch (mark) {
- case gfs2_dup_block:
+ if (mark == gfs2_dup_block)
gfs2_dup_clear(&sdp->dup_blocks, block);
- break;
- case gfs2_eattr_block:
- gfs2_special_clear(&sdp->eattr_blocks, block);
- break;
- default:
- /* FIXME: check types */
+ else
err = gfs2_bitmap_clear(il, block);
- break;
- }
return err;
}
@@ -253,12 +243,8 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block)
{
- int err;
-
gfs2_dup_clear(&sdp->dup_blocks, block);
- gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(il, block);
- return err;
+ return gfs2_bitmap_clear(il, block);
}
int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
@@ -282,7 +268,6 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
return -1;
val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0);
- val->eattr_block = (blockfind(&sdp->eattr_blocks, block) ? 1 : 0);
byte = il->map + BITMAP_SIZE4(block);
b = BITMAP_BYTE_OFFSET4(block);
val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index fc8af3f..3310044 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -340,13 +340,11 @@ enum gfs2_mark_block {
gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */
gfs2_meta_inval = INVALID_META,
gfs2_dup_block, /* Contains at least one duplicate block */
- gfs2_eattr_block, /* Contains an eattr */
};
struct gfs2_block_query {
uint8_t block_type;
uint8_t dup_block;
- uint8_t eattr_block;
};
extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
@@ -358,6 +356,8 @@ extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark);
extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark);
+extern void gfs2_special_clear(struct special_blocks *blocklist,
+ uint64_t block);
/* gfs2_block_unmark clears ONE mark for the given block */
extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block m);
14 years, 1 month
cluster: RHEL56 - Misc blocklist optimizations
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f6cdc874f5caa267d13f0f6741765bfaa2c24284
Parent: 8639e740d7b51c046d2cffd5b96c6319214b839f
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:35:29 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:49:39 2010 -0500
Misc blocklist optimizations
rhbz#455300
---
gfs2/fsck/fsck.h | 1 -
gfs2/fsck/metawalk.c | 3 ++-
gfs2/libgfs2/block_list.c | 37 ++++++++++++-------------------------
3 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 7cf0d8b..497be3a 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -71,7 +71,6 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
gfs2_grow or something. Count the RGs by hand. */
};
-struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block);
struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 70c3be6..38e1c00 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -27,7 +27,8 @@
#include "metawalk.h"
#include "hash.h"
-struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp, uint64_t block)
+static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
+ uint64_t block)
{
int j;
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 208897b..7fec19d 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -26,7 +26,7 @@ static int mark_to_gbmap[16] = {
FREE, BLOCK_IN_USE, DIR_INDIR_BLK, DIR_INODE, FILE_INODE,
LNK_INODE, BLK_INODE, CHR_INODE, FIFO_INODE, SOCK_INODE,
DIR_LEAF_INODE, JOURNAL_BLK, OTHER_META, EATTR_META,
- INVALID_META, INVALID_META
+ BAD_BLOCK, INVALID_META
};
#define BITMAP_SIZE4(size) (size >> 1)
@@ -65,20 +65,6 @@ static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val)
return -1;
}
-static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val)
-{
- static char *byte;
- static uint64_t b;
-
- if(bit < bmap->size) {
- byte = bmap->map + BITMAP_SIZE4(bit);
- b = BITMAP_BYTE_OFFSET4(bit);
- *val = (*byte & (BITMAP_MASK4 << b )) >> b;
- return 0;
- }
- return -1;
-}
-
static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset)
{
static char *byte;
@@ -267,7 +253,7 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block)
{
- int err = 0;
+ int err;
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
@@ -289,16 +275,17 @@ int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val)
{
- int err = 0;
+ static char *byte;
+ static uint64_t b;
+
+ if(block >= il->size)
+ return -1;
- val->dup_block = 0;
- val->eattr_block = 0;
- if (dupfind(&sdp->dup_blocks, block))
- val->dup_block = 1;
- if (blockfind(&sdp->eattr_blocks, block))
- val->eattr_block = 1;
- if((err = gfs2_bitmap_get(il, block, &val->block_type)))
- return err;
+ val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0);
+ val->eattr_block = (blockfind(&sdp->eattr_blocks, block) ? 1 : 0);
+ byte = il->map + BITMAP_SIZE4(block);
+ b = BITMAP_BYTE_OFFSET4(block);
+ val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b;
return 0;
}
14 years, 1 month
cluster: RHEL56 - Streamline the bitmap code by always using 4-bit size per block
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 8639e740d7b51c046d2cffd5b96c6319214b839f
Parent: d6e3399a259167c1762651586ea062cf7d0c6c30
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:34:55 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:48:09 2010 -0500
Streamline the bitmap code by always using 4-bit size per block
The block_map code was always using four bits to represent blocks in
the bitmap. Therefore, it didn't need all the logic to handle bitmaps
with one bit per block. This should improve performance.
rhbz#455300
---
gfs2/libgfs2/Makefile | 2 +-
gfs2/libgfs2/block_list.c | 85 +++++++--------------------------------------
2 files changed, 14 insertions(+), 73 deletions(-)
diff --git a/gfs2/libgfs2/Makefile b/gfs2/libgfs2/Makefile
index 05dde0d..7eeb2ac 100644
--- a/gfs2/libgfs2/Makefile
+++ b/gfs2/libgfs2/Makefile
@@ -27,7 +27,7 @@ CFLAGS=-Wall -ggdb -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
-D_GNU_SOURCE -DGFS2_RELEASE_NAME=\"2\" ${INCLUDEPATH}
H=gfs2_disk_hash.h libgfs2.h linux_endian.h ondisk.h osi_list.h
-C=bitmap.c block_list.c buf.c device_geometry.c fs_bits.c fs_geometry.c fs_ops.c gfs1.c locking.c gfs2_log.c misc.c ondisk.c recovery.c size.c structures.c super.c rgrp.c
+C=block_list.c buf.c device_geometry.c fs_bits.c fs_geometry.c fs_ops.c gfs1.c locking.c gfs2_log.c misc.c ondisk.c recovery.c size.c structures.c super.c rgrp.c
O=$(subst .c,.o,${C})
all: ${LIBGFS2}
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 19e91df..208897b 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -29,56 +29,17 @@ static int mark_to_gbmap[16] = {
INVALID_META, INVALID_META
};
-#define BITMAP_SIZE(size, cpb) (size / cpb)
-#define BITMAP_SIZE1(size) (size >> 3)
#define BITMAP_SIZE4(size) (size >> 1)
-
-#define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \
- * map->chunksize )
-
-/* BITMAP_BYTE_OFFSET1 is for chunksize==1, which implies chunks_per_byte==8 */
-/* Reducing the math, we get: */
-/* #define BITMAP_BYTE_OFFSET1(x) ((x % 8) * 1) */
-/* #define BITMAP_BYTE_OFFSET1(x) (x % 8) */
-/* #define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) */
-#define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007)
-
-/* BITMAP_BYTE_OFFSET4 is for chunksize==4, which implies chunks_per_byte==2 */
-/* Reducing the math, we get: */
-/* #define BITMAP_BYTE_OFFSET4(x) ((x % 2) * 4) */
-/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) * 4) */
-/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) */
#define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2)
+#define BITMAP_MASK4 (0xf)
-#define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1)
-/* BITMAP_MASK1 is for chunksize==1 */
-/* Reducing the math, we get: */
-/* #define BITMAP_MASK1(chunksize) ((2 << (1 - 1)) - 1) */
-/* #define BITMAP_MASK1(chunksize) ((2 << 0) - 1) */
-/* #define BITMAP_MASK1(chunksize) ((2) - 1) */
-#define BITMAP_MASK1(chunksize) (1)
-
-/* BITMAP_MASK4 is for chunksize==4 */
-/* #define BITMAP_MASK(chunksize) ((2 << (4 - 1)) - 1) */
-/* #define BITMAP_MASK(chunksize) ((2 << 3) - 1) */
-/* #define BITMAP_MASK(chunksize) (0x10 - 1) */
-#define BITMAP_MASK4(chunksize) (0xf)
-
-static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size,
- uint8_t chunksize)
+static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size)
{
- if((((chunksize >> 1) << 1) != chunksize) && chunksize != 1)
- return -1;
- if(chunksize > 8)
- return -1;
- bmap->chunksize = chunksize;
- bmap->chunks_per_byte = 8 / chunksize;
-
bmap->size = size;
/* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs
* must be 1-based */
- bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1;
+ bmap->mapsize = BITMAP_SIZE4(size);
if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
return -ENOMEM;
@@ -96,15 +57,9 @@ static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val)
static uint64_t b;
if(offset < bmap->size) {
- if (bmap->chunksize == 1) {
- byte = bmap->map + BITMAP_SIZE1(offset);
- b = BITMAP_BYTE_OFFSET1(offset);
- *byte |= (val & BITMAP_MASK1(bmap->chunksize));
- } else {
- byte = bmap->map + BITMAP_SIZE4(offset);
- b = BITMAP_BYTE_OFFSET4(offset);
- *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b;
- }
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte |= (val & BITMAP_MASK4) << b;
return 0;
}
return -1;
@@ -116,15 +71,9 @@ static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val)
static uint64_t b;
if(bit < bmap->size) {
- if (bmap->chunksize == 1) {
- byte = bmap->map + BITMAP_SIZE1(bit);
- b = BITMAP_BYTE_OFFSET1(bit);
- *val = (*byte & (BITMAP_MASK1(bmap->chunksize) << b )) >> b;
- } else {
- byte = bmap->map + BITMAP_SIZE4(bit);
- b = BITMAP_BYTE_OFFSET4(bit);
- *val = (*byte & (BITMAP_MASK4(bmap->chunksize) << b )) >> b;
- }
+ byte = bmap->map + BITMAP_SIZE4(bit);
+ b = BITMAP_BYTE_OFFSET4(bit);
+ *val = (*byte & (BITMAP_MASK4 << b )) >> b;
return 0;
}
return -1;
@@ -136,15 +85,9 @@ static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset)
static uint64_t b;
if(offset < bmap->size) {
- if (bmap->chunksize == 1) {
- byte = bmap->map + BITMAP_SIZE1(offset);
- b = BITMAP_BYTE_OFFSET1(offset);
- *byte &= ~(BITMAP_MASK1(bmap->chunksize) << b);
- } else {
- byte = bmap->map + BITMAP_SIZE4(offset);
- b = BITMAP_BYTE_OFFSET4(offset);
- *byte &= ~(BITMAP_MASK4(bmap->chunksize) << b);
- }
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte &= ~(BITMAP_MASK4 << b);
return 0;
}
return -1;
@@ -157,8 +100,6 @@ static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap)
free(bmap->map);
bmap->size = 0;
bmap->mapsize = 0;
- bmap->chunksize = 0;
- bmap->chunks_per_byte = 0;
}
struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
@@ -171,7 +112,7 @@ struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(il, size, 4)) {
+ if(gfs2_bitmap_create(il, size)) {
*addl_mem_needed = il->mapsize;
free(il);
il = NULL;
14 years, 1 month
cluster: RHEL56 - Simplify bitmap/block list structures
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: d6e3399a259167c1762651586ea062cf7d0c6c30
Parent: 3f47f6f9b2dc9f8e1dbfc27158d6bc1f64ad5cac
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:34:08 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:45:45 2010 -0500
Simplify bitmap/block list structures
This patch eliminates structures within structures to simplify the
code and improve performance.
rhbz#455300
---
gfs2/edit/savemeta.c | 8 +-
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/initialize.c | 4 +-
gfs2/fsck/main.c | 2 +-
gfs2/libgfs2/block_list.c | 166 ++++++++++++++++++++++++++++++++++++++++-----
gfs2/libgfs2/libgfs2.h | 48 +++++---------
6 files changed, 172 insertions(+), 58 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 8959442..50c9e2a 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -47,7 +47,7 @@ struct saved_metablock {
struct saved_metablock *savedata;
uint64_t last_fs_block, last_reported_block, blks_saved, total_out, pct;
-struct gfs2_block_list *blocklist = NULL;
+struct gfs2_bmap *blocklist = NULL;
uint64_t journal_blocks[MAX_JOURNALS_SAVED];
uint64_t gfs1_journal_size = 0; /* in blocks */
int journals_found = 0;
@@ -588,8 +588,8 @@ void savemeta(char *out_fn, int saveoption)
fflush(stdout);
}
if (!slow) {
- blocklist = gfs2_block_list_create(&sbd, last_fs_block + 1,
- &memreq);
+ blocklist = gfs2_bmap_create(&sbd, last_fs_block + 1,
+ &memreq);
if (!blocklist)
slow = TRUE;
}
@@ -683,7 +683,7 @@ void savemeta(char *out_fn, int saveoption)
}
/* Clean up */
if (blocklist)
- gfs2_block_list_destroy(&sbd, blocklist);
+ gfs2_bmap_destroy(&sbd, blocklist);
/* There may be a gap between end of file system and end of device */
/* so we tell the user that we've processed everything. */
block = last_fs_block;
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 57dd6b4..7cf0d8b 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -97,7 +97,7 @@ extern struct gfs2_options opts;
extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
extern osi_list_t dir_hash[FSCK_HASH_SIZE];
extern osi_list_t inode_hash[FSCK_HASH_SIZE];
-extern struct gfs2_block_list *bl;
+extern struct gfs2_bmap *bl;
extern uint64_t last_fs_block, last_reported_block;
extern int skip_this_pass, fsck_abort;
extern int errors_found, errors_corrected;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 67fa1fb..5985919 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -115,7 +115,7 @@ static void empty_super_block(struct gfs2_sbd *sdp)
}
if (bl)
- gfs2_block_list_destroy(sdp, bl);
+ gfs2_bmap_destroy(sdp, bl);
}
@@ -271,7 +271,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
goto fail;
}
- bl = gfs2_block_list_create(sdp, last_fs_block+1, &addl_mem_needed);
+ bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
if (!bl) {
log_crit( _("This system doesn't have enough memory + swap space to fsck this file system.\n"));
log_crit( _("Additional memory needed is approximately: %lluMB\n"),
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 56ac943..9da8dd2 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -32,7 +32,7 @@ struct gfs2_options opts = {0};
struct gfs2_inode *lf_dip; /* Lost and found directory inode */
osi_list_t dir_hash[FSCK_HASH_SIZE];
osi_list_t inode_hash[FSCK_HASH_SIZE];
-struct gfs2_block_list *bl = NULL;
+struct gfs2_bmap *bl = NULL;
uint64_t last_fs_block, last_reported_block = -1;
int skip_this_pass = FALSE, fsck_abort = FALSE;
int errors_found = 0, errors_corrected = 0;
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index c67c5a4..19e91df 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -29,19 +29,150 @@ static int mark_to_gbmap[16] = {
INVALID_META, INVALID_META
};
-struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed)
+#define BITMAP_SIZE(size, cpb) (size / cpb)
+#define BITMAP_SIZE1(size) (size >> 3)
+#define BITMAP_SIZE4(size) (size >> 1)
+
+#define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \
+ * map->chunksize )
+
+/* BITMAP_BYTE_OFFSET1 is for chunksize==1, which implies chunks_per_byte==8 */
+/* Reducing the math, we get: */
+/* #define BITMAP_BYTE_OFFSET1(x) ((x % 8) * 1) */
+/* #define BITMAP_BYTE_OFFSET1(x) (x % 8) */
+/* #define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) */
+#define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007)
+
+/* BITMAP_BYTE_OFFSET4 is for chunksize==4, which implies chunks_per_byte==2 */
+/* Reducing the math, we get: */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x % 2) * 4) */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) * 4) */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) */
+#define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2)
+
+#define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1)
+/* BITMAP_MASK1 is for chunksize==1 */
+/* Reducing the math, we get: */
+/* #define BITMAP_MASK1(chunksize) ((2 << (1 - 1)) - 1) */
+/* #define BITMAP_MASK1(chunksize) ((2 << 0) - 1) */
+/* #define BITMAP_MASK1(chunksize) ((2) - 1) */
+#define BITMAP_MASK1(chunksize) (1)
+
+/* BITMAP_MASK4 is for chunksize==4 */
+/* #define BITMAP_MASK(chunksize) ((2 << (4 - 1)) - 1) */
+/* #define BITMAP_MASK(chunksize) ((2 << 3) - 1) */
+/* #define BITMAP_MASK(chunksize) (0x10 - 1) */
+#define BITMAP_MASK4(chunksize) (0xf)
+
+static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size,
+ uint8_t chunksize)
{
- struct gfs2_block_list *il;
+ if((((chunksize >> 1) << 1) != chunksize) && chunksize != 1)
+ return -1;
+ if(chunksize > 8)
+ return -1;
+ bmap->chunksize = chunksize;
+ bmap->chunks_per_byte = 8 / chunksize;
+
+ bmap->size = size;
+
+ /* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs
+ * must be 1-based */
+ bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1;
+
+ if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
+ return -ENOMEM;
+ if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
+ free(bmap->map);
+ bmap->map = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(offset < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(offset);
+ b = BITMAP_BYTE_OFFSET1(offset);
+ *byte |= (val & BITMAP_MASK1(bmap->chunksize));
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(bit < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(bit);
+ b = BITMAP_BYTE_OFFSET1(bit);
+ *val = (*byte & (BITMAP_MASK1(bmap->chunksize) << b )) >> b;
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(bit);
+ b = BITMAP_BYTE_OFFSET4(bit);
+ *val = (*byte & (BITMAP_MASK4(bmap->chunksize) << b )) >> b;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(offset < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(offset);
+ b = BITMAP_BYTE_OFFSET1(offset);
+ *byte &= ~(BITMAP_MASK1(bmap->chunksize) << b);
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte &= ~(BITMAP_MASK4(bmap->chunksize) << b);
+ }
+ return 0;
+ }
+ return -1;
+
+}
+
+static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap)
+{
+ if(bmap->map)
+ free(bmap->map);
+ bmap->size = 0;
+ bmap->mapsize = 0;
+ bmap->chunksize = 0;
+ bmap->chunks_per_byte = 0;
+}
+
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
+{
+ struct gfs2_bmap *il;
*addl_mem_needed = 0L;
il = malloc(sizeof(*il));
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
- *addl_mem_needed = il->list.gbmap.mapsize;
+ if(gfs2_bitmap_create(il, size, 4)) {
+ *addl_mem_needed = il->mapsize;
free(il);
il = NULL;
}
@@ -156,7 +287,7 @@ static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
}
}
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -166,13 +297,12 @@ 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, block,
- mark_to_gbmap[mark]);
+ err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]);
return err;
}
/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -186,25 +316,25 @@ 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, block);
+ err = gfs2_bitmap_clear(il, block);
break;
}
return err;
}
/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block)
{
int err = 0;
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(&il->list.gbmap, block);
+ err = gfs2_bitmap_clear(il, block);
return err;
}
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err;
@@ -215,7 +345,7 @@ int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
return err;
}
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val)
{
int err = 0;
@@ -226,15 +356,15 @@ 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, block, &val->block_type)))
+ if((err = gfs2_bitmap_get(il, block, &val->block_type)))
return err;
return 0;
}
-void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
{
if(il) {
- gfs2_bitmap_destroy(&il->list.gbmap);
+ gfs2_bitmap_destroy(il);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a9aeb2a..fc8af3f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -301,11 +301,6 @@ struct gfs2_bmap {
char *map;
};
-int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size, uint8_t bitsize);
-int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val);
-int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val);
-int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset);
-void gfs2_bitmap_destroy(struct gfs2_bmap *bmap);
uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap);
/* block_list.c */
@@ -354,35 +349,24 @@ struct gfs2_block_query {
uint8_t eattr_block;
};
-union gfs2_block_lists {
- struct gfs2_bmap gbmap;
-};
-
-/* bitmap implementation */
-struct gfs2_block_list {
- union gfs2_block_lists list;
-};
-
-struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed);
-struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
-void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
-void gfs2_special_free(struct special_blocks *blist);
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block mark);
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block mark);
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed);
+extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
+extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
+extern void gfs2_special_free(struct special_blocks *blist);
+extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block mark);
+extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block mark);
/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block m);
+extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block m);
/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block);
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, struct gfs2_block_query *val);
-void *gfs2_block_list_destroy(struct gfs2_sbd *sdp,
- struct gfs2_block_list *il);
+extern int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block);
+extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, struct gfs2_block_query *val);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
14 years, 1 month
cluster: RHEL56 - Eliminate bad_block linked block list
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 3f47f6f9b2dc9f8e1dbfc27158d6bc1f64ad5cac
Parent: 4fbd5fa224b6dbcf0998c4cb352a92c4b49f6cdc
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:32:56 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:43:00 2010 -0500
Eliminate bad_block linked block list
This patch eliminates the special linked list designated for bad
blocks in fsck.gfs2 in lieu of a bad block designation in the
block list bitmap.
rhbz#455300
---
gfs2/fsck/pass2.c | 6 +++---
gfs2/fsck/pass3.c | 2 +-
gfs2/fsck/pass4.c | 2 +-
gfs2/libgfs2/block_list.c | 13 +------------
gfs2/libgfs2/libgfs2.h | 7 ++-----
5 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 395ca2c..05e73b9 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -259,7 +259,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return -1;
}
/* Get the status of the directory inode */
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
@@ -604,7 +604,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
}
}
pass2_fxns.private = (void *) &ds;
- if(ds.q.bad_block) {
+ if(ds.q.block_type == gfs2_bad_block) {
/* First check that the directory's metatree is valid */
if(check_metatree(sysinode, &pass2_fxns)) {
stack;
@@ -764,7 +764,7 @@ int pass2(struct gfs2_sbd *sbp)
memset(&ds, 0, sizeof(ds));
pass2_fxns.private = (void *) &ds;
- if(ds.q.bad_block) {
+ if(ds.q.block_type == gfs2_bad_block) {
/* First check that the directory's metatree
* is valid */
ip = fsck_load_inode(sbp, i);
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 48f6135..bb71e47 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -230,7 +230,7 @@ int pass3(struct gfs2_sbd *sbp)
stack;
return FSCK_ERROR;
}
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
log_err( _("Found unlinked directory containing bad block\n"));
errors_found++;
if(query(&opts,
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index fd0ac0e..b5ea674 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -77,7 +77,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
stack;
return -1;
}
- if(q.bad_block) {
+ if(q.block_type == gfs2_bad_block) {
log_err( _("Unlinked inode %llu (0x%llx) contains"
"bad blocks\n"),
(unsigned long long)ii->inode,
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 5d1851b..c67c5a4 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -45,7 +45,6 @@ struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
free(il);
il = NULL;
}
- osi_list_init(&sdp->bad_blocks.list);
osi_list_init(&sdp->dup_blocks.list);
osi_list_init(&sdp->eattr_blocks.list);
return il;
@@ -162,9 +161,7 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
{
int err = 0;
- if(mark == gfs2_bad_block)
- gfs2_special_set(&sdp->bad_blocks, block);
- else if(mark == gfs2_dup_block)
+ if(mark == gfs2_dup_block)
gfs2_dup_set(&sdp->dup_blocks, block);
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
@@ -184,9 +181,6 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
case gfs2_dup_block:
gfs2_dup_clear(&sdp->dup_blocks, block);
break;
- case gfs2_bad_block:
- gfs2_special_clear(&sdp->bad_blocks, block);
- break;
case gfs2_eattr_block:
gfs2_special_clear(&sdp->eattr_blocks, block);
break;
@@ -205,7 +199,6 @@ int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
int err = 0;
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, block);
return err;
@@ -227,11 +220,8 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
{
int err = 0;
- val->bad_block = 0;
val->dup_block = 0;
val->eattr_block = 0;
- if (blockfind(&sdp->bad_blocks, block))
- val->bad_block = 1;
if (dupfind(&sdp->dup_blocks, block))
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
@@ -248,7 +238,6 @@ void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
free(il);
il = NULL;
}
- gfs2_special_free(&sdp->bad_blocks);
gfs2_dup_free(&sdp->dup_blocks);
gfs2_special_free(&sdp->eattr_blocks);
return il;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 70cf6cf..a9aeb2a 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -255,7 +255,6 @@ struct gfs2_sbd {
unsigned int writes;
int metafs_fd;
char metafs_path[PATH_MAX]; /* where metafs is mounted */
- struct special_blocks bad_blocks;
struct dup_blocks dup_blocks;
struct special_blocks eattr_blocks;
};
@@ -324,7 +323,7 @@ uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap);
#define JOURNAL_BLK (0xB) /* 1011 */
#define OTHER_META (0xC) /* 1100 */
#define EATTR_META (0xD) /* 1101 */
-#define UNUSED1 (0xE) /* 1110 */
+#define BAD_BLOCK (0xE) /* 1110 */
#define INVALID_META (0xF) /* 1111 */
/* Must be kept in sync with mark_to_bitmap array in block_list.c */
@@ -343,16 +342,14 @@ enum gfs2_mark_block {
gfs2_journal_blk = JOURNAL_BLK,
gfs2_meta_other = OTHER_META,
gfs2_meta_eattr = EATTR_META,
- gfs2_meta_unused = UNUSED1,
+ gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */
gfs2_meta_inval = INVALID_META,
- gfs2_bad_block, /* Contains at least one bad block */
gfs2_dup_block, /* Contains at least one duplicate block */
gfs2_eattr_block, /* Contains an eattr */
};
struct gfs2_block_query {
uint8_t block_type;
- uint8_t bad_block;
uint8_t dup_block;
uint8_t eattr_block;
};
14 years, 1 month
cluster: RHEL56 - Remove nvbuf_list and use fewer buffers
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4fbd5fa224b6dbcf0998c4cb352a92c4b49f6cdc
Parent: 2040434f74cb6cd43e3b7781c7f6c11d3adfaa2b
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Nov 25 14:31:51 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 22:40:25 2010 -0500
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 | 124 ++++++++++++++++++++++++++----------------
gfs2/edit/hexedit.c | 57 ++++++++++----------
gfs2/edit/savemeta.c | 33 +++++++++---
gfs2/fsck/fs_recovery.c | 1 -
gfs2/fsck/initialize.c | 5 +-
gfs2/fsck/main.c | 22 +++++++-
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 | 52 ++++++++++++++----
gfs2/libgfs2/fs_geometry.c | 19 +++----
gfs2/libgfs2/fs_ops.c | 82 +++++++++++++++++------------
gfs2/libgfs2/gfs1.c | 30 +++++++++--
gfs2/libgfs2/libgfs2.h | 103 ++++++++++++++++-------------------
gfs2/libgfs2/rgrp.c | 34 ++++--------
gfs2/libgfs2/structures.c | 76 +++-----------------------
gfs2/libgfs2/super.c | 34 +++++++++---
gfs2/mkfs/main_grow.c | 4 +-
gfs2/mkfs/main_mkfs.c | 4 +-
gfs2/tool/df.c | 1 -
22 files changed, 479 insertions(+), 382 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 48b4087..028913b 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -167,34 +167,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 */
@@ -205,38 +200,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 */
@@ -983,6 +989,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 */
@@ -996,8 +1004,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 */
@@ -1042,9 +1060,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;
}
@@ -1054,7 +1072,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);
@@ -1379,8 +1398,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 */
compute_constants(sbp);
bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
@@ -1596,6 +1614,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;
@@ -1606,12 +1626,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);
@@ -1635,11 +1655,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 */
@@ -1650,19 +1670,31 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
while (rgd->ri.ri_data & 0x03)
rgd->ri.ri_data--;
sdp->blks_total += rgd->ri.ri_data; /* For statfs file update */
- rgd->rg.rg_free = rgd->ri.ri_data;
+ rg.rg_free = rgd->ri.ri_data;
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 */
@@ -1803,7 +1835,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. */
@@ -1870,10 +1902,9 @@ 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 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 */
@@ -1887,7 +1918,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 99b42bf..d6fb7fe 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -580,10 +580,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)
@@ -801,7 +800,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);
}
@@ -1004,7 +1003,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);
@@ -1707,7 +1706,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);
@@ -1726,8 +1725,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 &&
@@ -1760,7 +1758,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);
@@ -1770,7 +1769,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);*/
}
}
@@ -2040,7 +2040,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
else
printf("%llu\n", (unsigned long long)blk);
}
- gfs2_rgrp_free(&sbd.rglist, not_updated);
+ gfs2_rgrp_free(&sbd.rglist);
if (print)
exit(0);
return blk;
@@ -2079,7 +2079,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);
}
@@ -2105,7 +2105,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;
@@ -2139,7 +2139,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;
@@ -2448,7 +2448,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);
}
@@ -2491,7 +2491,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);
}
@@ -2512,7 +2512,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;
@@ -2529,17 +2529,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);
}
@@ -3343,7 +3342,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])) {
@@ -3353,11 +3352,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")) {
@@ -3389,7 +3388,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')
@@ -3406,7 +3405,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;
@@ -3415,7 +3414,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]);
@@ -3424,7 +3423,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);
}
}
@@ -3536,6 +3535,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 1983ba3..8959442 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -449,12 +449,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 "
@@ -469,9 +471,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;
@@ -493,6 +497,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;
@@ -522,8 +528,7 @@ void savemeta(char *out_fn, int saveoption)
device_geometry(&sbd);
fix_device_geometry(&sbd);
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;
compute_constants(&sbd);
@@ -617,7 +622,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 %"PRIu64" is %u long\n",
@@ -639,7 +653,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);
@@ -650,13 +665,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 a225eb1..3225c26 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -589,6 +589,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 a12deed..67fa1fb 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -303,9 +303,8 @@ 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);
- for(i = 0; i < BUF_HASH_SIZE; i++) {
+ 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 718aa8f..56ac943 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -276,10 +276,12 @@ void check_statfs(struct gfs2_sbd *sdp)
{
osi_list_t *tmp;
struct rgrp_list *rgd;
+ struct gfs2_rgrp rg;
struct gfs2_rindex *ri;
struct gfs2_statfs_change sc;
char buf[sizeof(struct gfs2_statfs_change)];
int count;
+ struct gfs2_buffer_head **rgbh;
/* Read the current statfs values */
count = gfs2_readi(sdp->md.statfs, buf, 0,
@@ -295,9 +297,24 @@ void check_statfs(struct gfs2_sbd *sdp)
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
ri = &rgd->ri;
+ if(!(rgbh = (struct gfs2_buffer_head **)
+ malloc(rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *)))) {
+ log_err( _("Error: can't allocate memory to check statfs.\n"));
+ return;
+ }
+ if(!memset(rgbh, 0, rgd->ri.ri_length *
+ sizeof(struct gfs2_buffer_head *))) {
+ free(rgbh);
+ log_err( _("Error: can't allocate memory to check statfs.\n"));
+ return;
+ }
+ gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
sdp->blks_total += ri->ri_data;
- sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
- sdp->dinodes_alloced += rgd->rg.rg_dinodes;
+ sdp->blks_alloced += (ri->ri_data - rg.rg_free);
+ sdp->dinodes_alloced += rg.rg_dinodes;
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
+ free(rgbh);
}
/* See if they match */
@@ -482,7 +499,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 a23da46..f011c64 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -995,6 +995,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,
@@ -1017,8 +1019,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"),
@@ -1029,6 +1041,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;
}
}
@@ -1039,11 +1052,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) {
@@ -1056,13 +1070,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 a533536..98cdeef 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -166,7 +166,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;
@@ -177,26 +178,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]) {
@@ -212,7 +213,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"));
@@ -229,9 +230,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){
@@ -241,16 +244,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 9d28b1a..cc5b2ca 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -142,7 +142,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)) {
@@ -220,7 +220,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. */
@@ -254,7 +254,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);
@@ -265,13 +265,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) {
@@ -386,37 +379,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;
@@ -437,6 +431,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;
@@ -445,7 +440,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;
}
}
@@ -454,18 +449,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,
@@ -473,8 +468,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;
}
/* ------------------------------------------------------------- */
@@ -505,8 +500,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;
}
/* ------------------------------------------------------------- */
@@ -546,8 +541,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);
}
@@ -567,28 +560,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 b0d7000..5d1851b 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -40,8 +40,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;
}
@@ -169,7 +169,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;
}
@@ -192,7 +192,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;
@@ -207,7 +207,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;
}
@@ -236,8 +236,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;
}
@@ -245,7 +244,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 6c7e181..48b1f5c 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -44,6 +44,10 @@ static void write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
do_write(sdp->device_fd, bh->b_data, sdp->bsize);
sdp->writes++;
}
+ bh->b_blocknr = -1;
+ bh->b_data = NULL;
+ bh->b_count = -1;
+ bh->b_changed = -1;
free(bh);
}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index b295261..2183aa5 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "libgfs2.h"
@@ -171,6 +172,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))
@@ -181,8 +184,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]);
@@ -190,7 +205,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;
@@ -198,12 +213,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
*
@@ -220,12 +236,15 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
struct rgrp_list *rgd)
{
- int buf, val;
+ int i, val;
uint32_t rgrp_block;
struct gfs2_bitmap *bits = NULL;
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;
@@ -235,30 +254,39 @@ 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);
- for(buf= 0; buf < rgd->ri.ri_length; buf++){
- bits = &(rgd->bits[buf]);
+ for(i= 0; i < rgd->ri.ri_length; i++){
+ bits = &(rgd->bits[i]);
if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){
break;
}
}
- if(buf >= rgd->ri.ri_length){
- gfs2_rgrp_relse(rgd, not_updated);
+ if(i >= rgd->ri.ri_length){
+ gfs2_rgrp_relse(rgd, not_updated, rgbh);
return -1;
}
- byte = (unsigned char *)(rgd->bh[buf]->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 0ad7df4..86e50f9 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -120,7 +120,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%"
@@ -191,7 +190,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;
@@ -205,7 +204,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);
@@ -216,19 +214,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 7dacd43..4b13d5c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -55,16 +55,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;
}
@@ -72,31 +73,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:
@@ -105,24 +118,25 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
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;
}
@@ -927,7 +941,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;
@@ -1563,13 +1577,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 */
sdp->blks_alloced--;
}
@@ -1588,6 +1605,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]);
@@ -1616,11 +1634,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);
}
@@ -1634,13 +1649,12 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
sdp->blks_alloced--;
/* 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 */
sdp->dinodes_alloced--;
return 0;
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index f9e5a6e..e783fdd 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 ffd673c..70cf6cf 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -103,12 +103,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;
- gfs2_bitmap_t *bits;
- struct gfs2_buffer_head **bh;
+ struct gfs2_bitmap *bits;
};
struct gfs2_buffer_head {
@@ -250,7 +248,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;
@@ -360,15 +357,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 */
@@ -571,20 +561,19 @@ struct gfs_dinode {
char di_reserved[56];
};
-void gfs1_lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
- unsigned int height, struct metapath *mp,
- int create, int *new, uint64_t *block);
-void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
- uint64_t *dblock, uint32_t *extlen, int prealloc);
-int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
- unsigned int size);
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
-struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
- struct gfs2_buffer_head *bh);
-
-/* locking.c */
-void test_locking(char *lockproto, char *locktable);
+extern void gfs1_lookup_block(struct gfs2_inode *ip,
+ struct gfs2_buffer_head *bh,
+ unsigned int height, struct metapath *mp,
+ int create, int *new, uint64_t *block);
+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,
+ 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);
/* gfs2_log.c */
struct gfs2_options {
@@ -696,38 +685,40 @@ int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head);
int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
/* rgrp.c */
-int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated);
-void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags updated);
+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,
+ 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 */
-void build_master(struct gfs2_sbd *sdp);
-void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
-void build_jindex(struct gfs2_sbd *sdp);
-void build_per_node(struct gfs2_sbd *sdp);
-void build_inum(struct gfs2_sbd *sdp);
-void build_statfs(struct gfs2_sbd *sdp);
-void build_rindex(struct gfs2_sbd *sdp);
-void build_quota(struct gfs2_sbd *sdp);
-void build_root(struct gfs2_sbd *sdp);
-void do_init_inum(struct gfs2_sbd *sdp);
-void do_init_statfs(struct gfs2_sbd *sdp);
-int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
-int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format);
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
-int gfs2_next_rg_meta_free(struct rgrp_list *rgd, uint64_t *block, int first,
- int *mfree);
-int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
- uint64_t *block, uint32_t type, int first);
+extern void build_master(struct gfs2_sbd *sdp);
+extern void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
+extern void build_jindex(struct gfs2_sbd *sdp);
+extern void build_per_node(struct gfs2_sbd *sdp);
+extern void build_inum(struct gfs2_sbd *sdp);
+extern void build_statfs(struct gfs2_sbd *sdp);
+extern void build_rindex(struct gfs2_sbd *sdp);
+extern void build_quota(struct gfs2_sbd *sdp);
+extern void build_root(struct gfs2_sbd *sdp);
+extern void do_init_inum(struct gfs2_sbd *sdp);
+extern void 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 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 */
-int check_sb(struct gfs2_sb *sb);
-int read_sb(struct gfs2_sbd *sdp);
-int ji_update(struct gfs2_sbd *sdp);
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
-int write_sb(struct gfs2_sbd *sdp);
+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,
+ int *bitmap_blocks);
+extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
+extern int write_sb(struct gfs2_sbd *sdp);
/* ondisk.c */
uint32_t gfs2_disk_hash(const char *data, int len);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 7bebb3f..9027909 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -85,14 +85,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;
}
@@ -127,51 +119,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 43a7e0f..2b63ad2 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -475,12 +475,14 @@ int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format)
*
* Returns: 0 on success, -1 when finished
*/
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct 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");
@@ -494,14 +496,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;
@@ -509,71 +514,6 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
}
/**
- * gfs2_next_rg_meta_free - finds free or used metadata
- * @rgd:
- * @block:
- * @first: if set, start at zero and ignore block
- *
- * The position to start looking from is *block. When a block
- * is found, it is returned in block.
- *
- * Returns: 0 on success, -1 when finished
- */
-int gfs2_next_rg_meta_free(struct rgrp_list *rgd, uint64_t *block, int first,
- int *mfree)
-{
- gfs2_bitmap_t *bits = NULL;
- uint32_t length = rgd->ri.ri_length;
- uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0);
- uint32_t iblk, ublk, fblk;
- int i;
-
- if(!first && (*block < rgd->ri.ri_data0)) {
- log_err("next_rg_meta_free: Start block is outside rgrp bounds.\n");
- exit(1);
- }
- for(i=0; i < length; i++){
- bits = &rgd->bits[i];
- if(blk < bits->bi_len*GFS2_NBBY)
- break;
- blk -= bits->bi_len*GFS2_NBBY;
- }
- for(; i < length; i++){
- bits = &rgd->bits[i];
-
- iblk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
- bits->bi_offset, bits->bi_len, blk,
- GFS2_BLKST_DINODE);
- ublk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
- bits->bi_offset, bits->bi_len, blk,
- GFS2_BLKST_USED);
- fblk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
- bits->bi_offset, bits->bi_len, blk,
- GFS2_BLKST_FREE);
- if(ublk < fblk) {
- blk = ublk;
- *mfree = 0;
- }
- else if(iblk < fblk) {
- blk = iblk;
- *mfree = 0;
- } else {
- blk = fblk;
- *mfree = 1;
- }
- if(blk != BFITNOENT){
- *block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
- break;
- }
- blk=0;
- }
-
- if(i == length)
- return -1;
- return 0;
-}
-
-/**
* next_rg_metatype
* @rgd:
* @block:
@@ -590,7 +530,7 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
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 9a42021..e31268e 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -175,7 +175,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;
@@ -185,6 +185,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));
@@ -207,6 +208,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;
@@ -241,19 +244,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++;
}
@@ -261,10 +278,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;
}
@@ -276,7 +295,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 879f399..60082a9 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -187,7 +187,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);
}
/**
@@ -286,8 +285,7 @@ main_grow(int argc, char *argv[])
device_geometry(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);
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 9eb4761..67b552b 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -437,8 +437,7 @@ 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 */
@@ -509,7 +508,6 @@ 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)
diff --git a/gfs2/tool/df.c b/gfs2/tool/df.c
index 3dbfd46..025fc85 100644
--- a/gfs2/tool/df.c
+++ b/gfs2/tool/df.c
@@ -113,7 +113,6 @@ do_df_one(char *path)
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
osi_list_init(&sbd.rglist);
init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
- init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
do_lseek(sbd.device_fd, 0x10 * sbd.bsize);
do_read(sbd.device_fd, buf, sbd.bsize); /* read in the superblock */
14 years, 1 month