summaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-04-05 00:32:43 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-04-05 00:32:43 +0000
commit5360e84d14494a6bc105edca255dcd3afe327848 (patch)
treeb6af7f9797a8575c0427ce2aa154048884fb4022 /libdiskfs
parent439dd44986de2e445365c27fa03a49534c344816 (diff)
(diskfs_S_dir_rmdir): Do fsys_goaway for translated nodes being
unlinked.
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/dir-rmdir.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/libdiskfs/dir-rmdir.c b/libdiskfs/dir-rmdir.c
index 959864e4..5dc6a854 100644
--- a/libdiskfs/dir-rmdir.c
+++ b/libdiskfs/dir-rmdir.c
@@ -17,6 +17,7 @@
#include "priv.h"
#include "fs_S.h"
+#include <hurd/fsys.h>
/* Implement dir_rmdir as described in <hurd/fs.defs>. */
kern_return_t
@@ -35,6 +36,8 @@ diskfs_S_dir_rmdir (struct protid *dircred,
if (diskfs_readonly)
return EROFS;
+ retry:
+
mutex_lock (&dnp->lock);
error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred);
@@ -56,6 +59,41 @@ diskfs_S_dir_rmdir (struct protid *dircred,
return EINVAL;
}
+ mutex_lock (&np->translator.lock);
+ if (np->translator.control != MACH_PORT_NULL)
+ {
+ mach_port_t control;
+
+ /* There is a running active translator here. Give it a push.
+ If it squeaks, then return an error. If it consents, then
+ clear the active translator spec (unless it's been changed
+ in the interim) and repeat the lookup above. */
+
+ control = np->translator.control;
+ mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1);
+
+ mutex_unlock (&np->translator.lock);
+ diskfs_drop_dirstat (dnp, ds);
+ mutex_unlock (&dnp->lock);
+ mutex_unlock (&np->lock);
+
+ error = fsys_goaway (control, FSYS_GOAWAY_UNLINK);
+ if (error)
+ return error;
+
+ mutex_lock (&np->lock);
+ mutex_lock (&np->translator.lock);
+ if (np->translator.control == control)
+ fshelp_translator_drop (&np->translator);
+ mutex_unlock (&np->translator.lock);
+ diskfs_nput (np);
+
+ mach_port_deallocate (mach_task_self (), control);
+
+ goto retry;
+ }
+ mutex_unlock (&np->translator.lock);
+
/* Verify the directory is empty (and valid). (Rmdir ".." won't be
valid since ".." will contain a reference to the current directory and
thus be non-empty). */