Skip to content

Commit

Permalink
bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Caputi authored and lundman committed Jul 12, 2017
1 parent 2992551 commit 69fcb39
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 57 deletions.
106 changes: 55 additions & 51 deletions usr/src/uts/common/fs/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2305,10 +2305,11 @@ arc_buf_fill(arc_buf_t *buf, spa_t *spa, uint64_t dsobj, arc_fill_flags_t flags)
if (HDR_ENCRYPTED(hdr) && ARC_BUF_ENCRYPTED(buf)) {
ASSERT3U(hdr->b_crypt_hdr.b_ot, ==, DMU_OT_DNODE);
arc_buf_untransform_in_place(buf, hash_lock);

/* Compute the hdr's checksum if necessary */
arc_cksum_compute(buf);
}

/* Compute the hdr's checksum if necessary */
arc_cksum_compute(buf);
return (0);
}

Expand Down Expand Up @@ -7800,16 +7801,21 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
mutex_exit(&dev->l2ad_mtx);
}

/*
* Handle any abd transforms that might be required for writing to the L2ARC.
* If successful, this function will always return an abd with the data
* transformed as it is on disk in a new abd of asize bytes.
*/
static int
l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,
uint64_t *bsize_out, uint64_t *csize_out)
l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize,
abd_t **abd_out)
{
int ret;
void *tmp = NULL;
abd_t *cabd = NULL, *eabd = NULL, *to_write = hdr->b_l1hdr.b_pabd;
enum zio_compress compress = HDR_GET_COMPRESS(hdr);
uint64_t bsize = arc_hdr_size(hdr);
uint64_t csize = bsize;
uint64_t psize = HDR_GET_PSIZE(hdr);
uint64_t size = arc_hdr_size(hdr);
boolean_t ismd = HDR_ISTYPE_METADATA(hdr);
boolean_t bswap = (hdr->b_l1hdr.b_byteswap != DMU_BSWAP_NUMFUNCS);
dsl_crypto_key_t *dck = NULL;
Expand All @@ -7818,37 +7824,39 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,

ASSERT((HDR_GET_COMPRESS(hdr) != ZIO_COMPRESS_OFF &&
!HDR_COMPRESSION_ENABLED(hdr)) ||
HDR_ENCRYPTED(hdr) || HDR_SHARED_DATA(hdr));
HDR_ENCRYPTED(hdr) || HDR_SHARED_DATA(hdr) || psize != asize);
ASSERT3U(psize, <=, asize);

/*
* If this is just a shared buffer, we simply copy the data. Otherwise
* we apply the needed transforms so that the data matches what is
* on disk.
* If this data simply needs its own buffer, we simply allocate it
* and copy the data. This may be done to elimiate a depedency on a
* shared buffer or to reallocate the buffer to match asize.
*/
if ((compress == ZIO_COMPRESS_OFF || HDR_COMPRESSION_ENABLED(hdr)) &&
!HDR_ENCRYPTED(hdr)) {
to_write = abd_alloc_for_io(bsize, ismd);
abd_copy(to_write, hdr->b_l1hdr.b_pabd, bsize);
ASSERT3U(size, ==, psize);
to_write = abd_alloc_for_io(asize, ismd);
abd_copy(to_write, hdr->b_l1hdr.b_pabd, size);
if (size != asize)
abd_zero_off(to_write, size, asize - size);
goto out;
}

if (compress != ZIO_COMPRESS_OFF && !HDR_COMPRESSION_ENABLED(hdr)) {
cabd = abd_alloc_for_io(bsize, ismd);
tmp = abd_borrow_buf(cabd, bsize);

csize = zio_compress_data(compress, to_write, tmp, bsize);
ASSERT3U(csize, <=, HDR_GET_PSIZE(hdr));
if (csize < HDR_GET_PSIZE(hdr)) {
bzero((char *)tmp + csize, HDR_GET_PSIZE(hdr) - csize);
csize = HDR_GET_PSIZE(hdr);
}
abd_return_buf_copy(cabd, tmp, bsize);

cabd = abd_alloc_for_io(asize, ismd);
tmp = abd_borrow_buf(cabd, asize);

psize = zio_compress_data(compress, to_write, tmp, size);
ASSERT3U(psize, <=, HDR_GET_PSIZE(hdr));
if (psize < asize)
bzero((char *)tmp + psize, asize - psize);
psize = HDR_GET_PSIZE(hdr);
abd_return_buf_copy(cabd, tmp, asize);
to_write = cabd;
}

