diff options
Diffstat (limited to 'src/lib-fs/fs-api-private.h')
-rw-r--r-- | src/lib-fs/fs-api-private.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/lib-fs/fs-api-private.h b/src/lib-fs/fs-api-private.h new file mode 100644 index 0000000..76eb2c5 --- /dev/null +++ b/src/lib-fs/fs-api-private.h @@ -0,0 +1,213 @@ +#ifndef FS_API_PRIVATE_H +#define FS_API_PRIVATE_H + +#include "fs-api.h" +#include "fs-wrapper.h" +#include "module-context.h" + +#include <sys/time.h> + +#define FS_EVENT_FIELD_FS "lib-fs#fs" +#define FS_EVENT_FIELD_FILE "lib-fs#file" +#define FS_EVENT_FIELD_ITER "lib-fs#iter" + +enum fs_get_metadata_flags { + FS_GET_METADATA_FLAG_LOADED_ONLY = BIT(0), +}; + +struct fs_api_module_register { + unsigned int id; +}; + +union fs_api_module_context { + struct fs_api_module_register *reg; +}; + +extern struct fs_api_module_register fs_api_module_register; + +struct fs_vfuncs { + struct fs *(*alloc)(void); + int (*init)(struct fs *fs, const char *args, + const struct fs_settings *set, const char **error_r); + void (*deinit)(struct fs *fs); + void (*free)(struct fs *fs); + + enum fs_properties (*get_properties)(struct fs *fs); + + struct fs_file *(*file_alloc)(void); + void (*file_init)(struct fs_file *file, const char *path, + enum fs_open_mode mode, enum fs_open_flags flags); + void (*file_deinit)(struct fs_file *file); + void (*file_close)(struct fs_file *file); + const char *(*get_path)(struct fs_file *file); + + void (*set_async_callback)(struct fs_file *file, + fs_file_async_callback_t *callback, + void *context); + void (*wait_async)(struct fs *fs); + + void (*set_metadata)(struct fs_file *file, const char *key, + const char *value); + int (*get_metadata)(struct fs_file *file, + enum fs_get_metadata_flags flags, + const ARRAY_TYPE(fs_metadata) **metadata_r); + + bool (*prefetch)(struct fs_file *file, uoff_t length); + ssize_t (*read)(struct fs_file *file, void *buf, size_t size); + struct istream *(*read_stream)(struct fs_file *file, + size_t max_buffer_size); + + int (*write)(struct fs_file *file, const void *data, size_t size); + void (*write_stream)(struct fs_file *file); + /* After write_stream_finish() is called once, all the following + (async) calls will have success==TRUE. */ + int (*write_stream_finish)(struct fs_file *file, bool success); + + int (*lock)(struct fs_file *file, unsigned int secs, + struct fs_lock **lock_r); + void (*unlock)(struct fs_lock *lock); + + int (*exists)(struct fs_file *file); + int (*stat)(struct fs_file *file, struct stat *st_r); + int (*copy)(struct fs_file *src, struct fs_file *dest); + int (*rename)(struct fs_file *src, struct fs_file *dest); + int (*delete_file)(struct fs_file *file); + + struct fs_iter *(*iter_alloc)(void); + void (*iter_init)(struct fs_iter *iter, const char *path, + enum fs_iter_flags flags); + const char *(*iter_next)(struct fs_iter *iter); + int (*iter_deinit)(struct fs_iter *iter); + + bool (*switch_ioloop)(struct fs *fs); + int (*get_nlinks)(struct fs_file *file, nlink_t *nlinks_r); +}; + +struct fs { + struct fs *parent; /* for wrapper filesystems */ + const char *name; + struct fs_vfuncs v; + char *temp_path_prefix; + int refcount; + + char *username, *session_id; + + struct fs_settings set; + + /* may be used by fs_wait_async() to do the waiting */ + struct ioloop *wait_ioloop, *prev_ioloop; + + unsigned int files_open_count; + struct fs_file *files; + struct fs_iter *iters; + struct event *event; + + struct fs_stats stats; + + ARRAY(union fs_api_module_context *) module_contexts; +}; + +struct fs_file { + /* linked list of all files */ + struct fs_file *prev, *next; + + struct fs_file *parent; /* for wrapper filesystems */ + struct fs *fs; + struct ostream *output; + struct event *event; + char *path; + char *last_error; + enum fs_open_flags flags; + + struct istream *seekable_input; + struct istream *pending_read_input; + + const struct hash_method *write_digest_method; + void *write_digest; + + pool_t metadata_pool; + ARRAY_TYPE(fs_metadata) metadata; + + struct fs_file *copy_src; + struct istream *copy_input; + struct ostream *copy_output; + + struct timeval timing_start[FS_OP_COUNT]; + + bool write_pending:1; + bool writing_stream:1; + bool metadata_changed:1; + + bool read_or_prefetch_counted:1; + bool lookup_metadata_counted:1; + bool stat_counted:1; + bool copy_counted:1; + bool istream_open:1; + bool last_error_changed:1; +}; + +struct fs_lock { + struct fs_file *file; +}; + +struct fs_iter { + /* linked list of all iters */ + struct fs_iter *prev, *next; + + struct fs *fs; + struct event *event; + char *path; + enum fs_iter_flags flags; + struct timeval start_time; + char *last_error; + + bool async_have_more; + fs_file_async_callback_t *async_callback; + void *async_context; +}; + +extern const struct fs fs_class_dict; +extern const struct fs fs_class_posix; +extern const struct fs fs_class_randomfail; +extern const struct fs fs_class_metawrap; +extern const struct fs fs_class_sis; +extern const struct fs fs_class_sis_queue; +extern const struct fs fs_class_test; + +void fs_class_register(const struct fs *fs_class); + +/* Event must be fs_file or fs_iter events. Set errno from err. */ +void fs_set_error(struct event *event, int err, + const char *fmt, ...) ATTR_FORMAT(3, 4); +/* Like fs_set_error(), but use the existing errno. */ +void fs_set_error_errno(struct event *event, const char *fmt, ...) ATTR_FORMAT(2, 3); +void fs_file_set_error_async(struct fs_file *file); + +ssize_t fs_read_via_stream(struct fs_file *file, void *buf, size_t size); +int fs_write_via_stream(struct fs_file *file, const void *data, size_t size); +void fs_metadata_init(struct fs_file *file); +void fs_metadata_init_or_clear(struct fs_file *file); +void fs_default_set_metadata(struct fs_file *file, + const char *key, const char *value); +int fs_get_metadata_full(struct fs_file *file, + enum fs_get_metadata_flags flags, + const ARRAY_TYPE(fs_metadata) **metadata_r); +const char *fs_metadata_find(const ARRAY_TYPE(fs_metadata) *metadata, + const char *key); +int fs_default_copy(struct fs_file *src, struct fs_file *dest); + +void fs_file_timing_end(struct fs_file *file, enum fs_op op); + +struct fs_file * +fs_file_init_parent(struct fs_file *parent, const char *path, + enum fs_open_mode mode, enum fs_open_flags flags); +struct fs_iter * +fs_iter_init_parent(struct fs_iter *parent, + const char *path, enum fs_iter_flags flags); +void fs_file_free(struct fs_file *file); + +/* Same as fs_write_stream_abort_error(), except it closes the *parent* file + and error is left untouched */ +void fs_write_stream_abort_parent(struct fs_file *file, struct ostream **output); + +#endif |