diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index b6e64274cd04..047a254882f7 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -2947,7 +2947,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (literal || localtime_r(&time, &t) == NULL || - strftime(propbuf, proplen, "%a %b %e %k:%M %Y", + strftime(propbuf, proplen, "%a %b %e %k:%M:%S %Y", &t) == 0) (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val); diff --git a/man/man7/zfsprops.7 b/man/man7/zfsprops.7 index 8fff09a19205..93a7bfcc865f 100644 --- a/man/man7/zfsprops.7 +++ b/man/man7/zfsprops.7 @@ -526,6 +526,9 @@ Specifies the time at which a snapshot for a dataset was last created or deleted. .Pp This allows us to be more efficient how often we query snapshots. +The property is persistent across mount and unmount operations only if the +.Sy extensible_dataset +feature is enabled. .It Sy volblocksize For volumes, specifies the block size of the volume. The diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c index 5a64e399cf94..7460269384b4 100644 --- a/module/zfs/dsl_dir.c +++ b/module/zfs/dsl_dir.c @@ -268,13 +268,15 @@ 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; + if (dsl_dir_is_zapified(dd)) { + inode_timespec_t t = {0}; + zap_lookup(dp->dp_meta_objset, ddobj, + 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); @@ -2251,16 +2253,23 @@ dsl_dir_snap_cmtime(dsl_dir_t *dd) void dsl_dir_snap_cmtime_update(dsl_dir_t *dd, dmu_tx_t *tx) { + dsl_pool_t *dp = dmu_tx_pool(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)); + if (spa_feature_is_enabled(dp->dp_spa, + SPA_FEATURE_EXTENSIBLE_DATASET)) { + objset_t *mos = dd->dd_pool->dp_meta_objset; + uint64_t ddobj = dd->dd_object; + dsl_dir_zapify(dd, tx); + VERIFY0(zap_update(mos, ddobj, + zfs_prop_to_name(ZFS_PROP_SNAPSHOTS_CHANGED), + sizeof (uint64_t), + sizeof (inode_timespec_t) / sizeof (uint64_t), + &t, tx)); + } mutex_exit(&dd->dd_lock); }