diff options
Diffstat (limited to 'libstore/stripe.c')
-rw-r--r-- | libstore/stripe.c | 145 |
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; } |