diff options
-rw-r--r-- | libstore/store.h | 230 |
1 files changed, 161 insertions, 69 deletions
diff --git a/libstore/store.h b/libstore/store.h index 2186c259..84e8aae3 100644 --- a/libstore/store.h +++ b/libstore/store.h @@ -41,9 +41,6 @@ struct store our store. */ file_t source; - /* The type of storage this is (see STORAGE_ in hurd/hurd_types.h). */ - enum file_storage_class class; - /* Address ranges in the underlying storage which make up our contiguous address space. In units of BLOCK_SIZE, below. */ struct store_run *runs; /* Malloced */ @@ -81,7 +78,7 @@ struct store void *misc; /* malloced */ size_t misc_len; - struct store_meths *meths; + struct store_class *class; /* A list of sub-stores. The interpretation of this is type-specific. */ struct store **children; @@ -89,6 +86,23 @@ struct store void *hook; /* Type specific noise. */ }; + +/* Store flags. These are in addition to the STORAGE_ flags defined in + <hurd/hurd_types.h>. XXX synchronize these values. */ + +/* Flags that reflect something immutable about the object. */ +#define STORE_IMMUTABLE_FLAGS 0xFF + +/* Flags implemented by generic store code. */ +#define STORE_READONLY 0x100 /* No writing allowed. */ +#define STORE_GENERIC_FLAGS STORE_READONLY + +/* Flags implemented by each backend. */ +#define STORE_HARD_READONLY 0x200 /* Can't be made writable. */ +#define STORE_ENFORCED 0x400 /* Range is enforced by device. */ +#define STORE_BACKEND_SPEC_BASE 0x1000 /* Here up are backend-specific */ +#define STORE_BACKEND_FLAGS (STORE_HARD_READONLY | STORE_ENFORCED \ + | ~(STORE_BACKEND_SPEC_BASE - 1)) typedef error_t (*store_write_meth_t)(struct store *store, off_t addr, size_t index, @@ -101,8 +115,14 @@ typedef error_t (*store_read_meth_t)(struct store *store, struct store_enc; /* fwd decl */ -struct store_meths +struct store_class { + /* The type of storage this is (see STORAGE_ in hurd/hurd_types.h). */ + enum file_storage_class id; + + /* Name of the class. */ + char *name; + /* Read up to AMOUNT bytes at the underlying address ADDR from the storage into BUF and LEN. INDEX varies from 0 to the number of runs in STORE. */ store_read_meth_t read; @@ -110,9 +130,6 @@ struct store_meths ADDR. INDEX varies from 0 to the number of runs in STORE. */ store_write_meth_t write; - /* Called just before deallocating STORE. */ - void (*cleanup) (struct store *store); - /* To the lengths of each for the four arrays in ENC, add how much STORE would need to be encoded. */ error_t (*allocate_encoding)(const struct store *store, @@ -120,61 +137,44 @@ struct store_meths /* Append the encoding for STORE to ENC. */ error_t (*encode) (const struct store *store, struct store_enc *enc); + /* Decode from ENC a new store, which return in STORE. CLASSES is used to + lookup child classes. */ + error_t (*decode) (struct store_enc *enc, struct store_class *classes, + struct store **store); + + /* Modify flags that reflect backend state, such as STORE_HARD_READONLY and + STORE_ENFORCED. */ + error_t (*set_flags) (struct store *store, int flags); + error_t (*clear_flags) (struct store *store, int flags); + + /* Called just before deallocating STORE. */ + void (*cleanup) (struct store *store); + /* Copy any format-dependent fields in FROM to TO; if there's some reason why the copy can't be made, an error should be returned. This call is made after all format-indendependent fields have been cloned. */ error_t (*clone) (const struct store *from, struct store *to); + + /* For making a list of classes to pass to e.g. store_create. */ + struct store_class *next; }; /* Return a new store in STORE, which refers to the storage underlying - SOURCE. Consumes a send-right to SOURCE (which is simply stored - STORE->source; you can steal it back if you like (replacing it with - MACH_PORT_NULL, or destroy it with store_close_source). */ -error_t store_create (file_t source, struct store **store); - -/* 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); - -/* Like store_device_create, but doesn't query the device for information. */ -error_t _store_device_create (device_t device, size_t block_size, - const struct store_run *runs, size_t num_runs, - struct store **store); - -/* Return a new store in STORE referring to the file FILE. Unlike - store_create, this will always use file i/o, even it would be possible to - be more direct. This may work in more cases, for instance if the file has - holes. Consumes the send right FILE. */ -error_t store_file_create (file_t file, struct store **store); - -/* Like store_file_create, but doesn't query the file for information. */ -error_t _store_file_create (file_t file, size_t block_size, - const struct store_run *runs, size_t num_runs, - struct store **store); - -/* Return a new store in STORE that interleaves all the stores in STRIPES - (NUM_STRIPES of them) every INTERLEAVE bytes; INTERLEAVE must be an - integer multiple of each stripe's block size. The stores in STRIPES are - consumed -- that is, will be freed when this store is (however, the - *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, struct store **store); - -/* Return a new store in STORE that concatenates all the stores in STORES - (NUM_STORES of them). The stores in STRIPES are consumed -- that is, will - be freed when this store is (however, the *array* STRIPES is copied, and - so should be freed by the caller). */ -error_t store_concat_create (struct store * const *stores, size_t num_stores, - struct store **store); + SOURCE. CLASSES is used to select classes specified by the provider; if + it is 0, STORE_STD_CLASSES is used. FLAGS is set with store_set_flags. A + reference to SOURCE is created (but may be destroyed with + store_close_source). */ +error_t store_create (file_t source, int flags, struct store_class *classes, + struct store **store); void store_free (struct store *store); -/* Allocate a new store structure of class CLASS, with meths METHS, and the - various other fields initialized to the given parameters. */ +/* Allocate a new store structure with class CLASS, and the various other + fields initialized to the given parameters. */ struct store * -_make_store (enum file_storage_class class, struct store_meths *meths, - mach_port_t port, size_t block_size, - const struct store_run *runs, size_t num_runs, off_t end); +_make_store (struct store_class *class, mach_port_t port, int flags, + size_t block_size, const struct store_run *runs, size_t num_runs, + off_t end); /* Set STORE's current runs list to (a copy of) RUNS and NUM_RUNS. */ error_t store_set_runs (struct store *store, @@ -188,6 +188,12 @@ error_t store_set_children (struct store *store, /* Sets the name associated with STORE to a copy of NAME. */ error_t store_set_name (struct store *store, const char *name); +/* Add FLAGS to STORE's currently set flags. */ +error_t store_set_flags (struct store *store, int flags); + +/* Remove FLAGS from STORE's currently set flags. */ +error_t store_clear_flags (struct store *store, int flags); + /* Fills in the values of the various fields in STORE that are derivable from the set of runs & the block size. */ void _store_derive (struct store *store); @@ -232,6 +238,68 @@ error_t store_create_pager (struct store *store, vm_prot_t prot, ..., #endif +/* Creating specific types of stores. */ + +/* 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, int flags, struct store **store); + +/* Like store_device_create, but doesn't query the device for information. */ +error_t _store_device_create (device_t device, int flags, size_t block_size, + const struct store_run *runs, size_t num_runs, + struct store **store); + +/* Open the device NAME, and return the corresponding store in STORE. */ +error_t store_device_open (const char *name, int flags, struct store **store); + +/* Return a new store in STORE referring to the file FILE. Unlike + store_create, this will always use file i/o, even it would be possible to + be more direct. This may work in more cases, for instance if the file has + holes. Consumes the send right FILE. */ +error_t store_file_create (file_t file, int flags, struct store **store); + +/* Like store_file_create, but doesn't query the file for information. */ +error_t _store_file_create (file_t file, int flags, size_t block_size, + const struct store_run *runs, size_t num_runs, + struct store **store); + +/* Open the file NAME, and return the corresponding store in STORE. */ +error_t store_file_open (const char *name, int flags, struct store **store); + +/* Return a new store in STORE that interleaves all the stores in STRIPES + (NUM_STRIPES of them) every INTERLEAVE bytes; INTERLEAVE must be an + integer multiple of each stripe's block size. The stores in STRIPES are + consumed -- that is, will be freed when this store is (however, the + *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); + +/* Return a new store in STORE that concatenates all the stores in STORES + (NUM_STORES of them). The stores in STRIPES are consumed -- that is, will + be freed when this store is (however, the *array* STRIPES is copied, and + so should be freed by the caller). */ +error_t store_concat_create (struct store * const *stores, size_t num_stores, + int flags, struct store **store); + +/* Return a new null store SIZE bytes long in STORE. */ +error_t store_null_create (size_t size, int flags, struct store **store); + +/* Standard store classes implemented by libstore. */ +extern struct store_class *store_std_classes; + +/* Add CLASS to the list of standard classes. It must not already be in the + list, or in any other, as its next field is simply written over. */ +void _store_add_std_class (struct store_class *class); + +/* Use this macro to automagically add a class to STORE_STD_CLASSES at + startup. */ +#define _STORE_STD_CLASS(class_struct) \ +static void _store_init_std_##class_struct () __attribute__ ((constructor));\ +static void _store_init_std_##class_struct () \ +{ \ + _store_add_std_class (&class_struct); \ +} + /* Used to hold the various bits that make up the representation of a store for transmission via rpc. See <hurd/hurd_types.h> for an explanation of the encodings for the various storage types. */ @@ -278,25 +346,49 @@ void store_enc_dealloc (struct store_enc *enc); used by the unsent vectors. */ error_t store_encode (const struct store *store, struct store_enc *enc); -/* Decode ENC, either returning a new store in STORE, or an error. If - nothing else is to be done with ENC, its contents may then be freed using - store_enc_dealloc. */ -error_t store_decode (struct store_enc *enc, struct store **store); +/* Decode ENC, either returning a new store in STORE, or an error. CLASSES + defines the mapping from hurd storage class ids to store classes; if it is + 0, STORE_STD_CLASSES is used. If nothing else is to be done with ENC, its + contents may then be freed using store_enc_dealloc. */ +error_t store_decode (struct store_enc *enc, struct store_class *classes, + struct store **store); + +/* Calls the allocate_encoding method in each child store of STORE, + propagating any errors. If any child does not hae such a method, + EOPNOTSUPP is returned. */ +error_t store_allocate_child_encodings (const struct store *store, + struct store_enc *enc); + +/* Calls the encode method in each child store of STORE, propagating any + errors. If any child does not hae such a method, EOPNOTSUPP is returned. */ +error_t store_encode_children (const struct store *store, + struct store_enc *enc); + +/* Decodes NUM_CHILDREN from ENC, storing the results into successive + positions in CHILDREN. */ +error_t store_decode_children (struct store_enc *enc, int num_children, + struct store_class *classes, + struct store **children); -/* Default encoding used for most leaf store types. */ -error_t store_default_leaf_allocate_encoding (struct store *store, - struct store_enc *enc); -error_t store_default_leaf_encode (struct store *store, struct store_enc *enc); +/* Standard encoding used for most leaf store types. */ +error_t store_std_leaf_allocate_encoding (const struct store *store, + struct store_enc *enc); +error_t store_std_leaf_encode (const struct store *store, + struct store_enc *enc); + +/* Creation function signature used by store_std_leaf_decode. */ +typedef error_t (*store_std_leaf_create_t)(mach_port_t port, + int flags, + size_t block_size, + const struct store_run *runs, + size_t num_runs, + struct store **store); /* Decodes the standard leaf encoding that's common to various builtin formats, and calls CREATE to actually create the store. */ -error_t store_default_leaf_decode (struct store_enc *enc, - error_t (*create)(mach_port_t port, - size_t block_size, - const struct store_run *runs, - size_t num_runs, - struct store **store), - struct store **store); +error_t store_std_leaf_decode (struct store_enc *enc, + store_std_leaf_create_t create, + struct store **store); /* An argument parser that may be used for parsing a simple command line specification for stores. The accompanying input parameter must be a @@ -307,8 +399,8 @@ extern struct argp store_argp; STORE_ARGP. */ struct store_argp_params { - /* If true, open the underlying file/device readonly. */ - int readonly : 1; + /* An initial set of flags desired to be set. */ + int flags; /* If true, don't attempt use store_file_create to create a store on files upon which store_create has failed. */ |