changeset 10373:bcf97ee54990

6395956 snapshot dir needs real c/mtime
author Chris Kirby <chris.kirby@sun.com>
date Mon, 24 Aug 2009 16:11:19 -0600
parents 2a69958cda3f
children d40b04ded33e
files usr/src/lib/libzpool/common/sys/zfs_context.h usr/src/uts/common/fs/zfs/dmu_objset.c usr/src/uts/common/fs/zfs/dsl_dataset.c usr/src/uts/common/fs/zfs/dsl_dir.c usr/src/uts/common/fs/zfs/sys/dmu.h usr/src/uts/common/fs/zfs/sys/dmu_objset.h usr/src/uts/common/fs/zfs/sys/dsl_dataset.h usr/src/uts/common/fs/zfs/sys/dsl_dir.h usr/src/uts/common/fs/zfs/zfs_ctldir.c
diffstat 9 files changed, 54 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/lib/libzpool/common/sys/zfs_context.h	Mon Aug 24 16:11:19 2009 -0600
@@ -440,6 +440,11 @@
 extern void delay(clock_t ticks);
 
 #define	gethrestime_sec() time(NULL)
+#define	gethrestime(t) \
+	do {\
+		(t)->tv_sec = gethrestime_sec();\
+		(t)->tv_nsec = 0;\
+	} while (0);
 
 #define	max_ncpus	64
 
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c	Mon Aug 24 16:11:19 2009 -0600
@@ -499,6 +499,12 @@
 	kmem_free(os, sizeof (objset_t));
 }
 
+timestruc_t
+dmu_objset_snap_cmtime(objset_t *os)
+{
+	return (dsl_dir_snap_cmtime(os->os_dsl_dataset->ds_dir));
+}
+
 /* called from dsl for meta-objset */
 objset_t *
 dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c	Mon Aug 24 16:11:19 2009 -0600
@@ -321,6 +321,8 @@
 	matchtype_t mt;
 	int err;
 
+	dsl_dir_snap_cmtime_update(ds->ds_dir);
+
 	if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET)
 		mt = MT_FIRST;
 	else
@@ -1968,6 +1970,8 @@
 
 	dsl_pool_ds_snapshotted(ds, tx);
 
+	dsl_dir_snap_cmtime_update(ds->ds_dir);
+
 	spa_history_internal_log(LOG_DS_SNAPSHOT, dp->dp_spa, tx, cr,
 	    "dataset = %llu", dsobj);
 }
--- a/usr/src/uts/common/fs/zfs/dsl_dir.c	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/dsl_dir.c	Mon Aug 24 16:11:19 2009 -0600
@@ -107,6 +107,8 @@
 		list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
 		    offsetof(dsl_prop_cb_record_t, cbr_node));
 
+		dsl_dir_snap_cmtime_update(dd);
+
 		if (dd->dd_phys->dd_parent_obj) {
 			err = dsl_dir_open_obj(dp, dd->dd_phys->dd_parent_obj,
 			    NULL, dd, &dd->dd_parent);
@@ -1315,3 +1317,26 @@
 
 	return (0);
 }
