Subject: Re: nfs between -current and netbsd-3
To: None <tech-net@netbsd.org>
From: Christos Zoulas <christos@astron.com>
List: tech-net
Date: 09/12/2005 15:29:21
In article <20050912134746.GA8322@spathi.chuq.com>,
Chuck Silvers <chuq@chuq.com> wrote:
>-=-=-=-=-=-
>
>hi,
>
>this is because netbsd's file systems do not always change a file's mtime
>when that file's contents are modified. the mtime is updated using the
>global variable "time" rather via than some more precise mechanism like
>microtime(). if a file is modified twice in the same clock tick, the
>second update to the file's mtime will be set it to the same value as
>the first, so NFS clients cannot use the mtime to reliably detect that
>a file's contents have changed.
>
>as part of the NFS cache coherency improvements that yamt and I did earlier
>this year, he added some code to our NFS client to detect this deficiency
>in an NFS server and work around the problem, and the message is just saying
>that the problem has been detected and the work-around activated.
>
>I had intended to change netbsd's file systems to use microtime() instead
>of "time" for updating file mtimes, but I got busy and didn't get back to it.
>looking at it again yesterday, I realized that it's not as complicated as
>I thought it was. the attached patch is sort of the right idea, except that
>it would be good to avoid calling microtime() if we aren't going to use
>the result (ie. if none of the timestamp-update flags is set).
>
>-Chuck
How about this?
Index: fs/msdosfs/denode.h
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/denode.h,v
retrieving revision 1.7
diff -u -u -r1.7 denode.h
--- fs/msdosfs/denode.h 29 Aug 2005 23:57:35 -0000 1.7
+++ fs/msdosfs/denode.h 12 Sep 2005 15:23:18 -0000
@@ -225,20 +225,8 @@
#define DETOV(de) ((de)->de_vnode)
#define DETIMES(dep, acc, mod, cre, gmtoff) \
- if ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) { \
- (dep)->de_flag |= DE_MODIFIED; \
- if ((dep)->de_flag & DE_UPDATE) { \
- unix2dostime((mod), gmtoff, &(dep)->de_MDate, &(dep)->de_MTime, NULL); \
- (dep)->de_Attributes |= ATTR_ARCHIVE; \
- } \
- if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \
- if ((dep)->de_flag & DE_ACCESS) \
- unix2dostime((acc), gmtoff, &(dep)->de_ADate, NULL, NULL); \
- if ((dep)->de_flag & DE_CREATE) \
- unix2dostime((cre), gmtoff, &(dep)->de_CDate, &(dep)->de_CTime, &(dep)->de_CHun); \
- } \
- (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
- }
+ while ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) \
+ msdosfs_detimes(dep, acc, mod, cre, gmtoff)
/*
* This overlays the fid structure (see mount.h)
@@ -313,4 +301,6 @@
int findwin95(struct denode *);
int msdosfs_gop_alloc(struct vnode *, off_t, off_t, int, struct ucred *);
void msdosfs_gop_markupdate(struct vnode *, int);
+void msdosfs_detimes(struct denode *, const struct timespec *,
+ const struct timespec *, const struct timespec *, int);
#endif /* _KERNEL */
Index: fs/msdosfs/direntry.h
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/direntry.h,v
retrieving revision 1.3
diff -u -u -r1.3 direntry.h
--- fs/msdosfs/direntry.h 29 Aug 2005 23:57:35 -0000 1.3
+++ fs/msdosfs/direntry.h 12 Sep 2005 15:23:18 -0000
@@ -119,7 +119,7 @@
#define DD_YEAR_SHIFT 9
#ifdef _KERNEL
-void unix2dostime(struct timespec *tsp, int gmtoff, u_int16_t *ddp,
+void unix2dostime(const struct timespec *tsp, int gmtoff, u_int16_t *ddp,
u_int16_t *dtp, u_int8_t *dhp);
void dos2unixtime(u_int dd, u_int dt, u_int dh, int gmtoff,
struct timespec *tsp);
Index: fs/msdosfs/msdosfs_conv.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_conv.c,v
retrieving revision 1.3
diff -u -u -r1.3 msdosfs_conv.c
--- fs/msdosfs/msdosfs_conv.c 26 Feb 2005 22:58:55 -0000 1.3
+++ fs/msdosfs/msdosfs_conv.c 12 Sep 2005 15:23:18 -0000
@@ -97,7 +97,7 @@
*/
void
unix2dostime(tsp, gmtoff, ddp, dtp, dhp)
- struct timespec *tsp;
+ const struct timespec *tsp;
int gmtoff;
u_int16_t *ddp;
u_int16_t *dtp;
Index: fs/msdosfs/msdosfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vnops.c,v
retrieving revision 1.19
diff -u -u -r1.19 msdosfs_vnops.c
--- fs/msdosfs/msdosfs_vnops.c 10 Sep 2005 18:35:56 -0000 1.19
+++ fs/msdosfs/msdosfs_vnops.c 12 Sep 2005 15:23:18 -0000
@@ -116,7 +116,6 @@
struct denode *dep;
struct denode *pdep = VTODE(ap->a_dvp);
int error;
- struct timespec ts;
#ifdef MSDOSFS_DEBUG
printf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap);
@@ -155,8 +154,7 @@
ndirent.de_devvp = pdep->de_devvp;
ndirent.de_pmp = pdep->de_pmp;
ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- DETIMES(&ndirent, &ts, &ts, &ts, pdep->de_pmp->pm_gmtoff);
+ DETIMES(&ndirent, NULL, NULL, NULL, pdep->de_pmp->pm_gmtoff);
if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)
goto bad;
if ((cnp->cn_flags & SAVESTART) == 0)
@@ -216,12 +214,10 @@
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct denode *dep = VTODE(vp);
- struct timespec ts;
simple_lock(&vp->v_interlock);
if (vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- DETIMES(dep, &ts, &ts, &ts, dep->de_pmp->pm_gmtoff);
+ DETIMES(dep, NULL, NULL, NULL, dep->de_pmp->pm_gmtoff);
}
simple_unlock(&vp->v_interlock);
return (0);
@@ -282,12 +278,10 @@
struct msdosfsmount *pmp = dep->de_pmp;
struct vattr *vap = ap->a_vap;
mode_t mode;
- struct timespec ts;
u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);
ino_t fileid;
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- DETIMES(dep, &ts, &ts, &ts, pmp->pm_gmtoff);
+ DETIMES(dep, NULL, NULL, NULL, pmp->pm_gmtoff);
vap->va_fsid = dep->de_dev;
/*
* The following computation of the fileid must be the same as that
@@ -708,15 +702,11 @@
struct direntry *dirp;
struct denode *dep;
int error;
- struct timespec ts;
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (0);
dep = VTODE(ap->a_vp);
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- DETIMES(dep,
- ap->a_access ? ap->a_access : &ts,
- ap->a_modify ? ap->a_modify : &ts, &ts, dep->de_pmp->pm_gmtoff);
+ DETIMES(dep, ap->a_access, ap->a_modify, NULL, dep->de_pmp->pm_gmtoff);
if ((dep->de_flag & DE_MODIFIED) == 0)
return (0);
dep->de_flag &= ~DE_MODIFIED;
@@ -1216,7 +1206,6 @@
struct direntry *denp;
struct msdosfsmount *pmp = pdep->de_pmp;
struct buf *bp;
- struct timespec ts;
int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC;
/*
@@ -1240,8 +1229,7 @@
memset(&ndirent, 0, sizeof(ndirent));
ndirent.de_pmp = pmp;
ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- DETIMES(&ndirent, &ts, &ts, &ts, pmp->pm_gmtoff);
+ DETIMES(&ndirent, NULL, NULL, NULL, pmp->pm_gmtoff);
/*
* Now fill the cluster with the "." and ".." entries. And write
@@ -1852,6 +1840,37 @@
/* NOTREACHED */
}
+void
+msdosfs_detimes(struct denode *dep, const struct timespec *acc,
+ const struct timespec *mod, const struct timespec *cre, int gmtoff)
+{
+ struct timespec *ts = NULL, tsb;
+
+ KASSERT(dep->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS));
+ dep->de_flag |= DE_MODIFIED;
+ if (dep->de_flag & DE_UPDATE) {
+ if (mod == NULL)
+ mod = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ unix2dostime(mod, gmtoff, &dep->de_MDate, &dep->de_MTime, NULL);
+ dep->de_Attributes |= ATTR_ARCHIVE;
+ }
+ if ((dep->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0) {
+ if (dep->de_flag & DE_ACCESS) {
+ if (acc == NULL)
+ acc = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ unix2dostime(acc, gmtoff, &dep->de_ADate, NULL, NULL);
+ }
+ if (dep->de_flag & DE_CREATE) {
+ if (cre == NULL)
+ cre = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ unix2dostime(cre, gmtoff, &dep->de_CDate,
+ &dep->de_CTime, &dep->de_CHun);
+ }
+ }
+
+ dep->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS);
+}
+
/* Global vfs data structures for msdosfs */
int (**msdosfs_vnodeop_p)(void *);
const struct vnodeopv_entry_desc msdosfs_vnodeop_entries[] = {
Index: ufs/ext2fs/ext2fs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_extern.h,v
retrieving revision 1.26
diff -u -u -r1.26 ext2fs_extern.h
--- ufs/ext2fs/ext2fs_extern.h 30 Aug 2005 22:01:12 -0000 1.26
+++ ufs/ext2fs/ext2fs_extern.h 12 Sep 2005 15:23:18 -0000
@@ -129,6 +129,8 @@
/* ext2fs_subr.c */
int ext2fs_blkatoff(void *);
void ext2fs_fragacct(struct m_ext2fs *, int, int32_t[], int);
+void ext2fs_itimes(struct inode *, const struct timespec *,
+ const struct timespec *, const struct timespec *);
#ifdef DIAGNOSTIC
void ext2fs_checkoverlap(struct buf *, struct inode *);
#endif
Index: ufs/ext2fs/ext2fs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_inode.c,v
retrieving revision 1.47
diff -u -u -r1.47 ext2fs_inode.c
--- ufs/ext2fs/ext2fs_inode.c 30 Aug 2005 22:01:12 -0000 1.47
+++ ufs/ext2fs/ext2fs_inode.c 12 Sep 2005 15:23:18 -0000
@@ -206,17 +206,13 @@
struct buf *bp;
struct inode *ip;
int error;
- struct timespec ts;
caddr_t cp;
int flags;
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (0);
ip = VTOI(ap->a_vp);
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- EXT2FS_ITIMES(ip,
- ap->a_access ? ap->a_access : &ts,
- ap->a_modify ? ap->a_modify : &ts, &ts);
+ EXT2FS_ITIMES(ip, ap->a_access, ap->a_modify, NULL);
if (ap->a_flags & UPDATE_CLOSE)
flags = ip->i_flag & (IN_MODIFIED | IN_ACCESSED);
else
Index: ufs/ext2fs/ext2fs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_subr.c,v
retrieving revision 1.14
diff -u -u -r1.14 ext2fs_subr.c
--- ufs/ext2fs/ext2fs_subr.c 30 Aug 2005 22:01:12 -0000 1.14
+++ ufs/ext2fs/ext2fs_subr.c 12 Sep 2005 15:23:18 -0000
@@ -111,6 +111,35 @@
return (0);
}
+void
+ext2fs_itimes(struct inode *ip, const struct timespec *acc,
+ const struct timespec *mod, const struct timespec *cre)
+{
+ struct timespec *ts = NULL, tsb;
+
+ if (ip->i_flag & IN_ACCESS) {
+ if (acc == NULL)
+ acc = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_e2fs_atime = acc->tv_sec;
+ }
+ if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) {
+ if (mod == NULL)
+ mod = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_e2fs_mtime = mod->tv_sec;
+ ip->i_modrev++;
+ }
+ if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) {
+ if (cre == NULL)
+ cre = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_e2fs_ctime = cre->tv_sec;
+ }
+ if (ip->i_flag & (IN_ACCESS | IN_MODIFY))
+ ip->i_flag |= IN_ACCESSED;
+ if (ip->i_flag & (IN_UPDATE | IN_CHANGE))
+ ip->i_flag |= IN_MODIFIED;
+ ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY);
+}
+
#ifdef DIAGNOSTIC
void
ext2fs_checkoverlap(struct buf *bp, struct inode *ip)
Index: ufs/ext2fs/ext2fs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v
retrieving revision 1.61
diff -u -u -r1.61 ext2fs_vnops.c
--- ufs/ext2fs/ext2fs_vnops.c 30 Aug 2005 22:01:12 -0000 1.61
+++ ufs/ext2fs/ext2fs_vnops.c 12 Sep 2005 15:23:18 -0000
@@ -276,10 +276,8 @@
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
struct vattr *vap = ap->a_vap;
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- EXT2FS_ITIMES(ip, &ts, &ts, &ts);
+ EXT2FS_ITIMES(ip, NULL, NULL, NULL);
/*
* Copy from inode table
*/
Index: ufs/ffs/ffs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_extern.h,v
retrieving revision 1.45
diff -u -u -r1.45 ffs_extern.h
--- ufs/ffs/ffs_extern.h 9 Sep 2005 15:00:39 -0000 1.45
+++ ufs/ffs/ffs_extern.h 12 Sep 2005 15:23:18 -0000
@@ -99,7 +99,9 @@
void ffs_sb_swap(struct fs*, struct fs *);
void ffs_dinode1_swap(struct ufs1_dinode *, struct ufs1_dinode *);
void ffs_dinode2_swap(struct ufs2_dinode *, struct ufs2_dinode *);
+struct csum;
void ffs_csum_swap(struct csum *, struct csum *, int);
+struct csum_total;
void ffs_csumtotal_swap(struct csum_total *, struct csum_total *);
void ffs_cg_swap(struct cg *, struct cg *, struct fs *);
@@ -119,6 +121,8 @@
int ffs_isfreeblock(struct fs *, u_char *, int32_t);
void ffs_clrblock(struct fs *, u_char *, int32_t);
void ffs_setblock(struct fs *, u_char *, int32_t);
+void ffs_itimes(struct inode *, const struct timespec *,
+ const struct timespec *, const struct timespec *);
/* ffs_vfsops.c */
void ffs_init(void);
@@ -142,6 +146,7 @@
int ffs_cgupdate(struct ufsmount *, int);
/* ffs_appleufs.c */
+struct appleufslabel;
u_int16_t ffs_appleufs_cksum(const struct appleufslabel *);
int ffs_appleufs_validate(const char*, const struct appleufslabel *,
struct appleufslabel *);
Index: ufs/ffs/ffs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_inode.c,v
retrieving revision 1.72
diff -u -u -r1.72 ffs_inode.c
--- ufs/ffs/ffs_inode.c 15 Jul 2005 05:01:16 -0000 1.72
+++ ufs/ffs/ffs_inode.c 12 Sep 2005 15:23:18 -0000
@@ -87,17 +87,13 @@
struct buf *bp;
struct inode *ip;
int error;
- struct timespec ts;
caddr_t cp;
int waitfor, flags;
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (0);
ip = VTOI(ap->a_vp);
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- FFS_ITIMES(ip,
- ap->a_access ? ap->a_access : &ts,
- ap->a_modify ? ap->a_modify : &ts, &ts);
+ FFS_ITIMES(ip, ap->a_access, ap->a_modify, NULL);
if (ap->a_flags & UPDATE_CLOSE)
flags = ip->i_flag & (IN_MODIFIED | IN_ACCESSED);
else
Index: ufs/ffs/ffs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_subr.c,v
retrieving revision 1.35
diff -u -u -r1.35 ffs_subr.c
--- ufs/ffs/ffs_subr.c 30 Aug 2005 22:01:12 -0000 1.35
+++ ufs/ffs/ffs_subr.c 12 Sep 2005 15:23:18 -0000
@@ -326,3 +326,36 @@
(int)fs->fs_fragshift);
}
}
+
+void
+ffs_itimes(struct inode *ip, const struct timespec *acc,
+ const struct timespec *mod, const struct timespec *cre)
+{
+ struct timespec *ts = NULL, tsb;
+ if (ip->i_flag & IN_ACCESS) {
+ if (acc == NULL)
+ acc = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ DIP_ASSIGN(ip, atime, acc->tv_sec);
+ DIP_ASSIGN(ip, atimensec, acc->tv_nsec);
+ }
+ if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) {
+ if ((ip->i_flags & SF_SNAPSHOT) == 0) {
+ if (mod == NULL)
+ mod = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ DIP_ASSIGN(ip, mtime, mod->tv_sec);
+ DIP_ASSIGN(ip, mtimensec, mod->tv_nsec);
+ }
+ ip->i_modrev++;
+ }
+ if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) {
+ if (cre == NULL)
+ cre = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ DIP_ASSIGN(ip, ctime, cre->tv_sec);
+ DIP_ASSIGN(ip, ctimensec, cre->tv_nsec);
+ }
+ if (ip->i_flag & (IN_ACCESS | IN_MODIFY))
+ ip->i_flag |= IN_ACCESSED;
+ if (ip->i_flag & (IN_UPDATE | IN_CHANGE))
+ ip->i_flag |= IN_MODIFIED;
+ ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY);
+}
Index: ufs/lfs/lfs.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs.h,v
retrieving revision 1.92
diff -u -u -r1.92 lfs.h
--- ufs/lfs/lfs.h 23 Aug 2005 08:05:13 -0000 1.92
+++ ufs/lfs/lfs.h 12 Sep 2005 15:23:18 -0000
@@ -325,44 +325,9 @@
simple_unlock(&(ip)->i_lfs->lfs_interlock); \
} while (0)
-#define LFS_ITIMES(ip, acc, mod, cre) do { \
- struct lfs *_fs = (ip)->i_lfs; \
- \
- if ((ip)->i_flag & IN_ACCESS) { \
- (ip)->i_ffs1_atime = (acc)->tv_sec; \
- (ip)->i_ffs1_atimensec = (acc)->tv_nsec; \
- if ((ip)->i_lfs->lfs_version > 1) { \
- struct buf *_ibp; \
- IFILE *_ifp; \
- \
- LFS_IENTRY(_ifp, ip->i_lfs, ip->i_number, _ibp); \
- _ifp->if_atime_sec = (acc)->tv_sec; \
- _ifp->if_atime_nsec = (acc)->tv_nsec; \
- LFS_BWRITE_LOG(_ibp); \
- simple_lock(&_fs->lfs_interlock); \
- _fs->lfs_flags |= LFS_IFDIRTY; \
- simple_unlock(&_fs->lfs_interlock); \
- } else { \
- LFS_SET_UINO(ip, IN_ACCESSED); \
- } \
- } \
- if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFY)) { \
- if ((ip)->i_flag & (IN_UPDATE | IN_MODIFY)) { \
- (ip)->i_ffs1_mtime = (mod)->tv_sec; \
- (ip)->i_ffs1_mtimensec = (mod)->tv_nsec; \
- (ip)->i_modrev++; \
- } \
- if ((ip)->i_flag & (IN_CHANGE | IN_MODIFY)) { \
- (ip)->i_ffs1_ctime = (cre)->tv_sec; \
- (ip)->i_ffs1_ctimensec = (cre)->tv_nsec; \
- } \
- if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE)) \
- LFS_SET_UINO(ip, IN_MODIFIED); \
- if ((ip)->i_flag & IN_MODIFY) \
- LFS_SET_UINO(ip, IN_ACCESSED); \
- } \
- (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY);\
-} while (0)
+#define LFS_ITIMES(ip, acc, mod, cre) \
+ while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
+ lfs_itimes(ip, acc, mod, cre)
/*
* "struct vnode" associated definitions
Index: ufs/lfs/lfs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_extern.h,v
retrieving revision 1.69
diff -u -u -r1.69 lfs_extern.h
--- ufs/lfs/lfs_extern.h 28 Jun 2005 09:30:38 -0000 1.69
+++ ufs/lfs/lfs_extern.h 12 Sep 2005 15:23:18 -0000
@@ -236,8 +236,8 @@
/* lfs_vnops.c */
void lfs_mark_vnode(struct vnode *);
void lfs_unmark_vnode(struct vnode *);
-void lfs_itimes(struct inode *, struct timespec *, struct timespec *,
- struct timespec *);
+void lfs_itimes(struct inode *, const struct timespec *,
+ const struct timespec *, const struct timespec *);
int lfs_gop_alloc(struct vnode *, off_t, off_t, int, struct ucred *);
void lfs_gop_size(struct vnode *, off_t, off_t *, int);
int lfs_putpages_ext(void *, int);
Index: ufs/lfs/lfs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_inode.c,v
retrieving revision 1.96
diff -u -u -r1.96 lfs_inode.c
--- ufs/lfs/lfs_inode.c 29 May 2005 21:25:24 -0000 1.96
+++ ufs/lfs/lfs_inode.c 12 Sep 2005 15:23:18 -0000
@@ -138,7 +138,6 @@
} */ *ap = v;
struct inode *ip;
struct vnode *vp = ap->a_vp;
- struct timespec ts;
struct lfs *fs = VFSTOUFS(vp->v_mount)->um_lfs;
int s;
int flags;
@@ -165,10 +164,7 @@
}
simple_unlock(&vp->v_interlock);
splx(s);
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- LFS_ITIMES(ip,
- ap->a_access ? ap->a_access : &ts,
- ap->a_modify ? ap->a_modify : &ts, &ts);
+ LFS_ITIMES(ip, ap->a_access, ap->a_modify, NULL);
if (ap->a_flags & UPDATE_CLOSE)
flags = ip->i_flag & (IN_MODIFIED | IN_ACCESSED | IN_CLEANING);
else
Index: ufs/lfs/lfs_segment.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_segment.c,v
retrieving revision 1.165
diff -u -u -r1.165 lfs_segment.c
--- ufs/lfs/lfs_segment.c 19 Aug 2005 02:04:09 -0000 1.165
+++ ufs/lfs/lfs_segment.c 12 Sep 2005 15:23:18 -0000
@@ -833,7 +833,6 @@
ino_t ino;
int error, i, ndx, fsb = 0;
int redo_ifile = 0;
- struct timespec ts;
int gotblk = 0;
ASSERT_SEGLOCK(fs);
@@ -872,10 +871,9 @@
}
/* Update the inode times and copy the inode onto the inode page. */
- TIMEVAL_TO_TIMESPEC(&time, &ts);
/* XXX kludge --- don't redirty the ifile just to put times on it */
if (ip->i_number != LFS_IFILE_INUM)
- LFS_ITIMES(ip, &ts, &ts, &ts);
+ LFS_ITIMES(ip, NULL, NULL, NULL);
/*
* If this is the Ifile, and we've already written the Ifile in this
Index: ufs/lfs/lfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v
retrieving revision 1.153
diff -u -u -r1.153 lfs_vnops.c
--- ufs/lfs/lfs_vnops.c 19 Aug 2005 02:04:09 -0000 1.153
+++ ufs/lfs/lfs_vnops.c 12 Sep 2005 15:23:19 -0000
@@ -268,13 +268,55 @@
static int check_dirty(struct lfs *, struct vnode *, off_t, off_t, off_t, int, int);
-/*
- * A function version of LFS_ITIMES, for the UFS functions which call ITIMES
- */
void
-lfs_itimes(struct inode *ip, struct timespec *acc, struct timespec *mod, struct timespec *cre)
+lfs_itimes(struct inode *ip, const struct timespec *acc,
+ const struct timespec *mod, const struct timespec *cre)
{
- LFS_ITIMES(ip, acc, mod, cre);
+ struct timespec *ts = NULL, tsb;
+
+ KASSERT(ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY));
+
+ if (ip->i_flag & IN_ACCESS) {
+ if (acc == NULL)
+ acc = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_ffs1_atime = acc->tv_sec;
+ ip->i_ffs1_atimensec = acc->tv_nsec;
+ if (ip->i_lfs->lfs_version > 1) {
+ struct lfs *fs = ip->i_lfs;
+ struct buf *ibp;
+ IFILE *ifp;
+
+ LFS_IENTRY(ifp, ip->i_lfs, ip->i_number, ibp);
+ ifp->if_atime_sec = acc->tv_sec;
+ ifp->if_atime_nsec = acc->tv_nsec;
+ LFS_BWRITE_LOG(ibp);
+ simple_lock(&fs->lfs_interlock);
+ fs->lfs_flags |= LFS_IFDIRTY;
+ simple_unlock(&fs->lfs_interlock);
+ } else {
+ LFS_SET_UINO(ip, IN_ACCESSED);
+ }
+ }
+ if (ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFY)) {
+ if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) {
+ if (mod == NULL)
+ mod = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_ffs1_mtime = mod->tv_sec;
+ ip->i_ffs1_mtimensec = mod->tv_nsec;
+ ip->i_modrev++;
+ }
+ if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) {
+ if (cre == NULL)
+ cre = ts == NULL ? (ts = nanotime(&tsb)) : ts;
+ ip->i_ffs1_ctime = cre->tv_sec;
+ ip->i_ffs1_ctimensec = cre->tv_nsec;
+ }
+ if (ip->i_flag & (IN_CHANGE | IN_UPDATE))
+ LFS_SET_UINO(ip, IN_MODIFIED);
+ if (ip->i_flag & IN_MODIFY)
+ LFS_SET_UINO(ip, IN_ACCESSED);
+ }
+ ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY);
}
#define LFS_READWRITE
@@ -954,15 +996,13 @@
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
- struct timespec ts;
if (vp == ip->i_lfs->lfs_ivnode &&
vp->v_mount->mnt_iflag & IMNT_UNMOUNT)
return 0;
if (vp->v_usecount > 1 && vp != ip->i_lfs->lfs_ivnode) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- LFS_ITIMES(ip, &ts, &ts, &ts);
+ LFS_ITIMES(ip, NULL, NULL, NULL);
}
return (0);
}
@@ -983,13 +1023,11 @@
} */ *ap = v;
struct vnode *vp;
struct inode *ip;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
if (vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- LFS_ITIMES(ip, &ts, &ts, &ts);
+ LFS_ITIMES(ip, NULL, NULL, NULL);
}
return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
}
@@ -1010,13 +1048,11 @@
} */ *ap = v;
struct vnode *vp;
struct inode *ip;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
if (ap->a_vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- LFS_ITIMES(ip, &ts, &ts, &ts);
+ LFS_ITIMES(ip, NULL, NULL, NULL);
}
return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
}
Index: ufs/ufs/inode.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/inode.h,v
retrieving revision 1.42
diff -u -u -r1.42 inode.h
--- ufs/ufs/inode.h 19 Aug 2005 02:04:09 -0000 1.42
+++ ufs/ufs/inode.h 12 Sep 2005 15:23:19 -0000
@@ -266,57 +266,19 @@
#define VTOI(vp) ((struct inode *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
-#define FFS_ITIMES(ip, acc, mod, cre) { \
- if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) {\
- if ((ip)->i_flag & IN_ACCESS) { \
- DIP_ASSIGN(ip, atime, (acc)->tv_sec); \
- DIP_ASSIGN(ip, atimensec, (acc)->tv_nsec); \
- } \
- if ((ip)->i_flag & (IN_UPDATE | IN_MODIFY)) { \
- if (((ip)->i_flags & SF_SNAPSHOT) == 0) { \
- DIP_ASSIGN(ip, mtime, (mod)->tv_sec); \
- DIP_ASSIGN(ip, mtimensec, (mod)->tv_nsec); \
- } \
- (ip)->i_modrev++; \
- } \
- if ((ip)->i_flag & (IN_CHANGE | IN_MODIFY)) { \
- DIP_ASSIGN(ip, ctime, (cre)->tv_sec); \
- DIP_ASSIGN(ip, ctimensec, (cre)->tv_nsec); \
- } \
- if ((ip)->i_flag & (IN_ACCESS | IN_MODIFY)) \
- ip->i_flag |= IN_ACCESSED; \
- if ((ip)->i_flag & (IN_UPDATE | IN_CHANGE)) \
- ip->i_flag |= IN_MODIFIED; \
- (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY); \
- } \
-}
+#define FFS_ITIMES(ip, acc, mod, cre) \
+ while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
+ ffs_itimes(ip, acc, mod, cre)
-#define EXT2FS_ITIMES(ip, acc, mod, cre) { \
- if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) {\
- if ((ip)->i_flag & IN_ACCESS) { \
- (ip)->i_e2fs_atime = (acc)->tv_sec; \
- } \
- if ((ip)->i_flag & (IN_UPDATE | IN_MODIFY)) { \
- (ip)->i_e2fs_mtime = (mod)->tv_sec; \
- (ip)->i_modrev++; \
- } \
- if ((ip)->i_flag & (IN_CHANGE | IN_MODIFY)) { \
- (ip)->i_e2fs_ctime = (cre)->tv_sec; \
- } \
- if ((ip)->i_flag & (IN_ACCESS | IN_MODIFY)) \
- (ip)->i_flag |= IN_ACCESSED; \
- if ((ip)->i_flag & (IN_UPDATE | IN_CHANGE)) \
- (ip)->i_flag |= IN_MODIFIED; \
- (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY); \
- } \
-}
+#define EXT2FS_ITIMES(ip, acc, mod, cre) \
+ while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
+ ext2fs_itimes(ip, acc, mod, cre)
-#define ITIMES(ip, acc, mod, cre) { \
- if (IS_EXT2_VNODE((ip)->i_vnode)) \
- EXT2FS_ITIMES(ip, acc, mod, cre) \
- else \
- FFS_ITIMES(ip, acc, mod, cre) \
-}
+#define ITIMES(ip, acc, mod, cre) \
+ while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
+ IS_EXT2_VNODE((ip)->i_vnode) ? \
+ ext2fs_itimes(ip, acc, mod, cre) : \
+ ffs_itimes(ip, acc, mod, cre)
/* Determine if soft dependencies are being done */
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
Index: ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.132
diff -u -u -r1.132 ufs_vnops.c
--- ufs/ufs/ufs_vnops.c 23 Aug 2005 12:27:47 -0000 1.132
+++ ufs/ufs/ufs_vnops.c 12 Sep 2005 15:23:19 -0000
@@ -73,6 +73,7 @@
#include <ufs/ufs/dirhash.h>
#endif
#include <ufs/ext2fs/ext2fs_extern.h>
+#include <ufs/ffs/ffs_extern.h>
#include <ufs/lfs/lfs_extern.h>
#include <uvm/uvm.h>
@@ -214,15 +215,12 @@
} */ *ap = v;
struct vnode *vp;
struct inode *ip;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
simple_lock(&vp->v_interlock);
- if (vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- ITIMES(ip, &ts, &ts, &ts);
- }
+ if (vp->v_usecount > 1)
+ ITIMES(ip, NULL, NULL, NULL);
simple_unlock(&vp->v_interlock);
return (0);
}
@@ -295,13 +293,11 @@
struct vnode *vp;
struct inode *ip;
struct vattr *vap;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
vap = ap->a_vap;
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- ITIMES(ip, &ts, &ts, &ts);
+ ITIMES(ip, NULL, NULL, NULL);
/*
* Copy from inode table
@@ -1836,15 +1832,12 @@
} */ *ap = v;
struct vnode *vp;
struct inode *ip;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
simple_lock(&vp->v_interlock);
- if (vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- ITIMES(ip, &ts, &ts, &ts);
- }
+ if (vp->v_usecount > 1)
+ ITIMES(ip, NULL, NULL, NULL);
simple_unlock(&vp->v_interlock);
return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
}
@@ -1905,15 +1898,12 @@
} */ *ap = v;
struct vnode *vp;
struct inode *ip;
- struct timespec ts;
vp = ap->a_vp;
ip = VTOI(vp);
simple_lock(&vp->v_interlock);
- if (ap->a_vp->v_usecount > 1) {
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- ITIMES(ip, &ts, &ts, &ts);
- }
+ if (ap->a_vp->v_usecount > 1)
+ ITIMES(ip, NULL, NULL, NULL);
simple_unlock(&vp->v_interlock);
return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
}
Index: kern/kern_clock.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_clock.c,v
retrieving revision 1.94
diff -u -u -r1.94 kern_clock.c
--- kern/kern_clock.c 2 Mar 2005 11:05:34 -0000 1.94
+++ kern/kern_clock.c 12 Sep 2005 15:23:19 -0000
@@ -1431,3 +1431,16 @@
}
#endif /* PPS_SYNC */
#endif /* NTP */
+
+/*
+ * XXX: Until all md code has it.
+ */
+struct timespec *
+nanotime(struct timespec *ts)
+{
+ struct timeval tv;
+
+ microtime(&tv);
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ return ts;
+}
Index: sys/time.h
===================================================================
RCS file: /cvsroot/src/sys/sys/time.h,v
retrieving revision 1.49
diff -u -u -r1.49 time.h
--- sys/time.h 23 Jul 2005 19:43:01 -0000 1.49
+++ sys/time.h 12 Sep 2005 15:23:19 -0000
@@ -212,7 +212,8 @@
int itimerfix(struct timeval *tv);
int itimerdecr(struct ptimer *, int);
void itimerfire(struct ptimer *);
-void microtime(struct timeval *tv);
+void microtime(struct timeval *);
+struct timespec *nanotime(struct timespec *);
int settime(struct timeval *);
int ratecheck(struct timeval *, const struct timeval *);
int ppsratecheck(struct timeval *, int *, int);