summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2014-01-25 23:31:14 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2014-01-25 23:31:14 +0000
commit0f625750d8460feae32186dea8a48954cfac73e4 (patch)
treed5912694801ee8816158f328e12da2dbf9bbbb83
parent2fdf77c4df090c6eff0f17e7cb6a976e47e0def0 (diff)
ufs_setattr() was assuming that the flag bits that indicate
atime/mtime/ctime need to be updated weren't already set. When they are, the code will end up treating the VNOVAL value from the VFS layer as a time_t. Port the fix from FreeBSD: the critical bit is to process the existing flag values before possibly setting them again in ufs_setattr(). This diff pulls in a larger change from FreeBSD to replace the macro ITIMES() with a function ufs_itimes() and to remove the atime and mtime arguments from ffs_update(): only ufs_setattr() used them so it makes more sense to just do the those bits directly there. tweaks and ok tedu@ matthew@
-rw-r--r--sys/ufs/ext2fs/ext2fs_extern.h5
-rw-r--r--sys/ufs/ext2fs/ext2fs_inode.c21
-rw-r--r--sys/ufs/ext2fs/ext2fs_readwrite.c4
-rw-r--r--sys/ufs/ext2fs/ext2fs_vnops.c30
-rw-r--r--sys/ufs/ffs/ffs_alloc.c4
-rw-r--r--sys/ufs/ffs/ffs_balloc.c6
-rw-r--r--sys/ufs/ffs/ffs_extern.h4
-rw-r--r--sys/ufs/ffs/ffs_inode.c42
-rw-r--r--sys/ufs/ufs/inode.h48
-rw-r--r--sys/ufs/ufs/ufs_extern.h3
-rw-r--r--sys/ufs/ufs/ufs_vnops.c90
11 files changed, 111 insertions, 146 deletions
diff --git a/sys/ufs/ext2fs/ext2fs_extern.h b/sys/ufs/ext2fs/ext2fs_extern.h
index e14bd4a3573..beac96e7fad 100644
--- a/sys/ufs/ext2fs/ext2fs_extern.h
+++ b/sys/ufs/ext2fs/ext2fs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_extern.h,v 1.32 2013/06/11 16:42:18 deraadt Exp $ */
+/* $OpenBSD: ext2fs_extern.h,v 1.33 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ext2fs_extern.h,v 1.1 1997/06/11 09:33:55 bouyer Exp $ */
/*-
@@ -79,8 +79,7 @@ int ext2fs_bmap(void *);
int ext2fs_init(struct vfsconf *);
u_int64_t ext2fs_size(struct inode *);
int ext2fs_setsize(struct inode *, u_int64_t);
-int ext2fs_update(struct inode *ip, struct timespec *atime,
- struct timespec *mtime, int waitfor);
+int ext2fs_update(struct inode *ip, int waitfor);
int ext2fs_truncate(struct inode *, off_t, int, struct ucred *);
int ext2fs_inactive(void *);
diff --git a/sys/ufs/ext2fs/ext2fs_inode.c b/sys/ufs/ext2fs/ext2fs_inode.c
index 21f3506d287..4088587ee47 100644
--- a/sys/ufs/ext2fs/ext2fs_inode.c
+++ b/sys/ufs/ext2fs/ext2fs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_inode.c,v 1.46 2013/12/12 19:00:09 tedu Exp $ */
+/* $OpenBSD: ext2fs_inode.c,v 1.47 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ext2fs_inode.c,v 1.24 2001/06/19 12:59:18 wiz Exp $ */
/*
@@ -135,7 +135,7 @@ ext2fs_inactive(void *v)
ext2fs_inode_free(ip, ip->i_number, ip->i_e2fs_mode);
}
if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
- ext2fs_update(ip, NULL, NULL, 0);
+ ext2fs_update(ip, 0);
}
out:
VOP_UNLOCK(vp, 0, p);
@@ -159,21 +159,16 @@ out:
* complete.
*/
int
-ext2fs_update(struct inode *ip, struct timespec *atime, struct timespec *mtime,
- int waitfor)
+ext2fs_update(struct inode *ip, int waitfor)
{
struct m_ext2fs *fs;
struct buf *bp;
int error;
- struct timespec ts;
caddr_t cp;
if (ITOV(ip)->v_mount->mnt_flag & MNT_RDONLY)
return (0);
- getnanotime(&ts);
- EXT2FS_ITIMES(ip,
- atime ? atime : &ts,
- mtime ? mtime : &ts);
+ EXT2FS_ITIMES(ip);
if ((ip->i_flag & IN_MODIFIED) == 0)
return (0);
ip->i_flag &= ~IN_MODIFIED;
@@ -249,12 +244,12 @@ ext2fs_truncate(struct inode *oip, off_t length, int flags, struct ucred *cred)
memset(&oip->i_e2din->e2di_shortlink, 0, ext2fs_size(oip));
(void)ext2fs_setsize(oip, 0);
oip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (ext2fs_update(oip, NULL, NULL, 1));
+ return (ext2fs_update(oip, 1));
}
if (ext2fs_size(oip) == length) {
oip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (ext2fs_update(oip, NULL, NULL, 0));
+ return (ext2fs_update(oip, 0));
}
fs = oip->i_e2fs;
osize = ext2fs_size(oip);
@@ -285,7 +280,7 @@ ext2fs_truncate(struct inode *oip, off_t length, int flags, struct ucred *cred)
else
bawrite(bp);
oip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (ext2fs_update(oip, NULL, NULL, 1));
+ return (ext2fs_update(oip, 1));
}
/*
* Shorten the size of the file. If the file is not being
@@ -343,7 +338,7 @@ ext2fs_truncate(struct inode *oip, off_t length, int flags, struct ucred *cred)
for (i = NDADDR - 1; i > lastblock; i--)
oip->i_e2fs_blocks[i] = 0;
oip->i_flag |= IN_CHANGE | IN_UPDATE;
- if ((error = ext2fs_update(oip, NULL, NULL, 1)) != 0)
+ if ((error = ext2fs_update(oip, 1)) != 0)
allerror = error;
/*
* Having written the new inode to disk, save its new configuration
diff --git a/sys/ufs/ext2fs/ext2fs_readwrite.c b/sys/ufs/ext2fs/ext2fs_readwrite.c
index 60d1dea1509..0f9b639c750 100644
--- a/sys/ufs/ext2fs/ext2fs_readwrite.c
+++ b/sys/ufs/ext2fs/ext2fs_readwrite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_readwrite.c,v 1.26 2013/09/14 02:28:03 guenther Exp $ */
+/* $OpenBSD: ext2fs_readwrite.c,v 1.27 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ext2fs_readwrite.c,v 1.16 2001/02/27 04:37:47 chs Exp $ */
/*-
@@ -273,7 +273,7 @@ ext2fs_write(void *v)
uio->uio_resid = resid;
}
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
- error = ext2fs_update(ip, NULL, NULL, 1);
+ error = ext2fs_update(ip, 1);
}
/* correct the result for writes clamped by vn_fsizechk() */
uio->uio_resid += overrun;
diff --git a/sys/ufs/ext2fs/ext2fs_vnops.c b/sys/ufs/ext2fs/ext2fs_vnops.c
index 636be0b840b..0acdfdaa6d9 100644
--- a/sys/ufs/ext2fs/ext2fs_vnops.c
+++ b/sys/ufs/ext2fs/ext2fs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_vnops.c,v 1.63 2013/12/12 19:00:09 tedu Exp $ */
+/* $OpenBSD: ext2fs_vnops.c,v 1.64 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ext2fs_vnops.c,v 1.1 1997/06/11 09:34:09 bouyer Exp $ */
/*
@@ -167,10 +167,8 @@ ext2fs_getattr(void *v)
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
struct vattr *vap = ap->a_vap;
- struct timeval tv;
- getmicrotime(&tv);
- EXT2FS_ITIMES(ip, &tv, &tv);
+ EXT2FS_ITIMES(ip);
/*
* Copy from inode table
*/
@@ -307,7 +305,12 @@ ext2fs_setattr(void *v)
(ip->i_flag & (IN_CHANGE | IN_UPDATE)))
ip->i_flag |= IN_ACCESS;
}
- error = ext2fs_update(ip, &vap->va_atime, &vap->va_mtime, 1);
+ EXT2FS_ITIMES(ip);
+ if (vap->va_mtime.tv_sec != VNOVAL)
+ ip->i_e2fs_mtime = vap->va_mtime.tv_sec;
+ if (vap->va_atime.tv_sec != VNOVAL)
+ ip->i_e2fs_atime = vap->va_atime.tv_sec;
+ error = ext2fs_update(ip, 1);
if (error)
return (error);
}
@@ -460,7 +463,7 @@ ext2fs_link(void *v)
}
ip->i_e2fs_nlink++;
ip->i_flag |= IN_CHANGE;
- error = ext2fs_update(ip, NULL, NULL, 1);
+ error = ext2fs_update(ip, 1);
if (!error)
error = ext2fs_direnter(ip, dvp, cnp);
if (error) {
@@ -633,7 +636,7 @@ abortit:
*/
ip->i_e2fs_nlink++;
ip->i_flag |= IN_CHANGE;
- if ((error = ext2fs_update(ip, NULL, NULL, 1)) != 0) {
+ if ((error = ext2fs_update(ip, 1)) != 0) {
VOP_UNLOCK(fvp, 0, p);
goto bad;
}
@@ -691,7 +694,7 @@ abortit:
}
dp->i_e2fs_nlink++;
dp->i_flag |= IN_CHANGE;
- if ((error = ext2fs_update(dp, NULL, NULL, 1)) != 0)
+ if ((error = ext2fs_update(dp, 1)) != 0)
goto bad;
}
error = ext2fs_direnter(ip, tdvp, tcnp);
@@ -699,7 +702,7 @@ abortit:
if (doingdirectory && newparent) {
dp->i_e2fs_nlink--;
dp->i_flag |= IN_CHANGE;
- (void)ext2fs_update(dp, NULL, NULL, 1);
+ (void)ext2fs_update(dp, 1);
}
goto bad;
}
@@ -917,7 +920,7 @@ ext2fs_mkdir(void *v)
ip->i_e2fs_mode = dmode;
tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
ip->i_e2fs_nlink = 2;
- error = ext2fs_update(ip, NULL, NULL, 1);
+ error = ext2fs_update(ip, 1);
/*
* Bump link count in parent directory
@@ -927,7 +930,7 @@ ext2fs_mkdir(void *v)
*/
dp->i_e2fs_nlink++;
dp->i_flag |= IN_CHANGE;
- if ((error = ext2fs_update(dp, NULL, NULL, 1)) != 0)
+ if ((error = ext2fs_update(dp, 1)) != 0)
goto bad;
/* Initialize directory with "." and ".." from static template. */
@@ -1194,7 +1197,7 @@ ext2fs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
/*
* Make sure inode goes to disk before directory entry.
*/
- if ((error = ext2fs_update(ip, NULL, NULL, 1)) != 0)
+ if ((error = ext2fs_update(ip, 1)) != 0)
goto bad;
error = ext2fs_direnter(ip, dvp, cnp);
if (error != 0)
@@ -1230,8 +1233,7 @@ ext2fs_fsync(void *v)
struct vnode *vp = ap->a_vp;
vflushbuf(vp, ap->a_waitfor == MNT_WAIT);
- return (ext2fs_update(VTOI(ap->a_vp), NULL, NULL,
- ap->a_waitfor == MNT_WAIT));
+ return (ext2fs_update(VTOI(ap->a_vp), ap->a_waitfor == MNT_WAIT));
}
/*
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 8e565a6b9c6..a37f53fc4c3 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_alloc.c,v 1.98 2013/12/12 19:00:09 tedu Exp $ */
+/* $OpenBSD: ffs_alloc.c,v 1.99 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.11 1996/05/11 18:27:09 mycroft Exp $ */
/*
@@ -741,7 +741,7 @@ ffs2_reallocblks(void *v)
} else {
ip->i_flag |= IN_CHANGE | IN_UPDATE;
if (!doasyncfree)
- ffs_update(ip, NULL, NULL, MNT_WAIT);
+ ffs_update(ip, MNT_WAIT);
}
if (ssize < len) {
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index 54befa03d4a..53847ed8938 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_balloc.c,v 1.39 2013/06/11 16:42:18 deraadt Exp $ */
+/* $OpenBSD: ffs_balloc.c,v 1.40 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ffs_balloc.c,v 1.3 1996/02/09 22:22:21 christos Exp $ */
/*
@@ -835,7 +835,7 @@ fail:
if (DOINGSOFTDEP(vp) && unwindidx == 0) {
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- ffs_update(ip, NULL, NULL, MNT_WAIT);
+ ffs_update(ip, MNT_WAIT);
}
/*
@@ -846,7 +846,7 @@ fail:
*allocib = 0;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
if (DOINGSOFTDEP(vp))
- ffs_update(ip, NULL, NULL, MNT_WAIT);
+ ffs_update(ip, MNT_WAIT);
} else {
r = bread(vp, indirs[unwindidx].in_lbn,
(int)fs->fs_bsize, &bp);
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 653c669ed14..67040d2eec6 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_extern.h,v 1.39 2013/06/11 16:42:18 deraadt Exp $ */
+/* $OpenBSD: ffs_extern.h,v 1.40 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ffs_extern.h,v 1.4 1996/02/09 22:22:22 christos Exp $ */
/*
@@ -120,7 +120,7 @@ int ffs_balloc(struct inode *, off_t, int, struct ucred *, int, struct buf **);
/* ffs_inode.c */
int ffs_init(struct vfsconf *);
-int ffs_update(struct inode *, struct timespec *, struct timespec *, int);
+int ffs_update(struct inode *, int);
int ffs_truncate(struct inode *, off_t, int, struct ucred *);
/* ffs_subr.c */
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index d41aa96bb49..80a1b1c11e9 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_inode.c,v 1.66 2013/12/12 19:00:09 tedu Exp $ */
+/* $OpenBSD: ffs_inode.c,v 1.67 2014/01/25 23:31:12 guenther Exp $ */
/* $NetBSD: ffs_inode.c,v 1.10 1996/05/11 18:27:19 mycroft Exp $ */
/*
@@ -59,52 +59,24 @@ int ffs_indirtrunc(struct inode *, daddr_t, daddr_t, daddr_t, int, long *);
* Update the access, modified, and inode change times as specified by the
* IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. The IN_MODIFIED
* flag is used to specify that the inode needs to be updated but that the
- * times have already been set. The access and modified times are taken from
- * the second and third parameters; the inode change time is always taken
- * from the current time. If waitfor is set, then wait for the disk write
- * of the inode to complete.
+ * times have already been set. If waitfor is set, then wait for
+ * the disk write of the inode to complete.
*/
int
-ffs_update(struct inode *ip, struct timespec *atime,
- struct timespec *mtime, int waitfor)
+ffs_update(struct inode *ip, int waitfor)
{
struct vnode *vp;
struct fs *fs;
struct buf *bp;
int error;
- struct timespec ts;
vp = ITOV(ip);
- if (vp->v_mount->mnt_flag & MNT_RDONLY) {
- ip->i_flag &=
- ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
- return (0);
- }
+ ufs_itimes(vp);
- if ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- waitfor != MNT_WAIT)
+ if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor != MNT_WAIT)
return (0);
- getnanotime(&ts);
-
- if (ip->i_flag & IN_ACCESS) {
- DIP_ASSIGN(ip, atime, atime ? atime->tv_sec : ts.tv_sec);
- DIP_ASSIGN(ip, atimensec, atime ? atime->tv_nsec : ts.tv_nsec);
- }
-
- if (ip->i_flag & IN_UPDATE) {
- DIP_ASSIGN(ip, mtime, mtime ? mtime->tv_sec : ts.tv_sec);
- DIP_ASSIGN(ip, mtimensec, mtime ? mtime->tv_nsec : ts.tv_nsec);
- ip->i_modrev++;
- }
-
- if (ip->i_flag & IN_CHANGE) {
- DIP_ASSIGN(ip, ctime, ts.tv_sec);
- DIP_ASSIGN(ip, ctimensec, ts.tv_nsec);
- }
-
- ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
+ ip->i_flag &= ~IN_MODIFIED;
fs = ip->i_fs;
/*
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 133fdc8068d..f35ecec31d8 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: inode.h,v 1.40 2013/06/11 16:42:19 deraadt Exp $ */
+/* $OpenBSD: inode.h,v 1.41 2014/01/25 23:31:13 guenther Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -129,8 +129,7 @@ struct inode {
struct inode_vtbl {
int (* iv_truncate)(struct inode *, off_t, int,
struct ucred *);
- int (* iv_update)(struct inode *, struct timespec *, struct timespec *,
- int waitfor);
+ int (* iv_update)(struct inode *, int waitfor);
int (* iv_inode_alloc)(struct inode *, mode_t mode,
struct ucred *, struct vnode **);
int (* iv_inode_free)(struct inode *, ufsino_t ino, mode_t mode);
@@ -144,10 +143,7 @@ struct inode_vtbl {
((ip)->i_vtbl->iv_truncate)((ip), (off), (flags), (cred))
#define UFS_UPDATE(ip, sync) \
- ((ip)->i_vtbl->iv_update)((ip), NULL, NULL, (sync))
-
-#define UFS_UPDATE2(ip, atime, mtime, sync) \
- ((ip)->i_vtbl->iv_update)((ip), (atime), (mtime), (sync))
+ ((ip)->i_vtbl->iv_update)((ip), (sync))
#define UFS_INODE_ALLOC(pip, mode, cred, vpp) \
((pip)->i_vtbl->iv_inode_alloc)((pip), (mode), (cred), (vpp))
@@ -315,44 +311,6 @@ struct indir {
#define VTOI(vp) ((struct inode *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
-#define FFS_ITIMES(ip, t1, t2) { \
- if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
- (ip)->i_flag |= IN_MODIFIED; \
- if ((ip)->i_flag & IN_ACCESS) \
- DIP_ASSIGN((ip), atime, (t1)->tv_sec); \
- if ((ip)->i_flag & IN_UPDATE) { \
- DIP_ASSIGN((ip), mtime, (t2)->tv_sec); \
- (ip)->i_modrev++; \
- } \
- if ((ip)->i_flag & IN_CHANGE) \
- DIP_ASSIGN((ip), ctime, time_second); \
- (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
- } \
-}
-
-#define EXT2FS_ITIMES(ip, t1, t2) { \
- if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
- (ip)->i_flag |= IN_MODIFIED; \
- if ((ip)->i_flag & IN_ACCESS) \
- (ip)->i_e2fs_atime = (t1)->tv_sec; \
- if ((ip)->i_flag & IN_UPDATE) { \
- (ip)->i_e2fs_mtime = (t2)->tv_sec; \
- (ip)->i_modrev++; \
- } \
- if ((ip)->i_flag & IN_CHANGE) \
- (ip)->i_e2fs_ctime = time_second; \
- (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
- } \
-}
-
-#define ITIMES(ip, t1, t2) { \
- if (IS_EXT2_VNODE((ip)->i_vnode)) { \
- EXT2FS_ITIMES(ip, t1, t2); \
- } else { \
- FFS_ITIMES(ip, t1, t2); \
- } \
-}
-
/* Determine if soft dependencies are being done */
#ifdef FFS_SOFTUPDATES
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index ecd41a55f80..be7ed8575da 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_extern.h,v 1.34 2013/06/11 16:42:19 deraadt Exp $ */
+/* $OpenBSD: ufs_extern.h,v 1.35 2014/01/25 23:31:13 guenther Exp $ */
/* $NetBSD: ufs_extern.h,v 1.5 1996/02/09 22:36:03 christos Exp $ */
/*-
@@ -131,6 +131,7 @@ int ufs_check_export(struct mount *, struct mbuf *, int *,
/* ufs_vnops.c */
int ufs_vinit(struct mount *, struct vops *, struct vops *, struct vnode **);
+void ufs_itimes(struct vnode *);
int ufs_makeinode(int, struct vnode *, struct vnode **,
struct componentname *);
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 942cabe1ab0..daf7b6ab9aa 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_vnops.c,v 1.111 2013/12/12 19:00:10 tedu Exp $ */
+/* $OpenBSD: ufs_vnops.c,v 1.112 2014/01/25 23:31:13 guenther Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
/*
@@ -109,6 +109,51 @@ static struct odirtemplate omastertemplate = {
};
/*
+ * Update the times in the inode
+ */
+void
+ufs_itimes(struct vnode *vp)
+{
+ struct inode *ip;
+ struct timespec ts;
+
+ ip = VTOI(vp);
+ if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
+ return;
+
+ if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ goto out;
+
+#ifdef EXT2FS
+ if (IS_EXT2_VNODE(ip->i_vnode)) {
+ EXT2FS_ITIMES(ip);
+ goto out;
+ }
+#endif
+
+ ip->i_flag |= IN_MODIFIED;
+
+ getnanotime(&ts);
+ if (ip->i_flag & IN_ACCESS) {
+ DIP_ASSIGN(ip, atime, ts.tv_sec);
+ DIP_ASSIGN(ip, atimensec, ts.tv_nsec);
+ }
+ if (ip->i_flag & IN_UPDATE) {
+ DIP_ASSIGN(ip, mtime, ts.tv_sec);
+ DIP_ASSIGN(ip, mtimensec, ts.tv_nsec);
+ }
+ if (ip->i_flag & IN_CHANGE) {
+ DIP_ASSIGN(ip, ctime, ts.tv_sec);
+ DIP_ASSIGN(ip, ctimensec, ts.tv_nsec);
+ ip->i_modrev++;
+ }
+
+ out:
+ ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
+}
+
+
+/*
* Create a regular file
*/
int
@@ -198,14 +243,9 @@ ufs_close(void *v)
{
struct vop_close_args *ap = v;
struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
-
- if (vp->v_usecount > 1) {
- struct timeval tv;
- getmicrotime(&tv);
- ITIMES(ip, &tv, &tv);
- }
+ if (vp->v_usecount > 1)
+ ufs_itimes(vp);
return (0);
}
@@ -260,10 +300,9 @@ ufs_getattr(void *v)
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
struct vattr *vap = ap->a_vap;
- struct timeval tv;
- getmicrotime(&tv);
- ITIMES(ip, &tv, &tv);
+ ufs_itimes(vp);
+
/*
* Copy from inode table
*/
@@ -393,7 +432,16 @@ ufs_setattr(void *v)
(ip->i_flag & (IN_CHANGE | IN_UPDATE)))
ip->i_flag |= IN_ACCESS;
}
- error = UFS_UPDATE2(ip, &vap->va_atime, &vap->va_mtime, 0);
+ ufs_itimes(vp);
+ if (vap->va_mtime.tv_sec != VNOVAL) {
+ DIP_ASSIGN(ip, mtime, vap->va_mtime.tv_sec);
+ DIP_ASSIGN(ip, mtimensec, vap->va_mtime.tv_nsec);
+ }
+ if (vap->va_atime.tv_sec != VNOVAL) {
+ DIP_ASSIGN(ip, atime, vap->va_atime.tv_sec);
+ DIP_ASSIGN(ip, atimensec, vap->va_atime.tv_nsec);
+ }
+ error = UFS_UPDATE(ip, 0);
if (error)
return (error);
}
@@ -1641,14 +1689,9 @@ ufsspec_close(void *v)
{
struct vop_close_args *ap = v;
struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
-
- if (ap->a_vp->v_usecount > 1) {
- struct timeval tv;
- getmicrotime(&tv);
- ITIMES(ip, &tv, &tv);
- }
+ if (vp->v_usecount > 1)
+ ufs_itimes(vp);
return (spec_close(ap));
}
@@ -1693,14 +1736,9 @@ ufsfifo_close(void *v)
{
struct vop_close_args *ap = v;
struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
- if (ap->a_vp->v_usecount > 1) {
- struct timeval tv;
-
- getmicrotime(&tv);
- ITIMES(ip, &tv, &tv);
- }
+ if (vp->v_usecount > 1)
+ ufs_itimes(vp);
return (fifo_close(ap));
}
#endif /* FIFO */