From: Edward Shishkin <edward.shishkin@gmail.com>
To: ReiserFS development mailing list <reiserfs-devel@vger.kernel.org>
Subject: [PATCH 1/3] reiser4: add metadata checksums support
Date: Sun, 16 Aug 2015 20:15:27 +0200 [thread overview]
Message-ID: <55D0D33F.4050901@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: reiser4-metadata-checksums.patch-1 --]
[-- Type: text/plain, Size: 8643 bytes --]
---
fs/reiser4/Makefile | 1
fs/reiser4/checksum.c | 29 ++++++++++++++++++++++++++
fs/reiser4/checksum.h | 39 +++++++++++++++++++++++++++++++++++
fs/reiser4/plugin/node/node.c | 3 +-
fs/reiser4/plugin/node/node.h | 3 ++
fs/reiser4/plugin/node/node41.c | 44 +++++++++++++++++++++++++++++++---------
fs/reiser4/plugin/node/node41.h | 2 +
fs/reiser4/super.h | 1
fs/reiser4/super_ops.c | 7 ++++++
fs/reiser4/wander.c | 13 ++++++++++-
fs/reiser4/znode.c | 3 --
fs/reiser4/znode.h | 1
12 files changed, 133 insertions(+), 13 deletions(-)
--- a/fs/reiser4/plugin/node/node.h
+++ b/fs/reiser4/plugin/node/node.h
@@ -233,6 +233,9 @@ typedef struct node_plugin {
/* change plugin id of items which are in a node already. Currently it is Used in tail conversion for regular
* files */
int (*set_item_plugin) (coord_t * coord, item_id);
+ /* calculate and check/update znode's checksum
+ (if @check is true, then check, otherwise update) */
+ int (*csum)(znode *node, int check);
} node_plugin;
typedef enum {
--- a/fs/reiser4/Makefile
+++ b/fs/reiser4/Makefile
@@ -48,6 +48,7 @@ reiser4-y := \
safe_link.o \
blocknrlist.o \
discard.o \
+ checksum.o \
\
plugin/plugin.o \
plugin/plugin_set.o \
--- /dev/null
+++ b/fs/reiser4/checksum.c
@@ -0,0 +1,29 @@
+#include <linux/err.h>
+#include "debug.h"
+#include "checksum.h"
+
+int reiser4_init_csum_tfm(struct crypto_shash **tfm)
+{
+ *tfm = crypto_alloc_shash("crc32c", 0, 0);
+ if (IS_ERR(*tfm)) {
+ *tfm = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+void reiser4_done_csum_tfm(struct crypto_shash *tfm)
+{
+ crypto_free_shash(tfm);
+}
+
+/*
+ Local variables:
+ c-indentation-style: "K&R"
+ mode-name: "LC"
+ c-basic-offset: 8
+ tab-width: 8
+ fill-column: 120
+ scroll-step: 1
+ End:
+*/
--- /dev/null
+++ b/fs/reiser4/checksum.h
@@ -0,0 +1,39 @@
+#ifndef __CHECKSUM__
+#define __CHECKSUM__
+
+#include <crypto/hash.h>
+
+int reiser4_init_csum_tfm(struct crypto_shash **tfm);
+void reiser4_done_csum_tfm(struct crypto_shash *tfm);
+u32 static inline reiser4_crc32c(struct crypto_shash *tfm,
+ u32 crc, const void *address,
+ unsigned int length)
+{
+ struct {
+ struct shash_desc shash;
+ char ctx[4];
+ } desc;
+ int err;
+
+ desc.shash.tfm = tfm;
+ desc.shash.flags = 0;
+ *(u32 *)desc.ctx = crc;
+
+ err = crypto_shash_update(&desc.shash, address, length);
+ BUG_ON(err);
+ return *(u32 *)desc.ctx;
+}
+
+#endif /* __CHECKSUM__ */
+
+/*
+ Local variables:
+ c-indentation-style: "K&R"
+ mode-name: "LC"
+ c-basic-offset: 8
+ tab-width: 8
+ fill-column: 120
+ scroll-step: 1
+ End:
+*/
+
--- a/fs/reiser4/plugin/node/node.c
+++ b/fs/reiser4/plugin/node/node.c
@@ -153,7 +153,8 @@ node_plugin node_plugins[LAST_NODE_ID] =
.fast_cut = fast_cut_node40,
.max_item_size = max_item_size_node41,
.prepare_removal = prepare_removal_node40,
- .set_item_plugin = set_item_plugin_node40
+ .set_item_plugin = set_item_plugin_node40,
+ .csum = csum_node41
}
};
--- a/fs/reiser4/super_ops.c
+++ b/fs/reiser4/super_ops.c
@@ -6,6 +6,7 @@
#include "ktxnmgrd.h"
#include "flush.h"
#include "safe_link.h"
+#include "checksum.h"
#include <linux/vfs.h>
#include <linux/writeback.h>
@@ -249,6 +250,7 @@ static void reiser4_put_super(struct sup
get_super_private(super)->df_plug->release(super);
reiser4_done_formatted_fake(super);
+ reiser4_done_csum_tfm(sbinfo->csum_tfm);
/* stop daemons: ktxnmgr and entd */
reiser4_done_entd(super);
@@ -514,6 +516,10 @@ static int fill_super(struct super_block
goto failed_init_sinfo;
sbinfo = get_super_private(super);
+
+ if ((result = reiser4_init_csum_tfm(&sbinfo->csum_tfm)) != 0)
+ goto failed_init_csum_tfm;
+
/* initialize various reiser4 parameters, parse mount options */
if ((result = reiser4_init_super_data(super, data)) != 0)
goto failed_init_super_data;
@@ -592,6 +598,7 @@ static int fill_super(struct super_block
failed_init_super_data:
reiser4_done_fs_info(super);
failed_init_sinfo:
+ failed_init_csum_tfm:
reiser4_exit_context(&ctx);
return result;
}
--- a/fs/reiser4/plugin/node/node41.c
+++ b/fs/reiser4/plugin/node/node41.c
@@ -17,6 +17,7 @@
#include "../../tap.h"
#include "../../tree.h"
#include "../../super.h"
+#include "../../checksum.h"
#include "../../reiser4.h"
#include <asm/uaccess.h>
@@ -27,7 +28,7 @@
* node41 layout it almost the same as node40:
* node41_header is at the beginning and a table of item headers
* is at the end. Ther difference is that node41_header contains
- * a 32-bit reference counter (see node41.h)
+ * a 32-bit checksum (see node41.h)
*/
static const __u32 REISER4_NODE41_MAGIC = 0x19051966;
@@ -41,12 +42,43 @@ static inline node41_header *node41_node
return (node41_header *)zdata(node);
}
+int csum_node41(znode *node, int check)
+{
+ __u32 cpu_csum;
+
+ cpu_csum = reiser4_crc32c(get_current_super_private()->csum_tfm,
+ ~0,
+ zdata(node),
+ sizeof(struct node40_header));
+ cpu_csum = reiser4_crc32c(get_current_super_private()->csum_tfm,
+ cpu_csum,
+ zdata(node) + sizeof(struct node41_header),
+ reiser4_get_current_sb()->s_blocksize -
+ sizeof(node41_header));
+ if (check)
+ return cpu_csum == nh41_get_csum(node41_node_header(node));
+ else {
+ nh41_set_csum(node41_node_header(node), cpu_csum);
+ return 1;
+ }
+}
+
/*
* plugin->u.node.parse
* look for description of this method in plugin/node/node.h
*/
int parse_node41(znode *node /* node to parse */)
{
+ int ret;
+
+ ret = csum_node41(node, 1/* check */);
+ if (!ret) {
+ warning("edward-1645",
+ "block %llu: bad checksum. FSCK?",
+ *jnode_get_block(ZJNODE(node)));
+ reiser4_handle_error();
+ return RETERR(-EIO);
+ }
return parse_node40_common(node, REISER4_NODE41_MAGIC);
}
@@ -56,14 +88,8 @@ int parse_node41(znode *node /* node to
*/
int init_node41(znode *node /* node to initialise */)
{
- node41_header *header41;
-
- init_node40_common(node, node_plugin_by_id(NODE41_ID),
- sizeof(node41_header), REISER4_NODE41_MAGIC);
-
- header41 = node41_node_header(node);
- nh41_set_csum(header41, 0);
- return 0;
+ return init_node40_common(node, node_plugin_by_id(NODE41_ID),
+ sizeof(node41_header), REISER4_NODE41_MAGIC);
}
/*
--- a/fs/reiser4/plugin/node/node41.h
+++ b/fs/reiser4/plugin/node/node41.h
@@ -29,10 +29,12 @@ int max_item_size_node41(void);
int shift_node41(coord_t *from, znode *to, shift_direction pend,
int delete_child, int including_stop_coord,
carry_plugin_info *info);
+int csum_node41(znode *node, int check);
#ifdef GUESS_EXISTS
int guess_node41(const znode * node);
#endif
+extern void reiser4_handle_error(void);
/* __REISER4_NODE41_H__ */
#endif
--- a/fs/reiser4/znode.c
+++ b/fs/reiser4/znode.c
@@ -635,7 +635,7 @@ int zload_ra(znode * node /* znode to lo
}
/* load content of node into memory */
-int zload(znode * node)
+int zload(znode *node)
{
return zload_ra(node, NULL);
}
@@ -651,7 +651,6 @@ int zinit_new(znode * node /* znode to i
void zrelse(znode * node /* znode to release references to */ )
{
assert("nikita-1381", znode_invariant(node));
-
jrelse(ZJNODE(node));
}
--- a/fs/reiser4/super.h
+++ b/fs/reiser4/super.h
@@ -275,6 +275,7 @@ struct reiser4_super_info_data {
* more details
*/
struct d_cursor_info d_info;
+ struct crypto_shash *csum_tfm;
#ifdef CONFIG_REISER4_BADBLOCKS
/* Alternative master superblock offset (in bytes) */
--- a/fs/reiser4/wander.c
+++ b/fs/reiser4/wander.c
@@ -769,8 +769,19 @@ static int write_jnodes_to_disk_extent(
JF_SET(cur, JNODE_WRITEBACK);
JF_CLR(cur, JNODE_DIRTY);
ON_DEBUG(cur->written++);
- spin_unlock_jnode(cur);
+ assert("edward-1647",
+ ergo(jnode_is_znode(cur), JF_ISSET(cur, JNODE_PARSED)));
+ spin_unlock_jnode(cur);
+ /*
+ * update checksum
+ */
+ if (jnode_is_znode(cur)) {
+ zload(JZNODE(cur));
+ if (node_plugin_by_node(JZNODE(cur))->csum)
+ node_plugin_by_node(JZNODE(cur))->csum(JZNODE(cur), 0);
+ zrelse(JZNODE(cur));
+ }
ClearPageError(pg);
set_page_writeback(pg);
--- a/fs/reiser4/znode.h
+++ b/fs/reiser4/znode.h
@@ -172,6 +172,7 @@ extern int zload_ra(znode * node, ra_inf
extern int zinit_new(znode * node, gfp_t gfp_flags);
extern void zrelse(znode * node);
extern void znode_change_parent(znode * new_parent, reiser4_block_nr * block);
+extern void znode_update_csum(znode *node);
/* size of data in znode */
static inline unsigned
next reply other threads:[~2015-08-16 18:15 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-16 18:15 Edward Shishkin [this message]
-- strict thread matches above, loose matches on Subject: below --
2015-08-16 13:22 [PATCH 1/3] reiser4: add metadata checksums support Edward Shishkin
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=55D0D33F.4050901@gmail.com \
--to=edward.shishkin@gmail.com \
--cc=reiserfs-devel@vger.kernel.org \
/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.