aboutsummaryrefslogtreecommitdiff
path: root/libstore/store.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstore/store.h')
-rw-r--r--libstore/store.h646
1 files changed, 646 insertions, 0 deletions
diff --git a/libstore/store.h b/libstore/store.h
new file mode 100644
index 00000000..c57e7fcf
--- /dev/null
+++ b/libstore/store.h
@@ -0,0 +1,646 @@
+/* Store I/O
+
+ Copyright (C) 1995, 96, 97, 98, 99 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
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+/* A `store' is a fixed-size block of storage, which can be read and perhaps
+ written to. This library implements many different backends which allow
+ the abstract store interface to be used with common types of storage --
+ devices, files, memory, tasks, etc. It also allows stores to be combined
+ and filtered in various ways. */
+
+#ifndef __STORE_H__
+#define __STORE_H__
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <mach.h>
+#include <device/device.h>
+#include <hurd/hurd_types.h>
+
+#ifndef STORE_EI
+#define STORE_EI extern inline
+#endif
+
+
+/* A portion of a store. If START == -1, it's a hole. */
+struct store_run
+{
+ off_t start, length;
+};
+
+struct store
+{
+ /* If this store was created using store_create, the file from which we got
+ our store. */
+ file_t source;
+
+ /* Address ranges in the underlying storage which make up our contiguous
+ address space. In units of BLOCK_SIZE, below. */
+ struct store_run *runs; /* Malloced */
+ size_t num_runs; /* Length of RUNS. */
+
+ /* Maximum valid offset. This is the same as SIZE, but in blocks. */
+ off_t end;
+
+ /* WRAP_SRC is the sum of the run lengths in RUNS. If this is less than
+ END, then RUNS describes a repeating pattern, of length WRAP_SRC -- each
+ successive iteration having an additional offset of WRAP_DST. */
+ off_t wrap_src;
+ off_t wrap_dst; /* Only meaningful if WRAP_SRC < END */
+
+ /* Handles for the underlying storage. */
+ char *name; /* Malloced */
+ mach_port_t port; /* Send right */
+
+ /* The size of a `block' on this storage. */
+ size_t block_size;
+
+ /* The number of blocks (of size BLOCK_SIZE) in this storage. */
+ off_t blocks;
+ /* The number of bytes in this storage, including holes. */
+ off_t size;
+
+ /* Log_2 (BLOCK_SIZE) or 0 if not a power of 2. */
+ unsigned log2_block_size;
+ /* Log_2 (VM_PAGE_SIZE / BLOCK_SIZE); only valid if LOG2_BLOCK_SIZE is. */
+ unsigned log2_blocks_per_page;
+
+ /* Random flags. */
+ int flags;
+
+ void *misc; /* malloced */
+ size_t misc_len;
+
+ const struct store_class *class;
+
+ /* A list of sub-stores. The interpretation of this is type-specific. */
+ struct store **children;
+ size_t num_children;
+
+ 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 0x00FF
+
+/* Flags implemented by generic store code. */
+#define STORE_READONLY 0x0100 /* No writing allowed. */
+#define STORE_NO_FILEIO 0x0200 /* If store_create can't fetch store
+ information, don't create a store
+ using file io instead. */
+#define STORE_GENERIC_FLAGS (STORE_READONLY | STORE_NO_FILEIO)
+
+/* Flags implemented by each backend. */
+#define STORE_HARD_READONLY 0x1000 /* Can't be made writable. */
+#define STORE_ENFORCED 0x2000 /* Range is enforced by device. */
+#define STORE_INACTIVE 0x4000 /* Not in a usable state. */
+#define STORE_INNOCUOUS 0x8000 /* Cannot modify anything dangerous. */
+#define STORE_BACKEND_SPEC_BASE 0x10000 /* Here up are backend-specific */
+#define STORE_BACKEND_FLAGS (STORE_HARD_READONLY | STORE_ENFORCED \
+ | STORE_INACTIVE \
+ | ~(STORE_BACKEND_SPEC_BASE - 1))
+
+typedef error_t (*store_write_meth_t)(struct store *store,
+ off_t addr, size_t index,
+ void *buf, mach_msg_type_number_t len,
+ mach_msg_type_number_t *amount);
+typedef error_t (*store_read_meth_t)(struct store *store,
+ off_t addr, size_t index,
+ mach_msg_type_number_t amount,
+ void **buf, mach_msg_type_number_t *len);
+
+struct store_enc; /* fwd decl */
+
+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. */
+ const 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;
+ /* Write up to LEN bytes from BUF to the storage at the underlying address
+ ADDR. INDEX varies from 0 to the number of runs in STORE. */
+ store_write_meth_t write;
+
+ /* 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,
+ struct store_enc *enc);
+ /* 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,
+ const struct store_class *const *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);
+
+ /* Return in STORE a store that only contains the parts of SOURCE as
+ enumerated in RUNS & RUNS_LEN, consuming SOURCE in the process. The
+ default behavior, if REMAP is 0, is to replace SOURCE's run list with
+ the subset selected by RUNS, and return SOURCE. */
+ error_t (*remap) (struct store *source,
+ const struct store_run *runs, size_t num_runs,
+ struct store **store);
+
+ /* Open a new store called NAME in this class. CLASSES is supplied in case
+ it's desirable to open a sub-store in some manner. */
+ error_t (*open) (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+ /* Given a user argument ARG, this function should check it for syntactic
+ validaty, or print a syntax error, using ARGP_STATE in the normal
+ manner; if zero is returned, then this argument is assumed valid, and
+ can be passed to the open function. If ARG is 0, then there were *no*
+ arguments specified; in this case, returning EINVAL means that this is
+ not kosher. If PARSE is 0, then it is assumed that if this class has an
+ OPEN function, then validity can't be syntactically determined. */
+ error_t (*validate_name) (const char *name,
+ const struct store_class *const *classes);
+
+ /* Return a memory object paging on STORE. */
+ error_t (*map) (const struct store *store, vm_prot_t prot, mach_port_t *memobj);
+};
+
+/* Return a new store in STORE, which refers to the storage underlying 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, with the
+ exception of STORE_INACTIVE, which merely indicates that no attempt should
+ be made to activate an inactive store; if STORE_INACTIVE is not specified,
+ and the store returned for SOURCE is inactive, an attempt is made to
+ activate it (failure of which causes an error to be returned). A reference
+ to SOURCE is created (but may be destroyed with store_close_source). */
+error_t store_create (file_t source, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+void store_free (struct store *store);
+
+/* Open the file NAME, and return a new store in STORE, which refers to the
+ storage underlying it. 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 the open file is created (but may be
+ destroyed with store_close_source). */
+error_t store_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+/* Allocate a new store structure, returned in STORE, with class CLASS and
+ the various other fields initialized to the given parameters. */
+error_t
+_store_create (const 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, struct store **store);
+
+/* Set STORE's current runs list to (a copy of) RUNS and NUM_RUNS. */
+error_t store_set_runs (struct store *store,
+ const struct store_run *runs, size_t num_runs);
+
+/* Set STORE's current children to (a copy of) CHILDREN and NUM_CHILDREN
+ (note that just the vector CHILDREN is copied, not the actual children). */
+error_t store_set_children (struct store *store,
+ struct store *const *children, size_t num_children);
+
+/* Try to come up with a name for the children in STORE, combining the names
+ of each child in a way that could be used to parse them with
+ store_open_children. This is done heuristically, and so may not succeed.
+ If a child doesn't have a name, EINVAL is returned. */
+error_t store_children_name (const struct store *store, char **name);
+
+/* 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);
+
+/* Set FLAGS in all children of STORE, and if successfull, add FLAGS to
+ STORE's flags. */
+error_t store_set_child_flags (struct store *store, int flags);
+
+/* Clear FLAGS in all children of STORE, and if successfull, remove FLAGS from
+ STORE's flags. */
+error_t store_clear_child_flags (struct store *store, int flags);
+
+/* Returns true if STORE can safely be returned to a user who has accessed it
+ via a node using OPEN_FLAGS, without compromising security. */
+STORE_EI int
+store_is_securely_returnable (struct store *store, int open_flags)
+{
+ int flags = store->flags;
+ return
+ (flags & (STORE_INNOCUOUS | STORE_INACTIVE))
+ || ((flags & STORE_ENFORCED)
+ && (((open_flags & O_ACCMODE) == O_RDWR)
+ || (flags & STORE_HARD_READONLY)));
+}
+
+/* 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);
+
+/* Return in TO a copy of FROM. */
+error_t store_clone (struct store *from, struct store **to);
+
+/* Return a store in STORE that reflects the blocks in RUNS & RUNS_LEN from
+ source; SOURCE is consumed, but not RUNS. Unlike the store_remap_create
+ function, this may simply modify SOURCE and return it. */
+error_t store_remap (struct store *source,
+ const struct store_run *runs, size_t num_runs,
+ struct store **store);
+
+/* Write LEN bytes from BUF to STORE at ADDR. Returns the amount written in
+ AMOUNT (in bytes). ADDR is in BLOCKS (as defined by STORE->block_size). */
+error_t store_write (struct store *store,
+ off_t addr, void *buf, size_t len, size_t *amount);
+
+/* Read AMOUNT bytes from STORE at ADDR into BUF & LEN (which following the
+ usual mach buffer-return semantics) to STORE at ADDR. ADDR is in BLOCKS
+ (as defined by STORE->block_size). Note that LEN is in bytes. */
+error_t store_read (struct store *store,
+ off_t addr, size_t amount, void **buf, size_t *len);
+
+/* If STORE was created using store_create, remove the reference to the
+ source from which it was created. */
+void store_close_source (struct store *store);
+
+/* Return a memory object paging on STORE. If this call fails with
+ EOPNOTSUPP, you can try calling some of the routines below to get a pager. */
+error_t store_map (const struct store *store, vm_prot_t prot,
+ mach_port_t *memobj);
+
+#if 0
+
+/* Create a new pager and paging threads paging on STORE, and return the
+ resulting memory object in PAGER. */
+error_t store_create_pager (struct store *store, vm_prot_t prot, ...,
+ mach_port_t *memobj)
+
+#endif
+
+/* Creating specific types of stores. */
+
+/* Return a new zero store SIZE bytes long in STORE. */
+error_t store_zero_create (off_t size, int flags, 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, 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 referring to the task TASK, consuming TASK. */
+error_t store_task_create (task_t task, int flags, struct store **store);
+
+/* Like store_task_create, but doesn't query the task for information. */
+error_t _store_task_create (task_t task, int flags, size_t block_size,
+ const struct store_run *runs, size_t num_runs,
+ struct store **store);
+
+/* Open the task NAME (NAME should be the task's pid), and return the
+ corresponding store in STORE. */
+error_t store_task_open (const char *name, int flags, struct store **store);
+
+/* Parse multiple store names in NAME, and open each individually, returning
+ all in the vector STORES, and the number in NUM_STORES. The syntax of
+ NAME is a single non-alpha-numeric separator character, followed by each
+ child store name separated by the same separator; each child name is
+ TYPE:NAME notation as parsed by store_typed_open. If every child uses the
+ same TYPE: prefix, then it may be factored out and put before the child
+ list instead (the two types of notation are differentiated by whether the
+ first character of name is alpha-numeric or not). */
+error_t store_open_children (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store ***stores, size_t *num_stores);
+
+/* Open the store indicated by NAME, which should consist of a store type
+ name followed by a ':' and any type-specific name, returning the new store
+ in STORE. CLASSES is used to select classes specified by the type name;
+ if it is 0, STORE_STD_CLASSES is used. */
+error_t store_typed_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ 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 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);
+
+/* Return a new store in STORE that reflects the blocks in RUNS & RUNS_LEN
+ from SOURCE; SOURCE is consumed, but RUNS is not. Unlike the store_remap
+ function, this function always operates by creating a new store of type
+ `remap' which has SOURCE as a child, and so may be less efficient than
+ store_remap for some types of stores. */
+error_t store_remap_create (struct store *source,
+ const struct store_run *runs, size_t num_runs,
+ int flags, struct store **store);
+
+/* Return a new store in STORE which contains a snapshot of the contents of
+ the store FROM; FROM is consumed. */
+error_t store_copy_create (struct store *from, int flags, struct store **store);
+
+/* Open the copy store NAME -- which consists of another store-class name, a
+ ':', and a name for that store class to open -- and return the
+ corresponding store in STORE. CLASSES is used to select classes specified
+ by the type name; if it is 0, STORE_STD_CLASSES is used. */
+error_t store_copy_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+/* Return a new store in STORE which contains the memory buffer BUF, of
+ length BUF_LEN. BUF must be vm_allocated, and will be consumed. */
+error_t store_buffer_create (void *buf, size_t buf_len, int flags,
+ struct store **store);
+
+/* Return a new store in STORE which contains a snapshot of the uncompressed
+ contents of the store FROM; FROM is consumed. BLOCK_SIZE is the desired
+ block size of the result. */
+error_t store_gunzip_create (struct store *from, int flags,
+ struct store **store);
+
+/* Open the gunzip NAME -- which consists of another store-class name, a ':',
+ and a name for that store class to open -- and return the corresponding
+ store in STORE. CLASSES is used to select classes specified by the type
+ name; if it is 0, STORE_STD_CLASSES is used. */
+error_t store_gunzip_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+/* Return a new store in STORE which contains a snapshot of the uncompressed
+ contents of the store FROM; FROM is consumed. BLOCK_SIZE is the desired
+ block size of the result. */
+error_t store_bunzip2_create (struct store *from, int flags,
+ struct store **store);
+
+/* Open the bunzip2 NAME -- which consists of another store-class name, a ':',
+ and a name for that store class to open -- and return the corresponding
+ store in STORE. CLASSES is used to select classes specified by the type
+ name; if it is 0, STORE_STD_CLASSES is used. */
+error_t store_bunzip2_open (const char *name, int flags,
+ const struct store_class *const *classes,
+ struct store **store);
+
+/* Return a new store in STORE that multiplexes multiple physical volumes
+ from PHYS as one larger virtual volume. SWAP_VOLS is a function that will
+ be called whenever the volume currently active isn't correct. PHYS is
+ consumed. */
+error_t store_mvol_create (struct store *phys,
+ error_t (*swap_vols) (struct store *store, size_t new_vol,
+ ssize_t old_vol),
+ int flags,
+ struct store **store);
+
+/* Standard store classes implemented by libstore. */
+extern const struct store_class *const store_std_classes[];
+
+extern const struct store_class store_device_class;
+extern const struct store_class store_file_class;
+extern const struct store_class store_task_class;
+extern const struct store_class store_zero_class;
+extern const struct store_class store_ileave_class;
+extern const struct store_class store_concat_class;
+extern const struct store_class store_remap_class;
+extern const struct store_class store_query_class;
+extern const struct store_class store_copy_class;
+extern const struct store_class store_gunzip_class;
+extern const struct store_class store_bunzip2_class;
+extern const struct store_class store_typed_open_class;
+
+/* The following are not included in STORE_STD_CLASSES. */
+extern const struct store_class store_mvol_class;
+
+/* Concatenates the store class vectors in CV1 and CV2, and returns a new
+ (malloced) vector in CONCAT. */
+error_t store_concat_class_vectors (struct store_class **cv1,
+ struct store_class **cv2,
+ struct store_class ***concat);
+
+/* 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. */
+struct store_enc
+{
+ /* Each of the four vectors used. All are vm_allocated. */
+ mach_port_t *ports;
+ int *ints;
+ off_t *offsets;
+ char *data;
+
+ /* The sizes of the vectors. */
+ mach_msg_type_number_t num_ports, num_ints, num_offsets, data_len;
+
+ /* Offsets into the above vectors, for an encoding/decoding in progress. */
+ size_t cur_port, cur_int, cur_offset, cur_data;
+
+ /* Each of these is an `initial' version of the associated vector. When
+ store_enc_dealloc is called, any vector that is the same as its `init_'
+ version won't be deallocated. */
+ mach_port_t *init_ports;
+ int *init_ints;
+ off_t *init_offsets;
+ char *init_data;
+};
+
+/* Initialize ENC. The given vector and sizes will be used for the encoding
+ if they are big enough (otherwise new ones will be automatically
+ allocated). */
+void store_enc_init (struct store_enc *enc,
+ mach_port_t *ports, mach_msg_type_number_t num_ports,
+ int *ints, mach_msg_type_number_t num_ints,
+ off_t *offsets, mach_msg_type_number_t num_offsets,
+ char *data, mach_msg_type_number_t data_len);
+
+/* Deallocate storage used by the fields in ENC (but nothing is done with ENC
+ itself). */
+void store_enc_dealloc (struct store_enc *enc);
+
+/* Copy out the parameters from ENC into the given variables suitably for
+ returning from a file_get_storage_info rpc, and deallocate ENC. */
+void store_enc_return (struct store_enc *enc,
+ mach_port_t **ports, mach_msg_type_number_t *num_ports,
+ int **ints, mach_msg_type_number_t *num_ints,
+ off_t **offsets, mach_msg_type_number_t *num_offsets,
+ char **data, mach_msg_type_number_t *data_len);
+
+/* Encode STORE into the given return variables, suitably for returning from a
+ file_get_storage_info rpc. */
+error_t store_return (const struct store *store,
+ mach_port_t **ports, mach_msg_type_number_t *num_ports,
+ int **ints, mach_msg_type_number_t *num_ints,
+ off_t **offsets, mach_msg_type_number_t *num_offsets,
+ char **data, mach_msg_type_number_t *data_len);
+
+/* Encode STORE into ENC, which should have been prepared with
+ store_enc_init, or return an error. The contents of ENC may then be
+ return as the value of file_get_storage_info; if for some reason this
+ can't be done, store_enc_dealloc may be used to deallocate the mmemory
+ 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. 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,
+ const struct store_class *const *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,
+ const struct store_class *const *classes,
+ struct store **children);
+
+/* Call FUN with the vector RUNS of length NUM_RUNS extracted from ENC. */
+error_t store_with_decoded_runs (struct store_enc *enc, size_t num_runs,
+ error_t (*fun) (const struct store_run *runs,
+ size_t num_runs));
+
+/* 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_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
+ pointer to a struct store_argp_params. */
+extern struct argp store_argp;
+
+/* The structure used to pass args back and forth from STORE_ARGP. */
+struct store_argp_params
+{
+ /* The resulting parsed result. */
+ struct store_parsed *result;
+
+ /* If --store-type isn't specified use this; 0 is equivalent to "query". */
+ const char *default_type;
+
+ /* The set of classes used to validate store-types and argument syntax. */
+ const struct store_class *const *classes;
+};
+
+/* The result of parsing a store, which should be enough information to open
+ it, or return the arguments. */
+struct store_parsed;
+
+/* Free all resources used by PARSED. */
+void store_parsed_free (struct store_parsed *parsed);
+
+/* Open PARSED, and return the corresponding store in STORE. */
+error_t store_parsed_open (const struct store_parsed *parsed, int flags,
+ struct store **store);
+
+/* Add the arguments used to create PARSED to ARGZ & ARGZ_LEN. */
+error_t store_parsed_append_args (const struct store_parsed *parsed,
+ char **argz, size_t *argz_len);
+
+/* Make a string describing PARSED, and return it in malloced storage in
+ NAME. */
+error_t store_parsed_name (const struct store_parsed *parsed, char **name);
+
+
+#endif /* __STORE_H__ */