aboutsummaryrefslogtreecommitdiff
path: root/libstore/stripe.c
diff options
context:
space:
mode:
Diffstat (limited to 'libstore/stripe.c')
-rw-r--r--libstore/stripe.c145
1 files changed, 100 insertions, 45 deletions
diff --git a/libstore/stripe.c b/libstore/stripe.c
index 055c548f..e9c58466 100644
--- a/libstore/stripe.c
+++ b/libstore/stripe.c
@@ -1,9 +1,7 @@
/* Striped store backend
- Copyright (C) 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
-
+ Copyright (C) 1996,97,99,2001, 2002 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
The GNU Hurd is free software; you can redistribute it and/or
@@ -18,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include <stdlib.h>
#include <string.h>
@@ -29,8 +27,8 @@ extern long lcm (long p, long q);
/* Return ADDR adjust for any block size difference between STORE and
STRIPE. We assume that STORE's block size is no less than STRIPE's. */
-static inline off_t
-addr_adj (off_t addr, struct store *store, struct store *stripe)
+static inline store_offset_t
+addr_adj (store_offset_t addr, struct store *store, struct store *stripe)
{
unsigned common_bs = store->log2_block_size;
unsigned stripe_bs = stripe->log2_block_size;
@@ -42,8 +40,8 @@ addr_adj (off_t addr, struct store *store, struct store *stripe)
static error_t
stripe_read (struct store *store,
- off_t addr, size_t index, mach_msg_type_number_t amount,
- char **buf, mach_msg_type_number_t *len)
+ store_offset_t addr, size_t index, size_t amount,
+ void **buf, size_t *len)
{
struct store *stripe = store->children[index];
return store_read (stripe, addr_adj (addr, store, stripe), amount, buf, len);
@@ -51,13 +49,27 @@ stripe_read (struct store *store,
static error_t
stripe_write (struct store *store,
- off_t addr, size_t index, char *buf, mach_msg_type_number_t len,
- mach_msg_type_number_t *amount)
+ store_offset_t addr, size_t index,
+ const void *buf, size_t len, size_t *amount)
{
struct store *stripe = store->children[index];
return
store_write (stripe, addr_adj (addr, store, stripe), buf, len, amount);
}
+
+error_t
+stripe_set_size (struct store *store, size_t newsize)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+stripe_remap (struct store *source,
+ const struct store_run *runs, size_t num_runs,
+ struct store **store)
+{
+ return store_remap_create (source, runs, num_runs, 0, store);
+}
error_t
ileave_allocate_encoding (const struct store *store, struct store_enc *enc)
@@ -77,14 +89,14 @@ ileave_encode (const struct store *store, struct store_enc *enc)
}
error_t
-ileave_decode (struct store_enc *enc, struct store_class *classes,
+ileave_decode (struct store_enc *enc, const struct store_class *const *classes,
struct store **store)
{
if (enc->cur_int + 4 > enc->num_ints)
return EINVAL;
else
{
- int type = enc->ints[enc->cur_int++];
+ int type __attribute__((unused)) = enc->ints[enc->cur_int++];
int flags = enc->ints[enc->cur_int++];
int interleave = enc->ints[enc->cur_int++];
int nkids = enc->ints[enc->cur_int++];
@@ -96,13 +108,14 @@ ileave_decode (struct store_enc *enc, struct store_class *classes,
}
}
-static struct store_class
-ileave_class =
+const struct store_class
+store_ileave_class =
{
- STORAGE_INTERLEAVE, "interleave", stripe_read, stripe_write,
+ STORAGE_INTERLEAVE, "interleave", stripe_read, stripe_write, stripe_set_size,
ileave_allocate_encoding, ileave_encode, ileave_decode,
+ store_set_child_flags, store_clear_child_flags, 0, 0, stripe_remap
};
-_STORE_STD_CLASS (ileave_class);
+STORE_STD_CLASS (ileave);
error_t
concat_allocate_encoding (const struct store *store, struct store_enc *enc)
@@ -121,14 +134,14 @@ concat_encode (const struct store *store, struct store_enc *enc)
}
error_t
-concat_decode (struct store_enc *enc, struct store_class *classes,
+concat_decode (struct store_enc *enc, const struct store_class *const *classes,
struct store **store)
{
if (enc->cur_int + 3 > enc->num_ints)
return EINVAL;
else
{
- int type = enc->ints[enc->cur_int++];
+ int type __attribute__((unused)) = enc->ints[enc->cur_int++];
int flags = enc->ints[enc->cur_int++];
int nkids = enc->ints[enc->cur_int++];
struct store *kids[nkids];
@@ -139,13 +152,15 @@ concat_decode (struct store_enc *enc, struct store_class *classes,
}
}
-static struct store_class
-concat_class =
+const struct store_class
+store_concat_class =
{
- STORAGE_CONCAT, "concat", stripe_read, stripe_write,
- concat_allocate_encoding, concat_encode, concat_decode
+ STORAGE_CONCAT, "concat", stripe_read, stripe_write, stripe_set_size,
+ concat_allocate_encoding, concat_encode, concat_decode,
+ store_set_child_flags, store_clear_child_flags, 0, 0, stripe_remap,
+ store_concat_open
};
-_STORE_STD_CLASS (concat_class);
+STORE_STD_CLASS (concat);
/* Return a new store in STORE that interleaves all the stores in STRIPES
(NUM_STRIPES of them) every INTERLEAVE bytes; INTERLEAVE must be an
@@ -154,12 +169,15 @@ _STORE_STD_CLASS (concat_class);
*array* STRIPES is copied, and so should be freed by the caller). */
error_t
store_ileave_create (struct store *const *stripes, size_t num_stripes,
- off_t interleave, int flags, struct store **store)
+ store_offset_t interleave, int flags,
+ struct store **store)
{
size_t i;
error_t err;
- off_t block_size = 1, min_end = 0;
+ size_t block_size = 1;
+ store_offset_t min_end = 0;
struct store_run runs[num_stripes];
+ int common_flags = STORE_BACKEND_FLAGS;
/* Find a common block size. */
for (i = 0; i < num_stripes; i++)
@@ -173,31 +191,34 @@ store_ileave_create (struct store *const *stripes, size_t num_stripes,
for (i = 0; i < num_stripes; i++)
{
/* The stripe's end adjusted to the common block size. */
- off_t end = stripes[i]->end;
+ store_offset_t end = stripes[i]->end;
runs[i].start = 0;
runs[i].length = interleave;
if (stripes[i]->block_size != block_size)
end /= (block_size / stripes[i]->block_size);
-
+
if (min_end < 0)
min_end = end;
else if (min_end > end)
/* Only use as much space as the smallest stripe has. */
min_end = end;
- }
- *store = _make_store (&ileave_class, MACH_PORT_NULL, flags, block_size,
- runs, num_stripes, min_end);
- if (! *store)
- return ENOMEM;
+ common_flags &= stripes[i]->flags;
+ }
- (*store)->wrap_dst = interleave;
+ err = _store_create (&store_ileave_class, MACH_PORT_NULL,
+ common_flags | flags, block_size,
+ runs, num_stripes, min_end, store);
+ if (! err)
+ {
+ (*store)->wrap_dst = interleave;
- err = store_set_children (*store, stripes, num_stripes);
- if (err)
- store_free (*store);
+ err = store_set_children (*store, stripes, num_stripes);
+ if (err)
+ store_free (*store);
+ }
return err;
}
@@ -212,7 +233,8 @@ store_concat_create (struct store * const *stores, size_t num_stores,
{
size_t i;
error_t err;
- off_t block_size = 1;
+ size_t block_size = 1;
+ int common_flags = STORE_BACKEND_FLAGS;
struct store_run runs[num_stores];
/* Find a common block size. */
@@ -223,16 +245,49 @@ store_concat_create (struct store * const *stores, size_t num_stores,
{
runs[i].start = 0;
runs[i].length = stores[i]->end;
+ common_flags &= stores[i]->flags;
}
- *store = _make_store (&concat_class, MACH_PORT_NULL, flags, block_size,
- runs, num_stores * 2, 0);
- if (! *store)
- return ENOMEM;
+ err = _store_create (&store_concat_class, MACH_PORT_NULL,
+ flags | common_flags, block_size,
+ runs, num_stores, 0, store);
+ if (! err)
+ {
+ err = store_set_children (*store, stores, num_stores);
+ if (! err)
+ {
+ err = store_children_name (*store, &(*store)->name);
+ if (err == EINVAL)
+ err = 0; /* Can't find a name; deal. */
+ }
+ if (err)
+ store_free (*store);
+ }
- err = store_set_children (*store, stores, num_stores);
- if (err)
- store_free (*store);
+ return err;
+}
+/* Return a new store that concatenates the stores created by opening all the
+ individual stores described in NAME; for the syntax of NAME, see
+ store_open_children. */
+error_t
+store_concat_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store)
+{
+ struct store **stores;
+ size_t num_stores;
+ error_t err =
+ store_open_children (name, flags, classes, &stores, &num_stores);
+ if (! err)
+ {
+ err = store_concat_create (stores, num_stores, flags, store);
+ if (err)
+ {
+ size_t k;
+ for (k = 0; k < (*store)->num_children; k++)
+ store_free ((*store)->children[k]);
+ }
+ }
return err;
}