summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-01-07 17:06:22 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2022-10-03 22:51:10 -0400
commit4d93decb1862ea221f18f102190b522e1a4a3482 (patch)
tree45fb5a7b532a3b3f21c5fad935dcb47c5b5c204d
parentc76ffaec959cf16b72bac9619278951da9cef837 (diff)
bcachefs: Work around a zstd bug
The zstd compression code seems to have a bug where it will write just past the end of the destination buffer - probably only when the compressed output isn't going to fit in the destination buffer, which will never happen if you're always allocating a bigger buffer than the source buffer which would explain other users not hitting it. But, we size the buffer according to how much contiguous space on disk we have, so... generally, bugs like this don't write more than a word past the end of the buffer, so an easy workaround is to subtract a fudge factor from the buffer size. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/compress.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c
index 27bbc265d550..78757dcede36 100644
--- a/fs/bcachefs/compress.c
+++ b/fs/bcachefs/compress.c
@@ -336,8 +336,19 @@ static int attempt_compress(struct bch_fs *c,
ZSTD_CCtx *ctx = zstd_init_cctx(workspace,
zstd_cctx_workspace_bound(&c->zstd_params.cParams));
+ /*
+ * ZSTD requires that when we decompress we pass in the exact
+ * compressed size - rounding it up to the nearest sector
+ * doesn't work, so we use the first 4 bytes of the buffer for
+ * that.
+ *
+ * Additionally, the ZSTD code seems to have a bug where it will
+ * write just past the end of the buffer - so subtract a fudge
+ * factor (7 bytes) from the dst buffer size to account for
+ * that.
+ */
size_t len = zstd_compress_cctx(ctx,
- dst + 4, dst_len - 4,
+ dst + 4, dst_len - 4 - 7,
src, src_len,
&c->zstd_params);
if (zstd_is_error(len))