summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/isofs/cd9660/cd9660_vnops.c7
-rw-r--r--sys/kern/vfs_syscalls.c35
-rw-r--r--sys/miscfs/fuse/fuse_vnops.c7
-rw-r--r--sys/msdosfs/msdosfs_vnops.c10
-rw-r--r--sys/nfs/nfs_subs.c29
-rw-r--r--sys/nfs/nfs_vnops.c17
-rw-r--r--sys/nfs/xdr_subs.h12
-rw-r--r--sys/sys/vnode.h11
-rw-r--r--sys/tmpfs/tmpfs_subr.c11
-rw-r--r--sys/tmpfs/tmpfs_vnops.c13
-rw-r--r--sys/ufs/ext2fs/ext2fs_vnops.c16
-rw-r--r--sys/ufs/ufs/ufs_vnops.c16
12 files changed, 111 insertions, 73 deletions
diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c
index 07ea2531a69..ce9d1c41cf5 100644
--- a/sys/isofs/cd9660/cd9660_vnops.c
+++ b/sys/isofs/cd9660/cd9660_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd9660_vnops.c,v 1.71 2015/03/14 03:38:50 jsg Exp $ */
+/* $OpenBSD: cd9660_vnops.c,v 1.72 2015/04/17 04:43:20 guenther Exp $ */
/* $NetBSD: cd9660_vnops.c,v 1.42 1997/10/16 23:56:57 christos Exp $ */
/*-
@@ -94,8 +94,9 @@ cd9660_setattr(void *v)
struct vattr *vap = ap->a_vap;
if (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
- vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)
+ vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_nsec != VNOVAL ||
+ vap->va_mtime.tv_nsec != VNOVAL || vap->va_mode != (mode_t)VNOVAL ||
+ (vap->va_vaflags & VA_UTIMES_CHANGE))
return (EROFS);
if (vap->va_size != VNOVAL) {
switch (vp->v_type) {
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 99d45dafdb0..7cac013b16b 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.217 2015/03/14 03:38:51 jsg Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.218 2015/04/17 04:43:20 guenther Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -2283,6 +2283,10 @@ dovutimens(struct proc *p, struct vnode *vp, struct timespec ts[2])
#endif
VATTR_NULL(&vattr);
+
+ /* make sure ctime is updated even if neither mtime nor atime is */
+ vattr.va_vaflags = VA_UTIMES_CHANGE;
+
if (ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) {
if (ts[0].tv_nsec == UTIME_NOW && ts[1].tv_nsec == UTIME_NOW)
vattr.va_vaflags |= VA_UTIMES_NULL;
@@ -2294,29 +2298,22 @@ dovutimens(struct proc *p, struct vnode *vp, struct timespec ts[2])
ts[1] = now;
}
- /*
- * XXX: Ideally the filesystem code would check tv_nsec ==
- * UTIME_OMIT instead of tv_sec == VNOVAL, but until then we
- * need to fudge tv_sec if it happens to equal VNOVAL.
- */
- if (ts[0].tv_nsec == UTIME_OMIT)
- ts[0].tv_sec = VNOVAL;
- else if (ts[0].tv_sec == VNOVAL)
- ts[0].tv_sec = VNOVAL - 1;
-
- if (ts[1].tv_nsec == UTIME_OMIT)
- ts[1].tv_sec = VNOVAL;
- else if (ts[1].tv_sec == VNOVAL)
- ts[1].tv_sec = VNOVAL - 1;
+ if (ts[0].tv_nsec != UTIME_OMIT) {
+ if (ts[0].tv_nsec < 0 || ts[0].tv_nsec >= 1000000000)
+ return (EINVAL);
+ vattr.va_atime = ts[0];
+ }
+ if (ts[1].tv_nsec != UTIME_OMIT) {
+ if (ts[1].tv_nsec < 0 || ts[1].tv_nsec >= 1000000000)
+ return (EINVAL);
+ vattr.va_mtime = ts[1];
+ }
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
- else {
- vattr.va_atime = ts[0];
- vattr.va_mtime = ts[1];
+ else
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
vput(vp);
return (error);
}
diff --git a/sys/miscfs/fuse/fuse_vnops.c b/sys/miscfs/fuse/fuse_vnops.c
index f6807648338..8ab7140ad50 100644
--- a/sys/miscfs/fuse/fuse_vnops.c
+++ b/sys/miscfs/fuse/fuse_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.23 2015/02/19 10:22:20 tedu Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.24 2015/04/17 04:43:21 guenther Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -478,7 +478,7 @@ fusefs_setattr(void *v)
io->fi_flags |= FUSE_FATTR_SIZE;
}
- if (vap->va_atime.tv_sec != VNOVAL) {
+ if (vap->va_atime.tv_nsec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
error = EROFS;
goto out;
@@ -488,7 +488,7 @@ fusefs_setattr(void *v)
io->fi_flags |= FUSE_FATTR_ATIME;
}
- if (vap->va_mtime.tv_sec != VNOVAL) {
+ if (vap->va_mtime.tv_nsec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
error = EROFS;
goto out;
@@ -497,6 +497,7 @@ fusefs_setattr(void *v)
fbuf->fb_vattr.va_mtime.tv_nsec = vap->va_mtime.tv_nsec;
io->fi_flags |= FUSE_FATTR_MTIME;
}
+ /* XXX should set a flag if (vap->va_vaflags & VA_UTIMES_CHANGE) */
if (vap->va_mode != (mode_t)VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
index 3f1646010bf..723f1109374 100644
--- a/sys/msdosfs/msdosfs_vnops.c
+++ b/sys/msdosfs/msdosfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_vnops.c,v 1.99 2015/03/14 03:38:51 jsg Exp $ */
+/* $OpenBSD: msdosfs_vnops.c,v 1.100 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.63 1997/10/17 11:24:19 ws Exp $ */
/*-
@@ -451,7 +451,9 @@ msdosfs_setattr(void *v)
if (error)
return error;
}
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
+ if ((vap->va_vaflags & VA_UTIMES_CHANGE) ||
+ vap->va_atime.tv_nsec != VNOVAL ||
+ vap->va_mtime.tv_nsec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EINVAL);
if (cred->cr_uid != pmp->pm_uid &&
@@ -461,12 +463,12 @@ msdosfs_setattr(void *v)
return (error);
if (vp->v_type != VDIR) {
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
- vap->va_atime.tv_sec != VNOVAL) {
+ vap->va_atime.tv_nsec != VNOVAL) {
dep->de_flag &= ~DE_ACCESS;
unix2dostime(&vap->va_atime, &dep->de_ADate,
NULL, NULL);
}
- if (vap->va_mtime.tv_sec != VNOVAL) {
+ if (vap->va_mtime.tv_nsec != VNOVAL) {
dep->de_flag &= ~DE_UPDATE;
unix2dostime(&vap->va_mtime, &dep->de_MDate,
&dep->de_MTime, NULL);
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c
index ac27c29b8c0..7fb7eb5d560 100644
--- a/sys/nfs/nfs_subs.c
+++ b/sys/nfs/nfs_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_subs.c,v 1.126 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: nfs_subs.c,v 1.127 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */
/*
@@ -1751,7 +1751,7 @@ nfsm_v3attrbuild(struct mbuf **mp, struct vattr *a, int full)
tl = nfsm_build(&mb, NFSX_UNSIGNED);
*tl = nfs_false;
}
- if (a->va_atime.tv_sec != VNOVAL) {
+ if (a->va_atime.tv_nsec != VNOVAL) {
if (a->va_atime.tv_sec != time_second) {
tl = nfsm_build(&mb, 3 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
@@ -1764,7 +1764,7 @@ nfsm_v3attrbuild(struct mbuf **mp, struct vattr *a, int full)
tl = nfsm_build(&mb, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);
}
- if (a->va_mtime.tv_sec != VNOVAL) {
+ if (a->va_mtime.tv_nsec != VNOVAL) {
if (a->va_mtime.tv_sec != time_second) {
tl = nfsm_build(&mb, 3 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
@@ -1870,11 +1870,13 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
switch (fxdr_unsigned(int, *tl)) {
case NFSV3SATTRTIME_TOCLIENT:
+ va->va_vaflags |= VA_UTIMES_CHANGE;
va->va_vaflags &= ~VA_UTIMES_NULL;
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
fxdr_nfsv3time(tl, &va->va_atime);
break;
case NFSV3SATTRTIME_TOSERVER:
+ va->va_vaflags |= VA_UTIMES_CHANGE;
getnanotime(&va->va_atime);
break;
};
@@ -1882,11 +1884,13 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
switch (fxdr_unsigned(int, *tl)) {
case NFSV3SATTRTIME_TOCLIENT:
+ va->va_vaflags |= VA_UTIMES_CHANGE;
va->va_vaflags &= ~VA_UTIMES_NULL;
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
fxdr_nfsv3time(tl, &va->va_mtime);
break;
case NFSV3SATTRTIME_TOSERVER:
+ va->va_vaflags |= VA_UTIMES_CHANGE;
getnanotime(&va->va_mtime);
break;
};
@@ -1896,3 +1900,22 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
nfsmout:
return (error);
}
+
+void
+txdr_nfsv2time(const struct timespec *from, struct nfsv2_time *to)
+{
+ if (from->tv_nsec == VNOVAL) {
+ to->nfsv2_sec = nfs_xdrneg1;
+ to->nfsv2_usec = nfs_xdrneg1;
+ } else if (from->tv_sec == -1) {
+ /*
+ * can't request a time of -1; send
+ * -1.000001 == {-2,999999} instead
+ */
+ to->nfsv2_sec = htonl(-2);
+ to->nfsv2_usec = htonl(999999);
+ } else {
+ to->nfsv2_sec = htonl(from->tv_sec);
+ to->nfsv2_usec = htonl(from->tv_nsec / 1000);
+ }
+}
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 8569053dd79..839624970d8 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.162 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.163 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -565,8 +565,10 @@ nfs_setattr(void *v)
* Disallow write attempts if the filesystem is mounted read-only.
*/
if ((vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
- vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
+ vap->va_gid != (gid_t)VNOVAL ||
+ vap->va_atime.tv_nsec != VNOVAL ||
+ vap->va_mtime.tv_nsec != VNOVAL ||
+ vap->va_mode != (mode_t)VNOVAL) &&
(vp->v_mount->mnt_flag & MNT_RDONLY))
return (EROFS);
if (vap->va_size != VNOVAL) {
@@ -577,8 +579,8 @@ nfs_setattr(void *v)
case VBLK:
case VSOCK:
case VFIFO:
- if (vap->va_mtime.tv_sec == VNOVAL &&
- vap->va_atime.tv_sec == VNOVAL &&
+ if (vap->va_mtime.tv_nsec == VNOVAL &&
+ vap->va_atime.tv_nsec == VNOVAL &&
vap->va_mode == (mode_t)VNOVAL &&
vap->va_uid == (uid_t)VNOVAL &&
vap->va_gid == (gid_t)VNOVAL)
@@ -604,8 +606,8 @@ nfs_setattr(void *v)
np->n_size = np->n_vattr.va_size = vap->va_size;
uvm_vnp_setsize(vp, np->n_size);
};
- } else if ((vap->va_mtime.tv_sec != VNOVAL ||
- vap->va_atime.tv_sec != VNOVAL) &&
+ } else if ((vap->va_mtime.tv_nsec != VNOVAL ||
+ vap->va_atime.tv_nsec != VNOVAL) &&
vp->v_type == VREG &&
(error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred,
ap->a_p)) == EINTR)
@@ -2172,6 +2174,7 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
ndp = (struct nfs_dirent *)
uiop->uio_iov->iov_base;
dp = &ndp->dirent;
+ memset(dp, 0, sizeof(dp));
dp->d_fileno = fileno;
dp->d_namlen = len;
dp->d_reclen = tlen;
diff --git a/sys/nfs/xdr_subs.h b/sys/nfs/xdr_subs.h
index 80b8b2ad1fd..05324284662 100644
--- a/sys/nfs/xdr_subs.h
+++ b/sys/nfs/xdr_subs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xdr_subs.h,v 1.9 2013/08/13 05:52:25 guenther Exp $ */
+/* $OpenBSD: xdr_subs.h,v 1.10 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: xdr_subs.h,v 1.11 1996/02/18 11:54:12 fvdl Exp $ */
/*
@@ -60,13 +60,9 @@
else \
(t)->tv_nsec = 0; \
} while (0)
-#define txdr_nfsv2time(f, t) do { \
- ((struct nfsv2_time *)(t))->nfsv2_sec = htonl((f)->tv_sec); \
- if ((f)->tv_nsec != -1) \
- ((struct nfsv2_time *)(t))->nfsv2_usec = htonl((f)->tv_nsec / 1000); \
- else \
- ((struct nfsv2_time *)(t))->nfsv2_usec = 0xffffffff; \
-} while (0)
+
+struct nfsv2_time;
+void txdr_nfsv2time(const struct timespec *_from, struct nfsv2_time *_to);
#define fxdr_nfsv3time(f, t) do { \
(t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index b9dc772c99f..85727da1bc5 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.129 2015/01/09 05:01:57 tedu Exp $ */
+/* $OpenBSD: vnode.h,v 1.130 2015/04/17 04:43:20 guenther Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -150,7 +150,9 @@ struct vnode {
/*
* Vnode attributes. A field value of VNOVAL represents a field whose value
- * is unavailable (getattr) or which is not to be changed (setattr).
+ * is unavailable (getattr) or which is not to be changed (setattr). For
+ * the timespec fields, only the tv_nsec member needs to be set to VNOVAL:
+ * if tv_nsec != VNOVAL then both tv_sec and tv_nsec are valid.
*/
struct vattr {
enum vtype va_type; /* vnode type (for create) */
@@ -177,8 +179,9 @@ struct vattr {
/*
* Flags for va_vaflags.
*/
-#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
-#define VA_EXCLUSIVE 0x02 /* exclusive create request */
+#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
+#define VA_EXCLUSIVE 0x02 /* exclusive create request */
+#define VA_UTIMES_CHANGE 0x04 /* ctime should be updated */
/*
* Flags for ioflag.
*/
diff --git a/sys/tmpfs/tmpfs_subr.c b/sys/tmpfs/tmpfs_subr.c
index a36eb21abba..ce21637c541 100644
--- a/sys/tmpfs/tmpfs_subr.c
+++ b/sys/tmpfs/tmpfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmpfs_subr.c,v 1.13 2015/02/10 21:56:10 miod Exp $ */
+/* $OpenBSD: tmpfs_subr.c,v 1.14 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: tmpfs_subr.c,v 1.79 2012/03/13 18:40:50 elad Exp $ */
/*
@@ -1112,12 +1112,17 @@ tmpfs_chtimes(struct vnode *vp, const struct timespec *atime,
(error = VOP_ACCESS(vp, VWRITE, cred, p))))
return error;
- if (atime->tv_sec != VNOVAL && atime->tv_nsec != VNOVAL)
+ if (atime->tv_nsec != VNOVAL)
node->tn_atime = *atime;
- if (mtime->tv_sec != VNOVAL && mtime->tv_nsec != VNOVAL)
+ if (mtime->tv_nsec != VNOVAL)
node->tn_mtime = *mtime;
+
+ if (mtime->tv_nsec != VNOVAL || (vaflags & VA_UTIMES_CHANGE))
+ tmpfs_update(VP_TO_TMPFS_NODE(vp), TMPFS_NODE_CHANGED);
+
VN_KNOTE(vp, NOTE_ATTRIB);
+
return 0;
}
diff --git a/sys/tmpfs/tmpfs_vnops.c b/sys/tmpfs/tmpfs_vnops.c
index 4da35bf4544..518d799ae11 100644
--- a/sys/tmpfs/tmpfs_vnops.c
+++ b/sys/tmpfs/tmpfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmpfs_vnops.c,v 1.21 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: tmpfs_vnops.c,v 1.22 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: tmpfs_vnops.c,v 1.100 2012/11/05 17:27:39 dholland Exp $ */
/*
@@ -480,7 +480,7 @@ tmpfs_getattr(void *v)
return 0;
}
-#define GOODTIME(tv) ((tv)->tv_sec != VNOVAL || (tv)->tv_nsec != VNOVAL)
+#define GOODTIME(tv) ((tv)->tv_nsec != VNOVAL)
/* XXX Should this operation be atomic? I think it should, but code in
* XXX other places (e.g., ufs) doesn't seem to be... */
int
@@ -519,13 +519,12 @@ tmpfs_setattr(void *v)
if (error == 0 && (vap->va_mode != VNOVAL))
error = tmpfs_chmod(vp, vap->va_mode, cred, p);
- if (error == 0 && (GOODTIME(&vap->va_atime)
- || GOODTIME(&vap->va_mtime))) {
+ if (error == 0 && ((vap->va_vaflags & VA_UTIMES_CHANGE)
+ || GOODTIME(&vap->va_atime)
+ || GOODTIME(&vap->va_mtime)))
error = tmpfs_chtimes(vp, &vap->va_atime, &vap->va_mtime,
vap->va_vaflags, cred, p);
- if (error == 0)
- return 0;
- }
+
return error;
}
diff --git a/sys/ufs/ext2fs/ext2fs_vnops.c b/sys/ufs/ext2fs/ext2fs_vnops.c
index c88e6f4617b..13c3356781b 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.72 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: ext2fs_vnops.c,v 1.73 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: ext2fs_vnops.c,v 1.1 1997/06/11 09:34:09 bouyer Exp $ */
/*
@@ -290,7 +290,9 @@ ext2fs_setattr(void *v)
if (error)
return (error);
}
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
+ if ((vap->va_vaflags & VA_UTIMES_CHANGE) ||
+ vap->va_atime.tv_nsec != VNOVAL ||
+ vap->va_mtime.tv_nsec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != ip->i_e2fs_uid &&
@@ -298,17 +300,19 @@ ext2fs_setattr(void *v)
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, p))))
return (error);
- if (vap->va_mtime.tv_sec != VNOVAL)
+ if (vap->va_mtime.tv_nsec != VNOVAL)
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- if (vap->va_atime.tv_sec != VNOVAL) {
+ else if (vap->va_vaflags & VA_UTIMES_CHANGE)
+ ip->i_flag |= IN_CHANGE;
+ if (vap->va_atime.tv_nsec != VNOVAL) {
if (!(vp->v_mount->mnt_flag & MNT_NOATIME) ||
(ip->i_flag & (IN_CHANGE | IN_UPDATE)))
ip->i_flag |= IN_ACCESS;
}
EXT2FS_ITIMES(ip);
- if (vap->va_mtime.tv_sec != VNOVAL)
+ if (vap->va_mtime.tv_nsec != VNOVAL)
ip->i_e2fs_mtime = vap->va_mtime.tv_sec;
- if (vap->va_atime.tv_sec != VNOVAL)
+ if (vap->va_atime.tv_nsec != VNOVAL)
ip->i_e2fs_atime = vap->va_atime.tv_sec;
error = ext2fs_update(ip, 1);
if (error)
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 13761130ce3..e6f543b8cb9 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.120 2015/03/14 03:38:53 jsg Exp $ */
+/* $OpenBSD: ufs_vnops.c,v 1.121 2015/04/17 04:43:21 guenther Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
/*
@@ -420,7 +420,9 @@ ufs_setattr(void *v)
if (vap->va_size < oldsize)
hint |= NOTE_TRUNCATE;
}
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
+ if ((vap->va_vaflags & VA_UTIMES_CHANGE) ||
+ vap->va_atime.tv_nsec != VNOVAL ||
+ vap->va_mtime.tv_nsec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != DIP(ip, uid) &&
@@ -428,19 +430,21 @@ ufs_setattr(void *v)
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, p))))
return (error);
- if (vap->va_mtime.tv_sec != VNOVAL)
+ if (vap->va_mtime.tv_nsec != VNOVAL)
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- if (vap->va_atime.tv_sec != VNOVAL) {
+ else if (vap->va_vaflags & VA_UTIMES_CHANGE)
+ ip->i_flag |= IN_CHANGE;
+ if (vap->va_atime.tv_nsec != VNOVAL) {
if (!(vp->v_mount->mnt_flag & MNT_NOATIME) ||
(ip->i_flag & (IN_CHANGE | IN_UPDATE)))
ip->i_flag |= IN_ACCESS;
}
ufs_itimes(vp);
- if (vap->va_mtime.tv_sec != VNOVAL) {
+ if (vap->va_mtime.tv_nsec != 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) {
+ if (vap->va_atime.tv_nsec != VNOVAL) {
DIP_ASSIGN(ip, atime, vap->va_atime.tv_sec);
DIP_ASSIGN(ip, atimensec, vap->va_atime.tv_nsec);
}