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;
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to