diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index a8cb812714ec..07712595a95b 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -62,6 +62,7 @@ struct dmu_tx; #define OBJSET_FLAG_USERACCOUNTING_COMPLETE (1ULL << 0) #define OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE (1ULL << 1) #define OBJSET_FLAG_PROJECTQUOTA_COMPLETE (1ULL << 2) +#define OBJSET_FLAG_USERACCOUNTING_INVALID (1ULL << 3) /* * This mask defines the set of flags which are "portable", meaning diff --git a/module/os/freebsd/zfs/zio_crypt.c b/module/os/freebsd/zfs/zio_crypt.c index fb88bc325d3c..3b58a5f4690b 100644 --- a/module/os/freebsd/zfs/zio_crypt.c +++ b/module/os/freebsd/zfs/zio_crypt.c @@ -1070,11 +1070,21 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, bcopy(raw_portable_mac, portable_mac, ZIO_OBJSET_MAC_LEN); + /* + * This is necessary here as we check next whether + * OBJSET_FLAG_USERACCOUNTING_INVALID is set in order to + * decide if the local_mac should be zeroed out. + */ + intval = osp->os_flags; + if (should_bswap) + intval = BSWAP_64(intval); + /* * The local MAC protects the user, group and project accounting. * If these objects are not present, the local MAC is zeroed out. */ - if ((datalen >= OBJSET_PHYS_SIZE_V3 && + if (osp->os_flags & OBJSET_FLAG_USERACCOUNTING_INVALID || + (datalen >= OBJSET_PHYS_SIZE_V3 && osp->os_userused_dnode.dn_type == DMU_OT_NONE && osp->os_groupused_dnode.dn_type == DMU_OT_NONE && osp->os_projectused_dnode.dn_type == DMU_OT_NONE) || diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c index 96dabe55a138..db4bff368857 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -1197,11 +1197,21 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, bcopy(raw_portable_mac, portable_mac, ZIO_OBJSET_MAC_LEN); + /* + * This is necessary here as we check next whether + * OBJSET_FLAG_USERACCOUNTING_INVALID is set in order to + * decide if the local_mac should be zeroed out. + */ + intval = osp->os_flags; + if (should_bswap) + intval = BSWAP_64(intval); + /* * The local MAC protects the user, group and project accounting. * If these objects are not present, the local MAC is zeroed out. */ - if ((datalen >= OBJSET_PHYS_SIZE_V3 && + if (intval & OBJSET_FLAG_USERACCOUNTING_INVALID || + (datalen >= OBJSET_PHYS_SIZE_V3 && osp->os_userused_dnode.dn_type == DMU_OT_NONE && osp->os_groupused_dnode.dn_type == DMU_OT_NONE && osp->os_projectused_dnode.dn_type == DMU_OT_NONE) || diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 66a8f20092e0..f02a05d282f5 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -1079,6 +1079,7 @@ dmu_objset_create_impl_dnstats(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, */ if (dmu_objset_userused_enabled(os) && (!os->os_encrypted || !dmu_objset_is_receiving(os))) { + os->os_phys->os_flags &= ~OBJSET_FLAG_USERACCOUNTING_INVALID; os->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; if (dmu_objset_userobjused_enabled(os)) { ds->ds_feature_activation[ @@ -2345,6 +2346,7 @@ dmu_objset_userspace_upgrade_cb(objset_t *os) return (err); os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; + os->os_flags &= ~OBJSET_FLAG_USERACCOUNTING_INVALID; txg_wait_synced(dmu_objset_pool(os), 0); return (0); } @@ -2383,6 +2385,7 @@ dmu_objset_id_quota_upgrade_cb(objset_t *os) return (err); os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; + os->os_flags &= ~OBJSET_FLAG_USERACCOUNTING_INVALID; if (dmu_objset_userobjused_enabled(os)) os->os_flags |= OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE; if (dmu_objset_projectquota_enabled(os)) diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index c46810b9715a..4781027322c4 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2098,6 +2098,10 @@ dsl_crypto_recv_raw_objset_sync(dsl_dataset_t *ds, dmu_objset_type_t ostype, 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_phys->os_flags &= ~OBJSET_FLAG_USERACCOUNTING_COMPLETE; + os->os_phys->os_flags &= ~OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE; + os->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_INVALID; + os->os_flags = os->os_phys->os_flags; os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; /* set metadnode compression and checksum */