mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
Illumos 4757, 4913
4757 ZFS embedded-data block pointers ("zero block compression")
4913 zfs release should not be subject to space checks
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>
References:
https://www.illumos.org/issues/4757
https://www.illumos.org/issues/4913
https://github.com/illumos/illumos-gate/commit/5d7b4d4
Porting notes:
For compatibility with the fastpath code the zio_done() function
needed to be updated. Because embedded-data block pointers do
not require DVAs to be allocated the associated vdevs will not
be marked and therefore should not be unmarked.
Ported by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2544
This commit is contained in:
committed by
Brian Behlendorf
parent
faf0f58c69
commit
9b67f60560
+64
-29
@@ -812,8 +812,10 @@ buf_discard_identity(arc_buf_hdr_t *hdr)
|
||||
}
|
||||
|
||||
static arc_buf_hdr_t *
|
||||
buf_hash_find(uint64_t spa, const dva_t *dva, uint64_t birth, kmutex_t **lockp)
|
||||
buf_hash_find(uint64_t spa, const blkptr_t *bp, kmutex_t **lockp)
|
||||
{
|
||||
const dva_t *dva = BP_IDENTITY(bp);
|
||||
uint64_t birth = BP_PHYSICAL_BIRTH(bp);
|
||||
uint64_t idx = BUF_HASH_INDEX(spa, dva, birth);
|
||||
kmutex_t *hash_lock = BUF_HASH_LOCK(idx);
|
||||
arc_buf_hdr_t *buf;
|
||||
@@ -845,6 +847,8 @@ buf_hash_insert(arc_buf_hdr_t *buf, kmutex_t **lockp)
|
||||
arc_buf_hdr_t *fbuf;
|
||||
uint32_t i;
|
||||
|
||||
ASSERT(!DVA_IS_EMPTY(&buf->b_dva));
|
||||
ASSERT(buf->b_birth != 0);
|
||||
ASSERT(!HDR_IN_HASH_TABLE(buf));
|
||||
*lockp = hash_lock;
|
||||
mutex_enter(hash_lock);
|
||||
@@ -3034,10 +3038,10 @@ arc_getbuf_func(zio_t *zio, arc_buf_t *buf, void *arg)
|
||||
static void
|
||||
arc_read_done(zio_t *zio)
|
||||
{
|
||||
arc_buf_hdr_t *hdr, *found;
|
||||
arc_buf_hdr_t *hdr;
|
||||
arc_buf_t *buf;
|
||||
arc_buf_t *abuf; /* buffer we're assigning to callback */
|
||||
kmutex_t *hash_lock;
|
||||
kmutex_t *hash_lock = NULL;
|
||||
arc_callback_t *callback_list, *acb;
|
||||
int freeable = FALSE;
|
||||
|
||||
@@ -3052,12 +3056,24 @@ arc_read_done(zio_t *zio)
|
||||
* reason for it not to be found is if we were freed during the
|
||||
* read.
|
||||
*/
|
||||
found = buf_hash_find(hdr->b_spa, &hdr->b_dva, hdr->b_birth,
|
||||
&hash_lock);
|
||||
if (HDR_IN_HASH_TABLE(hdr)) {
|
||||
arc_buf_hdr_t *found;
|
||||
|
||||
ASSERT((found == NULL && HDR_FREED_IN_READ(hdr) && hash_lock == NULL) ||
|
||||
(found == hdr && DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp))) ||
|
||||
(found == hdr && HDR_L2_READING(hdr)));
|
||||
ASSERT3U(hdr->b_birth, ==, BP_PHYSICAL_BIRTH(zio->io_bp));
|
||||
ASSERT3U(hdr->b_dva.dva_word[0], ==,
|
||||
BP_IDENTITY(zio->io_bp)->dva_word[0]);
|
||||
ASSERT3U(hdr->b_dva.dva_word[1], ==,
|
||||
BP_IDENTITY(zio->io_bp)->dva_word[1]);
|
||||
|
||||
found = buf_hash_find(hdr->b_spa, zio->io_bp,
|
||||
&hash_lock);
|
||||
|
||||
ASSERT((found == NULL && HDR_FREED_IN_READ(hdr) &&
|
||||
hash_lock == NULL) ||
|
||||
(found == hdr &&
|
||||
DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp))) ||
|
||||
(found == hdr && HDR_L2_READING(hdr)));
|
||||
}
|
||||
|
||||
hdr->b_flags &= ~ARC_L2_EVICTED;
|
||||
if (l2arc_noprefetch && (hdr->b_flags & ARC_PREFETCH))
|
||||
@@ -3181,17 +3197,26 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done,
|
||||
void *private, zio_priority_t priority, int zio_flags, uint32_t *arc_flags,
|
||||
const zbookmark_t *zb)
|
||||
{
|
||||
arc_buf_hdr_t *hdr;
|
||||
arc_buf_hdr_t *hdr = NULL;
|
||||
arc_buf_t *buf = NULL;
|
||||
kmutex_t *hash_lock;
|
||||
kmutex_t *hash_lock = NULL;
|
||||
zio_t *rzio;
|
||||
uint64_t guid = spa_load_guid(spa);
|
||||
int rc = 0;
|
||||
|
||||
ASSERT(!BP_IS_EMBEDDED(bp) ||
|
||||
BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA);
|
||||
|
||||
top:
|
||||
hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
|
||||
&hash_lock);
|
||||
if (hdr && hdr->b_datacnt > 0) {
|
||||
if (!BP_IS_EMBEDDED(bp)) {
|
||||
/*
|
||||
* Embedded BP's have no DVA and require no I/O to "read".
|
||||
* Create an anonymous arc buf to back it.
|
||||
*/
|
||||
hdr = buf_hash_find(guid, bp, &hash_lock);
|
||||
}
|
||||
|
||||
if (hdr != NULL && hdr->b_datacnt > 0) {
|
||||
|
||||
*arc_flags |= ARC_CACHED;
|
||||
|
||||
@@ -3265,7 +3290,7 @@ top:
|
||||
done(NULL, buf, private);
|
||||
} else {
|
||||
uint64_t size = BP_GET_LSIZE(bp);
|
||||
arc_callback_t *acb;
|
||||
arc_callback_t *acb;
|
||||
vdev_t *vd = NULL;
|
||||
uint64_t addr = 0;
|
||||
boolean_t devw = B_FALSE;
|
||||
@@ -3274,15 +3299,17 @@ top:
|
||||
|
||||
if (hdr == NULL) {
|
||||
/* this block is not in the cache */
|
||||
arc_buf_hdr_t *exists;
|
||||
arc_buf_hdr_t *exists = NULL;
|
||||
arc_buf_contents_t type = BP_GET_BUFC_TYPE(bp);
|
||||
buf = arc_buf_alloc(spa, size, private, type);
|
||||
hdr = buf->b_hdr;
|
||||
hdr->b_dva = *BP_IDENTITY(bp);
|
||||
hdr->b_birth = BP_PHYSICAL_BIRTH(bp);
|
||||
hdr->b_cksum0 = bp->blk_cksum.zc_word[0];
|
||||
exists = buf_hash_insert(hdr, &hash_lock);
|
||||
if (exists) {
|
||||
if (!BP_IS_EMBEDDED(bp)) {
|
||||
hdr->b_dva = *BP_IDENTITY(bp);
|
||||
hdr->b_birth = BP_PHYSICAL_BIRTH(bp);
|
||||
hdr->b_cksum0 = bp->blk_cksum.zc_word[0];
|
||||
exists = buf_hash_insert(hdr, &hash_lock);
|
||||
}
|
||||
if (exists != NULL) {
|
||||
/* somebody beat us to the hash insert */
|
||||
mutex_exit(hash_lock);
|
||||
buf_discard_identity(hdr);
|
||||
@@ -3354,7 +3381,8 @@ top:
|
||||
vd = NULL;
|
||||
}
|
||||
|
||||
mutex_exit(hash_lock);
|
||||
if (hash_lock != NULL)
|
||||
mutex_exit(hash_lock);
|
||||
|
||||
/*
|
||||
* At this point, we have a level 1 cache miss. Try again in
|
||||
@@ -3526,8 +3554,9 @@ arc_freed(spa_t *spa, const blkptr_t *bp)
|
||||
kmutex_t *hash_lock;
|
||||
uint64_t guid = spa_load_guid(spa);
|
||||
|
||||
hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
|
||||
&hash_lock);
|
||||
ASSERT(!BP_IS_EMBEDDED(bp));
|
||||
|
||||
hdr = buf_hash_find(guid, bp, &hash_lock);
|
||||
if (hdr == NULL)
|
||||
return;
|
||||
if (HDR_BUF_AVAILABLE(hdr)) {
|
||||
@@ -3854,7 +3883,7 @@ arc_write_done(zio_t *zio)
|
||||
ASSERT(hdr->b_acb == NULL);
|
||||
|
||||
if (zio->io_error == 0) {
|
||||
if (BP_IS_HOLE(zio->io_bp)) {
|
||||
if (BP_IS_HOLE(zio->io_bp) || BP_IS_EMBEDDED(zio->io_bp)) {
|
||||
buf_discard_identity(hdr);
|
||||
} else {
|
||||
hdr->b_dva = *BP_IDENTITY(zio->io_bp);
|
||||
@@ -3866,10 +3895,10 @@ arc_write_done(zio_t *zio)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the block to be written was all-zero, we may have
|
||||
* compressed it away. In this case no write was performed
|
||||
* so there will be no dva/birth/checksum. The buffer must
|
||||
* therefore remain anonymous (and uncached).
|
||||
* If the block to be written was all-zero or compressed enough to be
|
||||
* embedded in the BP, no write was performed so there will be no
|
||||
* dva/birth/checksum. The buffer must therefore remain anonymous
|
||||
* (and uncached).
|
||||
*/
|
||||
if (!BUF_EMPTY(hdr)) {
|
||||
arc_buf_hdr_t *exists;
|
||||
@@ -5219,7 +5248,7 @@ static boolean_t
|
||||
l2arc_compress_buf(l2arc_buf_hdr_t *l2hdr)
|
||||
{
|
||||
void *cdata;
|
||||
size_t csize, len;
|
||||
size_t csize, len, rounded;
|
||||
|
||||
ASSERT(l2hdr->b_compress == ZIO_COMPRESS_OFF);
|
||||
ASSERT(l2hdr->b_tmp_cdata != NULL);
|
||||
@@ -5229,6 +5258,12 @@ l2arc_compress_buf(l2arc_buf_hdr_t *l2hdr)
|
||||
csize = zio_compress_data(ZIO_COMPRESS_LZ4, l2hdr->b_tmp_cdata,
|
||||
cdata, l2hdr->b_asize);
|
||||
|
||||
rounded = P2ROUNDUP(csize, (size_t)SPA_MINBLOCKSIZE);
|
||||
if (rounded > csize) {
|
||||
bzero((char *)cdata + csize, rounded - csize);
|
||||
csize = rounded;
|
||||
}
|
||||
|
||||
if (csize == 0) {
|
||||
/* zero block, indicate that there's nothing to write */
|
||||
zio_data_buf_free(cdata, len);
|
||||
|
||||
Reference in New Issue
Block a user