From beace176493de44276a2f4e22add8e1acc8f4f96 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 21 Jan 2009 14:42:00 +0000 Subject: [PATCH] Move the VA_MARKATIME flag for VOP_SETATTR() out into its own VOP: VOP_MARKATIME() since unlike the rest of VOP_SETATTR(), VA_MARKATIME can be performed while holding a shared vnode lock (the same functionality is done internally by VOP_READ which can run with a shared vnode lock). Add missing locking of the vnode interlock to the ufs implementation and remove a special note and test from the NFS client about not supporting the feature. Inspired by: ups Tested by: pho --- sys/kern/vfs_subr.c | 7 ++----- sys/kern/vnode_if.src | 5 +++++ sys/nfsclient/nfs_vnops.c | 4 ++-- sys/ufs/ufs/ufs_vnops.c | 33 ++++++++++++++++++++++----------- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 1e4bf902d075..753f95ff737d 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -4206,18 +4206,15 @@ vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off) /* * Mark for update the access time of the file if the filesystem - * supports VA_MARK_ATIME. This functionality is used by execve + * supports VOP_MARKATIME. This functionality is used by execve * and mmap, so we want to avoid the synchronous I/O implied by * directly setting va_atime for the sake of efficiency. */ void vfs_mark_atime(struct vnode *vp, struct ucred *cred) { - struct vattr atimeattr; if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0) { - VATTR_NULL(&atimeattr); - atimeattr.va_vaflags |= VA_MARK_ATIME; - (void)VOP_SETATTR(vp, &atimeattr, cred); + (void)VOP_MARKATIME(vp); } } diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index 36ea43468b7f..ad4d1f7b1462 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -171,6 +171,11 @@ vop_setattr { IN struct ucred *cred; }; +%% markatime vp L L L + +vop_markatime { + IN struct vnode *vp; +}; %% read vp L L L diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 73994707875c..7f8ab1883d4b 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -707,9 +707,9 @@ nfs_setattr(struct vop_setattr_args *ap) #endif /* - * Setting of flags and marking of atimes are not supported. + * Setting of flags is not supported. */ - if (vap->va_flags != VNOVAL || (vap->va_vaflags & VA_MARK_ATIME)) + if (vap->va_flags != VNOVAL) return (EOPNOTSUPP); /* diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 7b639e8b126a..3fc16a1ec1d6 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -98,6 +98,7 @@ static vop_create_t ufs_create; static vop_getattr_t ufs_getattr; static vop_link_t ufs_link; static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); +static vop_markatime_t ufs_markatime; static vop_mkdir_t ufs_mkdir; static vop_mknod_t ufs_mknod; static vop_open_t ufs_open; @@ -491,17 +492,6 @@ ufs_setattr(ap) ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { return (EINVAL); } - /* - * Mark for update the file's access time for vfs_mark_atime(). - * We are doing this here to avoid some of the checks done - * below -- this operation is done by request of the kernel and - * should bypass some security checks. Things like read-only - * checks get handled by other levels (e.g., ffs_update()). - */ - if (vap->va_vaflags & VA_MARK_ATIME) { - ip->i_flag |= IN_ACCESS; - return (0); - } if (vap->va_flags != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); @@ -662,6 +652,25 @@ ufs_setattr(ap) return (error); } +/* + * Mark this file's access time for update for vfs_mark_atime(). This + * is called from execve() and mmap(). + */ +static int +ufs_markatime(ap) + struct vop_markatime_args /* { + struct vnode *a_vp; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + struct inode *ip = VTOI(vp); + + VI_LOCK(vp); + ip->i_flag |= IN_ACCESS; + VI_UNLOCK(vp); + return (0); +} + /* * Change the mode on a file. * Inode must be locked before calling. @@ -2481,6 +2490,7 @@ struct vop_vector ufs_vnodeops = { .vop_rename = ufs_rename, .vop_rmdir = ufs_rmdir, .vop_setattr = ufs_setattr, + .vop_markatime = ufs_markatime, #ifdef MAC .vop_setlabel = vop_stdsetlabel_ea, #endif @@ -2511,6 +2521,7 @@ struct vop_vector ufs_fifoops = { .vop_read = VOP_PANIC, .vop_reclaim = ufs_reclaim, .vop_setattr = ufs_setattr, + .vop_markatime = ufs_markatime, #ifdef MAC .vop_setlabel = vop_stdsetlabel_ea, #endif