diff options
author | Umer Saleem <[email protected]> | 2022-08-03 04:45:30 +0500 |
---|---|---|
committer | GitHub <[email protected]> | 2022-08-02 16:45:30 -0700 |
commit | 9681de4657686d0ed19ca18d578513e74395f00f (patch) | |
tree | be312549168f938e61fd275b19590a7c8eccb4ae /module | |
parent | 5ad44a0ce9cb0da43005cd3d899e345617460998 (diff) |
Add snapshots_changed as property
Make dd_snap_cmtime property persistent across mount and unmount
operations by storing in ZAP and restore the value from ZAP on hold
into dd_snap_cmtime instead of updating it.
Expose dd_snap_cmtime as 'snapshots_changed' property that provides a
mechanism to quickly determine whether snapshot list for dataset has
changed without having to mount a dataset or iterate the snapshot list.
It specifies the time at which a snapshot for a dataset was last
created or deleted. This allows us to be more efficient how often we
query snapshots.
Reviewed-by: Ryan Moeller <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Umer Saleem <[email protected]>
Closes #13635
Diffstat (limited to 'module')
-rw-r--r-- | module/zcommon/zfs_prop.c | 5 | ||||
-rw-r--r-- | module/zfs/dsl_dataset.c | 6 | ||||
-rw-r--r-- | module/zfs/dsl_dir.c | 17 | ||||
-rw-r--r-- | module/zfs/zcp_get.c | 4 |
4 files changed, 27 insertions, 5 deletions
diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c index 0b0fc9015..2a58088a7 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -734,6 +734,11 @@ zfs_prop_init(void) NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<date>", "CREATION", B_FALSE, B_TRUE, B_TRUE, NULL, sfeatures); + zprop_register_impl(ZFS_PROP_SNAPSHOTS_CHANGED, "snapshots_changed", + PROP_TYPE_NUMBER, 0, NULL, PROP_READONLY, ZFS_TYPE_FILESYSTEM | + ZFS_TYPE_VOLUME, "<date>", "SNAPSHOTS_CHANGED", B_FALSE, B_TRUE, + B_TRUE, NULL, sfeatures); + zfs_mod_list_supported_free(sfeatures); } diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 5f1235583..12fcecf0d 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -534,7 +534,7 @@ dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx, matchtype_t mt = 0; int err; - dsl_dir_snap_cmtime_update(ds->ds_dir); + dsl_dir_snap_cmtime_update(ds->ds_dir, tx); if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET) mt = MT_NORMALIZE; @@ -1865,7 +1865,7 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, dsl_scan_ds_snapshotted(ds, tx); - dsl_dir_snap_cmtime_update(ds->ds_dir); + dsl_dir_snap_cmtime_update(ds->ds_dir, tx); spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, " "); } @@ -2809,6 +2809,8 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) dsl_get_userrefs(ds)); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY, dsl_get_defer_destroy(ds)); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_SNAPSHOTS_CHANGED, + dsl_dir_snap_cmtime(ds->ds_dir).tv_sec); dsl_dataset_crypt_stats(ds, nv); if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) { diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c index cc870d1bc..5a64e399c 100644 --- a/module/zfs/dsl_dir.c +++ b/module/zfs/dsl_dir.c @@ -207,8 +207,6 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, } } - dsl_dir_snap_cmtime_update(dd); - if (dsl_dir_phys(dd)->dd_parent_obj) { err = dsl_dir_hold_obj(dp, dsl_dir_phys(dd)->dd_parent_obj, NULL, dd, @@ -270,6 +268,14 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj, } } + inode_timespec_t t = {0}; + zap_lookup(dd->dd_pool->dp_meta_objset, + dsl_dir_phys(dd)->dd_props_zapobj, + zfs_prop_to_name(ZFS_PROP_SNAPSHOTS_CHANGED), + sizeof (uint64_t), + sizeof (inode_timespec_t) / sizeof (uint64_t), &t); + dd->dd_snap_cmtime = t; + dmu_buf_init_user(&dd->dd_dbu, NULL, dsl_dir_evict_async, &dd->dd_dbuf); winner = dmu_buf_set_user_ie(dbuf, &dd->dd_dbu); @@ -2243,13 +2249,18 @@ dsl_dir_snap_cmtime(dsl_dir_t *dd) } void -dsl_dir_snap_cmtime_update(dsl_dir_t *dd) +dsl_dir_snap_cmtime_update(dsl_dir_t *dd, dmu_tx_t *tx) { inode_timespec_t t; + objset_t *mos = dd->dd_pool->dp_meta_objset; + uint64_t zapobj = dsl_dir_phys(dd)->dd_props_zapobj; + const char *prop_name = zfs_prop_to_name(ZFS_PROP_SNAPSHOTS_CHANGED); gethrestime(&t); mutex_enter(&dd->dd_lock); dd->dd_snap_cmtime = t; + VERIFY0(zap_update(mos, zapobj, prop_name, sizeof (uint64_t), + sizeof (inode_timespec_t) / sizeof (uint64_t), &t, tx)); mutex_exit(&dd->dd_lock); } diff --git a/module/zfs/zcp_get.c b/module/zfs/zcp_get.c index af495ce85..0a0466d46 100644 --- a/module/zfs/zcp_get.c +++ b/module/zfs/zcp_get.c @@ -403,6 +403,10 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname, break; } + case ZFS_PROP_SNAPSHOTS_CHANGED: + numval = dsl_dir_snap_cmtime(ds->ds_dir).tv_sec; + break; + default: /* Did not match these props, check in the dsl_dir */ error = get_dsl_dir_prop(ds, zfs_prop, &numval); |