Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01b5adce authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Theodore Ts'o
Browse files

jbd2: Grab a reference to the crc32c driver if necessary



Obtain a reference to the crc32c driver if needed for the v2 checksum.

Signed-off-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 25ed6e8a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
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
+25 −0
Original line number Diff line number Diff line
@@ -1438,6 +1438,17 @@ 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)) {
			printk(KERN_ERR "JBD: Cannot load crc32c driver.\n");
			err = PTR_ERR(journal->j_chksum_driver);
			journal->j_chksum_driver = NULL;
			goto out;
		}
	}

	set_buffer_verified(bh);

	return 0;
@@ -1591,6 +1602,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);

@@ -1707,6 +1720,18 @@ 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)) {
				printk(KERN_ERR "JBD: Cannot load crc32c "
				       "driver.\n");
				journal->j_chksum_driver = NULL;
				return 0;
			}
		}
	}

	/* If enabling v1 checksums, downgrade superblock */
+23 −0
Original line number Diff line number Diff line
@@ -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
@@ -965,6 +966,9 @@ struct journal_s
	 * superblock pointer here
	 */
	void *j_private;

	/* Reference to checksum algorithm driver via cryptoapi */
	struct crypto_shash *j_chksum_driver;
};

/*
@@ -1294,6 +1298,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)