Bug in fat-fs code: file date/time wrong

Peter Daum (gator@cs.tu-berlin.de)
Thu, 11 Nov 1999 14:20:09 +0100 (MET)


Hi,

it seems, that the calculation of fat/vfat file times in the
linux kernel is incorrect. Consider the following DOS directory
listing:

jan 0 01-01-1999 0:00
feb 0 02-01-1999 0:00
mar 0 03-01-1999 0:00
apr 0 04-01-1999 0:00
mai 0 05-01-1999 0:00
jun 0 06-01-1999 0:00
jul 0 07-01-1999 0:00
aug 0 08-01-1999 0:00
sep 0 09-01-1999 0:00
okt 0 10-01-1999 0:00
nov 0 11-01-1999 0:00
dec 0 12-01-1999 0:00

The listing is generated by mdir, which reports the same
date/time as MS-DOS. When mounted as a msdos or vfat file system,
Linux reports the following timestamps instead:

FILENAME MTIME
jan 98-12-31 23:00
feb 99-01-31 23:00
mar 99-02-28 23:00
apr 99-04-01 00:00
mai 99-05-01 00:00
jun 99-06-01 00:00
jul 99-07-01 00:00
aug 99-08-01 00:00
sep 99-09-01 00:00
okt 99-10-01 00:00
nov 99-10-31 23:00
dec 99-11-30 23:00

My local time is MET (GMT+1, DST= GMT+2). It seems, like the
timestamps are correct, when Daylight Saving Time is in effect
and on hour off otherwise. The responsible code in the linux
sources seems to be in fs/fat/misc.c:

> /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
> int date_dos2unix(unsigned short time,unsigned short date)
> [...]
> secs += sys_tz.tz_minuteswest*60;
> if (sys_tz.tz_dsttime) secs -= 3600;
> return secs;

and

> /* Convert linear UNIX date to a MS-DOS time/date pair. */
> void fat_date_unix2dos(int unix_date,unsigned short *time,
> unsigned short *date)
> [...]
> unix_date -= sys_tz.tz_minuteswest*60;
> if (sys_tz.tz_dsttime) unix_date += 3600;

I don't have enough insight into the linux kernel to figure out
what goes wrong here. The man page for gettimeofday states:

> The use of the timezone struct is obsolete; the tz_dsttime
> field has never been used under Linux - it has not been
> and will not be supported by libc or glibc. Each and
> every occurrence of this field in the kernel source (other
> than the declaration) is a bug. Thus, the following is
> purely of historic interest.

>From the example above it seems, like "sys_tz.tz_minuteswest"
does not even reflect the offset to GMT, not to mention DST...
Maybe somebody more involved in linux file-systems has any idea,
how to get this right? Correct handling of DST probably would be
pretty hard, but Isn't there any way to get the timestamps back,
that are actually stored in the directory entries (which would
contain the correct date/time)?

When file systems are shared between different operation systems,
the current bahavior can cause major trouble (at least it does
for me ... ;-)

Regards,
Peter

-- 
                                             __o  
     Peter Daum <gator at cs.tu-berlin.de> _'\<_ 
       - pgp messages welcome -       ____(_)/(_)

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/