fs: btrfs: Add more checksum algorithms
This mostly crossports crypto/hash.[ch] from btrfs-progs. The differences are: - No blake2 support No blake2 related library in U-Boot yet. - Use uboot xxhash/sha256 directly No need to implement the code as U-Boot has already provided the interface. This adds the support for the following csums: - SHA256 - XXHASH Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Marek Behún <marek.behun@nic.cz>
This commit is contained in:
		
							parent
							
								
									3b4b40c0d6
								
							
						
					
					
						commit
						565a4147d1
					
				|  | @ -3,4 +3,4 @@ | |||
| # 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
 | ||||
| 
 | ||||
| obj-y := btrfs.o chunk-map.o compression.o ctree.o dev.o dir-item.o \
 | ||||
| 	extent-io.o hash.o inode.o root.o subvolume.o super.o | ||||
| 	extent-io.o inode.o root.o subvolume.o super.o crypto/hash.o disk-io.o | ||||
|  |  | |||
|  | @ -5,11 +5,12 @@ | |||
|  * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz | ||||
|  */ | ||||
| 
 | ||||
| #include "btrfs.h" | ||||
| #include <config.h> | ||||
| #include <malloc.h> | ||||
| #include <uuid.h> | ||||
| #include <linux/time.h> | ||||
| #include "btrfs.h" | ||||
| #include "crypto/hash.h" | ||||
| 
 | ||||
