diff options
Diffstat (limited to 'libstore/store.h')
-rw-r--r-- | libstore/store.h | 573 |
1 files changed, 480 insertions, 93 deletions
diff --git a/libstore/store.h b/libstore/store.h index 84e8aae3..ae334a1d 100644 --- a/libstore/store.h +++ b/libstore/store.h @@ -1,9 +1,7 @@ /* Store I/O - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> - + Copyright (C) 1995,96,97,98,99,2001,02,04,05 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,21 +16,38 @@ 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. */ + +/* 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> +#include <features.h> + +#ifdef STORE_DEFINE_EI +#define STORE_EI +#else +#define STORE_EI __extern_inline +#endif +/* Type for addresses inside the store. */ +typedef off64_t store_offset_t; + /* A portion of a store. If START == -1, it's a hole. */ struct store_run { - off_t start, length; + store_offset_t start, length; }; struct store @@ -47,13 +62,13 @@ struct store size_t num_runs; /* Length of RUNS. */ /* Maximum valid offset. This is the same as SIZE, but in blocks. */ - off_t end; + store_offset_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 */ + store_offset_t wrap_src; + store_offset_t wrap_dst; /* Only meaningful if WRAP_SRC < END */ /* Handles for the underlying storage. */ char *name; /* Malloced */ @@ -63,14 +78,14 @@ struct store size_t block_size; /* The number of blocks (of size BLOCK_SIZE) in this storage. */ - size_t blocks; + store_offset_t blocks; /* The number of bytes in this storage, including holes. */ - size_t size; + store_offset_t size; /* Log_2 (BLOCK_SIZE) or 0 if not a power of 2. */ - int log2_block_size; + unsigned log2_block_size; /* Log_2 (VM_PAGE_SIZE / BLOCK_SIZE); only valid if LOG2_BLOCK_SIZE is. */ - int log2_blocks_per_page; + unsigned log2_blocks_per_page; /* Random flags. */ int flags; @@ -78,7 +93,7 @@ struct store void *misc; /* malloced */ size_t misc_len; - struct store_class *class; + const struct store_class *class; /* A list of sub-stores. The interpretation of this is type-specific. */ struct store **children; @@ -91,27 +106,36 @@ struct store <hurd/hurd_types.h>. XXX synchronize these values. */ /* Flags that reflect something immutable about the object. */ -#define STORE_IMMUTABLE_FLAGS 0xFF +#define STORE_IMMUTABLE_FLAGS 0x00FF /* Flags implemented by generic store code. */ -#define STORE_READONLY 0x100 /* No writing allowed. */ -#define STORE_GENERIC_FLAGS STORE_READONLY +#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 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_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, - char *buf, mach_msg_type_number_t len, + store_offset_t addr, size_t index, + const 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, + store_offset_t addr, size_t index, mach_msg_type_number_t amount, - char **buf, mach_msg_type_number_t *len); + void **buf, mach_msg_type_number_t *len); +typedef error_t (*store_set_size_meth_t)(struct store *store, + size_t newsize); struct store_enc; /* fwd decl */ @@ -121,14 +145,16 @@ struct store_class enum file_storage_class id; /* Name of the class. */ - char *name; + 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. */ + 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. */ + ADDR. INDEX varies from 0 to the number of runs in STORE. */ store_write_meth_t write; + /* Set store's size to NEWSIZE (in bytes). */ + store_set_size_meth_t set_size; /* To the lengths of each for the four arrays in ENC, add how much STORE would need to be encoded. */ @@ -139,7 +165,8 @@ struct store_class /* 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, + 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 @@ -155,26 +182,63 @@ struct store_class 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 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 + validity, 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. 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, + SOURCE. CLASSES is as if passed to store_find_class, which see. 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); -/* Allocate a new store structure with class CLASS, and the various other - fields initialized to the given parameters. */ -struct store * -_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); +/* Open the file NAME, and return a new store in STORE, which refers to the + storage underlying it. CLASSES is as if passed to store_find_class, + which see. 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, + store_offset_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, @@ -185,6 +249,12 @@ error_t store_set_runs (struct store *store, 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); @@ -194,52 +264,85 @@ 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 successful, 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 successful, remove FLAGS from + STORE's flags. */ +error_t store_clear_child_flags (struct store *store, int flags); + +extern int store_is_securely_returnable (struct store *store, int open_flags); + +#if defined(__USE_EXTERN_INLINES) || defined(STORE_DEFINE_EI) + +/* 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))); +} + +#endif /* Use extern inlines. */ + /* 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, char *buf, size_t len, size_t *amount); + store_offset_t addr, const 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, char **buf, size_t *len); + store_offset_t addr, size_t amount, void **buf, size_t *len); + +/* Set STORE's size to NEWSIZE (in bytes). */ +error_t store_set_size (struct store *store, size_t newsize); /* 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); -#if 0 - -/* Return a memory object paging on STORE. [among other reasons,] this may - fail because store contains non-contiguous regions on the underlying - object. In such a case you can try calling some of the routines below to - get a pager. */ -error_t store_map (struct store *store, vm_prot_t prot, ..., - mach_port_t *pager); +/* 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); -/* Returns a memory object paging on the file from which STORE was created. - If STORE wasn't created using store_create, or the source was destroyed - using store_close_source, this will fail. */ -error_t store_map_source (struct store *store, vm_prot_t prot, ..., - mach_port_t *pager) +#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 *pager) + 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 (store_offset_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); @@ -252,6 +355,21 @@ error_t _store_device_create (device_t device, int flags, size_t block_size, /* 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 which contains a remap store of partition + PART from the contents of SOURCE; SOURCE is consumed. */ +error_t store_part_create (struct store *source, int index, int flags, + struct store **store); + +/* Open the part NAME. NAME consists of a partition number, a ':', a + another store class name, a ':' and a name for to by passed to the + store class. E.g. "2:device:hd0" would open the second partition + on a DEVICE store named "hd0". FLAGS indicate how to open the + store. CLASSES is as if passed to store_find_class, which see. + The new store is returned in *STORE. */ +error_t store_part_open (const char *name, int flags, + const struct store_class *const *classes, + 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 @@ -266,13 +384,53 @@ error_t _store_file_create (file_t file, int flags, size_t block_size, /* 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); + +/* Return a new store in STORE referring to the memory object MEMOBJ. + Consumes the send right MEMOBJ. */ +error_t store_memobj_create (memory_object_t memobj, int flags, + size_t block_size, + const struct store_run *runs, size_t num_runs, + struct store **store); + +/* Open the network block device NAME (parsed as "HOSTNAME:PORT[/BLOCKSIZE]"), + and return the corresponding store in STORE. This opens a socket and + initial connection handshake, which determine the size of the device, + and then uses _store_nbd_create with the open socket port. */ +error_t store_nbd_open (const char *name, int flags, struct store **store); + +/* Create a store that works by talking to an nbd server on an existing + socket port. */ +error_t _store_nbd_create (mach_port_t port, int flags, size_t block_size, + const struct store_run *runs, size_t num_runs, + struct store **store); + +/* Return a new store of type "unknown" that holds a copy of the + given encoding. The name of the store is taken from ENC->data. + Future calls to store_encode/store_return will produce exactly + the encoding supplied here. All i/o operations fail with EFTYPE. */ +error_t store_unknown_decode (struct store_enc *enc, + 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); + store_offset_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 @@ -281,24 +439,208 @@ error_t store_ileave_create (struct store * const *stripes, size_t num_stripes, 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); +/* 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 as if passed to + store_find_class, which see. */ +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 as if passed to + store_find_class, which see. */ +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 as if passed to store_find_class, which see. */ +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); + +/* Opening stores from a standard set of store classes. + + These first two functions underlie the following functions, and + other functions such as store_open taking a CLASSES argument that + can be null. The standard set of classes to be searched when that + argument is null includes all the `const struct store_class *' + pointers found in the `store_std_classes' section of the executable + and all loaded shared objects; store_find_class searches that set + for the named class. The store_typed_open and store_url_open + functions also try store_module_find_class, but only if the + function has already been linked in; it's always available in the + shared library, and available for static linking with + -lstore_module -ldl. + + The macro STORE_STD_CLASS produces a reference in the `store_std_classes' + section, so that linking in a module containing that definition will add + the referenced class to the standard search list. In the shared library, + the various standard classes are included this way. In the static + library, only the pseudo classes like `query' and `typed' will normally + be linked in (via referenced to store_open and so forth); to force + specific store type modules to be linked in, you must specify an + `-lstore_CLASS' option for each individual class to be statically linked. +*/ + +/* Find a store class by name. CLNAME_END points to the character + after the class name NAME points to; if null, then NAME is just the + null-terminated class name. */ +const struct store_class * +store_find_class (const char *name, + const char *clname_end, + const struct store_class *const *classes); + +/* This is the underlying function that tries to load a module to + define the store type called NAME. On success, returns zero + and sets *CLASSP to the descriptor found. Returns ENOENT if + there is no such module, or other error codes if there is a + module but it does not load correctly. */ +error_t store_module_find_class (const char *name, + const char *clname_end, + const struct store_class **classp); + + +/* 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 as if passed to store_find_class, + which see. */ +error_t store_typed_open (const char *name, int flags, + const struct store_class *const *classes, + struct store **store); + +/* Similar to store_typed_open, but NAME must be in URL format, i.e. a + class name followed by a ':' and any type-specific name. A leading ':' + or no ':' at all is invalid syntax. (See store_module_open, below.) */ +error_t store_url_open (const char *name, int flags, + const struct store_class *const *classes, + struct store **store); + +/* This attempts to decode a standard-form STORAGE_NETWORK encoding whose + encoded name is in URL format, by finding the store type indicated in + the URL (as for store_url_open) and that type's decode function. */ +error_t store_url_decode (struct store_enc *enc, + const struct store_class *const *classes, + struct store **store); + + +/* Similar to store_typed_open, but the store type's code is found + dynamically rather than statically in CLASSES. A shared object name + for `dlopen' and symbol names for `dlsym' are derived from the type + name and used to find the `struct store_class' for the named type. + (CLASSES is used only by the type's own open function, e.g. if that + type accepts a child-store syntax in its name.) + + In fact, when this code is linked in (always in the shared library, + only with `-lstore_module -ldl -lstore' for static linking), all + the functions documented as using STORE_STD_CLASSES will also + check for loadable modules if the type name is not found statically. */ +error_t store_module_open (const char *name, int flags, + const struct store_class *const *classes, + struct store **store); + + +/* This attempts to find a module that can decode ENC. If no such + module can be found it returns ENOENT. Otherwise it returns + the result of the loaded store type's `decode' function. */ +error_t store_module_decode (struct store_enc *enc, + const struct store_class *const *classes, + 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); + /* 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); \ -} +extern const struct store_class store_device_class; +extern const struct store_class store_part_class; +extern const struct store_class store_file_class; +extern const struct store_class store_task_class; +extern const struct store_class store_nbd_class; +extern const struct store_class store_memobj_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; +extern const struct store_class store_url_open_class; +extern const struct store_class store_module_open_class; +extern const struct store_class store_unknown_class; + +/* The following are not included in STORE_STD_CLASSES. */ +extern const struct store_class store_mvol_class; + +#define STORE_STD_CLASS(name) \ + static const struct store_class *const store_std_classes_##name[] \ + __attribute_used__ __attribute__ ((section ("store_std_classes"))) \ + = { &store_##name##_class } + + +extern const struct store_class *const __start_store_std_classes[] __attribute__ ((weak)); +extern const struct store_class *const __stop_store_std_classes[] __attribute__ ((weak)); /* 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 @@ -308,7 +650,7 @@ struct store_enc /* Each of the four vectors used. All are vm_allocated. */ mach_port_t *ports; int *ints; - off_t *offsets; + loff_t *offsets; char *data; /* The sizes of the vectors. */ @@ -322,7 +664,7 @@ struct store_enc version won't be deallocated. */ mach_port_t *init_ports; int *init_ints; - off_t *init_offsets; + loff_t *init_offsets; char *init_data; }; @@ -332,13 +674,29 @@ struct store_enc 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, + loff_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, + loff_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, + loff_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 @@ -346,11 +704,12 @@ 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. 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, +/* Decode ENC, either returning a new store in STORE, or an error. + CLASSES is as if passed to store_find_class, which see. 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, @@ -367,9 +726,14 @@ error_t store_encode_children (const struct store *store, /* 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, + 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); @@ -392,22 +756,45 @@ error_t store_std_leaf_decode (struct store_enc *enc, /* 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 structure of type struct store_argp_param. */ + pointer to a struct store_argp_params. */ extern struct argp store_argp; -/* Structure used to pass in arguments and return the result from - STORE_ARGP. */ +/* The structure used to pass args back and forth from STORE_ARGP. */ struct store_argp_params { - /* An initial set of flags desired to be set. */ - int flags; + /* 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; - /* If true, don't attempt use store_file_create to create a store on files - upon which store_create has failed. */ - int no_file_io : 1; + /* The set of classes used to validate store-types and argument syntax. */ + const struct store_class *const *classes; - /* Parsed store returned here. */ - struct store *result; + /* This controls the behavior when no store arguments are specified. + If zero, the parser fails with the error message "No store specified". + If nonzero, the parser succeeds and sets `result' to null. */ + int store_optional; }; +/* 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__ */ |