Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/fs/tmpfs Check tmpfs_rmdired_p after tmpfs_vnode_get whe...



details:   https://anonhg.NetBSD.org/src/rev/2fca19ba7d87
branches:  trunk
changeset: 781721:2fca19ba7d87
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Sep 25 16:11:42 2012 +0000

description:
Check tmpfs_rmdired_p after tmpfs_vnode_get when walking up the tree.

tmpfs_vnode_get drops all locks except possibly the reclaiming bit
lock to keep the tmpfs node from being reclaimed while we're still
interested in it.  Consequently, it does not keep the directory's
existence invariant, so we must check that after tmpfs_vnode_get.

Fixes PR kern/46990.  Tested by Wolfgang Stukenbrock.

diffstat:

 sys/fs/tmpfs/tmpfs_rename.c |  15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diffs (36 lines):

diff -r d18fc5f57189 -r 2fca19ba7d87 sys/fs/tmpfs/tmpfs_rename.c
--- a/sys/fs/tmpfs/tmpfs_rename.c       Tue Sep 25 14:16:27 2012 +0000
+++ b/sys/fs/tmpfs/tmpfs_rename.c       Tue Sep 25 16:11:42 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_rename.c,v 1.2 2012/05/09 22:46:25 riastradh Exp $       */
+/*     $NetBSD: tmpfs_rename.c,v 1.3 2012/09/25 16:11:42 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.2 2012/05/09 22:46:25 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.3 2012/09/25 16:11:42 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -551,6 +551,17 @@
                error = tmpfs_vnode_get(mp, dnode, &vp);
                if (error)
                        return error;
+
+               /*
+                * tmpfs_vnode_get only guarantees that dnode will not
+                * be freed while we get a vnode for it.  It does not
+                * preserve any other invariants, so we must check
+                * whether the parent has been removed in the meantime.
+                */
+               if (tmpfs_rmdired_p(vp)) {
+                       vput(vp);
+                       return ENOENT;
+               }
        }
 }
 



Home | Main Index | Thread Index | Old Index