[Ocfs2-tools-devel] [PATCH 1/3] fsck.ocfs2: Handle errors from ocfs2_bitmap_set/clear()
Joel Becker
joel.becker at oracle.com
Fri Jun 19 22:08:20 PDT 2009
o2fsck expects to be able to treat ocfs2_bitmap_set() and
ocfs2_bitmap_clear() as void functions. However, since o2fsck uses the
sparse-memory bitmaps a lot, they can (in theory) have allocation
failures. A silent allocation failure looks like clear bits, which is
not a safe behavior.
So, let's wrap ocfs2_bitmap_set/clear() with o2fsck_bitmap_set/clear().
These are true void functions. If they get an error from
ocfs2_bitmap_set/clear() they will print the caller, the error, and the
bit number. Then they abort o2fsck.
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
fsck.ocfs2/icount.c | 4 ++--
fsck.ocfs2/include/util.h | 15 +++++++++++++++
fsck.ocfs2/journal.c | 2 +-
fsck.ocfs2/pass0.c | 10 +++++-----
fsck.ocfs2/pass1.c | 4 ++--
fsck.ocfs2/util.c | 43 +++++++++++++++++++++++++++++++++++++++++--
6 files changed, 66 insertions(+), 12 deletions(-)
diff --git a/fsck.ocfs2/icount.c b/fsck.ocfs2/icount.c
index 858063a..1fa7aab 100644
--- a/fsck.ocfs2/icount.c
+++ b/fsck.ocfs2/icount.c
@@ -95,9 +95,9 @@ errcode_t o2fsck_icount_set(o2fsck_icount *icount, uint64_t blkno,
errcode_t ret = 0;
if (count == 1)
- ocfs2_bitmap_set(icount->ic_single_bm, blkno, NULL);
+ o2fsck_bitmap_set(icount->ic_single_bm, blkno, NULL);
else
- ocfs2_bitmap_clear(icount->ic_single_bm, blkno, NULL);
+ o2fsck_bitmap_clear(icount->ic_single_bm, blkno, NULL);
in = icount_search(icount, blkno, NULL);
if (in) {
diff --git a/fsck.ocfs2/include/util.h b/fsck.ocfs2/include/util.h
index 77d36e4..c4e58ba 100644
--- a/fsck.ocfs2/include/util.h
+++ b/fsck.ocfs2/include/util.h
@@ -65,4 +65,19 @@ errcode_t handle_slots_system_file(ocfs2_filesys *fs,
errcode_t (*func)(ocfs2_filesys *fs,
struct ocfs2_dinode *di,
int slot));
+
+/*
+ * Wrap the ocfs2 bitmap functions to abort when errors are found. They're
+ * not supposed to fail, so we want to handle it.
+ */
+void __o2fsck_bitmap_set(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
+ const char *where);
+void __o2fsck_bitmap_clear(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
+ const char *where);
+
+/* These wrappers pass the caller into __o2fsck_bitmap_*() */
+#define o2fsck_bitmap_set(_map, _bit, _old) \
+ __o2fsck_bitmap_set((_map), (_bit), (_old), __FUNCTION__)
+#define o2fsck_bitmap_clear(_map, _bit, _old) \
+ __o2fsck_bitmap_clear((_map), (_bit), (_old), __FUNCTION__);
#endif /* __O2FSCK_UTIL_H__ */
diff --git a/fsck.ocfs2/journal.c b/fsck.ocfs2/journal.c
index 4ed7653..ee1ce60 100644
--- a/fsck.ocfs2/journal.c
+++ b/fsck.ocfs2/journal.c
@@ -247,7 +247,7 @@ static errcode_t lookup_journal_block(ocfs2_filesys *fs,
}
if (check_dup) {
- ocfs2_bitmap_set(ji->ji_used_blocks, *blkno, &was_set);
+ o2fsck_bitmap_set(ji->ji_used_blocks, *blkno, &was_set);
if (was_set) {
printf("Logical block %"PRIu64" in slot %d's journal "
"maps to block %"PRIu64" which has already "
diff --git a/fsck.ocfs2/pass0.c b/fsck.ocfs2/pass0.c
index b2172ce..66e18c7 100644
--- a/fsck.ocfs2/pass0.c
+++ b/fsck.ocfs2/pass0.c
@@ -494,13 +494,13 @@ static errcode_t check_chain(o2fsck_state *ost,
int was_set;
ocfs2_bitmap_test(allowed, blkno, &was_set);
if (was_set) {
- ocfs2_bitmap_clear(allowed, blkno,
- &was_set);
+ o2fsck_bitmap_clear(allowed, blkno,
+ &was_set);
mark_group_used(ost, cs, bg1->bg_blkno,
allowed != NULL);
} else if (forbidden)
- ocfs2_bitmap_set(forbidden, blkno,
- &was_set);
+ o2fsck_bitmap_set(forbidden, blkno,
+ &was_set);
} else
mark_group_used(ost, cs, bg1->bg_blkno,
allowed != NULL);
@@ -906,7 +906,7 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
i < cgs.cgs_cluster_groups;
i++, blkno = i * ocfs2_clusters_to_blocks(ost->ost_fs,
cgs.cgs_cpg)) {
- ocfs2_bitmap_set(allowed, blkno, NULL);
+ o2fsck_bitmap_set(allowed, blkno, NULL);
}
ret = verify_chain_alloc(ost, di, buf1, buf2, NULL, allowed, forbidden);
diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
index 15880bc..de09788 100644
--- a/fsck.ocfs2/pass1.c
+++ b/fsck.ocfs2/pass1.c
@@ -509,11 +509,11 @@ static void o2fsck_verify_inode_fields(ocfs2_filesys *fs,
}
if (S_ISDIR(di->i_mode)) {
- ocfs2_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
+ o2fsck_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, 0, 0,
di->i_flags & OCFS2_ORPHANED_FL);
} else if (S_ISREG(di->i_mode)) {
- ocfs2_bitmap_set(ost->ost_reg_inodes, blkno, NULL);
+ o2fsck_bitmap_set(ost->ost_reg_inodes, blkno, NULL);
} else if (S_ISLNK(di->i_mode)) {
/* we only make sure a link's i_size matches
* the link names length in the file data later when
diff --git a/fsck.ocfs2/util.c b/fsck.ocfs2/util.c
index 0238709..b12e3e1 100644
--- a/fsck.ocfs2/util.c
+++ b/fsck.ocfs2/util.c
@@ -28,6 +28,9 @@
#include <inttypes.h>
#include <string.h>
#include <assert.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
#include "ocfs2/ocfs2.h"
#include "util.h"
@@ -57,7 +60,7 @@ void o2fsck_mark_cluster_allocated(o2fsck_state *ost, uint32_t cluster)
{
int was_set;
- ocfs2_bitmap_set(ost->ost_allocated_clusters, cluster, &was_set);
+ o2fsck_bitmap_set(ost->ost_allocated_clusters, cluster, &was_set);
if (was_set) /* XX can go away one all callers handle this */
com_err(__FUNCTION__, OCFS2_ET_INTERNAL_FAILURE,
@@ -75,7 +78,7 @@ void o2fsck_mark_cluster_unallocated(o2fsck_state *ost, uint32_t cluster)
{
int was_set;
- ocfs2_bitmap_clear(ost->ost_allocated_clusters, cluster, &was_set);
+ o2fsck_bitmap_clear(ost->ost_allocated_clusters, cluster, &was_set);
}
errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino,
@@ -275,3 +278,39 @@ void o2fsck_reset_blocks_cached(void)
{
blocks_cached = 0;
}
+
+void __o2fsck_bitmap_set(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
+ const char *where)
+{
+ errcode_t ret;
+
+ ret = ocfs2_bitmap_set(bitmap, bitno, oldval);
+ if (ret) {
+ com_err(where, ret,
+ "while trying to set bit %"PRIu64", aborting\n",
+ bitno);
+ /*
+ * We abort with SIGTERM so that the signal handler can
+ * clean up the cluster stack.
+ */
+ kill(getpid(), SIGTERM);
+ }
+}
+
+void __o2fsck_bitmap_clear(ocfs2_bitmap *bitmap, uint64_t bitno, int *oldval,
+ const char *where)
+{
+ errcode_t ret;
+
+ ret = ocfs2_bitmap_clear(bitmap, bitno, oldval);
+ if (ret) {
+ com_err(where, ret,
+ "while trying to clear bit %"PRIu64", aborting\n",
+ bitno);
+ /*
+ * We abort with SIGTERM so that the signal handler can
+ * clean up the cluster stack.
+ */
+ kill(getpid(), SIGTERM);
+ }
+}
--
1.6.3.1
More information about the Ocfs2-tools-devel
mailing list