if (HDR_ENCRYPTED(hdr)) {
eabd = abd_alloc_for_io(csize, ismd);
eabd = abd_alloc_for_io(asize, ismd);

/*
* If the dataset was disowned before the buffer
Expand All @@ -7863,7 +7871,7 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,

ret = zio_do_crypt_abd(B_TRUE, &dck->dck_key,
hdr->b_crypt_hdr.b_salt, hdr->b_crypt_hdr.b_ot,
hdr->b_crypt_hdr.b_iv, mac, csize, bswap, to_write,
hdr->b_crypt_hdr.b_iv, mac, psize, bswap, to_write,
eabd, &no_crypt);
if (ret != 0)
goto error;
Expand All @@ -7874,6 +7882,9 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,
goto out;
}

if (psize != asize)
abd_zero_off(eabd, psize, asize - psize);

/* assert that the MAC we got here matches the one we saved */
ASSERT0(bcmp(mac, hdr->b_crypt_hdr.b_mac, ZIO_DATA_MAC_LEN));
spa_keystore_dsl_key_rele(spa, dck, FTAG);
Expand All @@ -7882,13 +7893,10 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,
abd_free(cabd);

to_write = eabd;
bsize = csize;
}

out:
ASSERT3P(to_write, !=, hdr->b_l1hdr.b_pabd);
*bsize_out = bsize;
*csize_out = csize;
*abd_out = to_write;
return (0);

Expand All @@ -7900,8 +7908,6 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, abd_t **abd_out,
if (eabd != NULL)
abd_free(eabd);

*bsize_out = 0;
*csize_out = 0;
*abd_out = NULL;
return (ret);
}
Expand Down Expand Up @@ -7942,6 +7948,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
multilist_sublist_t *mls = l2arc_sublist_lock(try);
uint64_t passed_sz = 0;