| struct btrfs_info btrfs_info; | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,17 +23,6 @@ struct btrfs_info { | |||
| 
 | ||||
| extern struct btrfs_info btrfs_info; | ||||
| 
 | ||||
| /* hash.c */ | ||||
| void btrfs_hash_init(void); | ||||
| u32 btrfs_crc32c(u32, const void *, size_t); | ||||
| u32 btrfs_csum_data(char *, u32, size_t); | ||||
| void btrfs_csum_final(u32, void *); | ||||
| 
 | ||||
| static inline u64 btrfs_name_hash(const char *name, int len) | ||||
| { | ||||
| 	return btrfs_crc32c((u32) ~1, name, len); | ||||
| } | ||||
| 
 | ||||
| /* dev.c */ | ||||
| extern struct blk_desc *btrfs_blk_desc; | ||||
| extern struct disk_partition *btrfs_part_info; | ||||
|  |  | |||
|  | @ -0,0 +1,55 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+
 | ||||
| 
 | ||||
| #include <linux/xxhash.h> | ||||
| #include <linux/unaligned/access_ok.h> | ||||
| #include <linux/types.h> | ||||
| #include <u-boot/sha256.h> | ||||
| #include <u-boot/crc.h> | ||||
| 
 | ||||
| static u32 btrfs_crc32c_table[256]; | ||||
| 
 | ||||
| void btrfs_hash_init(void) | ||||
| { | ||||
| 	static int inited = 0; | ||||
| 
 | ||||
| 	if (!inited) { | ||||
| 		crc32c_init(btrfs_crc32c_table, 0x82F63B78); | ||||
| 		inited = 1; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int hash_sha256(const u8 *buf, size_t length, u8 *out) | ||||
| { | ||||
| 	sha256_context ctx; | ||||
| 
 | ||||
| 	sha256_starts(&ctx); | ||||
| 	sha256_update(&ctx, buf, length); | ||||
| 	sha256_finish(&ctx, out); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int hash_xxhash(const u8 *buf, size_t length, u8 *out) | ||||
| { | ||||
| 	u64 hash; | ||||
| 
 | ||||
| 	hash = xxh64(buf, length, 0); | ||||
| 	put_unaligned_le64(hash, out); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int hash_crc32c(const u8 *buf, size_t length, u8 *out) | ||||
| { | ||||
| 	u32 crc; | ||||
| 
 | ||||
| 	crc = crc32c_cal((u32)~0, (char *)buf, length, btrfs_crc32c_table); | ||||
| 	put_unaligned_le32(~crc, out); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| u32 crc32c(u32 seed, const void * data, size_t len) | ||||
| { | ||||
| 	return crc32c_cal(seed, data, len, btrfs_crc32c_table); | ||||
| } | ||||
|  | @ -0,0 +1,17 @@ | |||
| #ifndef CRYPTO_HASH_H | ||||
| #define CRYPTO_HASH_H | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #define CRYPTO_HASH_SIZE_MAX	32 | ||||
| 
 | ||||
| void btrfs_hash_init(void); | ||||
| int hash_crc32c(const u8 *buf, size_t length, u8 *out); | ||||
| int hash_xxhash(const u8 *buf, size_t length, u8 *out); | ||||
| int hash_sha256(const u8 *buf, size_t length, u8 *out); | ||||
| 
 | ||||
| u32 crc32c(u32 seed, const void * data, size_t len); | ||||
| 
 | ||||
| /* Blake2B is not yet supported due to lack of library */ | ||||
| 
 | ||||
| #endif | ||||
|  | @ -6,6 +6,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "btrfs.h" | ||||
| #include "disk-io.h" | ||||
| 
 | ||||
| static int verify_dir_item(struct btrfs_dir_item *item, u32 start, u32 total) | ||||
| { | ||||
|  |  | |||
|  | @ -0,0 +1,22 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+
 | ||||
| #include <common.h> | ||||
| #include <fs_internal.h> | ||||
| #include "disk-io.h" | ||||
| #include "crypto/hash.h" | ||||
| 
 | ||||
| int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len) | ||||
| { | ||||
| 	memset(out, 0, BTRFS_CSUM_SIZE); | ||||
| 
 | ||||
| 	switch (csum_type) { | ||||
| 	case BTRFS_CSUM_TYPE_CRC32: | ||||
| 		return hash_crc32c(data, len, out); | ||||
| 	case BTRFS_CSUM_TYPE_XXHASH: | ||||
| 		return hash_xxhash(data, len, out); | ||||
| 	case BTRFS_CSUM_TYPE_SHA256: | ||||
| 		return hash_sha256(data, len, out); | ||||
| 	default: | ||||
| 		printf("Unknown csum type %d\n", csum_type); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,20 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+
 | ||||
| #ifndef __BTRFS_DISK_IO_H__ | ||||
| #define __BTRFS_DISK_IO_H__ | ||||
| 
 | ||||
| #include "crypto/hash.h" | ||||
| #include "ctree.h" | ||||
| #include "disk-io.h" | ||||
| 
 | ||||
| static inline u64 btrfs_name_hash(const char *name, int len) | ||||
| { | ||||
| 	u32 crc; | ||||
| 
 | ||||
| 	crc = crc32c((u32)~1, (unsigned char *)name, len); | ||||
| 
 | ||||
| 	return (u64)crc; | ||||
| } | ||||
| 
 | ||||
| int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,38 +0,0 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+
 | ||||
| /*
 | ||||
|  * BTRFS filesystem implementation for U-Boot | ||||
|  * | ||||
|  * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz | ||||
|  */ | ||||
| 
 | ||||
| #include "btrfs.h" | ||||
| #include <u-boot/crc.h> | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
| static u32 btrfs_crc32c_table[256]; | ||||
| 
 | ||||
| void btrfs_hash_init(void) | ||||
| { | ||||
| 	static int inited = 0; | ||||
| 
 | ||||
| 	if (!inited) { | ||||
| 		crc32c_init(btrfs_crc32c_table, 0x82F63B78); | ||||
| 		inited = 1; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| u32 btrfs_crc32c(u32 crc, const void *data, size_t length) | ||||
| { | ||||
| 	return crc32c_cal(crc, (const char *) data, length, | ||||
| 			  btrfs_crc32c_table); | ||||
| } | ||||
| 
 | ||||
| u32 btrfs_csum_data(char *data, u32 seed, size_t len) | ||||
| { | ||||
| 	return btrfs_crc32c(seed, data, len); | ||||
| } | ||||
| 
 | ||||
| void btrfs_csum_final(u32 crc, void *result) | ||||
| { | ||||
| 	put_unaligned(cpu_to_le32(~crc), (u32 *)result); | ||||
| } | ||||
|  | @ -11,6 +11,7 @@ | |||
| #include <part.h> | ||||
| #include <linux/compat.h> | ||||
| #include "btrfs.h" | ||||
| #include "disk-io.h" | ||||
| 
 | ||||
| #define BTRFS_SUPER_FLAG_SUPP	(BTRFS_HEADER_FLAG_WRITTEN	\ | ||||
| 				 | BTRFS_HEADER_FLAG_RELOC	\ | ||||
|  | @ -61,19 +62,19 @@ static int btrfs_check_super_csum(char *raw_disk_sb) | |||
| 		(struct btrfs_super_block *) raw_disk_sb; | ||||
| 	u16 csum_type = le16_to_cpu(disk_sb->csum_type); | ||||
| 
 | ||||
| 	if (csum_type == BTRFS_CSUM_TYPE_CRC32) { | ||||
| 		u32 crc = ~(u32) 0; | ||||
| 		const int csum_size = sizeof(crc); | ||||
| 		char result[csum_size]; | ||||
| 	if (csum_type == BTRFS_CSUM_TYPE_CRC32 || | ||||
| 	    csum_type == BTRFS_CSUM_TYPE_SHA256 || | ||||
| 	    csum_type == BTRFS_CSUM_TYPE_XXHASH) { | ||||
| 		u8 result[BTRFS_CSUM_SIZE]; | ||||
| 
 | ||||
| 		crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE, crc, | ||||
| 				      BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); | ||||
| 		btrfs_csum_final(crc, result); | ||||
| 		btrfs_csum_data(csum_type, (u8 *)raw_disk_sb + BTRFS_CSUM_SIZE, | ||||
| 			result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); | ||||
| 
 | ||||
| 		if (memcmp(raw_disk_sb, result, csum_size)) | ||||
| 			return -1; | ||||
| 	} else { | ||||
| 		return -1; | ||||
| 		if (memcmp(raw_disk_sb, result, BTRFS_CSUM_SIZE)) | ||||
| 			return -EIO; | ||||
| 	} else if (csum_type == BTRFS_CSUM_TYPE_BLAKE2) { | ||||
| 		printf("Blake2 csum type is not supported yet\n"); | ||||
| 		return -ENOTSUPP; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue