From: Joel Becker <Joel.Becker@oracle.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH] ocfs2: Checksum and ECC for directory blocks.
Date: Wed, 10 Dec 2008 18:25:41 -0800 [thread overview]
Message-ID: <20081211022541.GN21455@mail.oracle.com> (raw)
In-Reply-To: <20081211021612.GK21455@mail.oracle.com>
Use the db_check field of ocfs2_dir_block_trailer to crc/ecc the
dirblocks.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
---
fs/ocfs2/dir.c | 33 +++++++++++++++++++++++++++++++--
fs/ocfs2/dir.h | 2 ++
fs/ocfs2/journal.c | 31 +++++++++++++++++++++++++++++--
fs/ocfs2/ocfs2_fs.h | 2 +-
4 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 06077d0..e03c4ed 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -48,6 +48,7 @@
#include "ocfs2.h"
#include "alloc.h"
+#include "blockcheck.h"
#include "dir.h"
#include "dlmglue.h"
#include "extent_map.h"
@@ -104,6 +105,17 @@ static inline unsigned int ocfs2_dir_trailer_blk_off(struct super_block *sb)
#define ocfs2_trailer_from_bh(_bh, _sb) ((struct ocfs2_dir_block_trailer *) ((_bh)->b_data + ocfs2_dir_trailer_blk_off((_sb))))
+/* XXX ocfs2_block_dqtrailer() is similar but not quite - can we make
+ * them more consistent? */
+struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize,
+ void *data)
+{
+ char *p = data;
+
+ p += blocksize - sizeof(struct ocfs2_dir_block_trailer);
+ return (struct ocfs2_dir_block_trailer *)p;
+}
+
/*
* XXX: This is executed once on every dirent. We should consider optimizing
* it.
@@ -263,14 +275,31 @@ out:
static int ocfs2_validate_dir_block(struct super_block *sb,
struct buffer_head *bh)
{
+ int rc;
+ struct ocfs2_dir_block_trailer *trailer =
+ ocfs2_trailer_from_bh(bh, sb);
+
+
/*
- * Nothing yet. We don't validate dirents here, that's handled
+ * We don't validate dirents here, that's handled
* in-place when the code walks them.
*/
mlog(0, "Validating dirblock %llu\n",
(unsigned long long)bh->b_blocknr);
- return 0;
+ BUG_ON(!buffer_uptodate(bh));
+
+ /*
+ * If the ecc fails, we return the error but otherwise
+ * leave the filesystem running. We know any error is
+ * local to this block.
+ */
+ rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &trailer->db_check);
+ if (rc)
+ mlog(ML_ERROR, "Checksum failed for dinode %llu\n",
+ (unsigned long long)bh->b_blocknr);
+
+ return rc;
}
/*
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index ce48b90..c511e2e 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -83,4 +83,6 @@ int ocfs2_fill_new_dir(struct ocfs2_super *osb,
struct buffer_head *fe_bh,
struct ocfs2_alloc_context *data_ac);
+struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize,
+ void *data);
#endif /* OCFS2_DIR_H */
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 3b54dba..57d7d25 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -415,6 +415,26 @@ static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers,
ocfs2_block_check_compute(data, size, &dqt->dq_check);
}
+/*
+ * Directory blocks also have their own trigger because the
+ * struct ocfs2_block_check offset depends on the blocksize.
+ */
+static void ocfs2_db_commit_trigger(struct jbd2_buffer_trigger_type *triggers,
+ struct buffer_head *bh,
+ void *data, size_t size)
+{
+ struct ocfs2_dir_block_trailer *trailer =
+ ocfs2_dir_trailer_from_size(size, data);
+
+ /*
+ * We aren't guaranteed to have the superblock here, so we
+ * must unconditionally compute the ecc data.
+ * __ocfs2_journal_access() will only set the triggers if
+ * metaecc is enabled.
+ */
+ ocfs2_block_check_compute(data, size, &trailer->db_check);
+}
+
static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers,
struct buffer_head *bh)
{
@@ -454,6 +474,13 @@ static struct ocfs2_triggers gd_triggers = {
.ot_offset = offsetof(struct ocfs2_group_desc, bg_check),
};
+static struct ocfs2_triggers db_triggers = {
+ .ot_triggers = {
+ .t_commit = ocfs2_db_commit_trigger,
+ .t_abort = ocfs2_abort_trigger,
+ },
+};
+
static struct ocfs2_triggers xb_triggers = {
.ot_triggers = {
.t_commit = ocfs2_commit_trigger,
@@ -555,8 +582,8 @@ int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode,
int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type)
{
- /* Right now, nothing for dirblocks */
- return __ocfs2_journal_access(handle, inode, bh, NULL, type);
+ return __ocfs2_journal_access(handle, inode, bh, &db_triggers,
+ type);
}
int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode,
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index e6e7cb0..1d92806 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -767,7 +767,7 @@ struct ocfs2_dir_block_trailer {
__u8 db_signature[8]; /* Signature for verification */
__le64 db_reserved2;
__le64 db_free_next; /* Next block in list (unused) */
- __le64 db_check; /* Error checking */
+ struct ocfs2_block_check db_check; /* Error checking */
};
/*
--
1.5.6.5
next prev parent reply other threads:[~2008-12-11 2:25 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-10 1:09 [Ocfs2-devel] [PATCH 0/18] ocfs2: Add metadata ECC - almost there Joel Becker
2008-12-10 1:09 ` [PATCH 01/18] jbd2: Add buffer triggers Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] " Joel Becker
2008-12-11 19:57 ` Andreas Dilger
2008-12-13 0:45 ` Joel Becker
2008-12-13 0:45 ` [Ocfs2-devel] " Joel Becker
2008-12-18 18:08 ` Jan Kara
2008-12-18 18:08 ` Jan Kara
2008-12-19 0:32 ` Joel Becker
2008-12-19 0:32 ` [Ocfs2-devel] " Joel Becker
2008-12-19 0:40 ` Jan Kara
2008-12-19 0:40 ` Jan Kara
2008-12-19 1:43 ` Joel Becker
2008-12-19 1:43 ` [Ocfs2-devel] " Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 02/18] ocfs2: Add the on-disk structures for metadata checksums Joel Becker
2008-12-10 1:32 ` Tao Ma
2008-12-10 1:40 ` Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 03/18] ocfs2: Add the underlying blockcheck code Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 04/18] ocfs2: Add a validation hook for quota block reads Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 05/18] ocfs2: block read meta ecc Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 06/18] ocfs2: Add journal_access functions with jbd2 triggers Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 07/18] ocfs2: Wrap up the common use cases of ocfs2_new_path() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 08/18] ocfs2: Use metadata-specific ocfs2_journal_access_*() functions Joel Becker
2008-12-10 2:31 ` Tao Ma
2008-12-10 11:15 ` Joel Becker
2008-12-11 0:31 ` Tao Ma
2008-12-11 0:46 ` Joel Becker
2008-12-11 1:10 ` Tao Ma
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 09/18] ocfs2: Add ecc and checksums to ocfs2 xattr buckets Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 10/18] ocfs2: Create ocfs2_xattr_value_buf Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 11/18] ocfs2: Pull ocfs2_xattr_value_buf up from __ocfs2_remove_xattr_range() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 12/18] ocfs2: Pull ocfs2_xattr_value_buf up into ocfs2_xattr_value_truncate() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 13/18] ocfs2: Pass ocfs2_xattr_value_buf " Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 14/18] ocfs2: Pass value buf to ocfs2_xattr_update_entry() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 15/18] ocfs2: Use ocfs2_xattr_value_buf in ocfs2_xattr_set_entry() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 16/18] ocfs2: Pass value buf to ocfs2_remove_value_outside() Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 17/18] ocfs2: Use proper journal_access function in xattr.c Joel Becker
2008-12-10 1:09 ` [Ocfs2-devel] [PATCH 18/18] ocfs2: Enable metadata checksums Joel Becker
2008-12-10 1:52 ` [Ocfs2-devel] [PATCH 0/18] ocfs2: Add metadata ECC - almost there Joel Becker
2008-12-10 12:54 ` Andi Kleen
2008-12-10 18:15 ` Joel Becker
2008-12-10 19:27 ` Andi Kleen
2008-12-11 2:16 ` Joel Becker
2008-12-11 2:25 ` [Ocfs2-devel] [PATCH] ocfs2: Add directory block trailers Joel Becker
2008-12-11 2:25 ` Joel Becker [this message]
2008-12-11 2:46 ` [Ocfs2-devel] [PATCH 0/18] ocfs2: Add metadata ECC - almost there Tao Ma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081211022541.GN21455@mail.oracle.com \
--to=joel.becker@oracle.com \
--cc=ocfs2-devel@oss.oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.