From owner-svn-src-head@freebsd.org Fri Jan 6 17:43:38 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5E878CA23E5; Fri, 6 Jan 2017 17:43:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 39A6A1967; Fri, 6 Jan 2017 17:43:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v06HhbMP004141; Fri, 6 Jan 2017 17:43:37 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v06HhbIw004137; Fri, 6 Jan 2017 17:43:37 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201701061743.v06HhbIw004137@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 6 Jan 2017 17:43:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r311525 - head/sys/fs/tmpfs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Jan 2017 17:43:38 -0000 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