summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-10-19 19:54:23 +0000
committerMiles Bader <miles@gnu.org>1995-10-19 19:54:23 +0000
commite0d9406ea123ab78f4750856e298f18814a2a124 (patch)
tree7681f4ab283b1cfd1d44f99448e95f3d5734619e
parent4d306c0d3ba310ea97a60966de789900bb499c21 (diff)
(diskfs_S_fsys_set_options):
Hold DISKFS_FSYS_LOCK for writing while setting our own options, and for reading while setting our children's. Dereference PT even when a child filesystem returns an error.
-rw-r--r--libdiskfs/fsys-options.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/libdiskfs/fsys-options.c b/libdiskfs/fsys-options.c
index b2026bc5..a02ed78d 100644
--- a/libdiskfs/fsys-options.c
+++ b/libdiskfs/fsys-options.c
@@ -33,11 +33,10 @@ diskfs_S_fsys_set_options (fsys_t fsys,
char *data, mach_msg_type_number_t len,
int do_children)
{
- int argc = argz_count (data, len);
- char **argv = alloca (sizeof (char *) * (argc + 1));
- struct port_info *pt = ports_lookup_port (diskfs_port_bucket, fsys,
- diskfs_control_class);
- int ret;
+ error_t err = 0;
+ struct port_info *pt =
+ ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);
+
error_t
helper (struct node *np)
{
@@ -65,15 +64,23 @@ diskfs_S_fsys_set_options (fsys_t fsys,
if (do_children)
{
- ret = diskfs_node_iterate (helper);
- if (ret)
- return ret;
+ rwlock_reader_lock (&diskfs_fsys_lock);
+ err = diskfs_node_iterate (helper);
+ rwlock_writer_unlock (&diskfs_fsys_lock);
}
- argz_extract (data, len, argv);
+ if (!err)
+ {
+ int argc = argz_count (data, len);
+ char **argv = alloca (sizeof (char *) * (argc + 1));
+
+ argz_extract (data, len, argv);
- ret = diskfs_set_options (argc, argv);
+ rwlock_writer_lock (&diskfs_fsys_lock);
+ err = diskfs_set_options (argc, argv);
+ rwlock_writer_unlock (&diskfs_fsys_lock);
+ }
ports_port_deref (pt);
- return ret;
+ return err;
}