-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix endianness issues with zstd #12022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#if defined(__sparc) | ||
uint64_t __bswapdi2(uint64_t in); | ||
uint32_t __bswapsi2(uint32_t in); | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -380,6 +380,7 @@ zstd_enum_to_level(enum zio_zstd_levels level, int16_t *zstd_level) | |
return (1); | ||
} | ||
|
||
|
||
/* Compress block using zstd */ | ||
size_t | ||
zfs_zstd_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, | ||
|
@@ -477,8 +478,8 @@ zfs_zstd_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, | |
* As soon as such incompatibility occurs, handling code needs to be | ||
* added, differentiating between the versions. | ||
*/ | ||
hdr->version = ZSTD_VERSION_NUMBER; | ||
hdr->level = level; | ||
zfs_set_hdrversion(hdr, ZSTD_VERSION_NUMBER); | ||
zfs_set_hdrlevel(hdr, level); | ||
hdr->raw_version_level = BE_32(hdr->raw_version_level); | ||
|
||
return (c_len + sizeof (*hdr)); | ||
|
@@ -504,6 +505,7 @@ zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len, | |
* not modify the original data that may be used again later. | ||
*/ | ||
hdr_copy.raw_version_level = BE_32(hdr->raw_version_level); | ||
uint8_t curlevel = zfs_get_hdrlevel(&hdr_copy); | ||
|
||
/* | ||
* NOTE: We ignore the ZSTD version for now. As soon as any | ||
|
@@ -516,13 +518,13 @@ zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len, | |
* An invalid level is a strong indicator for data corruption! In such | ||
* case return an error so the upper layers can try to fix it. | ||
*/ | ||
if (zstd_enum_to_level(hdr_copy.level, &zstd_level)) { | ||
if (zstd_enum_to_level(curlevel, &zstd_level)) { | ||
ZSTDSTAT_BUMP(zstd_stat_dec_inval); | ||
return (1); | ||
} | ||
|
||
ASSERT3U(d_len, >=, s_len); | ||
ASSERT3U(hdr_copy.level, !=, ZIO_COMPLEVEL_INHERIT); | ||
ASSERT3U(curlevel, !=, ZIO_COMPLEVEL_INHERIT); | ||
|
||
/* Invalid compressed buffer size encoded at start */ | ||
if (c_len + sizeof (*hdr) > s_len) { | ||
|
@@ -553,7 +555,7 @@ zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len, | |
} | ||
|
||
if (level) { | ||
*level = hdr_copy.level; | ||
*level = curlevel; | ||
} | ||
|
||
return (0); | ||
|
@@ -783,7 +785,7 @@ module_exit(zstd_fini); | |
|
||
ZFS_MODULE_DESCRIPTION("ZSTD Compression for ZFS"); | ||
ZFS_MODULE_LICENSE("Dual BSD/GPL"); | ||
ZFS_MODULE_VERSION(ZSTD_VERSION_STRING); | ||
ZFS_MODULE_VERSION(ZSTD_VERSION_STRING "a"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this solely for debugging? I don't think we really need to change the version string here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, not for debugging. While working on this, I saw a number of times where DKMS explicitly printed "hey the version's the same, so I don't have to replace the module" before I started just using the kmod targets. Plus, even ignoring DKMS doing that, if we get reports of this problem happening in distro packages, not being able to check if this was applied short of going and fetching the source seems unnecessarily difficult. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking the OpenZFS version doesn't seem like it would be too onerous. Personally I'd suggest we drop the appended "a" suffix, but if you'd prefer to keep it I'm fine with that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather keep it, if only so that if someone cherrypicks this and doesn't change the version they tell DKMS, there's no chance it'll keep the old zstd.ko. Obviously there's no need to keep it if the version bumps in the future, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...come to think of it, why does it make sense for zzstd.ko to have the zstd version number? It's not like it's going to get updated independently of the rest of the codebase or used by not-ZFS consumers, and as in this example, it probably still makes sense to encode the version the rest of the codebase is using in the string even if we want to expose the zstd version somewhere? Oh well, a question for a future PR. |
||
|
||
EXPORT_SYMBOL(zfs_zstd_compress); | ||
EXPORT_SYMBOL(zfs_zstd_decompress_level); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifdef __sparc__ | ||
#include <stdint.h> | ||
#include <sys/byteorder.h> | ||
#include "include/sparc_compat.h" | ||
uint64_t __bswapdi2(uint64_t in) { | ||
return (BSWAP_64(in)); | ||
} | ||
uint32_t __bswapsi2(uint32_t in) { | ||
return (BSWAP_32(in)); | ||
} | ||
#endif |
Uh oh!
There was an error while loading. Please reload this page.