diff options
author | Tim Chase <[email protected]> | 2017-11-08 15:32:15 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-11-08 13:32:15 -0800 |
commit | 71a24c3c52f6223f54e6351b57e089791aa3b2f1 (patch) | |
tree | b0a33be5693236c9524b50b6ef4aa1b943a518ac /module/zfs/arc.c | |
parent | eef005d882dfaa2ffddfeea5d70ff27aadee344a (diff) |
Handle compressed buffers in __dbuf_hold_impl()
In __dbuf_hold_impl(), if a buffer is currently syncing and is still
referenced from db_data, a copy is made in case it is dirtied again in
the txg. Previously, the buffer for the copy was simply allocated with
arc_alloc_buf() which doesn't handle compressed or encrypted buffers
(which are a special case of a compressed buffer). The result was
typically an invalid memory access because the newly-allocated buffer
was of the uncompressed size.
This commit fixes the problem by handling the 2 compressed cases,
encrypted and unencrypted, respectively, with arc_alloc_raw_buf() and
arc_alloc_compressed_buf().
Although using the proper allocation functions fixes the invalid memory
access by allocating a buffer of the compressed size, another unrelated
issue made it impossible to properly detect compressed buffers in the
first place. The header's compression flag was set to ZIO_COMPRESS_OFF
in arc_write() when it was possible that an attached buffer was actually
compressed. This commit adds logic to only set ZIO_COMPRESS_OFF in
the non-ZIO_RAW case which wil handle both cases of compressed buffers
(encrypted or unencrypted).
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes #5742
Closes #6797
Diffstat (limited to 'module/zfs/arc.c')
-rw-r--r-- | module/zfs/arc.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 35f24d5d8..cd343b04e 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -6931,7 +6931,8 @@ arc_write(zio_t *pio, spa_t *spa, uint64_t txg, if (HDR_HAS_RABD(hdr)) arc_hdr_free_abd(hdr, B_TRUE); - arc_hdr_set_compress(hdr, ZIO_COMPRESS_OFF); + if (!(zio_flags & ZIO_FLAG_RAW)) + arc_hdr_set_compress(hdr, ZIO_COMPRESS_OFF); ASSERT(!arc_buf_is_shared(buf)); ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL); |