summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-04-10 15:38:06 +0000
committerMiles Bader <miles@gnu.org>1995-04-10 15:38:06 +0000
commitd01609ce36ab387b355c4199d53c5c6675472f57 (patch)
tree339a75927f0e4c91dbe309a20a7939877341d5a8
parentadbfecb7eb8ffaeed92f26cfabca301fae5391eb (diff)
(main, check_open_hook, close_device, trivfs_goaway): Add a new lock,
device_lock, and use it to control access to the DEVICE variable. (open_hook, trivfs_modify_stat, trivfs_S_fys_syncfs): Copy DEVICE before using it, so it doesn't change underneath us. (clean_exit): Add a new argument that says whether to aquire a lock before doing our work. (ports_notice_idle, ports_no_live_ports): Use it. (close_device): New function, closes DEVICE cleanly. (clean_exit, ports_no_hard_ports): Use close_device. (main): Use trivfs_startup instead of doing it manually. (trivfs_goaway): Try and do it better, paying attention to flags, etc.; this still isn't right though, we may want to wait for the ports library to be fixed first. (DEBUG): New macro, executes its arg with debug_lock locked.
-rw-r--r--devio/devio.c205
1 files changed, 81 insertions, 124 deletions
diff --git a/devio/devio.c b/devio/devio.c
index 05343b7e..deeebf7e 100644
--- a/devio/devio.c
+++ b/devio/devio.c
@@ -33,6 +33,16 @@
#include "open.h"
#include "dev.h"
#include "ptypes.h"
+
+#ifdef MSG
+#define DEBUG(what) \
+ ((debug) \
+ ? ({ mutex_lock(&debug_lock); what; mutex_unlock(&debug_lock);0;}) \
+ : 0)
+#else
+#define DEBUG(what) 0
+#endif
+
/* ---------------------------------------------------------------- */
@@ -88,6 +98,8 @@ static struct option options[] =
/* A struct dev for the open kernel device. */
static struct dev *device = NULL;
+/* And a lock to arbitrate changes to it. */
+static struct mutex device_lock;
/* Desired device parameters specified by the user. */
static char *device_name = NULL;
@@ -104,11 +116,9 @@ struct mutex debug_lock;
void main(int argc, char *argv[])
{
+ int opt;
error_t err;
mach_port_t bootstrap;
- int opt;
- struct trivfs_control *trivfs_control;
- mach_port_t realnode, control;
while ((opt = getopt_long(argc, argv, SHORT_OPTIONS, options, 0)) != EOF)
switch (opt)
@@ -138,25 +148,18 @@ void main(int argc, char *argv[])
device_name = argv[optind];
- _libports_initialize();
-
task_get_bootstrap_port (mach_task_self (), &bootstrap);
if (bootstrap == MACH_PORT_NULL)
error(2, 0, "Must be started as a translator");
/* Reply to our parent */
- control = trivfs_handle_port (MACH_PORT_NULL, PT_FSYS, PT_NODE);
- err = fsys_startup (bootstrap, control, MACH_MSG_TYPE_MAKE_SEND, &realnode);
-
- /* Install the returned realnode for trivfs's use */
- trivfs_control = ports_check_port_type (control, PT_FSYS);
- assert (trivfs_control);
- ports_change_hardsoft (trivfs_control, 1);
- trivfs_control->underlying = realnode;
- ports_done_with_port (trivfs_control);
+ err = trivfs_startup(bootstrap, PT_FSYS, PT_NODE, NULL);
+ if (err)
+ error(3, err, "Contacting parent");
/* Open the device only when necessary. */
device = NULL;
+ mutex_init(&device_lock);
/* Launch. */
ports_manage_port_operations_multithread ();
@@ -175,6 +178,7 @@ check_open_hook (struct trivfs_control *trivfs_control,
{
error_t err = 0;
+ mutex_lock(&device_lock);
if (device == NULL)
/* Try and open the device. */
{
@@ -186,6 +190,7 @@ check_open_hook (struct trivfs_control *trivfs_control,
error, as this allows stat to word correctly. XXX */
err = 0;
}
+ mutex_unlock(&device_lock);
return err;
}
@@ -193,8 +198,9 @@ check_open_hook (struct trivfs_control *trivfs_control,
static void
open_hook(struct trivfs_peropen *peropen)
{
- if (device)
- open_create(device, (struct open **)&peropen->hook);
+ struct dev *dev = device;
+ if (dev)
+ open_create(dev, (struct open **)&peropen->hook);
}
static void
@@ -205,38 +211,34 @@ close_hook(struct trivfs_peropen *peropen)
}
static void
-clean_exit(int status)
+close_device(int aquire_lock)
{
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "cleaning up and exiting (status = %d)...\n", status);
- mutex_unlock(&debug_lock);
- }
-#endif
+ DEBUG(fprintf(debug, "Closing device\n"));
+ if (aquire_lock)
+ mutex_lock(&device_lock);
if (device)
{
dev_close(device);
device = NULL;
}
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "Bye!\n");
- fclose(debug);
- debug = NULL;
- mutex_unlock(&debug_lock);
- }
-#endif
+ if (aquire_lock)
+ mutex_unlock(&device_lock);
+}
+
+static void
+clean_exit(int status, int aquire_lock)
+{
+ DEBUG(fprintf(debug, "Cleaning up and exiting (status = %d)...\n", status));
+ close_device(aquire_lock);
+ DEBUG({fprintf(debug, "Bye!\n"); fclose(debug); debug = NULL;});
+ exit(0);
}
/* ---------------------------------------------------------------- */
/* Trivfs hooks */
int trivfs_fstype = FSTYPE_DEV;
-int trivfs_fsid = 0; /* ??? */
+int trivfs_fsid = 0;
int trivfs_support_read = 1;
int trivfs_support_write = 1;
@@ -252,21 +254,23 @@ int trivfs_cntl_nporttypes = 1;
void
trivfs_modify_stat (struct stat *st)
{
- if (device)
+ struct dev *dev = device;
+
+ if (dev)
{
- vm_size_t size = device->size;
+ vm_size_t size = dev->size;
- if (device->block_size > 1)
- st->st_blksize = device->block_size;
+ if (dev->block_size > 1)
+ st->st_blksize = dev->block_size;
st->st_size = size;
st->st_blocks = size / 512;
- if (dev_is(device, DEV_READONLY))
+ if (dev_is(dev, DEV_READONLY))
st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
st->st_mode &= ~S_IFMT;
- st->st_mode |= dev_is(device, DEV_BUFFERED) ? S_IFBLK : S_IFCHR;
+ st->st_mode |= dev_is(dev, DEV_BUFFERED) ? S_IFBLK : S_IFCHR;
}
else
/* Try and do things without an open device... */
@@ -280,31 +284,27 @@ trivfs_modify_stat (struct stat *st)
st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
- st->st_fstype = FSTYPE_DEV;
st->st_rdev = device_number;
}
error_t
trivfs_goaway (int flags, mach_port_t realnode, int ctltype, int pitype)
{
- if (device != NULL && !(flags & FSYS_GOAWAY_FORCE))
- /* By default, don't go away if there are still opens on this device. */
- return EBUSY;
-
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "trivfs_goaway(0x%x, %d, %d, %d)\n",
- flags, realnode, ctltype, pitype);
- mutex_unlock(&debug_lock);
- }
-#endif
-
- if (flags & FSYS_GOAWAY_NOSYNC)
- exit(0);
- else
- clean_exit(0);
+ DEBUG(fprintf(debug, "trivfs_goaway(0x%x, %d, %d, %d)\n",
+ flags, realnode, ctltype, pitype));
+
+ mutex_lock(&device_lock);
+ if (device == NULL || (flags & FSYS_GOAWAY_FORCE))
+ /* Go away immediately. */
+ if (flags & FSYS_GOAWAY_NOSYNC)
+ /* Don't clean up. */
+ exit(0);
+ else
+ clean_exit(0, FALSE);
+ mutex_lock(&device_lock);
+
+ /* Complain that there are still users. */
+ return EBUSY;
}
/* If this variable is set, it is called every time an open happens.
@@ -335,16 +335,12 @@ trivfs_S_fsys_syncfs (struct trivfs_control *cntl,
mach_port_t reply, mach_msg_type_name_t replytype,
int wait, int dochildren)
{
-#ifdef MSG
- if (debug && device)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "syncing filesystem...\n");
- mutex_unlock(&debug_lock);
- }
-#endif
- if (device)
- return dev_sync(device, wait);
+ struct dev *dev = device;
+
+ DEBUG(fprintf(debug, "Syncing filesystem...\n"));
+
+ if (dev)
+ return dev_sync(dev, wait);
else
return 0;
}
@@ -361,32 +357,20 @@ void (*ports_cleanroutines[])(void *) =
int
ports_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
- error_t err;
+ int ok;
#ifdef MSG
static int next_msg_num = 0;
int msg_num;
-
- if (debug)
- {
- mutex_lock(&debug_lock);
- msg_num = next_msg_num++;
- fprintf(debug, "port_demuxer(%d) [%d]\n", inp->msgh_id, msg_num);
- mutex_unlock(&debug_lock);
- }
#endif
- err = pager_demuxer(inp, outp) || trivfs_demuxer(inp, outp);
+ DEBUG(msg_num = next_msg_num++;
+ fprintf(debug, "port_demuxer(%d) [%d]\n", inp->msgh_id, msg_num););
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "port_demuxer(%d) [%d] done!\n", inp->msgh_id, msg_num);
- mutex_unlock(&debug_lock);
- }
-#endif
+ ok = pager_demuxer(inp, outp) || trivfs_demuxer(inp, outp);
- return err;
+ DEBUG(fprintf(debug, "port_demuxer(%d) [%d] done!\n", inp->msgh_id,msg_num));
+
+ return ok;
}
/* This will be called whenever there have been no requests to the server for
@@ -397,17 +381,9 @@ ports_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
void
ports_notice_idle (int nhard, int nsoft)
{
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "ports_notice_idle(%d, %d)\n", nhard, nsoft);
- mutex_unlock(&debug_lock);
- }
- else
-#endif
- if (nhard == 0)
- clean_exit(0);
+ DEBUG(fprintf(debug, "ports_notice_idle(%d, %d)\n", nhard, nsoft));
+ if (nhard == 0)
+ clean_exit(0, TRUE);
}
/* This will be called whenever there are no hard ports or soft ports
@@ -416,16 +392,8 @@ ports_notice_idle (int nhard, int nsoft)
void
ports_no_live_ports ()
{
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "ports_no_live_ports()\n");
- mutex_unlock(&debug_lock);
- }
- else
-#endif
- clean_exit(0);
+ DEBUG(fprintf(debug, "ports_no_live_ports()\n"));
+ clean_exit(0, TRUE);
}
/* This will be called whenever there are no hard ports allocated but there
@@ -435,17 +403,6 @@ ports_no_live_ports ()
void
ports_no_hard_ports ()
{
-#ifdef MSG
- if (debug)
- {
- mutex_lock(&debug_lock);
- fprintf(debug, "ports_no_hard_ports()\n");
- mutex_unlock(&debug_lock);
- }
-#endif
- if (device != NULL)
- {
- dev_close(device);
- device = NULL;
- }
+ DEBUG(fprintf(debug, "ports_no_hard_ports()\n"));
+ close_device(TRUE);
}