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