Author: kib
Date: Fri Jan  6 17:43:36 2017
New Revision: 311525
URL: https://svnweb.freebsd.org/changeset/base/311525

Log:
  Lock tmpfs node tn_status updates done under the shared vnode lock.
  
  If tmpfs vnode is only shared locked, tn_status field still needs
  updates to note the access time modification.  Use the same locking
  scheme as for UFS, protect tn_status with the node interlock + shared
  vnode lock.
  
  Fix nearby style.
  
  Noted and reviewed by:        mjg
  Tested by:    pho
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week

Modified:
  head/sys/fs/tmpfs/tmpfs.h
  head/sys/fs/tmpfs/tmpfs_fifoops.c
  head/sys/fs/tmpfs/tmpfs_subr.c
  head/sys/fs/tmpfs/tmpfs_vnops.c

Modified: head/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs.h   Fri Jan  6 17:32:44 2017        (r311524)
+++ head/sys/fs/tmpfs/tmpfs.h   Fri Jan  6 17:43:36 2017        (r311525)
@@ -199,7 +199,9 @@ struct tmpfs_node {
         * allocated for it or it has been reclaimed). */
        struct vnode *          tn_vnode;
 
-       /* interlock to protect tn_vpstate */
+       /* Interlock to protect tn_vpstate, and tn_status under shared
+        * vnode lock.
+        */
        struct mtx      tn_interlock;
 
        /* Identify if current node has vnode assiocate with
@@ -420,6 +422,7 @@ int tmpfs_chtimes(struct vnode *, struct
 void   tmpfs_itimes(struct vnode *, const struct timespec *,
            const struct timespec *);
 
+void   tmpfs_set_status(struct tmpfs_node *node, int status);
 void   tmpfs_update(struct vnode *);
 int    tmpfs_truncate(struct vnode *, off_t);
 

Modified: head/sys/fs/tmpfs/tmpfs_fifoops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_fifoops.c   Fri Jan  6 17:32:44 2017        
(r311524)
+++ head/sys/fs/tmpfs/tmpfs_fifoops.c   Fri Jan  6 17:43:36 2017        
(r311525)
@@ -52,11 +52,11 @@ static int
 tmpfs_fifo_close(struct vop_close_args *v)
 {
        struct tmpfs_node *node;
-       node = VP_TO_TMPFS_NODE(v->a_vp);
-       node->tn_status |= TMPFS_NODE_ACCESSED;
 
+       node = VP_TO_TMPFS_NODE(v->a_vp);
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
        tmpfs_update(v->a_vp);
-       return fifo_specops.vop_close(v);
+       return (fifo_specops.vop_close(v));
 }
 
 /*

Modified: head/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c      Fri Jan  6 17:32:44 2017        
(r311524)
+++ head/sys/fs/tmpfs/tmpfs_subr.c      Fri Jan  6 17:43:36 2017        
(r311525)
@@ -1092,9 +1092,9 @@ tmpfs_dir_getdotdent(struct tmpfs_node *
        else
                error = uiomove(&dent, dent.d_reclen, uio);
 
-       node->tn_status |= TMPFS_NODE_ACCESSED;
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
 
-       return error;
+       return (error);
 }
 
 /*
@@ -1137,9 +1137,9 @@ tmpfs_dir_getdotdotdent(struct tmpfs_nod
        else
                error = uiomove(&dent, dent.d_reclen, uio);
 
-       node->tn_status |= TMPFS_NODE_ACCESSED;
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
 
-       return error;
+       return (error);
 }
 
 /*
@@ -1282,7 +1282,7 @@ tmpfs_dir_getdents(struct tmpfs_node *no
        node->tn_dir.tn_readdir_lastn = off;
        node->tn_dir.tn_readdir_lastp = de;
 
-       node->tn_status |= TMPFS_NODE_ACCESSED;
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
        return error;
 }
 
@@ -1735,15 +1735,25 @@ tmpfs_chtimes(struct vnode *vp, struct v
        return (0);
 }
 
-/* Sync timestamps */
 void
