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
This commit is contained in:
parent
1e9d4974c1
commit
beace17649
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187526
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user