kern/106018: [PATCH] msdosfs: fix handling of mtime,
ctime and birthtime
Oliver Fromme
olli at secnetix.de
Wed Nov 29 07:43:54 PST 2006
>Number: 106018
>Category: kern
>Synopsis: [PATCH] msdosfs: fix handling of mtime, ctime and birthtime
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 29 15:40:14 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Oliver Fromme
>Release: RELENG_6 + HEAD
>Organization:
secnetix GmbH & Co. KG
http://www.secnetix.de/bsd
>Environment:
This PR provides patches for RELENG_6 and HEAD
(as of 2006-11-29). However, the problem seems
to exist for as long as FreeBSD has msdosfs.
>Description:
A recent thread in the freebsd-fs mailing list
reveals that src/sys/fs/msdosfs/msdosfs_vnops.c
has a bug handling ctime, mtime and birthtime
time stamps. The cause of the bug is probably
the confusing fact that the FAT world calls the
birthtime "CTime" (creation time), while it does
not support at all what UNIX calls the ctime.
As a result from that confusion, the function
msdosfs_getattr() sets ctime field to the "CTime"
of the FAT entry (which is really the birthtime),
and doesn't set the birthtime in the struct vattr
at all, returning garbage.
The patch below fixes the problem as follows:
First, the ctime (which FAT doesn't support) is
always set equal to the mtime.
Second, in the MSDOSFSMNT_LONGNAME case, the
birthtime is taken from the FAT's "CTime", and
in the other case (unsupported) it is set to -1
which should be a reasonable value.
Bruce Evans asked me to record the whole thing
via send-pr, so here it is.
>How-To-Repeat:
Mount an msdosfs (you can easily create one with
mdconfig + newfs_msdos, or use a USB stick with
a FAT on it if you have one handy), touch a file
in it, and check the birthtime with "ls -lU".
>Fix:
Patch for RELENG_6:
--- src/sys/fs/msdosfs/msdosfs_vnops.c.orig Mon Mar 13 04:05:13 2006
+++ src/sys/fs/msdosfs/msdosfs_vnops.c Wed Nov 29 15:51:20 2006
@@ -341,12 +341,15 @@
vap->va_rdev = 0;
vap->va_size = dep->de_FileSize;
dos2unixtime(dep->de_MDate, dep->de_MTime, 0, &vap->va_mtime);
+ vap->va_ctime = vap->va_mtime;
if (pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
dos2unixtime(dep->de_ADate, 0, 0, &vap->va_atime);
- dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun, &vap->va_ctime);
+ dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun,
+ &vap->va_birthtime);
} else {
vap->va_atime = vap->va_mtime;
- vap->va_ctime = vap->va_mtime;
+ vap->va_birthtime.tv_sec = -1;
+ vap->va_birthtime.tv_nsec = 0;
}
vap->va_flags = 0;
if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
Patch for HEAD (untested!):
--- src/sys/fs/msdosfs/msdosfs_vnops.c.orig Mon Nov 6 14:41:57 2006
+++ src/sys/fs/msdosfs/msdosfs_vnops.c Wed Nov 29 16:13:19 2006
@@ -343,13 +343,15 @@
vap->va_rdev = 0;
vap->va_size = dep->de_FileSize;
fattime2timespec(dep->de_MDate, dep->de_MTime, 0, 0, &vap->va_mtime);
+ vap->va_ctime = vap->va_mtime;
if (pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
fattime2timespec(dep->de_ADate, 0, 0, 0, &vap->va_atime);
fattime2timespec(dep->de_CDate, dep->de_CTime, dep->de_CHun,
- 0, &vap->va_ctime);
+ 0, &vap->va_birthtime);
} else {
vap->va_atime = vap->va_mtime;
- vap->va_ctime = vap->va_mtime;
+ vap->va_birthtime.tv_sec = -1;
+ vap->va_birthtime.tv_nsec = 0;
}
vap->va_flags = 0;
if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list