+
+timestruc_t
+dsl_dir_snap_cmtime(dsl_dir_t *dd)
+{
+	timestruc_t t;
+
+	mutex_enter(&dd->dd_lock);
+	t = dd->dd_snap_cmtime;
+	mutex_exit(&dd->dd_lock);
+
+	return (t);
+}
+
+void
+dsl_dir_snap_cmtime_update(dsl_dir_t *dd)
+{
+	timestruc_t t;
+
+	gethrestime(&t);
+	mutex_enter(&dd->dd_lock);
+	dd->dd_snap_cmtime = t;
+	mutex_exit(&dd->dd_lock);
+}
--- a/usr/src/uts/common/fs/zfs/sys/dmu.h	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/sys/dmu.h	Mon Aug 24 16:11:19 2009 -0600
@@ -38,6 +38,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/cred.h>
+#include <sys/time.h>
 
 #ifdef	__cplusplus
 extern "C" {
@@ -558,6 +559,11 @@
  */
 uint64_t dmu_objset_fsid_guid(objset_t *os);
 
+/*
+ * Get the [cm]time for an objset's snapshot dir
+ */
+timestruc_t dmu_objset_snap_cmtime(objset_t *os);
+
 int dmu_objset_is_snapshot(objset_t *os);
 
 extern struct spa *dmu_objset_spa(objset_t *os);
--- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h	Mon Aug 24 16:11:19 2009 -0600
@@ -131,6 +131,7 @@
 int dmu_objset_prefetch(char *name, void *arg);
 void dmu_objset_byteswap(void *buf, size_t size);
 int dmu_objset_evict_dbufs(objset_t *os);
+timestruc_t dmu_objset_snap_cmtime(objset_t *os);
 
 /* called from dsl */
 void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h	Mon Aug 24 16:11:19 2009 -0600
@@ -236,9 +236,6 @@
 void dsl_dataset_set_quota_sync(void *arg1, void *arg2, cred_t *cr,
     dmu_tx_t *tx);
 int dsl_dataset_set_reservation(const char *dsname, uint64_t reservation);
-void dsl_dataset_set_flags(dsl_dataset_t *ds, uint64_t flags);
-int64_t dsl_dataset_new_refreservation(dsl_dataset_t *ds, uint64_t reservation,
-    dmu_tx_t *tx);
 
 int dsl_destroy_inconsistent(char *dsname, void *arg);
 
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dir.h	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_dir.h	Mon Aug 24 16:11:19 2009 -0600
@@ -89,6 +89,7 @@
 	/* Protected by dd_lock */
 	kmutex_t dd_lock;
 	list_t dd_prop_cbs; /* list of dsl_prop_cb_record_t's */
+	timestruc_t dd_snap_cmtime; /* last time snapshot namespace changed */
 
 	/* gross estimate of space used by in-flight tx's */
 	uint64_t dd_tempreserved[TXG_SIZE];
@@ -133,6 +134,8 @@
 boolean_t dsl_dir_is_clone(dsl_dir_t *dd);
 void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds,
     uint64_t reservation, cred_t *cr, dmu_tx_t *tx);
+void dsl_dir_snap_cmtime_update(dsl_dir_t *dd);
+timestruc_t dsl_dir_snap_cmtime(dsl_dir_t *dd);
 
 /* internal reserved dir name */
 #define	MOS_DIR_NAME "$MOS"
--- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c	Mon Aug 24 16:42:48 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c	Mon Aug 24 16:11:19 2009 -0600
@@ -311,14 +311,13 @@
 static void
 zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
 {
-	zfsctl_node_t	*zcp = vp->v_data;
 	timestruc_t	now;
 
 	vap->va_uid = 0;
 	vap->va_gid = 0;
 	vap->va_rdev = 0;
 	/*
-	 * We are a purly virtual object, so we have no
+	 * We are a purely virtual object, so we have no
 	 * blocksize or allocated blocks.
 	 */
 	vap->va_blksize = 0;
@@ -333,7 +332,6 @@
 	 */
 	gethrestime(&now);
 	vap->va_atime = now;
-	vap->va_mtime = vap->va_ctime = zcp->zc_cmtime;
 }
 
 /*ARGSUSED*/
@@ -416,10 +414,12 @@
     caller_context_t *ct)
 {
 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
+	zfsctl_node_t *zcp = vp->v_data;
 
 	ZFS_ENTER(zfsvfs);
 	vap->va_nodeid = ZFSCTL_INO_ROOT;
 	vap->va_nlink = vap->va_size = NROOT_ENTRIES;
+	vap->va_mtime = vap->va_ctime = zcp->zc_cmtime;
 
 	zfsctl_common_getattr(vp, vap);
 	ZFS_EXIT(zfsvfs);
@@ -1101,6 +1101,7 @@
 	zfsctl_common_getattr(vp, vap);
 	vap->va_nodeid = gfs_file_inode(vp);
 	vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2;
+	vap->va_ctime = vap->va_mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
 	ZFS_EXIT(zfsvfs);
 
 	return (0);