Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jan 2017 17:43:37 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r311525 - head/sys/fs/tmpfs
Message-ID:  <201701061743.v06HhbIw004137@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701061743.v06HhbIw004137>