svn commit: r254550 - stable/9/sys/fs/tmpfs

Konstantin Belousov kib at FreeBSD.org
Tue Aug 20 07:11:54 UTC 2013


Author: kib
Date: Tue Aug 20 07:11:53 2013
New Revision: 254550
URL: http://svnweb.freebsd.org/changeset/base/254550

Log:
  MFC r253967:
  Wait for the doomed vnode to be detached from the tmpfs
  node if sleepable allocation is requested.

Modified:
  stable/9/sys/fs/tmpfs/tmpfs.h
  stable/9/sys/fs/tmpfs/tmpfs_subr.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/fs/   (props changed)

Modified: stable/9/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- stable/9/sys/fs/tmpfs/tmpfs.h	Tue Aug 20 06:46:40 2013	(r254549)
+++ stable/9/sys/fs/tmpfs/tmpfs.h	Tue Aug 20 07:11:53 2013	(r254550)
@@ -327,6 +327,7 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
 #define TMPFS_VNODE_ALLOCATING	1
 #define TMPFS_VNODE_WANT	2
 #define TMPFS_VNODE_DOOMED	4
+#define	TMPFS_VNODE_WRECLAIM	8
 /* --------------------------------------------------------------------- */
 
 /*

Modified: stable/9/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- stable/9/sys/fs/tmpfs/tmpfs_subr.c	Tue Aug 20 06:46:40 2013	(r254549)
+++ stable/9/sys/fs/tmpfs/tmpfs_subr.c	Tue Aug 20 07:11:53 2013	(r254550)
@@ -386,11 +386,32 @@ tmpfs_alloc_vp(struct mount *mp, struct 
 
 loop:
 	TMPFS_NODE_LOCK(node);
+loop1:
 	if ((vp = node->tn_vnode) != NULL) {
 		MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0);
 		VI_LOCK(vp);
+		if ((node->tn_type == VDIR && node->tn_dir.tn_parent == NULL) ||
+		    ((vp->v_iflag & VI_DOOMED) != 0 &&
+		    (lkflag & LK_NOWAIT) != 0)) {
+			VI_UNLOCK(vp);
+			TMPFS_NODE_UNLOCK(node);
+			error = ENOENT;
+			vp = NULL;
+			goto out;
+		}
+		if ((vp->v_iflag & VI_DOOMED) != 0) {
+			VI_UNLOCK(vp);
+			node->tn_vpstate |= TMPFS_VNODE_WRECLAIM;
+			while ((node->tn_vpstate & TMPFS_VNODE_WRECLAIM) != 0) {
+				msleep(&node->tn_vnode, TMPFS_NODE_MTX(node),
+				    0, "tmpfsE", 0);
+			}
+			goto loop1;
+		}
 		TMPFS_NODE_UNLOCK(node);
 		error = vget(vp, lkflag | LK_INTERLOCK, curthread);
+		if (error == ENOENT)
+			goto loop;
 		if (error != 0) {
 			vp = NULL;
 			goto out;
@@ -519,6 +540,9 @@ tmpfs_free_vp(struct vnode *vp)
 
 	mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED);
 	node->tn_vnode = NULL;
+	if ((node->tn_vpstate & TMPFS_VNODE_WRECLAIM) != 0)
+		wakeup(&node->tn_vnode);
+	node->tn_vpstate &= ~TMPFS_VNODE_WRECLAIM;
 	vp->v_data = NULL;
 }
 


More information about the svn-src-stable-9 mailing list