Author: jhb
Date: Wed Jan 21 14:42:00 2009
New Revision: 187526
URL: http://svn.freebsd.org/changeset/base/187526

Log:
  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

Modified:
  head/sys/kern/vfs_subr.c
  head/sys/kern/vnode_if.src
  head/sys/nfsclient/nfs_vnops.c
  head/sys/ufs/ufs/ufs_vnops.c

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c    Wed Jan 21 14:22:06 2009        (r187525)
+++ head/sys/kern/vfs_subr.c    Wed Jan 21 14:42:00 2009        (r187526)
@@ -4206,18 +4206,15 @@ vfs_read_dirent(struct vop_readdir_args 
 
 /*
  * 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);
        }
 }

Modified: head/sys/kern/vnode_if.src
==============================================================================
--- head/sys/kern/vnode_if.src  Wed Jan 21 14:22:06 2009        (r187525)
+++ head/sys/kern/vnode_if.src  Wed Jan 21 14:42:00 2009        (r187526)
@@ -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
 

Modified: head/sys/nfsclient/nfs_vnops.c
==============================================================================
--- head/sys/nfsclient/nfs_vnops.c      Wed Jan 21 14:22:06 2009        
(r187525)
+++ head/sys/nfsclient/nfs_vnops.c      Wed Jan 21 14:42:00 2009        
(r187526)
@@ -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);
 
        /*

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c        Wed Jan 21 14:22:06 2009        
(r187525)
+++ head/sys/ufs/ufs/ufs_vnops.c        Wed Jan 21 14:42:00 2009        
(r187526)
@@ -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);
@@ -663,6 +653,25 @@ ufs_setattr(ap)
 }
 
 /*
+ * 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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to