Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/tmpfs - tmpfs_construct_node: prevent from the new no...
details: https://anonhg.NetBSD.org/src/rev/4b209f804b52
branches: trunk
changeset: 791593:4b209f804b52
user: rmind <rmind%NetBSD.org@localhost>
date: Sun Nov 24 17:16:29 2013 +0000
description:
- tmpfs_construct_node: prevent from the new node construction if the
directory was removed. Fixes the crash reported by Nicolas Joly.
- tmpfs_reclaim: avoid race by checking tn_links with the vnode locked.
diffstat:
sys/fs/tmpfs/tmpfs_subr.c | 13 +++++++++++--
sys/fs/tmpfs/tmpfs_vnops.c | 25 +++++++++++++------------
2 files changed, 24 insertions(+), 14 deletions(-)
diffs (93 lines):
diff -r 6bbc21fcb1a4 -r 4b209f804b52 sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Sun Nov 24 17:16:28 2013 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Sun Nov 24 17:16:29 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_subr.c,v 1.91 2013/11/23 21:53:27 rmind Exp $ */
+/* $NetBSD: tmpfs_subr.c,v 1.92 2013/11/24 17:16:29 rmind Exp $ */
/*
* Copyright (c) 2005-2013 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.91 2013/11/23 21:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.92 2013/11/24 17:16:29 rmind Exp $");
#include <sys/param.h>
#include <sys/cprng.h>
@@ -358,6 +358,15 @@
KASSERT(VOP_ISLOCKED(dvp));
*vpp = NULL;
+ /*
+ * If directory was removed, prevent from node creation. The vnode
+ * might still be referenced, but it is about to be reclaimed.
+ */
+ if (dnode->tn_links == 0) {
+ error = ENOENT;
+ goto out;
+ }
+
/* Check for the maximum number of links limit. */
if (vap->va_type == VDIR) {
/* Check for maximum links limit. */
diff -r 6bbc21fcb1a4 -r 4b209f804b52 sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c Sun Nov 24 17:16:28 2013 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c Sun Nov 24 17:16:29 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_vnops.c,v 1.108 2013/11/23 17:01:07 rmind Exp $ */
+/* $NetBSD: tmpfs_vnops.c,v 1.109 2013/11/24 17:16:29 rmind Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.108 2013/11/23 17:01:07 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.109 2013/11/24 17:16:29 rmind Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -195,7 +195,7 @@
/*
* Lock the parent tn_vlock before releasing the vnode lock,
- * and thus prevents parent from disappearing.
+ * and thus prevent parent from disappearing.
*/
mutex_enter(&pnode->tn_vlock);
VOP_UNLOCK(dvp);
@@ -1066,21 +1066,22 @@
vnode_t *vp = ap->a_vp;
tmpfs_mount_t *tmp = VFS_TO_TMPFS(vp->v_mount);
tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp);
- bool racing;
+ bool recycle;
+
+ mutex_enter(&node->tn_vlock);
+ VOP_LOCK(vp, LK_EXCLUSIVE);
/* Disassociate inode from vnode. */
- mutex_enter(&node->tn_vlock);
node->tn_vnode = NULL;
vp->v_data = NULL;
- /* Check if tmpfs_vnode_get() is racing with us. */
- racing = TMPFS_NODE_RECLAIMING(node);
+
+ /* If inode is not referenced, i.e. no links, then destroy it. */
+ recycle = node->tn_links == 0 && TMPFS_NODE_RECLAIMING(node) == 0;
+
+ VOP_UNLOCK(vp);
mutex_exit(&node->tn_vlock);
- /*
- * If inode is not referenced, i.e. no links, then destroy it.
- * Note: if racing - inode is about to get a new vnode, leave it.
- */
- if (node->tn_links == 0 && !racing) {
+ if (recycle) {
tmpfs_free_node(tmp, node);
}
return 0;
Home |
Main Index |
Thread Index |
Old Index