cluster: RHEL510 - fsck.gfs2: Combine block and char device inode types
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1323d19acf8...
Commit: 1323d19acf8bfebd71050fa68431be073487f97f
Parent: c0594820ac0b54599bfa86e31f0c2a6748a85313
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 11 09:16:33 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2: Combine block and char device inode types
This patch combines the block and character device block designations.
Devices are now treated equally as one block type, which is fine.
This buys back a block type in the block map which may be used later
for gfs1 support. It also eliminates the rgrp block designation,
which is not needed: We only need to know whether rgrp blocks are
"in use" or not. In fact, the rgrp blocks have special processing
anyway and special code (function valid_block) to check for overlaps.
rhbz#877150
---
gfs2/fsck/pass1.c | 6 +++---
gfs2/fsck/pass2.c | 8 ++------
gfs2/fsck/pass3.c | 5 ++---
gfs2/fsck/pass4.c | 3 +--
gfs2/fsck/pass5.c | 4 +---
gfs2/fsck/util.h | 50 +++++++++++++++++++++++++-------------------------
6 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index fdd8e9f..f92e29e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1168,12 +1168,12 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
break;
case S_IFBLK:
if (fsck_blockmap_set(ip, block, _("block device"),
- gfs2_inode_blk))
+ gfs2_inode_device))
goto bad_dinode;
break;
case S_IFCHR:
if (fsck_blockmap_set(ip, block, _("character device"),
- gfs2_inode_chr))
+ gfs2_inode_device))
goto bad_dinode;
break;
case S_IFIFO:
@@ -1564,7 +1564,7 @@ int pass1(struct gfs2_sbd *sdp)
"is now marked as 'rgrp data'\n"),
rgd->ri.ri_addr + i, rgd->ri.ri_addr + i);
if (gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
- gfs2_meta_rgrp)) {
+ gfs2_indir_blk)) {
stack;
return FSCK_ERROR;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index deaa883..3c5bda1 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -147,12 +147,8 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
if (de_type != DT_LNK)
return 1;
break;
- case gfs2_inode_blk:
- if (de_type != DT_BLK)
- return 1;
- break;
- case gfs2_inode_chr:
- if (de_type != DT_CHR)
+ case gfs2_inode_device:
+ if (de_type != DT_BLK && de_type != DT_CHR)
return 1;
break;
case gfs2_inode_fifo:
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 4ff1fc7..db59191 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -253,9 +253,8 @@ int pass3(struct gfs2_sbd *sdp)
log_err( _("Unlinked directory with bad block remains\n"));
}
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) {
+ q != gfs2_inode_lnk && q != gfs2_inode_device &&
+ q != gfs2_inode_fifo && q != gfs2_inode_sock) {
log_err( _("Unlinked block marked as an inode "
"is not an inode\n"));
if (!query(_("Clear the unlinked block?"
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 573a90a..355b88a 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -96,8 +96,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
if (q != gfs2_inode_dir &&
q != gfs2_inode_file &&
q != gfs2_inode_lnk &&
- q != gfs2_inode_blk &&
- q != gfs2_inode_chr &&
+ q != gfs2_inode_device &&
q != gfs2_inode_fifo &&
q != gfs2_inode_sock) {
log_err( _("Unlinked block %lld (0x%llx) "
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index cc11b6b..fc2eb80 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -40,8 +40,7 @@ static int convert_mark(uint8_t q, uint32_t *count)
case gfs2_inode_dir:
case gfs2_inode_file:
case gfs2_inode_lnk:
- case gfs2_inode_blk:
- case gfs2_inode_chr:
+ case gfs2_inode_device:
case gfs2_inode_fifo:
case gfs2_inode_sock:
count[1]++;
@@ -49,7 +48,6 @@ static int convert_mark(uint8_t q, uint32_t *count)
case gfs2_indir_blk:
case gfs2_leaf_blk:
- case gfs2_meta_rgrp:
case gfs2_meta_eattr:
count[2]++;
return GFS2_BLKST_USED;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 8454ffa..8bd1914 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -56,15 +56,15 @@ enum gfs2_mark_block {
gfs2_inode_file = (0x4),
gfs2_inode_lnk = (0x5),
- gfs2_inode_blk = (0x6),
- gfs2_inode_chr = (0x7),
+ gfs2_inode_device = (0x6),
+
gfs2_inode_fifo = (0x8),
gfs2_inode_sock = (0x9),
gfs2_inode_invalid = (0xa),
gfs2_meta_inval = (0xb),
gfs2_leaf_blk = (0xc),
- gfs2_meta_rgrp = (0xd),
+
gfs2_meta_eattr = (0xe),
gfs2_bad_block = (0xf), /* Contains at least one bad block */
@@ -80,15 +80,15 @@ static const inline char *block_type_string(uint8_t q)
"file",
"symlink",
- "block device",
- "char device",
+ "device",
+ "",
"fifo",
"socket",
"invalid inode",
"invalid meta",
"dir leaf",
- "rgrp meta",
+ "",
"eattribute",
"bad"};
@@ -102,25 +102,25 @@ static const inline char *block_type_string(uint8_t q)
static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
{
static int bitmap_states[16] = {
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_FREE,
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
-
- GFS2_BLKST_USED
+ GFS2_BLKST_FREE, /* free */
+ GFS2_BLKST_USED, /* data */
+ GFS2_BLKST_USED, /* indirect data or rgrp meta*/
+ GFS2_BLKST_DINODE, /* directory */
+ GFS2_BLKST_DINODE, /* file */
+
+ GFS2_BLKST_DINODE, /* symlink */
+ GFS2_BLKST_DINODE, /* block or char device */
+ GFS2_BLKST_USED, /* reserved */
+ GFS2_BLKST_DINODE, /* fifo */
+ GFS2_BLKST_DINODE, /* socket */
+
+ GFS2_BLKST_FREE, /* invalid inode */
+ GFS2_BLKST_FREE, /* invalid meta */
+ GFS2_BLKST_USED, /* dir leaf */
+ GFS2_BLKST_UNLINKED, /* unused */
+ GFS2_BLKST_USED, /* eattribute */
+
+ GFS2_BLKST_USED, /* bad */
};
return bitmap_states[m];
}
11 years, 2 months
cluster: RHEL510 - libgfs2: move block_map functions to fsck.gfs2
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=c0594820ac0...
Commit: c0594820ac0b54599bfa86e31f0c2a6748a85313
Parent: 0c09286131ae51005409f09f975705eb455234b6
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 13:12:54 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
libgfs2: move block_map functions to fsck.gfs2
Since the "blockmap" functions were only used in fsck.gfs2 they don't
have a place in libgfs2. This patch moves them to fsck.gfs2.
rhbz#877150
---
gfs2/fsck/metawalk.h | 2 +
gfs2/fsck/util.c | 73 +++++++++++++++++++++++++++++++++++++++
gfs2/fsck/util.h | 84 +++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/block_list.c | 72 --------------------------------------
gfs2/libgfs2/libgfs2.h | 82 -------------------------------------------
5 files changed, 159 insertions(+), 154 deletions(-)
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 854b3a7..7bebf1c 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -16,6 +16,8 @@
#define DIR_LINEAR 1
#define DIR_EXHASH 2
+#include "util.h"
+
struct metawalk_fxns;
extern int check_inode_eattr(struct gfs2_inode *ip,
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 031da42..bfcd139 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <libintl.h>
#include <ctype.h>
+#include <errno.h>
#define _(String) gettext(String)
#include "libgfs2.h"
@@ -394,3 +395,75 @@ void dirtree_delete(struct dir_info *b)
osi_erase(&b->node, &dirtree);
free(b);
}
+
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
+{
+ bmap->size = size;
+
+ /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
+ * must be 1-based */
+ bmap->mapsize = BLOCKMAP_SIZE4(size);
+
+ if (!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
+ return -ENOMEM;
+ if (!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
+ free(bmap->map);
+ bmap->map = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
+{
+ if (bmap->map)
+ free(bmap->map);
+ bmap->size = 0;
+ bmap->mapsize = 0;
+}
+
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
+{
+ struct gfs2_bmap *il;
+
+ *addl_mem_needed = 0L;
+ il = malloc(sizeof(*il));
+ if (!il || !memset(il, 0, sizeof(*il)))
+ return NULL;
+
+ if (gfs2_blockmap_create(il, size)) {
+ *addl_mem_needed = il->mapsize;
+ free(il);
+ il = NULL;
+ }
+ osi_list_init(&sdp->eattr_blocks.list);
+ return il;
+}
+
+int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
+ enum gfs2_mark_block mark)
+{
+ static unsigned char *byte;
+ static uint64_t b;
+
+ if (bblock > bmap->size)
+ return -1;
+
+ byte = bmap->map + BLOCKMAP_SIZE4(bblock);
+ b = BLOCKMAP_BYTE_OFFSET4(bblock);
+ *byte &= ~(BLOCKMAP_MASK4 << b);
+ *byte |= (mark & BLOCKMAP_MASK4) << b;
+ return 0;
+}
+
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
+{
+ if (il) {
+ gfs2_blockmap_destroy(il);
+ free(il);
+ il = NULL;
+ }
+ gfs2_special_free(&sdp->eattr_blocks);
+ return il;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 5b05081..8454ffa 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -47,4 +47,88 @@ static inline uint8_t block_type(uint64_t bblock)
return btype;
}
+/* blockmap declarations and functions */
+enum gfs2_mark_block {
+ gfs2_block_free = (0x0),
+ gfs2_block_used = (0x1),
+ gfs2_indir_blk = (0x2),
+ gfs2_inode_dir = (0x3),
+ gfs2_inode_file = (0x4),
+
+ gfs2_inode_lnk = (0x5),
+ gfs2_inode_blk = (0x6),
+ gfs2_inode_chr = (0x7),
+ gfs2_inode_fifo = (0x8),
+ gfs2_inode_sock = (0x9),
+
+ gfs2_inode_invalid = (0xa),
+ gfs2_meta_inval = (0xb),
+ gfs2_leaf_blk = (0xc),
+ gfs2_meta_rgrp = (0xd),
+ gfs2_meta_eattr = (0xe),
+
+ gfs2_bad_block = (0xf), /* Contains at least one bad block */
+};
+
+static const inline char *block_type_string(uint8_t q)
+{
+ const char *blktyp[] = {
+ "free",
+ "data",
+ "indirect data",
+ "directory",
+ "file",
+
+ "symlink",
+ "block device",
+ "char device",
+ "fifo",
+ "socket",
+
+ "invalid inode",
+ "invalid meta",
+ "dir leaf",
+ "rgrp meta",
+ "eattribute",
+
+ "bad"};
+ if (q < 16)
+ return (blktyp[q]);
+ return blktyp[15];
+}
+
+/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
+ invalid or bad are considered metadata until actually freed. */
+static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
+{
+ static int bitmap_states[16] = {
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+
+ GFS2_BLKST_USED
+ };
+ return bitmap_states[m];
+}
+
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
+extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
+ enum gfs2_mark_block mark);
+
#endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 4ec6834..a7e28f3 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -20,51 +20,6 @@
#include "libgfs2.h"
-static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
-{
- bmap->size = size;
-
- /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
- * must be 1-based */
- bmap->mapsize = BLOCKMAP_SIZE4(size);
-
- if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
- return -ENOMEM;
- if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
- free(bmap->map);
- bmap->map = NULL;
- return -ENOMEM;
- }
- return 0;
-}
-
-static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
-{
- if(bmap->map)
- free(bmap->map);
- bmap->size = 0;
- bmap->mapsize = 0;
-}
-
-struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
- uint64_t *addl_mem_needed)
-{
- struct gfs2_bmap *il;
-
- *addl_mem_needed = 0L;
- il = malloc(sizeof(*il));
- if (!il || !memset(il, 0, sizeof(*il)))
- return NULL;
-
- if(gfs2_blockmap_create(il, size)) {
- *addl_mem_needed = il->mapsize;
- free(il);
- il = NULL;
- }
- osi_list_init(&sdp->eattr_blocks.list);
- return il;
-}
-
void gfs2_special_free(struct special_blocks *blist)
{
struct special_blocks *f;
@@ -120,30 +75,3 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
free(b);
}
}
-
-int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
- enum gfs2_mark_block mark)
-{
- static unsigned char *byte;
- static uint64_t b;
-
- if(bblock > bmap->size)
- return -1;
-
- byte = bmap->map + BLOCKMAP_SIZE4(bblock);
- b = BLOCKMAP_BYTE_OFFSET4(bblock);
- *byte &= ~(BLOCKMAP_MASK4 << b);
- *byte |= (mark & BLOCKMAP_MASK4) << b;
- return 0;
-}
-
-void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
-{
- if(il) {
- gfs2_blockmap_destroy(il);
- free(il);
- il = NULL;
- }
- gfs2_special_free(&sdp->eattr_blocks);
- return il;
-}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 2acffcf..2c2bce5 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -264,94 +264,12 @@ uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap);
/* block_list.c */
-enum gfs2_mark_block {
- gfs2_block_free = (0x0),
- gfs2_block_used = (0x1),
- gfs2_indir_blk = (0x2),
- gfs2_inode_dir = (0x3),
- gfs2_inode_file = (0x4),
-
- gfs2_inode_lnk = (0x5),
- gfs2_inode_blk = (0x6),
- gfs2_inode_chr = (0x7),
- gfs2_inode_fifo = (0x8),
- gfs2_inode_sock = (0x9),
-
- gfs2_inode_invalid = (0xa),
- gfs2_meta_inval = (0xb),
- gfs2_leaf_blk = (0xc),
- gfs2_meta_rgrp = (0xd),
- gfs2_meta_eattr = (0xe),
-
- gfs2_bad_block = (0xf), /* Contains at least one bad block */
-};
-
-static const inline char *block_type_string(uint8_t q)
-{
- const char *blktyp[] = {
- "free",
- "data",
- "indirect data",
- "directory",
- "file",
-
- "symlink",
- "block device",
- "char device",
- "fifo",
- "socket",
-
- "invalid inode",
- "invalid meta",
- "dir leaf",
- "rgrp meta",
- "eattribute",
-
- "bad"};
- if (q < 16)
- return (blktyp[q]);
- return blktyp[15];
-}
-
-/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
- invalid or bad are considered metadata until actually freed. */
-static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
-{
- static int bitmap_states[16] = {
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_FREE,
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
-
- GFS2_BLKST_USED
- };
- return bitmap_states[m];
-}
-
-extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
- uint64_t *addl_mem_needed);
extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
extern void gfs2_special_add(struct special_blocks *blocklist, uint64_t block);
extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
extern void gfs2_special_free(struct special_blocks *blist);
-extern int gfs2_blockmap_set(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 void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp,
11 years, 2 months
cluster: RHEL510 - fsck.gfs2: Add find_remove_dup, free_block_if_notdup
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=0c09286131a...
Commit: 0c09286131ae51005409f09f975705eb455234b6
Parent: 1aa0537d3cbc2ede5dc994b356851952c762432f
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 15:29:35 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2: Add find_remove_dup, free_block_if_notdup
This patch adds a couple new functions to util.c: find_remove_dup
and free_block_if_notdup. This is a centralized function that
is used to remove a duplicate reference. Each reference needs to be
removed to determine when all duplicate references have been resolved.
The object is to get down to one reference, so we can set the proper
type based on the remaining reference. However, if the very last
reference is deleted as well, the block may be freed.
These functions present one consistent way to do all this rather than
before when the it wasn't very consistent and various bitmap
inaccuracies were sometimes left in the file system.
rhbz#877150
---
gfs2/fsck/metawalk.c | 64 ++++++++++++++++++++++++-------
gfs2/fsck/metawalk.h | 4 ++
gfs2/fsck/pass1.c | 34 +----------------
gfs2/fsck/util.c | 101 ++++++++++++++++++++++++++-----------------------
gfs2/fsck/util.h | 4 ++
5 files changed, 113 insertions(+), 94 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 5c09e85..1c06253 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -837,6 +837,54 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
}
/**
+ * find_remove_dup - find out if this is a duplicate ref. If so, remove it.
+ * Returns: 0 if not a duplicate reference, 1 if it is.
+ */
+int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
+{
+ struct duptree *d;
+ struct inode_with_dups *id;
+
+ d = dupfind(block);
+ if (!d)
+ return 0;
+
+ /* remove the inode reference id structure for this reference. */
+ id = find_dup_ref_inode(d, ip);
+ if (!id)
+ return 0;
+
+ dup_listent_delete(id);
+ log_err( _("Removing duplicate status of block %llu (0x%llx) "
+ "referenced as %s by dinode %llu (0x%llx)\n"),
+ (unsigned long long)block, (unsigned long long)block,
+ btype, (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ d->refs--; /* one less reference */
+ if (d->refs == 1) {
+ log_info( _("This leaves only one reference: it's "
+ "no longer a duplicate.\n"));
+ dup_delete(d); /* not duplicate now */
+ } else
+ log_info( _("%d block reference(s) remain.\n"),
+ d->refs);
+ return 1; /* but the original ref still exists so do not free it. */
+}
+
+/**
+ * free_block_if_notdup - free blocks associated with an inode, but if it's a
+ * duplicate, just remove that designation instead.
+ * Returns: 0 if the block was freed, 1 if a duplicate reference was removed
+ */
+int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype)
+{
+ if (!find_remove_dup(ip, block, btype))
+ fsck_blockmap_set(ip, block, btype, gfs2_block_free);
+ return 0;
+}
+
+/**
* delete_block_if_notdup - delete blocks associated with an inode
*
* Ignore blocks that are already marked free.
@@ -848,7 +896,6 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
const char *btype, void *private)
{
uint8_t q;
- struct duptree *d;
if (!valid_block(ip->i_sbd, block))
return -EFAULT;
@@ -863,20 +910,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr);
return 0;
}
- d = dupfind(block);
- if (d) {
- log_info( _("Removing duplicate reference %d "
- "to block %lld (0x%llx).\n"), d->refs,
- (unsigned long long)block,
- (unsigned long long)block);
- d->refs--; /* one less reference */
- if (d->refs == 1) /* If down to the last reference */
- dup_delete(d); /* not duplicate now */
- return 1; /* but the original ref still exists
- so return (do not free it). */
- }
- fsck_blockmap_set(ip, block, btype, gfs2_block_free);
- return 0;
+ return free_block_if_notdup(ip, block, btype);
}
/**
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 72ea672..854b3a7 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -47,6 +47,10 @@ extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
extern struct duptree *dupfind(uint64_t block);
extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
uint64_t block);
+extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype);
+extern int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ee81436..fdd8e9f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -453,7 +453,6 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h,
void *private)
{
- struct duptree *d;
int found_dup = 0, iblk_type;
struct gfs2_buffer_head *nbh;
struct block_count *bc = (struct block_count *)private;
@@ -470,20 +469,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
else
iblk_type = GFS2_METATYPE_IN;
- d = dupfind(block);
- if (d) {
- log_err( _("Reversing duplicate status of block %llu (0x%llx) "
- "referenced as metadata in indirect block for "
- "dinode %llu (0x%llx)\n"),
- (unsigned long long)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);
- d->refs--; /* one less reference */
- if (d->refs == 1)
- dup_delete(d);
- found_dup = 1;
- }
+ found_dup = find_remove_dup(ip, block, _("Metadata"));
nbh = bread(ip->i_sbd, block);
if (gfs2_check_meta(nbh, iblk_type)) {
@@ -563,7 +549,6 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
void *private)
{
- struct duptree *d;
struct block_count *bc = (struct block_count *) private;
if (!valid_block(ip->i_sbd, block)) {
@@ -575,23 +560,8 @@ static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
gfs2_block_free);
return 1;
}
- d = dupfind(block);
- if (d) {
- log_err( _("Reversing duplicate status of block %llu (0x%llx) "
- "referenced as data by dinode %llu (0x%llx)\n"),
- (unsigned long long)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);
- d->refs--; /* one less reference */
- if (d->refs == 1)
- dup_delete(d);
- bc->data_count--;
- return 1;
- }
- fsck_blockmap_set(ip, block, _("data"), gfs2_block_free);
bc->data_count--;
- return 0;
+ return free_block_if_notdup(ip, block, _("data"));
}
static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc)
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 7094e26..031da42 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -199,6 +199,30 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
return data;
}
+/**
+ * find_dup_ref_inode - find a duplicate reference inode entry for an inode
+ */
+struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+ struct gfs2_inode *ip)
+{
+ osi_list_t *ref;
+ struct inode_with_dups *id;
+
+ osi_list_foreach(ref, &dt->ref_invinode_list) {
+ id = osi_list_entry(ref, struct inode_with_dups, list);
+
+ if (id->block_no == ip->i_di.di_num.no_addr)
+ return id;
+ }
+ osi_list_foreach(ref, &dt->ref_inode_list) {
+ id = osi_list_entry(ref, struct inode_with_dups, list);
+
+ if (id->block_no == ip->i_di.di_num.no_addr)
+ return id;
+ }
+ return NULL;
+}
+
/*
* add_duplicate_ref - Add a duplicate reference to the duplicates tree list
* A new element of the tree will be created as needed
@@ -207,15 +231,19 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
* So we need to recreate the duplicate reference structure if it's not there.
* Later, in pass1b, it has to go back through the file system
* and figure out those original references in order to resolve them.
+ *
+ * first - if 1, we're being called from pass1b, in which case we're trying
+ * to find the first reference to this block. If 0, we're being
+ * called from pass1, which is the second reference, which determined
+ * it was a duplicate..
*/
int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
enum dup_ref_type reftype, int first, int inode_valid)
{
- osi_list_t *ref;
- struct inode_with_dups *id, *found_id;
+ struct inode_with_dups *id;
struct duptree *dt;
- if (!valid_block(ip->i_sbd, block) != 0)
+ if (!valid_block(ip->i_sbd, block))
return 0;
/* If this is not the first reference (i.e. all calls from pass1) we
need to create the duplicate reference. If this is pass1b, we want
@@ -235,65 +263,42 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
reference, we don't want to increment the reference count because
it's already accounted for. */
if (first) {
- if (!dt->first_ref_found) {
- dt->first_ref_found = 1;
- dups_found_first++; /* We found another first ref. */
- }
+ dt->first_ref_found = 1;
+ dups_found_first++; /* We found another first ref. */
} else {
dt->refs++;
}
- /* Check for a previous reference to this duplicate on the "invalid
- inode" reference list. */
- found_id = NULL;
- osi_list_foreach(ref, &dt->ref_invinode_list) {
- id = osi_list_entry(ref, struct inode_with_dups, list);
-
- if (id->block_no == ip->i_di.di_num.no_addr) {
- found_id = id;
- break;
- }
- }
- if (found_id == NULL) {
- osi_list_foreach(ref, &dt->ref_inode_list) {
- id = osi_list_entry(ref, struct inode_with_dups, list);
-
- if (id->block_no == ip->i_di.di_num.no_addr) {
- found_id = id;
- break;
- }
- }
- }
- if (found_id == NULL) {
+ /* Check for a previous reference to this duplicate */
+ id = find_dup_ref_inode(dt, ip);
+ if (id == NULL) {
/* Check for the inode on the invalid inode reference list. */
uint8_t q;
- if (!(found_id = malloc(sizeof(*found_id)))) {
+ if (!(id = malloc(sizeof(*id)))) {
log_crit( _("Unable to allocate "
"inode_with_dups structure\n"));
return -1;
}
- if (!(memset(found_id, 0, sizeof(*found_id)))) {
+ if (!(memset(id, 0, sizeof(*id)))) {
log_crit( _("Unable to zero inode_with_dups "
"structure\n"));
return -1;
}
- found_id->block_no = ip->i_di.di_num.no_addr;
+ id->block_no = ip->i_di.di_num.no_addr;
q = block_type(ip->i_di.di_num.no_addr);
/* If it's an invalid dinode, put it first on the invalid
inode reference list otherwise put it on the normal list. */
if (!inode_valid || q == gfs2_inode_invalid)
- osi_list_add_prev(&found_id->list,
- &dt->ref_invinode_list);
+ osi_list_add_prev(&id->list, &dt->ref_invinode_list);
else
- osi_list_add_prev(&found_id->list,
- &dt->ref_inode_list);
+ osi_list_add_prev(&id->list, &dt->ref_inode_list);
}
- found_id->reftypecount[reftype]++;
- found_id->dup_count++;
+ id->reftypecount[reftype]++;
+ id->dup_count++;
log_info( _("Found %d reference(s) to block %llu"
" (0x%llx) as %s in inode #%llu (0x%llx)\n"),
- found_id->dup_count, (unsigned long long)block,
+ id->dup_count, (unsigned long long)block,
(unsigned long long)block, reftypes[reftype],
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
@@ -357,6 +362,14 @@ struct dir_info *dirtree_find(uint64_t block)
return NULL;
}
+void dup_listent_delete(struct inode_with_dups *id)
+{
+ if (id->name)
+ free(id->name);
+ osi_list_del(&id->list);
+ free(id);
+}
+
void dup_delete(struct duptree *b)
{
struct inode_with_dups *id;
@@ -365,18 +378,12 @@ void dup_delete(struct duptree *b)
while (!osi_list_empty(&b->ref_invinode_list)) {
tmp = (&b->ref_invinode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->name)
- free(id->name);
- osi_list_del(&id->list);
- free(id);
+ dup_listent_delete(id);
}
while (!osi_list_empty(&b->ref_inode_list)) {
tmp = (&b->ref_inode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->name)
- free(id->name);
- osi_list_del(&id->list);
- free(id);
+ dup_listent_delete(id);
}
osi_erase(&b->node, &dup_blocks);
free(b);
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 2c46e09..5b05081 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -29,6 +29,10 @@ void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
void warm_fuzzy_stuff(uint64_t block);
int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
enum dup_ref_type reftype, int first, int inode_valid);
+extern struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+ struct gfs2_inode *ip);
+extern void dup_listent_delete(struct inode_with_dups *id);
+
extern const char *reftypes[3];
static inline uint8_t block_type(uint64_t bblock)
11 years, 2 months
cluster: RHEL510 - fsck.gfs2: Don't use old_leaf if it was a duplicate
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1aa0537d3cb...
Commit: 1aa0537d3cbc2ede5dc994b356851952c762432f
Parent: 62a86dd0925a4d914f01d041a43e26811b66f556
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 14:22:12 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2: Don't use old_leaf if it was a duplicate
In function check_leaf_blks fsck.gfs2 keeps track of the current leaf
and the previous leaf. It can only check the number of pointers is
correct for the old leaf after it finds a new leaf block. However,
it was getting confused if the old leaf was a duplicate reference.
If the old leaf was a duplicate referenced by a different dinode, we
can't check the number of pointers because the number of pointers may
be for that other dinode's reference, not this one. The other dinode
referencing this leaf block may have the correct depth and this one
may not. This patch adds an extra check for the old leaf block being
a duplicate before checking the number of pointers.
rhbz#877150
---
gfs2/fsck/metawalk.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 282822e..5c09e85 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -617,7 +617,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
struct gfs2_buffer_head *lbh;
int lindex;
struct gfs2_sbd *sdp = ip->i_sbd;
- int ref_count = 0;
+ int ref_count = 0, old_was_dup;
/* Find the first valid leaf pointer in range and use it as our "old"
leaf. That way, bad blocks at the beginning will be overwritten
@@ -645,7 +645,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
old_leaf = -1;
memset(&oldleaf, 0, sizeof(oldleaf));
- for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+ old_was_dup = 0;
+ for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
if (fsck_abort)
break;
gfs2_get_leaf_nr(ip, lindex, &leaf_no);
@@ -664,7 +665,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
do {
if (fsck_abort)
return 0;
- if (pass->check_num_ptrs &&
+ /* If the old leaf was a duplicate referenced by a
+ previous dinode, we can't check the number of
+ pointers because the number of pointers may be for
+ that other dinode's reference, not this one. */
+ if (pass->check_num_ptrs && !old_was_dup &&
valid_block(ip->i_sbd, old_leaf)) {
error = pass->check_num_ptrs(ip, old_leaf,
&ref_count,
@@ -676,6 +681,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
error = check_leaf(ip, lindex, pass, &ref_count,
&leaf_no, old_leaf, &bad_leaf,
first_ok_leaf, &leaf, &oldleaf);
+ old_was_dup = (error == -EEXIST);
old_leaf = leaf_no;
memcpy(&oldleaf, &leaf, sizeof(oldleaf));
if (!leaf.lf_next || error)
11 years, 2 months
cluster: RHEL510 - fsck.gfs2: misc cosmetic changes
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=62a86dd0925...
Commit: 62a86dd0925a4d914f01d041a43e26811b66f556
Parent: f3dcee6421d8d717c0d56c0b6a0cf61b27ed5454
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 14:07:21 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2: misc cosmetic changes
This patch is just cosmetic changes. It cleans up comments and code
but there should be no logic changes.
rhbz#877150
---
gfs2/fsck/metawalk.c | 17 +++++++----------
gfs2/fsck/pass1.c | 8 ++++----
gfs2/fsck/pass1b.c | 9 +++++----
gfs2/fsck/pass2.c | 2 +-
gfs2/fsck/pass5.c | 10 ++++++----
5 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 58fa88e..282822e 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -467,15 +467,14 @@ static int warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
}
if (*leaf_no == *bad_leaf ||
(okay_to_fix = query( _("Attempt to patch around it? (y/n) ")))) {
- if (!valid_block(ip->i_sbd, old_leaf) == 0)
+ if (valid_block(ip->i_sbd, old_leaf))
gfs2_put_leaf_nr(ip, pindex, old_leaf);
else
gfs2_put_leaf_nr(ip, pindex, first_ok_leaf);
log_err( _("Directory Inode %llu (0x%llx) repaired.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- }
- else
+ } else
log_err( _("Bad leaf left in place.\n"));
*bad_leaf = *leaf_no;
*leaf_no = old_leaf;
@@ -624,9 +623,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
leaf. That way, bad blocks at the beginning will be overwritten
with the first valid leaf. */
first_ok_leaf = leaf_no = -1;
- for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+ for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
gfs2_get_leaf_nr(ip, lindex, &leaf_no);
- if (!valid_block(ip->i_sbd, leaf_no) == 0) {
+ if (valid_block(ip->i_sbd, leaf_no)) {
lbh = bread(sdp, leaf_no);
/* Make sure it's really a valid leaf block. */
if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
@@ -652,11 +651,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
gfs2_get_leaf_nr(ip, lindex, &leaf_no);
/* GFS has multiple indirect pointers to the same leaf
- * until those extra pointers are needed, so skip the
- * dups */
+ * until those extra pointers are needed, so skip the dups */
if (leaf_no == bad_leaf) {
- gfs2_put_leaf_nr(ip, lindex, old_leaf); /* fill w/old
- leaf info */
+ gfs2_put_leaf_nr(ip, lindex, old_leaf);
ref_count++;
continue;
} else if (old_leaf == leaf_no) {
@@ -826,7 +823,7 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, const char *btype,
void *private)
{
- if (!valid_block(ip->i_sbd, block) == 0) {
+ if (valid_block(ip->i_sbd, block)) {
fsck_blockmap_set(ip, block, btype, gfs2_block_free);
return 0;
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 31b1f9c..ee81436 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -386,7 +386,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
- if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
+ if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("itself"), gfs2_bad_block);
log_debug( _("Bad indirect block (invalid/out of range) "
@@ -460,7 +460,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
- if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
+ if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
_("itself"), gfs2_block_free);
return 1;
@@ -881,7 +881,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_buffer_head *bh = NULL;
int error;
- if (!valid_block(sdp, el_blk)){
+ if (!valid_block(sdp, el_blk)) {
log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
"%llu (0x%llx) has an extended leaf block #%llu "
"(0x%llx) that is invalid or out of range.\n"),
@@ -1073,7 +1073,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
long *bad_pointers = (long *)private;
uint8_t q;
- if (!valid_block(ip->i_sbd, block) != 0) {
+ if (!valid_block(ip->i_sbd, block)) {
(*bad_pointers)++;
log_info( _("Bad %s block pointer (invalid or out of range "
"#%ld) found in inode %lld (0x%llx).\n"),
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 49b1d95..443daf5 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -225,7 +225,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
struct dup_handler *dh = (struct dup_handler *) private;
struct duptree *d;
- if (!valid_block(ip->i_sbd, block) != 0)
+ if (!valid_block(ip->i_sbd, block))
return 0;
/* This gets tricky. We're traversing a metadata tree trying to
@@ -641,9 +641,10 @@ int pass1b(struct gfs2_sbd *sdp)
/* Rescan the fs looking for pointers to blocks that are in
* the duplicate block map */
log_info( _("Scanning filesystem for inodes containing duplicate blocks...\n"));
- log_debug( _("Filesystem has %"PRIu64" (0x%" PRIx64 ") blocks total\n"),
- last_fs_block, last_fs_block);
- for(i = 0; i < last_fs_block; i++) {
+ log_debug( _("Filesystem has %llu (0x%llx) blocks total\n"),
+ (unsigned long long)last_fs_block,
+ (unsigned long long)last_fs_block);
+ for (i = 0; i < last_fs_block; i++) {
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
goto out;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index b050e44..deaa883 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -778,7 +778,7 @@ int pass2(struct gfs2_sbd *sdp)
}
log_info( _("Checking directory inodes.\n"));
/* Grab each directory inode, and run checks on it */
- for(dirblk = 0; dirblk < last_fs_block; dirblk++) {
+ 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;
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index f5798a0..cc11b6b 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -56,13 +56,14 @@ static int convert_mark(uint8_t q, uint32_t *count)
default:
log_err( _("Invalid block type %d found\n"), q);
- return -1;
}
return -1;
}
-static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int buflen,
- uint64_t *rg_block, uint64_t rg_data, uint32_t *count)
+
+static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
+ unsigned int buflen, uint64_t *rg_block,
+ uint64_t rg_data, uint32_t *count)
{
unsigned char *byte, *end;
unsigned int bit;
@@ -163,7 +164,8 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
/* update the bitmaps */
check_block_status(sdp, rgp->bh[i]->b_data + bits->bi_offset,
- bits->bi_len, &rg_block, rgp->ri.ri_data0, count);
+ bits->bi_len, &rg_block, rgp->ri.ri_data0,
+ count);
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return;
}
11 years, 2 months
cluster: RHEL510 - fsck.gfs2 pass3: Refactor mark_and_return_parent
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=f3dcee6421d...
Commit: f3dcee6421d8d717c0d56c0b6a0cf61b27ed5454
Parent: ecd111e3bc6d31edcd1bc1a62af78482f31b1751
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 13:27:01 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2 pass3: Refactor mark_and_return_parent
This patch refactors pass3 function "mark_and_return_parent". Before
it was so complex and indented you could hardly interpret it. Now you
can actually follow the logic.
rhbz#877150
---
gfs2/fsck/pass3.c | 162 ++++++++++++++++++++++++++---------------------------
1 files changed, 79 insertions(+), 83 deletions(-)
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 4440b98..4ff1fc7 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -86,102 +86,98 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
{
struct dir_info *pdi;
uint8_t q_dotdot, q_treewalk;
+ int error = 0;
di->checked = 1;
if (!di->treewalk_parent)
return NULL;
- if (di->dotdot_parent != di->treewalk_parent) {
- log_warn( _("Directory '..' and treewalk connections disagree for inode %llu"
- " (0x%llx)\n"), (unsigned long long)di->dinode,
- (unsigned long long)di->dinode);
- log_notice( _("'..' has %llu (0x%llx), treewalk has %llu"
- " (0x%llx)\n"),
- (unsigned long long)di->dotdot_parent,
- (unsigned long long)di->dotdot_parent,
- (unsigned long long)di->treewalk_parent,
- (unsigned long long)di->treewalk_parent);
+ if (di->dotdot_parent == di->treewalk_parent) {
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
- * is correct - if both are directories, which do we
- * choose? if neither are directories, we have a
- * problem - need to move this directory into lost+found
- */
if (q_dotdot != gfs2_inode_dir) {
- if (q_treewalk != gfs2_inode_dir) {
- log_err( _("Orphaned directory, move to lost+found\n"));
- return NULL;
- }
- else {
- log_warn( _("Treewalk parent is correct,"
- " fixing dotdot -> %llu (0x%llx)\n"),
- (unsigned long long)di->treewalk_parent,
- (unsigned long long)di->treewalk_parent);
- attach_dotdot_to(sdp, di->treewalk_parent,
- di->dotdot_parent, di->dinode);
- di->dotdot_parent = di->treewalk_parent;
- }
- } else {
- if (q_treewalk != gfs2_inode_dir) {
- int error = 0;
- log_warn( _(".. parent is valid, but treewalk"
- "is bad - reattaching to lost+found"));
-
- /* FIXME: add a dinode for this entry instead? */
-
- if (query( _("Remove directory entry for bad"
- " inode %llu (0x%llx) in %llu"
- " (0x%llx)? (y/n)"),
- (unsigned long long)di->dinode,
- (unsigned long long)di->dinode,
- (unsigned long long)di->treewalk_parent,
- (unsigned long long)di->treewalk_parent)) {
- error = remove_dentry_from_dir(sdp, di->treewalk_parent,
- di->dinode);
- if (error < 0) {
- stack;
- return NULL;
- }
- if (error > 0) {
- log_warn( _("Unable to find dentry for block %llu"
- " (0x%llx) in %llu (0x%llx)\n"),
- (unsigned long long)di->dinode,
- (unsigned long long)di->dinode,
- (unsigned long long)di->treewalk_parent,
- (unsigned long long)di->treewalk_parent);
- }
- log_warn( _("Directory entry removed\n"));
- } else {
- log_err( _("Directory entry to invalid inode remains\n"));
- }
- log_info( _("Marking directory unlinked\n"));
-
- return NULL;
- }
- else {
- log_err( _("Both .. and treewalk parents are "
- "directories, going with treewalk "
- "for now...\n"));
- attach_dotdot_to(sdp, di->treewalk_parent,
- di->dotdot_parent,
- di->dinode);
- di->dotdot_parent = di->treewalk_parent;
- }
+ log_err( _("Orphaned directory at block %llu (0x%llx) "
+ "moved to lost+found\n"),
+ (unsigned long long)di->dinode,
+ (unsigned long long)di->dinode);
+ return NULL;
}
+ goto out;
}
- else {
- q_dotdot = block_type(di->dotdot_parent);
- if (q_dotdot != gfs2_inode_dir) {
- log_err( _("Orphaned directory at block %llu (0x%llx) moved to lost+found\n"),
- (unsigned long long)di->dinode,
- (unsigned long long)di->dinode);
+
+ log_warn( _("Directory '..' and treewalk connections disagree for "
+ "inode %llu (0x%llx)\n"), (unsigned long long)di->dinode,
+ (unsigned long long)di->dinode);
+ log_notice( _("'..' has %llu (0x%llx), treewalk has %llu (0x%llx)\n"),
+ (unsigned long long)di->dotdot_parent,
+ (unsigned long long)di->dotdot_parent,
+ (unsigned long long)di->treewalk_parent,
+ (unsigned long long)di->treewalk_parent);
+ 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
+ * is correct - if both are directories, which do we
+ * choose? if neither are directories, we have a
+ * problem - need to move this directory into lost+found
+ */
+ if (q_dotdot != gfs2_inode_dir) {
+ if (q_treewalk != gfs2_inode_dir) {
+ log_err( _("Orphaned directory, move to "
+ "lost+found\n"));
return NULL;
+ } else {
+ log_warn( _("Treewalk parent is correct, fixing "
+ "dotdot -> %llu (0x%llx)\n"),
+ (unsigned long long)di->treewalk_parent,
+ (unsigned long long)di->treewalk_parent);
+ attach_dotdot_to(sdp, di->treewalk_parent,
+ di->dotdot_parent, di->dinode);
+ di->dotdot_parent = di->treewalk_parent;
}
+ goto out;
+ }
+ if (q_treewalk == gfs2_inode_dir) {
+ log_err( _("Both .. and treewalk parents are directories, "
+ "going with treewalk...\n"));
+ attach_dotdot_to(sdp, di->treewalk_parent,
+ di->dotdot_parent, di->dinode);
+ di->dotdot_parent = di->treewalk_parent;
+ goto out;
}
+ log_warn( _(".. parent is valid, but treewalk is bad - reattaching to "
+ "lost+found"));
+
+ /* FIXME: add a dinode for this entry instead? */
+
+ if (!query( _("Remove directory entry for bad inode %llu (0x%llx) in "
+ "%llu (0x%llx)? (y/n)"),
+ (unsigned long long)di->dinode,
+ (unsigned long long)di->dinode,
+ (unsigned long long)di->treewalk_parent,
+ (unsigned long long)di->treewalk_parent)) {
+ log_err( _("Directory entry to invalid inode remains\n"));
+ return NULL;
+ }
+ error = remove_dentry_from_dir(sdp, di->treewalk_parent, di->dinode);
+ if (error < 0) {
+ stack;
+ return NULL;
+ }
+ if (error > 0)
+ log_warn( _("Unable to find dentry for block %llu"
+ " (0x%llx) in %llu (0x%llx)\n"),
+ (unsigned long long)di->dinode,
+ (unsigned long long)di->dinode,
+ (unsigned long long)di->treewalk_parent,
+ (unsigned long long)di->treewalk_parent);
+ log_warn( _("Directory entry removed\n"));
+ log_info( _("Marking directory unlinked\n"));
+
+ return NULL;
+
+out:
pdi = dirtree_find(di->dotdot_parent);
return pdi;
11 years, 2 months
cluster: RHEL510 - fsck.gfs2 pass2: Don't delete invalid inode metadata
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=ecd111e3bc6...
Commit: ecd111e3bc6d31edcd1bc1a62af78482f31b1751
Parent: 9555c12ec4dbd75e638b859ef7e4658ba0239fa8
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 13:01:05 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2 pass2: Don't delete invalid inode metadata
In pass2, all metadata was deleted for inodes that were marked either
"bad" or "invalid" but that is wrong, and here is why:
Blocks marked "invalid" were invalidated due to duplicate block references.
Pass1b should have already taken care of deleting their metadata, so in pass2
we only need to delete the directory entries pointing to them. We delete the
metadata in pass1b because we need to eliminate the inode referencing the
duplicate-referenced block from the list of candidates to keep. So we have a
delete-as-we-go policy. Blocks marked "bad" need to have their entire
metadata tree deleted.
rhbz#877150
---
gfs2/fsck/pass2.c | 30 ++++++++++++++++++++++--------
1 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 51cbe33..b050e44 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -328,6 +328,18 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
q = block_type(entryblock);
/* Get the status of the directory inode */
+ /**
+ * 1. Blocks marked "invalid" were invalidated due to duplicate
+ * block references. Pass1b should have already taken care of deleting
+ * their metadata, so here we only need to delete the directory entries
+ * pointing to them. We delete the metadata in pass1b because we need
+ * to eliminate the inode referencing the duplicate-referenced block
+ * from the list of candidates to keep. So we have a delete-as-we-go
+ * policy.
+ *
+ * 2. Blocks marked "bad" need to have their entire
+ * metadata tree deleted.
+ */
if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
@@ -342,14 +354,16 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
goto dentry_is_valid;
}
- if (ip->i_di.di_num.no_addr == entryblock)
- entry_ip = ip;
- else
- entry_ip = fsck_load_inode(sdp, entryblock);
- check_inode_eattr(entry_ip, &pass2_fxns_delete);
- check_metatree(entry_ip, &pass2_fxns_delete);
- if (entry_ip != ip)
- fsck_inode_put(&entry_ip);
+ if (q == gfs2_bad_block) {
+ if (ip->i_di.di_num.no_addr == entryblock)
+ entry_ip = ip;
+ else
+ entry_ip = fsck_load_inode(sdp, entryblock);
+ check_inode_eattr(entry_ip, &pass2_fxns_delete);
+ check_metatree(entry_ip, &pass2_fxns_delete);
+ if (entry_ip != ip)
+ fsck_inode_put(&entry_ip);
+ }
fsck_blockmap_set(ip, entryblock,
_("bad directory entry"), gfs2_block_free);
log_err( _("Inode %lld (0x%llx) was deleted.\n"),
11 years, 2 months
cluster: RHEL510 - fsck.gfs2 pass2: Delete extended attributes with inode
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=9555c12ec4d...
Commit: 9555c12ec4dbd75e638b859ef7e4658ba0239fa8
Parent: 0bcaa5e0c191e81a3681cd883ac642859e62be79
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 12:48:36 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2 pass2: Delete extended attributes with inode
When pass2 decided to delete a bad/corrupt dinode from disk, it was
not deleting extended attributes associated with that dinode. Oops.
This patch corrects the situation and allows it to delete them.
rhbz#877150
---
gfs2/fsck/pass2.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index cba0094..51cbe33 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -171,6 +171,59 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
return 0;
}
+static int delete_eattr_entry (struct gfs2_inode *ip,
+ struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev,
+ 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 */
+ return 1;
+ }
+
+ if (ea_hdr->ea_num_ptrs){
+ uint32_t avail_size;
+ int max_ptrs;
+
+ avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+ max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
+ avail_size;
+
+ if (max_ptrs > ea_hdr->ea_num_ptrs)
+ return 1;
+ else {
+ log_debug( _(" Pointers Required: %d\n Pointers Reported: %d\n"),
+ max_ptrs, ea_hdr->ea_num_ptrs);
+ }
+ }
+ return 0;
+}
+
+static int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+ struct gfs2_buffer_head *leaf_bh,
+ struct gfs2_ea_header *ea_hdr,
+ struct gfs2_ea_header *ea_hdr_prev,
+ void *private)
+{
+ uint64_t block = be64_to_cpu(*ea_data_ptr);
+
+ return delete_metadata(ip, block, NULL, 0, private);
+}
+
struct metawalk_fxns pass2_fxns_delete = {
.private = NULL,
.check_metalist = delete_metadata,
@@ -178,6 +231,8 @@ struct metawalk_fxns pass2_fxns_delete = {
.check_leaf = delete_leaf,
.check_eattr_indir = delete_eattr_indir,
.check_eattr_leaf = delete_eattr_leaf,
+ .check_eattr_entry = delete_eattr_entry,
+ .check_eattr_extentry = delete_eattr_extentry,
};
/* FIXME: should maybe refactor this a bit - but need to deal with
11 years, 2 months
cluster: RHEL510 - fsck.gfs pass2: Refactor function set_dotdot_dir
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=0bcaa5e0c19...
Commit: 0bcaa5e0c191e81a3681cd883ac642859e62be79
Parent: 214fe5a6031fc76b3beacdbb151722a13be6bc25
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 12:45:18 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs pass2: Refactor function set_dotdot_dir
This patch refactors function set_dotdot_dir to make it more readable.
rhbz#877150
---
gfs2/fsck/pass2.c | 46 ++++++++++++++++++++++++++--------------------
1 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 67c0fcb..cba0094 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -70,34 +70,40 @@ static int set_parent_dir(struct gfs2_sbd *sdp, uint64_t childblock,
/* Set's the child's '..' directory inode number in dir_info structure */
static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
- uint64_t parentblock)
+ uint64_t parentblock)
{
struct dir_info *di;
di = dirtree_find(childblock);
- if (di) {
- if (di->dinode == childblock) {
- /* Special case for root inode because we set
- * it earlier */
- if (di->dotdot_parent && sdp->md.rooti->i_di.di_num.no_addr
- != di->dinode) {
- /* This should never happen */
- log_crit( _("Dotdot parent already set for"
- " block %"PRIu64" (0x%" PRIx64 ") -> %" PRIu64
- " (0x%" PRIx64 ")\n"), childblock, childblock,
- di->dotdot_parent, di->dotdot_parent);
- return -1;
- }
- di->dotdot_parent = parentblock;
- }
- } else {
+ if (!di) {
log_err( _("Unable to find block %"PRIu64" (0x%" PRIx64
- ") in dir_info list\n"), childblock, childblock);
+ ") in dir_info tree\n"), childblock, childblock);
return -1;
}
-
+ if (di->dinode != childblock) {
+ log_debug("'..' doesn't point to what we found: childblock "
+ "0x%llx != dinode 0x%llx\n",
+ (unsigned long long)childblock,
+ (unsigned long long)di->dinode);
+ return -1;
+ }
+ /* Special case for root inode because we set it earlier */
+ if (di->dotdot_parent &&
+ sdp->md.rooti->i_di.di_num.no_addr != di->dinode) {
+ /* This should never happen */
+ log_crit( _("Dotdot parent already set for block %llu (0x%llx)"
+ "-> %llu (0x%llx)\n"),
+ (unsigned long long)childblock,
+ (unsigned long long)childblock,
+ (unsigned long long)di->dotdot_parent,
+ (unsigned long long)di->dotdot_parent);
+ return -1;
+ }
+ log_debug("Setting '..' for directory block 0x%llx to parent 0x%llx\n",
+ (unsigned long long)childblock,
+ (unsigned long long)parentblock);
+ di->dotdot_parent = parentblock;
return 0;
-
}
static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
11 years, 2 months
cluster: RHEL510 - fsck.gfs2: Make output messages more sensible
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=214fe5a6031...
Commit: 214fe5a6031fc76b3beacdbb151722a13be6bc25
Parent: 8c7487c31e4fc38cf061596c7444034bac423b2a
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 12:36:04 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700
fsck.gfs2: Make output messages more sensible
This patch changes several fsck output messages so that they make more
sense. Digging through very big and complex fsck.gfs2 output, I found
myself lost in many occasions. This patch makes it a lot easier to see
what decisions are made by fsck.gfs2 and why.
rhbz#877150
Conflicts:
gfs2/fsck/initialize.c
---
gfs2/fsck/initialize.c | 35 +++++++++++++++++++++++++++++++----
gfs2/fsck/metawalk.c | 2 +-
gfs2/fsck/pass1.c | 4 ++++
gfs2/fsck/pass1b.c | 5 +++--
gfs2/fsck/pass2.c | 18 ++++++++++++++----
gfs2/fsck/pass5.c | 21 +++++++++++++--------
gfs2/fsck/util.c | 3 ++-
7 files changed, 68 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 85500a9..1db4ce6 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -473,6 +473,20 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
int rgcount, sane = 1;
enum rgindex_trust_level trust_lvl;
uint64_t addl_mem_needed;
+ const char *level_desc[] = {
+ _("Checking if all rgrp and rindex values are good"),
+ _("Checking if rindex values may be easily repaired"),
+ _("Calculating where the rgrps should be if evenly spaced"),
+ _("Trying to rebuild rindex assuming evenly spaced rgrps"),
+ _("Trying to rebuild rindex assuming unevenly spaced rgrps"),
+ };
+ const char *fail_desc[] = {
+ _("Some damage was found; we need to take remedial measures"),
+ _("rindex is unevenly spaced: either gfs1-style or corrupt"),
+ _("rindex calculations don't match: uneven rgrp boundaries"),
+ _("Too many rgrp misses: rgrps must be unevenly spaced"),
+ _("Too much damage found: we cannot rebuild this rindex"),
+ };
/*******************************************************************
****************** Initialize important inodes ******************
@@ -514,14 +528,27 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
*******************************************************************/
log_warn( _("Validating Resource Group index.\n"));
for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) {
- log_warn( _("Level %d RG check.\n"), trust_lvl + 1);
+ int ret;
+
+ log_warn( _("Level %d rgrp check: %s.\n"), trust_lvl + 1,
+ level_desc[trust_lvl]);
if ((rg_repair(sdp, trust_lvl, &rgcount, &sane) == 0) &&
- (ri_update(sdp, 0, &rgcount, &sane) == 0)) {
+ ((ret = ri_update(sdp, 0, &rgcount, &sane)) == 0)) {
log_warn( _("(level %d passed)\n"), trust_lvl + 1);
break;
+ } else {
+ if (ret < 0)
+ log_err( _("(level %d failed: %s)\n"),
+ trust_lvl + 1, fail_desc[trust_lvl]);
+ else
+ log_err( _("(level %d failed at block %lld "
+ "(0x%llx): %s)\n"), trust_lvl + 1,
+ (unsigned long long)ret,
+ (unsigned long long)ret,
+ fail_desc[trust_lvl]);
}
- else
- log_err( _("(level %d failed)\n"), trust_lvl + 1);
+ if (fsck_abort)
+ break;
}
if (trust_lvl > distrust) {
log_err( _("RG recovery impossible; I can't fix this file system.\n"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index c094e70..58fa88e 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -350,7 +350,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
de.de_name_len ||
(de.de_inum.no_formal_ino && !de.de_name_len && !first)) {
log_err( _("Directory block %llu (0x%llx"
- "), entry %d of directory %llu"
+ "), entry %d of directory %llu "
"(0x%llx) is corrupt.\n"),
(unsigned long long)bh->b_blocknr,
(unsigned long long)bh->b_blocknr,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 92bc1e6..31b1f9c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1228,6 +1228,10 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
words, we would introduce file system corruption. So we
need to keep track of the fact that it's invalid and
skip parts that we can't be sure of based on dinode type. */
+ log_debug("Invalid mode dinode found at block %lld (0x%llx): "
+ "Invalidating all its metadata.\n",
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
check_metatree(ip, &invalidate_fxns);
if (fsck_blockmap_set(ip, block, _("invalid mode"),
gfs2_inode_invalid))
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 8610956..49b1d95 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -442,7 +442,7 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
log_warn( _("The bad inode was not cleared...\n"));
continue;
}
- log_warn( _("Clearing inode %lld (0x%llx)....\n"),
+ log_warn( _("Clearing inode %lld (0x%llx)...\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
clear_dup_fxns.private = (void *) dh;
@@ -613,7 +613,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
gfs2_meta_eattr);
fsck_inode_put(&ip); /* out, brelse, free */
} else {
- log_debug( _("All duplicate references were resolved.\n"));
+ /* They may have answered no and not fixed all references. */
+ log_debug( _("All duplicate references were processed.\n"));
}
return 0;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index dd816ab..67c0fcb 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -271,7 +271,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
- log_err( _("Found a bad directory entry: %s\n"), tmp_name);
+ log_err( _("Found directory entry '%s' pointing to invalid "
+ "block %lld (0x%llx)\n"), tmp_name,
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock);
if (!query( _("Delete inode containing bad blocks? (y/n)"))) {
log_warn( _("Entry to inode containing bad blocks remains\n"));
@@ -288,6 +291,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
fsck_inode_put(&entry_ip);
fsck_blockmap_set(ip, entryblock,
_("bad directory entry"), gfs2_block_free);
+ log_err( _("Inode %lld (0x%llx) was deleted.\n"),
+ (unsigned long long)entryblock,
+ (unsigned long long)entryblock);
goto nuke_dentry;
}
if (q < gfs2_inode_dir || q > gfs2_inode_sock) {
@@ -363,7 +369,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
if (!strcmp(".", tmp_name)) {
- log_debug( _("Found . dentry\n"));
+ log_debug( _("Found . dentry in directory %lld (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
if (ds->dotdir) {
log_err( _("Already found '.' entry in directory %llu"
@@ -421,9 +429,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
goto dentry_is_valid;
}
if (!strcmp("..", tmp_name)) {
- log_debug( _("Found .. dentry\n"));
+ log_debug( _("Found '..' dentry in directory %lld (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
if (ds->dotdotdir) {
- log_err( _("Already found '..' entry in directory %llu"
+ log_err( _("Already had a '..' entry in 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);
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 95efd9f..f5798a0 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -96,7 +96,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
"(0x%llx).\n"),
(unsigned long long)block,
(unsigned long long)block);
- if (query(_("Do you want to fix the bitmap? (y/n) "))) {
+ if (query(_("Do you want to reclaim the block? "
+ "(y/n) "))) {
if (gfs2_set_bitmap(sdp, block, block_status))
log_err(_("Unlinked block %llu "
"(0x%llx) bitmap not fixed."
@@ -117,11 +118,12 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
const char *blockstatus[] = {"Free", "Data",
"Unlinked", "inode"};
- log_err( _("Ondisk and fsck bitmaps differ at"
- " block %"PRIu64" (0x%" PRIx64 ") \n"), block, block);
- 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( _("Block %llu (0x%llx) bitmap says %u (%s) "
+ "but FSCK saw %u (%s)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block, rg_status,
+ blockstatus[rg_status], block_status,
+ blockstatus[block_status]);
if (q) /* Don't print redundant "free" */
log_err( _("Metadata type is %u (%s)\n"), q,
block_type_string(q));
@@ -177,8 +179,11 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
update = 1;
}
if (rgp->rg.rg_dinodes != count[1]) {
- log_err( _("Inode count inconsistent: is %u should be %u\n"),
- rgp->rg.rg_dinodes, count[1]);
+ log_err( _("RG #%llu (0x%llx) Inode count inconsistent: is "
+ "%u should be %u\n"),
+ (unsigned long long)rgp->ri.ri_addr,
+ (unsigned long long)rgp->ri.ri_addr,
+ rgp->rg.rg_dinodes, count[1]);
rgp->rg.rg_dinodes = count[1];
update = 1;
}
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 5c5f1aa..7094e26 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -300,7 +300,8 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
if (first)
log_info( _("This is the original reference.\n"));
else
- log_info( _("This brings the total to: %d\n"), dt->refs);
+ log_info( _("This brings the total to: %d duplicate "
+ "references\n"), dt->refs);
return 0;
}
11 years, 2 months