On Wed, Feb 19, 2020 at 10:02:10AM -0600, Scott Cheloha wrote: > On Wed, Feb 19, 2020 at 04:00:34PM +0100, Otto Moerbeek wrote: > > > > [...] > > > > FFS1, the default filesystem, uses 32-bit signed timestamps on disk. > > That means that in 2038, there's going to be a problem, timestamps > > will the be interperet as coming from the start of the 1900's. > > > > FFS2 does not have this limitation, but at the moment, we cannot boot > > from it. I'm working on that as well, but for now I like to propose a > > diff that interprets all timestamps in FFS1 as unsigned. > > > > * On disk format dos not change > > * Current timestamp values do not change > > Doesn't this change the interpretation of timestamps before 1970? > > Humor me: > > # date 196901010000 > Wed Jan 1 00:00:00 CST 1969 > # touch test && ls -l test > -rw-r--r-- 1 ssc ssc 0 Jan 1 00:00 test > # stat test > 1038 8878266 -rw-r--r-- 1 ssc ssc 0 0 "Jan 1 00:00:58 1969" "Jan 1 00:00:58 > 1969" "Jan 1 00:00:58 1969" 32768 0 0 test > > ... so what happens to such files? The timestamps wrap around? > > I'm not sure if that should prevent us from implementing this stopgap, > but it's worth considering. > > > I have checked various tools like dump(8) and restore(8), they work > > properly. Code normally works with the fields from struct stat, which > > is already 64-bit. I can imagine code setting timestamps to -1 > > explicitly, that could cause surprises. > > > > So I'm asking for wider testing of the diff below. > > One small bug below. > > > Index: ufs/ffs/ffs_alloc.c > > =================================================================== > > RCS file: /cvs/src/sys/ufs/ffs/ffs_alloc.c,v > > retrieving revision 1.109 > > diff -u -p -r1.109 ffs_alloc.c > > --- ufs/ffs/ffs_alloc.c 19 Jul 2019 00:24:31 -0000 1.109 > > +++ ufs/ffs/ffs_alloc.c 16 Feb 2020 19:33:07 -0000 > > @@ -888,7 +888,8 @@ ffs_fragextend(struct inode *ip, int cg, > > return (0); > > > > cgp = (struct cg *)bp->b_data; > > - cgp->cg_ffs2_time = cgp->cg_time = time_second; > > + cgp->cg_ffs2_time = time_second; > > + cgp->cg_time = time_second; > > You shouldn't re-read time_second here unless you want to introduce a > possible difference between cg_ffs2_time and cg_time. > > You should also, in general, avoid time_second. There is a split-read > bug on 32-bit platforms at the 2038 cross-over. > > That one I'm less certain about, though. time_second assignment is > brief compared to the alternative: > > struct timespec now; > > nanotime(&now); > cgp->cg_ffs2_time = now.tv_sec; > cgp->cg_time = now.tv_sec; > > ... and the window for the split-read bug is very small... > > At minimum, don't re-read time_second.
OK, I'll change that. Ne aware the filesystems is full of time_second. -Otto > > > bno = dtogd(fs, bprev); > > for (i = numfrags(fs, osize); i < frags; i++) > > Index: ufs/ffs/fs.h > > =================================================================== > > RCS file: /cvs/src/sys/ufs/ffs/fs.h,v > > retrieving revision 1.42 > > diff -u -p -r1.42 fs.h > > --- ufs/ffs/fs.h 27 Nov 2016 13:27:55 -0000 1.42 > > +++ ufs/ffs/fs.h 16 Feb 2020 19:33:07 -0000 > > @@ -199,7 +199,7 @@ struct fs { > > int32_t fs_dblkno; /* offset of first data / frags */ > > int32_t fs_cgoffset; /* cylinder group offset in cylinder */ > > int32_t fs_cgmask; /* used to calc mod fs_ntrak */ > > - int32_t fs_ffs1_time; /* last time written */ > > + u_int32_t fs_ffs1_time; /* last time written */ > > int32_t fs_ffs1_size; /* # of blocks in fs / frags */ > > int32_t fs_ffs1_dsize; /* # of data blocks in fs */ > > int32_t fs_ncg; /* # of cylinder groups */ > > @@ -285,7 +285,7 @@ struct fs { > > int32_t fs_avgfpdir; /* expected # of files per directory */ > > int32_t fs_sparecon[26]; /* reserved for future constants */ > > u_int32_t fs_flags; /* see FS_ flags below */ > > - int32_t fs_fscktime; /* last time fsck(8)ed */ > > + u_int32_t fs_fscktime; /* last time fsck(8)ed */ > > int32_t fs_contigsumsize; /* size of cluster summary array */ > > int32_t fs_maxsymlinklen; /* max length of an internal symlink */ > > int32_t fs_inodefmt; /* format of on-disk inodes */ > > @@ -376,7 +376,7 @@ struct fs { > > struct cg { > > int32_t cg_firstfield; /* historic cyl groups linked list */ > > int32_t cg_magic; /* magic number */ > > - int32_t cg_time; /* time last written */ > > + u_int32_t cg_time; /* time last written */ > > int32_t cg_cgx; /* we are the cgx'th cylinder group */ > > int16_t cg_ncyl; /* number of cyl's this cg */ > > int16_t cg_niblk; /* number of inode blocks this cg */ > > Index: ufs/ufs/dinode.h > > =================================================================== > > RCS file: /cvs/src/sys/ufs/ufs/dinode.h,v > > retrieving revision 1.18 > > diff -u -p -r1.18 dinode.h > > --- ufs/ufs/dinode.h 30 May 2013 19:19:09 -0000 1.18 > > +++ ufs/ufs/dinode.h 16 Feb 2020 19:33:07 -0000 > > @@ -72,11 +72,11 @@ struct ufs1_dinode { > > u_int32_t inumber; /* 4: Lfs: inode number. */ > > } di_u; > > u_int64_t di_size; /* 8: File byte count. */ > > - int32_t di_atime; /* 16: Last access time. */ > > + u_int32_t di_atime; /* 16: Last access time. */ > > int32_t di_atimensec; /* 20: Last access time. */ > > - int32_t di_mtime; /* 24: Last modified time. */ > > + u_int32_t di_mtime; /* 24: Last modified time. */ > > int32_t di_mtimensec; /* 28: Last modified time. */ > > - int32_t di_ctime; /* 32: Last inode change time. */ > > + u_int32_t di_ctime; /* 32: Last inode change time. */ > > int32_t di_ctimensec; /* 36: Last inode change time. */ > > int32_t di_db[NDADDR]; /* 40: Direct disk blocks. */ > > int32_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */ > > >