From 349433c9ce488bf66a66873bc5591529ad32500f Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 20 Jan 2009 17:39:51 -0800 Subject: [PATCH] Issue 1013 - update atime on exec and mmap, add helper vop_markatime Add a new helper VOP which passively updates a vnode's atime. Implement the new VOP in HAMMER and UFS and create a default op which does nothing. Call the new function from mmap() and exec(). Submitted-by: Dion Blazakis Reported-by: Simon Schubert --- lib/libc/sys/stat.2 | 6 ++++-- sys/kern/kern_exec.c | 3 +++ sys/kern/vfs_default.c | 7 +++++++ sys/kern/vfs_subr.c | 10 ++++++++++ sys/kern/vfs_vopops.c | 27 ++++++++++++++++++++++++++- sys/sys/vfsops.h | 14 ++++++++++++++ sys/sys/vnode.h | 2 ++ sys/vfs/hammer/hammer_vnops.c | 31 +++++++++++++++++++++++++++++++ sys/vfs/ufs/ufs_vnops.c | 20 ++++++++++++++++++++ sys/vm/vm_mmap.c | 8 ++++++++ 10 files changed, 125 insertions(+), 3 deletions(-) diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2 index 8816375ecb..fa4ab27fda 100644 --- a/lib/libc/sys/stat.2 +++ b/lib/libc/sys/stat.2 @@ -123,10 +123,12 @@ are as follows: .It st_atime Time when file data last accessed. Changed by the +.Xr execve 2 , .Xr mknod 2 , -.Xr utimes 2 -and +.Xr mmap 2 , .Xr read 2 +and +.Xr utimes 2 system calls. .It st_mtime Time when file data last modified. diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 1212eef4cf..56e54ec14e 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -469,6 +469,9 @@ interpret: exec_setregs(imgp->entry_addr, (u_long)(uintptr_t)stack_base, imgp->ps_strings); + /* Set the access time on the vnode */ + vn_mark_atime(imgp->vp, td); + /* Free any previous argument cache */ if (p->p_args && --p->p_args->ar_ref == 0) FREE(p->p_args, M_PARGS); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index da0534c449..fe3c03325f 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -95,6 +95,7 @@ struct vop_ops default_vnode_vops = { .vop_aclcheck = (void *)vop_eopnotsupp, .vop_getextattr = (void *)vop_eopnotsupp, .vop_setextattr = (void *)vop_eopnotsupp, + .vop_markatime = vop_stdmarkatime, .vop_nresolve = vop_compat_nresolve, .vop_nlookupdotdot = vop_compat_nlookupdotdot, .vop_ncreate = vop_compat_ncreate, @@ -135,6 +136,12 @@ vop_einval(struct vop_generic_args *ap) return (EINVAL); } +int +vop_stdmarkatime(struct vop_markatime_args *ap) +{ + return (EOPNOTSUPP); +} + int vop_null(struct vop_generic_args *ap) { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 8c9f324297..6064667c17 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2143,3 +2143,13 @@ vop_write_dirent(int *error, struct uio *uio, ino_t d_ino, uint8_t d_type, return(0); } +void +vn_mark_atime(struct vnode *vp, struct thread *td) +{ + struct proc *p = td->td_proc; + struct ucred *cred = p ? p->p_ucred : proc0.p_ucred; + + if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0) { + VOP_MARKATIME(vp, cred); + } +} diff --git a/sys/kern/vfs_vopops.c b/sys/kern/vfs_vopops.c index a15bddc42d..89ce089418 100644 --- a/sys/kern/vfs_vopops.c +++ b/sys/kern/vfs_vopops.c @@ -127,6 +127,7 @@ VNODEOP_DESC_INIT(aclcheck); VNODEOP_DESC_INIT(getextattr); VNODEOP_DESC_INIT(setextattr); VNODEOP_DESC_INIT(mountctl); +VNODEOP_DESC_INIT(markatime); VNODEOP_DESC_INIT(nresolve); VNODEOP_DESC_INIT(nlookupdotdot); @@ -902,7 +903,7 @@ vop_setextattr(struct vop_ops *ops, struct vnode *vp, char *name, int vop_mountctl(struct vop_ops *ops, int op, struct file *fp, - const void *ctl, int ctllen, void *buf, int buflen, int *res) + const void *ctl, int ctllen, void *buf, int buflen, int *res) { struct vop_mountctl_args ap; int error; @@ -921,6 +922,21 @@ vop_mountctl(struct vop_ops *ops, int op, struct file *fp, return(error); } +int +vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred) +{ + struct vop_markatime_args ap; + int error; + + ap.a_head.a_desc = &vop_markatime_desc; + ap.a_head.a_ops = ops; + ap.a_vp = vp; + ap.a_cred = cred; + + DO_OPS(ops, error, &ap, vop_markatime); + return(error); +} + /* * NEW API FUNCTIONS * @@ -1605,6 +1621,15 @@ vop_mountctl_ap(struct vop_mountctl_args *ap) return(error); } +int +vop_markatime_ap(struct vop_markatime_args *ap) +{ + int error; + + DO_OPS(ap->a_head.a_ops, error, ap, vop_markatime); + return(error); +} + int vop_nresolve_ap(struct vop_nresolve_args *ap) { diff --git a/sys/sys/vfsops.h b/sys/sys/vfsops.h index 1e5bd3b002..b2ae193213 100644 --- a/sys/sys/vfsops.h +++ b/sys/sys/vfsops.h @@ -417,6 +417,13 @@ struct vop_mountctl_args { int *a_res; }; +struct vop_markatime_args { + struct vop_generic_args a_head; + int a_op; + struct vnode *a_vp; + struct ucred *a_cred; +}; + /* * NEW API */ @@ -621,6 +628,7 @@ struct vop_ops { int (*vop_unused07)(void *); int (*vop_unused08)(void *); int (*vop_mountctl)(struct vop_mountctl_args *); + int (*vop_markatime)(struct vop_markatime_args *); int (*vop_nresolve)(struct vop_nresolve_args *); int (*vop_nlookupdotdot)(struct vop_nlookupdotdot_args *); @@ -693,6 +701,7 @@ union vop_args_union { struct vop_getextattr_args vu_getextattr; struct vop_setextattr_args vu_setextattr; struct vop_mountctl_args vu_mountctl; + struct vop_markatime_args vu_markatime; struct vop_nresolve_args vu_nresolve; struct vop_nlookupdotdot_args vu_nlookupdotdot; @@ -802,6 +811,7 @@ int vop_setextattr(struct vop_ops *ops, struct vnode *vp, char *name, struct uio *uio, struct ucred *cred); int vop_mountctl(struct vop_ops *ops, int op, struct file *fp, const void *ctl, int ctllen, void *buf, int buflen, int *res); +int vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred); int vop_nresolve(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, struct ucred *cred); int vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, @@ -883,6 +893,7 @@ int vop_aclcheck_ap(struct vop_aclcheck_args *ap); int vop_getextattr_ap(struct vop_getextattr_args *ap); int vop_setextattr_ap(struct vop_setextattr_args *ap); int vop_mountctl_ap(struct vop_mountctl_args *ap); +int vop_markatime_ap(struct vop_markatime_args *ap); int vop_nresolve_ap(struct vop_nresolve_args *ap); int vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap); @@ -945,6 +956,7 @@ extern struct syslink_desc vop_aclcheck_desc; extern struct syslink_desc vop_getextattr_desc; extern struct syslink_desc vop_setextattr_desc; extern struct syslink_desc vop_mountctl_desc; +extern struct syslink_desc vop_markatime_desc; extern struct syslink_desc vop_nresolve_desc; extern struct syslink_desc vop_nlookupdotdot_desc; @@ -1026,6 +1038,8 @@ extern struct syslink_desc vop_nrename_desc; vop_getextattr(*(vp)->v_ops, vp, name, uio, cred) #define VOP_SETEXTATTR(vp, name, uio, cred) \ vop_setextattr(*(vp)->v_ops, vp, name, uio, cred) +#define VOP_MARKATIME(vp, cred) \ + vop_markatime(*(vp)->v_ops, vp, cred) /* no VOP_VFSSET() */ /* VOP_STRATEGY - does not exist, use vn_strategy() */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 253577c5fc..70c7ac4b0b 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -517,12 +517,14 @@ int vn_rdwr_inchunks (enum uio_rw rw, struct vnode *vp, caddr_t base, int vn_stat (struct vnode *vp, struct stat *sb, struct ucred *cred); cdev_t vn_todev (struct vnode *vp); void vfs_timestamp (struct timespec *); +void vn_mark_atime(struct vnode *vp, struct thread *td); int vn_writechk (struct vnode *vp, struct nchandle *nch); int ncp_writechk(struct nchandle *nch); int vop_stdopen (struct vop_open_args *ap); int vop_stdclose (struct vop_close_args *ap); int vop_stdgetpages(struct vop_getpages_args *ap); int vop_stdputpages(struct vop_putpages_args *ap); +int vop_stdmarkatime(struct vop_markatime_args *ap); int vop_nopoll (struct vop_poll_args *ap); int vop_stdpathconf (struct vop_pathconf_args *ap); int vop_stdpoll (struct vop_poll_args *ap); diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 7c443c8c99..5b4e14ae7e 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -73,6 +73,7 @@ static int hammer_vop_readlink(struct vop_readlink_args *); static int hammer_vop_nremove(struct vop_nremove_args *); static int hammer_vop_nrename(struct vop_nrename_args *); static int hammer_vop_nrmdir(struct vop_nrmdir_args *); +static int hammer_vop_markatime(struct vop_markatime_args *); static int hammer_vop_setattr(struct vop_setattr_args *); static int hammer_vop_strategy(struct vop_strategy_args *); static int hammer_vop_bmap(struct vop_bmap_args *ap); @@ -118,6 +119,7 @@ struct vop_ops hammer_vnode_vops = { .vop_nremove = hammer_vop_nremove, .vop_nrename = hammer_vop_nrename, .vop_nrmdir = hammer_vop_nrmdir, + .vop_markatime = hammer_vop_markatime, .vop_setattr = hammer_vop_setattr, .vop_bmap = hammer_vop_bmap, .vop_strategy = hammer_vop_strategy, @@ -135,6 +137,7 @@ struct vop_ops hammer_spec_vops = { .vop_write = hammer_vop_specwrite, .vop_access = hammer_vop_access, .vop_close = hammer_vop_specclose, + .vop_markatime = hammer_vop_markatime, .vop_getattr = hammer_vop_getattr, .vop_inactive = hammer_vop_inactive, .vop_reclaim = hammer_vop_reclaim, @@ -148,6 +151,7 @@ struct vop_ops hammer_fifo_vops = { .vop_write = hammer_vop_fifowrite, .vop_access = hammer_vop_access, .vop_close = hammer_vop_fifoclose, + .vop_markatime = hammer_vop_markatime, .vop_getattr = hammer_vop_getattr, .vop_inactive = hammer_vop_inactive, .vop_reclaim = hammer_vop_reclaim, @@ -1702,6 +1706,33 @@ hammer_vop_nrmdir(struct vop_nrmdir_args *ap) return (error); } +/* + * hammer_vop_markatime { vp, cred } + */ +static +int +hammer_vop_markatime(struct vop_markatime_args *ap) +{ + struct hammer_transaction trans; + struct hammer_inode *ip; + + ip = VTOI(ap->a_vp); + if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) + return (EROFS); + if (ip->flags & HAMMER_INODE_RO) + return (EROFS); + if (ip->hmp->mp->mnt_flag & MNT_NOATIME) + return (0); + hammer_start_transaction(&trans, ip->hmp); + ++hammer_stats_file_iopsw; + + ip->ino_data.atime = trans.time; + hammer_modify_inode(ip, HAMMER_INODE_ATIME); + hammer_done_transaction(&trans); + hammer_knote(ap->a_vp, NOTE_ATTRIB); + return (0); +} + /* * hammer_vop_setattr { vp, vap, cred } */ diff --git a/sys/vfs/ufs/ufs_vnops.c b/sys/vfs/ufs/ufs_vnops.c index bfcf1781eb..dfdf1ead32 100644 --- a/sys/vfs/ufs/ufs_vnops.c +++ b/sys/vfs/ufs/ufs_vnops.c @@ -89,6 +89,7 @@ static int ufs_create (struct vop_old_create_args *); static int ufs_getattr (struct vop_getattr_args *); static int ufs_link (struct vop_old_link_args *); static int ufs_makeinode (int mode, struct vnode *, struct vnode **, struct componentname *); +static int ufs_markatime (struct vop_markatime_args *); static int ufs_missingop (struct vop_generic_args *ap); static int ufs_mkdir (struct vop_old_mkdir_args *); static int ufs_mknod (struct vop_old_mknod_args *); @@ -444,6 +445,22 @@ ufs_getattr(struct vop_getattr_args *ap) return (0); } +static +int +ufs_markatime(struct vop_markatime_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct inode *ip = VTOI(vp); + + if (vp->v_mount->mnt_flag & MNT_RDONLY) + return (EROFS); + if (vp->v_mount->mnt_flag & MNT_NOATIME) + return (0); + ip->i_flag |= IN_ACCESS; + VN_KNOTE(vp, NOTE_ATTRIB); + return (0); +} + /* * Set attribute vnode op. called from several syscalls * @@ -2368,6 +2385,7 @@ static struct vop_ops ufs_vnode_vops = { .vop_old_rename = ufs_rename, .vop_old_rmdir = ufs_rmdir, .vop_setattr = ufs_setattr, + .vop_markatime = ufs_markatime, .vop_strategy = ufs_strategy, .vop_old_symlink = ufs_symlink, .vop_old_whiteout = ufs_whiteout @@ -2384,6 +2402,7 @@ static struct vop_ops ufs_spec_vops = { .vop_read = ufsspec_read, .vop_reclaim = ufs_reclaim, .vop_setattr = ufs_setattr, + .vop_markatime = ufs_markatime, .vop_write = ufsspec_write }; @@ -2399,6 +2418,7 @@ static struct vop_ops ufs_fifo_vops = { .vop_read = ufsfifo_read, .vop_reclaim = ufs_reclaim, .vop_setattr = ufs_setattr, + .vop_markatime = ufs_markatime, .vop_write = ufsfifo_write }; diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index cfe56ef01a..171737026a 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -985,6 +985,7 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, boolean_t fitit; vm_object_t object; struct vnode *vp = NULL; + struct thread *td = curthread; struct proc *p; objtype_t type; int rv = KERN_SUCCESS; @@ -1136,6 +1137,13 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, goto out; } } + + /* + * Set the access time on the vnode + */ + if (handle != NULL) { + vn_mark_atime(handle, td); + } out: switch (rv) { case KERN_SUCCESS: -- 2.41.0