Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Jul 2008 10:57:19 +0300
From:      Jaakko Heinonen <jh@saunalahti.fi>
To:        Bruce Evans <brde@optusnet.com.au>, freebsd-fs@freebsd.org
Cc:        ighighi@gmail.com
Subject:   birthtime initialization
Message-ID:  <20080722075718.GA1881@a91-153-120-204.elisa-laajakaista.fi>
In-Reply-To: <200806020800.m528038T072838@freefall.freebsd.org>
References:  <200806020800.m528038T072838@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2008-06-02, Bruce Evans wrote:
[about patch for ext2fs in PR kern/122047]
>  % +	vap->va_birthtime.tv_sec = 0;
>  % +	vap->va_birthtime.tv_nsec = 0;
>  
>  This is unrelated and should be handled centrally.  Almost all file
>  systems get this wrong.  Most fail to set va_birthtime, so stat()
>  returns kernel stack garbage for st_birthtime.  ffs1 does the same
>  as the above.  msdosfs does the above correctly, by setting tv_sec to
>  (time_t)-1 in unsupported cases.

How about this patch?

%%%
Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c	(revision 180588)
+++ sys/kern/vfs_vnops.c	(working copy)
@@ -703,6 +703,9 @@ vn_stat(vp, sb, active_cred, file_cred, 
 #endif
 
 	vap = &vattr;
+	/* Not all file systems initialize birthtime. */
+	VATTR_NULL(vap);
+
 	error = VOP_GETATTR(vp, vap, active_cred, td);
 	if (error)
 		return (error);
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
--- sys/ufs/ufs/ufs_vnops.c	(revision 180588)
+++ sys/ufs/ufs/ufs_vnops.c	(working copy)
@@ -410,8 +410,8 @@ ufs_getattr(ap)
 		vap->va_mtime.tv_nsec = ip->i_din1->di_mtimensec;
 		vap->va_ctime.tv_sec = ip->i_din1->di_ctime;
 		vap->va_ctime.tv_nsec = ip->i_din1->di_ctimensec;
-		vap->va_birthtime.tv_sec = 0;
-		vap->va_birthtime.tv_nsec = 0;
+		vap->va_birthtime.tv_sec = (time_t)-1;
+		vap->va_birthtime.tv_nsec = -1;
 		vap->va_bytes = dbtob((u_quad_t)ip->i_din1->di_blocks);
 	} else {
 		vap->va_rdev = ip->i_din2->di_rdev;
Index: sys/fs/msdosfs/msdosfs_vnops.c
===================================================================
--- sys/fs/msdosfs/msdosfs_vnops.c	(revision 180588)
+++ sys/fs/msdosfs/msdosfs_vnops.c	(working copy)
@@ -345,8 +345,8 @@ msdosfs_getattr(ap)
 		    0, &vap->va_birthtime);
 	} else {
 		vap->va_atime = vap->va_mtime;
-		vap->va_birthtime.tv_sec = -1;
-		vap->va_birthtime.tv_nsec = 0;
+		vap->va_birthtime.tv_sec = (time_t)-1;
+		vap->va_birthtime.tv_nsec = -1;
 	}
 	vap->va_flags = 0;
 	if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
Index: sys/nfsclient/nfs_subs.c
===================================================================
--- sys/nfsclient/nfs_subs.c	(revision 180588)
+++ sys/nfsclient/nfs_subs.c	(working copy)
@@ -628,6 +628,8 @@ nfs_loadattrcache(struct vnode **vpp, st
 	vap->va_rdev = rdev;
 	mtime_save = vap->va_mtime;
 	vap->va_mtime = mtime;
+	vap->va_birthtime.tv_sec = (time_t)-1;
+	vap->va_birthtime.tv_nsec = -1;
 	vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
 	if (v3) {
 		vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
%%%

The patch adds VATTR_NULL() call to vn_stat() to initialize the vattr
structure before VOP_GETATTR() call. VATTR_NULL() initializes
va_birthtime.tv_sec and va_birthtime.tv_nsec to -1 (VNOVAL). I also
changed UFS1 and msdosfs to use consistent values. NFS needs explicit
initialization because otherwise values would be set to 0 due to memory
obtained with M_ZERO flag.

I have tested the patch with UFS2, UFS1, cd9660, nfs, ext2fs and smbfs.

(There's also more information about the problem in this message:
http://lists.freebsd.org/pipermail/freebsd-bugs/2008-March/029682.html)

-- 
Jaakko



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080722075718.GA1881>