[Ocfs2-tools-devel] [PATCH 32/44] fsck.ocfs2: Add basic check for refcount block.
Tao Ma
tao.ma at oracle.com
Mon Dec 28 01:01:17 PST 2009
Add basic check for refcount block.
They are RB_BLKNO, RB_GEN and RB_GEN_FIX.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
fsck.ocfs2/Makefile | 1 +
fsck.ocfs2/fsck.ocfs2.checks.8.in | 26 +++++++++
fsck.ocfs2/refcount.c | 103 +++++++++++++++++++++++++++++++++++++
3 files changed, 130 insertions(+), 0 deletions(-)
create mode 100644 fsck.ocfs2/refcount.c
diff --git a/fsck.ocfs2/Makefile b/fsck.ocfs2/Makefile
index aa3e79e..63f86de 100644
--- a/fsck.ocfs2/Makefile
+++ b/fsck.ocfs2/Makefile
@@ -33,6 +33,7 @@ CFILES = fsck.c \
pass4.c \
pass5.c \
problem.c \
+ refcount.c \
slot_recovery.c \
strings.c \
util.c \
diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index f0b926c..4537cf2 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -566,6 +566,32 @@ found that a file has refcount loc while it does't have refcount flag set.
Answering yes reset refcount loc to zero for the file.
+.SS "RB_BLKNO"
+refcount blocks contain a record of the disk block where they are located.
+An refcount block was found at a block that didn't match its recorded location.
+
+Answering yes will update the data structure in the refcount block to reflect
+its real location on disk.
+
+.SS "RB_GEN"
+Refcount blocks are created with a generation number to match the generation
+number of the volume at the time of creation. An refcount block was found which
+contains a generation number that doesn't match.
+
+Answering yes implies that the generation number is correct and that the
+refcount block is from a previous file system. The refcount block will be
+ignored and the file that uses it will lose the refcounted information, but
+it may be regenerated later.
+
+.SS "RB_GEN_FIX"
+Refcount blocks are created with a generation number to match the generation
+number of the volume at the time of creation. An refcount block was found which
+contains a generation number that doesn't match.
+
+Answering yes implies that the generation number in the refcount block is
+incorrect and that the extent block is valid. The generation number in the
+block is updated to match the generation number in the volume.
+
\" pass1b.c
.SS "DUP_CLUSTERS_SYSFILE_CLONE"
diff --git a/fsck.ocfs2/refcount.c b/fsck.ocfs2/refcount.c
new file mode 100644
index 0000000..6e21a45
--- /dev/null
+++ b/fsck.ocfs2/refcount.c
@@ -0,0 +1,103 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * refcount.c
+ *
+ * Copyright (C) 2009 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <inttypes.h>
+#include "ocfs2/ocfs2.h"
+#include "problem.h"
+
+static const char *whoami = "refcount.c";
+
+static errcode_t check_rb(o2fsck_state *ost, uint64_t blkno,
+ uint64_t root_blkno, int *is_valid)
+{
+ int changed = 0;
+ char *buf = NULL;
+ struct ocfs2_refcount_block *rb;
+ errcode_t ret;
+
+ /* XXX test that the block isn't already used */
+
+ /* we only consider a refcount block invalid if we were able to read
+ * it and it didn't have a refcount block signature */
+ *is_valid = 1;
+
+ ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
+ if (ret) {
+ com_err(whoami, ret, "while allocating a block-sized buffer "
+ "for a refcount block");
+ goto out;
+ }
+
+ ret = ocfs2_read_refcount_block_nocheck(ost->ost_fs, blkno, buf);
+ if (ret) {
+ com_err(whoami, ret, "reading refcount block at %"PRIu64" in "
+ "refcount tree %"PRIu64" for verification", blkno,
+ root_blkno);
+ if (ret == OCFS2_ET_BAD_EXTENT_BLOCK_MAGIC)
+ *is_valid = 0;
+ goto out;
+ }
+
+ rb = (struct ocfs2_refcount_block *)buf;
+
+ if (rb->rf_blkno != blkno &&
+ prompt(ost, PY, PR_RB_BLKNO,
+ "A refcount block at %"PRIu64" in refcount tree %"PRIu64" "
+ "claims to be located at block %"PRIu64". Update the "
+ "refcount block's location?", blkno, root_blkno,
+ (uint64_t)rb->rf_blkno)) {
+ rb->rf_blkno = blkno;
+ changed = 1;
+ }
+
+ if (rb->rf_fs_generation != ost->ost_fs_generation) {
+ if (prompt(ost, PY, PR_RB_GEN,
+ "A refcount block at %"PRIu64" in refcount tree "
+ "%"PRIu64" has a generation of %x which doesn't "
+ "match the volume's generation of %x. Consider "
+ "this refcount block invalid?", blkno,
+ root_blkno, rb->rf_fs_generation,
+ ost->ost_fs_generation)) {
+
+ *is_valid = 0;
+ goto out;
+ }
+ if (prompt(ost, PY, PR_RB_GEN_FIX,
+ "Update the refcount block's generation to match "
+ "the volume?")) {
+ rb->rf_fs_generation = ost->ost_fs_generation;
+ changed = 1;
+ }
+ }
+
+ /* XXX worry about suballoc node/bit */
+
+ if (changed) {
+ ret = ocfs2_write_refcount_block(ost->ost_fs, blkno, buf);
+ if (ret) {
+ com_err(whoami, ret, "while writing an updated "
+ "refcount block at %"PRIu64" for refcount "
+ "tree %"PRIu64, blkno, root_blkno);
+ goto out;
+ }
+ }
+
+out:
+ if (buf)
+ ocfs2_free(&buf);
+ return 0;
+}
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list