Source-Changes-HG archive

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

[src/trunk]: src/sys/fs/udf On removing a directory make sure the leaf direct...



details:   https://anonhg.NetBSD.org/src/rev/f45f34fd2a2b
branches:  trunk
changeset: 787784:f45f34fd2a2b
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Wed Jul 03 14:35:28 2013 +0000

description:
On removing a directory make sure the leaf directory doesn't have a valid '..'
link anymore. In a corner case this leaf can be held by a process as a CWD. It
is guaranteed to be empty at this stage so we trunc it removing the only valid
FID, being the '..' entry.

Solves part of PR kern/47987
Solves tests/vfs/t_vnops udf_dir_rmdirdotdot

diffstat:

 sys/fs/udf/udf_vnops.c |  19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diffs (58 lines):

diff -r e7c2ef7dfc06 -r f45f34fd2a2b sys/fs/udf/udf_vnops.c
--- a/sys/fs/udf/udf_vnops.c    Wed Jul 03 14:29:28 2013 +0000
+++ b/sys/fs/udf/udf_vnops.c    Wed Jul 03 14:35:28 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.77 2013/07/03 12:55:34 reinoud Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.78 2013/07/03 14:35:28 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.77 2013/07/03 12:55:34 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.78 2013/07/03 14:35:28 reinoud Exp $");
 #endif /* not lint */
 
 
@@ -58,6 +58,8 @@
 
 #include <fs/udf/ecma167-udf.h>
 #include <fs/udf/udf_mount.h>
+#include <sys/dirhash.h>
+
 #include "udf.h"
 #include "udf_subr.h"
 #include "udf_bswap.h"
@@ -2166,7 +2168,7 @@
        struct udf_mount *ump = dir_node->ump;
        int refcnt, error;
 
-       DPRINTF(NOTIMPL, ("udf_rmdir called\n"));
+       DPRINTF(NOTIMPL, ("udf_rmdir '%s' called\n", cnp->cn_nameptr));
 
        /* don't allow '.' to be deleted */
        if (dir_node == udf_node) {
@@ -2189,11 +2191,20 @@
                return ENOTEMPTY;
        }
 
-       /* detach the node from the directory */
+       /* detach the node from the directory, udf_node is an empty dir here */
        error = udf_dir_detach(ump, dir_node, udf_node, cnp);
        if (error == 0) {
                cache_purge(vp);
 //             cache_purge(dvp);       /* XXX from msdosfs, why? */
+               /*
+                * Bug alert: we need to remove '..' from the detaching
+                * udf_node so further lookups of this are not possible. This
+                * prevents a process in a deleted directory from going to its
+                * deleted parent. Since `udf_node' is garanteed to be empty
+                * here, trunc it so no fids are there.
+                */
+               dirhash_purge(&udf_node->dir_hash);
+               udf_shrink_node(udf_node, 0);
                VN_KNOTE(vp, NOTE_DELETE);
        }
        DPRINTFIF(NODE, error, ("\tgot error removing dir\n"));



Home | Main Index | Thread Index | Old Index