summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstore/device.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/libstore/device.c b/libstore/device.c
index e42274f9..9036699f 100644
--- a/libstore/device.c
+++ b/libstore/device.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <hurd.h>
#include "store.h"
@@ -54,13 +55,25 @@ dev_write (struct store *store,
return device_write (store->port, 0, addr, (io_buf_ptr_t)buf, len, amount);
}
-static struct store_meths
-device_meths = {dev_read, dev_write};
+static error_t
+dev_decode (struct store_enc *enc, struct store_class *classes,
+ struct store **store)
+{
+ return store_std_leaf_decode (enc, _store_device_create, store);
+}
+
+static struct store_class
+dev_class =
+{
+ STORAGE_DEVICE, "device", dev_read, dev_write,
+ store_std_leaf_allocate_encoding, store_std_leaf_encode, dev_decode
+};
+_STORE_STD_CLASS (dev_class);
/* Return a new store in STORE referring to the mach device DEVICE. Consumes
the send right DEVICE. */
error_t
-store_device_create (device_t device, struct store **store)
+store_device_create (device_t device, int flags, struct store **store)
{
struct store_run run;
size_t sizes[DEV_GET_SIZE_COUNT], block_size;
@@ -76,16 +89,40 @@ store_device_create (device_t device, struct store **store)
run.start = 0;
run.length = sizes[DEV_GET_SIZE_DEVICE_SIZE] / block_size;
- return _store_device_create (device, block_size, &run, 1, store);
+ flags |= STORE_ENFORCED; /* 'cause it's the whole device. */
+
+ return _store_device_create (device, flags, block_size, &run, 1, store);
}
/* Like store_device_create, but doesn't query the device for information. */
error_t
-_store_device_create (device_t device, size_t block_size,
+_store_device_create (device_t device, int flags, size_t block_size,
const struct store_run *runs, size_t num_runs,
struct store **store)
{
- *store = _make_store (STORAGE_DEVICE, &device_meths, device, block_size,
- runs, num_runs, 0);
+ *store =
+ _make_store (&dev_class, device, flags, block_size, runs, num_runs, 0);
return *store ? 0 : ENOMEM;
}
+
+/* Open the device NAME, and return the corresponding store in STORE. */
+error_t
+store_device_open (const char *name, int flags, struct store **store)
+{
+ device_t dev_master, device;
+ int open_flags = ((flags & STORE_HARD_READONLY) ? 0 : D_WRITE) | D_READ;
+ error_t err = get_privileged_ports (0, &dev_master);
+
+ if (err)
+ return err;
+
+ err = device_open (dev_master, open_flags, (char *)name, &device);
+
+ mach_port_deallocate (mach_task_self (), dev_master);
+
+ err = store_device_create (device, flags, store);
+ if (err)
+ mach_port_deallocate (mach_task_self (), device);
+
+ return err;
+}