gfs2-utils: master - gfs2_edit: Use the metadata description in get_block_type
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=0d3b6ed1...
Commit: 0d3b6ed1eb4bb102f5f763596d0cb14a434559ae
Parent: 5d3e3f1ba4dace182696e07847240ec9b82974ab
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Feb 27 16:25:45 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Feb 27 20:27:34 2014 +0000
gfs2_edit: Use the metadata description in get_block_type
Replace the large switch statement in get_block_type() with calls to
lgfs2_get_block_type() and lgfs2_find_mtype().
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/hexedit.c | 68 +++++---------------------------------------------
1 files changed, 7 insertions(+), 61 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 0aa0771..ac91c83 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -578,69 +578,15 @@ static void print_usage(void)
/* ------------------------------------------------------------------------ */
uint32_t get_block_type(const struct gfs2_buffer_head *lbh, int *structlen)
{
- const struct gfs2_meta_header *mh = lbh->iov.iov_base;
- uint32_t ty;
+ uint32_t ty = lgfs2_get_block_type(lbh);
- if (!be32_to_cpu(mh->mh_magic) == GFS2_MAGIC)
- return 0;
-
- ty = be32_to_cpu(mh->mh_type);
- if (structlen == NULL)
- return ty;
- switch (ty) {
- case GFS2_METATYPE_SB: /* 1 */
- if (sbd.gfs1)
- *structlen = sizeof(struct gfs_sb);
- else
- *structlen = sizeof(struct gfs2_sb);
- break;
- case GFS2_METATYPE_RG: /* 2 */
- *structlen = sizeof(struct gfs2_rgrp);
- break;
- case GFS2_METATYPE_RB: /* 3 */
- *structlen = sizeof(struct gfs2_meta_header);
- break;
- case GFS2_METATYPE_DI: /* 4 */
- *structlen = sizeof(struct gfs2_dinode);
- break;
- case GFS2_METATYPE_IN: /* 5 */
- if (sbd.gfs1)
- *structlen = sizeof(struct gfs_indirect);
- else
- *structlen = sizeof(struct gfs2_meta_header);
- break;
- case GFS2_METATYPE_LF: /* 6 */
- *structlen = sizeof(struct gfs2_leaf);
- break;
- case GFS2_METATYPE_JD:
- *structlen = sizeof(struct gfs2_meta_header);
- break;
- case GFS2_METATYPE_LH:
- *structlen = sizeof(struct gfs2_log_header);
- break;
- case GFS2_METATYPE_LD:
- if (sbd.gfs1)
- *structlen = sizeof(struct gfs_log_descriptor);
+ if (ty != 0 && structlen != NULL) {
+ unsigned ver = sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2;
+ const struct lgfs2_metadata *mtype = lgfs2_find_mtype(ty, ver);
+ if (mtype != NULL)
+ *structlen = mtype->size;
else
- *structlen = sizeof(struct gfs2_log_descriptor);
- break;
- case GFS2_METATYPE_EA:
- *structlen = sizeof(struct gfs2_meta_header) +
- sizeof(struct gfs2_ea_header);
- break;
- case GFS2_METATYPE_ED:
- *structlen = sizeof(struct gfs2_meta_header) +
- sizeof(struct gfs2_ea_header);
- break;
- case GFS2_METATYPE_LB:
- *structlen = sizeof(struct gfs2_meta_header);
- break;
- case GFS2_METATYPE_QC:
- *structlen = sizeof(struct gfs2_quota_change);
- break;
- default:
- *structlen = sbd.bsize;
- break;
+ *structlen = sbd.bsize;
}
return ty;
}
10 years, 1 month
gfs2-utils: master - gfs2_edit: Add more intelligence to journal dumps
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=5d3e3f1b...
Commit: 5d3e3f1ba4dace182696e07847240ec9b82974ab
Parent: 478f093f301149c54db72a94ff7e9148ac00444e
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 27 09:25:12 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Feb 27 20:27:21 2014 +0000
gfs2_edit: Add more intelligence to journal dumps
This patch adds the ability for a gfs2_edit journal dump to look for
journal entries pertaining to a particular block. The syntax is:
gfs2_edit -p journal0 0x12345 /dev/my_vg/my_lv
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/edit/hexedit.c | 150 +++++++++++++------
gfs2/edit/hexedit.h | 6 +-
gfs2/edit/journal.c | 420 +++++++++++++++++++++++++++++++++++++++-----------
gfs2/edit/journal.h | 3 +-
gfs2/edit/savemeta.c | 2 +-
5 files changed, 442 insertions(+), 139 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 18d06c7..0aa0771 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -45,8 +45,6 @@ int details = 0;
long int gziplevel = 9;
static int termcols;
-int display(int identify_only);
-
/* for assigning numeric fields: */
#define checkassign(strfield, struct, member, value) do { \
if (strcmp(#member, strfield) == 0) { \
@@ -578,14 +576,73 @@ static void print_usage(void)
/* returns: metatype if block is a GFS2 structure block type */
/* 0 if block is not a GFS2 structure */
/* ------------------------------------------------------------------------ */
-uint32_t get_block_type(const struct gfs2_buffer_head *lbh)
+uint32_t get_block_type(const struct gfs2_buffer_head *lbh, int *structlen)
{
const struct gfs2_meta_header *mh = lbh->iov.iov_base;
+ uint32_t ty;
- if (be32_to_cpu(mh->mh_magic) == GFS2_MAGIC)
- return be32_to_cpu(mh->mh_type);
+ if (!be32_to_cpu(mh->mh_magic) == GFS2_MAGIC)
+ return 0;
- return 0;
+ ty = be32_to_cpu(mh->mh_type);
+ if (structlen == NULL)
+ return ty;
+ switch (ty) {
+ case GFS2_METATYPE_SB: /* 1 */
+ if (sbd.gfs1)
+ *structlen = sizeof(struct gfs_sb);
+ else
+ *structlen = sizeof(struct gfs2_sb);
+ break;
+ case GFS2_METATYPE_RG: /* 2 */
+ *structlen = sizeof(struct gfs2_rgrp);
+ break;
+ case GFS2_METATYPE_RB: /* 3 */
+ *structlen = sizeof(struct gfs2_meta_header);
+ break;
+ case GFS2_METATYPE_DI: /* 4 */
+ *structlen = sizeof(struct gfs2_dinode);
+ break;
+ case GFS2_METATYPE_IN: /* 5 */
+ if (sbd.gfs1)
+ *structlen = sizeof(struct gfs_indirect);
+ else
+ *structlen = sizeof(struct gfs2_meta_header);
+ break;
+ case GFS2_METATYPE_LF: /* 6 */
+ *structlen = sizeof(struct gfs2_leaf);
+ break;
+ case GFS2_METATYPE_JD:
+ *structlen = sizeof(struct gfs2_meta_header);
+ break;
+ case GFS2_METATYPE_LH:
+ *structlen = sizeof(struct gfs2_log_header);
+ break;
+ case GFS2_METATYPE_LD:
+ if (sbd.gfs1)
+ *structlen = sizeof(struct gfs_log_descriptor);
+ else
+ *structlen = sizeof(struct gfs2_log_descriptor);
+ break;
+ case GFS2_METATYPE_EA:
+ *structlen = sizeof(struct gfs2_meta_header) +
+ sizeof(struct gfs2_ea_header);
+ break;
+ case GFS2_METATYPE_ED:
+ *structlen = sizeof(struct gfs2_meta_header) +
+ sizeof(struct gfs2_ea_header);
+ break;
+ case GFS2_METATYPE_LB:
+ *structlen = sizeof(struct gfs2_meta_header);
+ break;
+ case GFS2_METATYPE_QC:
+ *structlen = sizeof(struct gfs2_quota_change);
+ break;
+ default:
+ *structlen = sbd.bsize;
+ break;
+ }
+ return ty;
}
/* ------------------------------------------------------------------------ */
@@ -629,78 +686,52 @@ int display_block_type(int from_restore)
ret_type = GFS2_METATYPE_DI;
struct_len = 0;
} else {
- ret_type = get_block_type(bh);
+ ret_type = get_block_type(bh, &struct_len);
switch (ret_type) {
case GFS2_METATYPE_SB: /* 1 */
print_gfs2("(superblock)");
- if (sbd.gfs1)
- struct_len = sizeof(struct gfs_sb);
- else
- struct_len = sizeof(struct gfs2_sb);
break;
case GFS2_METATYPE_RG: /* 2 */
print_gfs2("(rsrc grp hdr)");
- struct_len = sizeof(struct gfs2_rgrp);
break;
case GFS2_METATYPE_RB: /* 3 */
print_gfs2("(rsrc grp bitblk)");
- struct_len = sizeof(struct gfs2_meta_header);
break;
case GFS2_METATYPE_DI: /* 4 */
print_gfs2("(disk inode)");
- struct_len = sizeof(struct gfs2_dinode);
break;
case GFS2_METATYPE_IN: /* 5 */
print_gfs2("(indir blklist)");
- if (sbd.gfs1)
- struct_len = sizeof(struct gfs_indirect);
- else
- struct_len = sizeof(struct gfs2_meta_header);
break;
case GFS2_METATYPE_LF: /* 6 */
print_gfs2("(directory leaf)");
- struct_len = sizeof(struct gfs2_leaf);
break;
case GFS2_METATYPE_JD:
print_gfs2("(journal data)");
- struct_len = sizeof(struct gfs2_meta_header);
break;
case GFS2_METATYPE_LH:
print_gfs2("(log header)");
- struct_len = sizeof(struct gfs2_log_header);
break;
case GFS2_METATYPE_LD:
print_gfs2("(log descriptor)");
- if (sbd.gfs1)
- struct_len = sizeof(struct gfs_log_descriptor);
- else
- struct_len =
- sizeof(struct gfs2_log_descriptor);
break;
case GFS2_METATYPE_EA:
print_gfs2("(extended attr hdr)");
- struct_len = sizeof(struct gfs2_meta_header) +
- sizeof(struct gfs2_ea_header);
break;
case GFS2_METATYPE_ED:
print_gfs2("(extended attr data)");
- struct_len = sizeof(struct gfs2_meta_header) +
- sizeof(struct gfs2_ea_header);
break;
case GFS2_METATYPE_LB:
print_gfs2("(log buffer)");
- struct_len = sizeof(struct gfs2_meta_header);
break;
case GFS2_METATYPE_QC:
print_gfs2("(quota change)");
- struct_len = sizeof(struct gfs2_quota_change);
break;
case 0:
struct_len = sbd.bsize;
break;
default:
print_gfs2("(wtf?)");
- struct_len = sbd.bsize;
break;
}
}
@@ -855,18 +886,26 @@ static const struct lgfs2_metadata *find_mtype(uint32_t mtype, const unsigned ve
/* ------------------------------------------------------------------------ */
/* hexdump - hex dump the filesystem block to the screen */
/* ------------------------------------------------------------------------ */
-static int hexdump(uint64_t startaddr, int len)
+static int hexdump(uint64_t startaddr, int len, int trunc_zeros,
+ uint64_t flagref)
{
- const unsigned char *pointer,*ptr2;
+ const unsigned char *pointer, *ptr2;
int i;
uint64_t l;
const char *lpBuffer = bh->b_data;
+ const char *zeros_strt = lpBuffer + sbd.bsize;
int print_field, cursor_line;
- const uint32_t block_type = get_block_type(bh);
+ const uint32_t block_type = get_block_type(bh, NULL);
+ uint64_t *ref;
strcpy(edit_fmt,"%02x");
pointer = (unsigned char *)lpBuffer + offset;
ptr2 = (unsigned char *)lpBuffer + offset;
+ ref = (uint64_t *)lpBuffer + offset;
+ if (trunc_zeros) {
+ while (zeros_strt > lpBuffer && (*(zeros_strt - 1) == 0))
+ zeros_strt--;
+ }
l = offset;
print_entry_ndx = 0;
while (((termlines && line < termlines &&
@@ -997,9 +1036,20 @@ static int hexdump(uint64_t startaddr, int len)
}
if (line - 3 > last_entry_onscreen[dmode])
last_entry_onscreen[dmode] = line - 3;
+ if (flagref && be64_to_cpu(*ref) == flagref)
+ print_gfs2("<------------------------- ref to 0x%llx",
+ flagref);
+ ref++;
+ if (flagref && be64_to_cpu(*ref) == flagref)
+ print_gfs2("<------------------------- ref to 0x%llx",
+ flagref);
+ ref++;
eol(0);
- l+=16;
+ l += 16;
print_entry_ndx++;
+ /* This should only happen if trunc_zeros is specified: */
+ if ((const char *)pointer >= zeros_strt)
+ break;
} /* while */
if (sbd.gfs1) {
COLORS_NORMAL;
@@ -1351,7 +1401,7 @@ static void read_master_dir(void)
/* ------------------------------------------------------------------------ */
/* display */
/* ------------------------------------------------------------------------ */
-int display(int identify_only)
+int display(int identify_only, int trunc_zeros, uint64_t flagref)
{
uint64_t blk;
@@ -1446,7 +1496,8 @@ int display(int identify_only)
}
if (dmode == HEX_MODE) /* if hex display mode */
hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)?
- struct_len + di.di_size:sbd.bsize);
+ struct_len + di.di_size:sbd.bsize, trunc_zeros,
+ flagref);
else if (dmode == GFS2_MODE) { /* if structure display */
if (block != JOURNALS_DUMMY_BLOCK)
display_gfs2(); /* display the gfs2 structure */
@@ -1970,7 +2021,7 @@ static void find_print_block_type(void)
tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
lbh = bread(&sbd, tblock);
- type = get_block_type(lbh);
+ type = get_block_type(lbh, NULL);
print_block_type(tblock, type, "");
brelse(lbh);
gfs2_rgrp_free(&sbd.rgtree);
@@ -2104,7 +2155,7 @@ static void process_field(const char *field, const char *nstr)
setstring = 1;
fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
rbh = bread(&sbd, fblock);
- type = get_block_type(rbh);
+ type = get_block_type(rbh, NULL);
switch (type) {
case GFS2_METATYPE_SB:
gfs2_sb_in(&lsb, rbh);
@@ -2251,7 +2302,7 @@ static void interactive_mode(void)
Quit = FALSE;
editing = FALSE;
while (!Quit) {
- display(FALSE);
+ display(FALSE, 0, 0);
if (editing) {
if (edit_row[dmode] == -1)
block = goto_block();
@@ -2720,9 +2771,16 @@ static void process_parameters(int argc, char *argv[], int pass)
if (termlines || strchr(argv[i],'/')) /* if print or slash */
continue;
- if (!strncmp(argv[i], "journal", 7) &&
- isdigit(argv[i][7])) {
- dump_journal(argv[i]);
+ if (!strncmp(argv[i], "journal", 7) && isdigit(argv[i][7])) {
+ int blk = 0;
+
+ if (i < argc - 1 && isdigit(argv[i + 1][0])) {
+ if (argv[i + 1][0]=='0' && argv[i + 1][1]=='x')
+ sscanf(argv[i + 1], "%x", &blk);
+ else
+ blk = atoi(argv[i + 1]);
+ }
+ dump_journal(argv[i], blk);
continue;
}
keyword_blk = check_keywords(argv[i]);
@@ -2926,7 +2984,7 @@ int main(int argc, char *argv[])
block = blockstack[i + 1].block;
if (!block)
break;
- display(identify);
+ display(identify, 0, 0);
if (!identify) {
display_extended();
printf("-------------------------------------" \
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 53a0c72..715e3f2 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -68,6 +68,7 @@ extern int dsplines;
extern int dsp_lines[DMODES];
extern int combined_display;
extern int details;
+extern const char *allocdesc[2][5];
struct gfs2_dirents {
uint64_t block;
@@ -232,11 +233,12 @@ extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh);
extern void savemeta(char *out_fn, int saveoption, int gziplevel);
extern void restoremeta(const char *in_fn, const char *out_device,
uint64_t printblocksonly);
-extern int display(int identify_only);
+extern int display(int identify_only, int trunc_zeros, uint64_t flagref);
extern uint64_t check_keywords(const char *kword);
extern uint64_t masterblock(const char *fn);
extern void gfs_rgrp_print(struct gfs_rgrp *rg);
extern int has_indirect_blocks(void);
-extern uint32_t get_block_type(const struct gfs2_buffer_head *lbh);
+extern uint32_t get_block_type(const struct gfs2_buffer_head *lbh,
+ int *structlen);
#endif /* __HEXVIEW_DOT_H__ */
diff --git a/gfs2/edit/journal.c b/gfs2/edit/journal.c
index 102b4b9..c69f349 100644
--- a/gfs2/edit/journal.c
+++ b/gfs2/edit/journal.c
@@ -28,10 +28,10 @@
#include "gfs2hex.h"
#include "journal.h"
-/* ------------------------------------------------------------------------ */
-/* find_journal_block - figure out where a journal starts, given the name */
-/* Returns: journal block number, changes j_size to the journal size */
-/* ------------------------------------------------------------------------ */
+/**
+ * find_journal_block - figure out where a journal starts, given the name
+ * Returns: journal block number, changes j_size to the journal size
+ */
uint64_t find_journal_block(const char *journal, uint64_t *j_size)
{
int journal_num;
@@ -108,10 +108,10 @@ static int is_meta(struct gfs2_buffer_head *lbh)
return 0;
}
-/* ------------------------------------------------------------------------ */
-/* fsck_readi - same as libgfs2's gfs2_readi, but sets absolute block # */
-/* of the first bit of data read. */
-/* ------------------------------------------------------------------------ */
+/**
+ * fsck_readi - same as libgfs2's gfs2_readi, but sets absolute block #
+ * of the first bit of data read.
+ */
static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
unsigned int size, uint64_t *abs_block)
{
@@ -173,60 +173,290 @@ static int fsck_readi(struct gfs2_inode *ip, void *rbuf, uint64_t roffset,
return copied;
}
-/* ------------------------------------------------------------------------ */
-/* print_ld_blocks - print all blocks given in a log descriptor */
-/* returns: the number of block numbers it printed */
-/* ------------------------------------------------------------------------ */
-static int print_ld_blocks(const uint64_t *b, const char *end, int start_line)
+/**
+ * ld_is_pertinent - determine if a log descriptor is pertinent
+ *
+ * This function checks a log descriptor buffer to see if it contains
+ * references to a given traced block, or its rgrp bitmap block.
+ */
+static int ld_is_pertinent(const uint64_t *b, const char *end, uint64_t tblk,
+ struct rgrp_tree *rgd, uint64_t bitblk)
{
- int bcount = 0, i = 0;
+ const uint64_t *blk = b;
+
+ if (!tblk)
+ return 1;
+
+ while (*blk && (char *)blk < end) {
+ if (be64_to_cpu(*blk) == tblk || be64_to_cpu(*blk) == bitblk)
+ return 1;
+ blk++;
+ if (sbd.gfs1)
+ blk++;
+ }
+ return 0;
+}
+
+/**
+ * print_ld_blks - print all blocks given in a log descriptor
+ * returns: the number of block numbers it printed
+ */
+static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
+ uint64_t tblk, uint64_t *tblk_off, uint64_t bitblk,
+ struct rgrp_tree *rgd, uint64_t abs_block, int prnt,
+ uint64_t *bblk_off, int is_meta_ld)
+{
+ int bcount = 0, found_tblk = 0, found_bblk = 0;
static char str[256];
+ if (tblk_off)
+ *tblk_off = 0;
+ if (bblk_off)
+ *bblk_off = 0;
while (*b && (char *)b < end) {
if (!termlines ||
(print_entry_ndx >= start_row[dmode] &&
((print_entry_ndx - start_row[dmode])+1) *
lines_per_row[dmode] <= termlines - start_line - 2)) {
- if (i && i % 4 == 0) {
+ if (prnt && bcount && bcount % 4 == 0) {
eol(0);
print_gfs2(" ");
}
- i++;
- sprintf(str, "0x%llx",
- (unsigned long long)be64_to_cpu(*b));
- print_gfs2("%-18.18s ", str);
bcount++;
+ if (prnt) {
+ sprintf(str, "0x%llx",
+ (unsigned long long)be64_to_cpu(*b));
+ print_gfs2("%-18.18s ", str);
+ }
+ if (!found_tblk && tblk_off)
+ (*tblk_off)++;
+ if (!found_bblk && bblk_off)
+ (*bblk_off)++;
+ if (tblk && (be64_to_cpu(*b) == tblk)) {
+ found_tblk = 1;
+ print_gfs2("<-------------------------0x%llx ",
+ (unsigned long long)tblk);
+ eol(18 * (bcount % 4) + 1);
+ print_gfs2(" ");
+ }
+ if (tblk && rgd && (be64_to_cpu(*b) == bitblk)) {
+ int type, bmap = 0;
+ uint64_t o;
+ struct gfs2_buffer_head *save_bh;
+ struct gfs2_buffer_head *j_bmap_bh;
+
+ found_bblk = 1;
+ print_gfs2("<-------------------------");
+ if (is_meta_ld) {
+ o = tblk - rgd->ri.ri_data0;
+ if (o >= (rgd->bits->bi_start +
+ rgd->bits->bi_len) *
+ GFS2_NBBY)
+ o += (sizeof(struct gfs2_rgrp) -
+ sizeof(struct gfs2_meta_header))
+ * GFS2_NBBY;
+ bmap = o / sbd.sd_blocks_per_bitmap;
+ save_bh = rgd->bh[bmap];
+ j_bmap_bh = bread(&sbd, abs_block +
+ bcount);
+ rgd->bh[bmap] = j_bmap_bh;
+ type = lgfs2_get_bitmap(&sbd, tblk,
+ rgd);
+ brelse(j_bmap_bh);
+ rgd->bh[bmap] = save_bh;
+ print_gfs2("bit for blk 0x%llx is %d "
+ "(%s)",
+ (unsigned long long)tblk,
+ type,
+ allocdesc[sbd.gfs1][type]);
+ } else {
+ print_gfs2("bitmap for blk 0x%llx "
+ "was revoked",
+ (unsigned long long)tblk);
+ }
+ eol(18 * (bcount % 4) + 1);
+ print_gfs2(" ");
+ }
}
b++;
if (sbd.gfs1)
b++;
}
- eol(0);
+ if (prnt)
+ eol(0);
+ if (!found_tblk || !is_meta_ld)
+ *tblk_off = 0;
+ if (!found_bblk || !is_meta_ld)
+ *bblk_off = 0;
return bcount;
}
-/* ------------------------------------------------------------------------ */
-/* dump_journal - dump a journal file's contents. */
-/* ------------------------------------------------------------------------ */
-void dump_journal(const char *journal)
+/**
+ * find_wrap_pt - figure out where a journal wraps
+ * Returns: The wrap point, in bytes
+ */
+static uint64_t find_wrap_pt(struct gfs2_inode *j_inode, char *jbuf,
+ uint64_t jblock, uint64_t j_size)
{
struct gfs2_buffer_head *j_bh = NULL, dummy_bh;
- uint64_t jblock, j_size, jb, abs_block, saveblk;
+ uint64_t jb, abs_block;
+ int error;
+ uint64_t highest_seq = 0;
+
+ for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1 : sbd.bsize)) {
+ if (sbd.gfs1) {
+ if (j_bh)
+ brelse(j_bh);
+ j_bh = bread(&sbd, jblock + jb);
+ abs_block = jblock + jb;
+ 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(&dummy_bh, NULL) == GFS2_METATYPE_LH) {
+ struct gfs2_log_header lh;
+ struct gfs_log_header lh1;
+
+ if (sbd.gfs1) {
+ gfs_log_header_in(&lh1, &dummy_bh);
+ if (lh1.lh_sequence < highest_seq)
+ return jb;
+ highest_seq = lh1.lh_sequence;
+ } else {
+ gfs2_log_header_in(&lh, &dummy_bh);
+ if (lh.lh_sequence < highest_seq)
+ return jb;
+ highest_seq = lh.lh_sequence;
+ }
+ }
+ if (j_bh)
+ brelse(j_bh);
+ }
+ return 0;
+}
+
+/**
+ * process_ld - process a log descriptor
+ */
+static int process_ld(uint64_t abs_block, uint64_t wrappt, uint64_t j_size,
+ uint64_t jb, struct gfs2_buffer_head *dummy_bh, int tblk,
+ uint64_t *tblk_off, uint64_t bitblk,
+ struct rgrp_tree *rgd, int *prnt, uint64_t *bblk_off)
+{
+ uint64_t *b;
+ struct gfs2_log_descriptor ld;
+ int ltndx, is_meta_ld = 0;
+ int ld_blocks = 0;
+ uint32_t logtypes[2][6] = {
+ {GFS2_LOG_DESC_METADATA, GFS2_LOG_DESC_REVOKE,
+ GFS2_LOG_DESC_JDATA, 0, 0, 0},
+ {GFS_LOG_DESC_METADATA, GFS_LOG_DESC_IUL, GFS_LOG_DESC_IDA,
+ GFS_LOG_DESC_Q, GFS_LOG_DESC_LAST, 0}};
+ const char *logtypestr[2][6] = {
+ {"Metadata", "Revoke", "Jdata",
+ "Unknown", "Unknown", "Unknown"},
+ {"Metadata", "Unlinked inode", "Dealloc inode",
+ "Quota", "Final Entry", "Unknown"}};
+
+ gfs2_log_descriptor_in(&ld, dummy_bh);
+ if (sbd.gfs1)
+ b = (uint64_t *)(dummy_bh->b_data +
+ sizeof(struct gfs_log_descriptor));
+ else
+ b = (uint64_t *)(dummy_bh->b_data +
+ sizeof(struct gfs2_log_descriptor));
+ *prnt = ld_is_pertinent(b, (dummy_bh->b_data + sbd.bsize), tblk, rgd,
+ bitblk);
+
+ if (*prnt) {
+ print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
+ abs_block, ((jb + wrappt) % j_size) / sbd.bsize);
+ print_gfs2("type %d ", ld.ld_type);
+
+ for (ltndx = 0;; ltndx++) {
+ if (ld.ld_type == logtypes[sbd.gfs1][ltndx] ||
+ logtypes[sbd.gfs1][ltndx] == 0)
+ break;
+ }
+ print_gfs2("(%s) ", logtypestr[sbd.gfs1][ltndx]);
+ print_gfs2("len:%u, data1: %u", ld.ld_length, ld.ld_data1);
+ eol(0);
+ print_gfs2(" ");
+ }
+ ld_blocks = ld.ld_data1;
+ if (ld.ld_type == GFS2_LOG_DESC_METADATA ||
+ ld.ld_type == GFS_LOG_DESC_METADATA)
+ is_meta_ld = 1;
+ ld_blocks -= print_ld_blks(b, (dummy_bh->b_data + sbd.bsize), line,
+ tblk, tblk_off, bitblk, rgd, abs_block,
+ *prnt, bblk_off, is_meta_ld);
+
+ return ld_blocks;
+}
+
+/**
+ * meta_has_ref - check if a metadata block references a given block
+ */
+static int meta_has_ref(uint64_t abs_block, int tblk)
+{
+ struct gfs2_buffer_head *mbh;
+ int structlen, ty, has_ref = 0;
+ uint64_t *b;
+
+ mbh = bread(&sbd, abs_block);
+ ty = get_block_type(mbh, &structlen);
+ b = (uint64_t *)(mbh->b_data + structlen);
+ while (ty && (char *)b < mbh->b_data + sbd.bsize) {
+ if (be64_to_cpu(*b) == tblk) {
+ has_ref = 1;
+ break;
+ }
+ b++;
+ }
+ brelse(mbh);
+ return has_ref;
+}
+
+/**
+ * dump_journal - dump a journal file's contents.
+ * @journal: name of the journal to dump
+ * @tblk: block number to trace in the journals
+ *
+ * This function dumps the contents of a journal. If a trace block is specified
+ * then only information printed is: (1) log descriptors that reference that
+ * block, (2) metadata in the journal that references the block, or (3)
+ * rgrp bitmaps that reference that block's allocation bit status.
+ */
+void dump_journal(const char *journal, int tblk)
+{
+ struct gfs2_buffer_head *j_bh = NULL, dummy_bh;
+ uint64_t jblock, j_size, jb, abs_block, saveblk, wrappt = 0;
int error, start_line, journal_num;
struct gfs2_inode *j_inode = NULL;
- int ld_blocks = 0;
+ int ld_blocks = 0, offset_from_ld = 0;
+ uint64_t tblk_off = 0, bblk_off = 0, bitblk = 0;
uint64_t highest_seq = 0;
char *jbuf = NULL;
+ struct rgrp_tree *rgd = NULL;
start_line = line;
lines_per_row[dmode] = 1;
error = 0;
journal_num = atoi(journal + 7);
print_gfs2("Dumping journal #%d.", journal_num);
+ if (tblk) {
+ dmode = HEX_MODE;
+ print_gfs2(" Tracing block 0x%llx", (unsigned long long)tblk);
+ }
eol(0);
jblock = find_journal_block(journal, &j_size);
if (!jblock)
return;
+
if (!sbd.gfs1) {
j_bh = bread(&sbd, jblock);
j_inode = lgfs2_inode_get(&sbd, j_bh);
@@ -241,67 +471,68 @@ void dump_journal(const char *journal)
}
}
- for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1:sbd.bsize)) {
+ if (tblk) {
+ uint64_t wp;
+
+ rgd = gfs2_blk2rgrpd(&sbd, tblk);
+ if (!rgd) {
+ print_gfs2("Can't locate the rgrp for block 0x%x",
+ tblk);
+ eol(0);
+ } else {
+ uint64_t o;
+ int bmap = 0;
+
+ print_gfs2("rgd: 0x%llx for 0x%x, ", rgd->ri.ri_addr,
+ rgd->ri.ri_length);
+ o = tblk - rgd->ri.ri_data0;
+ if (o >= (rgd->bits->bi_start +
+ rgd->bits->bi_len) * GFS2_NBBY)
+ o += (sizeof(struct gfs2_rgrp) -
+ sizeof(struct gfs2_meta_header))
+ * GFS2_NBBY;
+ bmap = o / sbd.sd_blocks_per_bitmap;
+ bitblk = rgd->ri.ri_addr + bmap;
+ print_gfs2("bitmap: %d, bitblk: 0x%llx", bmap,
+ (unsigned long long)bitblk);
+ eol(0);
+ }
+
+ wrappt = find_wrap_pt(j_inode, jbuf, jblock, j_size);
+ wp = wrappt / (sbd.gfs1 ? 1 : sbd.bsize);
+ print_gfs2("Starting at journal wrap block: 0x%llx "
+ "(j + 0x%llx)",
+ (unsigned long long)jblock + wp,
+ (unsigned long long)wp);
+ eol(0);
+ }
+
+ for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1 : sbd.bsize)) {
+ int is_pertinent = 1;
+
if (sbd.gfs1) {
if (j_bh)
brelse(j_bh);
- j_bh = bread(&sbd, jblock + jb);
- abs_block = jblock + jb;
+ abs_block = jblock + ((jb + wrappt) % j_size);
+ j_bh = bread(&sbd, abs_block);
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 + wrappt) % j_size),
sbd.bsize, &abs_block);
if (!error) /* end of file */
break;
dummy_bh.b_data = jbuf;
}
- if (get_block_type(&dummy_bh) == GFS2_METATYPE_LD) {
- uint64_t *b;
- struct gfs2_log_descriptor ld;
- int ltndx;
- uint32_t logtypes[2][6] = {
- {GFS2_LOG_DESC_METADATA,
- GFS2_LOG_DESC_REVOKE,
- GFS2_LOG_DESC_JDATA,
- 0, 0, 0},
- {GFS_LOG_DESC_METADATA,
- GFS_LOG_DESC_IUL,
- GFS_LOG_DESC_IDA,
- GFS_LOG_DESC_Q,
- GFS_LOG_DESC_LAST,
- 0}};
- const char *logtypestr[2][6] = {
- {"Metadata", "Revoke", "Jdata",
- "Unknown", "Unknown", "Unknown"},
- {"Metadata", "Unlinked inode", "Dealloc inode",
- "Quota", "Final Entry", "Unknown"}};
-
- print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
- abs_block, jb / (sbd.gfs1 ? 1 : sbd.bsize));
- gfs2_log_descriptor_in(&ld, &dummy_bh);
- print_gfs2("type %d ", ld.ld_type);
-
- for (ltndx = 0;; ltndx++) {
- if (ld.ld_type == logtypes[sbd.gfs1][ltndx] ||
- logtypes[sbd.gfs1][ltndx] == 0)
- break;
- }
- print_gfs2("(%s) ", logtypestr[sbd.gfs1][ltndx]);
- print_gfs2("len:%u, data1: %u",
- ld.ld_length, ld.ld_data1);
- eol(0);
- print_gfs2(" ");
- if (sbd.gfs1)
- b = (uint64_t *)(dummy_bh.b_data +
- sizeof(struct gfs_log_descriptor));
- else
- b = (uint64_t *)(dummy_bh.b_data +
- sizeof(struct gfs2_log_descriptor));
- ld_blocks = ld.ld_data1;
- ld_blocks -= print_ld_blocks(b, (dummy_bh.b_data +
- sbd.bsize),
- start_line);
- } else if (get_block_type(&dummy_bh) == GFS2_METATYPE_LH) {
+ offset_from_ld++;
+ if (get_block_type(&dummy_bh, NULL) == GFS2_METATYPE_LD) {
+ ld_blocks = process_ld(abs_block, wrappt, j_size, jb,
+ &dummy_bh, tblk, &tblk_off,
+ bitblk, rgd, &is_pertinent,
+ &bblk_off);
+ offset_from_ld = 0;
+ } else if (!tblk &&
+ get_block_type(&dummy_bh, NULL) == GFS2_METATYPE_LH) {
struct gfs2_log_header lh;
struct gfs_log_header lh1;
@@ -310,10 +541,10 @@ void dump_journal(const char *journal)
check_journal_wrap(lh1.lh_sequence,
&highest_seq);
print_gfs2("0x%llx (j+%4llx): Log header: "
- "Flags:%x, Seq: 0x%x, "
- "1st: 0x%x, tail: 0x%x, "
- "last: 0x%x", abs_block,
- jb, lh1.lh_flags, lh1.lh_sequence,
+ "Flags:%x, Seq: 0x%x, 1st: 0x%x, "
+ "tail: 0x%x, last: 0x%x",
+ abs_block, jb + wrappt,
+ lh1.lh_flags, lh1.lh_sequence,
lh1.lh_first, lh1.lh_tail,
lh1.lh_last_dump);
} else {
@@ -322,8 +553,8 @@ void dump_journal(const char *journal)
&highest_seq);
print_gfs2("0x%llx (j+%4llx): Log header: Seq"
": 0x%x, tail: 0x%x, blk: 0x%x",
- abs_block,
- jb / sbd.bsize, lh.lh_sequence,
+ abs_block, ((jb + wrappt) % j_size)
+ / sbd.bsize, lh.lh_sequence,
lh.lh_tail, lh.lh_blkno);
}
eol(0);
@@ -332,13 +563,24 @@ void dump_journal(const char *journal)
" continuation block", abs_block, jb);
eol(0);
print_gfs2(" ");
- ld_blocks -= print_ld_blocks((uint64_t *)dummy_bh.b_data,
- (dummy_bh.b_data +
- sbd.bsize), start_line);
- } else if (details && is_meta(&dummy_bh)) {
+ ld_blocks -= print_ld_blks((uint64_t *)dummy_bh.b_data,
+ (dummy_bh.b_data +
+ sbd.bsize), start_line,
+ tblk, &tblk_off, 0, rgd,
+ 0, 1, NULL, 1);
+ } else if (!is_meta(&dummy_bh)) {
+ continue;
+ }
+ /* Check if this metadata block references the block we're
+ trying to trace. */
+ if (details ||
+ (is_pertinent && tblk &&
+ ((tblk_off && offset_from_ld == tblk_off) ||
+ (bblk_off && offset_from_ld == bblk_off))) ||
+ meta_has_ref(abs_block, tblk)) {
saveblk = block;
block = abs_block;
- display(0);
+ display(0, tblk ? 1 : 0, tblk);
block = saveblk;
}
}
@@ -346,4 +588,6 @@ void dump_journal(const char *journal)
brelse(j_bh);
blockhist = -1; /* So we don't print anything else */
free(jbuf);
+ if (!termlines)
+ fflush(stdout);
}
diff --git a/gfs2/edit/journal.h b/gfs2/edit/journal.h
index e227a77..1e5968b 100644
--- a/gfs2/edit/journal.h
+++ b/gfs2/edit/journal.h
@@ -1,8 +1,7 @@
#ifndef __JOURNAL_DOT_H__
#define __JOURNAL_DOT_H__
-extern void dump_journal(const char *journal);
+extern void dump_journal(const char *journal, int tblk);
extern uint64_t find_journal_block(const char *journal, uint64_t *j_size);
-
#endif
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 676bc29..c5a33db 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -932,7 +932,7 @@ static int restore_data(int fd, gzFile gzin_fd, int printblocksonly,
block = savedata->blk;
if (printblocksonly > 1 && printblocksonly == block) {
block_in_mem = block;
- display(0);
+ display(0, 0, 0);
return 0;
} else if (printblocksonly == 1) {
print_gfs2("%d (l=0x%x): ", blks_saved,
10 years, 1 month
gfs2-utils: master - gfs2_edit: Separate out the journal-related functions to journal.c
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=478f093f...
Commit: 478f093f301149c54db72a94ff7e9148ac00444e
Parent: 57f0e1b70dbd1de7aca9b2bdc09d49d28c25d888
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 27 09:23:04 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Feb 27 20:27:07 2014 +0000
gfs2_edit: Separate out the journal-related functions to journal.c
This patch takes all the code related to dumping journals and puts them
all in a separate journal.c. This will later be used for journal parsing.
Signed-off-by: Bob Peterson <rpeterso(a)redhat.com>
---
gfs2/edit/Makefile.am | 4 +-
gfs2/edit/hexedit.c | 323 +---------------------------------------------
gfs2/edit/hexedit.h | 2 +
gfs2/edit/journal.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/edit/journal.h | 8 +
5 files changed, 363 insertions(+), 323 deletions(-)
diff --git a/gfs2/edit/Makefile.am b/gfs2/edit/Makefile.am
index c4814dc..8b977ae 100644
--- a/gfs2/edit/Makefile.am
+++ b/gfs2/edit/Makefile.am
@@ -2,9 +2,9 @@ MAINTAINERCLEANFILES = Makefile.in
sbin_PROGRAMS = gfs2_edit
-noinst_HEADERS = gfs2hex.h hexedit.h extended.h
+noinst_HEADERS = gfs2hex.h hexedit.h extended.h journal.h
-gfs2_edit_SOURCES = gfs2hex.c hexedit.c savemeta.c extended.c
+gfs2_edit_SOURCES = gfs2hex.c hexedit.c savemeta.c extended.c journal.c
gfs2_edit_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -DHELPER_PROGRAM \
-I$(top_srcdir)/gfs2/include \
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index cf57ec8..18d06c7 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -26,6 +26,7 @@
#include "libgfs2.h"
#include "gfs2hex.h"
#include "extended.h"
+#include "journal.h"
const char *mtypes[] = {"none", "sb", "rg", "rb", "di", "in", "lf", "jd",
"lh", "ld", "ea", "ed", "lb", "13", "qc"};
@@ -577,7 +578,7 @@ static void print_usage(void)
/* returns: metatype if block is a GFS2 structure block type */
/* 0 if block is not a GFS2 structure */
/* ------------------------------------------------------------------------ */
-static uint32_t get_block_type(const struct gfs2_buffer_head *lbh)
+uint32_t get_block_type(const struct gfs2_buffer_head *lbh)
{
const struct gfs2_meta_header *mh = lbh->iov.iov_base;
@@ -1508,61 +1509,6 @@ static uint64_t pop_block(void)
}
/* ------------------------------------------------------------------------ */
-/* find_journal_block - figure out where a journal starts, given the name */
-/* Returns: journal block number, changes j_size to the journal size */
-/* ------------------------------------------------------------------------ */
-static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
-{
- int journal_num;
- uint64_t jindex_block, jblock = 0;
- int amtread;
- struct gfs2_buffer_head *jindex_bh, *j_bh;
- char jbuf[sbd.bsize];
-
- journal_num = atoi(journal + 7);
- /* Figure out the block of the jindex file */
- if (sbd.gfs1)
- jindex_block = sbd1->sb_jindex_di.no_addr;
- else
- jindex_block = masterblock("jindex");
- /* read in the block */
- jindex_bh = bread(&sbd, jindex_block);
- /* get the dinode data from it. */
- gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
-
- if (!sbd.gfs1)
- do_dinode_extended(&di, jindex_bh); /* parse dir. */
-
- if (sbd.gfs1) {
- struct gfs2_inode *jiinode;
- struct gfs_jindex ji;
-
- jiinode = lgfs2_inode_get(&sbd, jindex_bh);
- if (jiinode == NULL)
- return 0;
- amtread = gfs2_readi(jiinode, (void *)&jbuf,
- journal_num * sizeof(struct gfs_jindex),
- sizeof(struct gfs_jindex));
- if (amtread) {
- gfs_jindex_in(&ji, jbuf);
- jblock = ji.ji_addr;
- *j_size = ji.ji_nsegment * 0x10;
- }
- inode_put(&jiinode);
- } else {
- struct gfs2_dinode jdi;
-
- jblock = indirect->ii[0].dirent[journal_num + 2].block;
- j_bh = bread(&sbd, jblock);
- gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */
- *j_size = jdi.di_size;
- brelse(j_bh);
- }
- brelse(jindex_bh);
- return jblock;
-}
-
-/* ------------------------------------------------------------------------ */
/* Find next metadata block of a given type AFTER a given point in the fs */
/* */
/* This is used to find blocks that aren't represented in the bitmaps, such */
@@ -2577,271 +2523,6 @@ void gfs_log_header_print(struct gfs_log_header *lh)
}
/* ------------------------------------------------------------------------ */
-/* print_ld_blocks - print all blocks given in a log descriptor */
-/* returns: the number of block numbers it printed */
-/* ------------------------------------------------------------------------ */
-static int print_ld_blocks(const uint64_t *b, const char *end, int start_line)
-{
- int bcount = 0, i = 0;
- static char str[256];
-
- while (*b && (char *)b < end) {
- if (!termlines ||
- (print_entry_ndx >= start_row[dmode] &&
- ((print_entry_ndx - start_row[dmode])+1) *
- lines_per_row[dmode] <= termlines - start_line - 2)) {
- if (i && i % 4 == 0) {
- eol(0);
- print_gfs2(" ");
- }
- i++;
- sprintf(str, "0x%llx",
- (unsigned long long)be64_to_cpu(*b));
- print_gfs2("%-18.18s ", str);
- bcount++;
- }
- b++;
- if (sbd.gfs1)
- b++;
- }
- eol(0);
- return bcount;
-}
-
-/* ------------------------------------------------------------------------ */
-/* fsck_readi - same as libgfs2's gfs2_readi, but sets absolute block # */
-/* of the first bit of data read. */
-/* ------------------------------------------------------------------------ */
-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 *lbh;
- uint64_t lblock, dblock;
- unsigned int o;
- uint32_t extlen = 0;
- unsigned int amount;
- int not_new = 0;
- int isdir = !!(S_ISDIR(ip->i_di.di_mode));
- int copied = 0;
-
- *abs_block = 0;
- if (roffset >= ip->i_di.di_size)
- return 0;
- if ((roffset + size) > ip->i_di.di_size)
- size = ip->i_di.di_size - roffset;
- if (!size)
- return 0;
- if (isdir) {
- o = roffset % sdp->sd_jbsize;
- lblock = roffset / sdp->sd_jbsize;
- } else {
- lblock = roffset >> sdp->sd_sb.sb_bsize_shift;
- o = roffset & (sdp->bsize - 1);
- }
-
- if (!ip->i_di.di_height) /* inode_is_stuffed */
- o += sizeof(struct gfs2_dinode);
- else if (isdir)
- o += sizeof(struct gfs2_meta_header);
-
- while (copied < size) {
- amount = size - copied;
- if (amount > sdp->bsize - o)
- amount = sdp->bsize - o;
- if (!extlen)
- block_map(ip, lblock, ¬_new, &dblock, &extlen,
- FALSE);
- if (dblock) {
- lbh = bread(sdp, dblock);
- if (*abs_block == 0)
- *abs_block = lbh->b_blocknr;
- dblock++;
- extlen--;
- } else
- lbh = NULL;
- if (lbh) {
- memcpy(rbuf, lbh->b_data + o, amount);
- brelse(lbh);
- } else {
- memset(rbuf, 0, amount);
- }
- copied += amount;
- lblock++;
- o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
- }
- return copied;
-}
-
-static void check_journal_wrap(uint64_t seq, uint64_t *highest_seq)
-{
- if (seq < *highest_seq) {
- print_gfs2("------------------------------------------------"
- "------------------------------------------------");
- eol(0);
- print_gfs2("Journal wrapped here.");
- eol(0);
- print_gfs2("------------------------------------------------"
- "------------------------------------------------");
- eol(0);
- }
- *highest_seq = seq;
-}
-
-static int is_meta(struct gfs2_buffer_head *lbh)
-{
- uint32_t check_magic = ((struct gfs2_meta_header *)(lbh->b_data))->mh_magic;
-
- check_magic = be32_to_cpu(check_magic);
- if (check_magic == GFS2_MAGIC)
- return 1;
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-/* dump_journal - dump a journal file's contents. */
-/* ------------------------------------------------------------------------ */
-static void dump_journal(const char *journal)
-{
- struct gfs2_buffer_head *j_bh = NULL, dummy_bh;
- uint64_t jblock, j_size, jb, abs_block, saveblk;
- int error, start_line, journal_num;
- 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;
- error = 0;
- journal_num = atoi(journal + 7);
- print_gfs2("Dumping journal #%d.", journal_num);
- eol(0);
- jblock = find_journal_block(journal, &j_size);
- if (!jblock)
- return;
- if (!sbd.gfs1) {
- j_bh = bread(&sbd, jblock);
- j_inode = lgfs2_inode_get(&sbd, j_bh);
- if (j_inode == NULL) {
- fprintf(stderr, "Out of memory\n");
- exit(-1);
- }
- jbuf = malloc(sbd.bsize);
- if (jbuf == NULL) {
- fprintf(stderr, "Out of memory\n");
- exit(-1);
- }
- }
-
- for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1:sbd.bsize)) {
- if (sbd.gfs1) {
- if (j_bh)
- brelse(j_bh);
- j_bh = bread(&sbd, jblock + jb);
- abs_block = jblock + jb;
- 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(&dummy_bh) == GFS2_METATYPE_LD) {
- uint64_t *b;
- struct gfs2_log_descriptor ld;
- int ltndx;
- uint32_t logtypes[2][6] = {
- {GFS2_LOG_DESC_METADATA,
- GFS2_LOG_DESC_REVOKE,
- GFS2_LOG_DESC_JDATA,
- 0, 0, 0},
- {GFS_LOG_DESC_METADATA,
- GFS_LOG_DESC_IUL,
- GFS_LOG_DESC_IDA,
- GFS_LOG_DESC_Q,
- GFS_LOG_DESC_LAST,
- 0}};
- const char *logtypestr[2][6] = {
- {"Metadata", "Revoke", "Jdata",
- "Unknown", "Unknown", "Unknown"},
- {"Metadata", "Unlinked inode", "Dealloc inode",
- "Quota", "Final Entry", "Unknown"}};
-
- print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
- abs_block, jb / (sbd.gfs1 ? 1 : sbd.bsize));
- gfs2_log_descriptor_in(&ld, &dummy_bh);
- print_gfs2("type %d ", ld.ld_type);
-
- for (ltndx = 0;; ltndx++) {
- if (ld.ld_type == logtypes[sbd.gfs1][ltndx] ||
- logtypes[sbd.gfs1][ltndx] == 0)
- break;
- }
- print_gfs2("(%s) ", logtypestr[sbd.gfs1][ltndx]);
- print_gfs2("len:%u, data1: %u",
- ld.ld_length, ld.ld_data1);
- eol(0);
- print_gfs2(" ");
- if (sbd.gfs1)
- b = (uint64_t *)(dummy_bh.b_data +
- sizeof(struct gfs_log_descriptor));
- else
- b = (uint64_t *)(dummy_bh.b_data +
- sizeof(struct gfs2_log_descriptor));
- ld_blocks = ld.ld_data1;
- ld_blocks -= print_ld_blocks(b, (dummy_bh.b_data +
- sbd.bsize),
- start_line);
- } else if (get_block_type(&dummy_bh) == GFS2_METATYPE_LH) {
- struct gfs2_log_header lh;
- struct gfs_log_header lh1;
-
- if (sbd.gfs1) {
- gfs_log_header_in(&lh1, &dummy_bh);
- check_journal_wrap(lh1.lh_sequence,
- &highest_seq);
- print_gfs2("0x%llx (j+%4llx): Log header: "
- "Flags:%x, Seq: 0x%x, "
- "1st: 0x%x, tail: 0x%x, "
- "last: 0x%x", abs_block,
- jb, lh1.lh_flags, lh1.lh_sequence,
- lh1.lh_first, lh1.lh_tail,
- lh1.lh_last_dump);
- } else {
- gfs2_log_header_in(&lh, &dummy_bh);
- check_journal_wrap(lh.lh_sequence,
- &highest_seq);
- print_gfs2("0x%llx (j+%4llx): Log header: Seq"
- ": 0x%x, tail: 0x%x, blk: 0x%x",
- abs_block,
- jb / sbd.bsize, lh.lh_sequence,
- lh.lh_tail, lh.lh_blkno);
- }
- eol(0);
- } else if (sbd.gfs1 && ld_blocks > 0) {
- print_gfs2("0x%llx (j+%4llx): GFS log descriptor"
- " continuation block", abs_block, jb);
- eol(0);
- print_gfs2(" ");
- ld_blocks -= print_ld_blocks((uint64_t *)dummy_bh.b_data,
- (dummy_bh.b_data +
- sbd.bsize), start_line);
- } else if (details && is_meta(&dummy_bh)) {
- saveblk = block;
- block = abs_block;
- display(0);
- block = saveblk;
- }
- }
- inode_put(&j_inode);
- brelse(j_bh);
- blockhist = -1; /* So we don't print anything else */
- free(jbuf);
-}
-
-/* ------------------------------------------------------------------------ */
/* usage - print command line usage */
/* ------------------------------------------------------------------------ */
static void usage(void)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 7615242..53a0c72 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -67,6 +67,7 @@ extern const char *block_type_str[15];
extern int dsplines;
extern int dsp_lines[DMODES];
extern int combined_display;
+extern int details;
struct gfs2_dirents {
uint64_t block;
@@ -236,5 +237,6 @@ extern uint64_t check_keywords(const char *kword);
extern uint64_t masterblock(const char *fn);
extern void gfs_rgrp_print(struct gfs_rgrp *rg);
extern int has_indirect_blocks(void);
+extern uint32_t get_block_type(const struct gfs2_buffer_head *lbh);
#endif /* __HEXVIEW_DOT_H__ */
diff --git a/gfs2/edit/journal.c b/gfs2/edit/journal.c
new file mode 100644
index 0000000..102b4b9
--- /dev/null
+++ b/gfs2/edit/journal.c
@@ -0,0 +1,349 @@
+#include "clusterautoconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <curses.h>
+#include <term.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <dirent.h>
+
+#include <linux/gfs2_ondisk.h>
+#include "copyright.cf"
+
+#include "hexedit.h"
+#include "libgfs2.h"
+#include "extended.h"
+#include "gfs2hex.h"
+#include "journal.h"
+
+/* ------------------------------------------------------------------------ */
+/* find_journal_block - figure out where a journal starts, given the name */
+/* Returns: journal block number, changes j_size to the journal size */
+/* ------------------------------------------------------------------------ */
+uint64_t find_journal_block(const char *journal, uint64_t *j_size)
+{
+ int journal_num;
+ uint64_t jindex_block, jblock = 0;
+ int amtread;
+ struct gfs2_buffer_head *jindex_bh, *j_bh;
+ char jbuf[sbd.bsize];
+
+ journal_num = atoi(journal + 7);
+ /* Figure out the block of the jindex file */
+ if (sbd.gfs1)
+ jindex_block = sbd1->sb_jindex_di.no_addr;
+ else
+ jindex_block = masterblock("jindex");
+ /* read in the block */
+ jindex_bh = bread(&sbd, jindex_block);
+ /* get the dinode data from it. */
+ gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
+
+ if (!sbd.gfs1)
+ do_dinode_extended(&di, jindex_bh); /* parse dir. */
+
+ if (sbd.gfs1) {
+ struct gfs2_inode *jiinode;
+ struct gfs_jindex ji;
+
+ jiinode = lgfs2_inode_get(&sbd, jindex_bh);
+ if (jiinode == NULL)
+ return 0;
+ amtread = gfs2_readi(jiinode, (void *)&jbuf,
+ journal_num * sizeof(struct gfs_jindex),
+ sizeof(struct gfs_jindex));
+ if (amtread) {
+ gfs_jindex_in(&ji, jbuf);
+ jblock = ji.ji_addr;
+ *j_size = ji.ji_nsegment * 0x10;
+ }
+ inode_put(&jiinode);
+ } else {
+ struct gfs2_dinode jdi;
+
+ jblock = indirect->ii[0].dirent[journal_num + 2].block;
+ j_bh = bread(&sbd, jblock);
+ gfs2_dinode_in(&jdi, j_bh);/* parse dinode to struct */
+ *j_size = jdi.di_size;
+ brelse(j_bh);
+ }
+ brelse(jindex_bh);
+ return jblock;
+}
+
+static void check_journal_wrap(uint64_t seq, uint64_t *highest_seq)
+{
+ if (seq < *highest_seq) {
+ print_gfs2("------------------------------------------------"
+ "------------------------------------------------");
+ eol(0);
+ print_gfs2("Journal wrapped here.");
+ eol(0);
+ print_gfs2("------------------------------------------------"
+ "------------------------------------------------");
+ eol(0);
+ }
+ *highest_seq = seq;
+}
+
+static int is_meta(struct gfs2_buffer_head *lbh)
+{
+ uint32_t check_magic = ((struct gfs2_meta_header *)(lbh->b_data))->mh_magic;
+
+ check_magic = be32_to_cpu(check_magic);
+ if (check_magic == GFS2_MAGIC)
+ return 1;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+/* fsck_readi - same as libgfs2's gfs2_readi, but sets absolute block # */
+/* of the first bit of data read. */
+/* ------------------------------------------------------------------------ */
+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 *lbh;
+ uint64_t lblock, dblock;
+ unsigned int o;
+ uint32_t extlen = 0;
+ unsigned int amount;
+ int not_new = 0;
+ int isdir = !!(S_ISDIR(ip->i_di.di_mode));
+ int copied = 0;
+
+ *abs_block = 0;
+ if (roffset >= ip->i_di.di_size)
+ return 0;
+ if ((roffset + size) > ip->i_di.di_size)
+ size = ip->i_di.di_size - roffset;
+ if (!size)
+ return 0;
+ if (isdir) {
+ o = roffset % sdp->sd_jbsize;
+ lblock = roffset / sdp->sd_jbsize;
+ } else {
+ lblock = roffset >> sdp->sd_sb.sb_bsize_shift;
+ o = roffset & (sdp->bsize - 1);
+ }
+
+ if (!ip->i_di.di_height) /* inode_is_stuffed */
+ o += sizeof(struct gfs2_dinode);
+ else if (isdir)
+ o += sizeof(struct gfs2_meta_header);
+
+ while (copied < size) {
+ amount = size - copied;
+ if (amount > sdp->bsize - o)
+ amount = sdp->bsize - o;
+ if (!extlen)
+ block_map(ip, lblock, ¬_new, &dblock, &extlen,
+ FALSE);
+ if (dblock) {
+ lbh = bread(sdp, dblock);
+ if (*abs_block == 0)
+ *abs_block = lbh->b_blocknr;
+ dblock++;
+ extlen--;
+ } else
+ lbh = NULL;
+ if (lbh) {
+ memcpy(rbuf, lbh->b_data + o, amount);
+ brelse(lbh);
+ } else {
+ memset(rbuf, 0, amount);
+ }
+ copied += amount;
+ lblock++;
+ o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
+ }
+ return copied;
+}
+
+/* ------------------------------------------------------------------------ */
+/* print_ld_blocks - print all blocks given in a log descriptor */
+/* returns: the number of block numbers it printed */
+/* ------------------------------------------------------------------------ */
+static int print_ld_blocks(const uint64_t *b, const char *end, int start_line)
+{
+ int bcount = 0, i = 0;
+ static char str[256];
+
+ while (*b && (char *)b < end) {
+ if (!termlines ||
+ (print_entry_ndx >= start_row[dmode] &&
+ ((print_entry_ndx - start_row[dmode])+1) *
+ lines_per_row[dmode] <= termlines - start_line - 2)) {
+ if (i && i % 4 == 0) {
+ eol(0);
+ print_gfs2(" ");
+ }
+ i++;
+ sprintf(str, "0x%llx",
+ (unsigned long long)be64_to_cpu(*b));
+ print_gfs2("%-18.18s ", str);
+ bcount++;
+ }
+ b++;
+ if (sbd.gfs1)
+ b++;
+ }
+ eol(0);
+ return bcount;
+}
+
+/* ------------------------------------------------------------------------ */
+/* dump_journal - dump a journal file's contents. */
+/* ------------------------------------------------------------------------ */
+void dump_journal(const char *journal)
+{
+ struct gfs2_buffer_head *j_bh = NULL, dummy_bh;
+ uint64_t jblock, j_size, jb, abs_block, saveblk;
+ int error, start_line, journal_num;
+ 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;
+ error = 0;
+ journal_num = atoi(journal + 7);
+ print_gfs2("Dumping journal #%d.", journal_num);
+ eol(0);
+ jblock = find_journal_block(journal, &j_size);
+ if (!jblock)
+ return;
+ if (!sbd.gfs1) {
+ j_bh = bread(&sbd, jblock);
+ j_inode = lgfs2_inode_get(&sbd, j_bh);
+ if (j_inode == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(-1);
+ }
+ jbuf = malloc(sbd.bsize);
+ if (jbuf == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(-1);
+ }
+ }
+
+ for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1:sbd.bsize)) {
+ if (sbd.gfs1) {
+ if (j_bh)
+ brelse(j_bh);
+ j_bh = bread(&sbd, jblock + jb);
+ abs_block = jblock + jb;
+ 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(&dummy_bh) == GFS2_METATYPE_LD) {
+ uint64_t *b;
+ struct gfs2_log_descriptor ld;
+ int ltndx;
+ uint32_t logtypes[2][6] = {
+ {GFS2_LOG_DESC_METADATA,
+ GFS2_LOG_DESC_REVOKE,
+ GFS2_LOG_DESC_JDATA,
+ 0, 0, 0},
+ {GFS_LOG_DESC_METADATA,
+ GFS_LOG_DESC_IUL,
+ GFS_LOG_DESC_IDA,
+ GFS_LOG_DESC_Q,
+ GFS_LOG_DESC_LAST,
+ 0}};
+ const char *logtypestr[2][6] = {
+ {"Metadata", "Revoke", "Jdata",
+ "Unknown", "Unknown", "Unknown"},
+ {"Metadata", "Unlinked inode", "Dealloc inode",
+ "Quota", "Final Entry", "Unknown"}};
+
+ print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
+ abs_block, jb / (sbd.gfs1 ? 1 : sbd.bsize));
+ gfs2_log_descriptor_in(&ld, &dummy_bh);
+ print_gfs2("type %d ", ld.ld_type);
+
+ for (ltndx = 0;; ltndx++) {
+ if (ld.ld_type == logtypes[sbd.gfs1][ltndx] ||
+ logtypes[sbd.gfs1][ltndx] == 0)
+ break;
+ }
+ print_gfs2("(%s) ", logtypestr[sbd.gfs1][ltndx]);
+ print_gfs2("len:%u, data1: %u",
+ ld.ld_length, ld.ld_data1);
+ eol(0);
+ print_gfs2(" ");
+ if (sbd.gfs1)
+ b = (uint64_t *)(dummy_bh.b_data +
+ sizeof(struct gfs_log_descriptor));
+ else
+ b = (uint64_t *)(dummy_bh.b_data +
+ sizeof(struct gfs2_log_descriptor));
+ ld_blocks = ld.ld_data1;
+ ld_blocks -= print_ld_blocks(b, (dummy_bh.b_data +
+ sbd.bsize),
+ start_line);
+ } else if (get_block_type(&dummy_bh) == GFS2_METATYPE_LH) {
+ struct gfs2_log_header lh;
+ struct gfs_log_header lh1;
+
+ if (sbd.gfs1) {
+ gfs_log_header_in(&lh1, &dummy_bh);
+ check_journal_wrap(lh1.lh_sequence,
+ &highest_seq);
+ print_gfs2("0x%llx (j+%4llx): Log header: "
+ "Flags:%x, Seq: 0x%x, "
+ "1st: 0x%x, tail: 0x%x, "
+ "last: 0x%x", abs_block,
+ jb, lh1.lh_flags, lh1.lh_sequence,
+ lh1.lh_first, lh1.lh_tail,
+ lh1.lh_last_dump);
+ } else {
+ gfs2_log_header_in(&lh, &dummy_bh);
+ check_journal_wrap(lh.lh_sequence,
+ &highest_seq);
+ print_gfs2("0x%llx (j+%4llx): Log header: Seq"
+ ": 0x%x, tail: 0x%x, blk: 0x%x",
+ abs_block,
+ jb / sbd.bsize, lh.lh_sequence,
+ lh.lh_tail, lh.lh_blkno);
+ }
+ eol(0);
+ } else if (sbd.gfs1 && ld_blocks > 0) {
+ print_gfs2("0x%llx (j+%4llx): GFS log descriptor"
+ " continuation block", abs_block, jb);
+ eol(0);
+ print_gfs2(" ");
+ ld_blocks -= print_ld_blocks((uint64_t *)dummy_bh.b_data,
+ (dummy_bh.b_data +
+ sbd.bsize), start_line);
+ } else if (details && is_meta(&dummy_bh)) {
+ saveblk = block;
+ block = abs_block;
+ display(0);
+ block = saveblk;
+ }
+ }
+ inode_put(&j_inode);
+ brelse(j_bh);
+ blockhist = -1; /* So we don't print anything else */
+ free(jbuf);
+}
diff --git a/gfs2/edit/journal.h b/gfs2/edit/journal.h
new file mode 100644
index 0000000..e227a77
--- /dev/null
+++ b/gfs2/edit/journal.h
@@ -0,0 +1,8 @@
+#ifndef __JOURNAL_DOT_H__
+#define __JOURNAL_DOT_H__
+
+extern void dump_journal(const char *journal);
+extern uint64_t find_journal_block(const char *journal, uint64_t *j_size);
+
+
+#endif
10 years, 1 month
gfs2-utils: master - gfs2-utils: Fix up some errors reported by clang
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=57f0e1b7...
Commit: 57f0e1b70dbd1de7aca9b2bdc09d49d28c25d888
Parent: 4b5eb22347c722ca5a2a3db898e3babce8225d7d
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Feb 22 02:37:44 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Feb 27 20:26:51 2014 +0000
gfs2-utils: Fix up some errors reported by clang
Clang's analyzer found some potential memory leaks, most of which in
reality could never manifest, but it highlighted some places where
malloc and memset were being used unnecessarily, so those have been
removed and replaced with calloc() or literal assignments.
There were also some cases of dead assignments and initialisations, and
uses of uninitialised variables which have also been fixed up.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/savemeta.c | 7 ++---
gfs2/fsck/inode_hash.c | 6 +---
gfs2/fsck/main.c | 2 +-
gfs2/fsck/pass2.c | 64 ++++++-----------------------------------------
gfs2/fsck/pass3.c | 22 ++--------------
gfs2/fsck/rgrepair.c | 12 +++------
gfs2/fsck/util.c | 21 ++++-----------
gfs2/libgfs2/gfs2l.c | 1 +
gfs2/libgfs2/rgrp.c | 4 +--
9 files changed, 29 insertions(+), 110 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index c38c5ac..676bc29 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -397,12 +397,12 @@ static int save_block(int fd, struct metafd *mfd, uint64_t blk)
*/
static void save_ea_block(struct metafd *mfd, struct gfs2_buffer_head *metabh)
{
- int i, e, ea_len = sbd.bsize;
+ int e;
struct gfs2_ea_header ea;
- for (e = sizeof(struct gfs2_meta_header); e < sbd.bsize; e += ea_len) {
+ for (e = sizeof(struct gfs2_meta_header); e < sbd.bsize; e += ea.ea_rec_len) {
uint64_t blk, *b;
- int charoff;
+ int charoff, i;
gfs2_ea_header_in(&ea, metabh->b_data + e);
for (i = 0; i < ea.ea_num_ptrs; i++) {
@@ -417,7 +417,6 @@ static void save_ea_block(struct metafd *mfd, struct gfs2_buffer_head *metabh)
}
if (!ea.ea_rec_len)
break;
- ea_len = ea.ea_rec_len;
}
}
diff --git a/gfs2/fsck/inode_hash.c b/gfs2/fsck/inode_hash.c
index d5a35ce..aca5e61 100644
--- a/gfs2/fsck/inode_hash.c
+++ b/gfs2/fsck/inode_hash.c
@@ -46,15 +46,11 @@ struct inode_info *inodetree_insert(struct gfs2_inum di_num)
return cur;
}
- data = malloc(sizeof(struct inode_info));
+ data = calloc(1, sizeof(struct inode_info));
if (!data) {
log_crit( _("Unable to allocate inode_info structure\n"));
return NULL;
}
- if (!memset(data, 0, sizeof(struct inode_info))) {
- log_crit( _("Error while zeroing inode_info structure\n"));
- return NULL;
- }
/* Add new node and rebalance tree. */
data->di_num.no_addr = di_num.no_addr;
data->di_num.no_formal_ino = di_num.no_formal_ino;
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index b4b1a03..346e580 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -154,7 +154,7 @@ static int check_statfs(struct gfs2_sbd *sdp)
struct osi_node *n, *next = NULL;
struct rgrp_tree *rgd;
struct gfs2_rindex *ri;
- struct gfs2_statfs_change sc;
+ struct gfs2_statfs_change sc = {0,};
char buf[sizeof(struct gfs2_statfs_change)];
int count;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 9fd5be2..c8c047e 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -1413,7 +1413,6 @@ static int check_hash_tbl(struct gfs2_inode *ip, uint64_t *tbl,
struct gfs2_buffer_head *lbh;
int factor;
uint32_t proper_start;
- uint32_t next_proper_start;
int anomaly;
lindex = 0;
@@ -1423,9 +1422,9 @@ static int check_hash_tbl(struct gfs2_inode *ip, uint64_t *tbl,
len = 1;
factor = 0;
leafblk = be64_to_cpu(tbl[lindex]);
- next_proper_start = lindex;
anomaly = 0;
while (lindex + (len << 1) - 1 < hsize) {
+ uint32_t next_proper_start;
if (be64_to_cpu(tbl[lindex + (len << 1) - 1]) !=
leafblk)
break;
@@ -1714,9 +1713,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
{
uint64_t iblock = 0, cur_blks;
struct dir_status ds = {0};
- char *filename;
- int filename_len;
- char tmp_name[256];
int error = 0;
log_info( _("Checking system directory inode '%s'\n"), dirname);
@@ -1761,30 +1757,12 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
log_err( _("No '.' entry found for %s directory.\n"), dirname);
if (query( _("Is it okay to add '.' entry? (y/n) "))) {
cur_blks = sysinode->i_di.di_blocks;
- sprintf(tmp_name, ".");
- filename_len = strlen(tmp_name); /* no trailing NULL */
- if (!(filename = malloc(sizeof(char) * filename_len))) {
- log_err( _("Unable to allocate name string\n"));
- stack;
- return -1;
- }
- if (!(memset(filename, 0, sizeof(char) *
- filename_len))) {
- log_err( _("Unable to zero name string\n"));
- stack;
- free(filename);
- return -1;
- }
- memcpy(filename, tmp_name, filename_len);
log_warn( _("Adding '.' entry\n"));
- error = dir_add(sysinode, filename, filename_len,
- &(sysinode->i_di.di_num),
- (sysinode->i_sbd->gfs1 ?
- GFS_FILE_DIR : DT_DIR));
+ error = dir_add(sysinode, ".", 1, &(sysinode->i_di.di_num),
+ (sysinode->i_sbd->gfs1 ? GFS_FILE_DIR : DT_DIR));
if (error) {
- log_err(_("Error adding directory %s: %s\n"),
- filename, strerror(errno));
- free(filename);
+ log_err(_("Error adding directory %s: %s\n"), "'.'",
+ strerror(errno));
return -errno;
}
if (cur_blks != sysinode->i_di.di_blocks)
@@ -1793,7 +1771,6 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
incr_link_count(sysinode->i_di.di_num, sysinode,
"sysinode \".\"");
ds.entry_count++;
- free(filename);
} else
log_err( _("The directory was not fixed.\n"));
}
@@ -1874,9 +1851,6 @@ int pass2(struct gfs2_sbd *sdp)
uint8_t q;
struct dir_status ds = {0};
struct gfs2_inode *ip;
- char *filename;
- int filename_len;
- char tmp_name[256];
int error = 0;
/* Check all the system directory inodes. */
@@ -2007,31 +1981,12 @@ int pass2(struct gfs2_sbd *sdp)
(unsigned long long)dirblk);
if (query( _("Is it okay to add '.' entry? (y/n) "))) {
- sprintf(tmp_name, ".");
- filename_len = strlen(tmp_name); /* no trailing
- NULL */
- if (!(filename = malloc(sizeof(char) *
- filename_len))) {
- log_err(_("Unable to allocate name\n"));
- stack;
- return FSCK_ERROR;
- }
- if (!memset(filename, 0, sizeof(char) *
- filename_len)) {
- log_err( _("Unable to zero name\n"));
- stack;
- return FSCK_ERROR;
- }
- memcpy(filename, tmp_name, filename_len);
-
cur_blks = ip->i_di.di_blocks;
- error = dir_add(ip, filename, filename_len,
- &(ip->i_di.di_num),
- (sdp->gfs1 ? GFS_FILE_DIR :
- DT_DIR));
+ error = dir_add(ip, ".", 1, &(ip->i_di.di_num),
+ (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
if (error) {
- log_err(_("Error adding directory %s: %s\n"),
- filename, strerror(errno));
+ log_err(_("Error adding directory %s: %s\n"), "'.'",
+ strerror(errno));
return -errno;
}
if (cur_blks != ip->i_di.di_blocks) {
@@ -2047,7 +2002,6 @@ int pass2(struct gfs2_sbd *sdp)
incr_link_count(ip->i_di.di_num, ip,
_("\". (itself)\""));
ds.entry_count++;
- free(filename);
log_err( _("The directory was fixed.\n"));
} else {
log_err( _("The directory was not fixed.\n"));
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 4894d8c..6448da3 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -19,8 +19,9 @@
static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
uint64_t olddotdot, uint64_t block)
{
- char *filename;
- int filename_len, err;
+ const char *filename = "..";
+ int filename_len = 2;
+ int err;
struct gfs2_inode *ip, *pip;
uint64_t cur_blks;
@@ -33,22 +34,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
* '..' entry for this directory in
* this case? */
- 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);
- 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);
- stack;
- return -1;
- }
- memcpy(filename, "..", filename_len);
if (gfs2_dirent_del(ip, filename, filename_len))
log_warn( _("Unable to remove \"..\" directory entry.\n"));
else
@@ -72,7 +57,6 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
incr_link_count(pip->i_di.di_num, ip, _("new \"..\""));
fsck_inode_put(&ip);
fsck_inode_put(&pip);
- free(filename);
return 0;
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 2c1d613..4fdbcf7 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -327,7 +327,6 @@ static uint64_t find_next_rgrp_dist(struct gfs2_sbd *sdp, uint64_t blk,
rgrp_dist++;
}
if (found) {
- block = next_block;
log_info( _("rgrp found at 0x%llx, length=%d, "
"used=%llu, free=%d\n"),
prevrgd->ri.ri_addr, length,
@@ -442,7 +441,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs,
uint64_t first_rg_dist, initial_first_rg_dist;
struct rgrp_tree *calc_rgd, *prev_rgd;
int number_of_rgs, rgi;
- int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd;
+ int rg_was_fnd = FALSE, corrupt_rgs = 0;
sdp->rgcalc.osi_node = NULL;
initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1;
@@ -489,13 +488,10 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs,
/* ------------------------------------------------ */
/* Now go through and count the bitmaps for this RG */
/* ------------------------------------------------ */
- bitmap_was_fnd = FALSE;
- for (fwd_block = blk + 1;
- fwd_block < sdp->device.length;
- fwd_block++) {
+ for (fwd_block = blk + 1; fwd_block < sdp->device.length; fwd_block++) {
+ int bitmap_was_fnd;
bh = bread(sdp, fwd_block);
- bitmap_was_fnd =
- (!gfs2_check_meta(bh, GFS2_METATYPE_RB));
+ bitmap_was_fnd = !gfs2_check_meta(bh, GFS2_METATYPE_RB);
brelse(bh);
if (bitmap_was_fnd) /* if a bitmap */
calc_rgd->ri.ri_length++;
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 3e3050f..f8ccb3e 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -365,14 +365,9 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
/* Check for the inode on the invalid inode reference list. */
uint8_t q;
- if (!(id = malloc(sizeof(*id)))) {
- log_crit( _("Unable to allocate "
- "inode_with_dups structure\n"));
- return meta_error;
- }
- if (!(memset(id, 0, sizeof(*id)))) {
- log_crit( _("Unable to zero inode_with_dups "
- "structure\n"));
+ id = calloc(1, sizeof(*id));
+ if (!id) {
+ log_crit( _("Unable to allocate inode_with_dups structure\n"));
return meta_error;
}
id->block_no = ip->i_di.di_num.no_addr;
@@ -429,15 +424,11 @@ struct dir_info *dirtree_insert(struct gfs2_inum inum)
return cur;
}
- data = malloc(sizeof(struct dir_info));
+ data = calloc(1, sizeof(struct dir_info));
if (!data) {
log_crit( _("Unable to allocate dir_info structure\n"));
return NULL;
}
- if (!memset(data, 0, sizeof(struct dir_info))) {
- log_crit( _("Error while zeroing dir_info structure\n"));
- return NULL;
- }
/* Add new node and rebalance tree. */
data->dinode.no_addr = inum.no_addr;
data->dinode.no_formal_ino = inum.no_formal_ino;
@@ -555,8 +546,8 @@ struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
struct gfs2_bmap *il;
*addl_mem_needed = 0L;
- il = malloc(sizeof(*il));
- if (!il || !memset(il, 0, sizeof(*il)))
+ il = calloc(1, sizeof(*il));
+ if (!il)
return NULL;
if (gfs2_blockmap_create(il, size)) {
diff --git a/gfs2/libgfs2/gfs2l.c b/gfs2/libgfs2/gfs2l.c
index e58c827..eda9531 100644
--- a/gfs2/libgfs2/gfs2l.c
+++ b/gfs2/libgfs2/gfs2l.c
@@ -172,6 +172,7 @@ int main(int argc, char *argv[])
ret = lgfs2_lang_parsef(state, opts.src);
if (ret != 0) {
fprintf(stderr, "Parse failed\n");
+ free(opts.fspath);
return ret;
}
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 8fe7b6d..0752772 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -182,11 +182,9 @@ struct rgrp_tree *rgrp_insert(struct osi_root *rgtree, uint64_t rgblock)
return cur;
}
- data = malloc(sizeof(struct rgrp_tree));
+ data = calloc(1, sizeof(struct rgrp_tree));
if (!data)
return NULL;
- if (!memset(data, 0, sizeof(struct rgrp_tree)))
- return NULL;
/* Add new node and rebalance tree. */
data->ri.ri_addr = rgblock;
osi_link_node(&data->node, parent, newn);
10 years, 1 month
gfs2-utils: master - libgfs2: Remove another exit() call
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=4b5eb223...
Commit: 4b5eb22347c722ca5a2a3db898e3babce8225d7d
Parent: 638f3cd5b541dc5952651d696e26cd8a8abd27c1
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Feb 21 22:10:14 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Feb 27 20:26:43 2014 +0000
libgfs2: Remove another exit() call
gfs2_get_leaf_nr was another one of those libgfs2 functions which called
exit instead of returning an error value. This updates it with a new
function which does so.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/savemeta.c | 6 +++++-
gfs2/fsck/pass2.c | 5 ++++-
gfs2/libgfs2/fs_ops.c | 35 ++++++++++++++++++-----------------
gfs2/libgfs2/libgfs2.h | 3 +--
4 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index b4c85d6..c38c5ac 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -543,7 +543,11 @@ static void save_inode_data(struct metafd *mfd)
int li;
for (li = 0; li < (1 << inode->i_di.di_depth); li++) {
- gfs2_get_leaf_nr(inode, li, &leaf_no);
+ if (!lgfs2_get_leaf_ptr(inode, li, &leaf_no)) {
+ fprintf(stderr, "Could not read leaf index %d in dinode %"PRIu64"\n", li,
+ (uint64_t)inode->i_di.di_num.no_addr);
+ exit(-1);
+ }
if (leaf_no == old_leaf ||
gfs2_check_range(&sbd, leaf_no) != 0)
continue;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index d3b56fc..9fd5be2 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -369,7 +369,10 @@ static int wrong_leaf(struct gfs2_inode *ip, struct gfs2_inum *entry,
de->de_type) == 0) {
log_err(_("The misplaced directory entry was moved to a "
"valid leaf block.\n"));
- gfs2_get_leaf_nr(ip, hash_index, &real_leaf);
+ if (!lgfs2_get_leaf_ptr(ip, hash_index, &real_leaf)) {
+ log_err(_("Could not read leaf %d in dinode %"PRIu64": %s\n"), hash_index,
+ (uint64_t)ip->i_di.di_num.no_addr, strerror(errno));
+ }
if (real_leaf != planned_leaf) {
log_err(_("The planned leaf was split. The new leaf "
"is: %llu (0x%llx). di_blocks=%llu\n"),
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index f59f014..198f6eb 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -25,7 +25,7 @@ static __inline__ uint64_t *metapointer(struct gfs2_buffer_head *bh,
}
/* Detect directory is a stuffed inode */
-static int inode_is_stuffed(struct gfs2_inode *ip)
+static int inode_is_stuffed(const struct gfs2_inode *ip)
{
return !ip->i_di.di_height;
}
@@ -819,20 +819,15 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
prev->de_rec_len = cpu_to_be16(prev_rec_len);
}
-void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
- uint64_t *leaf_out)
+int lgfs2_get_leaf_ptr(struct gfs2_inode *dip, const uint32_t lindex, uint64_t *ptr)
{
uint64_t leaf_no;
- int count;
-
- count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
- sizeof(uint64_t));
- if (count != sizeof(uint64_t)) {
- fprintf(stderr, "gfs2_get_leaf_nr: Bad internal read.\n");
- exit(1);
- }
+ int count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t), sizeof(uint64_t));
+ if (count != sizeof(uint64_t))
+ return -1;
- *leaf_out = be64_to_cpu(leaf_no);
+ *ptr = be64_to_cpu(leaf_no);
+ return 0;
}
void dir_split_leaf(struct gfs2_inode *dip, uint32_t start, uint64_t leaf_no,
@@ -1034,13 +1029,15 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
* Returns: 0 on success, error code otherwise
*/
-static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
- struct gfs2_buffer_head **bh_out)
+static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex, struct gfs2_buffer_head **bh_out)
{
uint64_t leaf_no;
- gfs2_get_leaf_nr(dip, lindex, &leaf_no);
+ if (lgfs2_get_leaf_ptr(dip, lindex, &leaf_no) != 0)
+ return -1;
*bh_out = bread(dip->i_sbd, leaf_no);
+ if (*bh_out == NULL)
+ return -1;
return 0;
}
@@ -1085,7 +1082,9 @@ restart:
else
lindex = 0;
- gfs2_get_leaf_nr(dip, lindex, &leaf_no);
+ err = lgfs2_get_leaf_ptr(dip, lindex, &leaf_no);
+ if (err)
+ return err;
for (;;) {
bh = bread(dip->i_sbd, leaf_no);
@@ -1630,7 +1629,9 @@ static int dir_e_del(struct gfs2_inode *dip, const char *filename, int len)
lindex = (1 << (dip->i_di.di_depth))-1;
for(; (lindex >= 0) && !found; lindex--){
- gfs2_get_leaf_nr(dip, lindex, &leaf_no);
+ error = lgfs2_get_leaf_ptr(dip, lindex, &leaf_no);
+ if (error)
+ return error;
while(leaf_no && !found){
bh = bread(dip->i_sbd, leaf_no);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 6372128..6248e4b 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -479,8 +479,7 @@ 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,
- uint64_t *leaf_out);
+extern int lgfs2_get_leaf_ptr(struct gfs2_inode *dip, uint32_t index, uint64_t *ptr) __attribute__((warn_unused_result));
extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t start,
uint64_t leaf_no, struct gfs2_buffer_head *obh);
extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
10 years, 1 month
fence-agents: master - testing: Extend tests of using invalid keys for "options"
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=a6f697...
Commit: a6f6979c26b474ac0ef2695a39e45fcf26fa57f2
Parent: f1ee9c18423a1c65ccab4650601bd0146f200ef3
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Feb 27 14:52:08 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Sun Mar 2 14:57:33 2014 +0100
testing: Extend tests of using invalid keys for "options"
Previously only keys that match [--.*] where considered because [-.*] should not be used in
v4.x at all. Currently, tests where extended to find also these problems.
Relevant: rhbz#1018780
---
fence/agents/lib/check_used_options.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fence/agents/lib/check_used_options.py b/fence/agents/lib/check_used_options.py
index 2d75756..86dc35f 100755
--- a/fence/agents/lib/check_used_options.py
+++ b/fence/agents/lib/check_used_options.py
@@ -38,8 +38,8 @@ def main():
## check if all options are defined
agent_file = open(agent)
- option_use_re = re.compile("options\[\"(--[^\"]*)\"\]")
- option_has_re = re.compile("options.has_key\(\"(--[^\"]*)\"\)")
+ option_use_re = re.compile("options\[\"(-[^\"]*)\"\]")
+ option_has_re = re.compile("options.has_key\(\"(-[^\"]*)\"\)")
counter = 0
without_errors = True
10 years, 2 months