From 1b66810bad0a893031c6d49613aa83dc359bf034 Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Thu, 1 Feb 2018 15:37:24 -0500 Subject: [PATCH] Change os->os_next_write_raw to work per txg Currently, os_next_write_raw is a single boolean used for determining whether or not the next call to dmu_objset_sync() should write out the objset_phys_t as a raw buffer. Since the boolean is not associated with a txg, the work simply happens during the next txg, which is not necessarily the correct one. In the current implementation this issue was misdiagnosed, resulting in a small hack in dmu_objset_sync() which seemed to resolve the problem. This patch changes os_next_write_raw to be an array of booleans, one for each txg in TXG_OFF and removes the hack. Reviewed-by: Jorgen Lundman Reviewed-by: Brian Behlendorf Reviewed by: Matthew Ahrens Signed-off-by: Tom Caputi Closes #6864 --- include/sys/dmu_objset.h | 2 +- module/zfs/dbuf.c | 1 + module/zfs/dmu_objset.c | 4 ++-- module/zfs/dsl_crypt.c | 2 +- module/zfs/dsl_dataset.c | 2 +- module/zfs/zil.c | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index f3013ad13..7ee992f31 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -127,7 +127,7 @@ struct objset { boolean_t os_rescan_dnodes; /* os_phys_buf should be written raw next txg */ - boolean_t os_next_write_raw; + boolean_t os_next_write_raw[TXG_SIZE]; /* Protected by os_obj_lock */ kmutex_t os_obj_lock; diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 87b9ba461..3668ea315 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -2218,6 +2218,7 @@ dmu_buf_will_change_crypt_params(dmu_buf_t *db_fake, dmu_tx_t *tx) ASSERT3P(dr, !=, NULL); ASSERT3U(dr->dr_txg, ==, tx->tx_txg); dr->dt.dl.dr_raw = B_TRUE; + db->db_objset->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; } #pragma weak dmu_buf_fill_done = dbuf_fill_done diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 2b069b6ce..befce9be6 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -1508,9 +1508,9 @@ dmu_objset_sync(objset_t *os, zio_t *pio, dmu_tx_t *tx) * the os_phys_buf raw. Neither of these actions will effect the MAC * at this point. */ - if (arc_is_unauthenticated(os->os_phys_buf) || os->os_next_write_raw) { + if (os->os_next_write_raw[tx->tx_txg & TXG_MASK]) { ASSERT(os->os_encrypted); - os->os_next_write_raw = B_FALSE; + os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_FALSE; arc_convert_to_raw(os->os_phys_buf, os->os_dsl_dataset->ds_object, ZFS_HOST_BYTEORDER, DMU_OT_OBJSET, NULL, NULL, NULL); diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index cb13d2cdc..6a63d54ca 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2177,7 +2177,7 @@ dsl_crypto_recv_key_sync(void *arg, dmu_tx_t *tx) arc_release(os->os_phys_buf, &os->os_phys_buf); bcopy(portable_mac, os->os_phys->os_portable_mac, ZIO_OBJSET_MAC_LEN); bzero(os->os_phys->os_local_mac, ZIO_OBJSET_MAC_LEN); - os->os_next_write_raw = B_TRUE; + os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; /* set metadnode compression and checksum */ mdn->dn_compress = compress; diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 36ceaf175..3c329f207 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -941,7 +941,7 @@ dsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx) bzero(&os->os_zil_header, sizeof (os->os_zil_header)); if (os->os_encrypted) - os->os_next_write_raw = B_TRUE; + os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); dsl_dataset_sync(ds, zio, tx); diff --git a/module/zfs/zil.c b/module/zfs/zil.c index 234ce956a..d7bb33ab0 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -796,7 +796,7 @@ zil_claim(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg) zio_free_zil(zilog->zl_spa, first_txg, &zh->zh_log); BP_ZERO(&zh->zh_log); if (os->os_encrypted) - os->os_next_write_raw = B_TRUE; + os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; dsl_dataset_dirty(dmu_objset_ds(os), tx); dmu_objset_disown(os, B_FALSE, FTAG); return (0); @@ -820,7 +820,7 @@ zil_claim(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg) zh->zh_flags |= ZIL_REPLAY_NEEDED; zh->zh_flags |= ZIL_CLAIM_LR_SEQ_VALID; if (os->os_encrypted) - os->os_next_write_raw = B_TRUE; + os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; dsl_dataset_dirty(dmu_objset_ds(os), tx); }