aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorUmer Saleem <[email protected]>2022-08-03 04:45:30 +0500
committerGitHub <[email protected]>2022-08-02 16:45:30 -0700
commit9681de4657686d0ed19ca18d578513e74395f00f (patch)
treebe312549168f938e61fd275b19590a7c8eccb4ae /module
parent5ad44a0ce9cb0da43005cd3d899e345617460998 (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.c5
-rw-r--r--module/zfs/dsl_dataset.c6
-rw-r--r--module/zfs/dsl_dir.c17
-rw-r--r--module/zfs/zcp_get.c4
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);