From c379a3cf20f39a74798eeb048d095eaeb7b415c9 Mon Sep 17 00:00:00 2001 From: George Amanakis Date: Wed, 6 Jan 2021 22:34:32 +0100 Subject: [PATCH] new approach Signed-off-by: George Amanakis --- include/sys/dmu_objset.h | 1 + module/os/freebsd/zfs/zio_crypt.c | 12 +++++++++++- module/os/linux/zfs/zio_crypt.c | 12 +++++++++++- module/zfs/dmu_objset.c | 3 +++ module/zfs/dsl_crypt.c | 4 ++++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index e89ee64ea686..ccca5dec3576 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 fb714d399296..6ea3102b71e0 100644 --- a/module/os/freebsd/zfs/zio_crypt.c +++ b/module/os/freebsd/zfs/zio_crypt.c @@ -1076,11 +1076,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 52e62f4d1da4..ef3a48bfe817 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -1203,11 +1203,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 af107fb8ad63..1f78e167161a 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -1086,6 +1086,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[ @@ -2351,6 +2352,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); } @@ -2389,6 +2391,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 26d4c2fe7e33..b6885eb1b149 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2106,6 +2106,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 */