lkml.org 
[lkml]   [2011]   [Nov]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 17/22] jbd2: Grab a reference to the crc32c driver only when necessary
    From
    Date
    Obtain a reference to the crc32c driver only when the journal needs it for
    checksum v2.

    Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
    ---
    fs/jbd2/Kconfig | 2 ++
    fs/jbd2/journal.c | 22 ++++++++++++++++++++++
    include/linux/jbd2.h | 23 +++++++++++++++++++++++
    3 files changed, 47 insertions(+), 0 deletions(-)


    diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig
    index f32f346..69a48c2 100644
    --- a/fs/jbd2/Kconfig
    +++ b/fs/jbd2/Kconfig
    @@ -1,6 +1,8 @@
    config JBD2
    tristate
    select CRC32
    + select CRYPTO
    + select CRYPTO_CRC32C
    help
    This is a generic journaling layer for block devices that support
    both 32-bit and 64-bit block numbers. It is currently used by
    diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
    index 300b46f..fbf86ee 100644
    --- a/fs/jbd2/journal.c
    +++ b/fs/jbd2/journal.c
    @@ -1284,6 +1284,16 @@ static int journal_get_superblock(journal_t *journal)
    goto out;
    }

    + /* Load the checksum driver */
    + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) {
    + journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
    + if (IS_ERR(journal->j_chksum_driver)) {
    + err = PTR_ERR(journal->j_chksum_driver);
    + journal->j_chksum_driver = NULL;
    + goto out;
    + }
    + }
    +
    set_buffer_verified(bh);

    return 0;
    @@ -1440,6 +1450,8 @@ int jbd2_journal_destroy(journal_t *journal)
    iput(journal->j_inode);
    if (journal->j_revoke)
    jbd2_journal_destroy_revoke(journal);
    + if (journal->j_chksum_driver)
    + crypto_free_shash(journal->j_chksum_driver);
    kfree(journal->j_wbuf);
    kfree(journal);

    @@ -1556,6 +1568,16 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
    sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
    sb->s_feature_compat &=
    ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
    +
    + /* Load the checksum driver */
    + if (journal->j_chksum_driver == NULL) {
    + journal->j_chksum_driver = crypto_alloc_shash("crc32c",
    + 0, 0);
    + if (IS_ERR(journal->j_chksum_driver)) {
    + journal->j_chksum_driver = NULL;
    + return 0;
    + }
    + }
    }

    /* If enabling v1 checksums, downgrade superblock */
    diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
    index 4ead3d5..88af51f 100644
    --- a/include/linux/jbd2.h
    +++ b/include/linux/jbd2.h
    @@ -31,6 +31,7 @@
    #include <linux/mutex.h>
    #include <linux/timer.h>
    #include <linux/slab.h>
    +#include <crypto/hash.h>
    #endif

    #define journal_oom_retry 1
    @@ -945,6 +946,9 @@ struct journal_s

    /* Precomputed UUID checksum */
    __u32 j_uuid_csum;
    +
    + /* Reference to checksum algorithm driver via cryptoapi */
    + struct crypto_shash *j_chksum_driver;
    };

    /*
    @@ -1263,6 +1267,25 @@ static inline int jbd_space_needed(journal_t *journal)

    extern int jbd_blocks_per_page(struct inode *inode);

    +static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
    + const void *address, unsigned int length)
    +{
    + struct {
    + struct shash_desc shash;
    + char ctx[crypto_shash_descsize(journal->j_chksum_driver)];
    + } desc;
    + int err;
    +
    + desc.shash.tfm = journal->j_chksum_driver;
    + desc.shash.flags = 0;
    + *(u32 *)desc.ctx = crc;
    +
    + err = crypto_shash_update(&desc.shash, address, length);
    + BUG_ON(err);
    +
    + return *(u32 *)desc.ctx;
    +}
    +
    #ifdef __KERNEL__

    #define buffer_trace_init(bh) do {} while (0)


    \
     
     \ /
      Last update: 2011-11-29 00:31    [W:4.136 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site