diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-01-25 23:31:14 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-01-25 23:31:14 +0000 |
commit | 0f625750d8460feae32186dea8a48954cfac73e4 (patch) | |
tree | d5912694801ee8816158f328e12da2dbf9bbbb83 | |
parent | 2fdf77c4df090c6eff0f17e7cb6a976e47e0def0 (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.h | 5 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_inode.c | 21 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_readwrite.c | 4 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_vnops.c | 30 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 4 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_balloc.c | 6 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_extern.h | 4 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 42 | ||||
-rw-r--r-- | sys/ufs/ufs/inode.h | 48 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_extern.h | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 90 |
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 */ |