cluster: RHEL56 - libgfs2: fs_bits speed up bitmap operations
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 7d8b8ae7f3f3a425c11b58def216d45881e36ac9
Parent: 9b487b83bb443ab2f55e39d2f81f26e67b6ad791
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 08:50:05 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:33:16 2010 -0500
libgfs2: fs_bits speed up bitmap operations
This patch incorporates a faster set of bitmap operations once
used by the kernel code and currently used by GFS1.
rhbz#455300
---
gfs2/libgfs2/fs_bits.c | 75 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index e8e601b..aae2958 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -18,6 +18,18 @@
#include "libgfs2.h"
+#if BITS_PER_LONG == 32
+#define LBITMASK (0x55555555UL)
+#define LBITSKIP55 (0x55555555UL)
+#define LBITSKIP00 (0x00000000UL)
+#else
+#define LBITMASK (0x5555555555555555UL)
+#define LBITSKIP55 (0x5555555555555555UL)
+#define LBITSKIP00 (0x0000000000000000UL)
+#endif
+
+#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
+
/**
* gfs2_bitfit - Find a free block in the bitmaps
* @buffer: the buffer that holds the bitmaps
@@ -30,32 +42,55 @@
uint32_t gfs2_bitfit(unsigned char *buffer, unsigned int buflen,
uint32_t goal, unsigned char old_state)
{
- unsigned char *byte, *end, alloc;
- uint32_t blk = goal;
- unsigned int bit;
-
- byte = buffer + (goal / GFS2_NBBY);
- bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
- end = buffer + buflen;
- alloc = (old_state & 1) ? 0 : 0x55;
-
- while (byte < end){
- if ((*byte & 0x55) == alloc){
- blk += (8 - bit) >> 1;
- bit = 0;
- byte++;
- continue;
+ const uint8_t *byte, *start, *end;
+ int bit, startbit;
+ uint32_t g1, g2, misaligned;
+ unsigned long *plong;
+ unsigned long lskipval;
+
+ lskipval = (old_state & GFS2_BLKST_USED) ? LBITSKIP00 : LBITSKIP55;
+ g1 = (goal / GFS2_NBBY);
+ start = buffer + g1;
+ byte = start;
+ end = buffer + buflen;
+ g2 = ALIGN(g1, sizeof(unsigned long));
+ plong = (unsigned long *)(buffer + g2);
+ startbit = bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
+ misaligned = g2 - g1;
+ if (!misaligned)
+ goto ulong_aligned;
+/* parse the bitmap a byte at a time */
+misaligned:
+ while (byte < end) {
+ if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) {
+ return goal +
+ (((byte - start) * GFS2_NBBY) +
+ ((bit - startbit) >> 1));
}
-
- if (((*byte >> bit) & GFS2_BIT_MASK) == old_state)
- return blk;
-
bit += GFS2_BIT_SIZE;
- if (bit >= 8){
+ if (bit >= GFS2_NBBY * GFS2_BIT_SIZE) {
bit = 0;
byte++;
+ misaligned--;
+ if (!misaligned) {
+ plong = (unsigned long *)byte;
+ goto ulong_aligned;
+ }
}
- blk++;
+ }
+ return BFITNOENT;
+
+/* parse the bitmap a unsigned long at a time */
+ulong_aligned:
+ while ((unsigned char *)plong < end) {
+ if (((*plong) & LBITMASK) != lskipval)
+ break;
+ plong++;
+ }
+ if ((unsigned char *)plong < end) {
+ byte = (const uint8_t *)plong;
+ misaligned += sizeof(unsigned long) - 1;
+ goto misaligned;
}
return BFITNOENT;
}
14 years, 1 month
cluster: RHEL56 - gfs2: libgfs2 and fsck.gfs2 cleanups
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 9b487b83bb443ab2f55e39d2f81f26e67b6ad791
Parent: 8d3521017ebe5e9b8d8e190f1b33af601b461972
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Jan 20 15:46:50 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:30:18 2010 -0500
gfs2: libgfs2 and fsck.gfs2 cleanups
This patch is big, but mostly cosmetic. There are a few places
where I found and fixed a bug with the previous patches. However,
by and large, this patch is comprised of (1) comment changes,
(2) code reformatting for readability, (3) variable renames to
aid in readability, (4) code restructuring for efficiency, as in
the case where I got rid of useless function scan_meta and just
inlined it, (5) improved error messages given to aid in debugging.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 5 +-
gfs2/edit/gfs2hex.c | 3 +-
gfs2/edit/hexedit.c | 2 +-
gfs2/edit/savemeta.c | 21 +++++-
gfs2/fsck/eattr.c | 8 +--
gfs2/fsck/fsck.h | 28 ++++----
gfs2/fsck/lost_n_found.c | 56 +++++-----------
gfs2/fsck/metawalk.c | 48 +++++++-------
gfs2/fsck/metawalk.h | 50 ++++++++------
gfs2/fsck/pass1.c | 97 ++++++++++++---------------
gfs2/fsck/pass1b.c | 33 +++++----
gfs2/fsck/pass1c.c | 1 -
gfs2/fsck/pass2.c | 157 +++++++++++++++++++++++--------------------
gfs2/fsck/pass3.c | 13 ++--
gfs2/fsck/pass4.c | 21 +++---
gfs2/fsck/pass5.c | 8 +-
gfs2/fsck/rgrepair.c | 10 ++--
gfs2/fsck/util.c | 4 +-
gfs2/libgfs2/block_list.c | 1 -
gfs2/libgfs2/buf.c | 4 +-
gfs2/libgfs2/fs_ops.c | 78 ++++++++++-----------
gfs2/libgfs2/gfs2_log.c | 6 +--
gfs2/libgfs2/libgfs2.h | 5 +-
gfs2/libgfs2/super.c | 2 +-
24 files changed, 328 insertions(+), 333 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index d05eff5..fac5fec 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -340,8 +340,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
if (amount > sbp->bsize - hdrsize - ptramt)
amount = sbp->bsize - hdrsize - ptramt;
- memcpy(bh->b_data + hdrsize + ptramt,
- (char *)srcptr, amount);
+ memcpy(bh->b_data + hdrsize + ptramt, (char *)srcptr, amount);
srcptr += amount;
bmodified(bh);
if (bh != ip->i_bh)
@@ -1074,7 +1073,7 @@ static int fetch_inum(struct gfs2_sbd *sbp, uint64_t iblock,
/* Returns: 0 on success, -1 on failure */
/* ------------------------------------------------------------------------- */
static int process_dirent_info(struct gfs2_inode *dip, struct gfs2_sbd *sbp,
- struct gfs2_buffer_head *bh, int dir_entries)
+ struct gfs2_buffer_head *bh, int dir_entries)
{
int error;
struct gfs2_dirent *dent;
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index ef76f58..2934877 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -484,7 +484,8 @@ static void do_eattr_extended(struct gfs2_buffer_head *ebh)
print_gfs2("Eattr Entries:");
eol(0);
- for (x = sizeof(struct gfs2_meta_header); x < sbd.bsize; x += ea.ea_rec_len)
+ for (x = sizeof(struct gfs2_meta_header); x < sbd.bsize;
+ x += ea.ea_rec_len)
{
eol(0);
gfs2_ea_header_in(&ea, ebh->b_data + x);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 4d3d77c..643fdb5 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -3056,7 +3056,7 @@ static void dump_journal(const char *journal)
abs_block = jblock + jb;
dummy_bh.b_data = j_bh->b_data;
} else {
- error = fsck_readi(j_inode, (void *)&jbuf, jb,
+ error = fsck_readi(j_inode, (void *)jbuf, jb,
sbd.bsize, &abs_block);
if (!error) /* end of file */
break;
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 77ec485..554a3da 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -820,8 +820,25 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
"device; quitting.\n");
break;
}
- do_lseek(fd, savedata->blk * sbd.bsize);
- do_write(fd, savedata->buf, sbd.bsize);
+ if (lseek(fd, savedata->blk * sbd.bsize, SEEK_SET) !=
+ savedata->blk * sbd.bsize) {
+ fprintf(stderr, "bad seek: %s from %s:"
+ "%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__,
+ __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
+ if (write(fd, savedata->buf, sbd.bsize) != sbd.bsize) {
+ fprintf(stderr, "write error: %s from "
+ "%s:%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__,
+ __LINE__,
+ (unsigned long long)savedata->blk,
+ (unsigned long long)savedata->blk);
+ exit(-1);
+ }
writes++;
}
blks_saved++;
diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index cc9fec4..fb84854 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -54,17 +54,12 @@ int clear_eattr_entry (struct gfs2_inode *ip,
void *private)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- char ea_name[256];
if(!ea_hdr->ea_name_len){
/* Skip this entry for now */
return 1;
}
- memset(ea_name, 0, sizeof(ea_name));
- strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
- ea_hdr->ea_name_len);
-
if(!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
/* Skip invalid entry */
@@ -83,8 +78,7 @@ int clear_eattr_entry (struct gfs2_inode *ip,
} else {
log_debug( _(" Pointers Required: %d\n"
" Pointers Reported: %d\n"),
- max_ptrs,
- ea_hdr->ea_num_ptrs);
+ max_ptrs, ea_hdr->ea_num_ptrs);
}
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 2510ecb..5594548 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -73,7 +73,7 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
struct dup_blks {
osi_list_t list;
- uint64_t block_no;
+ uint64_t block;
osi_list_t ref_inode_list;
};
@@ -82,19 +82,21 @@ extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
extern void fsck_inode_put(struct gfs2_inode **ip);
-int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
- int *all_clean);
-void destroy(struct gfs2_sbd *sbp);
-int pass1(struct gfs2_sbd *sbp);
-int pass1b(struct gfs2_sbd *sbp);
-int pass1c(struct gfs2_sbd *sbp);
-int pass2(struct gfs2_sbd *sbp);
-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, ...)
+extern int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
+ int *all_clean);
+extern void destroy(struct gfs2_sbd *sbp);
+extern int pass1(struct gfs2_sbd *sbp);
+extern int pass1b(struct gfs2_sbd *sbp);
+extern int pass1c(struct gfs2_sbd *sbp);
+extern int pass2(struct gfs2_sbd *sbp);
+extern int pass3(struct gfs2_sbd *sbp);
+extern int pass4(struct gfs2_sbd *sbp);
+extern int pass5(struct gfs2_sbd *sbp);
+extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count);
+extern int fsck_query(const char *format, ...)
__attribute__((format(printf,1,2)));
+extern struct dir_info *dirtree_find(uint64_t block);
+extern void dirtree_delete(struct dir_info *b);
/* FIXME: Hack to get this going for pass2 - this should be pulled out
* of pass1 and put somewhere else... */
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 5fa5ce4..0e55724 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -38,8 +38,6 @@
*/
int add_inode_to_lf(struct gfs2_inode *ip){
char tmp_name[256];
- char *filename;
- int filename_len;
__be32 inode_type;
if(!lf_dip) {
@@ -47,7 +45,8 @@ int add_inode_to_lf(struct gfs2_inode *ip){
log_info( _("Locating/Creating lost and found directory\n"));
- lf_dip = createi(ip->i_sbd->md.rooti, "lost+found", S_IFDIR | 0700, 0);
+ lf_dip = createi(ip->i_sbd->md.rooti, "lost+found",
+ S_IFDIR | 0700, 0);
q = block_type(lf_dip->i_di.di_num.no_addr);
if(q != gfs2_inode_dir) {
/* This is a new lost+found directory, so set its
@@ -72,29 +71,18 @@ int add_inode_to_lf(struct gfs2_inode *ip){
}
switch(ip->i_di.di_mode & S_IFMT){
case S_IFDIR:
- log_info( _("Adding .. entry pointing to lost+found for %llu\n"),
- (unsigned long long)ip->i_di.di_num.no_addr);
- sprintf(tmp_name, "..");
- filename_len = strlen(tmp_name); /* no trailing NULL */
- if(!(filename = malloc((sizeof(char) * filename_len) + 1))) {
- log_err( _("Unable to allocate name\n"));
- stack;
- return -1;
- }
- if(!memset(filename, 0, (sizeof(char) * filename_len) + 1)) {
- log_err( _("Unable to zero name\n"));
- stack;
- return -1;
- }
- memcpy(filename, tmp_name, filename_len);
+ log_info( _("Adding .. entry pointing to lost+found for "
+ "directory %llu (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
- if(gfs2_dirent_del(ip, filename, filename_len))
- log_warn( _("add_inode_to_lf: "
- "Unable to remove \"..\" directory entry.\n"));
+ if(gfs2_dirent_del(ip, "..", 2))
+ log_warn( _("add_inode_to_lf: Unable to remove "
+ "\"..\" directory entry.\n"));
- dir_add(ip, filename, filename_len, &(lf_dip->i_di.di_num), DT_DIR);
- free(filename);
- sprintf(tmp_name, "lost_dir_%llu", ip->i_di.di_num.no_addr);
+ dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), DT_DIR);
+ sprintf(tmp_name, "lost_dir_%llu",
+ (unsigned long long)ip->i_di.di_num.no_addr);
inode_type = DT_DIR;
break;
case S_IFREG:
@@ -126,26 +114,14 @@ int add_inode_to_lf(struct gfs2_inode *ip){
inode_type = DT_REG;
break;
}
- filename_len = strlen(tmp_name); /* no trailing NULL */
- if(!(filename = malloc(sizeof(char) * filename_len))) {
- log_err( _("Unable to allocate name\n"));
- stack;
- return -1;
- }
- if(!memset(filename, 0, sizeof(char) * filename_len)) {
- log_err( _("Unable to zero name\n"));
- stack;
- return -1;
- }
- memcpy(filename, tmp_name, filename_len);
- dir_add(lf_dip, filename, filename_len, &(ip->i_di.di_num), inode_type);
- increment_link(ip->i_sbd, ip->i_di.di_num.no_addr);
+ dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num),
+ inode_type);
+ increment_link(ip->i_sbd, ip->i_di.di_num.no_addr);
if(S_ISDIR(ip->i_di.di_mode))
increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
- free(filename);
log_notice( _("Added inode #%llu to lost+found dir\n"),
- (unsigned long long)ip->i_di.di_num.no_addr);
+ (unsigned long long)ip->i_di.di_num.no_addr);
return 0;
}
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 1a701e1..b547f44 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -37,7 +37,7 @@ struct dup_blks *dupfind(uint64_t num)
for (tmp = head->next; tmp != head; tmp = tmp->next) {
b = osi_list_entry(tmp, struct dup_blks, list);
- if (b->block_no == num)
+ if (b->block == num)
return b;
}
return NULL;
@@ -293,8 +293,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
bmodified(bh);
/* Mark dirent buffer as modified */
first = 0;
- }
- else {
+ } else {
error = pass->check_dentry(ip, dent, prev, bh,
filename, count,
pass->private);
@@ -306,7 +305,12 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
}
if ((char *)dent + de.de_rec_len >= bh_end){
- log_debug( _("Last entry processed.\n"));
+ log_debug( _("Last entry processed for %lld->%lld "
+ "(0x%llx->0x%llx).\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)bh->b_blocknr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)bh->b_blocknr);
break;
}
@@ -399,8 +403,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
leaf info */
ref_count++;
continue;
- }
- else if(old_leaf == leaf_no) {
+ } else if(old_leaf == leaf_no) {
ref_count++;
continue;
}
@@ -502,11 +505,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
break;
}
exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth));
- log_debug( _("expected count %u - di_depth %u, leaf depth %u\n"),
- exp_count, ip->i_di.di_depth, leaf.lf_depth);
+ /*log_debug( _("expected count %u - di_depth %u,
+ leaf depth %u\n"),
+ exp_count, ip->i_di.di_depth, leaf.lf_depth);*/
- if(pass->check_dentry &&
- S_ISDIR(ip->i_di.di_mode)) {
+ if(pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) {
error = check_entries(ip, lbh, DIR_EXHASH,
&count, pass);
@@ -572,9 +575,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
int error = 0;
uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header);
- if(!pass->check_eattr_entry) {
+ if(!pass->check_eattr_entry)
return 0;
- }
ea_hdr = (struct gfs2_ea_header *)(bh->b_data +
sizeof(struct gfs2_meta_header));
@@ -773,7 +775,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
pass->private);
}
if (leaf_pointer_errors == leaf_pointers) {
- if (indirect_buf->b_changed)
+ if (indirect_buf->b_modified)
gfs2_set_bitmap(sdp, indirect,
GFS2_BLKST_FREE);
gfs2_blockmap_set(sdp, bl, indirect,
@@ -806,8 +808,7 @@ int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)ip->i_di.di_num.no_addr);
if(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT){
- if((error = check_indirect_eattr(ip, ip->i_di.di_eattr,
- pass)))
+ if((error = check_indirect_eattr(ip, ip->i_di.di_eattr, pass)))
stack;
} else {
error = check_leaf_eattr(ip, ip->i_di.di_eattr,
@@ -821,12 +822,13 @@ int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass)
/**
* build_and_check_metalist - check a bunch of indirect blocks
- * Note: Every buffer put on the metalist should be "held".
+ * This includes hash table blocks for directories
+ * which are technically "data" in the bitmap.
+ *
* @ip:
* @mlp:
*/
-static int build_and_check_metalist(struct gfs2_inode *ip,
- osi_list_t *mlp,
+static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
struct metawalk_fxns *pass)
{
uint32_t height = ip->i_di.di_height;
@@ -841,7 +843,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
/* if(<there are no indirect blocks to check>) */
if (height < 2)
return 0;
- for (i = 1; i < height; i++){
+ for (i = 1; i < height; i++) {
prev_list = &mlp[i - 1];
cur_list = &mlp[i];
@@ -860,7 +862,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
continue;
head_size = sizeof(struct gfs2_dinode);
}
-
+ /* Now check the metadata itself */
for (ptr = (uint64_t *)(bh->b_data + head_size);
(char *)ptr < (bh->b_data + ip->i_sbd->bsize);
ptr++) {
@@ -994,7 +996,6 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
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. "
@@ -1036,8 +1037,8 @@ end:
}
/* Checks stuffed inode directories */
-static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
- struct metawalk_fxns *pass)
+int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
+ struct metawalk_fxns *pass)
{
int error = 0;
uint16_t count = 0;
@@ -1051,7 +1052,6 @@ static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
return error;
}
-
int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass)
{
struct gfs2_inode *ip;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 0744ae6..1c1a646 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -18,26 +18,33 @@
struct metawalk_fxns;
-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);
-int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
- uint64_t dentryblock);
-int find_di(struct gfs2_sbd *sbp, uint64_t childblock, struct dir_info **dip);
-int dinode_hash_insert(osi_list_t *buckets, uint64_t key, struct dir_info *di);
-int dinode_hash_remove(osi_list_t *buckets, uint64_t key);
-int delete_blocks(struct gfs2_inode *ip, uint64_t block,
- struct gfs2_buffer_head **bh, const char *btype,
- void *private);
-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, void *private);
-int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
- struct gfs2_buffer_head **bh, void *private);
-struct dup_blks *dupfind(uint64_t num);
+extern int check_inode_eattr(struct gfs2_inode *ip,
+ struct metawalk_fxns *pass);
+extern int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass);
+extern int check_dir(struct gfs2_sbd *sbp, uint64_t block,
+ struct metawalk_fxns *pass);
+extern int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
+ struct metawalk_fxns *pass);
+extern int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
+ uint64_t dentryblock);
+extern int find_di(struct gfs2_sbd *sbp, uint64_t childblock,
+ struct dir_info **dip);
+extern int dinode_hash_insert(osi_list_t *buckets, uint64_t key,
+ struct dir_info *di);
+extern int dinode_hash_remove(osi_list_t *buckets, uint64_t key);
+extern int delete_blocks(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, const char *btype,
+ void *private);
+extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
+ struct gfs2_buffer_head **bh, void *private);
+extern int delete_data(struct gfs2_inode *ip, uint64_t block, void *private);
+extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block,
+ uint64_t parent, struct gfs2_buffer_head **bh,
+ void *private);
+extern int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
+ uint64_t parent, struct gfs2_buffer_head **bh,
+ void *private);
+extern struct dup_blks *dupfind(uint64_t num);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
@@ -86,8 +93,7 @@ struct metawalk_fxns {
struct gfs2_ea_header *ea_hdr_prev,
void *private);
int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
- int leaf_pointer_errors,
- void *private);
+ int leaf_pointer_errors, void *private);
};
#endif /* _METAWALK_H */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 40d316e..961a59c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -87,8 +87,11 @@ static int leaf(struct gfs2_inode *ip, uint64_t block,
{
struct block_count *bc = (struct block_count *) private;
- log_debug( _("\tLeaf block at %15" PRIu64 " (0x%" PRIx64 ")\n"),
- block, block);
+ log_debug( _("\tDinode %lld (0x%llx) references leaf block #%lld "
+ "(0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)block, (unsigned long long)block);
gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_leaf_blk);
bc->indir_count++;
return 0;
@@ -162,7 +165,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
return 1;
}
q = block_type(block);
- if(q != gfs2_block_free) {
+ if (q != gfs2_block_free) {
log_err( _("Found duplicate block referenced as data at %"
PRIu64 " (0x%"PRIx64 ")\n"), block, block);
if (q != gfs2_meta_inval) {
@@ -248,8 +251,7 @@ 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);
- if (query( _("Clear all Extended Attributes from the "
- "inode? (y/n) "))) {
+ if (query( _("Clear all Extended Attributes from the inode? (y/n) "))){
if (!remove_inode_eattr(ip, bc,
is_duplicate(ip->i_di.di_eattr)))
log_err( _("Extended attributes were removed.\n"));
@@ -799,14 +801,14 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
}
pass1_fxns.private = &bc;
-
error = check_metatree(ip, &pass1_fxns);
if (fsck_abort || error < 0) {
fsck_inode_put(&ip);
return 0;
}
- if(error > 0) {
- log_warn( _("Marking inode #%llu (0x%llx) invalid\n"),
+ if (error > 0) {
+ log_err( _("Error: inode %llu (0x%llx) has unrecoverable "
+ "errors; invalidating.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
/* FIXME: Must set all leaves invalid as well */
@@ -843,7 +845,9 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
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);
+ log_err( _("Block count for #%llu (0x%llx) fixed\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
} else
log_err( _("Bad block count for #%llu (0x%llx"
") not fixed\n"),
@@ -855,46 +859,6 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
return 0;
}
-static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
- uint64_t block)
-{
- if (gfs2_check_meta(bh, 0)) {
- log_info( _("Found invalid metadata at #%llu (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
- stack;
- return -1;
- }
- 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 {
- log_err( _("The invalid block was ignored.\n"));
- }
- return 0;
- }
-
- log_debug( _("Checking metadata block #%" PRIu64 " (0x%" PRIx64 ")\n"), block,
- block);
-
- if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
- /* handle_di calls inode_get, then inode_put, which does brelse. */
- /* In order to prevent brelse from getting the count off, hold it. */
- if(handle_di(sdp, bh, block)) {
- stack;
- return -1;
- }
- }
- /* Ignore everything else - they should be hit by the handle_di step.
- * Don't check NONE either, because check_meta passes everything if
- * GFS2_METATYPE_NONE is specified.
- * Hopefully, other metadata types such as indirect blocks will be
- * handled when the inode itself is processed, and if it's not, it
- * should be caught in pass5. */
- return 0;
-}
-
/**
* pass1 - walk through inodes and check inode state
*
@@ -935,10 +899,9 @@ int pass1(struct gfs2_sbd *sbp)
* uses the rg bitmaps, so maybe that's the best way to start
* things - we can change the method later if necessary.
*/
-
for (tmp = sbp->rglist.next; tmp != &sbp->rglist;
- tmp = tmp->next, rg_count++){
- log_info( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
+ tmp = tmp->next, rg_count++) {
+ log_debug( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
rg_count);
rgd = osi_list_entry(tmp, struct rgrp_list, list);
for (i = 0; i < rgd->ri.ri_length; i++) {
@@ -955,9 +918,12 @@ int pass1(struct gfs2_sbd *sbp)
while (1) {
/* "block" is relative to the entire file system */
+ /* Get the next dinode in the file system, according
+ to the bitmap. This should ONLY be dinodes. */
if (gfs2_next_rg_meta(rgd, &block, first))
break;
warm_fuzzy_stuff(block);
+
if (fsck_abort) /* if asked to abort */
return FSCK_OK;
if (skip_this_pass) {
@@ -967,11 +933,36 @@ int pass1(struct gfs2_sbd *sbp)
}
bh = bread(sbp, block);
- if (scan_meta(sbp, bh, block)) {
+ /*log_debug( _("Checking metadata block #%" PRIu64
+ " (0x%" PRIx64 ")\n"), block, block);*/
+
+ if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ log_err( _("Found invalid inode at block #"
+ "%llu (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ if(query( _("Okay to free the invalid block? "
+ "(y/n)"))) {
+ gfs2_set_bitmap(sbp, block,
+ GFS2_BLKST_FREE);
+ log_err( _("The invalid block was "
+ "freed.\n"));
+ } else {
+ log_err( _("The invalid block was "
+ "ignored.\n"));
+ }
+ } else if (handle_di(sbp, bh, block) < 0) {
stack;
brelse(bh);
return FSCK_ERROR;
}
+ /* Ignore everything else - they should be hit by the
+ handle_di step. Don't check NONE either, because
+ check_meta passes everything if GFS2_METATYPE_NONE
+ is specified. Hopefully, other metadata types such
+ as indirect blocks will be handled when the inode
+ itself is processed, and if it's not, it should be
+ caught in pass5. */
brelse(bh);
first = 0;
}
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 43158ef..57e4c47 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -176,7 +176,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
if(dh->ref_count == 1)
return 1;
- if(block == dh->b->block_no) {
+ if(block == dh->b->block) {
log_err( _("Found duplicate reference in inode \"%s\" at "
"block #%llu (0x%llx) to block #%llu (0x%llx)\n"),
dh->id->name ? dh->id->name : _("unknown name"),
@@ -210,7 +210,7 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
if(dh->ref_count == 1)
return 1;
- if(block == dh->b->block_no) {
+ if(block == dh->b->block) {
log_err( _("Found dup in inode \"%s\" with address #%llu"
" (0x%llx) with block #%llu (0x%llx)\n"),
dh->id->name ? dh->id->name : _("unknown name"),
@@ -236,7 +236,7 @@ static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
if(dh->ref_count == 1)
return 1;
- if(block == dh->b->block_no) {
+ if(block == dh->b->block) {
log_err( _("Found dup in inode \"%s\" with address #%llu"
" (0x%llx) with block #%llu (0x%llx)\n"),
dh->id->name ? dh->id->name : _("unknown name"),
@@ -308,7 +308,7 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
if(dh->ref_count == 1)
return 1;
- if(block == dh->b->block_no) {
+ if(block == dh->b->block) {
log_err( _("Found dup in inode \"%s\" with address #%llu"
" (0x%llx) with block #%llu (0x%llx)\n"),
dh->id->name ? dh->id->name : _("unknown name"),
@@ -331,7 +331,7 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_blks *b)
{
struct gfs2_inode *ip;
- struct fxn_info myfi = {b->block_no, 0, 1};
+ struct fxn_info myfi = {b->block, 0, 1};
struct inode_with_dups *id = NULL;
struct metawalk_fxns find_refs = {
.private = (void*) &myfi,
@@ -348,7 +348,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_blks
ip = fsck_load_inode(sbp, inode); /* bread, inode_get */
log_debug( _("Checking inode %" PRIu64 " (0x%" PRIx64 ")'s "
"metatree for references to block %" PRIu64 " (0x%" PRIx64
- ")\n"), inode, inode, b->block_no, b->block_no);
+ ")\n"), inode, inode, b->block, b->block);
if(check_metatree(ip, &find_refs)) {
stack;
fsck_inode_put(&ip); /* out, brelse, free */
@@ -372,7 +372,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_blks
}
log_debug( _("Found %d entries with block %" PRIu64
" (0x%" PRIx64 ") in inode #%" PRIu64 " (0x%" PRIx64 ")\n"),
- myfi.found, b->block_no, b->block_no, inode, inode);
+ myfi.found, b->block, b->block, inode, inode);
id->dup_count = myfi.found;
id->block_no = inode;
id->ea_only = myfi.ea_only;
@@ -417,7 +417,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blks *b)
struct gfs2_buffer_head *bh;
uint32_t cmagic;
- bh = bread(sbp, b->block_no);
+ bh = bread(sbp, b->block);
cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
brelse(bh);
if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
@@ -428,8 +428,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blks *b)
"but the block is really metadata.\n"),
id->name, (unsigned long long)id->block_no,
(unsigned long long)id->block_no,
- (unsigned long long)b->block_no,
- (unsigned long long)b->block_no);
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
if (query( _("Clear the inode? (y/n) "))) {
log_warn( _("Clearing inode %lld (0x%llx)...\n"),
(unsigned long long)id->block_no,
@@ -453,8 +453,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blks *b)
log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
" for a total of %d duplicate references\n"),
- (unsigned long long)b->block_no,
- (unsigned long long)b->block_no,
+ (unsigned long long)b->block, (unsigned long long)b->block,
dh.ref_inode_count, dh.ref_count);
osi_list_foreach(tmp, &b->ref_inode_list) {
@@ -463,8 +462,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blks *b)
"block %llu (0x%llx)\n"), id->name,
(unsigned long long)id->block_no,
(unsigned long long)id->block_no,
- id->dup_count, (unsigned long long)b->block_no,
- (unsigned long long)b->block_no);
+ id->dup_count, (unsigned long long)b->block,
+ (unsigned long long)b->block);
}
osi_list_foreach(tmp, &b->ref_inode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
@@ -565,6 +564,12 @@ out:
b = osi_list_entry(tmp, struct dup_blks, list);
if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */
handle_dup_blk(sbp, b);
+ /* Do not attempt to free the dup_blocks list or its parts
+ here because any func that calls check_metatree needs
+ to check duplicate status based on this linked list.
+ This is especially true for pass2 where it may delete "bad"
+ inodes, and we can't delete an inode's indirect block if
+ it was a duplicate (therefore in use by another dinode). */
}
return rc;
}
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 06020f0..d89b3b4 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -219,7 +219,6 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
uint8_t q;
struct gfs2_sbd *sbp = ip->i_sbd;
-
q = block_type(be64_to_cpu(*ea_ptr));
if(q != gfs2_meta_eattr) {
if(remove_eattr_entry(sbp, leaf_bh, ea_hdr, ea_hdr_prev)){
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 2d748e1..1547e6e 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -32,7 +32,7 @@
/* Set children's parent inode in dir_info structure - ext2 does not set
* dotdot inode here, but instead in pass3 - should we? */
static int set_parent_dir(struct gfs2_sbd *sbp, uint64_t childblock,
- uint64_t parentblock)
+ uint64_t parentblock)
{
struct dir_info *di;
@@ -50,7 +50,7 @@ static int set_parent_dir(struct gfs2_sbd *sbp, uint64_t childblock,
}
} else {
log_err( _("Unable to find block %"PRIu64" (0x%" PRIx64
- ") in dir_info list\n"), childblock, childblock);
+ ") in dir_info list\n"), childblock, childblock);
return -1;
}
@@ -106,9 +106,9 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
static const char *de_type_string(uint8_t de_type)
{
const char *de_types[15] = {"unknown", "fifo", "chrdev", "invalid",
- "directory", "invalid", "blkdev", "invalid",
- "file", "invalid", "symlink", "invalid",
- "socket", "invalid", "wht"};
+ "directory", "invalid", "blkdev", "invalid",
+ "file", "invalid", "symlink", "invalid",
+ "socket", "invalid", "wht"};
if (de_type < 15)
return de_types[de_type];
return de_types[3]; /* invalid */
@@ -233,8 +233,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
strncpy(tmp_name, filename, MAX_FILENAME - 1);
if(gfs2_check_range(ip->i_sbd, entryblock)) {
- log_err( _("Block # referenced by directory entry %s is out of range\n"),
- tmp_name);
+ log_err( _("Block # referenced by directory entry %s in inode "
+ "%lld (0x%llx) is out of range\n"),
+ tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
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);
@@ -244,10 +246,12 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Directory entry to out of range block remains\n"));
(*count)++;
ds->entry_count++;
+ /* can't do this because the block is out of range:
+ increment_link(entryblock); */
return 0;
}
}
- q = block_type(de->de_inum.no_addr);
+ q = block_type(entryblock);
/* Get the status of the directory inode */
if(q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
@@ -256,14 +260,13 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Found a bad directory entry: %s\n"), filename);
if(query( _("Delete inode containing bad blocks? (y/n)"))) {
- entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
+ entry_ip = fsck_load_inode(sbp, entryblock);
check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- gfs2_blockmap_set(sbp, bl, de->de_inum.no_addr,
- gfs2_block_free);
+ gfs2_blockmap_set(sbp, bl, entryblock, gfs2_block_free);
bmodified(bh);
log_warn( _("The inode containing bad blocks was "
"deleted.\n"));
@@ -276,15 +279,12 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
}
- if(q != gfs2_inode_dir && q != gfs2_inode_file &&
- q != gfs2_inode_lnk && q != gfs2_inode_blk &&
- q != gfs2_inode_chr && q != gfs2_inode_fifo &&
- q != gfs2_inode_sock) {
- log_err( _("Directory entry '%s' at block %llu (0x%llx"
- ") in dir inode %llu (0x%llx"
- ") block type %d: %s.\n"), tmp_name,
- (unsigned long long)de->de_inum.no_addr,
- (unsigned long long)de->de_inum.no_addr,
+ if(q < gfs2_inode_dir || q > gfs2_inode_sock) {
+ log_err( _("Directory entry '%s' referencing inode %llu "
+ "(0x%llx) in dir inode %llu (0x%llx) block type "
+ "%d: %s.\n"), tmp_name,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
q, q == gfs2_meta_inval ?
@@ -305,20 +305,19 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 1;
/* Now try to clear the dinode, if it is an dinode */
- bhi = bread(sbp, de->de_inum.no_addr);
+ bhi = bread(sbp, entryblock);
error = gfs2_check_meta(bhi, GFS2_METATYPE_DI);
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);
+ entry_ip = fsck_load_inode(sbp, entryblock);
check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
fsck_inode_put(&entry_ip);
- gfs2_blockmap_set(sbp, bl, de->de_inum.no_addr,
- gfs2_block_free);
+ gfs2_blockmap_set(sbp, bl, entryblock, gfs2_block_free);
return 1;
} else {
@@ -331,19 +330,29 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
error = check_file_type(de->de_type, q);
if(error < 0) {
+ log_err( _("Error: directory entry type is "
+ "incompatible with block type at block %lld "
+ "(0x%llx) in directory inode %llu (0x%llx).\n"),
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ log_err( _("Directory entry type is %d, block type is %d.\n"),
+ de->de_type, q);
stack;
return -1;
}
if(error > 0) {
- log_warn( _("Type '%s' in dir entry (%s, %llu/0x%llx) conflicts"
+ log_err( _("Type '%s' in dir entry (%s, %llu/0x%llx) conflicts"
" with type '%s' in dinode. (Dir entry is stale.)\n"),
de_type_string(de->de_type), tmp_name,
- (unsigned long long)de->de_inum.no_addr,
- (unsigned long long)de->de_inum.no_addr,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
block_type_string(q));
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);
+ entry_ip = fsck_load_inode(sbp, entryblock);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ if (entry_ip != ip)
fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
@@ -367,7 +376,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
if(query( _("Clear duplicate '.' entry? (y/n) "))) {
- entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
+ entry_ip = fsck_load_inode(sbp, entryblock);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(&entry_ip);
@@ -379,7 +388,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* FIXME: Should we continue on here
* and check the rest of the '.'
* entry? */
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
@@ -390,19 +399,19 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
* location */
/* check that '.' refers to this inode */
- if(de->de_inum.no_addr != ip->i_di.di_num.no_addr) {
+ if(entryblock != ip->i_di.di_num.no_addr) {
log_err( _("'.' entry's value incorrect in directory %llu"
" (0x%llx). Points to %llu"
" (0x%llx) when it should point to %llu"
" (0x%llx).\n"),
- (unsigned long long)de->de_inum.no_addr,
- (unsigned long long)de->de_inum.no_addr,
- (unsigned long long)de->de_inum.no_addr,
- (unsigned long long)de->de_inum.no_addr,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
if(query( _("Remove '.' reference? (y/n) "))) {
- entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
+ entry_ip = fsck_load_inode(sbp, entryblock);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(&entry_ip);
@@ -414,7 +423,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Invalid '.' reference remains\n"));
/* Not setting ds->dotdir here since
* this '.' entry is invalid */
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
@@ -422,7 +431,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
ds->dotdir = 1;
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
@@ -437,7 +446,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)ip->i_di.di_num.no_addr);
if(query( _("Clear duplicate '..' entry? (y/n) "))) {
- entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
+ entry_ip = fsck_load_inode(sbp, entryblock);
check_inode_eattr(entry_ip, &clear_eattrs);
fsck_inode_put(&entry_ip);
@@ -449,7 +458,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* FIXME: Should we continue on here
* and check the rest of the '..'
* entry? */
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
@@ -462,8 +471,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
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);
+ entry_ip = fsck_load_inode(sbp, entryblock);
+ check_inode_eattr(entry_ip, &clear_eattrs);
+ if (entry_ip != ip)
fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
@@ -471,14 +481,13 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 1;
} else {
log_err( _("Bad '..' directory entry remains\n"));
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
}
}
- /* GFS2 does not rely on '..' being in a
- * certain location */
+ /* GFS2 does not rely on '..' being in a certain location */
/* Add the address this entry is pointing to
* to this inode's dotdot_parent in
@@ -489,27 +498,26 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
ds->dotdotdir = 1;
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
}
- /* After this point we're only concerned with
- * directories */
+ /* After this point we're only concerned with directories */
if(q != gfs2_inode_dir) {
log_debug( _("Found non-dir inode dentry\n"));
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
return 0;
}
- log_debug( _("Found plain directory dentry\n"));
+ /*log_debug( _("Found plain directory dentry\n"));*/
error = set_parent_dir(sbp, entryblock, ip->i_di.di_num.no_addr);
if(error > 0) {
log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64
- ") detected.\n"), filename, entryblock, entryblock);
+ ") detected.\n"), tmp_name, entryblock, entryblock);
if(query( _("Clear hard link to directory? (y/n) "))) {
bmodified(bh);
@@ -523,12 +531,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
ds->entry_count++;
return 0;
}
- }
- else if (error < 0) {
+ } else if (error < 0) {
stack;
return -1;
}
- increment_link(sbp, de->de_inum.no_addr);
+ increment_link(sbp, entryblock);
(*count)++;
ds->entry_count++;
/* End of checks */
@@ -663,7 +670,7 @@ static inline int is_system_dir(struct gfs2_sbd *sbp, uint64_t block)
*/
int pass2(struct gfs2_sbd *sbp)
{
- uint64_t i;
+ uint64_t dirblk;
uint8_t q;
struct dir_status ds = {0};
struct gfs2_inode *ip;
@@ -692,43 +699,44 @@ 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++) {
- warm_fuzzy_stuff(i);
+ for(dirblk = 0; dirblk < last_fs_block; dirblk++) {
+ warm_fuzzy_stuff(dirblk);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return FSCK_OK;
/* Skip the system inodes - they're checked above */
- if (is_system_dir(sbp, i))
+ if (is_system_dir(sbp, dirblk))
continue;
- q = block_type(i);
+ q = block_type(dirblk);
if(q != gfs2_inode_dir)
continue;
log_debug( _("Checking directory inode at block %"PRIu64" (0x%"
- PRIx64 ")\n"), i, i);
+ PRIx64 ")\n"), dirblk, dirblk);
memset(&ds, 0, sizeof(ds));
pass2_fxns.private = (void *) &ds;
if(ds.q == gfs2_bad_block) {
/* First check that the directory's metatree
* is valid */
- ip = fsck_load_inode(sbp, i);
+ ip = fsck_load_inode(sbp, dirblk);
if(check_metatree(ip, &pass2_fxns)) {
fsck_inode_put(&ip);
stack;
return FSCK_ERROR;
}
}
- error = check_dir(sbp, i, &pass2_fxns);
+ error = check_dir(sbp, dirblk, &pass2_fxns);
if(error < 0) {
stack;
return FSCK_ERROR;
}
if (error > 0) {
struct dir_info *di = NULL;
- error = find_di(sbp, i, &di);
+
+ error = find_di(sbp, dirblk, &di);
if(error < 0) {
stack;
return FSCK_ERROR;
@@ -737,30 +745,33 @@ int pass2(struct gfs2_sbd *sbp)
/* FIXME: factor */
if(query( _("Remove directory entry for bad"
" inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
- " (0x%" PRIx64 ")? (y/n)"), i, i, di->treewalk_parent,
+ " (0x%" PRIx64 ")? (y/n)"),
+ dirblk, dirblk, di->treewalk_parent,
di->treewalk_parent)) {
- error = remove_dentry_from_dir(sbp, di->treewalk_parent,
- i);
+ error = remove_dentry_from_dir(sbp,
+ di->treewalk_parent,
+ dirblk);
if(error < 0) {
stack;
return FSCK_ERROR;
}
if(error > 0) {
log_warn( _("Unable to find dentry for %"
- PRIu64 " (0x%" PRIx64 ") in %" PRIu64
- " (0x%" PRIx64 ")\n"), i, i,
- di->treewalk_parent, di->treewalk_parent);
+ PRIu64 " (0x%" PRIx64 ") in %" PRIu64
+ " (0x%" PRIx64 ")\n"), dirblk, dirblk,
+ di->treewalk_parent, di->treewalk_parent);
}
log_warn( _("Directory entry removed\n"));
} else
log_err( _("Directory entry to invalid inode remains.\n"));
}
- gfs2_blockmap_set(sbp, bl, i, gfs2_meta_inval);
+ gfs2_blockmap_set(sbp, bl, dirblk, gfs2_meta_inval);
}
- ip = fsck_load_inode(sbp, i);
+ ip = fsck_load_inode(sbp, dirblk);
if(!ds.dotdir) {
log_err(_("No '.' entry found for directory inode at "
- "block %"PRIu64" (0x%" PRIx64 ")\n"), i, i);
+ "block %"PRIu64" (0x%" PRIx64 ")\n"),
+ dirblk, dirblk);
if (query( _("Is it okay to add '.' entry? (y/n) "))) {
sprintf(tmp_name, ".");
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 7d4fe41..5ccccc8 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -68,11 +68,12 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
bmodified(ip->i_bh);
fsck_inode_put(&ip);
fsck_inode_put(&pip);
+ free(filename);
return 0;
}
static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
- struct dir_info *di)
+ struct dir_info *di)
{
struct dir_info *pdi;
uint8_t q_dotdot, q_treewalk;
@@ -111,8 +112,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
di->dotdot_parent, di->dinode);
di->dotdot_parent = di->treewalk_parent;
}
- }
- else {
+ } else {
if(q_treewalk != gfs2_inode_dir) {
int error = 0;
log_warn( _(".. parent is valid, but treewalk"
@@ -146,10 +146,11 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
}
else {
log_err( _("Both .. and treewalk parents are "
- "directories, going with treewalk for "
- "now...\n"));
+ "directories, going with treewalk "
+ "for now...\n"));
attach_dotdot_to(sbp, di->treewalk_parent,
- di->dotdot_parent, di->dinode);
+ di->dotdot_parent,
+ di->dinode);
di->dotdot_parent = di->treewalk_parent;
}
}
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 8a1f2e3..eb4f413 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -37,7 +37,8 @@ struct metawalk_fxns pass4_fxns_delete = {
static int fix_inode_count(struct gfs2_sbd *sbp, struct inode_info *ii,
struct gfs2_inode *ip)
{
- log_info( _("Fixing inode count for %llu (0x%llx) \n"),
+ log_info( _("Fixing inode link count (%d->%d) for %llu (0x%llx) \n"),
+ ip->i_di.di_nlink, ii->counted_links,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
if(ip->i_di.di_nlink == ii->counted_links)
@@ -68,8 +69,6 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
log_crit( _("osi_list_foreach broken in scan_info_list!!\n"));
exit(FSCK_ERROR);
}
- log_debug( _("Checking reference count on inode at block %" PRIu64
- " (0x%" PRIx64 ")\n"), ii->inode, ii->inode);
if(ii->counted_links == 0) {
log_err( _("Found unlinked inode at %" PRIu64 " (0x%" PRIx64 ")\n"),
ii->inode, ii->inode);
@@ -100,8 +99,11 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
q != gfs2_inode_chr &&
q != gfs2_inode_fifo &&
q != gfs2_inode_sock) {
- log_err( _("Unlinked block marked as inode is "
- "not an inode (%d)\n"), q);
+ log_err( _("Unlinked block %lld (0x%llx) "
+ "marked as inode is "
+ "not an inode (%d)\n"),
+ (unsigned long long)ii->inode,
+ (unsigned long long)ii->inode, q);
ip = fsck_load_inode(sbp, ii->inode);
if(query(_("Delete unlinked inode? (y/n) "))) {
check_inode_eattr(ip,
@@ -139,8 +141,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
stack;
fsck_inode_put(&ip);
return -1;
- }
- else {
+ } else {
fix_inode_count(sbp, ii, ip);
lf_addition = 1;
}
@@ -161,8 +162,10 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
fix_inode_count(sbp, ii, ip);
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);
+ log_warn( _("Link count updated to %d for "
+ "inode %" PRIu64 " (0x%"
+ PRIx64 ") \n"), ii->link_count,
+ ii->inode, ii->inode);
} else {
log_err( _("Link count for inode %" PRIu64 " (0x%" PRIx64
") still incorrect\n"), ii->inode, ii->inode);
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index c6b005a..08217c7 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -56,7 +56,7 @@ static int convert_mark(uint8_t q, uint32_t *count)
return GFS2_BLKST_USED;
default:
- log_err( _("Invalid state %d found\n"), q);
+ log_err( _("Invalid block type %d found\n"), q);
return -1;
}
return -1;
@@ -135,9 +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_string(q));
- if(query( _("Fix bitmap for block %" PRIu64
- " (0x%" PRIx64 ") ? (y/n) "),
- block, block)) {
+ 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
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 9d7653a..aaf699b 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -32,11 +32,11 @@ struct special_blocks false_rgrps;
#define ri_compare(rg, ondisk, expected, field, fmt) \
if (ondisk.field != expected.field) { \
- log_warn("rindex #%d " #field " discrepancy: index 0x%" fmt \
- " != expected: 0x%" fmt "\n", \
- rg + 1, ondisk.field, expected.field); \
- ondisk.field = expected.field; \
- rindex_modified = TRUE; \
+ log_warn( _("rindex #%d " #field " discrepancy: index 0x%" \
+ fmt " != expected: 0x%" fmt "\n"), \
+ rg + 1, ondisk.field, expected.field); \
+ ondisk.field = expected.field; \
+ rindex_modified = TRUE; \
}
/*
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index d0dd4af..264489a 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -104,7 +104,7 @@ void warm_fuzzy_stuff(uint64_t block)
static uint64_t one_percent = 0;
static struct timeval tv;
static uint32_t seconds = 0;
-
+
if (!one_percent)
one_percent = last_fs_block / 100;
if (block - last_reported_block >= one_percent) {
@@ -206,7 +206,7 @@ void gfs2_dup_set(uint64_t block)
b = malloc(sizeof(struct dup_blks));
if (b) {
memset(b, 0, sizeof(*b));
- b->block_no = block;
+ b->block = block;
osi_list_init(&b->ref_inode_list);
osi_list_add(&b->list, &dup_blocks.list);
}
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index b57f58d..153ed9a 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -103,7 +103,6 @@ void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
b->block = block;
osi_list_add(&b->list, &blocklist->list);
}
- return;
}
void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 4d5f2b5..3a96ef3 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -81,7 +81,7 @@ int bwrite(struct gfs2_buffer_head *bh)
if (write(sdp->device_fd, bh->b_data, sdp->bsize) != sdp->bsize)
return -1;
sdp->writes++;
- bh->b_changed = 0;
+ bh->b_modified = 0;
return 0;
}
@@ -91,7 +91,7 @@ int brelse(struct gfs2_buffer_head *bh)
if (bh->b_blocknr == -1)
printf("Double free!\n");
- if (bh->b_changed)
+ if (bh->b_modified)
error = bwrite(bh);
bh->b_blocknr = -1;
if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist))
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 27362e1..e9c7626 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -96,7 +96,7 @@ void inode_put(struct gfs2_inode **ip_in)
uint64_t block = ip->i_di.di_num.no_addr;
struct gfs2_sbd *sdp = ip->i_sbd;
- if (ip->i_bh->b_changed) {
+ if (ip->i_bh->b_modified) {
gfs2_dinode_out(&ip->i_di, ip->i_bh);
if (!ip->bh_owned && is_system_inode(sdp, block))
fprintf(stderr, "Warning: Change made to inode "
@@ -157,8 +157,9 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
found:
if (bn >= ri->ri_bitbytes * GFS2_NBBY)
- die("allocation is broken (2): %u %u %"PRIu64" %u\n",
- bn, ri->ri_bitbytes * GFS2_NBBY,
+ die("allocation is broken (2): bn: %u %u rgrp: %"PRIu64
+ " (0x%" PRIx64 ") Free:%u\n",
+ bn, ri->ri_bitbytes * GFS2_NBBY, (uint64_t)rl->ri.ri_addr,
(uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
switch (type) {
@@ -237,15 +238,14 @@ void unstuff_dinode(struct gfs2_inode *ip)
if (ip->i_di.di_size) {
if (isdir) {
+ struct gfs2_meta_header mh;
+
block = meta_alloc(ip);
bh = bget(sdp, block);
- {
- struct gfs2_meta_header mh;
- mh.mh_magic = GFS2_MAGIC;
- mh.mh_type = GFS2_METATYPE_JD;
- mh.mh_format = GFS2_FORMAT_JD;
- gfs2_meta_header_out(&mh, bh);
- }
+ mh.mh_magic = GFS2_MAGIC;
+ mh.mh_type = GFS2_METATYPE_JD;
+ mh.mh_format = GFS2_FORMAT_JD;
+ gfs2_meta_header_out(&mh, bh);
buffer_copy_tail(sdp, bh,
sizeof(struct gfs2_meta_header),
@@ -315,15 +315,14 @@ void build_height(struct gfs2_inode *ip, int height)
}
if (new_block) {
+ struct gfs2_meta_header mh;
+
block = meta_alloc(ip);
bh = bget(sdp, block);
- {
- struct gfs2_meta_header mh;
- mh.mh_magic = GFS2_MAGIC;
- mh.mh_type = GFS2_METATYPE_IN;
- mh.mh_format = GFS2_FORMAT_IN;
- gfs2_meta_header_out(&mh, bh);
- }
+ mh.mh_magic = GFS2_MAGIC;
+ mh.mh_type = GFS2_METATYPE_IN;
+ mh.mh_format = GFS2_FORMAT_IN;
+ gfs2_meta_header_out(&mh, bh);
buffer_copy_tail(sdp, bh,
sizeof(struct gfs2_meta_header),
ip->i_bh, sizeof(struct gfs2_dinode));
@@ -567,7 +566,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
}
static void copy_from_mem(struct gfs2_buffer_head *bh, void **buf,
- unsigned int offset, unsigned int size)
+ unsigned int offset, unsigned int size)
{
char **p = (char **)buf;
@@ -762,7 +761,7 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
memset(new, 0, sizeof(struct gfs2_dirent));
new->de_rec_len = cpu_to_be16(cur_rec_len -
- GFS2_DIRENT_SIZE(cur_name_len));
+ GFS2_DIRENT_SIZE(cur_name_len));
new->de_name_len = cpu_to_be16(name_len);
dent->de_rec_len = cpu_to_be16(cur_rec_len -
be16_to_cpu(new->de_rec_len));
@@ -809,14 +808,13 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
}
void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
- uint64_t *leaf_out)
+ uint64_t *leaf_out)
{
uint64_t leaf_no;
int count;
- count = gfs2_readi(dip, (char *)&leaf_no,
- lindex * sizeof(uint64_t),
- sizeof(uint64_t));
+ count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
+ sizeof(uint64_t));
if (count != sizeof(uint64_t))
die("gfs2_get_leaf_nr: Bad internal read.\n");
@@ -835,7 +833,8 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
die("gfs2_put_leaf_nr: Bad internal write.\n");
}
-static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no)
+static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
+ uint64_t leaf_no)
{
struct gfs2_buffer_head *nbh, *obh;
struct gfs2_leaf *nleaf, *oleaf;
@@ -867,18 +866,16 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
start = (lindex & ~(len - 1));
- zalloc(lp, half_len * sizeof(uint64_t));
-
- count = gfs2_readi(dip, (char *)lp, start * sizeof(uint64_t),
- half_len * sizeof(uint64_t));
- if (count != half_len * sizeof(uint64_t))
- die("dir_split_leaf (1)\n");
-
+ lp = calloc(1, half_len * sizeof(uint64_t));
+ if (lp == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
for (x = 0; x < half_len; x++)
lp[x] = cpu_to_be64(bn);
count = gfs2_writei(dip, (char *)lp, start * sizeof(uint64_t),
- half_len * sizeof(uint64_t));
+ half_len * sizeof(uint64_t));
if (count != half_len * sizeof(uint64_t))
die("dir_split_leaf (2)\n");
@@ -966,7 +963,7 @@ static void dir_double_exhash(struct gfs2_inode *dip)
}
count = gfs2_writei(dip, (char *)buf + sdp->sd_hash_bsize,
- block * sdp->bsize, sdp->bsize);
+ block * sdp->bsize, sdp->bsize);
if (count != sdp->bsize)
die("dir_double_exhash (2)\n");
@@ -1052,8 +1049,8 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
uint32_t hash;
uint64_t leaf_no, bn;
- restart:
hash = gfs2_disk_hash(filename, len);
+restart:
/* Have to kludge because (hash >> 32) gives hash for some reason. */
if (dip->i_di.di_depth)
lindex = hash >> (32 - dip->i_di.di_depth);
@@ -1084,15 +1081,14 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
continue;
} else {
+ struct gfs2_meta_header mh;
+
bn = meta_alloc(dip);
nbh = bget(dip->i_sbd, bn);
- {
- struct gfs2_meta_header mh;
- mh.mh_magic = GFS2_MAGIC;
- mh.mh_type = GFS2_METATYPE_LF;
- mh.mh_format = GFS2_FORMAT_LF;
- gfs2_meta_header_out(&mh, nbh);
- }
+ mh.mh_magic = GFS2_MAGIC;
+ mh.mh_type = GFS2_METATYPE_LF;
+ mh.mh_format = GFS2_FORMAT_LF;
+ gfs2_meta_header_out(&mh, nbh);
leaf->lf_next = cpu_to_be64(bn);
diff --git a/gfs2/libgfs2/gfs2_log.c b/gfs2/libgfs2/gfs2_log.c
index fbb30e0..d3cf7e5 100644
--- a/gfs2/libgfs2/gfs2_log.c
+++ b/gfs2/libgfs2/gfs2_log.c
@@ -61,19 +61,16 @@ void print_msg(int priority, const char *file, int line, const char *format,
vfprintf(stderr, format, args);
break;
}
- return;
}
void print_fsck_log(int iif, int priority, const char *file, int line,
const char *format, ...)
{
-
va_list args;
const char *transform;
- va_start(args, format);
-
+ va_start(args, format);
transform = _(format);
if((_state.print_level == priority) ||
@@ -158,7 +155,6 @@ char generic_interrupt(const char *caller, const char *where,
int gfs2_query(int *setonabort, struct gfs2_options *opts,
const char *format, ...)
{
-
va_list args;
const char *transform;
char response;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index e243d3f..1cd441f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -108,7 +108,7 @@ struct rgrp_list {
struct gfs2_buffer_head {
osi_list_t b_altlist; /* alternate list */
uint64_t b_blocknr;
- int b_changed;
+ int b_modified;
char *b_data;
struct gfs2_sbd *sdp;
};
@@ -329,7 +329,7 @@ extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num,
extern int bwrite(struct gfs2_buffer_head *bh);
extern int brelse(struct gfs2_buffer_head *bh);
-#define bmodified(bh) do { bh->b_changed = 1; } while(0)
+#define bmodified(bh) do { bh->b_modified = 1; } while(0)
#define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \
__LINE__, \
@@ -734,7 +734,6 @@ extern void gfs2_leaf_print(struct gfs2_leaf *lf);
extern void gfs2_ea_header_print(struct gfs2_ea_header *ea, char *name);
extern void gfs2_log_header_print(struct gfs2_log_header *lh);
extern void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld);
-extern void gfs2_inum_range_print(struct gfs2_inum_range *ir);
extern void gfs2_statfs_change_print(struct gfs2_statfs_change *sc);
extern void gfs2_quota_change_print(struct gfs2_quota_change *qc);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index dd805b4..f48bad5 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -144,7 +144,7 @@ int ji_update(struct gfs2_sbd *sdp)
int i;
if(!ip) {
- log_crit("Journal inode not found.\n");
+ log_crit("Journal index inode not found.\n");
return -1;
}
14 years, 1 month
cluster: RHEL56 - libgfs2, fsck.gfs2: simplify block_query code
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 8d3521017ebe5e9b8d8e190f1b33af601b461972
Parent: b486ce1bf1519f42a252a0b49ea177a1c87b4593
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Jan 20 12:31:38 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:30:11 2010 -0500
libgfs2, fsck.gfs2: simplify block_query code
This patch simplifies the block query code. Now that the blockmap
code doesn't have the duplicate block reference responsibilities,
we don't need the query info to be in its own structure. The
block query can be reduced to a simple fetch from memory and mask
off the bits we need. The block query used to check for a valid
block range. Now, for performance reasons, that's the
responsibility of the caller. Most of the callers check for a
valid range anyway, so checking it in the query was a waste of
time. This is for better performance and makes the code simpler
and more readable.
rhbz#455300
---
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/lost_n_found.c | 10 ++---
gfs2/fsck/main.c | 16 +++-----
gfs2/fsck/metawalk.c | 13 ++-----
gfs2/fsck/pass1.c | 81 +++++++++++----------------------------------
gfs2/fsck/pass1b.c | 24 +++++--------
gfs2/fsck/pass1c.c | 28 +++++----------
gfs2/fsck/pass2.c | 51 ++++++++++++----------------
gfs2/fsck/pass3.c | 56 ++++++++++--------------------
gfs2/fsck/pass4.c | 27 +++++++--------
gfs2/fsck/pass5.c | 16 ++++----
gfs2/fsck/util.c | 6 ++--
gfs2/fsck/util.h | 15 ++++++++-
gfs2/libgfs2/block_list.c | 15 --------
gfs2/libgfs2/libgfs2.h | 6 ---
15 files changed, 131 insertions(+), 235 deletions(-)
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 37fe632..2510ecb 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -56,7 +56,7 @@ struct dir_info
struct dir_status {
uint8_t dotdir:1;
uint8_t dotdotdir:1;
- struct gfs2_block_query q;
+ uint8_t q;
uint32_t entry_count;
};
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 07850de..5fa5ce4 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -25,6 +25,7 @@
#include "libgfs2.h"
#include "lost_n_found.h"
#include "link.h"
+#include "util.h"
/* add_inode_to_lf - Add dir entry to lost+found for the inode
* @ip: inode to add to lost + found
@@ -42,16 +43,13 @@ int add_inode_to_lf(struct gfs2_inode *ip){
__be32 inode_type;
if(!lf_dip) {
- struct gfs2_block_query q = {0};
+ uint8_t q;
log_info( _("Locating/Creating lost and found directory\n"));
lf_dip = createi(ip->i_sbd->md.rooti, "lost+found", S_IFDIR | 0700, 0);
- if(gfs2_block_check(ip->i_sbd, bl, lf_dip->i_di.di_num.no_addr, &q)) {
- stack;
- return -1;
- }
- if(q.block_type != gfs2_inode_dir) {
+ q = block_type(lf_dip->i_di.di_num.no_addr);
+ if(q != gfs2_inode_dir) {
/* This is a new lost+found directory, so set its
* block type and increment link counts for
* the directories */
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 8d1f8e8..3b5bfac 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -27,6 +27,7 @@
#include "libgfs2.h"
#include "fsck.h"
#include "osi_list.h"
+#include "util.h"
struct gfs2_options opts = {0};
struct gfs2_inode *lf_dip; /* Lost and found directory inode */
@@ -174,22 +175,17 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
/* FIXME: check this block's validity */
- if(gfs2_block_check(sysinode->i_sbd, bl, iblock, &ds.q)) {
- log_crit( _("Can't get %s inode block %" PRIu64 " (0x%"
- PRIx64 ") from block list\n"), filename,
- iblock, iblock);
- return -1;
- }
+ ds.q = block_type(iblock);
/* If the inode exists but the block is marked */
/* free, we might be recovering from a corrupt */
/* bitmap. In that case, don't rebuild the inode. */
/* Just reuse the inode and fix the bitmap. */
- if (ds.q.block_type == gfs2_block_free) {
+ if (ds.q == gfs2_block_free) {
log_info( _("The inode exists but the block is not marked 'in use'; fixing it.\n"));
gfs2_blockmap_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
mark);
- ds.q.block_type = mark;
+ ds.q = mark;
if (mark == gfs2_inode_dir)
add_to_dir_list(sysinode->i_sbd,
sysinode->i_di.di_num.no_addr);
@@ -201,14 +197,14 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
* create a new inode and get it all setup - of course,
* everything will be in lost+found then, but we *need* our
* system inodes before we can do any of that. */
- if(!sysinode || ds.q.block_type != mark) {
+ if(!sysinode || ds.q != mark) {
log_err( _("Invalid or missing %s system inode.\n"), filename);
if (query(_("Create new %s system inode? (y/n) "), filename)) {
builder(sysinode->i_sbd);
gfs2_blockmap_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
mark);
- ds.q.block_type = mark;
+ ds.q = mark;
if (mark == gfs2_inode_dir)
add_to_dir_list(sysinode->i_sbd,
sysinode->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 38e9cc5..1a701e1 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1098,7 +1098,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
uint64_t dentryblock)
{
struct metawalk_fxns remove_dentry_fxns = {0};
- struct gfs2_block_query q;
+ uint8_t q;
int error;
log_debug( _("Removing dentry %" PRIu64 " (0x%" PRIx64 ") from directory %"
@@ -1110,11 +1110,8 @@ int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
remove_dentry_fxns.private = &dentryblock;
remove_dentry_fxns.check_dentry = remove_dentry;
- if(gfs2_block_check(sbp, bl, dir, &q)) {
- stack;
- return -1;
- }
- if(q.block_type != gfs2_inode_dir) {
+ q = block_type(dir);
+ if(q != gfs2_inode_dir) {
log_info( _("Parent block is not a directory...ignoring\n"));
return 1;
}
@@ -1205,11 +1202,7 @@ int delete_blocks(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, const char *btype,
void *private)
{
- struct gfs2_block_query q = {0};
-
if (gfs2_check_range(ip->i_sbd, block) == 0) {
- if (gfs2_block_check(ip->i_sbd, bl, block, &q))
- return 0;
if(!is_duplicate(block)) {
log_info( _("Deleting %s block %lld (0x%llx) as part "
"of inode %lld (0x%llx)\n"), btype,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 134476b..40d316e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -97,7 +97,7 @@ static int leaf(struct gfs2_inode *ip, uint64_t block,
static int check_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, void *private)
{
- struct gfs2_block_query q = {0};
+ uint8_t q;
int found_dup = 0;
struct gfs2_buffer_head *nbh;
struct block_count *bc = (struct block_count *)private;
@@ -111,13 +111,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
return 1;
}
- if(gfs2_block_check(ip->i_sbd, bl, block, &q)) {
- stack;
- return -1;
- }
- if(q.block_type != gfs2_block_free) {
+ q = block_type(block);
+ if(q != gfs2_block_free) {
log_err( _("Found duplicate block referenced as metadata in "
- "indirect block - was marked %d\n"), q.block_type);
+ "indirect block - was marked %d\n"), q);
gfs2_dup_set(block);
found_dup = 1;
}
@@ -147,7 +144,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
{
- struct gfs2_block_query q = {0};
+ uint8_t q;
struct block_count *bc = (struct block_count *) private;
int error = 0, btype;
@@ -164,20 +161,15 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
gfs2_bad_block);
return 1;
}
- if(gfs2_block_check(ip->i_sbd, bl, block, &q)) {
- stack;
- log_err( _("Found bad block referenced as data at %"
- PRIu64 " (0x%"PRIx64 ")\n"), block, block);
- return -1;
- }
- if(q.block_type != gfs2_block_free) {
+ q = block_type(block);
+ if(q != gfs2_block_free) {
log_err( _("Found duplicate block referenced as data at %"
PRIu64 " (0x%"PRIx64 ")\n"), block, block);
- if (q.block_type != gfs2_meta_inval) {
+ if (q != gfs2_meta_inval) {
gfs2_dup_set(block);
/* If the prev ref was as data, this is likely a data
block, so keep the block count for both refs. */
- if (q.block_type == gfs2_block_used)
+ if (q == gfs2_block_used)
bc->data_count++;
return 1;
}
@@ -258,11 +250,6 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
(unsigned long long)ip->i_di.di_num.no_addr);
if (query( _("Clear all Extended Attributes from the "
"inode? (y/n) "))) {
- struct gfs2_block_query q;
- if(gfs2_block_check(ip->i_sbd, bl, ip->i_di.di_eattr, &q)) {
- stack;
- return -1;
- }
if (!remove_inode_eattr(ip, bc,
is_duplicate(ip->i_di.di_eattr)))
log_err( _("Extended attributes were removed.\n"));
@@ -319,7 +306,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
{
struct gfs2_sbd *sdp = ip->i_sbd;
int ret = 0;
- struct gfs2_block_query q = {0};
+ uint8_t q;
struct block_count *bc = (struct block_count *) private;
/* This inode contains an eattr - it may be invalid, but the
@@ -332,10 +319,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
* in pass1c */
return 1;
}
- if(gfs2_block_check(sdp, bl, indirect, &q)) {
- stack;
- return -1;
- }
+ q = block_type(indirect);
/* Special duplicate processing: If we have an EA block,
check if it really is an EA. If it is, let duplicate
@@ -343,7 +327,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
count it as a duplicate. */
*bh = bread(sdp, indirect);
if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
- if(q.block_type != gfs2_block_free) { /* Duplicate? */
+ if(q != gfs2_block_free) { /* Duplicate? */
if (!clear_eas(ip, bc, indirect, 1,
_("Bad indirect Extended Attribute "
"duplicate found"))) {
@@ -357,7 +341,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
"type"));
return 1;
}
- if(q.block_type != gfs2_block_free) { /* Duplicate? */
+ if(q != gfs2_block_free) { /* Duplicate? */
log_err( _("Inode #%llu (0x%llx): Duplicate Extended "
"Attribute indirect block found at #%llu "
"(0x%llx).\n"),
@@ -414,19 +398,16 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
{
struct gfs2_buffer_head *leaf_bh = NULL;
struct gfs2_sbd *sdp = ip->i_sbd;
- struct gfs2_block_query q = {0};
+ uint8_t q;
struct block_count *bc = (struct block_count *) private;
- if(gfs2_block_check(sdp, bl, block, &q)) {
- stack;
- return -1;
- }
+ q = block_type(block);
/* Special duplicate processing: If we have an EA block, check if it
really is an EA. If it is, let duplicate handling sort it out.
If it isn't, clear it but don't count it as a duplicate. */
leaf_bh = bread(sdp, block);
if(gfs2_check_meta(leaf_bh, btype)) {
- if(q.block_type != gfs2_block_free) { /* Duplicate? */
+ if(q != gfs2_block_free) { /* Duplicate? */
clear_eas(ip, bc, block, 1,
_("Bad Extended Attribute duplicate found"));
} else {
@@ -437,7 +418,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
brelse(leaf_bh);
return 1;
}
- if(q.block_type != gfs2_block_free) { /* Duplicate? */
+ if(q != gfs2_block_free) { /* Duplicate? */
log_debug( _("Duplicate block found at #%lld (0x%llx).\n"),
(unsigned long long)block,
(unsigned long long)block);
@@ -581,14 +562,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, void *private)
{
- struct gfs2_block_query q = {0};
-
*bh = NULL;
- if(gfs2_block_check(ip->i_sbd, bl, block, &q)) {
- stack;
- return -1;
- }
if(!is_duplicate(block)) {
gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
@@ -598,12 +573,6 @@ static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
static int clear_data(struct gfs2_inode *ip, uint64_t block, void *private)
{
- struct gfs2_block_query q = {0};
-
- if(gfs2_block_check(ip->i_sbd, bl, block, &q)) {
- stack;
- return -1;
- }
if(!is_duplicate(block)) {
gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
@@ -615,15 +584,9 @@ static int clear_data(struct gfs2_inode *ip, uint64_t block, void *private)
static int clear_leaf(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *bh, void *private)
{
- struct gfs2_block_query q = {0};
-
log_crit( _("Clearing leaf #%" PRIu64 " (0x%" PRIx64 ")\n"),
block, block);
- if(gfs2_block_check(ip->i_sbd, bl, block, &q)) {
- stack;
- return -1;
- }
if(!is_duplicate(block)) {
log_crit( _("Setting leaf #%" PRIu64 " (0x%" PRIx64 ") invalid\n"),
block, block);
@@ -669,7 +632,7 @@ int add_to_dir_list(struct gfs2_sbd *sbp, uint64_t block)
static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
uint64_t block)
{
- struct gfs2_block_query q = {0};
+ uint8_t q;
struct gfs2_inode *ip;
int error;
struct block_count bc = {0};
@@ -697,12 +660,8 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
" (0x%" PRIx64 ") not fixed\n"), block, block);
}
- if(gfs2_block_check(sdp, bl, block, &q)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
- if(q.block_type != gfs2_block_free) {
+ q = block_type(block);
+ if(q != gfs2_block_free) {
log_err( _("Found duplicate block referenced as an inode at "
"#%" PRIu64 " (0x%" PRIx64 ")\n"), block, block);
gfs2_dup_set(block);
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 5c6abb7..43158ef 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -509,7 +509,7 @@ int pass1b(struct gfs2_sbd *sbp)
{
struct dup_blks *b;
uint64_t i;
- struct gfs2_block_query q;
+ uint8_t q;
osi_list_t *tmp = NULL, *x;
struct metawalk_fxns find_dirents = {0};
int rc = FSCK_OK;
@@ -534,18 +534,14 @@ int pass1b(struct gfs2_sbd *sbp)
goto out;
log_debug( _("Scanning block %" PRIu64 " (0x%" PRIx64 ") for inodes\n"),
i, i);
- if(gfs2_block_check(sbp, bl, i, &q)) {
- stack;
- rc = FSCK_ERROR;
- goto out;
- }
- if((q.block_type == gfs2_inode_dir) ||
- (q.block_type == gfs2_inode_file) ||
- (q.block_type == gfs2_inode_lnk) ||
- (q.block_type == gfs2_inode_blk) ||
- (q.block_type == gfs2_inode_chr) ||
- (q.block_type == gfs2_inode_fifo) ||
- (q.block_type == gfs2_inode_sock)) {
+ q = block_type(i);
+ if((q == gfs2_inode_dir) ||
+ (q == gfs2_inode_file) ||
+ (q == gfs2_inode_lnk) ||
+ (q == gfs2_inode_blk) ||
+ (q == gfs2_inode_chr) ||
+ (q == gfs2_inode_fifo) ||
+ (q == gfs2_inode_sock)) {
osi_list_foreach_safe(tmp, &dup_blocks.list, x) {
b = osi_list_entry(tmp, struct dup_blks,
list);
@@ -556,7 +552,7 @@ int pass1b(struct gfs2_sbd *sbp)
}
}
}
- if(q.block_type == gfs2_inode_dir) {
+ if(q == gfs2_inode_dir) {
check_dir(sbp, i, &find_dirents);
}
}
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 514afac..06020f0 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -85,7 +85,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
- struct gfs2_block_query q;
+ uint8_t q;
struct gfs2_buffer_head *indir_bh = NULL;
if(gfs2_check_range(sbp, block)) {
@@ -98,11 +98,8 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr);
return ask_remove_eattr(ip);
}
- else if (gfs2_block_check(sbp, bl, block, &q)) {
- stack;
- return -1;
- }
- else if(q.block_type != gfs2_indir_blk) {
+ q = block_type(block);
+ if(q != gfs2_indir_blk) {
log_err( _("Extended attributes indirect block #%llu"
" (0x%llx) for inode #%llu"
" (0x%llx) invalid.\n"),
@@ -124,7 +121,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
void *private)
{
struct gfs2_sbd *sbp = ip->i_sbd;
- struct gfs2_block_query q;
+ uint8_t q;
if(gfs2_check_range(sbp, block)) {
log_err( _("Extended attributes block for inode #%llu"
@@ -133,11 +130,8 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr);
return ask_remove_eattr(ip);
}
- else if (gfs2_block_check(sbp, bl, block, &q)) {
- stack;
- return -1;
- }
- else if(q.block_type != gfs2_meta_eattr) {
+ q = block_type(block);
+ if(q != gfs2_meta_eattr) {
log_err( _("Extended attributes block for inode #%llu"
" (0x%llx) invalid.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -222,14 +216,12 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev, void *private)
{
- struct gfs2_block_query q;
+ uint8_t q;
struct gfs2_sbd *sbp = ip->i_sbd;
- if(gfs2_block_check(sbp, bl, be64_to_cpu(*ea_ptr), &q)) {
- stack;
- return -1;
- }
- if(q.block_type != gfs2_meta_eattr) {
+
+ q = block_type(be64_to_cpu(*ea_ptr));
+ if(q != gfs2_meta_eattr) {
if(remove_eattr_entry(sbp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 2cfe12d..2d748e1 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -114,9 +114,9 @@ static const char *de_type_string(uint8_t de_type)
return de_types[3]; /* invalid */
}
-static int check_file_type(uint8_t de_type, uint8_t block_type)
+static int check_file_type(uint8_t de_type, uint8_t blk_type)
{
- switch(block_type) {
+ switch(blk_type) {
case gfs2_inode_dir:
if(de_type != DT_DIR)
return 1;
@@ -169,7 +169,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
uint16_t *count, void *priv)
{
struct gfs2_sbd *sbp = ip->i_sbd;
- struct gfs2_block_query q = {0};
+ uint8_t q;
char tmp_name[MAX_FILENAME];
uint64_t entryblock;
struct dir_status *ds = (struct dir_status *) priv;
@@ -247,12 +247,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 0;
}
}
- if(gfs2_block_check(sbp, bl, de->de_inum.no_addr, &q)) {
- stack;
- return -1;
- }
+ q = block_type(de->de_inum.no_addr);
/* Get the status of the directory inode */
- if(q.block_type == gfs2_bad_block) {
+ if(q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
@@ -279,10 +276,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
}
- if(q.block_type != gfs2_inode_dir && q.block_type != gfs2_inode_file &&
- q.block_type != gfs2_inode_lnk && q.block_type != gfs2_inode_blk &&
- q.block_type != gfs2_inode_chr && q.block_type != gfs2_inode_fifo &&
- q.block_type != gfs2_inode_sock) {
+ if(q != gfs2_inode_dir && q != gfs2_inode_file &&
+ q != gfs2_inode_lnk && q != gfs2_inode_blk &&
+ q != gfs2_inode_chr && q != gfs2_inode_fifo &&
+ q != gfs2_inode_sock) {
log_err( _("Directory entry '%s' at block %llu (0x%llx"
") in dir inode %llu (0x%llx"
") block type %d: %s.\n"), tmp_name,
@@ -290,7 +287,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,
- q.block_type, q.block_type == gfs2_meta_inval ?
+ q, q == gfs2_meta_inval ?
_("previously marked invalid") :
_("is not an inode"));
@@ -304,7 +301,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* If it was previously marked invalid (i.e. known
to be bad, not just a free block, etc.) then
delete any metadata it holds. If not, return. */
- if (q.block_type != gfs2_meta_inval)
+ if (q != gfs2_meta_inval)
return 1;
/* Now try to clear the dinode, if it is an dinode */
@@ -332,7 +329,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
}
- error = check_file_type(de->de_type, q.block_type);
+ error = check_file_type(de->de_type, q);
if(error < 0) {
stack;
return -1;
@@ -343,7 +340,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
de_type_string(de->de_type), tmp_name,
(unsigned long long)de->de_inum.no_addr,
(unsigned long long)de->de_inum.no_addr,
- block_type_string(&q));
+ block_type_string(q));
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);
@@ -459,7 +456,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
}
- if(q.block_type != gfs2_inode_dir) {
+ if(q != gfs2_inode_dir) {
log_err( _("Found '..' entry in directory %llu (0x%llx) "
"pointing to something that's not a directory"),
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -500,7 +497,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* After this point we're only concerned with
* directories */
- if(q.block_type != gfs2_inode_dir) {
+ if(q != gfs2_inode_dir) {
log_debug( _("Found non-dir inode dentry\n"));
increment_link(sbp, de->de_inum.no_addr);
(*count)++;
@@ -566,12 +563,10 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
if (sysinode) {
iblock = sysinode->i_di.di_num.no_addr;
- if(gfs2_block_check(sysinode->i_sbd, bl, iblock, &ds.q)) {
- iblock = sysinode->i_di.di_num.no_addr;
- }
+ ds.q = block_type(iblock);
}
pass2_fxns.private = (void *) &ds;
- if(ds.q.block_type == gfs2_bad_block) {
+ if(ds.q == gfs2_bad_block) {
/* First check that the directory's metatree is valid */
if(check_metatree(sysinode, &pass2_fxns)) {
stack;
@@ -669,7 +664,7 @@ static inline int is_system_dir(struct gfs2_sbd *sbp, uint64_t block)
int pass2(struct gfs2_sbd *sbp)
{
uint64_t i;
- struct gfs2_block_query q;
+ uint8_t q;
struct dir_status ds = {0};
struct gfs2_inode *ip;
char *filename;
@@ -706,13 +701,9 @@ int pass2(struct gfs2_sbd *sbp)
if (is_system_dir(sbp, i))
continue;
- if(gfs2_block_check(sbp, bl, i, &q)) {
- log_err( _("Can't get block %"PRIu64 " (0x%" PRIx64
- ") from block list\n"), i, i);
- return FSCK_ERROR;
- }
+ q = block_type(i);
- if(q.block_type != gfs2_inode_dir)
+ if(q != gfs2_inode_dir)
continue;
log_debug( _("Checking directory inode at block %"PRIu64" (0x%"
@@ -720,7 +711,7 @@ int pass2(struct gfs2_sbd *sbp)
memset(&ds, 0, sizeof(ds));
pass2_fxns.private = (void *) &ds;
- if(ds.q.block_type == gfs2_bad_block) {
+ if(ds.q == 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 3182db1..7d4fe41 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -25,6 +25,7 @@
#include "lost_n_found.h"
#include "link.h"
#include "metawalk.h"
+#include "util.h"
static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
uint64_t olddotdot, uint64_t block)
@@ -74,7 +75,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
struct dir_info *di)
{
struct dir_info *pdi;
- struct gfs2_block_query q_dotdot, q_treewalk;
+ uint8_t q_dotdot, q_treewalk;
di->checked = 1;
@@ -88,19 +89,8 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
PRIu64" (0x%" PRIx64 ")\n"), di->dotdot_parent,
di->dotdot_parent, di->treewalk_parent,
di->treewalk_parent);
- if(gfs2_block_check(sbp, bl, di->dotdot_parent, &q_dotdot)) {
- log_err( _("Unable to find block %"PRIu64
- " (0x%" PRIx64 ") in block map.\n"),
- di->dotdot_parent, di->dotdot_parent);
- return NULL;
- }
- if(gfs2_block_check(sbp, bl, di->treewalk_parent,
- &q_treewalk)) {
- log_err( _("Unable to find block %"PRIu64
- " (0x%" PRIx64 ") in block map\n"),
- di->treewalk_parent, di->treewalk_parent);
- return NULL;
- }
+ q_dotdot = block_type(di->dotdot_parent);
+ q_treewalk = block_type(di->treewalk_parent);
/* if the dotdot entry isn't a directory, but the
* treewalk is, treewalk is correct - if the treewalk
* entry isn't a directory, but the dotdot is, dotdot
@@ -108,8 +98,8 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
* choose? if neither are directories, we have a
* problem - need to move this directory into lost+found
*/
- if(q_dotdot.block_type != gfs2_inode_dir) {
- if(q_treewalk.block_type != gfs2_inode_dir) {
+ if(q_dotdot != gfs2_inode_dir) {
+ if(q_treewalk != gfs2_inode_dir) {
log_err( _("Orphaned directory, move to lost+found\n"));
return NULL;
}
@@ -123,7 +113,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
}
}
else {
- if(q_treewalk.block_type != gfs2_inode_dir) {
+ if(q_treewalk != gfs2_inode_dir) {
int error = 0;
log_warn( _(".. parent is valid, but treewalk"
"is bad - reattaching to lost+found"));
@@ -165,13 +155,8 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
}
}
else {
- if(gfs2_block_check(sbp, bl, di->dotdot_parent, &q_dotdot)) {
- log_err( _("Unable to find parent block %"PRIu64
- " (0x%" PRIx64 ") in block map\n"),
- di->dotdot_parent, di->dotdot_parent);
- return NULL;
- }
- if(q_dotdot.block_type != gfs2_inode_dir) {
+ q_dotdot = block_type(di->dotdot_parent);
+ if(q_dotdot != gfs2_inode_dir) {
log_err( _("Orphaned directory at block %" PRIu64 " (0x%" PRIx64
") moved to lost+found\n"), di->dinode, di->dinode);
return NULL;
@@ -193,7 +178,7 @@ int pass3(struct gfs2_sbd *sbp)
osi_list_t *tmp;
struct dir_info *di, *tdi;
struct gfs2_inode *ip;
- struct gfs2_block_query q;
+ uint8_t q;
int i;
find_di(sbp, sbp->md.rooti->i_di.di_num.no_addr, &di);
@@ -225,11 +210,8 @@ int pass3(struct gfs2_sbd *sbp)
/* FIXME: Factor this ? */
if(!tdi) {
- if(gfs2_block_check(sbp, bl, di->dinode, &q)) {
- stack;
- return FSCK_ERROR;
- }
- if(q.block_type == gfs2_bad_block) {
+ q = block_type(di->dinode);
+ if(q == gfs2_bad_block) {
log_err( _("Found unlinked directory containing bad block\n"));
if(query(
_("Clear unlinked directory with bad blocks? (y/n) "))) {
@@ -240,13 +222,13 @@ int pass3(struct gfs2_sbd *sbp)
} else
log_err( _("Unlinked directory with bad block remains\n"));
}
- if(q.block_type != gfs2_inode_dir &&
- q.block_type != gfs2_inode_file &&
- q.block_type != gfs2_inode_lnk &&
- q.block_type != gfs2_inode_blk &&
- q.block_type != gfs2_inode_chr &&
- q.block_type != gfs2_inode_fifo &&
- q.block_type != gfs2_inode_sock) {
+ if(q != gfs2_inode_dir &&
+ q != gfs2_inode_file &&
+ q != gfs2_inode_lnk &&
+ q != gfs2_inode_blk &&
+ q != gfs2_inode_chr &&
+ q != gfs2_inode_fifo &&
+ q != gfs2_inode_sock) {
log_err( _("Unlinked block marked as inode not an inode\n"));
gfs2_blockmap_set(sbp, bl, di->dinode,
gfs2_block_free);
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0c8f969..8a1f2e3 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -22,6 +22,7 @@
#include "lost_n_found.h"
#include "inode_hash.h"
#include "metawalk.h"
+#include "util.h"
struct metawalk_fxns pass4_fxns_delete = {
.private = NULL,
@@ -56,7 +57,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
struct inode_info *ii;
struct gfs2_inode *ip;
int lf_addition = 0;
- struct gfs2_block_query q;
+ uint8_t q;
/* FIXME: should probably factor this out into a generic
* scanning fxn */
@@ -72,11 +73,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
if(ii->counted_links == 0) {
log_err( _("Found unlinked inode at %" PRIu64 " (0x%" PRIx64 ")\n"),
ii->inode, ii->inode);
- if(gfs2_block_check(sbp, bl, ii->inode, &q)) {
- stack;
- return -1;
- }
- if(q.block_type == gfs2_bad_block) {
+ q = block_type(ii->inode);
+ if(q == gfs2_bad_block) {
log_err( _("Unlinked inode %llu (0x%llx) contains"
"bad blocks\n"),
(unsigned long long)ii->inode,
@@ -95,16 +93,15 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
} else
log_err( _("Unlinked inode with bad blocks not cleared\n"));
}
- if(q.block_type != gfs2_inode_dir &&
- q.block_type != gfs2_inode_file &&
- q.block_type != gfs2_inode_lnk &&
- q.block_type != gfs2_inode_blk &&
- q.block_type != gfs2_inode_chr &&
- q.block_type != gfs2_inode_fifo &&
- q.block_type != gfs2_inode_sock) {
+ if(q != gfs2_inode_dir &&
+ q != gfs2_inode_file &&
+ q != gfs2_inode_lnk &&
+ q != gfs2_inode_blk &&
+ q != gfs2_inode_chr &&
+ q != gfs2_inode_fifo &&
+ q != gfs2_inode_sock) {
log_err( _("Unlinked block marked as inode is "
- "not an inode (%d)\n"),
- q.block_type);
+ "not an inode (%d)\n"), q);
ip = fsck_load_inode(sbp, ii->inode);
if(query(_("Delete unlinked inode? (y/n) "))) {
check_inode_eattr(ip,
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index efad774..c6b005a 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -23,9 +23,9 @@
#include "fs_bits.h"
#include "util.h"
-static int convert_mark(struct gfs2_block_query *q, uint32_t *count)
+static int convert_mark(uint8_t q, uint32_t *count)
{
- switch(q->block_type) {
+ switch(q) {
case gfs2_meta_inval:
/* Convert invalid metadata to free blocks */
@@ -56,7 +56,7 @@ static int convert_mark(struct gfs2_block_query *q, uint32_t *count)
return GFS2_BLKST_USED;
default:
- log_err( _("Invalid state %d found\n"), q->block_type);
+ log_err( _("Invalid state %d found\n"), q);
return -1;
}
return -1;
@@ -68,7 +68,7 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
unsigned char *byte, *end;
unsigned int bit;
unsigned char rg_status, block_status;
- struct gfs2_block_query q;
+ uint8_t q;
uint64_t block;
static int free_unlinked = -1;
@@ -83,9 +83,9 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
warm_fuzzy_stuff(block);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
- gfs2_block_check(sbp, bl, block, &q);
+ q = block_type(block);
- block_status = convert_mark(&q, count);
+ block_status = convert_mark(q, count);
/* If one node opens a file and another node deletes it, we
may be left with a block that appears to be "unlinked" in
@@ -132,8 +132,8 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
log_err( _("Ondisk status is %u (%s) but FSCK thinks it should be "),
rg_status, blockstatus[rg_status]);
log_err("%u (%s)\n", block_status, blockstatus[block_status]);
- log_err( _("Metadata type is %u (%s)\n"), q.block_type,
- block_type_string(&q));
+ log_err( _("Metadata type is %u (%s)\n"), q,
+ block_type_string(q));
if(query( _("Fix bitmap for block %" PRIu64
" (0x%" PRIx64 ") ? (y/n) "),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 48de4bd..d0dd4af 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -125,15 +125,15 @@ void warm_fuzzy_stuff(uint64_t block)
}
}
-const char *block_type_string(struct gfs2_block_query *q)
+const char *block_type_string(uint8_t q)
{
const char *blktyp[] = {"free", "used", "indirect data", "inode",
"file", "symlink", "block dev", "char dev",
"fifo", "socket", "dir leaf", "journ data",
"other meta", "eattribute", "unused",
"invalid"};
- if (q->block_type < 16)
- return (blktyp[q->block_type]);
+ if (q < 16)
+ return (blktyp[q]);
return blktyp[15];
}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 3f9e921..3a0d959 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -14,6 +14,7 @@
#ifndef __UTIL_H__
#define __UTIL_H__
+#include "fsck.h"
#include "libgfs2.h"
#define fsck_lseek(fd, off) \
@@ -23,7 +24,19 @@ 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);
+const char *block_type_string(uint8_t q);
void gfs2_dup_set(uint64_t block);
+static inline uint8_t block_type(uint64_t bblock)
+{
+ static unsigned char *byte;
+ static uint64_t b;
+ static uint8_t btype;
+
+ byte = bl->map + BLOCKMAP_SIZE4(bblock);
+ b = BLOCKMAP_BYTE_OFFSET4(bblock);
+ btype = (*byte & (BLOCKMAP_MASK4 << b )) >> b;
+ return btype;
+}
+
#endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index e9287d1..b57f58d 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -149,21 +149,6 @@ int gfs2_blockmap_set(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
return 0;
}
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, struct gfs2_block_query *val)
-{
- static unsigned char *byte;
- static uint64_t b;
-
- if(block >= il->size)
- return -1;
-
- byte = il->map + BLOCKMAP_SIZE4(block);
- b = BLOCKMAP_BYTE_OFFSET4(block);
- val->block_type = (*byte & (BLOCKMAP_MASK4 << b )) >> b;
- return 0;
-}
-
void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
{
if(il) {
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 5ac92d1..e243d3f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -300,10 +300,6 @@ enum gfs2_mark_block {
gfs2_meta_inval = INVALID_META,
};
-struct gfs2_block_query {
- uint8_t block_type;
-};
-
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);
@@ -319,8 +315,6 @@ extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
/* gfs2_block_clear clears all the marks for the given block */
extern int gfs2_blockmap_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 */
14 years, 1 month
cluster: RHEL56 - Move duplicate code from libgfs2 to fsck.gfs2
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: b486ce1bf1519f42a252a0b49ea177a1c87b4593
Parent: 2ac3e54d005e9fdd3103bf5a78502f92ac8a4aec
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Wed Jan 20 09:47:30 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:30:00 2010 -0500
Move duplicate code from libgfs2 to fsck.gfs2
This patch removes the duplicate block management from
libgfs2 and puts it into the only code that used it: fsck.gfs2.
This has several advantages for performance and readability.
Since it no longer has to worry about duplicates, the blockmap
code in libgfs2 can do less work in places where fsck.gfs2
doesn't care one way or another if the block is a duplicate.
Conversely, the places in fsck.gfs2 that only care if the
block is a duplicate are also simplified because they don't
have to do the additional blockmap code that went along.
This also paves the way for future code simplification.
rhbz#455300
---
gfs2/fsck/eattr.c | 11 +----
gfs2/fsck/fsck.h | 7 +++
gfs2/fsck/initialize.c | 18 ++++++++-
gfs2/fsck/main.c | 1 +
gfs2/fsck/metawalk.c | 16 +++++++-
gfs2/fsck/metawalk.h | 3 +
gfs2/fsck/pass1.c | 31 ++++++--------
gfs2/fsck/pass1b.c | 24 +++++-----
gfs2/fsck/pass2.c | 8 ++--
gfs2/fsck/util.c | 17 ++++++++
gfs2/fsck/util.h | 1 +
gfs2/libgfs2/block_list.c | 101 ++++-----------------------------------------
gfs2/libgfs2/libgfs2.h | 11 -----
13 files changed, 101 insertions(+), 148 deletions(-)
diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index 68829d2..cc9fec4 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -17,17 +17,12 @@
#include "libgfs2.h"
#include "fsck.h"
+#include "eattr.h"
+#include "metawalk.h"
static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block)
{
- struct gfs2_block_query q;
-
- if(gfs2_block_check(sbp, bl, block, &q)) {
- stack;
- return -1;
- }
-
- if(q.dup_block) {
+ if(is_duplicate(block)) {
log_debug( _("Not clearing block with marked as a duplicate\n"));
return 1;
}
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index b46df92..37fe632 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -71,6 +71,12 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
gfs2_grow or something. Count the RGs by hand. */
};
+struct dup_blks {
+ osi_list_t list;
+ uint64_t block_no;
+ osi_list_t ref_inode_list;
+};
+
extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
@@ -105,5 +111,6 @@ extern int skip_this_pass, fsck_abort;
extern int errors_found, errors_corrected;
extern uint64_t last_data_block;
extern uint64_t first_data_block;
+extern struct dup_blks dup_blocks;
#endif /* _FSCK_H */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 0c0990f..7aad96e 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -72,6 +72,19 @@ static int block_mounters(struct gfs2_sbd *sbp, int block_em)
return 0;
}
+static void gfs2_dup_free(void)
+{
+ struct dup_blks *f;
+
+ while(!osi_list_empty(&dup_blocks.list)) {
+ f = osi_list_entry(dup_blocks.list.next, struct dup_blks,
+ list);
+ while (!osi_list_empty(&f->ref_inode_list))
+ osi_list_del(&f->ref_inode_list);
+ osi_list_del(&f->list);
+ free(f);
+ }
+}
/*
* empty_super_block - free all structures in the super block
@@ -104,8 +117,10 @@ static void empty_super_block(struct gfs2_sbd *sdp)
}
}
- if (bl)
+ if (bl) {
gfs2_bmap_destroy(sdp, bl);
+ gfs2_dup_free();
+ }
}
@@ -396,6 +411,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_crit( _("Please increase your swap space by that amount and run gfs2_fsck again.\n"));
goto fail;
}
+ osi_list_init(&dup_blocks.list);
return 0;
fail:
empty_super_block(sdp);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 6d19146..8d1f8e8 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -42,6 +42,7 @@ uint64_t last_data_block;
uint64_t first_data_block;
const char *prog_name = "gfs2_fsck"; /* needed by libgfs2 */
int preen = 0, force_check = 0;
+struct dup_blks dup_blocks;
/* This function is for libgfs2's sake. */
void print_it(const char *label, const char *fmt, const char *fmt2, ...)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index e5d33b1..38e9cc5 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -29,6 +29,20 @@
#define COMFORTABLE_BLKS 5242880 /* 20GB in 4K blocks */
+struct dup_blks *dupfind(uint64_t num)
+{
+ osi_list_t *head = &dup_blocks.list;
+ osi_list_t *tmp;
+ struct dup_blks *b;
+
+ for (tmp = head->next; tmp != head; tmp = tmp->next) {
+ b = osi_list_entry(tmp, struct dup_blks, list);
+ if (b->block_no == num)
+ return b;
+ }
+ return NULL;
+}
+
static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
uint64_t block)
{
@@ -1196,7 +1210,7 @@ int delete_blocks(struct gfs2_inode *ip, uint64_t block,
if (gfs2_check_range(ip->i_sbd, block) == 0) {
if (gfs2_block_check(ip->i_sbd, bl, block, &q))
return 0;
- if (!q.dup_block) {
+ if(!is_duplicate(block)) {
log_info( _("Deleting %s block %lld (0x%llx) as part "
"of inode %lld (0x%llx)\n"), btype,
(unsigned long long)block,
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 2b83229..0744ae6 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -37,6 +37,9 @@ int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
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, void *private);
+struct dup_blks *dupfind(uint64_t num);
+
+#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
/* metawalk_fxns: function pointers to check various parts of the fs
*
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 341a10b..134476b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -118,7 +118,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
if(q.block_type != gfs2_block_free) {
log_err( _("Found duplicate block referenced as metadata in "
"indirect block - was marked %d\n"), q.block_type);
- gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
+ gfs2_dup_set(block);
found_dup = 1;
}
nbh = bread(ip->i_sbd, block);
@@ -174,7 +174,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
log_err( _("Found duplicate block referenced as data at %"
PRIu64 " (0x%"PRIx64 ")\n"), block, block);
if (q.block_type != gfs2_meta_inval) {
- gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
+ gfs2_dup_set(block);
/* If the prev ref was as data, this is likely a data
block, so keep the block count for both refs. */
if (q.block_type == gfs2_block_used)
@@ -192,11 +192,11 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
marked as duplicate, but also as a data block. */
error = 1;
gfs2_block_unmark(ip->i_sbd, bl, block, gfs2_meta_inval);
- gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
+ gfs2_dup_set(block);
}
log_debug( _("Marking block %llu (0x%llx) as data block\n"),
(unsigned long long)block, (unsigned long long)block);
- gfs2_block_mark(ip->i_sbd, bl, block, gfs2_block_used);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_used);
/* This is also confusing, so I'll clarify. There are two bitmaps:
(1) The gfs2_bmap that fsck uses to keep track of what block
@@ -259,12 +259,12 @@ static int ask_remove_inode_eattr(struct gfs2_inode *ip,
if (query( _("Clear all Extended Attributes from the "
"inode? (y/n) "))) {
struct gfs2_block_query q;
-
if(gfs2_block_check(ip->i_sbd, bl, ip->i_di.di_eattr, &q)) {
stack;
return -1;
}
- if (!remove_inode_eattr(ip, bc, q.dup_block))
+ if (!remove_inode_eattr(ip, bc,
+ is_duplicate(ip->i_di.di_eattr)))
log_err( _("Extended attributes were removed.\n"));
else
log_err( _("Unable to remove inode eattr pointer; "
@@ -347,8 +347,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
if (!clear_eas(ip, bc, indirect, 1,
_("Bad indirect Extended Attribute "
"duplicate found"))) {
- gfs2_block_mark(sdp, bl, indirect,
- gfs2_dup_block);
+ gfs2_dup_set(indirect);
bc->ea_count++;
}
return 1;
@@ -366,7 +365,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)indirect,
(unsigned long long)indirect);
- gfs2_block_mark(sdp, bl, indirect, gfs2_dup_block);
+ gfs2_dup_set(indirect);
bc->ea_count++;
ret = 1;
} else {
@@ -442,7 +441,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
log_debug( _("Duplicate block found at #%lld (0x%llx).\n"),
(unsigned long long)block,
(unsigned long long)block);
- gfs2_block_mark(sdp, bl, block, gfs2_dup_block);
+ gfs2_dup_set(block);
bc->ea_count++;
brelse(leaf_bh);
return 1;
@@ -590,7 +589,7 @@ static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
stack;
return -1;
}
- if(!q.dup_block) {
+ if(!is_duplicate(block)) {
gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
}
@@ -605,7 +604,7 @@ static int clear_data(struct gfs2_inode *ip, uint64_t block, void *private)
stack;
return -1;
}
- if(!q.dup_block) {
+ if(!is_duplicate(block)) {
gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
}
@@ -625,7 +624,7 @@ static int clear_leaf(struct gfs2_inode *ip, uint64_t block,
stack;
return -1;
}
- if(!q.dup_block) {
+ if(!is_duplicate(block)) {
log_crit( _("Setting leaf #%" PRIu64 " (0x%" PRIx64 ") invalid\n"),
block, block);
if(gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free)) {
@@ -706,11 +705,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
if(q.block_type != gfs2_block_free) {
log_err( _("Found duplicate block referenced as an inode at "
"#%" PRIu64 " (0x%" PRIx64 ")\n"), block, block);
- if(gfs2_block_mark(sdp, bl, block, gfs2_dup_block)) {
- stack;
- fsck_inode_put(&ip);
- return -1;
- }
+ gfs2_dup_set(block);
fsck_inode_put(&ip);
return 0;
}
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index c9fa04f..5c6abb7 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -42,7 +42,7 @@ struct fxn_info {
};
struct dup_handler {
- struct dup_blocks *b;
+ struct dup_blks *b;
struct inode_with_dups *id;
int ref_inode_count;
int ref_count;
@@ -128,12 +128,12 @@ static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
uint16_t *count, void *priv)
{
osi_list_t *tmp1, *tmp2;
- struct dup_blocks *b;
+ struct dup_blks *b;
struct inode_with_dups *id;
struct gfs2_leaf leaf;
- osi_list_foreach(tmp1, &ip->i_sbd->dup_blocks.list) {
- b = osi_list_entry(tmp1, struct dup_blocks, list);
+ osi_list_foreach(tmp1, &dup_blocks.list) {
+ b = osi_list_entry(tmp1, struct dup_blks, list);
osi_list_foreach(tmp2, &b->ref_inode_list) {
id = osi_list_entry(tmp2, struct inode_with_dups,
list);
@@ -328,7 +328,7 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
}
/* Finds all references to duplicate blocks in the metadata */
-static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_blocks *b)
+static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_blks *b)
{
struct gfs2_inode *ip;
struct fxn_info myfi = {b->block_no, 0, 1};
@@ -382,7 +382,7 @@ static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode, struct dup_block
return 0;
}
-static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
+static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blks *b)
{
osi_list_t *tmp;
struct inode_with_dups *id;
@@ -507,7 +507,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
* use in pass2 */
int pass1b(struct gfs2_sbd *sbp)
{
- struct dup_blocks *b;
+ struct dup_blks *b;
uint64_t i;
struct gfs2_block_query q;
osi_list_t *tmp = NULL, *x;
@@ -518,7 +518,7 @@ int pass1b(struct gfs2_sbd *sbp)
log_info( _("Looking for duplicate blocks...\n"));
/* If there were no dups in the bitmap, we don't need to do anymore */
- if(osi_list_empty(&sbp->dup_blocks.list)) {
+ if(osi_list_empty(&dup_blocks.list)) {
log_info( _("No duplicate blocks found\n"));
return FSCK_OK;
}
@@ -546,8 +546,8 @@ int pass1b(struct gfs2_sbd *sbp)
(q.block_type == gfs2_inode_chr) ||
(q.block_type == gfs2_inode_fifo) ||
(q.block_type == gfs2_inode_sock)) {
- osi_list_foreach_safe(tmp, &sbp->dup_blocks.list, x) {
- b = osi_list_entry(tmp, struct dup_blocks,
+ osi_list_foreach_safe(tmp, &dup_blocks.list, x) {
+ b = osi_list_entry(tmp, struct dup_blks,
list);
if(find_block_ref(sbp, i, b)) {
stack;
@@ -565,8 +565,8 @@ int pass1b(struct gfs2_sbd *sbp)
* it later */
log_info( _("Handling duplicate blocks\n"));
out:
- osi_list_foreach_safe(tmp, &sbp->dup_blocks.list, x) {
- b = osi_list_entry(tmp, struct dup_blocks, list);
+ osi_list_foreach_safe(tmp, &dup_blocks.list, x) {
+ b = osi_list_entry(tmp, struct dup_blks, list);
if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */
handle_dup_blk(sbp, b);
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index b1eefed..2cfe12d 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -676,7 +676,7 @@ int pass2(struct gfs2_sbd *sbp)
int filename_len;
char tmp_name[256];
int error = 0;
- struct dup_blocks *b;
+ struct dup_blks *b;
/* Check all the system directory inodes. */
if (check_system_dir(sbp->md.jiinode, "jindex", build_jindex)) {
@@ -822,9 +822,9 @@ int pass2(struct gfs2_sbd *sbp)
deleting it from both inodes referencing it. Note: The other
returns from this function are premature exits of the program
and gfs2_block_list_destroy should get rid of the list for us. */
- while (!osi_list_empty(&sbp->dup_blocks.list)) {
- b = osi_list_entry(sbp->dup_blocks.list.next,
- struct dup_blocks, list);
+ while (!osi_list_empty(&dup_blocks.list)) {
+ b = osi_list_entry(dup_blocks.list.next,
+ struct dup_blks, list);
osi_list_del(&b->list);
free(b);
}
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 3d3707c..48de4bd 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -25,6 +25,7 @@
#include "libgfs2.h"
#include "fs_bits.h"
+#include "metawalk.h"
#include "util.h"
/**
@@ -195,3 +196,19 @@ int fsck_query(const char *format, ...)
opts.query = FALSE;
return ret;
}
+
+void gfs2_dup_set(uint64_t block)
+{
+ struct dup_blks *b;
+
+ if (dupfind(block))
+ return;
+ b = malloc(sizeof(struct dup_blks));
+ if (b) {
+ memset(b, 0, sizeof(*b));
+ b->block_no = block;
+ osi_list_init(&b->ref_inode_list);
+ osi_list_add(&b->list, &dup_blocks.list);
+ }
+ return;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index ffbe975..3f9e921 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -24,5 +24,6 @@ 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);
+void gfs2_dup_set(uint64_t block);
#endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 44435ff..e9287d1 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -20,15 +20,6 @@
#include "libgfs2.h"
-/* Must be kept in sync with mark_block enum in block_list.h */
-/* FIXME: Fragile */
-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,
- BAD_BLOCK, INVALID_META
-};
-
static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
{
bmap->size = size;
@@ -70,7 +61,6 @@ struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
free(il);
il = NULL;
}
- osi_list_init(&sdp->dup_blocks.list);
osi_list_init(&sdp->eattr_blocks.list);
return il;
}
@@ -87,19 +77,6 @@ void gfs2_special_free(struct special_blocks *blist)
}
}
-static void gfs2_dup_free(struct dup_blocks *blist)
-{
- struct dup_blocks *f;
-
- while(!osi_list_empty(&blist->list)) {
- f = osi_list_entry(blist->list.next, struct dup_blocks, list);
- while (!osi_list_empty(&f->ref_inode_list))
- osi_list_del(&f->ref_inode_list);
- osi_list_del(&f->list);
- free(f);
- }
-}
-
struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num)
{
osi_list_t *head = &blist->list;
@@ -114,20 +91,6 @@ struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num)
return NULL;
}
-static struct dup_blocks *dupfind(struct dup_blocks *blist, uint64_t num)
-{
- osi_list_t *head = &blist->list;
- osi_list_t *tmp;
- struct dup_blocks *b;
-
- for (tmp = head->next; tmp != head; tmp = tmp->next) {
- b = osi_list_entry(tmp, struct dup_blocks, list);
- if (b->block_no == num)
- return b;
- }
- return NULL;
-}
-
void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
{
struct special_blocks *b;
@@ -143,33 +106,6 @@ void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
return;
}
-static void gfs2_dup_set(struct dup_blocks *blocklist, uint64_t block)
-{
- struct dup_blocks *b;
-
- if (dupfind(blocklist, block))
- return;
- b = malloc(sizeof(struct dup_blocks));
- if (b) {
- memset(b, 0, sizeof(*b));
- b->block_no = block;
- osi_list_init(&b->ref_inode_list);
- osi_list_add(&b->list, &blocklist->list);
- }
- return;
-}
-
-static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
-{
- struct dup_blocks *b;
-
- b = dupfind(blocklist, block);
- if (b) {
- osi_list_del(&b->list);
- free(b);
- }
-}
-
void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
{
struct special_blocks *b;
@@ -181,39 +117,20 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
}
}
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, enum gfs2_mark_block mark)
-{
- int err = 0;
-
- if(mark == gfs2_dup_block)
- gfs2_dup_set(&sdp->dup_blocks, block);
- else
- err = gfs2_blockmap_set(sdp, 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_bmap *bmap,
uint64_t block, enum gfs2_mark_block mark)
{
- int err = 0;
-
- if (mark == gfs2_dup_block)
- gfs2_dup_clear(&sdp->dup_blocks, block);
- else {
- static unsigned char *byte;
- static uint64_t b;
+ static unsigned char *byte;
+ static uint64_t b;
- if(block > bmap->size)
- return -1;
+ if(block > bmap->size)
+ return -1;
- byte = bmap->map + BLOCKMAP_SIZE4(block);
- b = BLOCKMAP_BYTE_OFFSET4(block);
- *byte &= ~(BLOCKMAP_MASK4 << b);
- return 0;
- }
- return err;
+ byte = bmap->map + BLOCKMAP_SIZE4(block);
+ b = BLOCKMAP_BYTE_OFFSET4(block);
+ *byte &= ~(BLOCKMAP_MASK4 << b);
+ return 0;
}
int gfs2_blockmap_set(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
@@ -241,7 +158,6 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
if(block >= il->size)
return -1;
- val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0);
byte = il->map + BLOCKMAP_SIZE4(block);
b = BLOCKMAP_BYTE_OFFSET4(block);
val->block_type = (*byte & (BLOCKMAP_MASK4 << b )) >> b;
@@ -255,7 +171,6 @@ void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
free(il);
il = NULL;
}
- 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 41759a8..5ac92d1 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -113,12 +113,6 @@ struct gfs2_buffer_head {
struct gfs2_sbd *sdp;
};
-struct dup_blocks {
- osi_list_t list;
- uint64_t block_no;
- osi_list_t ref_inode_list;
-};
-
struct special_blocks {
osi_list_t list;
uint64_t block;
@@ -237,7 +231,6 @@ struct gfs2_sbd {
unsigned int writes;
int metafs_fd;
char metafs_path[PATH_MAX]; /* where metafs is mounted */
- struct dup_blocks dup_blocks;
struct special_blocks eattr_blocks;
};
@@ -305,12 +298,10 @@ enum gfs2_mark_block {
gfs2_meta_eattr = EATTR_META,
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 */
};
struct gfs2_block_query {
uint8_t block_type;
- uint8_t dup_block;
};
extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
@@ -322,8 +313,6 @@ extern int gfs2_blockmap_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);
-extern int gfs2_block_mark(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 */
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 - libgfs2: Consistent naming for blockmap functions
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 2ac3e54d005e9fdd3103bf5a78502f92ac8a4aec
Parent: 0895e0b00958a36645c5250b988c4ba4cc2939ab
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 19 18:00:45 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:29:52 2010 -0500
libgfs2: Consistent naming for blockmap functions
This patch provides for better consistency in naming of the
functions that operate on the blockmap in memory. Before,
there were functions like gfs2_bitmap_set and gfs2_set_bitmap
but one operated on the rgrp bitmap and the other operated
on the blockmap in memory. This patch makes the code more
readable and understandable. It also paves the way for later
simplification of blockmap querying and separating out the
duplicate reference management for performance purposes.
rhbz#455300
---
gfs2/edit/savemeta.c | 6 +-
gfs2/fsck/eattr.c | 2 +-
gfs2/fsck/lost_n_found.c | 2 +-
gfs2/fsck/main.c | 4 +-
gfs2/fsck/metawalk.c | 6 +-
gfs2/fsck/pass1.c | 62 ++++++++++++++--------------
gfs2/fsck/pass1b.c | 12 +++---
gfs2/fsck/pass2.c | 10 ++--
gfs2/fsck/pass3.c | 6 +-
gfs2/fsck/pass4.c | 6 +-
gfs2/libgfs2/block_list.c | 96 ++++++++++++++++----------------------------
gfs2/libgfs2/fs_ops.c | 12 ++++--
gfs2/libgfs2/libgfs2.h | 22 ++++-------
gfs2/libgfs2/misc.c | 4 +-
14 files changed, 111 insertions(+), 139 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 3017aa5..77ec485 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -621,9 +621,9 @@ void savemeta(char *out_fn, int saveoption)
log_debug("RG at %"PRIu64" is %u long\n",
rgd->ri.ri_addr, rgd->ri.ri_length);
for (i = 0; i < rgd->ri.ri_length; i++) {
- if(gfs2_block_set(&sbd, blocklist,
- rgd->ri.ri_addr + i,
- gfs2_meta_other))
+ if(gfs2_blockmap_set(&sbd, blocklist,
+ rgd->ri.ri_addr + i,
+ gfs2_meta_other))
break;
}
first = 1;
diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index af9d474..68829d2 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -32,7 +32,7 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block)
return 1;
}
- gfs2_block_set(sbp, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(sbp, bl, block, gfs2_block_free);
return 0;
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 333409a..07850de 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -60,7 +60,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
* directory or just found an old one, and we
* used that instead of the block_type to run
* this */
- gfs2_block_set(ip->i_sbd, bl,
+ gfs2_blockmap_set(ip->i_sbd, bl,
lf_dip->i_di.di_num.no_addr, gfs2_inode_dir);
increment_link(ip->i_sbd,
ip->i_sbd->md.rooti->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 48a8070..6d19146 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -185,7 +185,7 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
/* Just reuse the inode and fix the bitmap. */
if (ds.q.block_type == gfs2_block_free) {
log_info( _("The inode exists but the block is not marked 'in use'; fixing it.\n"));
- gfs2_block_set(sysinode->i_sbd, bl,
+ gfs2_blockmap_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
mark);
ds.q.block_type = mark;
@@ -204,7 +204,7 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
log_err( _("Invalid or missing %s system inode.\n"), filename);
if (query(_("Create new %s system inode? (y/n) "), filename)) {
builder(sysinode->i_sbd);
- gfs2_block_set(sysinode->i_sbd, bl,
+ gfs2_blockmap_set(sysinode->i_sbd, bl,
sysinode->i_di.di_num.no_addr,
mark);
ds.q.block_type = mark;
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 4d1985f..e5d33b1 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -608,7 +608,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
/* Endianness doesn't matter
in this case because it's
a single byte. */
- gfs2_block_set(sdp, bl,
+ gfs2_blockmap_set(sdp, bl,
ip->i_di.di_eattr,
gfs2_meta_eattr);
log_err( _("The EA was "
@@ -762,7 +762,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
if (indirect_buf->b_changed)
gfs2_set_bitmap(sdp, indirect,
GFS2_BLKST_FREE);
- gfs2_block_set(sdp, bl, indirect,
+ gfs2_blockmap_set(sdp, bl, indirect,
gfs2_block_free);
error = 1;
}
@@ -1203,7 +1203,7 @@ int delete_blocks(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);
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
gfs2_free_block(ip->i_sbd, block);
}
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 33f2dba..341a10b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -89,7 +89,7 @@ static int leaf(struct gfs2_inode *ip, uint64_t block,
log_debug( _("\tLeaf block at %15" PRIu64 " (0x%" PRIx64 ")\n"),
block, block);
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_leaf_blk);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_leaf_blk);
bc->indir_count++;
return 0;
}
@@ -105,7 +105,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
gfs2_bad_block);
log_debug( _("Bad indirect block pointer (out of range).\n"));
@@ -127,7 +127,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
log_debug( _("Bad indirect block pointer (points to "
"something that is not an indirect block).\n"));
if(!found_dup) {
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_meta_inval);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_meta_inval);
brelse(nbh);
return 1;
}
@@ -138,7 +138,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
if (!found_dup) {
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to indirect "
"block.\n"), block, block);
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_indir_blk);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_indir_blk);
}
bc->indir_count++;
@@ -160,7 +160,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
/* Mark the owner of this block with the bad_block
* designator so we know to check it for out of range
* blocks later */
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
gfs2_bad_block);
return 1;
}
@@ -201,7 +201,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
/* This is also confusing, so I'll clarify. There are two bitmaps:
(1) The gfs2_bmap that fsck uses to keep track of what block
type has been discovered, and (2) The rgrp bitmap. Function
- gfs2_block_set is used to set the former and gfs2_set_bitmap
+ gfs2_blockmap_set is used to set the former and gfs2_set_bitmap
is used to set the latter. In this function we need to set both
because we found a "data" block that could be "meta" in the rgrp
bitmap. If we don't we could run into the data block again as
@@ -239,7 +239,7 @@ static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc,
if (!duplicate) {
gfs2_set_bitmap(ip->i_sbd, ip->i_di.di_eattr,
GFS2_BLKST_FREE);
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
gfs2_block_free);
}
ip->i_di.di_eattr = 0;
@@ -300,7 +300,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
log_err( _("The bad extended attribute was "
"removed.\n"));
} else if (!duplicate) {
- gfs2_block_set(sdp, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(sdp, bl, block, gfs2_block_free);
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
log_err( _("The bad Extended Attribute was "
"removed.\n"));
@@ -327,7 +327,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
if(gfs2_check_range(sdp, indirect)) {
/*log_warn("EA indirect block #%"PRIu64" is out of range.\n",
indirect);
- gfs2_block_set(sdp, bl, parent, bad_block);*/
+ gfs2_blockmap_set(sdp, bl, parent, bad_block);*/
/* Doesn't help to mark this here - this gets checked
* in pass1c */
return 1;
@@ -373,7 +373,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
log_debug( _("Setting #%" PRIu64 " (0x%" PRIx64
") to indirect Extended Attribute block\n"),
indirect, indirect);
- gfs2_block_set(sdp, bl, indirect, gfs2_indir_blk);
+ gfs2_blockmap_set(sdp, bl, indirect, gfs2_indir_blk);
bc->ea_count++;
}
return ret;
@@ -463,7 +463,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
/* Point of confusion: We've got to set the ea block itself to
gfs2_meta_eattr here. Elsewhere we mark the inode with
gfs2_eattr_block meaning it contains an eattr for pass1c. */
- gfs2_block_set(sdp, bl, block, gfs2_meta_eattr);
+ gfs2_blockmap_set(sdp, bl, block, gfs2_meta_eattr);
bc->ea_count++;
*bh = leaf_bh;
return 0;
@@ -501,7 +501,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
(unsigned long long)ip->i_di.di_eattr,
(unsigned long long)el_blk,
(unsigned long long)el_blk);
- gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
+ gfs2_blockmap_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
@@ -532,7 +532,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)block, (unsigned long long)block);
- gfs2_block_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
+ gfs2_blockmap_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
@@ -591,7 +591,7 @@ static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
return -1;
}
if(!q.dup_block) {
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
}
return 0;
@@ -606,7 +606,7 @@ static int clear_data(struct gfs2_inode *ip, uint64_t block, void *private)
return -1;
}
if(!q.dup_block) {
- gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
return 0;
}
return 0;
@@ -628,7 +628,7 @@ static int clear_leaf(struct gfs2_inode *ip, uint64_t block,
if(!q.dup_block) {
log_crit( _("Setting leaf #%" PRIu64 " (0x%" PRIx64 ") invalid\n"),
block, block);
- if(gfs2_block_set(ip->i_sbd, bl, block, gfs2_block_free)) {
+ if(gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free)) {
stack;
return -1;
}
@@ -720,7 +720,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFDIR:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to directory inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_dir)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_dir)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -734,7 +734,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFREG:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to file inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_file)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_file)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -743,7 +743,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFLNK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to symlink inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_lnk)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_lnk)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -752,7 +752,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFBLK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to block dev inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_blk)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_blk)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -761,7 +761,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFCHR:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to char dev inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_chr)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_chr)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -770,7 +770,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFIFO:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to fifo inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_fifo)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_fifo)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -779,7 +779,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFSOCK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to socket inode.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_inode_sock)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_sock)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -788,7 +788,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
default:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to invalid.\n"),
block, block);
- if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -812,13 +812,13 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
compute_height(sdp, ip->i_di.di_size));
/* once implemented, remove continue statement */
log_warn( _("Marking inode invalid\n"));
- if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return 0;
}
@@ -833,7 +833,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(1 >> (ip->i_di.di_size/sizeof(uint64_t))));
/* once implemented, remove continue statement */
log_warn( _("Marking inode invalid\n"));
- if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -857,7 +857,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(unsigned long long)ip->i_di.di_num.no_addr);
/* FIXME: Must set all leaves invalid as well */
check_metatree(ip, &invalidate_metatree);
- gfs2_block_set(sdp, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_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);
@@ -908,7 +908,7 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
log_info( _("Found invalid metadata at #%llu (0x%llx)\n"),
(unsigned long long)block,
(unsigned long long)block);
- if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
stack;
return -1;
}
@@ -988,7 +988,7 @@ int pass1(struct gfs2_sbd *sbp)
rg_count);
rgd = osi_list_entry(tmp, struct rgrp_list, list);
for (i = 0; i < rgd->ri.ri_length; i++) {
- if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
+ if(gfs2_blockmap_set(sbp, bl, rgd->ri.ri_addr + i,
gfs2_meta_other)){
stack;
return FSCK_ERROR;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index f529b06..c9fa04f 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -189,7 +189,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
inode_hash_remove(inode_hash, ip->i_di.di_num.no_addr);
/* Setting the block to invalid means the inode is
* cleared in pass2 */
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
gfs2_meta_inval);
}
return 0;
@@ -221,7 +221,7 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
log_err( _("Inode %s is in directory %" PRIu64 " (0x%" PRIx64 ")\n"),
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
gfs2_meta_inval);
}
@@ -248,7 +248,7 @@ static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
/* mark the main eattr block invalid */
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
gfs2_meta_inval);
}
@@ -319,7 +319,7 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
/* mark the main eattr block invalid */
- gfs2_block_set(ip->i_sbd, bl, ip->i_di.di_eattr,
+ gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
gfs2_meta_inval);
}
@@ -439,7 +439,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
ip->i_di.di_num.no_addr);
/* Setting the block to invalid means the inode
is cleared in pass2 */
- gfs2_block_set(ip->i_sbd, bl,
+ gfs2_blockmap_set(ip->i_sbd, bl,
ip->i_di.di_num.no_addr,
gfs2_meta_inval);
bmodified(ip->i_bh);
@@ -487,7 +487,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
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_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
gfs2_meta_inval);
fsck_inode_put(&ip); /* out, brelse, free */
dh.ref_inode_count--;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 2642ad8..b1eefed 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -197,7 +197,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
"\tName length = %u\n"),
de->de_rec_len,
de->de_name_len);
- gfs2_block_set(sbp, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(sbp, bl, ip->i_di.di_num.no_addr,
gfs2_meta_inval);
return 1;
/* FIXME: should probably delete the entry here at the
@@ -265,7 +265,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
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_blockmap_set(sbp, bl, de->de_inum.no_addr,
gfs2_block_free);
bmodified(bh);
log_warn( _("The inode containing bad blocks was "
@@ -320,7 +320,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
fsck_inode_put(&entry_ip);
- gfs2_block_set(sbp, bl, de->de_inum.no_addr,
+ gfs2_blockmap_set(sbp, bl, de->de_inum.no_addr,
gfs2_block_free);
return 1;
@@ -584,7 +584,7 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
return -1;
}
if (error > 0)
- gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval);
+ gfs2_blockmap_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval);
if(check_inode_eattr(sysinode, &pass2_fxns)) {
stack;
@@ -764,7 +764,7 @@ int pass2(struct gfs2_sbd *sbp)
} else
log_err( _("Directory entry to invalid inode remains.\n"));
}
- gfs2_block_set(sbp, bl, i, gfs2_meta_inval);
+ gfs2_blockmap_set(sbp, bl, i, gfs2_meta_inval);
}
ip = fsck_load_inode(sbp, i);
if(!ds.dotdir) {
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index f09c2ae..3182db1 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -233,7 +233,7 @@ int pass3(struct gfs2_sbd *sbp)
log_err( _("Found unlinked directory containing bad block\n"));
if(query(
_("Clear unlinked directory with bad blocks? (y/n) "))) {
- gfs2_block_set(sbp, bl,
+ gfs2_blockmap_set(sbp, bl,
di->dinode,
gfs2_block_free);
break;
@@ -248,7 +248,7 @@ int pass3(struct gfs2_sbd *sbp)
q.block_type != gfs2_inode_fifo &&
q.block_type != gfs2_inode_sock) {
log_err( _("Unlinked block marked as inode not an inode\n"));
- gfs2_block_set(sbp, bl, di->dinode,
+ gfs2_blockmap_set(sbp, bl, di->dinode,
gfs2_block_free);
log_err( _("Cleared\n"));
break;
@@ -262,7 +262,7 @@ int pass3(struct gfs2_sbd *sbp)
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked directory has zero size.\n"));
if(query( _("Remove zero-size unlinked directory? (y/n) "))) {
- gfs2_block_set(sbp, bl,
+ gfs2_blockmap_set(sbp, bl,
di->dinode,
gfs2_block_free);
fsck_inode_put(&ip);
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index c6328b5..0c8f969 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -89,7 +89,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
check_metatree(ip, &pass4_fxns_delete);
bmodified(ip->i_bh);
fsck_inode_put(&ip);
- gfs2_block_set(sbp, bl, ii->inode,
+ gfs2_blockmap_set(sbp, bl, ii->inode,
gfs2_block_free);
continue;
} else
@@ -111,7 +111,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
bmodified(ip->i_bh);
- gfs2_block_set(sbp, bl, ii->inode,
+ gfs2_blockmap_set(sbp, bl, ii->inode,
gfs2_block_free);
log_err( _("The inode was deleted\n"));
} else {
@@ -129,7 +129,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked inode has zero size\n"));
if(query( _("Clear zero-size unlinked inode? (y/n) "))) {
- gfs2_block_set(sbp, bl, ii->inode,
+ gfs2_blockmap_set(sbp, bl, ii->inode,
gfs2_block_free);
fsck_inode_put(&ip);
continue;
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 5a23351..44435ff 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -29,17 +29,13 @@ static int mark_to_gbmap[16] = {
BAD_BLOCK, INVALID_META
};
-#define BITMAP_SIZE4(size) (size >> 1)
-#define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2)
-#define BITMAP_MASK4 (0xf)
-
-static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size)
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
{
bmap->size = size;
- /* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs
+ /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
* must be 1-based */
- bmap->mapsize = BITMAP_SIZE4(size);
+ bmap->mapsize = BLOCKMAP_SIZE4(size);
if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
return -ENOMEM;
@@ -51,36 +47,7 @@ static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size)
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) {
- byte = bmap->map + BITMAP_SIZE4(offset);
- b = BITMAP_BYTE_OFFSET4(offset);
- *byte |= (val & BITMAP_MASK4) << 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) {
- byte = bmap->map + BITMAP_SIZE4(offset);
- b = BITMAP_BYTE_OFFSET4(offset);
- *byte &= ~(BITMAP_MASK4 << b);
- return 0;
- }
- return -1;
-
-}
-
-static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap)
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
{
if(bmap->map)
free(bmap->map);
@@ -98,7 +65,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)) {
+ if(gfs2_blockmap_create(il, size)) {
*addl_mem_needed = il->mapsize;
free(il);
il = NULL;
@@ -222,62 +189,69 @@ 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
- err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]);
+ err = gfs2_blockmap_set(sdp, 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_bmap *il,
+int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
if (mark == gfs2_dup_block)
gfs2_dup_clear(&sdp->dup_blocks, block);
- else
- err = gfs2_bitmap_clear(il, block);
+ else {
+ static unsigned char *byte;
+ static uint64_t b;
+
+ if(block > bmap->size)
+ return -1;
+
+ byte = bmap->map + BLOCKMAP_SIZE4(block);
+ b = BLOCKMAP_BYTE_OFFSET4(block);
+ *byte &= ~(BLOCKMAP_MASK4 << b);
+ return 0;
+ }
return err;
}
-/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block)
+int gfs2_blockmap_set(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
+ uint64_t bblock, enum gfs2_mark_block mark)
{
- gfs2_dup_clear(&sdp->dup_blocks, block);
- return gfs2_bitmap_clear(il, block);
-}
+ static unsigned char *byte;
+ static uint64_t b;
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, enum gfs2_mark_block mark)
-{
- int err;
+ if(bblock > bmap->size)
+ return -1;
- err = gfs2_block_clear(sdp, il, block); /* clear all block status */
- if(!err)
- err = gfs2_block_mark(sdp, il, block, mark);
- return err;
+ byte = bmap->map + BLOCKMAP_SIZE4(bblock);
+ b = BLOCKMAP_BYTE_OFFSET4(bblock);
+ *byte &= ~(BLOCKMAP_MASK4 << b);
+ *byte |= (mark & BLOCKMAP_MASK4) << b;
+ return 0;
}
int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val)
{
- static char *byte;
+ static unsigned char *byte;
static uint64_t b;
if(block >= il->size)
return -1;
val->dup_block = (dupfind(&sdp->dup_blocks, block) ? 1 : 0);
- byte = il->map + BITMAP_SIZE4(block);
- b = BITMAP_BYTE_OFFSET4(block);
- val->block_type = (*byte & (BITMAP_MASK4 << b )) >> b;
+ byte = il->map + BLOCKMAP_SIZE4(block);
+ b = BLOCKMAP_BYTE_OFFSET4(block);
+ val->block_type = (*byte & (BLOCKMAP_MASK4 << b )) >> b;
return 0;
}
void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
{
if(il) {
- gfs2_bitmap_destroy(il);
+ gfs2_blockmap_destroy(il);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 4639a23..27362e1 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -351,8 +351,10 @@ struct metapath *find_metapath(struct gfs2_inode *ip, uint64_t block)
zalloc(mp, sizeof(struct metapath));
- for (i = ip->i_di.di_height; i--;)
- mp->mp_list[i] = do_div(b, sdp->sd_inptrs);
+ for (i = ip->i_di.di_height; i--;) {
+ mp->mp_list[i] = b % sdp->sd_inptrs;
+ b /= sdp->sd_inptrs;
+ }
return mp;
}
@@ -520,7 +522,8 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
if (isdir) {
lblock = offset;
- o = do_div(lblock, sdp->sd_jbsize);
+ o = lblock % sdp->sd_jbsize;
+ lblock /= sdp->sd_jbsize;
} else {
lblock = offset >> sdp->sd_sb.sb_bsize_shift;
o = offset & (sdp->bsize - 1);
@@ -596,7 +599,8 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
if (isdir) {
lblock = offset;
- o = do_div(lblock, sdp->sd_jbsize);
+ o = lblock % sdp->sd_jbsize;
+ lblock /= sdp->sd_jbsize;
} else {
lblock = offset >> sdp->sd_sb.sb_bsize_shift;
o = offset & (sdp->bsize - 1);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a7bd792..41759a8 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -72,13 +72,9 @@ do { \
#define DIV_RU(x, y) (((x) + (y) - 1) / (y))
-static __inline__ uint64_t do_div_i(uint64_t *num, unsigned int den)
-{
- unsigned int m = *num % den;
- *num /= den;
- return m;
-}
-#define do_div(n, d) do_div_i(&(n), (d))
+#define BLOCKMAP_SIZE4(size) (size >> 1)
+#define BLOCKMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2)
+#define BLOCKMAP_MASK4 (0xf)
#define SRANDOM do { srandom(time(NULL) ^ getpid()); } while (0)
#define RESRANDOM do { srandom(RANDOM(1000000000)); } while (0)
@@ -268,9 +264,7 @@ extern const char *prog_name;
struct gfs2_bmap {
uint64_t size;
uint64_t mapsize;
- int chunksize;
- int chunks_per_byte;
- char *map;
+ unsigned char *map;
};
uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap);
@@ -324,17 +318,17 @@ extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
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,
+extern int gfs2_blockmap_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);
+extern int gfs2_block_mark(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 */
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 */
-extern int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+extern int gfs2_blockmap_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);
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index 5a4e42b..e277e27 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -48,8 +48,8 @@ uint32_t compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize,
uint32_t m;
space = heightsize[x - 1] * inptrs;
- d = space;
- m = do_div(d, inptrs);
+ m = space % inptrs;
+ d = space / inptrs;
if (d != heightsize[x - 1] || m)
break;
14 years, 1 month
cluster: RHEL56 - fsck.gfs2: Verify rgrps free space against bitmap
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 0895e0b00958a36645c5250b988c4ba4cc2939ab
Parent: c418417c6c16447f388fc568dfdcc9ad0a6a0138
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 19 15:33:17 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:29:29 2010 -0500
fsck.gfs2: Verify rgrps free space against bitmap
This patch makes fsck.gfs2 check the actual bits in the rgrp
bitmaps to see how many blocks are free. It verifies that
value against the rg_free value in the rgrp. It needs to
ensure that it starts with an accurate value for rg_free because
an inaccurate value can get us into trouble and cause fsck.gfs2
to abort abnormally. This can happen in cases where it tries to
allocate blocks (for example, for lost+found metadata) when the
bitmaps say there is free space when there really isn't.
rhbz#455300
---
gfs2/fsck/initialize.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 26f6953..0c0990f 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -175,6 +175,132 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
}
/**
+ * check_rgrp_integrity - verify a rgrp free block count against the bitmap
+ */
+static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+ int *fixit, int *this_rg_fixed,
+ int *this_rg_bad)
+{
+ uint32_t rg_free, rg_reclaimed;
+ int rgb, x, y, off, bytes_to_check, total_bytes_to_check;
+ unsigned int state;
+
+ rg_free = rg_reclaimed = 0;
+ total_bytes_to_check = rgd->ri.ri_bitbytes;
+ *this_rg_fixed = *this_rg_bad = 0;
+
+ for (rgb = 0; rgb < rgd->ri.ri_length; rgb++){
+ /* Count up the free blocks in the bitmap */
+ off = (rgb) ? sizeof(struct gfs2_meta_header) :
+ sizeof(struct gfs2_rgrp);
+ if (total_bytes_to_check <= sdp->bsize - off)
+ bytes_to_check = total_bytes_to_check;
+ else
+ bytes_to_check = sdp->bsize - off;
+ total_bytes_to_check -= bytes_to_check;
+ for (x = 0; x < bytes_to_check; x++) {
+ unsigned char *byte;
+
+ byte = (unsigned char *)&rgd->bh[rgb]->b_data[off + x];
+ if (*byte == 0x55)
+ continue;
+ if (*byte == 0x00) {
+ rg_free += GFS2_NBBY;
+ continue;
+ }
+ for (y = 0; y < GFS2_NBBY; y++) {
+ state = (*byte >>
+ (GFS2_BIT_SIZE * y)) & GFS2_BIT_MASK;
+ if (state == GFS2_BLKST_USED)
+ continue;
+ if (state == GFS2_BLKST_DINODE)
+ continue;
+ if (state == GFS2_BLKST_FREE) {
+ rg_free++;
+ continue;
+ }
+ /* GFS2_BLKST_UNLINKED */
+ *this_rg_bad = 1;
+ if (!(*fixit)) {
+ if (query(_("Okay to reclaim unlinked "
+ "inodes? (y/n)")))
+ *fixit = 1;
+ }
+ if (!(*fixit))
+ continue;
+ *byte &= ~(GFS2_BIT_MASK <<
+ (GFS2_BIT_SIZE * y));
+ bmodified(rgd->bh[rgb]);
+ rg_reclaimed++;
+ rg_free++;
+ *this_rg_fixed = 1;
+ }
+ }
+ }
+ if (rgd->rg.rg_free != rg_free) {
+ *this_rg_bad = 1;
+ log_err( _("Error: resource group %lld (0x%llx): "
+ "free space (%d) does not match bitmap (%d)\n"),
+ (unsigned long long)rgd->ri.ri_addr,
+ (unsigned long long)rgd->ri.ri_addr,
+ rgd->rg.rg_free, rg_free);
+ if (rg_reclaimed)
+ log_err( _("(%d blocks were reclaimed)\n"),
+ rg_reclaimed);
+ if (query( _("Fix the rgrp free blocks count? (y/n)"))) {
+ rgd->rg.rg_free = rg_free;
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+ *this_rg_fixed = 1;
+ log_err( _("The rgrp was fixed.\n"));
+ } else
+ log_err( _("The rgrp was not fixed.\n"));
+ }
+ /*
+ else {
+ log_debug( _("Resource group %lld (0x%llx) free space "
+ "is consistent: free: %d reclaimed: %d\n"),
+ (unsigned long long)rgd->ri.ri_addr,
+ (unsigned long long)rgd->ri.ri_addr,
+ rg_free, rg_reclaimed);
+ }*/
+}
+
+/**
+ * check_rgrps_integrity - verify rgrp consistency
+ *
+ * Returns: 0 on success, 1 if errors were detected
+ */
+static int check_rgrps_integrity(struct gfs2_sbd *sdp)
+{
+ int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0;
+ int was_bad = 0, was_fixed = 0, error = 0;
+ osi_list_t *tmp;
+ struct rgrp_list *rgd;
+ int reclaim_unlinked = 0;
+
+ log_info( _("Checking the integrity of all resource groups.\n"));
+ for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+ if (fsck_abort)
+ return 0;
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ check_rgrp_integrity(sdp, rgd, &reclaim_unlinked,
+ &was_fixed, &was_bad);
+ if (was_fixed)
+ rgs_fixed++;
+ if (was_bad) {
+ error = 1;
+ rgs_bad++;
+ } else
+ rgs_good++;
+ }
+ if (rgs_bad)
+ log_err( _("RGs: Consistent: %d Inconsistent: %d Fixed: %d"
+ " Total: %d\n"),
+ rgs_good, rgs_bad, rgs_fixed, rgs_good + rgs_bad);
+ return error;
+}
+
+/**
* init_system_inodes
*
* Returns: 0 on success, -1 on failure
@@ -251,6 +377,8 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
}
log_info( _("%u resource groups found.\n"), rgcount);
+ check_rgrps_integrity(sdp);
+
/*******************************************************************
******* Now, set boundary fields in the super block *************
*******************************************************************/
14 years, 1 month
cluster: RHEL56 - gfs2: Remove buf_lists
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c418417c6c16447f388fc568dfdcc9ad0a6a0138
Parent: 1a6be82a56458a55a6e6a489c0672b1bec444704
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 19 15:05:52 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:28:27 2010 -0500
gfs2: Remove buf_lists
This patch removes once and for all the linked lists of buffer_heads
attached to the superblock. We should trust that the vfs layer of
the kernel is going to keep the blocks we most want in memory rather
than trying to do it in user space. While this was likely put in
place for performance reasons, it actually performs better with vfs
managing the buffers because we ended up spending too much time
searching through the linked lists for the buffer we need to use.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 40 ++++----
gfs2/edit/gfs2hex.c | 2 +-
gfs2/edit/hexedit.c | 47 ++++-----
gfs2/edit/savemeta.c | 25 +++--
gfs2/fsck/fs_recovery.c | 8 +-
gfs2/fsck/initialize.c | 1 -
gfs2/fsck/main.c | 10 +--
gfs2/fsck/metawalk.c | 12 +--
gfs2/fsck/pass1.c | 8 +-
gfs2/fsck/pass1b.c | 6 +-
gfs2/fsck/pass1c.c | 6 +-
gfs2/fsck/pass2.c | 6 +-
gfs2/fsck/pass3.c | 1 -
gfs2/fsck/rgrepair.c | 10 +-
gfs2/libgfs2/buf.c | 232 ++++++-------------------------------------
gfs2/libgfs2/fs_geometry.c | 2 +-
gfs2/libgfs2/fs_ops.c | 47 +++++-----
gfs2/libgfs2/gfs1.c | 8 +-
gfs2/libgfs2/libgfs2.h | 38 ++-----
gfs2/libgfs2/recovery.c | 4 +-
gfs2/libgfs2/rgrp.c | 2 +-
gfs2/libgfs2/structures.c | 8 +-
gfs2/libgfs2/super.c | 6 +-
gfs2/mkfs/main_grow.c | 3 +-
gfs2/mkfs/main_mkfs.c | 4 -
gfs2/tool/df.c | 1 -
26 files changed, 167 insertions(+), 370 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 22be04f..d05eff5 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -329,7 +329,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
if (!block)
break;
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (new)
memset(bh->b_data, 0, sbp->bsize);
gfs2_meta_header_out(&mh, bh);
@@ -502,7 +502,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_inode *ip)
osi_list_add_prev(&newblk->list, &blocks.list);
/* read the new metadata block's pointers */
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
memcpy(newblk->ptrbuf, bh->b_data +
sizeof(struct gfs_indirect), bufsize);
/* Zero the buffer so we can fill it in later */
@@ -652,20 +652,21 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
amount = size;
while (copied < size) {
- bh = bhold(ip->i_bh);
+ bh = ip->i_bh;
/* First, build up the metatree */
for (h = 0; h < blk->height; h++) {
lookup_block(ip, bh, h, &blk->mp, 1, &new, &block);
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
if (!block)
break;
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (new)
memset(bh->b_data, 0, sbp->bsize);
if (h < (blk->height - 1))
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
if (amount > sbp->bsize - ptramt)
@@ -674,7 +675,8 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
memcpy(bh->b_data + ptramt,
(char *)srcptr, amount);
srcptr += amount;
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
copied += amount;
@@ -789,7 +791,7 @@ int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_inode *ip)
/* Queue it to be processed later on in the loop. */
osi_list_add_prev(&newblk->list, &blocks.list);
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (newblk->height == ip->i_di.di_height) {
/* read in the jdata block */
memcpy(newblk->ptrbuf, bh->b_data +
@@ -1009,10 +1011,10 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
sbp->sd_sb.sb_root_dir.no_addr = block;
sbp->sd_sb.sb_root_dir.no_formal_ino = sbp->md.next_inum;
}
- bh = bread(&sbp->buf_list, block);
- if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) {/* if it is an dinode */
+ bh = bread(sbp, block);
+ if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) /* if it is an dinode */
error = adjust_inode(sbp, bh);
- } else { /* It's metadata, but not an inode, so fix the bitmap. */
+ else { /* It's metadata, but not an inode, so fix the bitmap. */
int blk, buf_offset;
int bitmap_byte; /* byte within the bitmap to fix */
int byte_bit; /* bit within the byte */
@@ -1363,10 +1365,9 @@ static int init(struct gfs2_sbd *sbp)
sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sbp->bsize = sbp->sd_sb.sb_bsize;
osi_list_init(&sbp->rglist);
- init_buf_list(sbp, &sbp->buf_list, 1 << 20); /* only use 1MB of bufs */
compute_constants(sbp);
- bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
+ bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
gfs2_sb_in(&sbp->sd_sb, bh);
@@ -1645,7 +1646,7 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
return -1;
}
for (x = 0; x < rgd->ri.ri_length; x++) {
- rgd->bh[x] = bget(&sdp->buf_list, rgd->ri.ri_addr + x);
+ rgd->bh[x] = bget(sdp, rgd->ri.ri_addr + x);
memset(rgd->bh[x]->b_data, 0, sdp->bsize);
}
if (gfs2_compute_bitstructs(sdp, rgd)) {
@@ -1802,7 +1803,7 @@ int main(int argc, char **argv)
if (error)
log_crit("%s: Unable to convert resource groups.\n",
device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Renumber the inodes consecutively. */
@@ -1811,7 +1812,7 @@ int main(int argc, char **argv)
error = inode_renumber(&sb2, sb2.sd_sb.sb_root_dir.no_addr);
if (error)
log_crit("\n%s: Error renumbering inodes.\n", device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Fix the directories to match the new numbers. */
@@ -1832,7 +1833,7 @@ int main(int argc, char **argv)
error = journ_space_to_rg(&sb2);
if (error)
log_crit("%s: Error converting journal space.\n", device);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
}
/* ---------------------------------------------- */
/* Create our system files and directories. */
@@ -1868,7 +1869,7 @@ int main(int argc, char **argv)
inode_put(&sb2.md.inum);
inode_put(&sb2.md.statfs);
- bcommit(&sb2.buf_list); /* write the buffers to disk */
+ fsync(sb2.device_fd); /* write the buffers to disk */
/* Now free all the in memory */
gfs2_rgrp_free(&sb2.rglist);
@@ -1878,13 +1879,12 @@ int main(int argc, char **argv)
/* end because if the tool is interrupted in the middle, we want */
/* it to not reject the partially converted fs as already done */
/* when it's run a second time. */
- bh = bread(&sb2.buf_list, sb2.sb_addr);
+ bh = bread(&sb2, sb2.sb_addr);
sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS;
sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI;
gfs2_sb_out(&sb2.sd_sb, bh);
brelse(bh);
- bsync(&sb2.buf_list); /* write the buffers to disk */
error = fsync(sb2.device_fd);
if (error)
perror(device);
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 20bbe42..ef76f58 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -349,7 +349,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh)
if (last >= max_block)
break;
- tmp_bh = bread(&sbd.buf_list, last);
+ tmp_bh = bread(&sbd, last);
gfs2_leaf_in(&leaf, tmp_bh);
indirect->ii[indirect_blocks].dirents = 0;
for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index b99580d..4d3d77c 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -924,7 +924,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
uint64_t rgblk;
rgblk = get_rg_addr(rgnum);
- rbh = bread(&sbd.buf_list, rgblk);
+ rbh = bread(&sbd, rgblk);
if (gfs1)
gfs_rgrp_in(&rg.rg1, rbh);
else
@@ -956,7 +956,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
brelse(rbh);
}
if (modify)
- bsync(&sbd.buf_list);
+ fsync(sbd.device_fd);
}
/* ------------------------------------------------------------------------ */
@@ -1008,7 +1008,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
else {
struct gfs2_buffer_head *tmp_bh;
- tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
+ tmp_bh = bread(&sbd, ri.ri_addr);
if (gfs1) {
struct gfs_rgrp rg1;
gfs_rgrp_in(&rg1, tmp_bh);
@@ -1657,7 +1657,7 @@ static int display_extended(void)
/* Display any indirect pointers that we have. */
if (block_is_rindex()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, TRUE);
brelse(tmp_bh);
@@ -1669,34 +1669,34 @@ static int display_extended(void)
return -1;
else if (block_is_rglist()) {
if (gfs1)
- tmp_bh = bread(&sbd.buf_list,
+ tmp_bh = bread(&sbd,
sbd1->sb_rindex_di.no_addr);
else
- tmp_bh = bread(&sbd.buf_list, masterblock("rindex"));
+ tmp_bh = bread(&sbd, masterblock("rindex"));
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, FALSE);
brelse(tmp_bh);
}
else if (block_is_jindex()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_jindex(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_inum_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_inum(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_statfs_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_statfs(tmp_inode);
brelse(tmp_bh);
}
else if (block_is_quota_file()) {
- tmp_bh = bread(&sbd.buf_list, block);
+ tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
print_quota(tmp_inode);
brelse(tmp_bh);
@@ -1716,14 +1716,13 @@ static void read_superblock(int fd)
memset(&sbd, 0, sizeof(struct gfs2_sbd));
sbd.bsize = GFS2_DEFAULT_BSIZE;
sbd.device_fd = fd;
- bh = bread(&sbd.buf_list, 0x10);
+ bh = bread(&sbd, 0x10);
sbd.jsize = GFS2_DEFAULT_JSIZE;
sbd.rgsize = GFS2_DEFAULT_RGSIZE;
sbd.utsize = GFS2_DEFAULT_UTSIZE;
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
sbd.time = time(NULL);
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */
/* Check to see if this is really gfs1 */
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -1813,7 +1812,7 @@ int display(int identify_only)
if (block_in_mem != blk) { /* If we changed blocks from the last read */
dev_offset = blk * sbd.bsize;
ioctl(sbd.device_fd, BLKFLSBUF, 0);
- if (!(bh = bread(&sbd.buf_list, blk))) {
+ if (!(bh = bread(&sbd, blk))) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
strerror(errno), __FUNCTION__, __LINE__,
@@ -1966,7 +1965,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
else
jindex_block = masterblock("jindex");
/* read in the block */
- jindex_bh = bread(&sbd.buf_list, jindex_block);
+ jindex_bh = bread(&sbd, jindex_block);
/* get the dinode data from it. */
gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
@@ -1991,7 +1990,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
struct gfs2_dinode jdi;
jblock = indirect->ii[0].dirent[journal_num + 2].block;
- j_bh = bread(&sbd.buf_list, jblock);
+ j_bh = bread(&sbd, jblock);
j_inode = inode_get(&sbd, j_bh);
gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */
*j_size = jdi.di_size;
@@ -2014,7 +2013,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
for (blk = startblk + 1; blk < last_fs_block; blk++) {
- lbh = bread(&sbd.buf_list, blk);
+ lbh = bread(&sbd, blk);
/* Can't use get_block_type here (returns false "none") */
if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 &&
lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 &&
@@ -2439,7 +2438,7 @@ static void find_print_block_type(void)
int type;
tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- lbh = bread(&sbd.buf_list, tblock);
+ lbh = bread(&sbd, tblock);
type = get_block_type(lbh);
print_block_type(tblock, type, "");
brelse(lbh);
@@ -2535,7 +2534,7 @@ static void find_change_block_alloc(int *newval)
}
gfs2_rgrp_free(&sbd.rglist);
if (newval)
- bcommit(&sbd.buf_list);
+ fsync(sbd.device_fd);
exit(0);
}
@@ -2550,7 +2549,7 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
struct gfs2_rgrp rg;
fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- rbh = bread(&sbd.buf_list, block);
+ rbh = bread(&sbd, block);
type = get_block_type(rbh);
switch (type) {
@@ -2603,10 +2602,8 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
" which is not implemented");
break;
}
- if (newval)
- bmodified(rbh);
brelse(rbh);
- bcommit(&sbd.buf_list);
+ fsync(sbd.device_fd);
}
/* ------------------------------------------------------------------------ */
@@ -2988,7 +2985,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
block_map(ip, lblock, ¬_new, &dblock, &extlen,
FALSE);
if (dblock) {
- lbh = bread(&sdp->buf_list, dblock);
+ lbh = bread(sdp, dblock);
if (*abs_block == 0)
*abs_block = lbh->b_blocknr;
dblock++;
@@ -3046,7 +3043,7 @@ static void dump_journal(const char *journal)
if (!jblock)
return;
if (!gfs1) {
- j_bh = bread(&sbd.buf_list, jblock);
+ j_bh = bread(&sbd, jblock);
j_inode = inode_get(&sbd, j_bh);
jbuf = malloc(sbd.bsize);
}
@@ -3055,7 +3052,7 @@ static void dump_journal(const char *journal)
if (gfs1) {
if (j_bh)
brelse(j_bh);
- j_bh = bread(&sbd.buf_list, jblock + jb);
+ j_bh = bread(&sbd, jblock + jb);
abs_block = jblock + jb;
dummy_bh.b_data = j_bh->b_data;
} else {
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 1e533a6..3017aa5 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -202,7 +202,7 @@ static int save_block(int fd, int out_fd, uint64_t blk)
return 0;
}
memset(savedata, 0, sizeof(struct saved_metablock));
- savebh = bread(&sbd.buf_list, blk);
+ savebh = bread(&sbd, blk);
memcpy(&savedata->buf, savebh->b_data, sbd.bsize);
/* If this isn't metadata and isn't a system file, we don't want it.
@@ -284,12 +284,12 @@ static void save_indirect_blocks(int out_fd, osi_list_t *cur_list,
old_block = indir_block;
blktype = save_block(sbd.device_fd, out_fd, indir_block);
if (blktype == GFS2_METATYPE_EA) {
- nbh = bread(&sbd.buf_list, indir_block);
+ nbh = bread(&sbd, indir_block);
save_ea_block(out_fd, nbh);
brelse(nbh);
}
if (height != hgt) { /* If not at max height */
- nbh = bread(&sbd.buf_list, indir_block);
+ nbh = bread(&sbd, indir_block);
osi_list_add_prev(&nbh->b_altlist,
cur_list);
brelse(nbh);
@@ -323,7 +323,7 @@ static void save_inode_data(int out_fd)
for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
osi_list_init(&metalist[i]);
- metabh = bread(&sbd.buf_list, block);
+ metabh = bread(&sbd, block);
if (gfs1)
inode = inode_get(&sbd, metabh);
else
@@ -374,7 +374,7 @@ static void save_inode_data(int out_fd)
struct gfs2_meta_header mh;
struct gfs2_buffer_head *lbh;
- lbh = bread(&sbd.buf_list, inode->i_di.di_eattr);
+ lbh = bread(&sbd, inode->i_di.di_eattr);
save_block(sbd.device_fd, out_fd, inode->i_di.di_eattr);
gfs2_meta_header_in(&mh, lbh);
if (mh.mh_magic == GFS2_MAGIC &&
@@ -468,8 +468,8 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
}
for(; i < length; i++){
bits = &rgd->bits[i];
- lbh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
- blk = gfs2_bitfit((unsigned char *)bh->b_data +
+ lbh = bread(sdp, rgd->ri.ri_addr + i);
+ blk = gfs2_bitfit((unsigned char *)lbh->b_data +
bits->bi_offset, bits->bi_len, blk,
GFS2_BLKST_UNLINKED);
brelse(lbh);
@@ -523,7 +523,6 @@ 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, 1 << 20);
if (!gfs1)
sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
compute_constants(&sbd);
@@ -565,7 +564,7 @@ void savemeta(char *out_fn, int saveoption)
&sbd.md.riinode);
jindex_block = masterblock("jindex");
}
- lbh = bread(&sbd.buf_list, jindex_block);
+ lbh = bread(&sbd, jindex_block);
gfs2_dinode_in(&di, lbh);
if (!gfs1)
do_dinode_extended(&di, lbh);
@@ -726,6 +725,8 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
blks_saved = total_out = 0;
last_fs_block = 0;
while (TRUE) {
+ struct gfs2_buffer_head dummy_bh;
+
memset(savedata, 0, sizeof(struct saved_metablock));
rs = read(in_fd, &buf64, sizeof(uint64_t));
if (!rs)
@@ -767,8 +768,9 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
if (first) {
struct gfs2_sb bufsb;
+ dummy_bh.b_data = (char *)&bufsb;
memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, (void *)&bufsb);
+ gfs2_sb_in(&sbd.sd_sb, &dummy_bh);
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
sbd1->sb_header.mh_type ==
@@ -796,12 +798,13 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
}
first = 0;
}
+ bh = &dummy_bh;
+ bh->b_data = savedata->buf;
if (printblocksonly) {
block = savedata->blk;
if (block > highest_valid_block)
highest_valid_block = block;
if (printblocksonly > 1 && printblocksonly == block) {
- memcpy(bh->b_data, savedata->buf, sbd.bsize);
block_in_mem = block;
display(0);
return 0;
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index cbc5fe2..fd61821 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -133,7 +133,7 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
if (error)
return error;
- bh_ip = bget(&sdp->buf_list, blkno);
+ bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
check_magic = ((struct gfs2_meta_header *)
@@ -230,7 +230,7 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
if (error)
return error;
- bh_ip = bget(&sdp->buf_list, blkno);
+ bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
/* Unescape */
@@ -385,7 +385,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip)
prev_seq = lh.lh_sequence;
log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence);
block_map(ip, blk, &new, &dblock, &extlen, FALSE);
- bh = bread(&ip->i_sbd->buf_list, dblock);
+ bh = bread(ip->i_sbd, dblock);
gfs2_log_header_out(&lh, bh);
brelse(bh);
}
@@ -594,6 +594,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
inode_put(&sdp->master_dir);
inode_put(&sdp->md.jiinode);
/* Sync the buffers to disk so we get a fresh start. */
- bsync(&sdp->buf_list);
+ fsync(sdp->device_fd);
return error;
}
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f6746e7..26f6953 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -292,7 +292,6 @@ static int fill_super_block(struct gfs2_sbd *sdp)
********************************************************************/
log_info( _("Initializing lists...\n"));
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 1 << 20);
for(i = 0; i < FSCK_HASH_SIZE; i++) {
osi_list_init(&dir_hash[i]);
osi_list_init(&inode_hash[i]);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 4fd7a09..48a8070 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -362,8 +362,6 @@ int main(int argc, char **argv)
int j;
int error = 0;
int all_clean = 0;
- osi_list_t *tmp;
- struct rgrp_list *rgd;
setlocale(LC_ALL, "");
textdomain("gfs2-utils");
@@ -499,13 +497,7 @@ int main(int argc, char **argv)
if (!opts.no && errors_corrected)
log_notice( _("Writing changes to disk\n"));
-
- for (tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
- gfs2_rgrp_relse(rgd);
- }
-
- bsync(&sbp->buf_list);
+ fsync(sbp->device_fd);
destroy(sbp);
log_notice( _("gfs2_fsck complete \n"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index b29224f..4d1985f 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -361,7 +361,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (first_leaf_ptr == -1)
first_leaf_ptr = first_ok_leaf;
if(gfs2_check_range(ip->i_sbd, first_ok_leaf) == 0) {
- lbh = bread(&sbp->buf_list, first_ok_leaf);
+ lbh = bread(sbp, first_ok_leaf);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
brelse(lbh);
@@ -405,7 +405,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (query( _("Attempt to fix it? (y/n) "))) {
int factor = 0, divisor = ref_count;
- lbh = bread(&sbp->buf_list, old_leaf);
+ lbh = bread(sbp, old_leaf);
while (divisor > 1) {
factor++;
divisor /= 2;
@@ -442,7 +442,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
/* Try to read in the leaf block. */
- lbh = bread(&sbp->buf_list, leaf_no);
+ lbh = bread(sbp, leaf_no);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
warn_and_patch(ip, &leaf_no, &bad_leaf,
@@ -508,7 +508,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
if(count != leaf.lf_entries) {
- lbh = bread(&sbp->buf_list, leaf_no);
+ lbh = bread(sbp, leaf_no);
gfs2_leaf_in(&leaf, lbh);
log_err( _("Leaf %llu (0x%llx) entry "
@@ -878,9 +878,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
continue;
}
if(!nbh)
- nbh = bread(&ip->i_sbd->buf_list,
- block);
-
+ nbh = bread(ip->i_sbd, block);
osi_list_add(&nbh->b_altlist, cur_list);
} /* for all data on the indirect block */
} /* for blocks at that height */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index e00b7d6..33f2dba 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -121,7 +121,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
found_dup = 1;
}
- nbh = bread(&ip->i_sbd->buf_list, block);
+ nbh = bread(ip->i_sbd, block);
if (gfs2_check_meta(nbh, GFS2_METATYPE_IN)){
log_debug( _("Bad indirect block pointer (points to "
@@ -341,7 +341,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
check if it really is an EA. If it is, let duplicate
handling sort it out. If it isn't, clear it but don't
count it as a duplicate. */
- *bh = bread(&sdp->buf_list, indirect);
+ *bh = bread(sdp, indirect);
if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
if (!clear_eas(ip, bc, indirect, 1,
@@ -425,7 +425,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
/* Special duplicate processing: If we have an EA block, check if it
really is an EA. If it is, let duplicate handling sort it out.
If it isn't, clear it but don't count it as a duplicate. */
- leaf_bh = bread(&sdp->buf_list, block);
+ leaf_bh = bread(sdp, block);
if(gfs2_check_meta(leaf_bh, btype)) {
if(q.block_type != gfs2_block_free) { /* Duplicate? */
clear_eas(ip, bc, block, 1,
@@ -1011,7 +1011,7 @@ int pass1(struct gfs2_sbd *sbp)
skip_this_pass = FALSE;
fflush(stdout);
}
- bh = bread(&sbp->buf_list, block);
+ bh = bread(sbp, block);
if (scan_meta(sbp, bh, block)) {
stack;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 3121d4c..f529b06 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -80,7 +80,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *indir_bh = NULL;
inc_if_found(block, 0, private);
- indir_bh = bread(&sbp->buf_list, block);
+ indir_bh = bread(sbp, block);
*bh = indir_bh;
return 0;
@@ -94,7 +94,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head *leaf_bh = NULL;
inc_if_found(block, 0, private);
- leaf_bh = bread(&sbp->buf_list, block);
+ leaf_bh = bread(sbp, block);
*bh = leaf_bh;
return 0;
@@ -417,7 +417,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
struct gfs2_buffer_head *bh;
uint32_t cmagic;
- bh = bread(&sbp->buf_list, b->block_no);
+ bh = bread(sbp, b->block_no);
cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
brelse(bh);
if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 3595bb1..514afac 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -113,7 +113,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
return ask_remove_eattr(ip);
}
else
- indir_bh = bread(&sbp->buf_list, block);
+ indir_bh = bread(sbp, block);
*bh = indir_bh;
return 0;
@@ -145,7 +145,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
return ask_remove_eattr(ip);
}
else
- *bh = bread(&sbp->buf_list, block);
+ *bh = bread(sbp, block);
return 0;
}
@@ -265,7 +265,7 @@ int pass1c(struct gfs2_sbd *sbp)
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return FSCK_OK;
- bh = bread(&sbp->buf_list, block_no);
+ bh = bread(sbp, block_no);
if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */
log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"),
block_no, block_no);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 8e4f05b..2642ad8 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -92,14 +92,14 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
{
- *bh = bread(&ip->i_sbd->buf_list, block);
+ *bh = bread(ip->i_sbd, block);
return 0;
}
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
{
- *bh = bread(&ip->i_sbd->buf_list, block);
+ *bh = bread(ip->i_sbd, block);
return 0;
}
@@ -308,7 +308,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 1;
/* Now try to clear the dinode, if it is an dinode */
- bhi = bread(&sbp->buf_list, de->de_inum.no_addr);
+ bhi = bread(sbp, de->de_inum.no_addr);
error = gfs2_check_meta(bhi, GFS2_METATYPE_DI);
bmodified(bhi);
brelse(bhi);
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index c4ea3a5..f09c2ae 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -66,7 +66,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
increment_link(sbp, newdotdot);
bmodified(ip->i_bh);
fsck_inode_put(&ip);
- bmodified(pip->i_bh);
fsck_inode_put(&pip);
return 0;
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index a20e9c5..9d7653a 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -67,7 +67,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp)
block_map(ip, b, &new, &dblock, &extlen, 0);
if (!dblock)
break;
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
if (!gfs2_check_meta(bh, GFS2_METATYPE_RG)) {
log_debug( _("False RG found at block "
"0x%" PRIx64 "\n"), dblock);
@@ -141,7 +141,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (blk = sdp->sb_addr + 1;
blk < sdp->device.length && number_of_rgs < 6;
blk++) {
- bh = bread(&sdp->buf_list, blk);
+ bh = bread(sdp, blk);
if (((blk == sdp->sb_addr + 1) ||
(!gfs2_check_meta(bh, GFS2_METATYPE_RG))) &&
!is_false_rg(blk)) {
@@ -219,7 +219,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (blk = sdp->sb_addr + 1; blk <= sdp->device.length;
blk += block_bump) {
log_debug( _("Block 0x%" PRIx64 "\n"), blk);
- bh = bread(&sdp->buf_list, blk);
+ bh = bread(sdp, blk);
rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
brelse(bh);
/* Allocate a new RG and index. */
@@ -253,7 +253,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
for (fwd_block = blk + 1;
fwd_block < sdp->device.length;
fwd_block++) {
- bh = bread(&sdp->buf_list, fwd_block);
+ bh = bread(sdp, fwd_block);
bitmap_was_fnd =
(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
brelse(bh);
@@ -389,7 +389,7 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
(int)x+1, (int)rg->ri.ri_length);
if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
- rg->bh[x] = bread(&sdp->buf_list, rg->ri.ri_addr + x);
+ rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
if (x) {
struct gfs2_meta_header mh;
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 65136f2..4d5f2b5 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -25,117 +25,18 @@
#include "libgfs2.h"
-static __inline__ osi_list_t *
-blkno2head(struct buf_list *bl, uint64_t blkno)
-{
- return bl->buf_hash +
- (gfs2_disk_hash((char *)&blkno, sizeof(uint64_t)) & BUF_HASH_MASK);
-}
-
-static int write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
-{
- struct gfs2_sbd *sdp = bl->sbp;
-
- osi_list_del(&bh->b_list);
- osi_list_del(&bh->b_hash);
- bl->num_bufs--;
- if (bh->b_changed) {
- if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize,
- SEEK_SET) != bh->b_blocknr * sdp->bsize) {
- return -1;
- }
- if (write(sdp->device_fd, bh->b_data, sdp->bsize) !=
- sdp->bsize) {
- return -1;
- }
- sdp->writes++;
- }
- bh->b_blocknr = -1;
- bh->b_data = NULL;
- bh->b_count = -1;
- bh->b_changed = -1;
- free(bh);
- return 0;
-}
-
-void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit)
-{
- int i;
-
- bl->num_bufs = 0;
- bl->spills = 0;
- bl->limit = limit;
- bl->sbp = sdp;
- osi_list_init(&bl->list);
- for(i = 0; i < BUF_HASH_SIZE; i++)
- osi_list_init(&bl->buf_hash[i]);
-}
-
-static void
-add_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
-{
- osi_list_t *head = blkno2head(bl, bh->b_blocknr);
-
- osi_list_add(&bh->b_list, &bl->list);
- osi_list_add(&bh->b_hash, head);
- bl->num_bufs++;
-
- if (bl->num_bufs * bl->sbp->bsize > bl->limit) {
- int found = 0;
- osi_list_t *tmp, *x;
-
- for (tmp = bl->list.prev, x = tmp->prev; tmp != &bl->list;
- tmp = x, x = x->prev) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head,
- b_list);
- if (!bh->b_count) {
- write_buffer(bl, bh);
- found++;
- if (found >= 10)
- break;
- }
- }
- bl->spills++;
- }
-}
-
-struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num)
-{
- osi_list_t *head = blkno2head(bl, num);
- osi_list_t *tmp;
- struct gfs2_buffer_head *bh;
-
- for (tmp = head->next; tmp != head; tmp = tmp->next) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_hash);
- if (bh->b_blocknr == num) {
- osi_list_del(&bh->b_list);
- osi_list_add(&bh->b_list, &bl->list);
- osi_list_del(&bh->b_hash);
- osi_list_add(&bh->b_hash, head);
- bh->b_count++;
- return bh;
- }
- }
-
- return NULL;
-}
-
-struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, uint64_t num,
- int find_existing, int read_disk,
- int line, const char *caller)
+struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, uint64_t num,
+ int read_disk,
+ int line, const char *caller)
{
struct gfs2_buffer_head *bh;
- struct gfs2_sbd *sdp = bl->sbp;
- if (find_existing) {
- bh = bfind(bl, num);
- if (bh)
- return bh;
- }
- zalloc(bh, sizeof(struct gfs2_buffer_head) + sdp->bsize);
+ bh = calloc(1, sizeof(struct gfs2_buffer_head) + sdp->bsize);
+ if (bh == NULL)
+ return NULL;
- bh->b_count = 1;
bh->b_blocknr = num;
+ bh->sdp = sdp;
bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head);
if (read_disk) {
if (lseek(sdp->device_fd, num * sdp->bsize, SEEK_SET) !=
@@ -154,116 +55,47 @@ struct gfs2_buffer_head *__bget_generic(struct buf_list *bl, uint64_t num,
exit(-1);
}
}
- add_buffer(bl, bh);
- bh->b_changed = FALSE;
-
return bh;
}
-struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num, int line,
+struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num, int line,
const char *caller)
{
- return __bget_generic(bl, num, TRUE, FALSE, line, caller);
+ return __bget_generic(sdp, num, FALSE, line, caller);
}
-struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num, int line,
+struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
const char *caller)
{
- return __bget_generic(bl, num, TRUE, TRUE, line, caller);
+ return __bget_generic(sdp, num, TRUE, line, caller);
}
-struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh)
+int bwrite(struct gfs2_buffer_head *bh)
{
- if (!bh->b_count) {
- stack;
- die("buffer hold error for block %" PRIu64 " (0x%" PRIx64")\n",
- bh->b_blocknr, bh->b_blocknr);
- }
- bh->b_count++;
- return bh;
-}
-
-void bmodified(struct gfs2_buffer_head *bh)
-{
- bh->b_changed = 1;
-}
+ struct gfs2_sbd *sdp = bh->sdp;
-void brelse(struct gfs2_buffer_head *bh)
-{
- /* We can't just say b_changed = updated because we don't want to */
- /* set it FALSE if it's TRUE until we write the changed data to disk. */
- if (!bh->b_count) {
- stack;
- die("buffer count underflow for block %" PRIu64 " (0x%" PRIx64")\n",
- bh->b_blocknr, bh->b_blocknr);
+ if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize, SEEK_SET) !=
+ bh->b_blocknr * sdp->bsize) {
+ return -1;
}
- bh->b_count--;
-}
-
-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) {
- 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);
+ if (write(sdp->device_fd, bh->b_data, sdp->bsize) != sdp->bsize)
+ return -1;
+ sdp->writes++;
+ bh->b_changed = 0;
+ return 0;
}
-/* commit buffers to disk but do not discard */
-void __bcommit(struct buf_list *bl, int line, const char *caller)
+int brelse(struct gfs2_buffer_head *bh)
{
- osi_list_t *tmp, *x;
- struct gfs2_buffer_head *bh;
- struct gfs2_sbd *sdp = bl->sbp;
+ int error = 0;
- osi_list_foreach_safe(tmp, &bl->list, x) {
- bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
- if (!bh->b_count) { /* if not reserved for later */
- if (write_buffer(bl, bh)) { /* write & free */
- fprintf(stderr, "bad write: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- } else if (bh->b_changed) { /* if buffer has changed */
- if (lseek(sdp->device_fd,
- bh->b_blocknr * sdp->bsize, SEEK_SET) !=
- bh->b_blocknr * sdp->bsize) {
- fprintf(stderr, "bad seek: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- if (write(sdp->device_fd, bh->b_data, sdp->bsize) !=
- sdp->bsize) {
- fprintf(stderr, "bad write: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- strerror(errno), caller, line,
- (unsigned long long)bh->b_blocknr,
- (unsigned long long)bh->b_blocknr);
- exit(-1);
- }
- bh->b_changed = FALSE; /* no longer changed */
- }
- }
- fsync(sdp->device_fd);
+ if (bh->b_blocknr == -1)
+ printf("Double free!\n");
+ if (bh->b_changed)
+ error = bwrite(bh);
+ bh->b_blocknr = -1;
+ if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist))
+ osi_list_del(&bh->b_altlist);
+ free(bh);
+ return error;
}
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index ea72e3d..28de184 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -222,7 +222,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
if (do_write) {
for (x = 0; x < bitblocks; x++) {
- bh = bget(&sdp->buf_list, rl->start + x);
+ bh = bget(sdp, rl->start + x);
if (x)
gfs2_meta_header_out(&mh, bh);
else
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index fccbfd3..4639a23 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -56,7 +56,7 @@ struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
exit(-1);
}
- ip->i_bh = bread(&sdp->buf_list, di_addr);
+ ip->i_bh = bread(sdp, di_addr);
gfs2_dinode_in(&ip->i_di, ip->i_bh);
ip->i_sbd = sdp;
ip->bh_owned = 1; /* We did the bread so we own the bh */
@@ -238,7 +238,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
if (ip->i_di.di_size) {
if (isdir) {
block = meta_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -254,7 +254,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
brelse(bh);
} else {
block = data_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
buffer_copy_tail(sdp, bh, 0,
ip->i_bh, sizeof(struct gfs2_dinode));
@@ -316,7 +316,7 @@ void build_height(struct gfs2_inode *ip, int height)
if (new_block) {
block = meta_alloc(ip);
- bh = bget(&sdp->buf_list, block);
+ bh = bget(sdp, block);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -437,7 +437,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
if (*new) {
struct gfs2_meta_header mh;
- bh = bget(&sdp->buf_list, *dblock);
+ bh = bget(sdp, *dblock);
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
@@ -446,7 +446,7 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
if (*dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, *dblock);
+ bh = bread(sdp, *dblock);
}
}
@@ -544,7 +544,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
if (dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
dblock++;
extlen--;
} else
@@ -618,7 +618,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
}
if (new) {
- bh = bget(&sdp->buf_list, dblock);
+ bh = bget(sdp, dblock);
if (isdir) {
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -630,7 +630,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
if (dblock == ip->i_di.di_num.no_addr)
bh = ip->i_bh;
else
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
}
copy_from_mem(bh, &buf, o, amount);
if (bh != ip->i_bh)
@@ -672,12 +672,12 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn,
ip->i_di.di_size = (lbn + 1) << sdp->sd_sb.sb_bsize_shift;
}
if (new)
- return bget(&sdp->buf_list, dbn);
+ return bget(sdp, dbn);
else {
if (dbn == ip->i_di.di_num.no_addr)
return ip->i_bh;
else
- return bread(&sdp->buf_list, dbn);
+ return bread(sdp, dbn);
}
}
@@ -843,7 +843,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
int count;
bn = meta_alloc(dip);
- nbh = bget(&dip->i_sbd->buf_list, bn);
+ nbh = bget(dip->i_sbd, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -855,7 +855,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
nleaf = (struct gfs2_leaf *)nbh->b_data;
nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
- obh = bread(&dip->i_sbd->buf_list, leaf_no);
+ obh = bread(dip->i_sbd, leaf_no);
oleaf = (struct gfs2_leaf *)obh->b_data;
len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
@@ -988,7 +988,7 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
{
int error = 0;
- *bhp = bread(&dip->i_sbd->buf_list, leaf_no);
+ *bhp = bread(dip->i_sbd, leaf_no);
if (error)
return error;
error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF);
@@ -1012,7 +1012,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
uint64_t leaf_no;
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
- *bh_out = bread(&dip->i_sbd->buf_list, leaf_no);
+ *bh_out = bread(dip->i_sbd, leaf_no);
return 0;
}
@@ -1034,7 +1034,7 @@ static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in,
if (!leaf->lf_next)
return -1;
- *bh_out = bread(&dip->i_sbd->buf_list, be64_to_cpu(leaf->lf_next));
+ *bh_out = bread(dip->i_sbd, be64_to_cpu(leaf->lf_next));
return 0;
}
@@ -1059,7 +1059,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
for (;;) {
- bh = bread(&dip->i_sbd->buf_list, leaf_no);
+ bh = bread(dip->i_sbd, leaf_no);
leaf = (struct gfs2_leaf *)bh->b_data;
if (dirent_alloc(dip, bh, len, &dent)) {
@@ -1081,7 +1081,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
} else {
bn = meta_alloc(dip);
- nbh = bget(&dip->i_sbd->buf_list, bn);
+ nbh = bget(dip->i_sbd, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -1131,7 +1131,7 @@ static void dir_make_exhash(struct gfs2_inode *dip)
uint64_t *lp, bn;
bn = meta_alloc(dip);
- bh = bget(&sdp->buf_list, bn);
+ bh = bget(sdp, bn);
{
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
@@ -1180,6 +1180,7 @@ static void dir_make_exhash(struct gfs2_inode *dip)
dip->i_di.di_depth = y;
gfs2_dinode_out(&dip->i_di, dip->i_bh);
+ bwrite(dip->i_bh);
}
static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1217,7 +1218,7 @@ init_dinode(struct gfs2_sbd *sdp, struct gfs2_inum *inum,
struct gfs2_buffer_head *bh;
struct gfs2_dinode di;
- bh = bget(&sdp->buf_list, inum->no_addr);
+ bh = bget(sdp, inum->no_addr);
memset(&di, 0, sizeof(struct gfs2_dinode));
di.di_header.mh_magic = GFS2_MAGIC;
@@ -1543,7 +1544,7 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len)
gfs2_get_leaf_nr(dip, lindex, &leaf_no);
while(leaf_no && !found){
- bh = bread(&dip->i_sbd->buf_list, leaf_no);
+ bh = bread(dip->i_sbd, leaf_no);
error = leaf_search(dip, bh, filename, len, &cur, &prev);
if (error) {
if(error != -ENOENT){
@@ -1683,7 +1684,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
osi_list_init(&metalist[h]);
- bh = bread(&sdp->buf_list, diblock);
+ bh = bread(sdp, diblock);
ip = inode_get(sdp, bh);
height = ip->i_di.di_height;
osi_list_add(&bh->b_altlist, &metalist[0]);
@@ -1708,7 +1709,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
if (h == height - 1) /* if not metadata */
continue; /* don't queue it up */
/* Read the next metadata block in the chain */
- nbh = bread(&sdp->buf_list, block);
+ nbh = bread(sdp, block);
osi_list_add(&nbh->b_altlist, next_list);
brelse(nbh);
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5232c01..5cced66 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -110,13 +110,13 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
if (*new) {
struct gfs2_meta_header mh;
- bh = bget(&sdp->buf_list, *dblock);
+ bh = bget(sdp, *dblock);
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
gfs2_meta_header_out(&mh, bh);
} else {
- bh = bread(&sdp->buf_list, *dblock);
+ bh = bread(sdp, *dblock);
}
}
@@ -199,7 +199,7 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
&extlen, FALSE);
if (dblock) {
- bh = bread(&sdp->buf_list, dblock);
+ bh = bread(sdp, dblock);
dblock++;
extlen--;
} else
@@ -412,7 +412,7 @@ struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
exit(-1);
}
- ip->i_bh = bread(&sdp->buf_list, di_addr);
+ ip->i_bh = bread(sdp, di_addr);
gfs_dinode_in(&gfs1_dinode, ip->i_bh);
memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
sizeof(struct gfs2_meta_header));
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a6b9314..a7bd792 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -110,15 +110,11 @@ struct rgrp_list {
};
struct gfs2_buffer_head {
- osi_list_t b_list;
- osi_list_t b_hash;
osi_list_t b_altlist; /* alternate list */
-
- unsigned int b_count;
uint64_t b_blocknr;
- char *b_data;
-
int b_changed;
+ char *b_data;
+ struct gfs2_sbd *sdp;
};
struct dup_blocks {
@@ -179,15 +175,6 @@ struct master_dir
struct per_node *pn; /* Array of per_node entries */
};
-struct buf_list {
- unsigned int num_bufs;
- unsigned int spills;
- uint32_t limit;
- osi_list_t list;
- struct gfs2_sbd *sbp;
- osi_list_t buf_hash[BUF_HASH_SIZE];
-};
-
struct gfs2_sbd {
struct gfs2_sb sd_sb; /* a copy of the ondisk structure */
char lockproto[GFS2_LOCKNAME_LEN];
@@ -248,8 +235,6 @@ struct gfs2_sbd {
unsigned int orig_journals;
- struct buf_list buf_list; /* transient buffer list */
-
struct gfs2_inode *master_dir;
struct master_dir md;
@@ -356,21 +341,18 @@ extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
-extern void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
-extern struct gfs2_buffer_head *bfind(struct buf_list *bl, uint64_t num);
-extern struct gfs2_buffer_head *__bget_generic(struct buf_list *bl,
- uint64_t num, int find_existing,
+extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp,
+ uint64_t num,
int read_disk, int line,
const char *caller);
-extern struct gfs2_buffer_head *__bget(struct buf_list *bl, uint64_t num,
+extern struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
-extern struct gfs2_buffer_head *__bread(struct buf_list *bl, uint64_t num,
+extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
-extern struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh);
-extern void bmodified(struct gfs2_buffer_head *bh);
-extern void brelse(struct gfs2_buffer_head *bh);
-extern void __bsync(struct buf_list *bl, int line, const char *caller);
-extern void __bcommit(struct buf_list *bl, int line, const char *caller);
+extern int bwrite(struct gfs2_buffer_head *bh);
+extern int brelse(struct gfs2_buffer_head *bh);
+
+#define bmodified(bh) do { bh->b_changed = 1; } while(0)
#define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \
__LINE__, \
diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c
index f6b609d..741fa40 100644
--- a/gfs2/libgfs2/recovery.c
+++ b/gfs2/libgfs2/recovery.c
@@ -40,7 +40,7 @@ int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk,
if (!dblock)
return -EIO;
- *bh = bread(&ip->i_sbd->buf_list, dblock);
+ *bh = bread(ip->i_sbd, dblock);
return 0;
}
@@ -232,7 +232,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head)
if (!dblock)
return -EIO;
- bh = bread(&ip->i_sbd->buf_list, dblock);
+ bh = bread(ip->i_sbd, dblock);
memset(bh->b_data, 0, ip->i_sbd->bsize);
lh = (struct gfs2_log_header *)bh->b_data;
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 092df6b..2c3187d 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -139,7 +139,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++){
- rgd->bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ rgd->bh[x] = bread(sdp, rgd->ri.ri_addr + x);
if(gfs2_check_meta(rgd->bh[x],
(x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 0dabbc0..5e176a9 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -55,7 +55,7 @@ build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
/* Zero out the beginning of the device up to the superblock */
for (x = 0; x < sdp->sb_addr; x++) {
- bh = bget(&sdp->buf_list, x);
+ bh = bget(sdp, x);
memset(bh->b_data, 0, sdp->bsize);
bmodified(bh);
brelse(bh);
@@ -76,7 +76,7 @@ build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
#ifdef GFS2_HAS_UUID
memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid));
#endif
- bh = bget(&sdp->buf_list, sdp->sb_addr);
+ bh = bget(sdp, sdp->sb_addr);
gfs2_sb_out(&sb, bh);
brelse(bh);
@@ -458,7 +458,7 @@ int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format)
header.mh_type = type;
header.mh_format = format;
- gfs2_meta_header_out(&header, bh->b_data);
+ gfs2_meta_header_out(&header, bh);
}
return 0;
}
@@ -526,7 +526,7 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
brelse(bh);
if (gfs2_next_rg_meta(rgd, block, first))
return -1;
- bh = bread(&sdp->buf_list, *block);
+ bh = bread(sdp, *block);
first = 0;
} while(gfs2_check_meta(bh, type));
brelse(bh);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 5d05f75..dd805b4 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -71,7 +71,7 @@ int read_sb(struct gfs2_sbd *sdp)
unsigned int x;
int error;
- bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
+ bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
gfs2_sb_in(&sdp->sd_sb, bh);
brelse(bh);
@@ -269,10 +269,10 @@ int write_sb(struct gfs2_sbd *sbp)
{
struct gfs2_buffer_head *bh;
- bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
+ bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
gfs2_sb_out(&sbp->sd_sb, bh);
brelse(bh);
- bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
+ fsync(sbp->device_fd); /* make sure the change gets to disk ASAP */
return 0;
}
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 1b7b501..a8e2f66 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -183,7 +183,7 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
inode_put(&sdp->master_dir);
/* We're done with the libgfs portion, so commit it to disk. */
- bsync(&sdp->buf_list);
+ fsync(sdp->device_fd);
}
/**
@@ -282,7 +282,6 @@ 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, 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 101280b..31ef735 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -403,8 +403,6 @@ print_results(struct gfs2_sbd *sdp, uint64_t real_device_size,
if (sdp->debug) {
printf("\n");
- printf( _("Spills: %u\n"),
- sdp->buf_list.spills);
printf( _("Writes: %u\n"), sdp->writes);
}
@@ -437,7 +435,6 @@ main_mkfs(int argc, char *argv[])
strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
sdp->time = time(NULL);
osi_list_init(&sdp->rglist);
- init_buf_list(sdp, &sdp->buf_list, 1 << 20);
decode_arguments(argc, argv, sdp);
if (sdp->rgsize == -1) /* if rg size not specified */
@@ -507,7 +504,6 @@ main_mkfs(int argc, char *argv[])
inode_put(&sdp->master_dir);
inode_put(&sdp->md.inum);
inode_put(&sdp->md.statfs);
- bsync(&sdp->buf_list);
error = fsync(sdp->device_fd);
if (error)
diff --git a/gfs2/tool/df.c b/gfs2/tool/df.c
index abf00f9..26299ff 100644
--- a/gfs2/tool/df.c
+++ b/gfs2/tool/df.c
@@ -113,7 +113,6 @@ do_df_one(char *path)
sbd.utsize = GFS2_DEFAULT_UTSIZE;
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
osi_list_init(&sbd.rglist);
- init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
do_lseek(sbd.device_fd, 0x10 * sbd.bsize);
do_read(sbd.device_fd, buf, sbd.bsize); /* read in the superblock */
14 years, 1 month
cluster: RHEL56 - Attach bh's to inodes
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 1a6be82a56458a55a6e6a489c0672b1bec444704
Parent: a6d56a0938ad396bda77a04102c644df3202ec93
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Tue Jan 19 13:51:13 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:16:03 2010 -0500
Attach bh's to inodes
This patch attaches buffer_heads to inodes. This gives us better
performance because we don't have to constantly keep searching for
the buffer based on the dinode address. It's also another step in
eliminating the linked list of buffers altogether.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 79 ++++++++---------
gfs2/edit/hexedit.c | 24 ++----
gfs2/edit/hexedit.h | 2 +-
gfs2/edit/savemeta.c | 22 ++---
gfs2/fsck/fs_recovery.c | 9 +-
gfs2/fsck/fsck.h | 6 +-
gfs2/fsck/initialize.c | 5 +-
gfs2/fsck/lost_n_found.c | 2 +-
gfs2/fsck/main.c | 25 +++---
gfs2/fsck/metawalk.c | 111 ++++++++++--------------
gfs2/fsck/pass1.c | 40 ++++-----
gfs2/fsck/pass1b.c | 10 +-
gfs2/fsck/pass1c.c | 4 +-
gfs2/fsck/pass2.c | 31 ++-----
gfs2/fsck/pass3.c | 22 +++---
gfs2/fsck/pass4.c | 16 ++--
gfs2/libgfs2/fs_bits.c | 47 ----------
gfs2/libgfs2/fs_ops.c | 196 ++++++++++++++++++++++++++++++-------------
gfs2/libgfs2/gfs1.c | 52 +++++++++++-
gfs2/libgfs2/libgfs2.h | 13 ++-
gfs2/libgfs2/structures.c | 41 ++++------
gfs2/mkfs/main_grow.c | 9 +--
gfs2/mkfs/main_mkfs.c | 12 +--
gfs2/tool/df.c | 7 +-
24 files changed, 401 insertions(+), 384 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 5630b9c..22be04f 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -319,12 +319,13 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
amount = size;
while (copied < size) {
- bh = bhold(ip->i_bh);
-
+ bh = ip->i_bh;
/* First, build up the metatree */
for (h = 0; h < blk->height; h++) {
- lookup_block(ip, bh, h, &blk->mp, 1, &new, &block);
- brelse(bh);
+ lookup_block(ip, ip->i_bh, h, &blk->mp, 1, &new,
+ &block);
+ if (bh != ip->i_bh)
+ brelse(bh);
if (!block)
break;
@@ -343,7 +344,8 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
(char *)srcptr, amount);
srcptr += amount;
bmodified(bh);
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
copied += amount;
@@ -413,8 +415,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
/* */
/* Adapted from gfs2_fsck metawalk.c's build_and_check_metalist */
/* ------------------------------------------------------------------------- */
-static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head *dibh,
- struct gfs2_inode *ip)
+static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_inode *ip)
{
uint32_t gfs2_hgt;
struct gfs2_buffer_head *bh;
@@ -425,6 +426,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head
int error = 0, di_height;
struct blocklist blocks, *blk, *newblk;
struct metapath gfs2mp;
+ struct gfs2_buffer_head *dibh = ip->i_bh;
/* if there are no indirect blocks to check */
if (ip->i_di.di_height <= 1)
@@ -693,8 +695,7 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
}
}
-int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *dibh,
- struct gfs2_inode *ip)
+int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_inode *ip)
{
uint32_t gfs2_hgt;
struct gfs2_buffer_head *bh;
@@ -705,6 +706,7 @@ int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *dibh,
int error = 0, di_height;
struct blocklist blocks, *blk, *newblk;
struct metapath gfs2mp;
+ struct gfs2_buffer_head *dibh = ip->i_bh;
/* Don't have to worry about things with stuffed inodes */
if (ip->i_di.di_height == 0)
@@ -941,14 +943,15 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_generation = 0;
if (!(inode->i_di.di_mode & S_IFDIR) &&
inode->i_di.di_flags & GFS2_DIF_JDATA)
- ret = adjust_jdata_inode(sbp, bh, inode);
+ ret = adjust_jdata_inode(sbp, inode);
else
- ret = adjust_indirect_blocks(sbp, bh, inode);
+ ret = adjust_indirect_blocks(sbp, inode);
if (ret)
return -1;
}
- gfs2_dinode_out(&inode->i_di, bh);
+ bmodified(inode->i_bh);
+ inode_put(&inode); /* does gfs2_dinode_out if modified */
sbp->md.next_inum++; /* update inode count */
return 0;
} /* adjust_inode */
@@ -1051,15 +1054,12 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
static int fetch_inum(struct gfs2_sbd *sbp, uint64_t iblock,
struct gfs2_inum *inum)
{
- struct gfs2_buffer_head *bh_fix;
struct gfs2_inode *fix_inode;
- bh_fix = bread(&sbp->buf_list, iblock);
- fix_inode = inode_get(sbp, bh_fix);
+ fix_inode = inode_read(sbp, iblock);
inum->no_formal_ino = fix_inode->i_di.di_num.no_formal_ino;
inum->no_addr = fix_inode->i_di.di_num.no_addr;
- bmodified(bh_fix);
- brelse(bh_fix);
+ inode_put(&fix_inode);
return 0;
}/* fetch_inum */
@@ -1213,7 +1213,6 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix)
struct inode_block *dir_iblk;
uint64_t offset, dirblock;
struct gfs2_inode *dip;
- struct gfs2_buffer_head *bh_dir;
dirs_fixed = 0;
dirents_fixed = 0;
@@ -1235,27 +1234,24 @@ static int fix_directory_info(struct gfs2_sbd *sbp, osi_list_t *dir_to_fix)
dir_iblk = (struct inode_block *)fix;
dirblock = dir_iblk->di_addr; /* addr of dir inode */
/* read in the directory inode */
- bh_dir = bread(&sbp->buf_list, dirblock);
- dip = inode_get(sbp, bh_dir);
+ dip = inode_read(sbp, dirblock);
/* fix the directory: either exhash (leaves) or linear (stuffed) */
if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
if (fix_one_directory_exhash(sbp, dip)) {
log_crit("Error fixing exhash directory.\n");
- bmodified(bh_dir);
- brelse(bh_dir);
+ inode_put(&dip);
return -1;
}
}
else {
- if (process_dirent_info(dip, sbp, bh_dir, dip->i_di.di_entries)) {
+ if (process_dirent_info(dip, sbp, dip->i_bh,
+ dip->i_di.di_entries)) {
log_crit("Error fixing linear directory.\n");
- bmodified(bh_dir);
- brelse(bh_dir);
+ inode_put(&dip);
return -1;
}
}
- bmodified(bh_dir);
- brelse(bh_dir);
+ inode_put(&dip);
}
/* Free the last entry in memory: */
if (tmp) {
@@ -1416,11 +1412,10 @@ static int init(struct gfs2_sbd *sbp)
}
/* get gfs1 rindex inode - gfs1's rindex inode ptr became __pad2 */
gfs2_inum_in(&inum, (char *)&raw_gfs1_ondisk_sb.sb_rindex_di);
- bh = bread(&sbp->buf_list, inum.no_addr);
- sbp->md.riinode = gfs_inode_get(sbp, bh);
+ sbp->md.riinode = gfs_inode_read(sbp, inum.no_addr);
/* get gfs1 jindex inode - gfs1's journal index inode ptr became master */
gfs2_inum_in(&inum, (char *)&raw_gfs1_ondisk_sb.sb_jindex_di);
- sbp->md.jiinode = gfs2_load_inode(sbp, inum.no_addr);
+ sbp->md.jiinode = inode_read(sbp, inum.no_addr);
/* read in the journal index data */
read_gfs1_jiindex(sbp);
/* read in the resource group index data: */
@@ -1439,8 +1434,8 @@ static int init(struct gfs2_sbd *sbp)
}
printf("\n");
fflush(stdout);
- inode_put(sbp->md.riinode);
- inode_put(sbp->md.jiinode);
+ inode_put(&sbp->md.riinode);
+ inode_put(&sbp->md.jiinode);
log_debug("%d rgs found.\n", rgcount);
return 0;
}/* fill_super_block */
@@ -1739,11 +1734,10 @@ static void remove_obsolete_gfs1(struct gfs2_sbd *sbp)
/* ------------------------------------------------------------------------- */
static void conv_build_jindex(struct gfs2_sbd *sdp)
{
- struct gfs2_inode *jindex;
unsigned int j;
- jindex = createi(sdp->master_dir, "jindex", S_IFDIR | 0700,
- GFS2_DIF_SYSTEM);
+ sdp->md.jiinode = createi(sdp->master_dir, "jindex", S_IFDIR | 0700,
+ GFS2_DIF_SYSTEM);
for (j = 0; j < sdp->md.journals; j++) {
char name[256];
@@ -1752,20 +1746,21 @@ static void conv_build_jindex(struct gfs2_sbd *sdp)
printf("Writing journal #%d...", j + 1);
fflush(stdout);
sprintf(name, "journal%u", j);
- ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
+ ip = createi(sdp->md.jiinode, name, S_IFREG | 0600,
+ GFS2_DIF_SYSTEM);
write_journal(sdp, ip, j,
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
- inode_put(ip);
+ inode_put(&ip);
printf("done.\n");
fflush(stdout);
}
if (sdp->debug) {
printf("\nJindex:\n");
- gfs2_dinode_print(&jindex->i_di);
+ gfs2_dinode_print(&sdp->md.jiinode->i_di);
}
- inode_put(jindex);
+ inode_put(&sdp->md.jiinode);
}
/* ------------------------------------------------------------------------- */
@@ -1869,9 +1864,9 @@ int main(int argc, char **argv)
write_statfs_file(&sb2);
- inode_put(sb2.master_dir);
- inode_put(sb2.md.inum);
- inode_put(sb2.md.statfs);
+ inode_put(&sb2.master_dir);
+ inode_put(&sb2.md.inum);
+ inode_put(&sb2.md.statfs);
bcommit(&sb2.buf_list); /* write the buffers to disk */
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 1a9c7ae..b99580d 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -55,7 +55,6 @@ const char *allocdesc[2][5] = {
const char *prog_name;
int display(int identify_only);
-extern void savemeta(const char *out_fn, int slow);
extern void restoremeta(const char *in_fn, const char *out_device,
uint64_t printblocksonly);
@@ -807,7 +806,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);
+ inode_put(&sbd.md.riinode);
gfs2_rgrp_free(&sbd.rglist);
exit(EXIT_SUCCESS);
}
@@ -891,7 +890,6 @@ static void gfs_rgrp_print(struct gfs_rgrp *rg)
/* ------------------------------------------------------------------------ */
static uint64_t get_rg_addr(int rgnum)
{
- struct gfs2_buffer_head *lbh;
uint64_t rgblk = 0, gblock;
struct gfs2_inode *riinode;
@@ -899,14 +897,13 @@ static uint64_t get_rg_addr(int rgnum)
gblock = sbd1->sb_rindex_di.no_addr;
else
gblock = masterblock("rindex");
- lbh = bread(&sbd.buf_list, gblock);
- riinode = inode_get(&sbd, lbh);
+ riinode = inode_read(&sbd, gblock);
if (rgnum < riinode->i_di.di_size / risize())
rgblk = find_rgrp_block(riinode, rgnum);
else
fprintf(stderr, "Error: File system only has %lld RGs.\n",
(unsigned long long)riinode->i_di.di_size / risize());
- inode_put(riinode);
+ inode_put(&riinode);
return rgblk;
}
@@ -1617,17 +1614,15 @@ int block_is_per_node(void)
int block_is_in_per_node(void)
{
int d;
- struct gfs2_dinode per_node_di;
- struct gfs2_buffer_head *per_node_bh;
+ struct gfs2_inode *per_node_di;
if (gfs1)
return FALSE;
- per_node_bh = bread(&sbd.buf_list, masterblock("per_node"));
- gfs2_dinode_in(&per_node_di, per_node_bh);
+ per_node_di = inode_read(&sbd, masterblock("per_node"));
- do_dinode_extended(&per_node_di, per_node_bh);
- brelse(per_node_bh);
+ do_dinode_extended(&per_node_di->i_di, per_node_di->i_bh);
+ inode_put(&per_node_di);
for (d = 0; d < indirect->ii[0].dirents; d++) {
if (block == indirect->ii[0].dirent[d].block)
@@ -1758,8 +1753,7 @@ static void read_superblock(int fd)
sizeof(uint64_t);
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
sizeof(uint64_t);
- sbd.md.riinode = gfs2_load_inode(&sbd,
- sbd1->sb_rindex_di.no_addr);
+ sbd.md.riinode = inode_read(&sbd, sbd1->sb_rindex_di.no_addr);
sbd.fssize = sbd.device.length;
gfs1_rindex_read(&sbd, 0, &count);
} else {
@@ -1767,7 +1761,7 @@ static void read_superblock(int fd)
sizeof(uint64_t);
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
sizeof(uint64_t);
- sbd.master_dir = gfs2_load_inode(&sbd,
+ sbd.master_dir = inode_read(&sbd,
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
sbd.fssize = sbd.device.length;
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 6996ab5..d78779d 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -184,7 +184,7 @@ extern void gfs_log_header_in(struct gfs_log_header *head,
struct gfs2_buffer_head *bh);
extern void gfs_log_header_print(struct gfs_log_header *lh);
extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh);
-extern void savemeta(const char *out_fn, int saveoption);
+extern void savemeta(char *out_fn, int saveoption);
extern void restoremeta(const char *in_fn, const char *out_device,
uint64_t printblocksonly);
extern int display(int identify_only);
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 39888fa..1e533a6 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -398,7 +398,7 @@ static void save_inode_data(int out_fd)
}
brelse(lbh);
}
- inode_put(inode);
+ inode_put(&inode);
brelse(metabh);
}
@@ -420,19 +420,18 @@ static void get_journal_inode_blocks(void)
for (journal = 0; ; journal++) { /* while journals exist */
uint64_t jblock;
int amt;
- struct gfs2_dinode jdi;
struct gfs2_inode *j_inode = NULL;
if (gfs1) {
struct gfs_jindex ji;
char jbuf[sizeof(struct gfs_jindex)];
- bh = bread(&sbd.buf_list, sbd1->sb_jindex_di.no_addr);
- j_inode = gfs_inode_get(&sbd, bh);
+ j_inode = gfs_inode_read(&sbd,
+ sbd1->sb_jindex_di.no_addr);
amt = gfs2_readi(j_inode, (void *)&jbuf,
journal * sizeof(struct gfs_jindex),
sizeof(struct gfs_jindex));
- brelse(bh);
+ inode_put(&j_inode);
if (!amt)
break;
gfs_jindex_in(&ji, jbuf);
@@ -442,10 +441,6 @@ static void get_journal_inode_blocks(void)
if (journal > indirect->ii[0].dirents - 3)
break;
jblock = indirect->ii[0].dirent[journal + 2].block;
- bh = bread(&sbd.buf_list, jblock);
- j_inode = inode_get(&sbd, bh);
- gfs2_dinode_in(&jdi, bh);
- inode_put(j_inode);
}
journal_blocks[journals_found++] = jblock;
}
@@ -490,7 +485,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
return 0;
}
-void savemeta(const char *out_fn, int saveoption)
+void savemeta(char *out_fn, int saveoption)
{
int out_fd;
int slow;
@@ -558,14 +553,13 @@ void savemeta(const char *out_fn, int saveoption)
last_fs_block, sbd.bsize);
if (!slow) {
if (gfs1) {
- sbd.md.riinode =
- gfs2_load_inode(&sbd,
+ sbd.md.riinode = inode_read(&sbd,
sbd1->sb_rindex_di.no_addr);
jindex_block = sbd1->sb_jindex_di.no_addr;
} else {
sbd.master_dir =
- gfs2_load_inode(&sbd,
- sbd.sd_sb.sb_master_dir.no_addr);
+ inode_read(&sbd,
+ sbd.sd_sb.sb_master_dir.no_addr);
slow = gfs2_lookupi(sbd.master_dir, "rindex", 6,
&sbd.md.riinode);
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 13a60ae..cbc5fe2 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -565,8 +565,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
/* Get master dinode */
- sdp->master_dir = gfs2_load_inode(sdp,
- sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
/* read in the journal index data */
@@ -590,10 +589,10 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
*clean_journals += clean;
}
- inode_put(sdp->md.journal[i]);
+ inode_put(&sdp->md.journal[i]);
}
- inode_put(sdp->master_dir);
- inode_put(sdp->md.jiinode);
+ 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 6bba989..b46df92 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -71,10 +71,10 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
gfs2_grow or something. Count the RGs by hand. */
};
-struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
-struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
+extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
+extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
-void fsck_inode_put(struct gfs2_inode *ip);
+extern 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/initialize.c b/gfs2/fsck/initialize.c
index d82313b..f6746e7 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -195,10 +195,9 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("Initializing special inodes...\n"));
/* Get master dinode */
- sdp->master_dir = gfs2_load_inode(sdp,
- sdp->sd_sb.sb_master_dir.no_addr);
+ sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
/* Get root dinode */
- sdp->md.rooti = gfs2_load_inode(sdp, sdp->sd_sb.sb_root_dir.no_addr);
+ sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
/* Look for "inum" entry in master dinode */
gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index e55b5f2..333409a 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -90,7 +90,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
}
memcpy(filename, tmp_name, filename_len);
- if(gfs2_dirent_del(ip, NULL, filename, filename_len))
+ if(gfs2_dirent_del(ip, filename, filename_len))
log_warn( _("add_inode_to_lf: "
"Unable to remove \"..\" directory entry.\n"));
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index f7d1279..4fd7a09 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -274,7 +274,6 @@ 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)];
@@ -309,8 +308,8 @@ void check_statfs(struct gfs2_sbd *sdp)
}
gfs2_rgrp_read(sdp, rgd);
sdp->blks_total += ri->ri_data;
- sdp->blks_alloced += (ri->ri_data - rg.rg_free);
- sdp->dinodes_alloced += rg.rg_dinodes;
+ sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
+ sdp->dinodes_alloced += rgd->rg.rg_dinodes;
gfs2_rgrp_relse(rgd);
free(rgbh);
}
@@ -485,18 +484,18 @@ int main(int argc, char **argv)
check_statfs(sbp);
/* Free up our system inodes */
- inode_put(sbp->md.inum);
- inode_put(sbp->md.statfs);
+ inode_put(&sbp->md.inum);
+ inode_put(&sbp->md.statfs);
for (j = 0; j < sbp->md.journals; j++)
- 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);
+ 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);
+ 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 d3cdd22..b29224f 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -32,8 +32,6 @@
static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
uint64_t block)
{
- int j;
-
if (block == sbp->md.inum->i_di.di_num.no_addr)
return sbp->md.inum;
if (block == sbp->md.statfs->i_di.di_num.no_addr)
@@ -52,10 +50,7 @@ static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
return sbp->master_dir;
if (lf_dip && block == lf_dip->i_di.di_num.no_addr)
return lf_dip;
- for (j = 0; j < sbp->md.journals; j++)
- if (block == sbp->md.journal[j]->i_di.di_num.no_addr)
- return sbp->md.journal[j];
- return NULL;
+ return is_system_inode(sbp, block);
}
/* fsck_load_inode - same as gfs2_load_inode() in libgfs2 but system inodes
@@ -65,11 +60,9 @@ struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block)
struct gfs2_inode *ip = NULL;
ip = get_system_inode(sbp, block);
- if (ip) {
- bhold(ip->i_bh);
+ if (ip)
return ip;
- }
- return gfs2_load_inode(sbp, block);
+ return inode_read(sbp, block);
}
/* fsck_inode_get - same as inode_get() in libgfs2 but system inodes
@@ -77,39 +70,25 @@ 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)
{
- struct gfs2_inode *ip, *sysip;
-
- ip = calloc(1, sizeof(struct gfs2_inode));
- if (ip == NULL) {
- fprintf(stderr, _("Out of memory in %s\n"), __FUNCTION__);
- exit(-1);
- }
- gfs2_dinode_in(&ip->i_di, bh);
- ip->i_bh = bh;
- ip->i_sbd = sdp;
+ struct gfs2_inode *sysip;
- sysip = get_system_inode(sdp, ip->i_di.di_num.no_addr);
- if (sysip) {
- free(ip);
+ sysip = get_system_inode(sdp, bh->b_blocknr);
+ if (sysip)
return sysip;
- }
- return ip;
+
+ return inode_get(sdp, bh);
}
/* fsck_inode_put - same as inode_put() in libgfs2 but system inodes
get special treatment. */
-void fsck_inode_put(struct gfs2_inode *ip)
+void fsck_inode_put(struct gfs2_inode **ip_in)
{
+ struct gfs2_inode *ip = *ip_in;
struct gfs2_inode *sysip;
sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr);
- if (sysip) {
- if (ip->i_bh->b_changed)
- gfs2_dinode_out(&ip->i_di, ip->i_bh);
- brelse(ip->i_bh);
- } else {
- inode_put(ip);
- }
+ if (!sysip)
+ inode_put(ip_in);
}
/**
@@ -257,7 +236,6 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
} else {
log_err( _("Corrupt directory entry "
"repaired.\n"));
- bmodified(bh);
/* keep looping through dentries */
}
} else {
@@ -765,6 +743,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
GGGG when we finish. To do that, we set
di_eattr to 0 temporarily. */
ip->i_di.di_eattr = 0;
+ bmodified(ip->i_bh);
}
ea_leaf_ptr++;
}
@@ -837,14 +816,12 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
struct metawalk_fxns *pass)
{
uint32_t height = ip->i_di.di_height;
- struct gfs2_buffer_head *bh, *nbh, *metabh;
+ struct gfs2_buffer_head *bh, *nbh, *metabh = ip->i_bh;
osi_list_t *prev_list, *cur_list, *tmp;
int i, head_size;
uint64_t *ptr, block;
int err;
- metabh = bread(&ip->i_sbd->buf_list, ip->i_di.di_num.no_addr);
-
osi_list_add(&metabh->b_altlist, &mlp[0]);
/* if(<there are no indirect blocks to check>) */
@@ -889,8 +866,15 @@ static int build_and_check_metalist(struct gfs2_inode *ip,
}
if(err > 0) {
log_debug( _("Skipping block %" PRIu64
- " (0x%" PRIx64 ")\n"),
- block, block);
+ " (0x%" PRIx64 ")\n"),
+ block, block);
+ continue;
+ }
+ if (gfs2_check_range(ip->i_sbd, block)) {
+ log_debug( _("Skipping invalid block "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
continue;
}
if(!nbh)
@@ -913,8 +897,6 @@ fail:
osi_list_del(&nbh->b_altlist);
}
}
- /* This is an error path, so we need to release the buffer here: */
- brelse(metabh);
return -1;
}
@@ -963,14 +945,23 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_altlist);
if (height > 1) {
- /* if this isn't really a block list skip it */
- if (gfs2_check_meta(bh, GFS2_METATYPE_IN))
+ if (gfs2_check_meta(bh, GFS2_METATYPE_IN)) {
+ if (bh == ip->i_bh)
+ osi_list_del(&bh->b_altlist);
+ else
+ brelse(bh);
continue;
+ }
head_size = sizeof(struct gfs2_meta_header);
} else {
/* if this isn't really a dinode, skip it */
- if (gfs2_check_meta(bh, GFS2_METATYPE_DI))
+ if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ if (bh == ip->i_bh)
+ osi_list_del(&bh->b_altlist);
+ else
+ brelse(bh);
continue;
+ }
head_size = sizeof(struct gfs2_dinode);
}
ptr = (uint64_t *)(bh->b_data + head_size);
@@ -1009,7 +1000,10 @@ 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);
+ if (bh == ip->i_bh)
+ osi_list_del(&bh->b_altlist);
+ else
+ brelse(bh);
osi_list_del(&bh->b_altlist);
}
}
@@ -1048,31 +1042,20 @@ static int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass)
{
- struct gfs2_buffer_head *bh;
struct gfs2_inode *ip;
int error = 0;
- bh = bread(&sbp->buf_list, block);
- ip = fsck_inode_get(sbp, bh);
+ ip = fsck_load_inode(sbp, block);
- if(ip->i_di.di_flags & GFS2_DIF_EXHASH) {
+ if(ip->i_di.di_flags & GFS2_DIF_EXHASH)
error = check_leaf_blks(ip, pass);
- if(error < 0) {
- stack;
- fsck_inode_put(ip); /* does brelse(bh); */
- return -1;
- }
- }
- else {
- error = check_linear_dir(ip, bh, pass);
- if(error < 0) {
- stack;
- fsck_inode_put(ip); /* does brelse(bh); */
- return -1;
- }
- }
+ else
+ error = check_linear_dir(ip, ip->i_bh, pass);
+
+ if(error < 0)
+ stack;
- fsck_inode_put(ip); /* does a brelse */
+ fsck_inode_put(&ip); /* does a brelse */
return error;
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index de93345..e00b7d6 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -435,7 +435,6 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
_("Extended Attribute leaf block "
"has incorrect type"));
}
- bmodified(leaf_bh);
brelse(leaf_bh);
return 1;
}
@@ -701,7 +700,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);
+ fsck_inode_put(&ip);
return -1;
}
if(q.block_type != gfs2_block_free) {
@@ -709,10 +708,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);
+ fsck_inode_put(&ip);
return -1;
}
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return 0;
}
@@ -723,12 +722,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);
+ fsck_inode_put(&ip);
return -1;
}
if(add_to_dir_list(sdp, block)) {
stack;
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -737,7 +736,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -746,7 +745,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -755,7 +754,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -764,7 +763,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -773,7 +772,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -782,7 +781,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);
+ fsck_inode_put(&ip);
return -1;
}
break;
@@ -791,16 +790,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);
+ fsck_inode_put(&ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip);
+ 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);
+ fsck_inode_put(&ip);
return -1;
}
@@ -836,11 +835,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);
+ fsck_inode_put(&ip);
return -1;
}
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return 0;
}
}
@@ -849,7 +848,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);
+ fsck_inode_put(&ip);
return 0;
}
if(error > 0) {
@@ -861,7 +860,7 @@ 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);
+ fsck_inode_put(&ip);
return 0;
}
@@ -898,7 +897,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);
+ fsck_inode_put(&ip);
return 0;
}
@@ -928,7 +927,6 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
/* handle_di calls inode_get, then inode_put, which does brelse. */
/* In order to prevent brelse from getting the count off, hold it. */
- bhold(bh);
if(handle_di(sdp, bh, block)) {
stack;
return -1;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 78f1ed6..3121d4c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -351,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); /* 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, &find_refs) < 0){
stack;
- fsck_inode_put(ip); /* out, brelse, free */
+ fsck_inode_put(&ip); /* out, brelse, free */
return -1;
}
if (myfi.found) {
@@ -378,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); /* out, brelse, free */
+ fsck_inode_put(&ip); /* out, brelse, free */
return 0;
}
@@ -443,7 +443,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct dup_blocks *b)
ip->i_di.di_num.no_addr,
gfs2_meta_inval);
bmodified(ip->i_bh);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
} else {
log_warn( _("The bad inode was not cleared."));
}
@@ -489,7 +489,7 @@ 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); /* 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 a00ce2d..3595bb1 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -271,6 +271,7 @@ int pass1c(struct gfs2_sbd *sbp)
block_no, block_no);
gfs2_special_clear(&sbp->eattr_blocks, block_no);
ip = fsck_inode_get(sbp, bh);
+ ip->bh_owned = 1;
log_debug( _("Found eattr at %llu (0x%llx)\n"),
(unsigned long long)ip->i_di.di_eattr,
@@ -282,7 +283,8 @@ int pass1c(struct gfs2_sbd *sbp)
brelse(bh);
return FSCK_ERROR;
}
- fsck_inode_put(ip); /* dinode_out, brelse, free */
+
+ fsck_inode_put(&ip); /* dinode_out, brelse, free */
} else {
brelse(bh);
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 6509171..8e4f05b 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -263,7 +263,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
- fsck_inode_put(entry_ip);
+ 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);
@@ -319,7 +319,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
check_inode_eattr(entry_ip, &pass2_fxns_delete);
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
- fsck_inode_put(entry_ip);
+ fsck_inode_put(&entry_ip);
gfs2_block_set(sbp, bl, de->de_inum.no_addr,
gfs2_block_free);
@@ -347,7 +347,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
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);
+ fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -372,7 +372,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
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);
+ fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -407,7 +407,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
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);
+ fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -442,7 +442,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
entry_ip = fsck_load_inode(sbp, de->de_inum.no_addr);
check_inode_eattr(entry_ip, &clear_eattrs);
- fsck_inode_put(entry_ip);
+ fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -467,7 +467,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
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);
+ fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
bmodified(bh);
@@ -557,7 +557,6 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
{
uint64_t iblock = 0;
struct dir_status ds = {0};
- struct gfs2_buffer_head b, *bh = &b;
char *filename;
int filename_len;
char tmp_name[256];
@@ -587,7 +586,6 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
if (error > 0)
gfs2_block_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval);
- bh = bhold(sysinode->i_bh);
if(check_inode_eattr(sysinode, &pass2_fxns)) {
stack;
return -1;
@@ -616,7 +614,6 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
sysinode->i_di.di_num.no_addr);
ds.entry_count++;
free(filename);
- bmodified(sysinode->i_bh);
} else
log_err( _("The directory was not fixed.\n"));
}
@@ -642,10 +639,6 @@ int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
sysinode->i_di.di_num.no_addr);
}
}
-
- if (!opts.no)
- bmodified(bh);
- brelse(bh);
return 0;
}
@@ -679,7 +672,6 @@ int pass2(struct gfs2_sbd *sbp)
struct gfs2_block_query q;
struct dir_status ds = {0};
struct gfs2_inode *ip;
- struct gfs2_buffer_head *bh = NULL;
char *filename;
int filename_len;
char tmp_name[256];
@@ -733,11 +725,10 @@ int pass2(struct gfs2_sbd *sbp)
* is valid */
ip = fsck_load_inode(sbp, i);
if(check_metatree(ip, &pass2_fxns)) {
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
stack;
return FSCK_ERROR;
}
- fsck_inode_put(ip);
}
error = check_dir(sbp, i, &pass2_fxns);
if(error < 0) {
@@ -775,8 +766,7 @@ int pass2(struct gfs2_sbd *sbp)
}
gfs2_block_set(sbp, bl, i, gfs2_meta_inval);
}
- bh = bread(&sbp->buf_list, i);
- ip = fsck_inode_get(sbp, bh);
+ ip = fsck_load_inode(sbp, i);
if(!ds.dotdir) {
log_err(_("No '.' entry found for directory inode at "
"block %"PRIu64" (0x%" PRIx64 ")\n"), i, i);
@@ -806,7 +796,6 @@ int pass2(struct gfs2_sbd *sbp)
ds.entry_count++;
free(filename);
log_err( _("The directory was fixed.\n"));
- bmodified(ip->i_bh);
} else {
log_err( _("The directory was not fixed.\n"));
}
@@ -825,7 +814,7 @@ int pass2(struct gfs2_sbd *sbp)
log_err( _("The entry count was not fixed.\n"));
}
}
- fsck_inode_put(ip); /* 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 910ecf3..c4ea3a5 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -45,29 +45,29 @@ 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);
- fsck_inode_put(pip);
+ 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);
- fsck_inode_put(pip);
+ fsck_inode_put(&ip);
+ fsck_inode_put(&pip);
stack;
return -1;
}
memcpy(filename, "..", filename_len);
- if(gfs2_dirent_del(ip, NULL, filename, filename_len))
+ if(gfs2_dirent_del(ip, filename, filename_len))
log_warn( _("Unable to remove \"..\" directory entry.\n"));
else
decrement_link(sbp, olddotdot);
dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
increment_link(sbp, newdotdot);
bmodified(ip->i_bh);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
bmodified(pip->i_bh);
- fsck_inode_put(pip);
+ fsck_inode_put(&pip);
return 0;
}
@@ -266,7 +266,7 @@ int pass3(struct gfs2_sbd *sbp)
gfs2_block_set(sbp, bl,
di->dinode,
gfs2_block_free);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
break;
} else {
log_err( _("Zero-size unlinked directory remains\n"));
@@ -275,16 +275,16 @@ int pass3(struct gfs2_sbd *sbp)
if(query( _("Add unlinked directory to "
"lost+found? (y/n) "))) {
if(add_inode_to_lf(ip)) {
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
stack;
return FSCK_ERROR;
}
log_warn( _("Directory relinked to lost+found\n"));
bmodified(ip->i_bh);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
} else {
log_err( _("Unlinked directory remains unlinked\n"));
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
}
break;
}
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0d590d5..c6328b5 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -88,7 +88,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
bmodified(ip->i_bh);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
continue;
@@ -117,7 +117,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
} else {
log_err( _("The inode was not "
"deleted\n"));
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
}
continue;
}
@@ -131,16 +131,16 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
if(query( _("Clear zero-size unlinked inode? (y/n) "))) {
gfs2_block_set(sbp, bl, ii->inode,
gfs2_block_free);
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
continue;
}
}
- if(query( _("Add unlinked inode to lost+found? (y/n)"))) {
- bmodified(ip->i_bh);
+ if(query( _("Add unlinked inode to lost+found? "
+ "(y/n)"))) {
if(add_inode_to_lf(ip)) {
stack;
- fsck_inode_put(ip);
+ fsck_inode_put(&ip);
return -1;
}
else {
@@ -149,7 +149,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);
+ 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
@@ -163,7 +163,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp, osi_list_t *list) {
ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
fix_inode_count(sbp, ii, ip);
bmodified(ip->i_bh);
- fsck_inode_put(ip); /* out, brelse, free */
+ 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/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 9dc34c8..e8e601b 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -18,53 +18,6 @@
#include "libgfs2.h"
-uint32_t gfs2_bitfit_core(struct gfs2_sbd *sbp, uint64_t goal, uint64_t start,
- uint64_t len, unsigned char old_state,
- struct gfs2_block_list *bl)
-{
- uint64_t block;
- struct gfs2_block_query q;
-
- for(block = start+goal; block < start+len; block++) {
- gfs2_block_check(sbp, bl, block, &q);
- switch(old_state) {
- /* FIXME Make sure these are handled correctly */
- case GFS2_BLKST_FREE:
- switch(q.block_type) {
- case gfs2_block_free:
- return block - start;
- }
- break;
- case GFS2_BLKST_DINODE:
- switch(q.block_type) {
- case gfs2_inode_dir:
- case gfs2_inode_file:
- case gfs2_inode_lnk:
- case gfs2_inode_blk:
- case gfs2_inode_chr:
- case gfs2_inode_fifo:
- case gfs2_inode_sock:
- return block - start;
- }
- break;
- case GFS2_BLKST_USED:
- switch(q.block_type) {
- case gfs2_indir_blk:
- case gfs2_leaf_blk:
- case gfs2_journal_blk:
- case gfs2_meta_other:
- case gfs2_meta_eattr:
- case gfs2_block_used:
- return block - start;
- }
- break;
- case GFS2_BLKST_UNLINKED:
- default:
- break;
- }
- }
- return BFITNOENT;
-}
/**
* gfs2_bitfit - Find a free block in the bitmaps
* @buffer: the buffer that holds the bitmaps
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 1dcae78..fccbfd3 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -43,15 +43,76 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
gfs2_dinode_in(&ip->i_di, bh);
ip->i_bh = bh;
ip->i_sbd = sdp;
+ ip->bh_owned = 0; /* caller did the bread so we don't own the bh */
return ip;
}
-void inode_put(struct gfs2_inode *ip)
+struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
{
- if (ip->i_bh->b_changed)
+ struct gfs2_inode *ip;
+
+ ip = calloc(1, sizeof(struct gfs2_inode));
+ if (ip == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+ ip->i_bh = bread(&sdp->buf_list, di_addr);
+ gfs2_dinode_in(&ip->i_di, ip->i_bh);
+ ip->i_sbd = sdp;
+ ip->bh_owned = 1; /* We did the bread so we own the bh */
+ return ip;
+}
+
+struct gfs2_inode *is_system_inode(struct gfs2_sbd *sdp, uint64_t block)
+{
+ int j;
+
+ if (sdp->md.inum && block == sdp->md.inum->i_di.di_num.no_addr)
+ return sdp->md.inum;
+ if (sdp->md.statfs && block == sdp->md.statfs->i_di.di_num.no_addr)
+ return sdp->md.statfs;
+ if (sdp->md.jiinode && block == sdp->md.jiinode->i_di.di_num.no_addr)
+ return sdp->md.jiinode;
+ if (sdp->md.riinode && block == sdp->md.riinode->i_di.di_num.no_addr)
+ return sdp->md.riinode;
+ if (sdp->md.qinode && block == sdp->md.qinode->i_di.di_num.no_addr)
+ return sdp->md.qinode;
+ if (sdp->md.pinode && block == sdp->md.pinode->i_di.di_num.no_addr)
+ return sdp->md.pinode;
+ if (sdp->md.rooti && block == sdp->md.rooti->i_di.di_num.no_addr)
+ return sdp->md.rooti;
+ if (sdp->master_dir && block == sdp->master_dir->i_di.di_num.no_addr)
+ return sdp->master_dir;
+ for (j = 0; j < sdp->md.journals; j++)
+ if (sdp->md.journal && sdp->md.journal[j] &&
+ block == sdp->md.journal[j]->i_di.di_num.no_addr)
+ return sdp->md.journal[j];
+ return NULL;
+}
+
+void inode_put(struct gfs2_inode **ip_in)
+{
+ struct gfs2_inode *ip = *ip_in;
+ uint64_t block = ip->i_di.di_num.no_addr;
+ struct gfs2_sbd *sdp = ip->i_sbd;
+
+ if (ip->i_bh->b_changed) {
gfs2_dinode_out(&ip->i_di, ip->i_bh);
- brelse(ip->i_bh);
+ if (!ip->bh_owned && is_system_inode(sdp, block))
+ fprintf(stderr, "Warning: Change made to inode "
+ "were discarded.\n");
+ /* This is for debugging only: a convenient place to set
+ a breakpoint. This means a system inode was modified but
+ not written. That's not fatal: some places like
+ adjust_inode in gfs2_convert will do this on purpose.
+ It can also point out a coding problem, but we don't
+ want to raise alarm in the users either. */
+ }
+ if (ip->bh_owned)
+ brelse(ip->i_bh);
+ ip->i_bh = NULL;
free(ip);
+ *ip_in = NULL; /* make sure the memory isn't accessed again */
}
static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
@@ -129,6 +190,7 @@ uint64_t data_alloc(struct gfs2_inode *ip)
uint64_t x;
x = blk_alloc_i(ip->i_sbd, DATA);
ip->i_di.di_goal_data = x;
+ bmodified(ip->i_bh);
return x;
}
@@ -137,6 +199,7 @@ uint64_t meta_alloc(struct gfs2_inode *ip)
uint64_t x;
x = blk_alloc_i(ip->i_sbd, META);
ip->i_di.di_goal_meta = x;
+ bmodified(ip->i_bh);
return x;
}
@@ -319,6 +382,7 @@ void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
*ptr = cpu_to_be64(*block);
bmodified(bh);
ip->i_di.di_blocks++;
+ bmodified(ip->i_bh);
*new = 1;
}
@@ -362,11 +426,12 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mp = find_metapath(ip, lblock);
end_of_metadata = ip->i_di.di_height - 1;
- bh = bhold(ip->i_bh);
+ bh = ip->i_bh;
for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, bh, x, mp, create, new, dblock);
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
if (!*dblock)
goto out;
@@ -377,8 +442,12 @@ void 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);
- } else
- bh = bread(&sdp->buf_list, *dblock);
+ } else {
+ if (*dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(&sdp->buf_list, *dblock);
+ }
}
if (!prealloc)
@@ -406,7 +475,8 @@ void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
}
}
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
out:
free(mp);
@@ -471,14 +541,17 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
FALSE);
if (dblock) {
- bh = bread(&sdp->buf_list, dblock);
+ if (dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(&sdp->buf_list, dblock);
dblock++;
extlen--;
} else
bh = NULL;
copy2mem(bh, &buf, o, amount);
- if (bh)
+ if (bh && bh != ip->i_bh)
brelse(bh);
copied += amount;
@@ -553,11 +626,15 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
mh.mh_format = GFS2_FORMAT_JD;
gfs2_meta_header_out(&mh, bh);
}
- } else
- bh = bread(&sdp->buf_list, dblock);
+ } else {
+ if (dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(&sdp->buf_list, dblock);
+ }
copy_from_mem(bh, &buf, o, amount);
- bmodified(bh);
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
copied += amount;
lblock++;
@@ -567,8 +644,10 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
}
- if (ip->i_di.di_size < start + copied)
+ if (ip->i_di.di_size < start + copied) {
+ bmodified(ip->i_bh);
ip->i_di.di_size = start + copied;
+ }
return copied;
}
@@ -588,13 +667,18 @@ struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn,
die("get_file_buf\n");
if (!prealloc && new &&
- ip->i_di.di_size < (lbn + 1) << sdp->sd_sb.sb_bsize_shift)
+ ip->i_di.di_size < (lbn + 1) << sdp->sd_sb.sb_bsize_shift) {
+ bmodified(ip->i_bh);
ip->i_di.di_size = (lbn + 1) << sdp->sd_sb.sb_bsize_shift;
-
+ }
if (new)
return bget(&sdp->buf_list, dbn);
- else
- return bread(&sdp->buf_list, dbn);
+ else {
+ if (dbn == ip->i_di.di_num.no_addr)
+ return ip->i_bh;
+ else
+ return bread(&sdp->buf_list, dbn);
+ }
}
int gfs2_dirent_first(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
@@ -653,6 +737,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
dent->de_name_len = cpu_to_be16(name_len);
bmodified(bh);
*dent_out = dent;
+ dip->i_di.di_entries++;
+ bmodified(dip->i_bh);
return 0;
}
@@ -678,6 +764,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
be16_to_cpu(new->de_rec_len));
*dent_out = new;
bmodified(bh);
+ dip->i_di.di_entries++;
+ bmodified(dip->i_bh);
return 0;
}
@@ -685,6 +773,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
*dent_out = dent;
bmodified(bh);
+ dip->i_di.di_entries++;
+ bmodified(dip->i_bh);
return 0;
}
} while (gfs2_dirent_next(dip, bh, &dent) == 0);
@@ -698,9 +788,10 @@ 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)
+ if (dip->i_di.di_entries) {
+ bmodified(dip->i_bh);
dip->i_di.di_entries--;
+ }
if (!prev) {
cur->de_inum.no_formal_ino = 0;
return;
@@ -837,8 +928,10 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
nleaf->lf_depth = oleaf->lf_depth;
dip->i_di.di_blocks++;
+ bmodified(dip->i_bh);
brelse(obh);
+ bmodified(nbh);
brelse(nbh);
}
@@ -878,6 +971,7 @@ static void dir_double_exhash(struct gfs2_inode *dip)
free(buf);
dip->i_di.di_depth++;
+ bmodified(dip->i_bh);
}
/**
@@ -1004,6 +1098,7 @@ 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++;
+ bmodified(dip->i_bh);
bmodified(bh);
brelse(bh);
bh = nbh;
@@ -1021,9 +1116,6 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
bmodified(bh);
brelse(bh);
-
- dip->i_di.di_entries++;
- bmodified(dip->i_bh);
return;
}
}
@@ -1086,6 +1178,8 @@ static void dir_make_exhash(struct gfs2_inode *dip)
for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
dip->i_di.di_depth = y;
+
+ gfs2_dinode_out(&dip->i_di, dip->i_bh);
}
static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1104,9 +1198,6 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
dent->de_hash = cpu_to_be32(dent->de_hash);
dent->de_type = cpu_to_be16(type);
memcpy((char *)(dent + 1), filename, len);
-
- dip->i_di.di_entries++;
- bmodified(dip->i_bh);
}
void dir_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1199,13 +1290,16 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode));
- if(S_ISDIR(mode))
+ if(S_ISDIR(mode)) {
+ bmodified(dip->i_bh);
dip->i_di.di_nlink++;
+ }
bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num);
ip = inode_get(sdp, bh);
bmodified(bh);
}
+ ip->bh_owned = 1;
return ip;
}
@@ -1321,7 +1415,7 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
/* Find the entry */
do{
- if (bh)
+ if (bh && bh != dip->i_bh)
brelse(bh);
bh = bh_next;
@@ -1336,14 +1430,16 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
break;
default:
- brelse(bh);
+ if (bh && bh != dip->i_bh)
+ brelse(bh);
return error;
}
error = get_next_leaf(dip, bh, &bh_next);
} while (!error);
- brelse(bh);
+ if (bh && bh != dip->i_bh)
+ brelse(bh);
return error;
}
@@ -1388,21 +1484,18 @@ static int dir_e_search(struct gfs2_inode *dip, const char *filename,
static int dir_l_search(struct gfs2_inode *dip, const char *filename,
int len, unsigned int *type, struct gfs2_inum *inum)
{
- struct gfs2_buffer_head *dibh;
struct gfs2_dirent *dent;
int error;
if(!inode_is_stuffed(dip))
return -1;
- dibh = bread(&dip->i_sbd->buf_list, dip->i_di.di_num.no_addr);
- error = leaf_search(dip, dibh, filename, len, &dent, NULL);
+ error = leaf_search(dip, dip->i_bh, filename, len, &dent, NULL);
if (!error) {
gfs2_inum_in(inum, (char *)&dent->de_inum);
if(type)
*type = be16_to_cpu(dent->de_type);
}
- brelse(dibh);
return error;
}
@@ -1474,37 +1567,23 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len)
return 0;
}
-static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh,
- const char *filename, int len){
+static int dir_l_del(struct gfs2_inode *dip, const char *filename, int len)
+{
int error=0;
- int got_buf = 0;
struct gfs2_dirent *cur, *prev;
if(!inode_is_stuffed(dip))
return -1;
- if(!dibh) {
- dibh = bread(&dip->i_sbd->buf_list, dip->i_di.di_num.no_addr);
- if (error)
- return -1;
- got_buf = 1;
- }
-
- error = leaf_search(dip, dibh, filename, len, &cur, &prev);
+ error = leaf_search(dip, dip->i_bh, filename, len, &cur, &prev);
if (error) {
- if (got_buf)
- brelse(dibh);
if (error == -ENOENT)
return 1;
else
return -1;
}
- dirent2_del(dip, dibh, prev, cur);
- if (got_buf) {
- bmodified(dibh);
- brelse(dibh);
- }
+ dirent2_del(dip, dip->i_bh, prev, cur);
return 0;
}
@@ -1520,8 +1599,8 @@ static int dir_l_del(struct gfs2_inode *dip, struct gfs2_buffer_head *dibh,
*
* Returns: 0 on success (or if it doesn't already exist), -1 on failure
*/
-int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
- const char *filename, int len){
+int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, int len)
+{
int error;
if(!S_ISDIR(dip->i_di.di_mode))
@@ -1530,7 +1609,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
error = dir_e_del(dip, filename, len);
else
- error = dir_l_del(dip, bh, filename, len);
+ error = dir_l_del(dip, filename, len);
bmodified(dip->i_bh);
return error;
}
@@ -1564,7 +1643,7 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
return 0;
}
else
- *ipp = gfs2_load_inode(sdp, inum.no_addr);
+ *ipp = inode_read(sdp, inum.no_addr);
return error;
}
@@ -1637,8 +1716,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
}
/* Set the bitmap type for inode to free space: */
gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE);
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
/* inode_put deallocated the extra block used by the disk inode, */
/* so adjust it in the superblock struct */
sdp->blks_alloced--;
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index a06fe11..5232c01 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -98,11 +98,12 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mp = find_metapath(ip, lblock);
end_of_metadata = ip->i_di.di_height - 1;
- bh = bhold(ip->i_bh);
+ bh = ip->i_bh;
for (x = 0; x < end_of_metadata; x++) {
gfs1_lookup_block(ip, bh, x, mp, create, new, dblock);
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
if (!*dblock)
goto out;
@@ -146,7 +147,8 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
}
}
- brelse(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
out:
free(mp);
@@ -395,5 +397,49 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
ip->i_di.di_eattr = gfs1_dinode.di_eattr;
ip->i_bh = bh;
ip->i_sbd = sdp;
+ ip->bh_owned = 0;
+ return ip;
+}
+
+struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
+{
+ struct gfs_dinode gfs1_dinode;
+ struct gfs2_inode *ip;
+
+ ip = calloc(1, sizeof(struct gfs2_inode));
+ if (ip == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+
+ ip->i_bh = bread(&sdp->buf_list, di_addr);
+ gfs_dinode_in(&gfs1_dinode, ip->i_bh);
+ memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
+ sizeof(struct gfs2_meta_header));
+ memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num,
+ sizeof(struct gfs2_inum));
+ ip->i_di.di_mode = gfs1_dinode.di_mode;
+ ip->i_di.di_uid = gfs1_dinode.di_uid;
+ ip->i_di.di_gid = gfs1_dinode.di_gid;
+ ip->i_di.di_nlink = gfs1_dinode.di_nlink;
+ ip->i_di.di_size = gfs1_dinode.di_size;
+ ip->i_di.di_blocks = gfs1_dinode.di_blocks;
+ ip->i_di.di_atime = gfs1_dinode.di_atime;
+ ip->i_di.di_mtime = gfs1_dinode.di_mtime;
+ ip->i_di.di_ctime = gfs1_dinode.di_ctime;
+ ip->i_di.di_major = gfs1_dinode.di_major;
+ ip->i_di.di_minor = gfs1_dinode.di_minor;
+ ip->i_di.di_goal_data = gfs1_dinode.di_goal_dblk;
+ ip->i_di.di_goal_meta = gfs1_dinode.di_goal_mblk;
+ ip->i_di.di_flags = gfs1_dinode.di_flags;
+ ip->i_di.di_payload_format = gfs1_dinode.di_payload_format;
+ ip->i_di.__pad1 = gfs1_dinode.di_type;
+ ip->i_di.di_height = gfs1_dinode.di_height;
+ ip->i_di.di_depth = gfs1_dinode.di_depth;
+ ip->i_di.di_entries = gfs1_dinode.di_entries;
+ ip->i_di.di_eattr = gfs1_dinode.di_eattr;
+ ip->i_sbd = sdp;
+ ip->bh_owned = 1;
return ip;
}
+
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 47faa60..a6b9314 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -134,6 +134,7 @@ struct special_blocks {
struct gfs2_sbd;
struct gfs2_inode {
+ int bh_owned; /* Is this bh owned, iow, should we release it later? */
struct gfs2_dinode i_di;
struct gfs2_buffer_head *i_bh;
struct gfs2_sbd *i_sbd;
@@ -438,7 +439,10 @@ extern void lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
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 struct gfs2_inode *inode_read(struct gfs2_sbd *sdp, uint64_t di_addr);
+extern struct gfs2_inode *is_system_inode(struct gfs2_sbd *sdp,
+ uint64_t block);
+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);
@@ -456,13 +460,12 @@ 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 int gfs2_dirent_del(struct gfs2_inode *dip, 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,
@@ -558,6 +561,8 @@ extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
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);
+extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp,
+ uint64_t di_addr);
/* gfs2_log.c */
struct gfs2_options {
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 5e4a8c3..0dabbc0 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -43,6 +43,7 @@ void build_master(struct gfs2_sbd *sdp)
printf("\nMaster dir:\n");
gfs2_dinode_print(&sdp->master_dir->i_di);
}
+ sdp->master_dir->bh_owned = 1;
}
void
@@ -123,6 +124,7 @@ 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);
+ bmodified(bh);
brelse(bh);
if (++seq == blocks)
@@ -152,8 +154,7 @@ 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);
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
if (sdp->debug) {
@@ -161,8 +162,7 @@ build_jindex(struct gfs2_sbd *sdp)
gfs2_dinode_print(&jindex->i_di);
}
- bmodified(jindex->i_bh);
- inode_put(jindex);
+ inode_put(&jindex);
}
static void
@@ -176,14 +176,14 @@ build_inum_range(struct gfs2_inode *per_node, unsigned int j)
ip = createi(per_node, name, S_IFREG | 0600,
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
ip->i_di.di_size = sizeof(struct gfs2_inum_range);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
if (sdp->debug) {
printf("\nInum Range %u:\n", j);
gfs2_dinode_print(&ip->i_di);
}
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
static void
@@ -197,14 +197,14 @@ build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
ip = createi(per_node, name, S_IFREG | 0600,
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
ip->i_di.di_size = sizeof(struct gfs2_statfs_change);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
if (sdp->debug) {
printf("\nStatFS Change %u:\n", j);
gfs2_dinode_print(&ip->i_di);
}
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
static void
@@ -241,8 +241,7 @@ build_quota_change(struct gfs2_inode *per_node, unsigned int j)
gfs2_dinode_print(&ip->i_di);
}
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
void
@@ -265,8 +264,7 @@ build_per_node(struct gfs2_sbd *sdp)
gfs2_dinode_print(&per_node->i_di);
}
- bmodified(per_node->i_bh);
- inode_put(per_node);
+ inode_put(&per_node);
}
void
@@ -313,6 +311,7 @@ build_rindex(struct gfs2_sbd *sdp)
ip = createi(sdp->master_dir, "rindex", S_IFREG | 0600,
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
ip->i_di.di_payload_format = GFS2_FORMAT_RI;
+ bmodified(ip->i_bh);
for (head = &sdp->rglist, tmp = head->next;
tmp != head;
@@ -332,8 +331,7 @@ build_rindex(struct gfs2_sbd *sdp)
gfs2_dinode_print(&ip->i_di);
}
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
void
@@ -347,6 +345,7 @@ build_quota(struct gfs2_sbd *sdp)
ip = createi(sdp->master_dir, "quota", S_IFREG | 0600,
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
ip->i_di.di_payload_format = GFS2_FORMAT_QU;
+ bmodified(ip->i_bh);
memset(&qu, 0, sizeof(struct gfs2_quota));
qu.qu_value = 1;
@@ -364,8 +363,7 @@ build_quota(struct gfs2_sbd *sdp)
gfs2_quota_print(&qu);
}
- bmodified(ip->i_bh);
- inode_put(ip);
+ inode_put(&ip);
}
void
@@ -386,6 +384,7 @@ build_root(struct gfs2_sbd *sdp)
printf("\nRoot directory:\n");
gfs2_dinode_print(&sdp->md.rooti->i_di);
}
+ sdp->md.rooti->bh_owned = 1;
}
void do_init_inum(struct gfs2_sbd *sdp)
@@ -426,16 +425,6 @@ void do_init_statfs(struct gfs2_sbd *sdp)
}
}
-struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block)
-{
- struct gfs2_buffer_head *bh;
- struct gfs2_inode *ip;
-
- bh = bread(&sbp->buf_list, block);
- ip = inode_get(sbp, bh);
- return ip;
-}
-
int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
{
uint32_t check_magic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 345babe..1b7b501 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -179,11 +179,8 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
/* Build the remaining resource groups */
build_rgrps(sdp, !test);
- /* 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);
- inode_put(sdp->master_dir);
+ 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);
@@ -304,7 +301,7 @@ main_grow(int argc, char *argv[])
}
/* Get master dinode */
sdp->master_dir =
- gfs2_load_inode(sdp, sdp->sd_sb.sb_master_dir.no_addr);
+ inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
/* Fetch the rindex from disk. We aren't using gfs2 here, */
/* which means that the bitmaps will most likely be cached */
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index c33f216..101280b 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -503,14 +503,10 @@ main_mkfs(int argc, char *argv[])
/* Cleanup */
- 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);
+ inode_put(&sdp->md.rooti);
+ inode_put(&sdp->master_dir);
+ inode_put(&sdp->md.inum);
+ inode_put(&sdp->md.statfs);
bsync(&sdp->buf_list);
error = fsync(sdp->device_fd);
diff --git a/gfs2/tool/df.c b/gfs2/tool/df.c
index 025fc85..abf00f9 100644
--- a/gfs2/tool/df.c
+++ b/gfs2/tool/df.c
@@ -96,6 +96,7 @@ do_df_one(char *path)
struct gfs2_sbd sbd;
char buf[GFS2_DEFAULT_BSIZE], statfs_fn[PATH_MAX];
struct gfs2_statfs_change sc;
+ struct gfs2_buffer_head bh;
memset(&sbd, 0, sizeof(struct gfs2_sbd));
sbd.path_name = path;
@@ -117,12 +118,12 @@ do_df_one(char *path)
do_lseek(sbd.device_fd, 0x10 * sbd.bsize);
do_read(sbd.device_fd, buf, sbd.bsize); /* read in the superblock */
- gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
+ bh.b_data = buf;
+ gfs2_sb_in(&sbd.sd_sb, &bh); /* parse it out into the sb structure */
sbd.bsize = sbd.sd_sb.sb_bsize;
compute_constants(&sbd);
- sbd.master_dir = gfs2_load_inode(&sbd,
- sbd.sd_sb.sb_master_dir.no_addr);
+ sbd.master_dir = inode_read(&sbd, sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
gfs2_lookupi(sbd.master_dir, "jindex", 6, &sbd.md.jiinode);
14 years, 1 month
cluster: RHEL56 - Make struct_out functions operate on bh's
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: a6d56a0938ad396bda77a04102c644df3202ec93
Parent: 8bc98f2fad5ecf63e42bd44e93f5b5349c7f1253
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Sat Jan 16 12:07:00 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:11:05 2010 -0500
Make struct_out functions operate on bh's
This patch changes most the gfs2_struct_in and gfs2_struct_out functions
so that they take a bh parameter rather than a buffer. It ensures that
whenever a structure is pushed to a buffer, the buffer is marked as
modified so that it later gets written to disk. This is one step in
getting rid of the buffer lists and helps ensure data integrity. This
takes most of the guess-work out of the buffer writing: No more "rewrite
the buffer because it may or may not have been changed."
Some structures, such as rindex entries and dentry pointers, can't
operate on a bh, mostly because they use the readi/writei functions to
write the data out, but this covers the majority of gfs2 structures.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 18 ++--
gfs2/edit/gfs2hex.c | 116 +++++++++++++++--------
gfs2/edit/gfs2hex.h | 2 +-
gfs2/edit/hexedit.c | 215 ++++++++++++++++++++++---------------------
gfs2/edit/hexedit.h | 121 +++++++++++++------------
gfs2/edit/savemeta.c | 52 ++++++-----
gfs2/fsck/fs_recovery.c | 3 +-
gfs2/fsck/main.c | 19 +++--
gfs2/fsck/metawalk.c | 25 +++---
gfs2/fsck/pass1.c | 4 +-
gfs2/fsck/pass1b.c | 2 +-
gfs2/fsck/pass5.c | 2 +-
gfs2/fsck/rgrepair.c | 5 +-
gfs2/libgfs2/Makefile | 2 +-
gfs2/libgfs2/fs_geometry.c | 5 +-
gfs2/libgfs2/fs_ops.c | 41 ++++----
gfs2/libgfs2/gfs1.c | 18 ++--
gfs2/libgfs2/libgfs2.h | 79 +++++++++++++---
gfs2/libgfs2/ondisk.c | 142 ++++++++++++++--------------
gfs2/libgfs2/recovery.c | 2 +-
gfs2/libgfs2/rgrp.c | 2 +-
gfs2/libgfs2/structures.c | 9 +-
gfs2/libgfs2/super.c | 5 +-
gfs2/mkfs/Makefile | 2 +-
gfs2/mkfs/gfs2_mkfs.h | 1 -
gfs2/mkfs/main_jadd.c | 8 +-
gfs2/quota/main.c | 19 +++-
gfs2/tool/sb.c | 6 +-
28 files changed, 522 insertions(+), 403 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index e701169..5630b9c 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -31,7 +31,6 @@
#include <linux/gfs2_ondisk.h>
#include "osi_list.h"
#include "copyright.cf"
-#include "ondisk.h"
#include "libgfs2.h"
#include "global.h"
@@ -217,7 +216,7 @@ static int convert_rgs(struct gfs2_sbd *sbp)
sbp->dinodes_alloced += rgd1->rg_useddi;
convert_bitmaps(sbp, rgd);
/* Write the updated rgrp to the gfs2 buffer */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
rgs++;
if (rgs % 100 == 0) {
printf(".");
@@ -332,7 +331,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
bh = bread(&sbp->buf_list, block);
if (new)
memset(bh->b_data, 0, sbp->bsize);
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
hdrsize = sizeof(struct gfs2_meta_header);
@@ -949,7 +948,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
return -1;
}
- gfs2_dinode_out(&inode->i_di, bh->b_data);
+ gfs2_dinode_out(&inode->i_di, bh);
sbp->md.next_inum++; /* update inode count */
return 0;
} /* adjust_inode */
@@ -1196,7 +1195,7 @@ static int fix_one_directory_exhash(struct gfs2_sbd *sbp, struct gfs2_inode *dip
log_crit("Error reading leaf %" PRIx64 "\n", leaf_block);
break;
}
- gfs2_leaf_in(&leaf, (char *)bh_leaf->b_data); /* buffer to structure */
+ gfs2_leaf_in(&leaf, bh_leaf); /* buffer to structure */
error = process_dirent_info(dip, sbp, bh_leaf, leaf.lf_entries);
bmodified(bh_leaf);
brelse(bh_leaf);
@@ -1374,7 +1373,7 @@ static int init(struct gfs2_sbd *sbp)
bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
- gfs2_sb_in(&sbp->sd_sb, bh->b_data);
+ gfs2_sb_in(&sbp->sd_sb, bh);
sbp->bsize = sbp->sd_sb.sb_bsize;
sbp->sd_inptrs = (sbp->bsize - sizeof(struct gfs_indirect)) /
sizeof(uint64_t);
@@ -1661,9 +1660,9 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
convert_bitmaps(sdp, rgd);
for (x = 0; x < rgd->ri.ri_length; x++) {
if (x)
- gfs2_meta_header_out(&mh, rgd->bh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgd->bh[x]);
else
- gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data);
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[x]);
}
/* Add the new gfs2 rg to our list: We'll output the rg index later. */
osi_list_add_prev((osi_list_t *)&rgd->list,
@@ -1887,8 +1886,7 @@ int main(int argc, char **argv)
bh = bread(&sb2.buf_list, sb2.sb_addr);
sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS;
sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI;
- gfs2_sb_out(&sb2.sd_sb, bh->b_data);
- bmodified(bh);
+ gfs2_sb_out(&sb2.sd_sb, bh);
brelse(bh);
bsync(&sb2.buf_list); /* write the buffers to disk */
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 0cf36ef..20bbe42 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -32,21 +32,58 @@
#include "gfs2hex.h"
/* from libgfs2: */
#include "libgfs2.h"
-#include "ondisk.h"
-
-
-extern struct gfs2_sb sb;
-extern char *buf;
-extern struct gfs2_dinode di;
-extern int line, termlines;
-extern char edit_fmt[80];
-extern char estring[1024];
-extern char efield[64];
-extern int edit_mode INIT(0);
-extern int edit_row[DMODES], edit_col[DMODES];
-extern int edit_size[DMODES], last_entry_onscreen[DMODES];
-extern char edit_fmt[80];
-extern enum dsp_mode dmode INIT(HEX_MODE); /* display mode */
+
+#define pv(struct, member, fmt, fmt2) do { \
+ print_it(" "#member, fmt, fmt2, struct->member); \
+ } while (FALSE);
+#define pv2(struct, member, fmt, fmt2) do { \
+ print_it(" ", fmt, fmt2, struct->member); \
+ } while (FALSE);
+
+
+struct gfs2_sb sb;
+struct gfs2_buffer_head *bh;
+struct gfs2_dinode di;
+int line, termlines;
+char edit_fmt[80];
+char estring[1024];
+char efield[64];
+int edit_mode = 0;
+int edit_row[DMODES], edit_col[DMODES];
+int edit_size[DMODES], last_entry_onscreen[DMODES];
+char edit_fmt[80];
+enum dsp_mode dmode = HEX_MODE; /* display mode */
+uint64_t block = 0;
+int blockhist = 0;
+struct iinfo *indirect;
+int indirect_blocks;
+int gfs1 = 0;
+uint64_t block_in_mem = -1;
+struct gfs2_sbd sbd;
+uint64_t starting_blk;
+struct blkstack_info blockstack[BLOCK_STACK_SIZE];
+int identify = FALSE;
+char device[NAME_MAX];
+uint64_t max_block = 0;
+int start_row[DMODES], end_row[DMODES], lines_per_row[DMODES];
+struct gfs_sb *sbd1;
+int gfs2_struct_type;
+unsigned int offset;
+int termcols = 80;
+struct indirect_info masterdir;
+struct gfs2_inum gfs1_quota_di;
+int print_entry_ndx;
+struct gfs2_inum gfs1_license_di;
+int screen_chunk_size = 512;
+uint64_t temp_blk;
+int color_scheme = 0;
+int struct_len;
+uint64_t dev_offset = 0;
+int editing = 0;
+int insert = 0;
+const char *termtype;
+WINDOW *wind;
+int dsplines = 0;
const char *block_type_str[15] = {
"Clump",
@@ -253,7 +290,7 @@ static int indirect_dirent(struct indirect_info *indir, char *ptr, int d)
**
*******************************************************************************
******************************************************************************/
-void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
+void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh)
{
unsigned int x, y, ptroff = 0;
uint64_t p, last;
@@ -266,7 +303,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
/* Indirect pointers */
for (x = sizeof(struct gfs2_dinode); x < sbd.bsize;
x += sizeof(uint64_t)) {
- p = be64_to_cpu(*(uint64_t *)(dinebuf + x));
+ p = be64_to_cpu(*(uint64_t *)(lbh->b_data + x));
if (p) {
indirect->ii[indirect_blocks].block = p;
indirect->ii[indirect_blocks].mp.mp_list[0] =
@@ -285,8 +322,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
indirect->ii[0].block = block;
indirect->ii[0].is_dir = TRUE;
for (x = sizeof(struct gfs2_dinode); x < sbd.bsize; x += skip) {
- skip = indirect_dirent(indirect->ii,
- dinebuf + x,
+ skip = indirect_dirent(indirect->ii, lbh->b_data + x,
indirect->ii[0].dirents);
if (skip <= 0)
break;
@@ -297,12 +333,13 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
dine->di_height == 0) {
/* Leaf Pointers: */
- last = be64_to_cpu(*(uint64_t *)(dinebuf + sizeof(struct gfs2_dinode)));
+ last = be64_to_cpu(*(uint64_t *)(lbh->b_data +
+ sizeof(struct gfs2_dinode)));
for (x = sizeof(struct gfs2_dinode), y = 0;
y < (1 << dine->di_depth);
x += sizeof(uint64_t), y++) {
- p = be64_to_cpu(*(uint64_t *)(dinebuf + x));
+ p = be64_to_cpu(*(uint64_t *)(lbh->b_data + x));
if (p != last || ((y + 1) * sizeof(uint64_t) == dine->di_size)) {
struct gfs2_buffer_head *tmp_bh;
@@ -313,7 +350,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, char *dinebuf)
if (last >= max_block)
break;
tmp_bh = bread(&sbd.buf_list, last);
- gfs2_leaf_in(&leaf, tmp_bh->b_data);
+ gfs2_leaf_in(&leaf, tmp_bh);
indirect->ii[indirect_blocks].dirents = 0;
for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf);
bufoffset < sbd.bsize;
@@ -438,7 +475,7 @@ void do_leaf_extended(char *dlebuf, struct iinfo *indir)
*******************************************************************************
******************************************************************************/
-static void do_eattr_extended(char *deebuf)
+static void do_eattr_extended(struct gfs2_buffer_head *ebh)
{
struct gfs2_ea_header ea;
unsigned int x;
@@ -450,8 +487,9 @@ static void do_eattr_extended(char *deebuf)
for (x = sizeof(struct gfs2_meta_header); x < sbd.bsize; x += ea.ea_rec_len)
{
eol(0);
- gfs2_ea_header_in(&ea, deebuf + x);
- gfs2_ea_header_print(&ea, deebuf + x + sizeof(struct gfs2_ea_header));
+ gfs2_ea_header_in(&ea, ebh->b_data + x);
+ gfs2_ea_header_print(&ea, ebh->b_data + x +
+ sizeof(struct gfs2_ea_header));
}
}
@@ -509,11 +547,11 @@ static void gfs2_sb_print2(struct gfs2_sb *sbp2)
/**
* gfs1_rgrp_in - read in a gfs1 rgrp
*/
-static void gfs1_rgrp_in(struct gfs1_rgrp *rgrp, char *rbuf)
+static void gfs1_rgrp_in(struct gfs1_rgrp *rgrp, struct gfs2_buffer_head *rbh)
{
- struct gfs1_rgrp *str = (struct gfs1_rgrp *)rbuf;
+ struct gfs1_rgrp *str = (struct gfs1_rgrp *)rbh->b_data;
- gfs2_meta_header_in(&rgrp->rg_header, rbuf);
+ gfs2_meta_header_in(&rgrp->rg_header, rbh);
rgrp->rg_flags = be32_to_cpu(str->rg_flags);
rgrp->rg_free = be32_to_cpu(str->rg_free);
rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
@@ -569,12 +607,12 @@ int display_gfs2(void)
uint32_t magic;
- magic = be32_to_cpu(*(uint32_t *)buf);
+ magic = be32_to_cpu(*(uint32_t *)bh->b_data);
switch (magic)
{
case GFS2_MAGIC:
- gfs2_meta_header_in(&mh, buf);
+ gfs2_meta_header_in(&mh, bh);
if (mh.mh_type > GFS2_METATYPE_QC)
print_gfs2("Unknown metadata type");
else
@@ -584,7 +622,7 @@ int display_gfs2(void)
switch (mh.mh_type)
{
case GFS2_METATYPE_SB:
- gfs2_sb_in(&sbd.sd_sb, buf);
+ gfs2_sb_in(&sbd.sd_sb, bh);
gfs2_sb_print2(&sbd.sd_sb);
break;
@@ -592,10 +630,10 @@ int display_gfs2(void)
if (gfs1) {
struct gfs1_rgrp rg1;
- gfs1_rgrp_in(&rg1, buf);
+ gfs1_rgrp_in(&rg1, bh);
gfs1_rgrp_print(&rg1);
} else {
- gfs2_rgrp_in(&rg, buf);
+ gfs2_rgrp_in(&rg, bh);
gfs2_rgrp_print(&rg);
}
break;
@@ -613,7 +651,7 @@ int display_gfs2(void)
break;
case GFS2_METATYPE_LF:
- gfs2_leaf_in(&lf, buf);
+ gfs2_leaf_in(&lf, bh);
gfs2_leaf_print(&lf);
break;
@@ -623,21 +661,21 @@ int display_gfs2(void)
case GFS2_METATYPE_LH:
if (gfs1) {
- gfs_log_header_in(&lh1, buf);
+ gfs_log_header_in(&lh1, bh);
gfs_log_header_print(&lh1);
} else {
- gfs2_log_header_in(&lh, buf);
+ gfs2_log_header_in(&lh, bh);
gfs2_log_header_print(&lh);
}
break;
case GFS2_METATYPE_LD:
- gfs2_log_descriptor_in(&ld, buf);
+ gfs2_log_descriptor_in(&ld, bh);
gfs2_log_descriptor_print(&ld);
break;
case GFS2_METATYPE_EA:
- do_eattr_extended(buf);
+ do_eattr_extended(bh);
break;
case GFS2_METATYPE_ED:
@@ -649,7 +687,7 @@ int display_gfs2(void)
break;
case GFS2_METATYPE_QC:
- gfs2_quota_change_in(&qc, buf);
+ gfs2_quota_change_in(&qc, bh);
gfs2_quota_change_print(&qc);
break;
diff --git a/gfs2/edit/gfs2hex.h b/gfs2/edit/gfs2hex.h
index a35fce5..ebe6b0e 100644
--- a/gfs2/edit/gfs2hex.h
+++ b/gfs2/edit/gfs2hex.h
@@ -18,7 +18,7 @@
int display_gfs2(void);
int edit_gfs2(void);
-void do_dinode_extended(struct gfs2_dinode *di, char *buf);
+void do_dinode_extended(struct gfs2_dinode *di, struct gfs2_buffer_head *lbh);
void print_gfs2(const char *fmt, ...);
int do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt);
void do_leaf_extended(char *dlebuf, struct iinfo *indir);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index a0b9b81..1a9c7ae 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -42,6 +42,10 @@
#define RGLIST_DUMMY_BLOCK -2
+#define pv(struct, member, fmt, fmt2) do { \
+ print_it(" "#member, fmt, fmt2, struct->member); \
+ } while (FALSE);
+
const char *mtypes[] = {"none", "sb", "rg", "rb", "di", "in", "lf", "jd",
"lh", "ld", "ea", "ed", "lb", "13", "qc"};
const char *allocdesc[2][5] = {
@@ -444,9 +448,10 @@ static void print_usage(void)
/* returns: metatype if block is a GFS2 structure block type */
/* 0 if block is not a GFS2 structure */
/* ------------------------------------------------------------------------ */
-static int get_block_type(const char *lpBuffer)
+static int get_block_type(struct gfs2_buffer_head *lbh)
{
int ret_type = 0;
+ char *lpBuffer = lbh->b_data;
if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 &&
*(lpBuffer+2)==0x19 && *(lpBuffer+3)==0x70 &&
@@ -461,7 +466,7 @@ static int get_block_type(const char *lpBuffer)
/* returns: metatype if block is a GFS2 structure block type */
/* 0 if block is not a GFS2 structure */
/* ------------------------------------------------------------------------ */
-int display_block_type(const char *lpBuffer, int from_restore)
+int display_block_type(int from_restore)
{
int ret_type = 0; /* return type */
@@ -498,8 +503,8 @@ int display_block_type(const char *lpBuffer, int from_restore)
ret_type = GFS2_METATYPE_RG;
struct_len = gfs1 ? sizeof(struct gfs_rgrp) : sizeof(struct gfs2_rgrp);
}
- else if ((ret_type = get_block_type(lpBuffer))) {
- switch (*(lpBuffer+7)) {
+ else if ((ret_type = get_block_type(bh))) {
+ switch (*(bh->b_data + 7)) {
case GFS2_METATYPE_SB: /* 1 */
print_gfs2("(superblock)");
if (gfs1)
@@ -595,9 +600,9 @@ int display_block_type(const char *lpBuffer, int from_restore)
sbd.bsize / screen_chunk_size + 1 : sbd.bsize /
screen_chunk_size, allocdesc[gfs1][type]);
/*eol(9);*/
- if ((*(lpBuffer+7) == GFS2_METATYPE_IN) ||
- (*(lpBuffer+7) == GFS2_METATYPE_DI &&
- (*(lpBuffer + 0x8b) || *(lpBuffer + 0x8a)))) {
+ if ((*(bh->b_data + 7) == GFS2_METATYPE_IN) ||
+ (*(bh->b_data + 7) == GFS2_METATYPE_DI &&
+ (*(bh->b_data + 0x8b) || *(bh->b_data + 0x8a)))) {
int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
if (ptroffset >= struct_len || pgnum) {
@@ -656,11 +661,12 @@ int display_block_type(const char *lpBuffer, int from_restore)
/* ------------------------------------------------------------------------ */
/* hexdump - hex dump the filesystem block to the screen */
/* ------------------------------------------------------------------------ */
-static int hexdump(uint64_t startaddr, const char *lpBuffer, int len)
+static int hexdump(uint64_t startaddr, int len)
{
const unsigned char *pointer,*ptr2;
int i;
uint64_t l;
+ const char *lpBuffer = bh->b_data;
strcpy(edit_fmt,"%02X");
pointer = (unsigned char *)lpBuffer + offset;
@@ -834,11 +840,11 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
/* ------------------------------------------------------------------------ */
/* gfs_rgrp_in - Read in a resource group header */
/* ------------------------------------------------------------------------ */
-static void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *gbuf)
+static void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
{
- struct gfs_rgrp *str = (struct gfs_rgrp *)gbuf;
+ struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
- gfs2_meta_header_in(&rgrp->rg_header, gbuf);
+ gfs2_meta_header_in(&rgrp->rg_header, rbh);
rgrp->rg_flags = be32_to_cpu(str->rg_flags);
rgrp->rg_free = be32_to_cpu(str->rg_free);
rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
@@ -851,11 +857,11 @@ static void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *gbuf)
/* ------------------------------------------------------------------------ */
/* gfs_rgrp_out */
/* ------------------------------------------------------------------------ */
-static void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *gbuf)
+static void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
{
- struct gfs_rgrp *str = (struct gfs_rgrp *)gbuf;
+ struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
- gfs2_meta_header_out(&rgrp->rg_header, gbuf);
+ gfs2_meta_header_out(&rgrp->rg_header, rbh);
str->rg_flags = cpu_to_be32(rgrp->rg_flags);
str->rg_free = cpu_to_be32(rgrp->rg_free);
str->rg_useddi = cpu_to_be32(rgrp->rg_useddi);
@@ -885,7 +891,7 @@ static void gfs_rgrp_print(struct gfs_rgrp *rg)
/* ------------------------------------------------------------------------ */
static uint64_t get_rg_addr(int rgnum)
{
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *lbh;
uint64_t rgblk = 0, gblock;
struct gfs2_inode *riinode;
@@ -893,8 +899,8 @@ static uint64_t get_rg_addr(int rgnum)
gblock = sbd1->sb_rindex_di.no_addr;
else
gblock = masterblock("rindex");
- bh = bread(&sbd.buf_list, gblock);
- riinode = inode_get(&sbd, bh);
+ lbh = bread(&sbd.buf_list, gblock);
+ riinode = inode_get(&sbd, lbh);
if (rgnum < riinode->i_di.di_size / risize())
rgblk = find_rgrp_block(riinode, rgnum);
else
@@ -917,26 +923,25 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
struct gfs2_rgrp rg2;
struct gfs_rgrp rg1;
} rg;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *rbh;
uint64_t rgblk;
rgblk = get_rg_addr(rgnum);
- bh = bread(&sbd.buf_list, rgblk);
+ rbh = bread(&sbd.buf_list, rgblk);
if (gfs1)
- gfs_rgrp_in(&rg.rg1, bh->b_data);
+ gfs_rgrp_in(&rg.rg1, rbh);
else
- gfs2_rgrp_in(&rg.rg2, bh->b_data);
+ gfs2_rgrp_in(&rg.rg2, rbh);
if (modify) {
printf("RG #%d (block %llu / 0x%llx) rg_flags changed from 0x%08x to 0x%08x\n",
rgnum, (unsigned long long)rgblk,
(unsigned long long)rgblk, rg.rg2.rg_flags, new_flags);
rg.rg2.rg_flags = new_flags;
if (gfs1)
- gfs_rgrp_out(&rg.rg1, bh->b_data);
+ gfs_rgrp_out(&rg.rg1, rbh);
else
- gfs2_rgrp_out(&rg.rg2, bh->b_data);
- bmodified(bh);
- brelse(bh);
+ gfs2_rgrp_out(&rg.rg2, rbh);
+ brelse(rbh);
} else {
if (full) {
print_gfs2("RG #%d", rgnum);
@@ -951,7 +956,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);
+ brelse(rbh);
}
if (modify)
bsync(&sbd.buf_list);
@@ -1009,11 +1014,11 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
if (gfs1) {
struct gfs_rgrp rg1;
- gfs_rgrp_in(&rg1, tmp_bh->b_data);
+ gfs_rgrp_in(&rg1, tmp_bh);
gfs_rgrp_print(&rg1);
} else {
struct gfs2_rgrp rg;
- gfs2_rgrp_in(&rg, tmp_bh->b_data);
+ gfs2_rgrp_in(&rg, tmp_bh);
gfs2_rgrp_print(&rg);
}
brelse(tmp_bh);
@@ -1619,9 +1624,9 @@ int block_is_in_per_node(void)
return FALSE;
per_node_bh = bread(&sbd.buf_list, masterblock("per_node"));
- gfs2_dinode_in(&per_node_di, per_node_bh->b_data);
+ gfs2_dinode_in(&per_node_di, per_node_bh);
- do_dinode_extended(&per_node_di, per_node_bh->b_data);
+ do_dinode_extended(&per_node_di, per_node_bh);
brelse(per_node_bh);
for (d = 0; d < indirect->ii[0].dirents; d++) {
@@ -1713,15 +1718,10 @@ static void read_superblock(int fd)
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
ioctl(fd, BLKFLSBUF, 0);
- lseek(fd, 0x10 * 4096, SEEK_SET);
- if (read(fd, buf, sbd.bsize) != sbd.bsize) {
- fprintf(stderr, "bad read: %s from %s:%d: superblock\n",
- strerror(errno), __FUNCTION__, __LINE__);
- exit(-1);
- }
memset(&sbd, 0, sizeof(struct gfs2_sbd));
- sbd.device_fd = fd;
sbd.bsize = GFS2_DEFAULT_BSIZE;
+ sbd.device_fd = fd;
+ bh = bread(&sbd.buf_list, 0x10);
sbd.jsize = GFS2_DEFAULT_JSIZE;
sbd.rgsize = GFS2_DEFAULT_RGSIZE;
sbd.utsize = GFS2_DEFAULT_UTSIZE;
@@ -1729,13 +1729,13 @@ static void read_superblock(int fd)
sbd.time = time(NULL);
osi_list_init(&sbd.rglist);
init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
- gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
+ gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */
/* Check to see if this is really gfs1 */
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
sbd1->sb_header.mh_type == GFS_METATYPE_SB &&
sbd1->sb_header.mh_format == GFS_FORMAT_SB &&
sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
- struct gfs_sb *sbbuf = (struct gfs_sb *)buf;
+ struct gfs_sb *sbbuf = (struct gfs_sb *)bh->b_data;
gfs1 = TRUE;
sbd1->sb_flags = be32_to_cpu(sbbuf->sb_flags);
@@ -1784,7 +1784,7 @@ static void read_master_dir(void)
ioctl(sbd.device_fd, BLKFLSBUF, 0);
lseek(sbd.device_fd, sbd.sd_sb.sb_master_dir.no_addr * sbd.bsize,
SEEK_SET);
- if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) {
+ if (read(sbd.device_fd, bh->b_data, sbd.bsize) != sbd.bsize) {
fprintf(stderr, "read error: %s from %s:%d: "
"master dir block %lld (0x%llx)\n",
strerror(errno), __FUNCTION__,
@@ -1793,8 +1793,8 @@ static void read_master_dir(void)
(unsigned long long)sbd.sd_sb.sb_master_dir.no_addr);
exit(-1);
}
- gfs2_dinode_in(&di, buf); /* parse disk inode into structure */
- do_dinode_extended(&di, buf); /* get extended data, if any */
+ gfs2_dinode_in(&di, bh); /* parse disk inode into structure */
+ do_dinode_extended(&di, bh); /* get extended data, if any */
memcpy(&masterdir, &indirect[0], sizeof(struct indirect_info));
}
@@ -1819,8 +1819,7 @@ int display(int identify_only)
if (block_in_mem != blk) { /* If we changed blocks from the last read */
dev_offset = blk * sbd.bsize;
ioctl(sbd.device_fd, BLKFLSBUF, 0);
- lseek(sbd.device_fd, dev_offset, SEEK_SET);
- if (read(sbd.device_fd, buf, sbd.bsize) != sbd.bsize) {
+ if (!(bh = bread(&sbd.buf_list, blk))) {
fprintf(stderr, "read error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
strerror(errno), __FUNCTION__, __LINE__,
@@ -1831,13 +1830,13 @@ int display(int identify_only)
block_in_mem = blk; /* remember which block is in memory */
}
line = 1;
- gfs2_struct_type = display_block_type(buf, FALSE);
+ gfs2_struct_type = display_block_type(FALSE);
if (identify_only)
return 0;
indirect_blocks = 0;
lines_per_row[dmode] = 1;
if (gfs2_struct_type == GFS2_METATYPE_SB || blk == 0x10 * (4096 / sbd.bsize)) {
- gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
+ gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */
memset(indirect, 0, sizeof(indirect));
indirect->ii[0].block = sbd.sd_sb.sb_master_dir.no_addr;
indirect->ii[0].is_dir = TRUE;
@@ -1860,8 +1859,8 @@ int display(int identify_only)
indirect->ii[0].dirent[1].dirent.de_type = DT_DIR;
}
else if (gfs2_struct_type == GFS2_METATYPE_DI) {
- gfs2_dinode_in(&di, buf); /* parse disk inode into structure */
- do_dinode_extended(&di, buf); /* get extended data, if any */
+ gfs2_dinode_in(&di, bh); /* parse disk inode into structure */
+ do_dinode_extended(&di, bh); /* get extended data, if any */
}
else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */
int i, hgt = get_height();
@@ -1872,10 +1871,11 @@ int display(int identify_only)
&blockstack[blockhist - 1].mp,
sizeof(struct metapath));
}
- indirect_blocks = do_indirect_extended(buf, indirect, hgt);
+ indirect_blocks = do_indirect_extended(bh->b_data, indirect,
+ hgt);
}
else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */
- do_leaf_extended(buf, indirect);
+ do_leaf_extended(bh->b_data, indirect);
}
last_entry_onscreen[dmode] = 0;
if (dmode == EXTENDED_MODE && !block_has_extended_info())
@@ -1890,8 +1890,7 @@ int display(int identify_only)
move(line, 0);
}
if (dmode == HEX_MODE) /* if hex display mode */
- hexdump(dev_offset, buf,
- (gfs2_struct_type == GFS2_METATYPE_DI)?
+ hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)?
struct_len + di.di_size:sbd.bsize);
else if (dmode == GFS2_MODE) /* if structure display */
display_gfs2(); /* display the gfs2 structure */
@@ -1975,10 +1974,10 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
/* read in the block */
jindex_bh = bread(&sbd.buf_list, jindex_block);
/* get the dinode data from it. */
- gfs2_dinode_in(&di, jindex_bh->b_data); /* parse disk inode to struct*/
+ gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
if (!gfs1)
- do_dinode_extended(&di, jindex_bh->b_data); /* parse dir. */
+ do_dinode_extended(&di, jindex_bh); /* parse dir. */
brelse(jindex_bh);
if (gfs1) {
@@ -2000,7 +1999,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
jblock = indirect->ii[0].dirent[journal_num + 2].block;
j_bh = bread(&sbd.buf_list, jblock);
j_inode = inode_get(&sbd, j_bh);
- gfs2_dinode_in(&jdi, j_bh->b_data);/* parse dinode to struct */
+ gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */
*j_size = jdi.di_size;
brelse(j_bh);
}
@@ -2017,21 +2016,21 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
{
uint64_t blk, last_fs_block;
int found = 0;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *lbh;
last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
for (blk = startblk + 1; blk < last_fs_block; blk++) {
- bh = bread(&sbd.buf_list, blk);
+ lbh = bread(&sbd.buf_list, blk);
/* Can't use get_block_type here (returns false "none") */
- if (bh->b_data[0] == 0x01 && bh->b_data[1] == 0x16 &&
- bh->b_data[2] == 0x19 && bh->b_data[3] == 0x70 &&
- bh->b_data[4] == 0x00 && bh->b_data[5] == 0x00 &&
- bh->b_data[6] == 0x00 && bh->b_data[7] == metatype) {
+ if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 &&
+ lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 &&
+ lbh->b_data[4] == 0x00 && lbh->b_data[5] == 0x00 &&
+ lbh->b_data[6] == 0x00 && lbh->b_data[7] == metatype) {
found = 1;
- brelse(bh);
+ brelse(lbh);
break;
}
- brelse(bh);
+ brelse(lbh);
}
if (!found)
blk = 0;
@@ -2312,10 +2311,10 @@ static void hex_edit(int *exitch)
else if (estring[i+1] >= 'A' &&
estring[i+1] <= 'F')
ch += (estring[i+1] - 'A' + 0x0a);
- buf[offset + hexoffset] = ch;
+ bh->b_data[offset + hexoffset] = ch;
}
lseek(sbd.device_fd, dev_offset, SEEK_SET);
- if (write(sbd.device_fd, buf, sbd.bsize) !=
+ if (write(sbd.device_fd, bh->b_data, sbd.bsize) !=
sbd.bsize) {
fprintf(stderr, "write error: %s from %s:%d: "
"offset %lld (0x%llx)\n",
@@ -2402,7 +2401,8 @@ static void jump(void)
if (edit_row[dmode] >= 0) {
col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */
- b = (uint64_t *)&buf[edit_row[dmode]*16 + offset + col2];
+ b = (uint64_t *)&bh->b_data[edit_row[dmode]*16 +
+ offset + col2];
temp_blk=be64_to_cpu(*b);
}
}
@@ -2441,14 +2441,14 @@ static void print_block_type(uint64_t tblock, int type, const char *additional)
static void find_print_block_type(void)
{
uint64_t tblock;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *lbh;
int type;
tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- bh = bread(&sbd.buf_list, tblock);
- type = get_block_type(bh->b_data);
+ lbh = bread(&sbd.buf_list, tblock);
+ type = get_block_type(lbh);
print_block_type(tblock, type, "");
- brelse(bh);
+ brelse(lbh);
gfs2_rgrp_free(&sbd.rglist);
exit(0);
}
@@ -2551,13 +2551,14 @@ static void find_change_block_alloc(int *newval)
static void process_field(const char *field, uint64_t *newval, int print_field)
{
uint64_t fblock;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *rbh;
int type;
struct gfs2_rgrp rg;
fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
- bh = bread(&sbd.buf_list, fblock);
- type = get_block_type(bh->b_data);
+ rbh = bread(&sbd.buf_list, block);
+ type = get_block_type(rbh);
+
switch (type) {
case GFS2_METATYPE_SB:
if (print_field)
@@ -2565,10 +2566,10 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
" which is not implemented");
break;
case GFS2_METATYPE_RG:
- gfs2_rgrp_in(&rg, bh->b_data);
+ gfs2_rgrp_in(&rg, rbh);
if (newval) {
gfs2_rgrp_assignval(&rg, field, *newval);
- gfs2_rgrp_out(&rg, bh->b_data);
+ gfs2_rgrp_out(&rg, rbh);
if (print_field)
gfs2_rgrp_printval(&rg, field);
} else {
@@ -2582,10 +2583,10 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
" which is not implemented");
break;
case GFS2_METATYPE_DI:
- gfs2_dinode_in(&di, bh->b_data);
+ gfs2_dinode_in(&di, rbh);
if (newval) {
gfs2_dinode_assignval(&di, field, *newval);
- gfs2_dinode_out(&di, bh->b_data);
+ gfs2_dinode_out(&di, rbh);
if (print_field)
gfs2_dinode_printval(&di, field);
} else {
@@ -2609,8 +2610,8 @@ static void process_field(const char *field, uint64_t *newval, int print_field)
break;
}
if (newval)
- bmodified(bh);
- brelse(bh);
+ bmodified(rbh);
+ brelse(rbh);
bcommit(&sbd.buf_list);
}
@@ -2882,11 +2883,12 @@ static void interactive_mode(void)
/* ------------------------------------------------------------------------ */
/* gfs_log_header_in - read in a gfs1-style log header */
/* ------------------------------------------------------------------------ */
-void gfs_log_header_in(struct gfs_log_header *head, char *inbuf)
+void gfs_log_header_in(struct gfs_log_header *head,
+ struct gfs2_buffer_head *lbh)
{
- struct gfs_log_header *str = (struct gfs_log_header *) inbuf;
+ struct gfs_log_header *str = (struct gfs_log_header *)lbh->b_data;
- gfs2_meta_header_in(&head->lh_header, inbuf);
+ gfs2_meta_header_in(&head->lh_header, lbh);
head->lh_flags = be32_to_cpu(str->lh_flags);
head->lh_pad = be32_to_cpu(str->lh_pad);
@@ -2955,7 +2957,7 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
unsigned int size, uint64_t *abs_block)
{
struct gfs2_sbd *sdp = ip->i_sbd;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *lbh;
uint64_t lblock, dblock;
unsigned int o;
uint32_t extlen = 0;
@@ -2992,16 +2994,16 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
block_map(ip, lblock, ¬_new, &dblock, &extlen,
FALSE);
if (dblock) {
- bh = bread(&sdp->buf_list, dblock);
+ lbh = bread(&sdp->buf_list, dblock);
if (*abs_block == 0)
- *abs_block = bh->b_blocknr;
+ *abs_block = lbh->b_blocknr;
dblock++;
extlen--;
} else
- bh = NULL;
- if (bh) {
- memcpy(rbuf, bh->b_data + o, amount);
- brelse(bh);
+ lbh = NULL;
+ if (lbh) {
+ memcpy(rbuf, lbh->b_data + o, amount);
+ brelse(lbh);
} else {
memset(rbuf, 0, amount);
}
@@ -3032,13 +3034,13 @@ static void check_journal_wrap(uint64_t seq, uint64_t *highest_seq)
/* ------------------------------------------------------------------------ */
static void dump_journal(const char *journal)
{
- struct gfs2_buffer_head *j_bh = NULL;
+ struct gfs2_buffer_head *j_bh = NULL, dummy_bh;
uint64_t jblock, j_size, jb, abs_block;
int error, start_line, journal_num;
- char jbuf[sbd.bsize];
struct gfs2_inode *j_inode = NULL;
int ld_blocks = 0;
uint64_t highest_seq = 0;
+ char *jbuf = NULL;
start_line = line;
lines_per_row[dmode] = 1;
@@ -3052,6 +3054,7 @@ static void dump_journal(const char *journal)
if (!gfs1) {
j_bh = bread(&sbd.buf_list, jblock);
j_inode = inode_get(&sbd, j_bh);
+ jbuf = malloc(sbd.bsize);
}
for (jb = 0; jb < j_size; jb += (gfs1 ? 1:sbd.bsize)) {
@@ -3060,14 +3063,15 @@ static void dump_journal(const char *journal)
brelse(j_bh);
j_bh = bread(&sbd.buf_list, jblock + jb);
abs_block = jblock + jb;
- memcpy(jbuf, j_bh->b_data, sbd.bsize);
+ dummy_bh.b_data = j_bh->b_data;
} else {
error = fsck_readi(j_inode, (void *)&jbuf, jb,
sbd.bsize, &abs_block);
if (!error) /* end of file */
break;
+ dummy_bh.b_data = jbuf;
}
- if (get_block_type(jbuf) == GFS2_METATYPE_LD) {
+ if (get_block_type(&dummy_bh) == GFS2_METATYPE_LD) {
uint64_t *b;
struct gfs2_log_descriptor ld;
int ltndx;
@@ -3090,7 +3094,7 @@ static void dump_journal(const char *journal)
print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
abs_block, jb / (gfs1 ? 1 : sbd.bsize));
- gfs2_log_descriptor_in(&ld, jbuf);
+ gfs2_log_descriptor_in(&ld, &dummy_bh);
print_gfs2("type %d ", ld.ld_type);
for (ltndx = 0;; ltndx++) {
@@ -3104,20 +3108,21 @@ static void dump_journal(const char *journal)
eol(0);
print_gfs2(" ");
if (gfs1)
- b = (uint64_t *)(jbuf +
+ b = (uint64_t *)(dummy_bh.b_data +
sizeof(struct gfs_log_descriptor));
else
- b = (uint64_t *)(jbuf +
+ b = (uint64_t *)(dummy_bh.b_data +
sizeof(struct gfs2_log_descriptor));
ld_blocks = ld.ld_data1;
- ld_blocks -= print_ld_blocks(b, (jbuf + sbd.bsize),
+ ld_blocks -= print_ld_blocks(b, (dummy_bh.b_data +
+ sbd.bsize),
start_line);
- } else if (get_block_type(jbuf) == GFS2_METATYPE_LH) {
+ } else if (get_block_type(&dummy_bh) == GFS2_METATYPE_LH) {
struct gfs2_log_header lh;
struct gfs_log_header lh1;
if (gfs1) {
- gfs_log_header_in(&lh1, jbuf);
+ gfs_log_header_in(&lh1, &dummy_bh);
check_journal_wrap(lh1.lh_sequence,
&highest_seq);
print_gfs2("0x%llx (j+%4llx): Log header: "
@@ -3128,7 +3133,7 @@ static void dump_journal(const char *journal)
lh1.lh_first, lh1.lh_tail,
lh1.lh_last_dump);
} else {
- gfs2_log_header_in(&lh, jbuf);
+ gfs2_log_header_in(&lh, &dummy_bh);
check_journal_wrap(lh.lh_sequence,
&highest_seq);
print_gfs2("0x%llx (j+%4llx): Log header: Seq"
@@ -3143,13 +3148,14 @@ static void dump_journal(const char *journal)
" continuation block", abs_block, jb);
eol(0);
print_gfs2(" ");
- ld_blocks -= print_ld_blocks((uint64_t *)jbuf,
- (jbuf + sbd.bsize),
- start_line);
+ ld_blocks -= print_ld_blocks((uint64_t *)dummy_bh.b_data,
+ (dummy_bh.b_data +
+ sbd.bsize), start_line);
}
}
brelse(j_bh);
blockhist = -1; /* So we don't print anything else */
+ free(jbuf);
}
/* ------------------------------------------------------------------------ */
@@ -3479,7 +3485,6 @@ int main(int argc, char *argv[])
memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
dmode = INIT_MODE;
sbd.bsize = 4096;
- type_alloc(buf, char, sbd.bsize); /* allocate/malloc a new 4K buffer */
block = starting_blk = 0x10;
for (i = 0; i < BLOCK_STACK_SIZE; i++) {
blockstack[i].dmode = HEX_MODE;
@@ -3536,8 +3541,6 @@ int main(int argc, char *argv[])
}
}
close(fd);
- if (buf)
- free(buf);
if (indirect)
free(indirect);
gfs2_rgrp_free(&sbd.rglist);
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index c508345..6996ab5 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -66,45 +66,45 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
#define GFS_LOG_DESC_Q (402) /* quota */
#define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */
-EXTERN uint64_t block INIT(0);
-EXTERN int blockhist INIT(0);
-EXTERN int edit_mode INIT(0);
-EXTERN int line;
-EXTERN char edit_fmt[80];
-EXTERN char estring[1024]; /* edit string */
-EXTERN char efield[64];
-EXTERN uint64_t dev_offset INIT(0);
-EXTERN uint64_t max_block INIT(0);
-EXTERN char *buf INIT(NULL);
-EXTERN int termlines INIT(30);
-EXTERN int termcols INIT(80);
-EXTERN int insert INIT(0);
-EXTERN const char *termtype;
-EXTERN int line INIT(1);
-EXTERN int struct_len INIT(0);
-EXTERN unsigned int offset;
-EXTERN int edit_row[DMODES], edit_col[DMODES], print_entry_ndx;
-EXTERN int start_row[DMODES], end_row[DMODES], lines_per_row[DMODES];
-EXTERN int edit_size[DMODES], last_entry_onscreen[DMODES];
-EXTERN char edit_fmt[80];
-EXTERN struct gfs2_sbd sbd;
-EXTERN struct gfs_sb *sbd1;
-EXTERN struct gfs2_inum gfs1_quota_di; /* kludge because gfs2 sb too small */
-EXTERN struct gfs2_inum gfs1_license_di; /* kludge because gfs2 sb too small */
-EXTERN struct gfs2_dinode di;
-EXTERN int screen_chunk_size INIT(512); /* how much of the 4K can fit on screen */
-EXTERN int gfs2_struct_type;
-EXTERN uint64_t block_in_mem INIT(-1);
-EXTERN char device[NAME_MAX];
-EXTERN int identify INIT(FALSE);
-EXTERN int color_scheme INIT(0);
-EXTERN WINDOW *wind;
-EXTERN int gfs1 INIT(0);
-EXTERN int editing INIT(0);
-EXTERN uint64_t temp_blk;
-EXTERN uint64_t starting_blk;
-EXTERN const char *block_type_str[15];
-EXTERN int dsplines;
+extern uint64_t block;
+extern int blockhist;
+extern int edit_mode;
+extern int line;
+extern char edit_fmt[80];
+extern char estring[1024]; /* edit string */
+extern char efield[64];
+extern uint64_t dev_offset;
+extern uint64_t max_block;
+extern struct gfs2_buffer_head *bh;
+extern int termlines;
+extern int termcols;
+extern int insert;
+extern const char *termtype;
+extern int line;
+extern int struct_len;
+extern unsigned int offset;
+extern int edit_row[DMODES], edit_col[DMODES], print_entry_ndx;
+extern int start_row[DMODES], end_row[DMODES], lines_per_row[DMODES];
+extern int edit_size[DMODES], last_entry_onscreen[DMODES];
+extern char edit_fmt[80];
+extern struct gfs2_sbd sbd;
+extern struct gfs_sb *sbd1;
+extern struct gfs2_inum gfs1_quota_di; /* kludge because gfs2 sb too small */
+extern struct gfs2_inum gfs1_license_di; /* kludge because gfs2 sb too small */
+extern struct gfs2_dinode di;
+extern int screen_chunk_size; /* how much of the 4K can fit on screen */
+extern int gfs2_struct_type;
+extern uint64_t block_in_mem;
+extern char device[NAME_MAX];
+extern int identify;
+extern int color_scheme;
+extern WINDOW *wind;
+extern int gfs1;
+extern int editing;
+extern uint64_t temp_blk;
+extern uint64_t starting_blk;
+extern const char *block_type_str[15];
+extern int dsplines;
struct gfs_jindex {
uint64_t ji_addr; /* starting block of the journal */
@@ -171,20 +171,25 @@ struct gfs_rgrp {
char rg_reserved[64];
};
-EXTERN int block_is_jindex(void);
-EXTERN int block_is_rindex(void);
-EXTERN int block_is_inum_file(void);
-EXTERN int block_is_statfs_file(void);
-EXTERN int block_is_quota_file(void);
-EXTERN int block_is_per_node(void);
-EXTERN int block_is_in_per_node(void);
-EXTERN int display_block_type(const char *lpBuffer, int from_restore);
-EXTERN void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
-EXTERN void gfs_log_header_in(struct gfs_log_header *head, char *buf);
-EXTERN void gfs_log_header_print(struct gfs_log_header *lh);
-EXTERN void gfs_dinode_in(struct gfs_dinode *di, char *buf);
-EXTERN int display(int identify_only);
-EXTERN uint64_t check_keywords(const char *kword);
+extern int block_is_jindex(void);
+extern int block_is_rindex(void);
+extern int block_is_inum_file(void);
+extern int block_is_statfs_file(void);
+extern int block_is_quota_file(void);
+extern int block_is_per_node(void);
+extern int block_is_in_per_node(void);
+extern int display_block_type(int from_restore);
+extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
+extern void gfs_log_header_in(struct gfs_log_header *head,
+ struct gfs2_buffer_head *bh);
+extern void gfs_log_header_print(struct gfs_log_header *lh);
+extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh);
+extern void savemeta(const char *out_fn, int saveoption);
+extern void restoremeta(const char *in_fn, const char *out_device,
+ uint64_t printblocksonly);
+extern int display(int identify_only);
+extern uint64_t check_keywords(const char *kword);
+extern uint64_t masterblock(const char *fn);
struct gfs2_dirents {
uint64_t block;
@@ -246,12 +251,12 @@ struct gfs_sb {
char sb_reserved[96];
};
-EXTERN struct blkstack_info blockstack[BLOCK_STACK_SIZE];
-EXTERN struct iinfo *indirect; /* more than the most indirect
+extern struct blkstack_info blockstack[BLOCK_STACK_SIZE];
+extern struct iinfo *indirect; /* more than the most indirect
pointers possible for any given 4K block */
-EXTERN struct indirect_info masterdir; /* Master directory info */
-EXTERN int indirect_blocks INIT(0); /* count of indirect blocks */
-EXTERN enum dsp_mode dmode INIT(HEX_MODE);
+extern struct indirect_info masterdir; /* Master directory info */
+extern int indirect_blocks; /* count of indirect blocks */
+extern enum dsp_mode dmode;
#define SCREEN_HEIGHT (16)
#define SCREEN_WIDTH (16)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 3a34c96..39888fa 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -46,6 +46,7 @@ struct saved_metablock {
};
struct saved_metablock *savedata;
+struct gfs2_buffer_head *savebh;
uint64_t last_fs_block, last_reported_block, blks_saved, total_out, pct;
struct gfs2_bmap *blocklist = NULL;
uint64_t journal_blocks[MAX_JOURNALS_SAVED];
@@ -64,15 +65,15 @@ uint64_t masterblock(const char *fn);
* returns: 0 if successful
* -1 if this isn't gfs metadata.
*/
-static int get_gfs_struct_info(char *gbuf, int *block_type, int *gstruct_len)
+static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
+ int *gstruct_len)
{
- struct gfs2_meta_header mh, mhbuf;
+ struct gfs2_meta_header mh;
*block_type = 0;
*gstruct_len = sbd.bsize;
- memcpy(&mhbuf, gbuf, sizeof(mhbuf));
- gfs2_meta_header_in(&mh, (void *)&mhbuf);
+ gfs2_meta_header_in(&mh, lbh);
if (mh.mh_magic != GFS2_MAGIC)
return -1;
@@ -201,15 +202,15 @@ static int save_block(int fd, int out_fd, uint64_t blk)
return 0;
}
memset(savedata, 0, sizeof(struct saved_metablock));
- do_lseek(fd, blk * sbd.bsize);
- do_read(fd, savedata->buf, sbd.bsize); /* read in the block */
+ savebh = bread(&sbd.buf_list, blk);
+ memcpy(&savedata->buf, savebh->b_data, sbd.bsize);
/* If this isn't metadata and isn't a system file, we don't want it.
Note that we're checking "block" here rather than blk. That's
because we want to know if the source inode's "block" is a system
inode, not the block within the inode "blk". They may or may not
be the same thing. */
- if (get_gfs_struct_info(savedata->buf, &blktype, &blklen) &&
+ if (get_gfs_struct_info(savebh, &blktype, &blklen) &&
!block_is_systemfile())
return 0; /* Not metadata, and not system file, so skip it */
trailing0 = 0;
@@ -371,16 +372,17 @@ static void save_inode_data(int out_fd)
}
if (inode->i_di.di_eattr) { /* if this inode has extended attributes */
struct gfs2_meta_header mh;
+ struct gfs2_buffer_head *lbh;
- metabh = bread(&sbd.buf_list, inode->i_di.di_eattr);
+ lbh = bread(&sbd.buf_list, inode->i_di.di_eattr);
save_block(sbd.device_fd, out_fd, inode->i_di.di_eattr);
- gfs2_meta_header_in(&mh, metabh->b_data);
+ gfs2_meta_header_in(&mh, lbh);
if (mh.mh_magic == GFS2_MAGIC &&
mh.mh_type == GFS2_METATYPE_EA)
- save_ea_block(out_fd, metabh);
+ save_ea_block(out_fd, lbh);
else if (mh.mh_magic == GFS2_MAGIC &&
mh.mh_type == GFS2_METATYPE_IN)
- save_indirect_blocks(out_fd, cur_list, metabh, 2, 2);
+ save_indirect_blocks(out_fd, cur_list, lbh, 2, 2);
else {
if (mh.mh_magic == GFS2_MAGIC) /* if it's metadata */
save_block(sbd.device_fd, out_fd,
@@ -394,15 +396,15 @@ static void save_inode_data(int out_fd)
(unsigned long long)block,
(unsigned long long)block);
}
- brelse(metabh);
+ brelse(lbh);
}
inode_put(inode);
+ brelse(metabh);
}
static void get_journal_inode_blocks(void)
{
int journal;
- struct gfs2_buffer_head *bh;
journals_found = 0;
memset(journal_blocks, 0, sizeof(journal_blocks));
@@ -442,7 +444,7 @@ static void get_journal_inode_blocks(void)
jblock = indirect->ii[0].dirent[journal + 2].block;
bh = bread(&sbd.buf_list, jblock);
j_inode = inode_get(&sbd, bh);
- gfs2_dinode_in(&jdi, bh->b_data);
+ gfs2_dinode_in(&jdi, bh);
inode_put(j_inode);
}
journal_blocks[journals_found++] = jblock;
@@ -456,7 +458,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
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;
+ struct gfs2_buffer_head *lbh;
if(!first && (*nrfblock < rgd->ri.ri_data0)) {
log_err("next_rg_freemeta: Start block is outside rgrp "
@@ -471,11 +473,11 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
}
for(; i < length; i++){
bits = &rgd->bits[i];
- bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+ lbh = 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);
+ brelse(lbh);
if(blk != BFITNOENT){
*nrfblock = blk + (bits->bi_start * GFS2_NBBY) +
rgd->ri.ri_data0;
@@ -488,7 +490,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
return 0;
}
-void savemeta(char *out_fn, int saveoption)
+void savemeta(const char *out_fn, int saveoption)
{
int out_fd;
int slow;
@@ -496,7 +498,7 @@ void savemeta(char *out_fn, int saveoption)
uint64_t memreq;
int rgcount;
uint64_t jindex_block;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *lbh;
slow = (saveoption == 1);
sbd.md.journals = 1;
@@ -569,11 +571,11 @@ void savemeta(char *out_fn, int saveoption)
&sbd.md.riinode);
jindex_block = masterblock("jindex");
}
- bh = bread(&sbd.buf_list, jindex_block);
- gfs2_dinode_in(&di, bh->b_data);
+ lbh = bread(&sbd.buf_list, jindex_block);
+ gfs2_dinode_in(&di, lbh);
if (!gfs1)
- do_dinode_extended(&di, bh->b_data);
- brelse(bh);
+ do_dinode_extended(&di, lbh);
+ brelse(lbh);
}
if (!slow) {
printf("Reading resource groups...");
@@ -805,14 +807,14 @@ static int restore_data(int fd, int in_fd, int printblocksonly)
if (block > highest_valid_block)
highest_valid_block = block;
if (printblocksonly > 1 && printblocksonly == block) {
- memcpy(buf, savedata->buf, sbd.bsize);
+ memcpy(bh->b_data, savedata->buf, sbd.bsize);
block_in_mem = block;
display(0);
return 0;
} else if (printblocksonly == 1) {
print_gfs2("%d (l=0x%x): ", blks_saved,
savedata->siglen);
- display_block_type(savedata->buf, TRUE);
+ display_block_type(TRUE);
}
} else {
warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 29e7d2e..13a60ae 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -386,8 +386,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip)
log_warn( _("Renumbering it as 0x%llx\n"), lh.lh_sequence);
block_map(ip, blk, &new, &dblock, &extlen, FALSE);
bh = bread(&ip->i_sbd->buf_list, dblock);
- gfs2_log_header_out(&lh, bh->b_data);
- bmodified(bh);
+ gfs2_log_header_out(&lh, bh);
brelse(bh);
}
return 0;
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 953c2dc..f7d1279 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -325,20 +325,25 @@ void check_statfs(struct gfs2_sbd *sdp)
log_err( _("The statfs file is wrong:\n\n"));
log_err( _("Current statfs values:\n"));
log_err( _("blocks: %lld (0x%llx)\n"),
- sc.sc_total, sc.sc_total);
+ (unsigned long long)sc.sc_total,
+ (unsigned long long)sc.sc_total);
log_err( _("free: %lld (0x%llx)\n"),
- sc.sc_free, sc.sc_free);
+ (unsigned long long)sc.sc_free,
+ (unsigned long long)sc.sc_free);
log_err( _("dinodes: %lld (0x%llx)\n\n"),
- sc.sc_dinodes, sc.sc_dinodes);
+ (unsigned long long)sc.sc_dinodes,
+ (unsigned long long)sc.sc_dinodes);
log_err( _("Calculated statfs values:\n"));
log_err( _("blocks: %lld (0x%llx)\n"),
- sdp->blks_total, sdp->blks_total);
+ (unsigned long long)sdp->blks_total,
+ (unsigned long long)sdp->blks_total);
log_err( _("free: %lld (0x%llx)\n"),
- sdp->blks_total - sdp->blks_alloced,
- sdp->blks_total - sdp->blks_alloced);
+ (unsigned long long)(sdp->blks_total - sdp->blks_alloced),
+ (unsigned long long)(sdp->blks_total - sdp->blks_alloced));
log_err( _("dinodes: %lld (0x%llx)\n"),
- sdp->dinodes_alloced, sdp->dinodes_alloced);
+ (unsigned long long)sdp->dinodes_alloced,
+ (unsigned long long)sdp->dinodes_alloced);
errors_found++;
if (!query( _("Okay to fix the master statfs file? (y/n)"))) {
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 5052eb6..d3cdd22 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -79,8 +79,12 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
{
struct gfs2_inode *ip, *sysip;
- zalloc(ip, sizeof(struct gfs2_inode));
- gfs2_dinode_in(&ip->i_di, bh->b_data);
+ ip = calloc(1, sizeof(struct gfs2_inode));
+ if (ip == NULL) {
+ fprintf(stderr, _("Out of memory in %s\n"), __FUNCTION__);
+ exit(-1);
+ }
+ gfs2_dinode_in(&ip->i_di, bh);
ip->i_bh = bh;
ip->i_sbd = sdp;
@@ -101,7 +105,7 @@ void fsck_inode_put(struct gfs2_inode *ip)
sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr);
if (sysip) {
if (ip->i_bh->b_changed)
- gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
brelse(ip->i_bh);
} else {
inode_put(ip);
@@ -428,10 +432,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
factor++;
divisor /= 2;
}
- gfs2_leaf_in(&oldleaf, lbh->b_data);
+ gfs2_leaf_in(&oldleaf, lbh);
oldleaf.lf_depth = ip->i_di.di_depth - factor;
- gfs2_leaf_out(&oldleaf, lbh->b_data);
- bmodified(lbh);
+ gfs2_leaf_out(&oldleaf, lbh);
brelse(lbh);
}
else
@@ -472,7 +475,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
brelse(lbh);
break;
}
- gfs2_leaf_in(&leaf, lbh->b_data);
+ gfs2_leaf_in(&leaf, lbh);
if(pass->check_leaf) {
error = pass->check_leaf(ip, leaf_no, lbh,
pass->private);
@@ -488,9 +491,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (leaf.lf_dirent_format == (GFS2_FORMAT_DE << 16)) {
log_debug( _("incorrect lf_dirent_format at leaf #%" PRIu64 "\n"), leaf_no);
leaf.lf_dirent_format = GFS2_FORMAT_DE;
- gfs2_leaf_out(&leaf, lbh->b_data);
+ gfs2_leaf_out(&leaf, lbh);
log_debug( _("Fixing lf_dirent_format.\n"));
- bmodified(lbh);
}
/* Make sure it's really a leaf. */
@@ -529,7 +531,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if(count != leaf.lf_entries) {
lbh = bread(&sbp->buf_list, leaf_no);
- gfs2_leaf_in(&leaf, lbh->b_data);
+ gfs2_leaf_in(&leaf, lbh);
log_err( _("Leaf %llu (0x%llx) entry "
"count in directory %llu"
@@ -545,9 +547,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
leaf.lf_entries, count);
if(query( _("Update leaf entry count? (y/n) "))) {
leaf.lf_entries = count;
- gfs2_leaf_out(&leaf, lbh->b_data);
+ gfs2_leaf_out(&leaf, lbh);
log_warn( _("Leaf entry count updated\n"));
- bmodified(lbh);
} else
log_err( _("Leaf entry count left in inconsistant state\n"));
brelse(lbh);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index bbf2e83..de93345 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -692,7 +692,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
PRIu64 " (0x%" PRIx64 ")? (y/n) "),
block, block)) {
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);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
bmodified(ip->i_bh);
} else
log_err( _("Address in inode at block #%" PRIu64
@@ -890,7 +890,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
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);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
} else
log_err( _("Bad block count for #%llu (0x%llx"
") not fixed\n"),
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index e0b7ab3..78f1ed6 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -164,7 +164,7 @@ static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
}
/* Return the number of leaf entries so metawalk doesn't flag this
leaf as having none. */
- gfs2_leaf_in(&leaf, bh->b_data);
+ gfs2_leaf_in(&leaf, bh);
*count = leaf.lf_entries;
return 0;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index dae2c66..efad774 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -202,7 +202,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
if(query( _("Update resource group counts? (y/n) "))) {
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
- gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
+ gfs2_rgrp_out(&rgp->rg, rgp->bh[0]);
} else
log_err( _("Resource group counts left inconsistent\n"));
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 65080a2..a20e9c5 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -396,16 +396,15 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
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, rg->bh[x]);
} 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);
+ gfs2_rgrp_out(&rg->rg, rg->bh[x]);
}
- bmodified(rg->bh[x]);
brelse(rg->bh[x]);
return 0;
}
diff --git a/gfs2/libgfs2/Makefile b/gfs2/libgfs2/Makefile
index 7eeb2ac..855bc4c 100644
--- a/gfs2/libgfs2/Makefile
+++ b/gfs2/libgfs2/Makefile
@@ -26,7 +26,7 @@ LD=gcc
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
+H=gfs2_disk_hash.h libgfs2.h linux_endian.h osi_list.h
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})
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index aa62edf..ea72e3d 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -224,10 +224,9 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
for (x = 0; x < bitblocks; x++) {
bh = bget(&sdp->buf_list, rl->start + x);
if (x)
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
else
- gfs2_rgrp_out(&rg, bh->b_data);
- bmodified(bh);
+ gfs2_rgrp_out(&rg, bh);
brelse(bh);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 48ad90d..1dcae78 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -35,8 +35,12 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
{
struct gfs2_inode *ip;
- zalloc(ip, sizeof(struct gfs2_inode));
- gfs2_dinode_in(&ip->i_di, bh->b_data);
+ ip = calloc(1, sizeof(struct gfs2_inode));
+ if (ip == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+ gfs2_dinode_in(&ip->i_di, bh);
ip->i_bh = bh;
ip->i_sbd = sdp;
return ip;
@@ -45,7 +49,7 @@ struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
void inode_put(struct gfs2_inode *ip)
{
if (ip->i_bh->b_changed)
- gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
brelse(ip->i_bh);
free(ip);
}
@@ -114,7 +118,7 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
rg->rg_free--;
bmodified(bh);
- gfs2_rgrp_out(rg, rl->bh[0]->b_data);
+ gfs2_rgrp_out(rg, rl->bh[0]);
sdp->blks_alloced++;
return ri->ri_data0 + bn;
@@ -177,14 +181,13 @@ void unstuff_dinode(struct gfs2_inode *ip)
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_JD;
mh.mh_format = GFS2_FORMAT_JD;
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
buffer_copy_tail(sdp, bh,
sizeof(struct gfs2_meta_header),
ip->i_bh, sizeof(struct gfs2_dinode));
- bmodified(bh);
brelse(bh);
} else {
block = data_alloc(ip);
@@ -192,8 +195,6 @@ void unstuff_dinode(struct gfs2_inode *ip)
buffer_copy_tail(sdp, bh, 0,
ip->i_bh, sizeof(struct gfs2_dinode));
-
- bmodified(bh);
brelse(bh);
}
}
@@ -202,6 +203,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
if (ip->i_di.di_size) {
*(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block);
+ /* no need: bmodified(ip->i_bh); buffer_clear_tail does it */
ip->i_di.di_blocks++;
}
@@ -257,13 +259,11 @@ void build_height(struct gfs2_inode *ip, int height)
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_IN;
mh.mh_format = GFS2_FORMAT_IN;
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
buffer_copy_tail(sdp, bh,
sizeof(struct gfs2_meta_header),
ip->i_bh, sizeof(struct gfs2_dinode));
-
- bmodified(bh);
brelse(bh);
}
@@ -271,6 +271,7 @@ void build_height(struct gfs2_inode *ip, int height)
if (new_block) {
*(uint64_t *)(ip->i_bh->b_data + sizeof(struct gfs2_dinode)) = cpu_to_be64(block);
+ /* no need: bmodified(ip->i_bh);*/
ip->i_di.di_blocks++;
}
@@ -375,8 +376,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);
+ gfs2_meta_header_out(&mh, bh);
} else
bh = bread(&sdp->buf_list, *dblock);
}
@@ -551,7 +551,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_JD;
mh.mh_format = GFS2_FORMAT_JD;
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
} else
bh = bread(&sdp->buf_list, dblock);
@@ -758,7 +758,7 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_LF;
mh.mh_format = GFS2_FORMAT_LF;
- gfs2_meta_header_out(&mh, nbh->b_data);
+ gfs2_meta_header_out(&mh, nbh);
}
nleaf = (struct gfs2_leaf *)nbh->b_data;
@@ -839,7 +839,6 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t lea
dip->i_di.di_blocks++;
brelse(obh);
- bmodified(nbh);
brelse(nbh);
}
@@ -994,7 +993,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_LF;
mh.mh_format = GFS2_FORMAT_LF;
- gfs2_meta_header_out(&mh, nbh->b_data);
+ gfs2_meta_header_out(&mh, nbh);
}
leaf->lf_next = cpu_to_be64(bn);
@@ -1046,7 +1045,7 @@ static void dir_make_exhash(struct gfs2_inode *dip)
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_LF;
mh.mh_format = GFS2_FORMAT_LF;
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
}
leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1177,7 +1176,7 @@ init_dinode(struct gfs2_sbd *sdp, struct gfs2_inum *inum,
di.di_entries = 2;
}
- gfs2_dinode_out(&di, bh->b_data);
+ gfs2_dinode_out(&di, bh);
return bh;
}
@@ -1582,7 +1581,7 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
if (rgd) {
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
rgd->rg.rg_free++; /* adjust the free count */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); /* back to the buffer */
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); /* back to the buffer */
sdp->blks_alloced--;
}
}
@@ -1647,7 +1646,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
rgd = gfs2_blk2rgrpd(sdp, diblock);
rgd->rg.rg_free++;
rgd->rg.rg_dinodes--; /* one less inode in use */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
sdp->dinodes_alloced--;
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 0f59669..a06fe11 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -113,8 +113,7 @@ void gfs1_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;
- gfs2_meta_header_out(&mh, bh->b_data);
- bmodified(bh);
+ gfs2_meta_header_out(&mh, bh);
} else {
bh = bread(&sdp->buf_list, *dblock);
}
@@ -328,11 +327,11 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
/* ------------------------------------------------------------------------ */
/* gfs_dinode_in */
/* ------------------------------------------------------------------------ */
-static void gfs_dinode_in(struct gfs_dinode *di, char *buf)
+static void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh)
{
- struct gfs_dinode *str = (struct gfs_dinode *)buf;
+ struct gfs_dinode *str = (struct gfs_dinode *)bh->b_data;
- gfs2_meta_header_in(&di->di_header, buf);
+ gfs2_meta_header_in(&di->di_header, bh);
gfs2_inum_in(&di->di_num, (char *)&str->di_num);
di->di_mode = be32_to_cpu(str->di_mode);
@@ -363,8 +362,13 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
struct gfs_dinode gfs1_dinode;
struct gfs2_inode *ip;
- zalloc(ip, sizeof(struct gfs2_inode));
- gfs_dinode_in(&gfs1_dinode, bh->b_data);
+ ip = calloc(1, sizeof(struct gfs2_inode));
+ if (ip == NULL) {
+ fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
+ exit(-1);
+ }
+
+ gfs_dinode_in(&gfs1_dinode, bh);
memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
sizeof(struct gfs2_meta_header));
memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num,
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index c158886..47faa60 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -23,7 +23,6 @@
#include <linux/gfs2_ondisk.h>
#include "osi_list.h"
#include "copyright.cf"
-#include "ondisk.h"
#ifndef TRUE
#define TRUE (1)
@@ -710,17 +709,71 @@ 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);
-const char *str_uuid(const unsigned char *uuid);
-void gfs2_print_uuid(const unsigned char *uuid);
-
-extern void print_it(const char *label, const char *fmt,
- const char *fmt2, ...);
-#define pv(struct, member, fmt, fmt2) do { \
- print_it(" "#member, fmt, fmt2, struct->member); \
- } while (FALSE);
-#define pv2(struct, member, fmt, fmt2) do { \
- print_it(" ", fmt, fmt2, struct->member); \
- } while (FALSE);
+extern uint32_t gfs2_disk_hash(const char *data, int len);
+extern const char *str_uuid(const unsigned char *uuid);
+extern void gfs2_print_uuid(const unsigned char *uuid);
+extern void print_it(const char *label, const char *fmt, const char *fmt2, ...)
+ __attribute__((format(printf,2,4)));
+
+/* Translation functions */
+
+extern void gfs2_inum_in(struct gfs2_inum *no, char *buf);
+extern void gfs2_inum_out(struct gfs2_inum *no, char *buf);
+extern void gfs2_meta_header_in(struct gfs2_meta_header *mh,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_meta_header_out(struct gfs2_meta_header *mh,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh);
+extern void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh);
+extern void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf);
+extern void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf);
+extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs2_quota_in(struct gfs2_quota *qu, char *buf);
+extern void gfs2_quota_out(struct gfs2_quota *qu, char *buf);
+extern void gfs2_dinode_in(struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_dinode_out(struct gfs2_dinode *di,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_dirent_in(struct gfs2_dirent *de, char *buf);
+extern void gfs2_dirent_out(struct gfs2_dirent *de, char *buf);
+extern void gfs2_leaf_in(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh);
+extern void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh);
+extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, char *buf);
+extern void gfs2_ea_header_out(struct gfs2_ea_header *ea, char *buf);
+extern void gfs2_log_header_in(struct gfs2_log_header *lh,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_log_header_out(struct gfs2_log_header *lh,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf);
+extern void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf);
+extern void gfs2_quota_change_in(struct gfs2_quota_change *qc,
+ struct gfs2_buffer_head *bh);
+extern void gfs2_quota_change_out(struct gfs2_quota_change *qc,
+ struct gfs2_buffer_head *bh);
+
+/* Printing functions */
+
+extern void gfs2_inum_print(struct gfs2_inum *no);
+extern void gfs2_meta_header_print(struct gfs2_meta_header *mh);
+extern void gfs2_sb_print(struct gfs2_sb *sb);
+extern void gfs2_rindex_print(struct gfs2_rindex *ri);
+extern void gfs2_rgrp_print(struct gfs2_rgrp *rg);
+extern void gfs2_quota_print(struct gfs2_quota *qu);
+extern void gfs2_dinode_print(struct gfs2_dinode *di);
+extern void gfs2_dirent_print(struct gfs2_dirent *de, char *name);
+extern void gfs2_leaf_print(struct gfs2_leaf *lf);
+extern void gfs2_ea_header_print(struct gfs2_ea_header *ea, char *name);
+extern void gfs2_log_header_print(struct gfs2_log_header *lh);
+extern void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld);
+extern void gfs2_inum_range_print(struct gfs2_inum_range *ir);
+extern void gfs2_statfs_change_print(struct gfs2_statfs_change *sc);
+extern void gfs2_quota_change_print(struct gfs2_quota_change *qc);
+
+__END_DECLS
#endif /* __LIBGFS2_DOT_H__ */
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index 896ec73..e41d380 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -23,6 +23,12 @@
#include "gfs2_disk_hash.h"
+#define pv(struct, member, fmt, fmt2) do { \
+ print_it(" "#member, fmt, fmt2, struct->member); \
+ } while (FALSE);
+#define pv2(struct, member, fmt, fmt2) do { \
+ print_it(" ", fmt, fmt2, struct->member); \
+ } while (FALSE);
#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));}
#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));}
@@ -36,11 +42,11 @@
/*
* gfs2_xxx_in - read in an xxx struct
* first arg: the cpu-order structure
- * buf: the disk-order buffer
+ * bh: the disk-order buffer_head
*
* gfs2_xxx_out - write out an xxx struct
* first arg: the cpu-order structure
- * buf: the disk-order buffer
+ * bh: the disk-order buffer_head
*
* gfs2_xxx_print - print out an xxx struct
* first arg: the cpu-order structure
@@ -68,24 +74,27 @@ void gfs2_inum_print(struct gfs2_inum *no)
pv(no, no_addr, "%llu", "0x%llx");
}
-void gfs2_meta_header_in(struct gfs2_meta_header *mh, char *buf)
+void gfs2_meta_header_in(struct gfs2_meta_header *mh,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_meta_header *str = (struct gfs2_meta_header *)buf;
+ struct gfs2_meta_header *str = (struct gfs2_meta_header *)bh->b_data;
CPIN_32(mh, str, mh_magic);
CPIN_32(mh, str, mh_type);
CPIN_32(mh, str, mh_format);
}
-void gfs2_meta_header_out(struct gfs2_meta_header *mh, char *buf)
+void gfs2_meta_header_out(struct gfs2_meta_header *mh,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_meta_header *str = (struct gfs2_meta_header *)buf;
+ struct gfs2_meta_header *str = (struct gfs2_meta_header *)bh->b_data;
CPOUT_32(mh, str, mh_magic);
CPOUT_32(mh, str, mh_type);
CPOUT_32(mh, str, mh_format);
str->__pad0 = 0;
str->__pad1 = 0;
+ bmodified(bh);
}
void gfs2_meta_header_print(struct gfs2_meta_header *mh)
@@ -95,11 +104,11 @@ void gfs2_meta_header_print(struct gfs2_meta_header *mh)
pv(mh, mh_format, "%u", "0x%x");
}
-void gfs2_sb_in(struct gfs2_sb *sb, char *buf)
+void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh)
{
- struct gfs2_sb *str = (struct gfs2_sb *)buf;
+ struct gfs2_sb *str = (struct gfs2_sb *)bh->b_data;
- gfs2_meta_header_in(&sb->sb_header, buf);
+ gfs2_meta_header_in(&sb->sb_header, bh);
CPIN_32(sb, str, sb_fs_format);
CPIN_32(sb, str, sb_multihost_format);
@@ -117,11 +126,11 @@ void gfs2_sb_in(struct gfs2_sb *sb, char *buf)
#endif
}
-void gfs2_sb_out(struct gfs2_sb *sb, char *buf)
+void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh)
{
- struct gfs2_sb *str = (struct gfs2_sb *)buf;
+ struct gfs2_sb *str = (struct gfs2_sb *)bh->b_data;
- gfs2_meta_header_out(&sb->sb_header, buf);
+ gfs2_meta_header_out(&sb->sb_header, bh);
CPOUT_32(sb, str, sb_fs_format);
CPOUT_32(sb, str, sb_multihost_format);
@@ -137,6 +146,7 @@ void gfs2_sb_out(struct gfs2_sb *sb, char *buf)
#ifdef GFS2_HAS_UUID
CPOUT_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
#endif
+ bmodified(bh);
}
const char *str_uuid(const unsigned char *uuid)
@@ -228,11 +238,11 @@ void gfs2_rindex_print(struct gfs2_rindex *ri)
pv(ri, ri_bitbytes, "%u", "0x%x");
}
-void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf)
+void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
{
- struct gfs2_rgrp *str = (struct gfs2_rgrp *)buf;
+ struct gfs2_rgrp *str = (struct gfs2_rgrp *)bh->b_data;
- gfs2_meta_header_in(&rg->rg_header, buf);
+ gfs2_meta_header_in(&rg->rg_header, bh);
CPIN_32(rg, str, rg_flags);
CPIN_32(rg, str, rg_free);
CPIN_32(rg, str, rg_dinodes);
@@ -240,16 +250,17 @@ void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf)
CPIN_08(rg, str, rg_reserved, 36);
}
-void gfs2_rgrp_out(struct gfs2_rgrp *rg, char *buf)
+void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
{
- struct gfs2_rgrp *str = (struct gfs2_rgrp *)buf;
+ struct gfs2_rgrp *str = (struct gfs2_rgrp *)bh->b_data;
- gfs2_meta_header_out(&rg->rg_header, buf);
+ gfs2_meta_header_out(&rg->rg_header, bh);
CPOUT_32(rg, str, rg_flags);
CPOUT_32(rg, str, rg_free);
CPOUT_32(rg, str, rg_dinodes);
CPOUT_08(rg, str, rg_reserved, 36);
+ bmodified(bh);
}
void gfs2_rgrp_print(struct gfs2_rgrp *rg)
@@ -267,7 +278,8 @@ void gfs2_quota_in(struct gfs2_quota *qu, char *buf)
CPIN_64(qu, str, qu_limit);
CPIN_64(qu, str, qu_warn);
CPIN_64(qu, str, qu_value);
- CPIN_08(qu, str, qu_reserved, sizeof(qu->qu_reserved));
+ CPIN_32(qu, str, qu_ll_next);
+ CPIN_08(qu, str, qu_reserved, 60);
}
void gfs2_quota_out(struct gfs2_quota *qu, char *buf)
@@ -277,7 +289,8 @@ void gfs2_quota_out(struct gfs2_quota *qu, char *buf)
CPOUT_64(qu, str, qu_limit);
CPOUT_64(qu, str, qu_warn);
CPOUT_64(qu, str, qu_value);
- memset(qu->qu_reserved, 0, sizeof(qu->qu_reserved));
+ CPOUT_32(qu, str, qu_ll_next);
+ CPOUT_08(qu, str, qu_reserved, 60);
}
void gfs2_quota_print(struct gfs2_quota *qu)
@@ -287,11 +300,11 @@ void gfs2_quota_print(struct gfs2_quota *qu)
pv(qu, qu_value, "%lld", "0x%llx");
}
-void gfs2_dinode_in(struct gfs2_dinode *di, char *buf)
+void gfs2_dinode_in(struct gfs2_dinode *di, struct gfs2_buffer_head *bh)
{
- struct gfs2_dinode *str = (struct gfs2_dinode *)buf;
+ struct gfs2_dinode *str = (struct gfs2_dinode *)bh->b_data;
- gfs2_meta_header_in(&di->di_header, buf);
+ gfs2_meta_header_in(&di->di_header, bh);
gfs2_inum_in(&di->di_num, (char *)&str->di_num);
CPIN_32(di, str, di_mode);
@@ -322,11 +335,11 @@ void gfs2_dinode_in(struct gfs2_dinode *di, char *buf)
CPIN_08(di, str, di_reserved, 32);
}
-void gfs2_dinode_out(struct gfs2_dinode *di, char *buf)
+void gfs2_dinode_out(struct gfs2_dinode *di, struct gfs2_buffer_head *bh)
{
- struct gfs2_dinode *str = (struct gfs2_dinode *)buf;
+ struct gfs2_dinode *str = (struct gfs2_dinode *)bh->b_data;
- gfs2_meta_header_out(&di->di_header, buf);
+ gfs2_meta_header_out(&di->di_header, bh);
gfs2_inum_out(&di->di_num, (char *)&str->di_num);
CPOUT_32(di, str, di_mode);
@@ -354,6 +367,7 @@ void gfs2_dinode_out(struct gfs2_dinode *di, char *buf)
CPOUT_64(di, str, di_eattr);
CPOUT_08(di, str, di_reserved, 32);
+ bmodified(bh);
}
void gfs2_dinode_print(struct gfs2_dinode *di)
@@ -424,11 +438,11 @@ void gfs2_dirent_print(struct gfs2_dirent *de, char *name)
print_it(" name", "%s", NULL, buf);
}
-void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf)
+void gfs2_leaf_in(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh)
{
- struct gfs2_leaf *str = (struct gfs2_leaf *)buf;
+ struct gfs2_leaf *str = (struct gfs2_leaf *)bh->b_data;
- gfs2_meta_header_in(&lf->lf_header, buf);
+ gfs2_meta_header_in(&lf->lf_header, bh);
CPIN_16(lf, str, lf_depth);
CPIN_16(lf, str, lf_entries);
CPIN_32(lf, str, lf_dirent_format);
@@ -437,17 +451,18 @@ void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf)
CPIN_08(lf, str, lf_reserved, 32);
}
-void gfs2_leaf_out(struct gfs2_leaf *lf, char *buf)
+void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh)
{
- struct gfs2_leaf *str = (struct gfs2_leaf *)buf;
+ struct gfs2_leaf *str = (struct gfs2_leaf *)bh->b_data;
- gfs2_meta_header_out(&lf->lf_header, buf);
+ gfs2_meta_header_out(&lf->lf_header, bh);
CPOUT_16(lf, str, lf_depth);
CPOUT_16(lf, str, lf_entries);
CPOUT_32(lf, str, lf_dirent_format);
CPOUT_64(lf, str, lf_next);
CPOUT_08(lf, str, lf_reserved, 32);
+ bmodified(bh);
}
void gfs2_leaf_print(struct gfs2_leaf *lf)
@@ -500,11 +515,12 @@ void gfs2_ea_header_print(struct gfs2_ea_header *ea, char *name)
print_it(" name", "%s", NULL, buf);
}
-void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf)
+void gfs2_log_header_in(struct gfs2_log_header *lh,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_log_header *str = (struct gfs2_log_header *)buf;
+ struct gfs2_log_header *str = (struct gfs2_log_header *)bh->b_data;
- gfs2_meta_header_in(&lh->lh_header, buf);
+ gfs2_meta_header_in(&lh->lh_header, bh);
CPIN_64(lh, str, lh_sequence);
CPIN_32(lh, str, lh_flags);
CPIN_32(lh, str, lh_tail);
@@ -512,16 +528,18 @@ void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf)
CPIN_32(lh, str, lh_hash);
}
-void gfs2_log_header_out(struct gfs2_log_header *lh, char *buf)
+void gfs2_log_header_out(struct gfs2_log_header *lh,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_log_header *str = (struct gfs2_log_header *)buf;
+ struct gfs2_log_header *str = (struct gfs2_log_header *)bh->b_data;
- gfs2_meta_header_out(&lh->lh_header, buf);
+ gfs2_meta_header_out(&lh->lh_header, bh);
CPOUT_64(lh, str, lh_sequence);
CPOUT_32(lh, str, lh_flags);
CPOUT_32(lh, str, lh_tail);
CPOUT_32(lh, str, lh_blkno);
CPOUT_32(lh, str, lh_hash);
+ bmodified(bh);
}
void gfs2_log_header_print(struct gfs2_log_header *lh)
@@ -534,11 +552,12 @@ void gfs2_log_header_print(struct gfs2_log_header *lh)
pv(lh, lh_hash, "0x%.8X", NULL);
}
-void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf)
+void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)buf;
+ struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)bh->b_data;
- gfs2_meta_header_in(&ld->ld_header, buf);
+ gfs2_meta_header_in(&ld->ld_header, bh);
CPIN_32(ld, str, ld_type);
CPIN_32(ld, str, ld_length);
CPIN_32(ld, str, ld_data1);
@@ -547,17 +566,19 @@ void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf)
CPIN_08(ld, str, ld_reserved, 32);
}
-void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, char *buf)
+void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)buf;
+ struct gfs2_log_descriptor *str = (struct gfs2_log_descriptor *)bh->b_data;
- gfs2_meta_header_out(&ld->ld_header, buf);
+ gfs2_meta_header_out(&ld->ld_header, bh);
CPOUT_32(ld, str, ld_type);
CPOUT_32(ld, str, ld_length);
CPOUT_32(ld, str, ld_data1);
CPOUT_32(ld, str, ld_data2);
CPOUT_08(ld, str, ld_reserved, 32);
+ bmodified(bh);
}
void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld)
@@ -569,28 +590,6 @@ void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld)
pv(ld, ld_data2, "%u", "0x%x");
}
-void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf)
-{
- struct gfs2_inum_range *str = (struct gfs2_inum_range *)buf;
-
- CPIN_64(ir, str, ir_start);
- CPIN_64(ir, str, ir_length);
-}
-
-void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf)
-{
- struct gfs2_inum_range *str = (struct gfs2_inum_range *)buf;
-
- CPOUT_64(ir, str, ir_start);
- CPOUT_64(ir, str, ir_length);
-}
-
-void gfs2_inum_range_print(struct gfs2_inum_range *ir)
-{
- pv(ir, ir_start, "%llu", "0x%llx");
- pv(ir, ir_length, "%llu", "0x%llx");
-}
-
void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf)
{
struct gfs2_statfs_change *str = (struct gfs2_statfs_change *)buf;
@@ -616,22 +615,25 @@ void gfs2_statfs_change_print(struct gfs2_statfs_change *sc)
pv(sc, sc_dinodes, "%lld", "0x%llx");
}
-void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf)
+void gfs2_quota_change_in(struct gfs2_quota_change *qc,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
+ struct gfs2_quota_change *str = (struct gfs2_quota_change *)bh->b_data;
CPIN_64(qc, str, qc_change);
CPIN_32(qc, str, qc_flags);
CPIN_32(qc, str, qc_id);
}
-void gfs2_quota_change_out(struct gfs2_quota_change *qc, char *buf)
+void gfs2_quota_change_out(struct gfs2_quota_change *qc,
+ struct gfs2_buffer_head *bh)
{
- struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
+ struct gfs2_quota_change *str = (struct gfs2_quota_change *)bh->b_data;
CPOUT_64(qc, str, qc_change);
CPOUT_32(qc, str, qc_flags);
CPOUT_32(qc, str, qc_id);
+ bmodified(bh);
}
void gfs2_quota_change_print(struct gfs2_quota_change *qc)
diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c
index f0f119d..f6b609d 100644
--- a/gfs2/libgfs2/recovery.c
+++ b/gfs2/libgfs2/recovery.c
@@ -75,7 +75,7 @@ int get_log_header(struct gfs2_inode *ip, unsigned int blk,
tmp->lh_hash = 0;
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);
+ gfs2_log_header_in(&lh, bh);
brelse(bh);
if (error || lh.lh_blkno != blk || lh.lh_hash != hash)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index c0f9e10..092df6b 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -152,7 +152,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
}
}
- gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data);
+ gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
return 0;
}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 89d0e12..5e4a8c3 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -76,8 +76,7 @@ build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid));
#endif
bh = bget(&sdp->buf_list, sdp->sb_addr);
- gfs2_sb_out(&sb, bh->b_data);
- bmodified(bh);
+ gfs2_sb_out(&sb, bh);
brelse(bh);
if (sdp->debug) {
@@ -120,11 +119,10 @@ void write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
lh.lh_sequence = seq;
lh.lh_blkno = x;
- gfs2_log_header_out(&lh, bh->b_data);
+ gfs2_log_header_out(&lh, bh);
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);
- bmodified(bh);
brelse(bh);
if (++seq == blocks)
@@ -233,9 +231,8 @@ build_quota_change(struct gfs2_inode *per_node, unsigned int j)
if (!bh)
die("build_quota_change\n");
- gfs2_meta_header_out(&mh, bh->b_data);
+ gfs2_meta_header_out(&mh, bh);
- bmodified(bh);
brelse(bh);
}
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index debe0f6..5d05f75 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -72,7 +72,7 @@ int read_sb(struct gfs2_sbd *sdp)
int error;
bh = bread(&sdp->buf_list, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
- gfs2_sb_in(&sdp->sd_sb, bh->b_data);
+ gfs2_sb_in(&sdp->sd_sb, bh);
brelse(bh);
error = check_sb(&sdp->sd_sb);
@@ -270,8 +270,7 @@ int write_sb(struct gfs2_sbd *sbp)
struct gfs2_buffer_head *bh;
bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
- gfs2_sb_out(&sbp->sd_sb, bh->b_data);
- bmodified(bh);
+ gfs2_sb_out(&sbp->sd_sb, bh);
brelse(bh);
bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
return 0;
diff --git a/gfs2/mkfs/Makefile b/gfs2/mkfs/Makefile
index 6b1d8cd..4b894ec 100644
--- a/gfs2/mkfs/Makefile
+++ b/gfs2/mkfs/Makefile
@@ -19,7 +19,7 @@ CFLAGS=-Wall -O2 -ggdb -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
-D_GNU_SOURCE -DGFS2_RELEASE_NAME=\"2\" ${INCLUDEPATH}
LDFLAGS=-L${top_srcdir}/libgfs2 -L${libdir}
-H=gfs2_disk_hash.h gfs2_mkfs.h linux_endian.h ondisk.h osi_list.h
+H=gfs2_disk_hash.h gfs2_mkfs.h linux_endian.h osi_list.h
C=main.c main_mkfs.c main_jadd.c main_grow.c
O=$(subst .c,.o,${C})
diff --git a/gfs2/mkfs/gfs2_mkfs.h b/gfs2/mkfs/gfs2_mkfs.h
index 627c018..34457f2 100644
--- a/gfs2/mkfs/gfs2_mkfs.h
+++ b/gfs2/mkfs/gfs2_mkfs.h
@@ -18,7 +18,6 @@
#include <linux/gfs2_ondisk.h>
#include "osi_list.h"
#include "copyright.cf"
-#include "ondisk.h"
#define SRANDOM do { srandom(time(NULL) ^ getpid()); } while (0)
#define RESRANDOM do { srandom(RANDOM(1000000000)); } while (0)
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index ce47ebd..c0945d1 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -296,7 +296,9 @@ add_qc(struct gfs2_sbd *sdp)
sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift);
unsigned int x;
struct gfs2_meta_header mh;
+ struct gfs2_buffer_head dummy_bh;
+ dummy_bh.b_data = buf;
make_jdata(fd, "clear");
memset(buf, 0, sdp->bsize);
@@ -310,7 +312,7 @@ add_qc(struct gfs2_sbd *sdp)
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_QC;
mh.mh_format = GFS2_FORMAT_QC;
- gfs2_meta_header_out(&mh, buf);
+ gfs2_meta_header_out(&mh, &dummy_bh);
for (x=0; x<blocks; x++) {
do_write(fd, buf, sdp->bsize);
@@ -438,10 +440,12 @@ add_j(struct gfs2_sbd *sdp)
for (x=0; x<blocks; x++) {
uint32_t hash;
+ struct gfs2_buffer_head dummy_bh;
+ dummy_bh.b_data = buf;
lh.lh_sequence = seq;
lh.lh_blkno = x;
- gfs2_log_header_out(&lh, buf);
+ gfs2_log_header_out(&lh, &dummy_bh);
hash = gfs2_disk_hash(buf, sizeof(struct gfs2_log_header));
((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash);
diff --git a/gfs2/quota/main.c b/gfs2/quota/main.c
index 0136d18..7cd1b7d 100644
--- a/gfs2/quota/main.c
+++ b/gfs2/quota/main.c
@@ -291,16 +291,27 @@ read_superblock(struct gfs2_sb *sb, struct gfs2_sbd *sdp)
{
int fd;
char buf[PATH_MAX];
-
+ struct gfs2_buffer_head dummy_bh;
+
+ dummy_bh.b_data = buf;
fd = open(sdp->device_name, O_RDONLY);
if (fd < 0) {
die("Could not open the block device %s: %s\n",
sdp->device_name, strerror(errno));
}
- do_lseek(fd, 0x10 * 4096);
- do_read(fd, buf, PATH_MAX);
- gfs2_sb_in(sb, buf);
+ if (lseek(fd, 0x10 * 4096, SEEK_SET) != 0x10 * 4096) {
+ fprintf(stderr, "bad seek: %s from %s:%d: "
+ "superblock\n",
+ strerror(errno), __FUNCTION__, __LINE__);
+ exit(-1);
+ }
+ if (read(fd, buf, PATH_MAX) != PATH_MAX) {
+ fprintf(stderr, "bad read: %s from %s:%d: superblock\n",
+ strerror(errno), __FUNCTION__, __LINE__);
+ exit(-1);
+ }
+ gfs2_sb_in(sb, &dummy_bh);
close(fd);
}
diff --git a/gfs2/tool/sb.c b/gfs2/tool/sb.c
index 44f4443..83b24a9 100644
--- a/gfs2/tool/sb.c
+++ b/gfs2/tool/sb.c
@@ -84,7 +84,9 @@ do_sb(int argc, char **argv)
int fd;
unsigned char buf[GFS2_BASIC_BLOCK], input[256];
struct gfs2_sb sb;
+ struct gfs2_buffer_head dummy_bh;
+ dummy_bh.b_data = (char *)buf;
if (optind == argc)
die("Usage: gfs2_tool sb <device> <field> [newval]\n");
@@ -121,7 +123,7 @@ do_sb(int argc, char **argv)
do_lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK);
do_read(fd, buf, GFS2_BASIC_BLOCK);
- gfs2_sb_in(&sb, (char*) buf);
+ gfs2_sb_in(&sb, &dummy_bh);
if (sb.sb_header.mh_magic != GFS2_MAGIC ||
sb.sb_header.mh_type != GFS2_METATYPE_SB)
@@ -205,7 +207,7 @@ do_sb(int argc, char **argv)
die( _("unknown field %s\n"), field);
if (newval) {
- gfs2_sb_out(&sb,(char*) buf);
+ gfs2_sb_out(&sb, &dummy_bh);
do_lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK);
do_write(fd, buf, GFS2_BASIC_BLOCK);
14 years, 1 month
cluster: RHEL56 - Attach buffers to rgrp_list structs
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 8bc98f2fad5ecf63e42bd44e93f5b5349c7f1253
Parent: 965554a2d3d18d877bb4ce3f1cf369775b882e7a
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Dec 4 10:40:54 2009 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 9 23:10:00 2010 -0500
Attach buffers to rgrp_list structs
This patch attaches a buffer_head to every rgrp_list in memory.
This greatly improves performance because it no longer needs to
get and put the buffers for the rgrps all the time. Since the
buffers are linked to the rgrp list, they no longer need to be
linked to each other, so it helps untangle the buffer_head mess.
rhbz#455300
---
gfs2/convert/gfs2_convert.c | 99 ++++++++++++++-----------------------------
gfs2/edit/hexedit.c | 16 ++++---
gfs2/edit/savemeta.c | 19 +-------
gfs2/fsck/initialize.c | 12 +-----
gfs2/fsck/main.c | 13 ++++-
gfs2/fsck/pass1.c | 32 +-------------
gfs2/fsck/pass5.c | 43 +++++-------------
gfs2/fsck/rgrepair.c | 65 ++++++++++-------------------
gfs2/libgfs2/fs_bits.c | 61 ++++----------------------
gfs2/libgfs2/fs_geometry.c | 1 -
gfs2/libgfs2/fs_ops.c | 81 ++++++++++-------------------------
gfs2/libgfs2/gfs1.c | 33 ++++----------
gfs2/libgfs2/libgfs2.h | 20 ++++-----
gfs2/libgfs2/rgrp.c | 57 +++++++++++++++++--------
gfs2/libgfs2/structures.c | 13 ++----
gfs2/libgfs2/super.c | 31 +++-----------
16 files changed, 191 insertions(+), 405 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index f27b25f..e701169 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -166,29 +166,24 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
/* Fixes all unallocated metadata bitmap states (which are */
/* valid in gfs1 but invalid in gfs2). */
/* ------------------------------------------------------------------------- */
-static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
- struct gfs2_buffer_head **rgbh)
+static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
{
uint32_t blk;
int x, y;
struct gfs2_rindex *ri;
unsigned char state;
- ri = &rgd2->ri;
- if (gfs2_compute_bitstructs(sdp, rgd2)) {
- log_crit("gfs2_convert: Error converting bitmaps.\n");
- exit(-1);
- }
+ ri = &rg->ri;
for (blk = 0; blk < ri->ri_length; blk++) {
x = (blk) ? sizeof(struct gfs2_meta_header) :
sizeof(struct gfs2_rgrp);
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (rgbh[blk]->b_data[x] >>
+ state = (rg->bh[blk]->b_data[x] >>
(GFS2_BIT_SIZE * y)) & 0x03;
if (state == 0x02) /* unallocated metadata state invalid */
- rgbh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+ rg->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
}
}
}/* convert_bitmaps */
@@ -200,49 +195,34 @@ 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 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);
- 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 */
+ rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */
/* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */
/* convert from be to cpu. We must do it now. */
- rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
- rgd->rg_free = rg.rg_free;
+ rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
/* 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 - rg.rg_free);
+ sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free);
sbp->dinodes_alloced += rgd1->rg_useddi;
- convert_bitmaps(sbp, rgd, rgbh);
+ convert_bitmaps(sbp, rgd);
/* Write the updated rgrp to the gfs2 buffer */
- gfs2_rgrp_out(&rg, rgbh[0]->b_data);
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
rgs++;
if (rgs % 100 == 0) {
printf(".");
fflush(stdout);
}
- free(rgbh);
}
return 0;
}/* superblock_cvt */
@@ -991,8 +971,6 @@ 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 */
@@ -1006,20 +984,6 @@ 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(!(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 */
gettimeofday(&tv, NULL);
/* Put out a warm, fuzzy message every second so the customer */
@@ -1062,21 +1026,19 @@ 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) {
- rgbh[blk]->b_data[buf_offset + bitmap_byte] &=
+ rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &=
~(0x03 << (GFS2_BIT_SIZE * byte_bit));
- rgbh[blk]->b_data[buf_offset + bitmap_byte] |=
+ rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
(0x01 << (GFS2_BIT_SIZE * byte_bit));
break;
}
bitmap_byte -= (sbp->bsize - buf_offset);
- bmodified(bh);
+ bmodified(rgd->bh[blk]);
}
}
brelse(bh);
first = 0;
} /* while 1 */
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
} /* for all rgs */
log_notice("\r%" PRIu64" inodes from %d rgs converted.",
sbp->md.next_inum, rgs_processed);
@@ -1622,8 +1584,6 @@ 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;
@@ -1663,11 +1623,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);
- 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->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;
rgd->ri.ri_addr = jndx->ji_addr; /* new rg addr becomes ji addr */
rgd->ri.ri_length = rgrp_length(size, sdp); /* aka bitblocks */
@@ -1678,31 +1638,36 @@ 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 */
- rg.rg_free = rgd->ri.ri_data;
+ rgd->rg.rg_free = rgd->ri.ri_data;
rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
- if(!(rgbh = (struct gfs2_buffer_head **)
+ if(!(rgd->bh = (struct gfs2_buffer_head **)
malloc(rgd->ri.ri_length *
sizeof(struct gfs2_buffer_head *))))
return -1;
- if(!memset(rgbh, 0, rgd->ri.ri_length *
+ if(!memset(rgd->bh, 0, rgd->ri.ri_length *
sizeof(struct gfs2_buffer_head *))) {
- free(rgbh);
+ free(rgd->bh);
return -1;
}
-
- convert_bitmaps(sdp, rgd, rgbh);
for (x = 0; x < rgd->ri.ri_length; x++) {
- rgbh[x]->b_count++;
+ rgd->bh[x] = bget(&sdp->buf_list, rgd->ri.ri_addr + x);
+ memset(rgd->bh[x]->b_data, 0, sdp->bsize);
+ }
+ if (gfs2_compute_bitstructs(sdp, rgd)) {
+ log_crit("gfs2_convert: Error converting bitmaps.\n");
+ exit(-1);
+ }
+ convert_bitmaps(sdp, rgd);
+ for (x = 0; x < rgd->ri.ri_length; x++) {
if (x)
- gfs2_meta_header_out(&mh, rgbh[x]->b_data);
+ gfs2_meta_header_out(&mh, rgd->bh[x]->b_data);
else
- gfs2_rgrp_out(&rg, rgbh[x]->b_data);
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[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 */
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index ef0bc50..a0b9b81 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -580,9 +580,11 @@ int display_block_type(const char *lpBuffer, int from_restore)
struct rgrp_list *rgd;
rgd = gfs2_blk2rgrpd(&sbd, block);
- if (rgd)
+ if (rgd) {
+ gfs2_rgrp_read(&sbd, rgd);
type = gfs2_get_bitmap(&sbd, block, rgd);
- else
+ gfs2_rgrp_relse(rgd);
+ } else
type = 4;
screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
if (!screen_chunk_size)
@@ -1707,7 +1709,7 @@ static int display_extended(void)
/* ------------------------------------------------------------------------ */
static void read_superblock(int fd)
{
- int count, bitmap_blocks = 0;
+ int count;
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
ioctl(fd, BLKFLSBUF, 0);
@@ -1759,8 +1761,7 @@ 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_rindex_read(&sbd, fd, &count, &bitmap_blocks);
- /*gfs1_ri_update(&sbd, 0, &count, 1);*/
+ gfs1_rindex_read(&sbd, 0, &count);
} else {
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
@@ -1770,8 +1771,7 @@ 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;
- rindex_read(&sbd, fd, &count, &bitmap_blocks);
- /*ri_update(&sbd, 0, &count);*/
+ rindex_read(&sbd, 0, &count);
}
}
@@ -2528,7 +2528,9 @@ static void find_change_block_alloc(int *newval)
} else {
rgd = gfs2_blk2rgrpd(&sbd, ablock);
if (rgd) {
+ gfs2_rgrp_read(&sbd, rgd);
type = gfs2_get_bitmap(&sbd, ablock, rgd);
+ gfs2_rgrp_relse(rgd);
printf("%d (%s)\n", type, allocdesc[gfs1][type]);
} else {
gfs2_rgrp_free(&sbd.rglist);
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 51ea37a..3a34c96 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -497,8 +497,6 @@ 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;
@@ -622,16 +620,7 @@ void savemeta(char *out_fn, int saveoption)
int i, first;
rgd = osi_list_entry(tmp, struct rgrp_list, list);
- 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);
+ slow = gfs2_rgrp_read(&sbd, rgd);
if (slow)
continue;
log_debug("RG at %"PRIu64" is %u long\n",
@@ -653,8 +642,7 @@ void savemeta(char *out_fn, int saveoption)
if (saveoption != 2) {
int blktype;
- while (!gfs2_next_rg_meta(&sbd, rgd, &block,
- first)) {
+ while (!gfs2_next_rg_meta(rgd, &block, first)){
warm_fuzzy_stuff(block, FALSE, TRUE);
blktype = save_block(sbd.device_fd,
out_fd, block);
@@ -672,8 +660,7 @@ void savemeta(char *out_fn, int saveoption)
first = 0;
}
}
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
+ gfs2_rgrp_relse(rgd);
}
}
if (slow) {
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 5985919..d82313b 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -87,17 +87,7 @@ static void empty_super_block(struct gfs2_sbd *sdp)
uint32_t i;
log_info( _("Freeing buffers.\n"));
- while(!osi_list_empty(&sdp->rglist)){
- struct rgrp_list *rgd;
-
- rgd = osi_list_entry(sdp->rglist.next, struct rgrp_list, list);
- log_debug( _("Deleting rgd for 0x%llx: rgd=0x%p bits=0x%p\n"),
- (unsigned long long)rgd->ri.ri_addr, rgd, rgd->bits);
- osi_list_del(&rgd->list);
- if(rgd->bits)
- free(rgd->bits);
- free(rgd);
- }
+ gfs2_rgrp_free(&sdp->rglist);
for(i = 0; i < FSCK_HASH_SIZE; i++) {
while(!osi_list_empty(&inode_hash[i])) {
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 841d351..953c2dc 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -307,11 +307,11 @@ void check_statfs(struct gfs2_sbd *sdp)
log_err( _("Error: can't allocate memory to check statfs.\n"));
return;
}
- gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+ gfs2_rgrp_read(sdp, rgd);
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, rgbh);
+ gfs2_rgrp_relse(rgd);
free(rgbh);
}
@@ -341,7 +341,7 @@ void check_statfs(struct gfs2_sbd *sdp)
sdp->dinodes_alloced, sdp->dinodes_alloced);
errors_found++;
- if (!query(&opts, _("Okay to fix the master statfs file? (y/n)"))) {
+ if (!query( _("Okay to fix the master statfs file? (y/n)"))) {
log_err( _("The statfs file was not fixed.\n"));
return;
}
@@ -358,6 +358,8 @@ int main(int argc, char **argv)
int j;
int error = 0;
int all_clean = 0;
+ osi_list_t *tmp;
+ struct rgrp_list *rgd;
setlocale(LC_ALL, "");
textdomain("gfs2-utils");
@@ -494,6 +496,11 @@ int main(int argc, char **argv)
if (!opts.no && errors_corrected)
log_notice( _("Writing changes to disk\n"));
+ for (tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next) {
+ rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ gfs2_rgrp_relse(rgd);
+ }
+
bsync(&sbp->buf_list);
destroy(sbp);
log_notice( _("gfs2_fsck complete \n"));
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f61164c..bbf2e83 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -967,8 +967,6 @@ 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,
@@ -991,29 +989,10 @@ 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(!(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"),
- (unsigned long long)rgd->ri.ri_addr,
- (unsigned long long)rgd->ri.ri_addr,
- rgd->ri.ri_length);
for (i = 0; i < rgd->ri.ri_length; i++) {
if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
gfs2_meta_other)){
stack;
- free(rgbh);
return FSCK_ERROR;
}
}
@@ -1024,14 +1003,11 @@ int pass1(struct gfs2_sbd *sbp)
while (1) {
/* "block" is relative to the entire file system */
- if (gfs2_next_rg_meta(sbp, rgd, &block, first))
+ if (gfs2_next_rg_meta(rgd, &block, first))
break;
warm_fuzzy_stuff(block);
- if (fsck_abort) { /* if asked to abort */
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
+ if (fsck_abort) /* if asked to abort */
return FSCK_OK;
- }
if (skip_this_pass) {
printf( _("Skipping pass 1 is not a good idea.\n"));
skip_this_pass = FALSE;
@@ -1042,15 +1018,11 @@ int pass1(struct gfs2_sbd *sbp)
if (scan_meta(sbp, bh, block)) {
stack;
brelse(bh);
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
return FSCK_ERROR;
}
brelse(bh);
first = 0;
}
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
}
return FSCK_OK;
}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index f36eb7d..dae2c66 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -158,8 +158,7 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
}
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 *count)
{
uint32_t i;
struct gfs2_bitmap *bits;
@@ -170,26 +169,26 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
bits = &rgp->bits[i];
/* update the bitmaps */
- check_block_status(sbp, rgbh[i]->b_data + bits->bi_offset,
+ check_block_status(sbp, rgp->bh[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;
}
/* actually adjust counters and write out to disk */
- if(rgp->rg_free != count[0]) {
+ if(rgp->rg.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_free, count[0]);
- rgp->rg_free = count[0];
+ rgp->rg.rg_free, count[0]);
+ rgp->rg.rg_free = count[0];
update = 1;
}
- if(rg->rg_dinodes != count[1]) {
+ if(rgp->rg.rg_dinodes != count[1]) {
log_err( _("Inode count inconsistent: is %u should be %u\n"),
- rg->rg_dinodes, count[1]);
- rg->rg_dinodes = count[1];
+ rgp->rg.rg_dinodes, count[1]);
+ rgp->rg.rg_dinodes = count[1];
update = 1;
}
if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
@@ -203,7 +202,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
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);
+ gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
} else
log_err( _("Resource group counts left inconsistent\n"));
}
@@ -218,11 +217,9 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
int pass5(struct gfs2_sbd *sbp)
{
osi_list_t *tmp;
- struct rgrp_list *rgd = NULL;
+ struct rgrp_list *rgp = 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){
@@ -230,27 +227,11 @@ int pass5(struct gfs2_sbd *sbp)
return FSCK_OK;
log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
memset(count, 0, sizeof(count));
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
+ rgp = osi_list_entry(tmp, struct rgrp_list, list);
- 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 */
- update_rgrp(sbp, rgd, count, rgbh, &rg);
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
+ update_rgrp(sbp, rgp, count);
}
/* 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 06603b1..65080a2 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -378,36 +378,35 @@ 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 *rgd,
- uint64_t errblock, struct gfs2_buffer_head **rgbh,
- struct gfs2_rgrp *rg)
+static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
+ uint64_t errblock)
{
- int x = errblock - rgd->ri.ri_addr;
+ int x = errblock - rg->ri.ri_addr;
log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither"
" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
- rgbh[x]->b_blocknr, rgbh[x]->b_blocknr,
- (int)x+1, (int)rgd->ri.ri_length);
- if (query( _("Fix the RG? (y/n)"))) {
+ rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
+ (int)x+1, (int)rg->ri.ri_length);
+ if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the RG.\n"));
- rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ rg->bh[x] = bread(&sdp->buf_list, rg->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, rgbh[x]->b_data);
+ gfs2_meta_header_out(&mh, rg->bh[x]->b_data);
} else {
- 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);
+ 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);
}
- bmodified(rgbh[x]);
- brelse(rgbh[x]);
+ bmodified(rg->bh[x]);
+ brelse(rg->bh[x]);
return 0;
}
return 1;
@@ -428,7 +427,6 @@ 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;
@@ -453,7 +451,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
}
/* Read in the rindex */
osi_list_init(&sdp->rglist); /* Just to be safe */
- rindex_read(sdp, 0, &rgcount_from_index, &bitmap_blocks);
+ rindex_read(sdp, 0, &rgcount_from_index);
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);
@@ -555,41 +553,22 @@ 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);
-
- 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);
+ errblock = gfs2_rgrp_read(sdp, rgd);
if (errblock) {
- if (errblock == prev_err) {
- free(rgbh);
+ if (errblock == prev_err)
break;
- }
prev_err = errblock;
- rewrite_rg_block(sdp, rgd, errblock, rgbh,
- &rgrp);
- }
- else {
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
+ rewrite_rg_block(sdp, rgd, errblock);
+ } else {
+ gfs2_rgrp_relse(rgd);
break;
}
- free(rgbh);
i++;
} while (i < rgd->ri.ri_length);
}
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 73499c8..9dc34c8 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -172,8 +172,6 @@ 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))
@@ -184,20 +182,6 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
if(!rgd)
return -1;
- 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]);
@@ -205,7 +189,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
break;
}
- byte = (unsigned char *)(rgbh[buf]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
@@ -213,9 +197,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
*byte ^= cur_state << bit;
*byte |= state << bit;
- bmodified(rgbh[buf]);
- gfs2_rgrp_relse(rgd, rgbh);
- free(rgbh);
+ bmodified(rgd->bh[buf]);
return 0;
}
@@ -242,51 +224,28 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
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;
- if(rgd == NULL) {
- local_rgd = 1;
+ if (rgd == NULL) {
rgd = gfs2_blk2rgrpd(sdp, blkno);
- }
- if(rgd == NULL)
- return -1;
- 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(rgd == NULL)
+ return -1;
}
- if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg))
- return -1;
-
rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
- for(i= 0; i < rgd->ri.ri_length; i++){
+ for (i = 0; i < rgd->ri.ri_length; i++) {
bits = &(rgd->bits[i]);
- if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){
+ if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY))
break;
- }
}
- if(i >= rgd->ri.ri_length){
- gfs2_rgrp_relse(rgd, rgbh);
+ if (i >= rgd->ri.ri_length)
return -1;
- }
-
- byte = (unsigned char *)(rgbh[i]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(rgd->bh[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, rgbh);
+
return val;
}
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 0c8c169..aa62edf 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -219,7 +219,6 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
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++) {
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 63c190c..48ad90d 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -55,17 +55,16 @@ 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_buffer_head **rgbh;
+ struct gfs2_rgrp *rg;
unsigned int block, bn = 0, x = 0, y = 0;
unsigned int state;
+ struct gfs2_buffer_head *bh;
memset(&rg, 0, sizeof(rg));
- for (head = &sdp->rglist, tmp = head->next;
- tmp != head;
+ for (head = &sdp->rglist, tmp = head->next; tmp != head;
tmp = tmp->next) {
rl = osi_list_entry(tmp, struct rgrp_list, list);
- if (rl->rg_free)
+ if (rl->rg.rg_free)
break;
}
@@ -73,43 +72,29 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
die("out of space\n");
ri = &rl->ri;
-
- 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;
- }
+ rg = &rl->rg;
for (block = 0; block < ri->ri_length; block++) {
- rgbh[block] = bread(&sdp->buf_list, ri->ri_addr + block);
+ bh = rl->bh[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 = (rgbh[block]->b_data[x] >>
- (GFS2_BIT_SIZE * y)) & 0x03;
+ state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
if (state == GFS2_BLKST_FREE)
goto found;
bn++;
}
-
- brelse(rgbh[block]);
}
die("allocation is broken (1): %"PRIu64" %u\n",
- (uint64_t)rl->ri.ri_addr, rl->rg_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg.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_free);
+ (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
switch (type) {
case DATA:
@@ -118,27 +103,20 @@ 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");
}
- 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--;
-
- bmodified(rgbh[block]);
- brelse(rgbh[block]);
+ bh->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
+ bh->b_data[x] |= state << (GFS2_BIT_SIZE * y);
+ rg->rg_free--;
- rgbh[0] = bread(&sdp->buf_list, ri->ri_addr);
- gfs2_rgrp_out(&rg, rgbh[0]->b_data);
- bmodified(rgbh[0]);
- brelse(rgbh[0]);
+ bmodified(bh);
+ gfs2_rgrp_out(rg, rl->bh[0]->b_data);
sdp->blks_alloced++;
- free(rgbh);
return ri->ri_data0 + bn;
}
@@ -1597,21 +1575,16 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
*/
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->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 */
- bmodified(bh);
- brelse(bh); /* release the buffer */
- sdp->blks_alloced--;
+ if (rgd) {
+ gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
+ rgd->rg.rg_free++; /* adjust the free count */
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data); /* back to the buffer */
+ sdp->blks_alloced--;
+ }
}
/**
@@ -1628,7 +1601,6 @@ 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]);
@@ -1673,14 +1645,9 @@ 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);
- 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);
- bmodified(bh);
- brelse(bh); /* release the buffer */
+ rgd->rg.rg_free++;
+ rgd->rg.rg_dinodes--; /* one less inode in use */
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
sdp->dinodes_alloced--;
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 428ba70..0f59669 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -229,8 +229,7 @@ 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 *bitmap_blocks)
+int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
{
unsigned int rg;
int error;
@@ -240,7 +239,6 @@ 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));
@@ -263,8 +261,6 @@ 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;
@@ -295,48 +291,37 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
{
struct rgrp_list *rgd;
+ struct gfs2_rindex *ri;
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;
+ uint64_t rmax = 0;
- if (gfs1_rindex_read(sdp, fd, &count1, &bitmap_blocks))
+ if (gfs1_rindex_read(sdp, fd, &count1))
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, rgbh, &rg);
- if (errblock) {
- free(rgbh);
+ errblock = gfs2_rgrp_read(sdp, rgd);
+ if (errblock)
return errblock;
- }
count2++;
if (!quiet && count2 % 100 == 0) {
printf(".");
fflush(stdout);
}
+ ri = &rgd->ri;
+ if (ri->ri_data0 + ri->ri_data - 1 > rmax)
+ rmax = ri->ri_data0 + ri->ri_data - 1;
}
*rgcount = count1;
if (count1 != count2)
goto fail;
- free(rgbh);
return 0;
fail:
gfs2_rgrp_free(&sdp->rglist);
- free(rgbh);
return -1;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 16bd1db..c158886 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -103,10 +103,11 @@ 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 rg_free; /* Free blocks */
struct gfs2_rindex ri;
+ struct gfs2_rgrp rg;
struct gfs2_bitmap *bits;
+ struct gfs2_buffer_head **bh;
};
struct gfs2_buffer_head {
@@ -554,8 +555,7 @@ 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_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
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);
@@ -680,11 +680,8 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
/* rgrp.c */
extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
- struct gfs2_buffer_head **bh,
- struct gfs2_rgrp *rg);
-extern void gfs2_rgrp_relse(struct rgrp_list *rgd,
- struct gfs2_buffer_head **bh);
+extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
+extern void gfs2_rgrp_relse(struct rgrp_list *rgd);
extern void gfs2_rgrp_free(osi_list_t *rglist);
/* structures.c */
@@ -700,16 +697,15 @@ 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_meta(struct rgrp_list *rgd, uint64_t *block,
+ int first);
extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
uint64_t *block, uint32_t type, int first);
/* super.c */
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
extern int ji_update(struct gfs2_sbd *sdp);
-extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
- int *bitmap_blocks);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index f4da1a0..c0f9e10 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -85,6 +85,14 @@ 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;
}
@@ -99,56 +107,63 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
{
osi_list_t *tmp;
- struct rgrp_list *rgd = NULL;
+ struct rgrp_list *rgd;
+ static struct rgrp_list *prev_rgd = NULL;
struct gfs2_rindex *ri;
- for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){
+ if (prev_rgd) {
+ ri = &prev_rgd->ri;
+ if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data)
+ return prev_rgd;
+ }
+
+ for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
ri = &rgd->ri;
- if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data){
- break;
- } else
- rgd = NULL;
+ if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) {
+ prev_rgd = rgd;
+ return rgd;
+ }
}
- return rgd;
+ return NULL;
}
/**
- * fs_rgrp_read - read in the resource group information from disk.
+ * gfs2_rgrp_read - read in the resource group information from disk.
* @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,
- struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg)
+uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
{
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++){
- bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
- if(gfs2_check_meta(bh[x],
+ rgd->bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+ if(gfs2_check_meta(rgd->bh[x],
(x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
uint64_t error;
error = rgd->ri.ri_addr + x;
for (; x >= 0; x--)
- brelse(bh[x]);
+ brelse(rgd->bh[x]);
return error;
}
}
- gfs2_rgrp_in(rg, bh[0]->b_data);
- rgd->rg_free = rg->rg_free;
+ gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data);
return 0;
}
-void gfs2_rgrp_relse(struct rgrp_list *rgd, struct gfs2_buffer_head **bh)
+void gfs2_rgrp_relse(struct rgrp_list *rgd)
{
int x, length = rgd->ri.ri_length;
- for (x = 0; x < length; x++)
- brelse(bh[x]);
+ for (x = 0; x < length; x++) {
+ brelse(rgd->bh[x]);
+ rgd->bh[x] = NULL;
+ }
}
void gfs2_rgrp_free(osi_list_t *rglist)
@@ -157,8 +172,14 @@ void gfs2_rgrp_free(osi_list_t *rglist)
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 */
+ gfs2_rgrp_relse(rgd); /* 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 b3e884d..89d0e12 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -488,14 +488,12 @@ 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 gfs2_sbd *sdp, struct rgrp_list *rgd,
- uint64_t *block, int first)
+int gfs2_next_rg_meta(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");
@@ -509,17 +507,14 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
}
for(; i < length; i++){
bits = &rgd->bits[i];
- bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
- blk = gfs2_bitfit((unsigned char *)bh->b_data +
+ blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->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);
break;
}
blk=0;
- brelse(bh);
}
if(i == length)
return -1;
@@ -536,14 +531,14 @@ int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
* Returns: 0 on success, -1 on error or finished
*/
int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
- uint64_t *block, uint32_t type, int first)
+ uint64_t *block, uint32_t type, int first)
{
struct gfs2_buffer_head *bh = NULL;
do{
if (bh)
brelse(bh);
- if (gfs2_next_rg_meta(sdp, rgd, block, first))
+ if (gfs2_next_rg_meta(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 32407bc..debe0f6 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 *bitmap_blocks)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
{
unsigned int rg;
int error;
@@ -185,7 +185,6 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
*count1 = 0;
prev_rgd = NULL;
- *bitmap_blocks = 0;
for (rg = 0; ; rg++) {
if (fd > 0)
error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -208,8 +207,6 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
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,33 +238,19 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
{
struct rgrp_list *rgd;
+ struct gfs2_rindex *ri;
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, &bitmap_blocks))
+ if (rindex_read(sdp, fd, &count1))
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, rgbh, &rg);
- if (errblock) {
- free(rgbh);
+ errblock = gfs2_rgrp_read(sdp, rgd);
+ if (errblock)
return errblock;
- } else
- gfs2_rgrp_relse(rgd, rgbh);
+ ri = &rgd->ri;
count2++;
}
@@ -275,12 +258,10 @@ 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);
- free(rgbh);
return -1;
}
14 years, 1 month