Subject: Fix for PR kern/2187 (msdosfs w/Win95 support tries to keep access
To: None <netbsd-bugs@NetBSD.ORG>
From: Dave Huang <khym@bga.com>
List: current-users
Date: 04/27/1997 16:21:52
Okay, after seeing Jason Thorpe's comment about PRs with patches being
fixed faster than those without (and waiting over a year :), here's a
patch for kern/2187...
I couldn't find any detailed "official" docs on the structure of a
VFAT directory entry, so I used the brief description from the Windows
NT resource kit (Figure 17.7, p. 571) and the Linux VFAT
implementation as my documentation. It seems to work fine for me; NT's
chkdsk no longer complains "Unrecognized extended attribute handle",
and creation timestamps now have 100th of a second accuracy.
diff -ur /usr/src/sys/msdosfs/denode.h ./denode.h
--- /usr/src/sys/msdosfs/denode.h Sat Apr 12 06:42:53 1997
+++ ./denode.h Sun Apr 27 16:13:05 1997
@@ -151,10 +151,10 @@
pid_t de_lockwaiter; /* lock wanter */
u_char de_Name[12]; /* name, from DOS directory entry */
u_char de_Attributes; /* attributes, from directory entry */
+ u_char de_CTimeHundredth; /* creation time, 1/100th of a sec */
u_short de_CTime; /* creation time */
u_short de_CDate; /* creation date */
u_short de_ADate; /* access date */
- u_short de_ATime; /* access time */
u_short de_MTime; /* modification time */
u_short de_MDate; /* modification date */
u_short de_StartCluster; /* starting cluster of file */
@@ -187,9 +187,9 @@
#define DE_INTERNALIZE(dep, dp) \
(bcopy((dp)->deName, (dep)->de_Name, 11), \
(dep)->de_Attributes = (dp)->deAttributes, \
+ (dep)->de_CTimeHundredth = (dp)->deCTimeHundredth, \
(dep)->de_CTime = getushort((dp)->deCTime), \
(dep)->de_CDate = getushort((dp)->deCDate), \
- (dep)->de_ATime = getushort((dp)->deATime), \
(dep)->de_ADate = getushort((dp)->deADate), \
(dep)->de_MTime = getushort((dp)->deMTime), \
(dep)->de_MDate = getushort((dp)->deMDate), \
@@ -199,10 +199,13 @@
#define DE_EXTERNALIZE(dp, dep) \
(bcopy((dep)->de_Name, (dp)->deName, 11), \
(dp)->deAttributes = (dep)->de_Attributes, \
+ (dp)->deLowerCase = CASE_LOWER_BASE | CASE_LOWER_EXT, \
+ (dp)->deCTimeHundredth = (dep)->de_CTimeHundredth, \
putushort((dp)->deCTime, (dep)->de_CTime), \
putushort((dp)->deCDate, (dep)->de_CDate), \
- putushort((dp)->deATime, (dep)->de_ATime), \
putushort((dp)->deADate, (dep)->de_ADate), \
+ (dp)->deReserved[0] = 0, \
+ (dp)->deReserved[1] = 0, \
putushort((dp)->deMTime, (dep)->de_MTime), \
putushort((dp)->deMDate, (dep)->de_MDate), \
putushort((dp)->deStartCluster, (dep)->de_StartCluster), \
@@ -226,9 +229,11 @@
} \
if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \
if ((dep)->de_flag & DE_ACCESS) \
- unix2dostime((acc), &(dep)->de_ADate, &(dep)->de_ATime); \
- if ((dep)->de_flag & DE_CREATE) \
+ unix2dostime((acc), &(dep)->de_ADate, NULL); \
+ if ((dep)->de_flag & DE_CREATE) { \
unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime); \
+ (dep)->de_CTimeHundredth = ((cre)->tv_sec & 1 ? 100 : 0) + (cre)->tv_nsec / 10000000; \
+ } \
} \
(dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
}
diff -ur /usr/src/sys/msdosfs/direntry.h ./direntry.h
--- /usr/src/sys/msdosfs/direntry.h Sat Oct 26 06:21:01 1996
+++ ./direntry.h Sun Apr 27 16:11:26 1997
@@ -64,11 +64,14 @@
#define ATTR_VOLUME 0x08 /* entry is a volume label */
#define ATTR_DIRECTORY 0x10 /* entry is a directory name */
#define ATTR_ARCHIVE 0x20 /* file is new or modified */
- u_int8_t deReserved[2]; /* reserved */
+ u_int8_t deLowerCase; /* case for base and extension */
+#define CASE_LOWER_BASE 0x08 /* base is lower case */
+#define CASE_LOWER_EXT 0x10 /* extension is lower case */
+ u_int8_t deCTimeHundredth; /* create time, 1/100th of a sec */
u_int8_t deCTime[2]; /* create time */
u_int8_t deCDate[2]; /* create date */
u_int8_t deADate[2]; /* access date */
- u_int8_t deATime[2]; /* access time */
+ u_int8_t deReserved[2]; /* reserved */
u_int8_t deMTime[2]; /* last update time */
u_int8_t deMDate[2]; /* last update date */
u_int8_t deStartCluster[2]; /* starting cluster of file */
diff -ur /usr/src/sys/msdosfs/msdosfs_conv.c ./msdosfs_conv.c
--- /usr/src/sys/msdosfs/msdosfs_conv.c Wed Jan 15 06:23:19 1997
+++ ./msdosfs_conv.c Sun Apr 27 12:51:46 1997
@@ -150,7 +150,9 @@
lastddate += (year - 1980) << DD_YEAR_SHIFT;
}
}
- *dtp = lastdtime;
+
+ if (dtp != NULL)
+ *dtp = lastdtime;
*ddp = lastddate;
}
diff -ur /usr/src/sys/msdosfs/msdosfs_denode.c ./msdosfs_denode.c
--- /usr/src/sys/msdosfs/msdosfs_denode.c Mon Oct 14 11:42:15 1996
+++ ./msdosfs_denode.c Sun Apr 27 16:10:07 1997
@@ -240,10 +240,10 @@
* denode
*/
ldep->de_CTime = 0x0000; /* 00:00:00 */
+ ldep->de_CTimeHundredth = 0;
ldep->de_CDate = (0 << DD_YEAR_SHIFT) | (1 << DD_MONTH_SHIFT)
| (1 << DD_DAY_SHIFT);
/* Jan 1, 1980 */
- ldep->de_ATime = ldep->de_CTime;
ldep->de_ADate = ldep->de_CDate;
ldep->de_MTime = ldep->de_CTime;
ldep->de_MDate = ldep->de_CDate;
diff -ur /usr/src/sys/msdosfs/msdosfs_vnops.c ./msdosfs_vnops.c
--- /usr/src/sys/msdosfs/msdosfs_vnops.c Sat Nov 9 06:20:26 1996
+++ ./msdosfs_vnops.c Sun Apr 27 16:10:56 1997
@@ -301,8 +301,14 @@
vap->va_size = dep->de_FileSize;
dos2unixtime(dep->de_MDate, dep->de_MTime, &vap->va_mtime);
if (dep->de_pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
- dos2unixtime(dep->de_ADate, dep->de_ATime, &vap->va_atime);
+ dos2unixtime(dep->de_ADate, 0, &vap->va_atime);
dos2unixtime(dep->de_CDate, dep->de_CTime, &vap->va_ctime);
+ if (dep->de_CTimeHundredth >= 100) {
+ vap->va_ctime.tv_sec++;
+ vap->va_ctime.tv_nsec = (dep->de_CTimeHundredth - 100) * 10000000;
+ } else
+ vap->va_ctime.tv_nsec = dep->de_CTimeHundredth * 10000000;
+
} else {
vap->va_atime = vap->va_mtime;
vap->va_ctime = vap->va_mtime;
@@ -372,7 +378,7 @@
return (error);
if (!(dep->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)
&& vap->va_atime.tv_sec != VNOVAL)
- unix2dostime(&vap->va_atime, &dep->de_ADate, &dep->de_ATime);
+ unix2dostime(&vap->va_atime, &dep->de_ADate, NULL);
if (vap->va_mtime.tv_sec != VNOVAL)
unix2dostime(&vap->va_mtime, &dep->de_MDate, &dep->de_MTime);
dep->de_Attributes |= ATTR_ARCHIVE;
@@ -1169,18 +1175,22 @@
} dosdirtemplate = {
{ ". ", " ", /* the . entry */
ATTR_DIRECTORY, /* file attribute */
- { 0, 0 }, /* reserved */
+ CASE_LOWER_BASE | CASE_LOWER_EXT, /* lower case */
+ 0, /* create time 100ths */
{ 0, 0 }, { 0, 0 }, /* create time & date */
- { 0, 0 }, { 0, 0 }, /* access time & date */
+ { 0, 0 }, /* access date */
+ { 0, 0 }, /* reserved */
{ 210, 4 }, { 210, 4 }, /* modify time & date */
{ 0, 0 }, /* startcluster */
{ 0, 0, 0, 0 } /* filesize */
},
{ ".. ", " ", /* the .. entry */
ATTR_DIRECTORY, /* file attribute */
- { 0, 0 }, /* reserved */
+ CASE_LOWER_BASE | CASE_LOWER_EXT, /* lower case */
+ 0, /* create time 100ths */
{ 0, 0 }, { 0, 0 }, /* create time & date */
- { 0, 0 }, { 0, 0 }, /* access time & date */
+ { 0, 0 }, /* access date */
+ { 0, 0 }, /* reserved */
{ 210, 4 }, { 210, 4 }, /* modify time & date */
{ 0, 0 }, /* startcluster */
{ 0, 0, 0, 0 } /* filesize */
@@ -1247,15 +1257,15 @@
putushort(denp[0].deStartCluster, newcluster);
putushort(denp[0].deCDate, ndirent.de_CDate);
putushort(denp[0].deCTime, ndirent.de_CTime);
+ denp[0].deCTimeHundredth = ndirent.de_CTimeHundredth;
putushort(denp[0].deADate, ndirent.de_ADate);
- putushort(denp[0].deATime, ndirent.de_ATime);
putushort(denp[0].deMDate, ndirent.de_MDate);
putushort(denp[0].deMTime, ndirent.de_MTime);
putushort(denp[1].deStartCluster, pdep->de_StartCluster);
putushort(denp[1].deCDate, ndirent.de_CDate);
putushort(denp[1].deCTime, ndirent.de_CTime);
+ denp[1].deCTimeHundredth = ndirent.de_CTimeHundredth;
putushort(denp[1].deADate, ndirent.de_ADate);
- putushort(denp[1].deATime, ndirent.de_ATime);
putushort(denp[1].deMDate, ndirent.de_MDate);
putushort(denp[1].deMTime, ndirent.de_MTime);
if ((error = bwrite(bp)) != 0)
Name: Dave Huang | Mammal, mammal / their names are called /
INet: khym@bga.com | they raise a paw / the bat, the cat /
FurryMUCK: Dahan | dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 21 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++