VERIFY3P(mls, !=, NULL);
/*
* L2ARC fast warmup.
*
Expand All @@ -7959,7 +7966,6 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)

for (; hdr; hdr = hdr_prev) {
kmutex_t *hash_lock;
uint64_t bsize, csize;
abd_t *to_write = NULL;

if (arc_warm == B_FALSE)
Expand Down Expand Up @@ -7998,9 +8004,10 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
ASSERT(HDR_HAS_L1HDR(hdr));

ASSERT3U(HDR_GET_PSIZE(hdr), >, 0);
ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL);
ASSERT3U(arc_hdr_size(hdr), >, 0);
uint64_t psize = arc_hdr_size(hdr);
ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL ||
HDR_HAS_RABD(hdr));
uint64_t psize = HDR_GET_PSIZE(hdr);
uint64_t asize = vdev_psize_to_asize(dev->l2ad_vdev,
psize);

Expand Down Expand Up @@ -8038,30 +8045,27 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
* data (compression, encryption) we will also need the
* extra buffer.
*/
if (HDR_HAS_RABD(hdr)) {
bsize = HDR_GET_PSIZE(hdr);
csize = bsize;
if (HDR_HAS_RABD(hdr) && psize == asize) {
to_write = hdr->b_crypt_hdr.b_rabd;
} else if ((HDR_COMPRESSION_ENABLED(hdr) ||
HDR_GET_COMPRESS(hdr) == ZIO_COMPRESS_OFF) &&
!HDR_ENCRYPTED(hdr) && !HDR_SHARED_DATA(hdr)) {
bsize = arc_hdr_size(hdr);
csize = bsize;
!HDR_ENCRYPTED(hdr) && !HDR_SHARED_DATA(hdr) &&
psize == asize) {
to_write = hdr->b_l1hdr.b_pabd;
} else {
int ret;
arc_buf_contents_t type = arc_buf_type(hdr);

ret = l2arc_apply_transforms(spa, hdr,
&to_write, &bsize, &csize);
ret = l2arc_apply_transforms(spa, hdr, asize,
&to_write);
if (ret != 0) {
arc_hdr_clear_flags(hdr,
ARC_FLAG_L2_WRITING);
mutex_exit(hash_lock);
continue;
}

l2arc_free_abd_on_write(to_write, bsize, type);
l2arc_free_abd_on_write(to_write, asize, type);
}

if (pio == NULL) {
Expand Down Expand Up @@ -8109,18 +8113,18 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
*/

asize = vdev_psize_to_asize(dev->l2ad_vdev,
csize);
if (!HDR_SHARED_DATA(hdr) && csize == asize) {
psize);
if (!HDR_SHARED_DATA(hdr) && psize == asize) {
to_write = hdr->b_l1hdr.b_pabd;
} else {
to_write = abd_alloc_for_io(asize,
HDR_ISTYPE_METADATA(hdr));
abd_copy(to_write, hdr->b_l1hdr.b_pabd, csize);
if (asize != csize) {
abd_zero_off(to_write, csize,
asize - csize);
abd_copy(to_write, hdr->b_l1hdr.b_pabd, psize);
if (asize != psize) {
abd_zero_off(to_write, psize,
asize - psize);
}
l2arc_free_abd_on_write(to_write, csize,
l2arc_free_abd_on_write(to_write, asize,
arc_buf_type(hdr));
}
wzio = zio_write_phys(pio, dev->l2ad_vdev,
Expand All @@ -8133,11 +8137,11 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
DTRACE_PROBE2(l2arc__write, vdev_t *, dev->l2ad_vdev,
zio_t *, wzio);

write_asize += csize;
write_asize += asize;
/*
* Keep the clock hand suitably device-aligned.
*/
write_psize += asize;
write_psize += psize;
dev->l2ad_hand += asize;

mutex_exit(hash_lock);
Expand Down
6 changes: 3 additions & 3 deletions usr/src/uts/common/fs/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,8 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
/* if the underlying dnode block is encrypted, decrypt it */
if (dn_buf != NULL && dn->dn_objset->os_encrypted &&
DMU_OT_IS_ENCRYPTED(dn->dn_bonustype) &&
(flags & DB_RF_NO_DECRYPT) == 0) {
(flags & DB_RF_NO_DECRYPT) == 0 &&
arc_is_encrypted(dn_buf)) {
err = arc_untransform(dn_buf, dn->dn_objset->os_spa,
dmu_objset_id(dn->dn_objset), B_TRUE);
if (err != 0) {
Expand Down Expand Up @@ -1166,8 +1167,7 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
if (db->db_buf != NULL && (flags & DB_RF_NO_DECRYPT) == 0 &&
(arc_is_encrypted(db->db_buf) ||
arc_get_compression(db->db_buf) != ZIO_COMPRESS_OFF)) {
dbuf_fix_old_data(db,
spa_syncing_txg(dmu_objset_spa(db->db_objset)));
dbuf_fix_old_data(db, spa_syncing_txg(spa));
err = arc_untransform(db->db_buf, spa,
dmu_objset_id(db->db_objset), B_FALSE);
dbuf_set_data(db, db->db_buf);
Expand Down
5 changes: 2 additions & 3 deletions usr/src/uts/common/fs/zfs/dmu_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -1537,9 +1537,7 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
/* if full, then must be forced */
if (!drba->drba_cookie->drc_force)
return (SET_ERROR(EEXIST));
/* start from $ORIGIN@$ORIGIN, if supported */
drba->drba_snapobj = dp->dp_origin_snap != NULL ?
dp->dp_origin_snap->ds_object : 0;
drba->drba_snapobj = 0;
}

return (0);
Expand Down Expand Up @@ -1737,6 +1735,7 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
/* we use the dcp whenever we are not making a clone */
dcpp = &dcp;
}

dsobj = dsl_dataset_create_sync(ds->ds_dir, recv_clone_name,
snap, crflags, drba->drba_cred, dcpp, tx);
if (drba->drba_snapobj != 0)
Expand Down

0 comments on commit 69fcb39

Please sign in to comment.