X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=module%2Fzfs%2Fdsl_dir.c;h=a866c3074d3c5c83632aaeb1f133dbbfb4b37a01;hb=a1d477c24c7badc89c60955995fd84d311938486;hp=bf130eb990ae9aa59550e6ea9df08fd0608577d0;hpb=4b0f5b2d7b99ca3ed9585173fe4b1c7fedda5aa5;p=mirror_zfs.git diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c index bf130eb99..a866c3074 100644 --- a/module/zfs/dsl_dir.c +++ b/module/zfs/dsl_dir.c @@ -129,6 +129,11 @@ extern inline dsl_dir_phys_t *dsl_dir_phys(dsl_dir_t *dd); static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd); +typedef struct ddulrt_arg { + dsl_dir_t *ddulrta_dd; + uint64_t ddlrta_txg; +} ddulrt_arg_t; + static void dsl_dir_evict_async(void *dbu) { @@ -750,6 +755,35 @@ dsl_enforce_ds_ss_limits(dsl_dir_t *dd, zfs_prop_t prop, cred_t *cr) return (enforce); } +static void +dsl_dir_update_last_remap_txg_sync(void *varg, dmu_tx_t *tx) +{ + ddulrt_arg_t *arg = varg; + uint64_t last_remap_txg; + dsl_dir_t *dd = arg->ddulrta_dd; + objset_t *mos = dd->dd_pool->dp_meta_objset; + + dsl_dir_zapify(dd, tx); + if (zap_lookup(mos, dd->dd_object, DD_FIELD_LAST_REMAP_TXG, + sizeof (last_remap_txg), 1, &last_remap_txg) != 0 || + last_remap_txg < arg->ddlrta_txg) { + VERIFY0(zap_update(mos, dd->dd_object, DD_FIELD_LAST_REMAP_TXG, + sizeof (arg->ddlrta_txg), 1, &arg->ddlrta_txg, tx)); + } +} + +int +dsl_dir_update_last_remap_txg(dsl_dir_t *dd, uint64_t txg) +{ + ddulrt_arg_t arg; + arg.ddulrta_dd = dd; + arg.ddlrta_txg = txg; + + return (dsl_sync_task(spa_name(dd->dd_pool->dp_spa), + NULL, dsl_dir_update_last_remap_txg_sync, &arg, + 1, ZFS_SPACE_CHECK_RESERVED)); +} + /* * Check if adding additional child filesystem(s) would exceed any filesystem * limits or adding additional snapshot(s) would exceed any snapshot limits. @@ -947,7 +981,6 @@ dsl_dir_is_clone(dsl_dir_t *dd) dd->dd_pool->dp_origin_snap->ds_object)); } - uint64_t dsl_dir_get_used(dsl_dir_t *dd) { @@ -1042,6 +1075,19 @@ dsl_dir_get_snapshot_count(dsl_dir_t *dd, uint64_t *count) } } +int +dsl_dir_get_remaptxg(dsl_dir_t *dd, uint64_t *count) +{ + if (dsl_dir_is_zapified(dd)) { + objset_t *os = dd->dd_pool->dp_meta_objset; + return (zap_lookup(os, dd->dd_object, DD_FIELD_LAST_REMAP_TXG, + sizeof (*count), 1, count)); + } else { + return (ENOENT); + } + +} + void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv) { @@ -1073,6 +1119,10 @@ dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv) dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_SNAPSHOT_COUNT, count); } + if (dsl_dir_get_remaptxg(dd, &count) == 0) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REMAPTXG, + count); + } if (dsl_dir_is_clone(dd)) { char buf[ZFS_MAX_DATASET_NAME_LEN];