NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: PR/49144 CVS commit: src/tests/fs/vfs



The following reply was made to PR bin/49144; it has been noted by GNATS.

From: Martin Husemann <martin%duskware.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: Andreas Gustafsson <gson%gson.org@localhost>
Subject: Re: PR/49144 CVS commit: src/tests/fs/vfs
Date: Sat, 30 Aug 2014 17:33:28 +0200

 I was going to suggest something like the below (untested) change and then
 only make sure that the todr(9) helper functions perform well, but
 that breaks the tool compilation of makefs (which can do -t msdos).
 
 UDF already uses the todr(9) functions directly.
 At least this patch avoids threading issues with the caching done in
 msdofs.
 
 Suggestions how to best "toolify" sys/dev/clock_subr.c ?
 
 Martin
 
 Index: msdosfs_conv.c
 ===================================================================
 RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_conv.c,v
 retrieving revision 1.9
 diff -u -p -r1.9 msdosfs_conv.c
 --- msdosfs_conv.c     26 Jan 2013 16:51:51 -0000      1.9
 +++ msdosfs_conv.c     30 Aug 2014 15:28:29 -0000
 @@ -64,6 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_conv
  #include <sys/systm.h>
  #include <sys/kernel.h>
  #include <sys/vnode.h>
 +#include <dev/clock_subr.h>
  #else
  #include <stdio.h>
  #include <dirent.h>
 @@ -77,29 +78,10 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_conv
  #include <fs/msdosfs/denode.h>
  
  /*
 - * Days in each month in a regular year.
 - */
 -u_short const regyear[] = {
 -      31, 28, 31, 30, 31, 30,
 -      31, 31, 30, 31, 30, 31
 -};
 -
 -/*
 - * Days in each month in a leap year.
 - */
 -u_short const leapyear[] = {
 -      31, 29, 31, 30, 31, 30,
 -      31, 31, 30, 31, 30, 31
 -};
 -
 -/*
 - * Variables used to remember parts of the last time conversion.  Maybe we
 - * can avoid a full conversion.
 + * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
 + * interval there were 8 regular years and 2 leap years.
   */
 -u_long lasttime;
 -u_long lastday;
 -u_short lastddate;
 -u_short lastdtime;
 +#define       SECONDSTO1980   (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
  
  /*
   * Convert the unix version of time to dos's idea of time to be used in
 @@ -109,74 +91,47 @@ void
  unix2dostime(const struct timespec *tsp, int gmtoff, u_int16_t *ddp, 
u_int16_t *dtp, u_int8_t *dhp)
  {
        u_long t;
 -      u_long days;
 -      u_long inc;
 -      u_long year;
 -      u_long month;
 -      const u_short *months;
 +      struct clock_ymdhms ymd;
 +
 +      t = tsp->tv_sec + gmtoff; /* time zone correction */
  
        /*
 -       * If the time from the last conversion is the same as now, then
 -       * skip the computations and use the saved result.
 +       * DOS timestamps can not represent dates before 1980.
 +       */
 +      if (t < SECONDSTO1980) {
 +              *ddp = 0;
 +              if (dtp)
 +                      *dtp = 0;
 +              if (dhp)
 +                      *dhp = 0;
 +              return;
 +      }
 +
 +      /*
 +       * DOS granularity is 2 seconds
         */
 -      t = tsp->tv_sec + gmtoff; /* time zone correction */
        t &= ~1;
 -      if (lasttime != t) {
 -              lasttime = t;
 -              lastdtime = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
 -                  + (((t / 60) % 60) << DT_MINUTES_SHIFT)
 -                  + (((t / 3600) % 24) << DT_HOURS_SHIFT);
  
 -              /*
 -               * If the number of days since 1970 is the same as the last
 -               * time we did the computation then skip all this leap year
 -               * and month stuff.
 -               */
 -              days = t / (24 * 60 * 60);
 -              if (days != lastday) {
 -                      lastday = days;
 -                      for (year = 1970;; year++) {
 -                              inc = year & 0x03 ? 365 : 366;
 -                              if (days < inc)
 -                                      break;
 -                              days -= inc;
 -                      }
 -                      months = year & 0x03 ? regyear : leapyear;
 -                      for (month = 0; month < 12; month++) {
 -                              if (days < months[month])
 -                                      break;
 -                              days -= months[month];
 -                      }
 -                      lastddate = ((days + 1) << DD_DAY_SHIFT)
 -                          + ((month + 1) << DD_MONTH_SHIFT);
 -                      /*
 -                       * Remember dos's idea of time is relative to 1980.
 -                       * unix's is relative to 1970.  If somehow we get a
 -                       * time before 1980 then don't give totally crazy
 -                       * results.
 -                       */
 -                      if (year > 1980)
 -                              lastddate += (year - 1980) << DD_YEAR_SHIFT;
 -              }
 -      }
 -      if (dtp)
 -              *dtp = lastdtime;
 +      /*
 +       * Convert to year/month/day/.. format
 +       */
 +      clock_secs_to_ymdhms(t, &ymd);
 +
 +      /*
 +       * Now transform to DOS format
 +       */
 +      *ddp = (ymd.dt_day << DD_DAY_SHIFT)
 +          + (ymd.dt_mon << DD_MONTH_SHIFT)
 +          + ((ymd.dt_year - 1980) << DD_YEAR_SHIFT);
        if (dhp)
                *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
 -
 -      *ddp = lastddate;
 +      if (dtp)
 +              *dtp = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
 +                  + (((t / 60) % 60) << DT_MINUTES_SHIFT)
 +                  + (((t / 3600) % 24) << DT_HOURS_SHIFT);
  }
  
  /*
 - * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
 - * interval there were 8 regular years and 2 leap years.
 - */
 -#define       SECONDSTO1980   (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
 -
 -u_short lastdosdate;
 -u_long lastseconds;
 -
 -/*
   * Convert from dos' idea of time to unix'. This will probably only be
   * called from the stat(), and fstat() system calls and so probably need
   * not be too efficient.
 @@ -184,11 +139,8 @@ u_long lastseconds;
  void
  dos2unixtime(u_int dd, u_int dt, u_int dh, int gmtoff, struct timespec *tsp)
  {
 -      u_long seconds;
 -      u_long m, month;
 -      u_long y, year;
 -      u_long days;
 -      const u_short *months;
 +      time_t seconds;
 +      struct clock_ymdhms ymd;
  
        if (dd == 0) {
                /*
 @@ -198,37 +150,15 @@ dos2unixtime(u_int dd, u_int dt, u_int d
                tsp->tv_nsec = 0;
                return;
        }
 -      seconds = ((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) * 2
 -          + ((dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT) * 60
 -          + ((dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT) * 3600
 -          + dh / 100;
 -      /*
 -       * If the year, month, and day from the last conversion are the
 -       * same then use the saved value.
 -       */
 -      if (lastdosdate != dd) {
 -              lastdosdate = dd;
 -              days = 0;
 -              year = (dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT;
 -              for (y = 0; y < year; y++)
 -                      days += y & 0x03 ? 365 : 366;
 -              months = year & 0x03 ? regyear : leapyear;
 -              /*
 -               * Prevent going from 0 to 0xffffffff in the following
 -               * loop.
 -               */
 -              month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT;
 -              if (month == 0) {
 -                      printf("%s: month value out of range (%ld)\n",
 -                          __func__, month);
 -                      month = 1;
 -              }
 -              for (m = 0; m < month - 1; m++)
 -                      days += months[m];
 -              days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1;
 -              lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980;
 -      }
 -      tsp->tv_sec = seconds + lastseconds;
 +
 +      memset(&ymd, 0, sizeof(ymd));
 +      ymd.dt_year = ((dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT) + 1980 ;
 +      ymd.dt_mon = ((dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT);
 +      ymd.dt_day = ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT);
 +
 +      seconds = clock_ymdhms_to_secs(&ymd);
 +
 +      tsp->tv_sec = seconds;
        tsp->tv_sec -= gmtoff;  /* time zone correction */
        tsp->tv_nsec = (dh % 100) * 10000000;
  }
 


Home | Main Index | Thread Index | Old Index