From: Christoph Hellwig <hch@lst.de>
To: xfs@oss.sgi.com
Subject: [PATCH 4/9] add infrastructure for crc in metadata
Date: Fri, 26 Sep 2008 00:56:29 +0200 [thread overview]
Message-ID: <20080925225629.GE9822@lst.de> (raw)
[-- Attachment #1: xfs-crc-bit --]
[-- Type: text/plain, Size: 7561 bytes --]
- add a mount feature bit for CRC enabled filesystems
- add some helpers for generating and verifying the CRCs
- add a copy_uuid helper
- add a pre-io callback to xfs_buf for calculating the CRCs
The checksumming helpers are losely based on similar ones in sctp,
all other bits come from Dave Chinner.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6-xfs/fs/xfs/Kconfig
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/Kconfig 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/Kconfig 2008-09-25 20:04:58.000000000 +0200
@@ -1,6 +1,6 @@
config XFS_FS
tristate "XFS filesystem support"
- depends on BLOCK
+ depends on BLOCK && LIBCRC32C
help
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_linux.h
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_linux.h 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_linux.h 2008-09-25 20:04:58.000000000 +0200
@@ -77,6 +77,7 @@
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/ctype.h>
+#include <linux/crc32c.h>
#include <asm/page.h>
#include <asm/div64.h>
Index: linux-2.6-xfs/fs/xfs/xfs_sb.h
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/xfs_sb.h 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/xfs_sb.h 2008-09-25 20:05:06.000000000 +0200
@@ -79,10 +79,12 @@ struct xfs_mount;
#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */
#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
+#define XFS_SB_VERSION2_CRCBIT 0x00000020 /* metadata has CRCs */
#define XFS_SB_VERSION2_OKREALFBITS \
(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
- XFS_SB_VERSION2_ATTR2BIT)
+ XFS_SB_VERSION2_ATTR2BIT | \
+ XFS_SB_VERSION2_CRCBIT)
#define XFS_SB_VERSION2_OKSASHFBITS \
(0)
#define XFS_SB_VERSION2_OKREALBITS \
@@ -494,6 +496,12 @@ static inline void xfs_sb_version_remove
sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
}
+static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp)
+{
+ return (xfs_sb_version_hasmorebits(sbp) &&
+ (sbp->sb_features2 & XFS_SB_VERSION2_CRCBIT));
+}
+
/*
* end of superblock version macros
*/
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_buf.c
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_buf.c 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_buf.c 2008-09-25 20:04:58.000000000 +0200
@@ -1179,6 +1179,14 @@ _xfs_buf_ioapply(
(bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
}
+ /*
+ * call out to buffer specific pre-write I/O functions. Used for
+ * validation of buffers and CRC calculations prior to I/O issue.
+ */
+ if (bp->b_io_callback && (bp->b_flags & XBF_WRITE))
+ bp->b_io_callback(bp);
+
+
/* Special code path for reading a sub page size buffer in --
* we populate up the whole page, and hence the other metadata
* in the same page. This optimization is only valid when the
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_buf.h
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_buf.h 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_buf.h 2008-09-25 20:04:58.000000000 +0200
@@ -166,6 +166,8 @@ typedef struct xfs_buf {
unsigned int b_offset; /* page offset in first page */
struct page **b_pages; /* array of page pointers */
struct page *b_page_array[XB_PAGES]; /* inline pages */
+ void (*b_io_callback)(struct xfs_buf *);
+ /* pre-write I/O callback */
#ifdef XFS_BUF_LOCK_TRACKING
int b_last_holder;
#endif
@@ -228,6 +230,16 @@ static inline int xfs_buf_geterror(xfs_b
/* Buffer Utility Routines */
extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t);
+/*
+ * Set the function that should be called immediately prior
+ * to a write I/O being issued on this buffer.
+ */
+static inline void
+xfs_buf_set_io_callback(xfs_buf_t *bp, void (*func)(xfs_buf_t *))
+{
+ bp->b_io_callback = func;
+}
+
/* Pinning Buffer Storage in Memory */
extern void xfs_buf_pin(xfs_buf_t *);
extern void xfs_buf_unpin(xfs_buf_t *);
Index: linux-2.6-xfs/fs/xfs/support/uuid.c
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/support/uuid.c 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/support/uuid.c 2008-09-25 20:04:58.000000000 +0200
@@ -72,6 +72,12 @@ uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
}
+void
+uuid_copy(uuid_t *dst, uuid_t *src)
+{
+ memcpy(dst, src, sizeof(uuid_t));
+}
+
/*
* Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
* 64-bit words. NOTE: This function can not be changed EVER. Although
Index: linux-2.6-xfs/fs/xfs/support/uuid.h
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/support/uuid.h 2008-09-25 20:04:39.000000000 +0200
+++ linux-2.6-xfs/fs/xfs/support/uuid.h 2008-09-25 20:04:58.000000000 +0200
@@ -25,6 +25,7 @@ typedef struct {
extern void uuid_create_nil(uuid_t *uuid);
extern int uuid_is_nil(uuid_t *uuid);
extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
+extern void uuid_copy(uuid_t *dst, uuid_t *src);
extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
extern __uint64_t uuid_hash64(uuid_t *uuid);
extern int uuid_table_insert(uuid_t *uuid);
Index: linux-2.6-xfs/fs/xfs/xfs_cksum.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-xfs/fs/xfs/xfs_cksum.h 2008-09-25 20:09:52.000000000 +0200
@@ -0,0 +1,62 @@
+#ifndef _XFS_CKSUM_H
+#define _XFS_CKSUM_H 1
+
+#define XFS_CRC_SEED (~(__uint32_t)0)
+
+/*
+ * Calculate the intermediate checksum for a buffer that has the CRC field
+ * inside it. The offset of the 32bit crc fields is passed as the
+ * cksum_offset parameter.
+ */
+static inline __uint32_t
+xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t zero = 0;
+ __uint32_t crc;
+
+ /* Calculate CRC up to the checksum. */
+ crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset);
+
+ /* Skip checksum field */
+ crc = crc32c(crc, &zero, sizeof(__u32));
+
+ /* Calculate the rest of the CRC. */
+ return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)],
+ length - (cksum_offset + sizeof(__be32)));
+}
+
+/*
+ * Convert the intermediate checksum to the final ondisk format.
+ *
+ * Note that crc32c is already endianess agnostic, so no additional
+ * byte swap is needed.
+ */
+static inline __be32
+xfs_end_cksum(__uint32_t crc)
+{
+ return (__force __be32)~crc;
+}
+
+/*
+ * Helper to generate the checksum for a buffer.
+ */
+static inline void
+xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+
+ *(__be32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
+}
+
+/*
+ * Helper to verify the checksum for a buffer.
+ */
+static inline int
+xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+
+ return *(__be32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
+}
+
+#endif /* _XFS_CKSUM_H */
--
next reply other threads:[~2008-09-25 22:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-25 22:56 Christoph Hellwig [this message]
2008-10-29 19:12 ` [PATCH 4/9] add infrastructure for crc in metadata Bill O'Donnell
2008-12-02 13:05 ` Bill O'Donnell
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=20080925225629.GE9822@lst.de \
--to=hch@lst.de \
--cc=xfs@oss.sgi.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.