svn commit: r313483 - in head/sys/cddl/contrib/opensolaris/uts/common: fs/zfs sys

Alan Somers asomers at FreeBSD.org
Thu Feb 9 21:30:55 UTC 2017


Author: asomers
Date: Thu Feb  9 21:30:53 2017
New Revision: 313483
URL: https://svnweb.freebsd.org/changeset/base/313483

Log:
  Fix setting birthtime in ZFS
  
  sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  	* In zfs_freebsd_setattr, if the caller wants to set the birthtime,
  	  set the bits that zfs_settattr expects
  
  	* In zfs_setattr, if XAT_CREATETIME is set, set xoa_createtime,
  	  expected by zfs_xvattr_set.  The two levels of indirection seem
  	  excessive, but it minimizes diffs vs OpenZFS.
  
  	* In zfs_setattr, check for overflow of va_birthtime (from delphij)
  
  	* Remove red herring in zfs_getattr
  
  sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
  	* Un-booby-trap some macros
  
  New tests are under review at https://github.com/pjd/pjdfstest/pull/6
  
  Reviewed by:	avg
  MFC after:	3 weeks
  Sponsored by:	Spectra Logic Corp
  Differential Revision:	https://reviews.freebsd.org/D9353

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  head/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Feb  9 21:29:18 2017	(r313482)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Feb  9 21:30:53 2017	(r313483)
@@ -2786,15 +2786,6 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, i
 			zfs_sa_get_scanstamp(zp, xvap);
 		}
 
-		if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
-			uint64_t times[2];
-
-			(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs),
-			    times, sizeof (times));
-			ZFS_TIME_DECODE(&xoap->xoa_createtime, times);
-			XVA_SET_RTN(xvap, XAT_CREATETIME);
-		}
-
 		if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) {
 			xoap->xoa_reparse = ((zp->z_pflags & ZFS_REPARSE) != 0);
 			XVA_SET_RTN(xvap, XAT_REPARSE);
@@ -2956,6 +2947,11 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i
 			return (SET_ERROR(EOVERFLOW));
 		}
 	}
+	if (xoap && (mask & AT_XVATTR) && XVA_ISSET_REQ(xvap, XAT_CREATETIME) &&
+	    TIMESPEC_OVERFLOW(&vap->va_birthtime)) {
+		ZFS_EXIT(zfsvfs);
+		return (SET_ERROR(EOVERFLOW));
+	}
 
 	attrzp = NULL;
 	aclp = NULL;
@@ -3400,6 +3396,8 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i
 
 	if (xoap && (mask & AT_XVATTR)) {
 
+		if (XVA_ISSET_REQ(xvap, XAT_CREATETIME))
+			xoap->xoa_createtime = vap->va_birthtime;
 		/*
 		 * restore trimmed off masks
 		 * so that return masks can be set for caller.
@@ -5251,6 +5249,10 @@ zfs_freebsd_setattr(ap)
 		    xvap.xva_xoptattrs.xoa_sparse);
 #undef	FLAG_CHANGE
 	}
+	if (vap->va_birthtime.tv_sec != VNOVAL) {
+		xvap.xva_vattr.va_mask |= AT_XVATTR;
+		XVA_SET_REQ(&xvap, XAT_CREATETIME);
+	}
 	return (zfs_setattr(vp, (vattr_t *)&xvap, 0, cred, NULL));
 }
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h	Thu Feb  9 21:29:18 2017	(r313482)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h	Thu Feb  9 21:30:53 2017	(r313483)
@@ -268,27 +268,30 @@ typedef struct xvattr {
  * XVA_SET_REQ() sets an attribute bit in the proper element in the bitmap
  * of requested attributes (xva_reqattrmap[]).
  */
-#define	XVA_SET_REQ(xvap, attr)					\
+#define	XVA_SET_REQ(xvap, attr)	{				\
 	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
 	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
-	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
+	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr); \
+}
 /*
  * XVA_CLR_REQ() clears an attribute bit in the proper element in the bitmap
  * of requested attributes (xva_reqattrmap[]).
  */
-#define	XVA_CLR_REQ(xvap, attr)					\
+#define	XVA_CLR_REQ(xvap, attr)	{				\
 	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
 	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
-	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
+	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr); \
+}
 
 /*
  * XVA_SET_RTN() sets an attribute bit in the proper element in the bitmap
  * of returned attributes (xva_rtnattrmap[]).
  */
-#define	XVA_SET_RTN(xvap, attr)					\
+#define	XVA_SET_RTN(xvap, attr)	{				\
 	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
 	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
-	(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
+	(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr); \
+}
 
 /*
  * XVA_ISSET_REQ() checks the requested attribute bitmap (xva_reqattrmap[])


More information about the svn-src-head mailing list