birthtime initialization
Jaakko Heinonen
jh at saunalahti.fi
Tue Jul 22 08:16:56 UTC 2008
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
More information about the freebsd-fs
mailing list