summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-05-07 00:13:38 +0000
committerMiles Bader <miles@gnu.org>1996-05-07 00:13:38 +0000
commitd031fe3d6e92f3effd0ea64df9dbd896228f237d (patch)
tree985ff845f090d1ed565758602169c77375dabade
parent0978efca18269d4326a35f351928fb9fefabfed7 (diff)
(diskfs_get_file_device): Rewrite to use new interface.
-rw-r--r--libdiskfs/filedev.c111
1 files changed, 69 insertions, 42 deletions
diff --git a/libdiskfs/filedev.c b/libdiskfs/filedev.c
index 5a3e752d..ab600e8c 100644
--- a/libdiskfs/filedev.c
+++ b/libdiskfs/filedev.c
@@ -1,6 +1,6 @@
/* Get the mach device underlying a file
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -25,8 +25,6 @@
#include "priv.h"
-typedef int run_elem_t;
-
/* Returns the name and a send right for the mach device on which the file
NAME is stored, and returns it in DEV_NAME (which is malloced) and PORT.
Other values returned are START, the first valid offset, SIZE, the the
@@ -40,12 +38,14 @@ diskfs_get_file_device (char *name,
char **dev_name, mach_port_t *port,
off_t *start, off_t *size, size_t *block_size)
{
+ int i;
error_t err;
- int class, flags;
- char *misc = 0;
- off_t *runs = 0;
- mach_msg_type_number_t misc_len = 0, runs_len = 0;
- string_t dev_name_buf;
+ mach_msg_type_number_t data_len = 100;
+ mach_msg_type_number_t num_ints = 10, num_ports = 10, num_offsets = 10;
+ int _ints[num_ints], *ints = _ints;
+ mach_port_t _ports[num_ports], *ports = _ports;
+ off_t _offsets[num_offsets], *offsets = _offsets;
+ char *_data[data_len], **data = _data;
file_t node =
file_name_lookup (name, diskfs_readonly ? O_RDONLY : O_RDWR, 0);
@@ -54,54 +54,81 @@ diskfs_get_file_device (char *name,
*port = MACH_PORT_NULL;
- err = file_get_storage_info (node, &class, &runs, &runs_len, block_size,
- dev_name_buf, port, &misc, &misc_len, &flags);
+ err = file_get_storage_info (node, &ports, &num_ports, &ints, &num_ints,
+ &offsets, &num_offsets, &data, &data_len);
if (err)
- goto done;
+ return err;
+
+ /* See <hurd/store.h> for an explanation of what's in the vectors returned
+ by file_get_storage_info. */
+
+ if (num_ints < 6)
+ err = EGRATUITOUS;
+ else if (ints[0] != STORAGE_DEVICE)
+ err = ENODEV;
+
+ if (!err && blocksize)
+ *block_size = ints[2];
- if (class != STORAGE_DEVICE)
+ if (!err && port)
+ /* Extract the device port. */
+ if (num_ports != 1)
+ err = EGRATUITOUS;
+ else
+ *port = ports[0];
+
+ if (!err && dev_name)
+ /* Extract the device name into DEV_NAME. */
{
- err = ENODEV;
- goto done;
+ size_t name_len = ints[4];
+ if (data && name_len > 0)
+ if (data_len < name_len)
+ err = EGRATUITOUS;
+ else
+ {
+ *dev_name = malloc (name_len);
+ if (*dev_name)
+ strcpy (*dev_name, dev_name_buf);
+ else
+ err = ENOMEM;
+ }
}
- if (dev_name)
+ if (!err && (start || size))
+ /* Extract the device block addresses. */
{
- *dev_name = malloc (strlen (dev_name_buf) + 1);
- if (*dev_name)
- strcpy (*dev_name, dev_name_buf);
+ size_t runs_len = ints[3];
+ if (runs_len != 2)
+ /* We can't handle anything but a contiguous set of blocks. */
+ err = ENODEV; /* XXX */
else
- err = ENOMEM;
+ {
+ if (start)
+ *start = offsets[0];
+ if (size)
+ *size = offsets[1];
+ }
}
- if (start || size)
- if (runs_len > 2)
- /* We can't handle anything but a contiguous set of blocks. */
- err = ENODEV; /* XXX */
- else
- {
- if (start)
- *start = runs[0];
- if (size)
- *size = runs[1];
- }
-
- /* Note that we don't deallocate NODE, which should prevent the information
- returned by file_get_storage_info from changing. */
+ /* Note that we don't deallocate NODE unless we're returning an error,
+ which should prevent the information returned by file_get_storage_info
+ from changing. */
- done:
if (err)
+ /* We got an error, so deallocate everything we got back from the device. */
{
+ for (i = 0; i < num_ports; i++)
+ if (MACH_PORT_VALID (ports[i]))
+ mach_port_deallocate (mach_task_self (), ports[i]);
+#define DISCARD_MEM(v, vl, b) \
+ if (v != b) \
+ vm_deallocate (mach_task_self (), (vm_address_t)v, vl * sizeof *v);
+ DISCARD_MEM (ports, num_ports, _ports);
+ DISCARD_MEM (ints, num_ints, _ints);
+ DISCARD_MEM (offsets, num_offsets, _offsets);
+ DISCARD_MEM (data, data_len, _data);
mach_port_deallocate (mach_task_self (), node);
- if (*port)
- mach_port_deallocate (mach_task_self (), *port);
}
- if (misc_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t)misc, misc_len);
- if (runs_len > 0)
- vm_deallocate (mach_task_self (),
- (vm_address_t)runs, runs_len * sizeof (*runs));
-
return err;
}