-tmpfs_itimes(struct vnode *vp, const struct timespec *acc,
+tmpfs_set_status(struct tmpfs_node *node, int status)
+{
+
+       if ((node->tn_status & status) == status)
+               return;
+       TMPFS_NODE_LOCK(node);
+       node->tn_status |= status;
+       TMPFS_NODE_UNLOCK(node);
+}
+
+/* Sync timestamps */
+static void
+tmpfs_itimes_locked(struct tmpfs_node *node, const struct timespec *acc,
     const struct timespec *mod)
 {
-       struct tmpfs_node *node;
        struct timespec now;
 
-       node = VP_TO_TMPFS_NODE(vp);
+       TMPFS_ASSERT_LOCKED(node);
 
        if ((node->tn_status & (TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
            TMPFS_NODE_CHANGED)) == 0)
@@ -1760,11 +1770,25 @@ tmpfs_itimes(struct vnode *vp, const str
                        mod = &now;
                node->tn_mtime = *mod;
        }
-       if (node->tn_status & TMPFS_NODE_CHANGED) {
+       if (node->tn_status & TMPFS_NODE_CHANGED)
                node->tn_ctime = now;
-       }
-       node->tn_status &=
-           ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED);
+       node->tn_status &= ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
+           TMPFS_NODE_CHANGED);
+}
+
+void
+tmpfs_itimes(struct vnode *vp, const struct timespec *acc,
+    const struct timespec *mod)
+{
+       struct tmpfs_node *node;
+
+       ASSERT_VOP_LOCKED(vp, "tmpfs_itimes");
+       node = VP_TO_TMPFS_NODE(vp);
+
+       TMPFS_NODE_LOCK(node);
+       tmpfs_itimes_locked(node, acc, mod);
+       TMPFS_NODE_UNLOCK(node);
+
        /* XXX: FIX? The entropy here is desirable, but the harvesting may be 
expensive */
        random_harvest_queue(node, sizeof(*node), 1, RANDOM_FS_ATIME);
 }
@@ -1798,14 +1822,13 @@ tmpfs_truncate(struct vnode *vp, off_t l
                return (EFBIG);
 
        error = tmpfs_reg_resize(vp, length, FALSE);
-       if (error == 0) {
+       if (error == 0)
                node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
-       }
 
 out:
        tmpfs_update(vp);
 
-       return error;
+       return (error);
 }
 
 static __inline int

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c     Fri Jan  6 17:32:44 2017        
(r311524)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c     Fri Jan  6 17:43:36 2017        
(r311525)
@@ -445,7 +445,7 @@ tmpfs_read(struct vop_read_args *v)
        if (uio->uio_offset < 0)
                return (EINVAL);
        node = VP_TO_TMPFS_NODE(vp);
-       node->tn_status |= TMPFS_NODE_ACCESSED;
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
        return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio));
 }
 
@@ -1082,8 +1082,8 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
            v->a_cnp->cn_namelen));
 
        /* Check flags to see if we are allowed to remove the directory. */
-       if (dnode->tn_flags & APPEND
-               || node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) {
+       if ((dnode->tn_flags & APPEND) != 0 ||
+           (node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) != 0) {
                error = EPERM;
                goto out;
        }
@@ -1099,7 +1099,7 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
        TMPFS_ASSERT_ELOCKED(node);
        node->tn_links--;
        node->tn_dir.tn_parent = NULL;
-       node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
+       node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
            TMPFS_NODE_MODIFIED;
 
        TMPFS_NODE_UNLOCK(node);
@@ -1107,8 +1107,8 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
        TMPFS_NODE_LOCK(dnode);
        TMPFS_ASSERT_ELOCKED(dnode);
        dnode->tn_links--;
-       dnode->tn_status |= TMPFS_NODE_ACCESSED | \
-           TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
+       dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
+           TMPFS_NODE_MODIFIED;
        TMPFS_NODE_UNLOCK(dnode);
 
        cache_purge(dvp);
@@ -1220,9 +1220,9 @@ tmpfs_readlink(struct vop_readlink_args 
 
        error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid),
            uio);
-       node->tn_status |= TMPFS_NODE_ACCESSED;
+       tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
 
-       return error;
+       return (error);
 }
 
 static int
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to