struct metawrap_fs_file {
struct fs_file file;
struct metawrap_fs *fs;
- struct fs_file *super, *super_read;
+ struct fs_file *super_read;
enum fs_open_mode open_mode;
struct istream *input;
bool metadata_read;
bool metadata_changed_since_write;
};
-struct metawrap_fs_iter {
- struct fs_iter iter;
- struct fs_iter *super;
-};
-
static struct fs *fs_metawrap_alloc(void)
{
struct metawrap_fs *fs;
/* avoid unnecessarily creating two seekable streams */
flags &= ~FS_OPEN_FLAG_SEEKABLE;
- file->super = fs_file_init(_fs->parent, path, mode | flags);
+ file->file.parent = fs_file_init(_fs->parent, path, mode | flags);
if (file->fs->wrap_metadata && mode == FS_OPEN_MODE_READONLY &&
(flags & FS_OPEN_FLAG_ASYNC) == 0) {
- /* use async stream for super, so fs_read_stream() won't create
+ /* use async stream for parent, so fs_read_stream() won't create
another seekable stream unneededly */
file->super_read = fs_file_init(_fs->parent, path, mode | flags |
FS_OPEN_FLAG_ASYNC);
} else {
- file->super_read = file->super;
+ file->super_read = file->file.parent;
}
fs_metadata_init(&file->file);
return &file->file;
{
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
- if (file->super_read != file->super && file->super_read != NULL)
+ if (file->super_read != _file->parent && file->super_read != NULL)
fs_file_deinit(&file->super_read);
if (file->metadata_header != NULL)
str_free(&file->metadata_header);
- fs_file_deinit(&file->super);
+ fs_file_deinit(&_file->parent);
i_free(file->file.path);
i_free(file);
}
i_stream_unref(&file->input);
if (file->super_read != NULL)
fs_file_close(file->super_read);
- if (file->super != NULL)
- fs_file_close(file->super);
-}
-
-static const char *fs_metawrap_file_get_path(struct fs_file *_file)
-{
- struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
-
- return fs_file_path(file->super);
-}
-
-static void
-fs_metawrap_set_async_callback(struct fs_file *_file,
- fs_file_async_callback_t *callback,
- void *context)
-{
- struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
-
- fs_file_set_async_callback(file->super, callback, context);
-}
-
-static int fs_metawrap_wait_async(struct fs *_fs)
-{
- return fs_wait_async(_fs->parent);
+ if (_file->parent != NULL)
+ fs_file_close(_file->parent);
}
static void
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
if (!file->fs->wrap_metadata)
- fs_set_metadata(file->super, key, value);
+ fs_set_metadata(_file->parent, key, value);
else {
fs_default_set_metadata(_file, key, value);
file->metadata_changed_since_write = TRUE;
char c;
if (!file->fs->wrap_metadata)
- return fs_get_metadata(file->super, metadata_r);
+ return fs_get_metadata(_file->parent, metadata_r);
if (file->metadata_read) {
/* we have the metadata */
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
if (!file->fs->wrap_metadata)
- return fs_prefetch(file->super, length);
+ return fs_prefetch(_file->parent, length);
else
return fs_prefetch(file->super_read, length);
}
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
if (!file->fs->wrap_metadata)
- return fs_read(file->super, buf, size);
+ return fs_read(_file->parent, buf, size);
return fs_read_via_stream(_file, buf, size);
}
struct istream *input;
if (!file->fs->wrap_metadata)
- return fs_read_stream(file->super, max_buffer_size);
+ return fs_read_stream(_file->parent, max_buffer_size);
if (file->input != NULL) {
i_stream_ref(file->input);
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
if (!file->fs->wrap_metadata)
- return fs_write(file->super, data, size);
+ return fs_write(_file->parent, data, size);
return fs_write_via_stream(_file, data, size);
}
i_assert(_file->output == NULL);
if (!file->fs->wrap_metadata) {
- file->super_output = fs_write_stream(file->super);
+ file->super_output = fs_write_stream(_file->parent);
_file->output = file->super_output;
} else {
file->temp_output =
if (file->super_output != NULL) {
/* no metawrap */
i_assert(file->temp_output == NULL);
- fs_write_stream_abort(file->super, &file->super_output);
+ fs_write_stream_abort(_file->parent, &file->super_output);
} else {
i_assert(file->temp_output != NULL);
o_stream_destroy(&file->temp_output);
if (file->super_output != NULL) {
/* no metawrap */
i_assert(file->temp_output == NULL);
- return fs_write_stream_finish(file->super, &file->super_output);
+ return fs_write_stream_finish(_file->parent, &file->super_output);
}
if (file->temp_output == NULL) {
/* finishing up */
i_assert(file->super_output == NULL);
- return fs_write_stream_finish_async(file->super);
+ return fs_write_stream_finish_async(_file->parent);
}
/* finish writing the temporary file */
input = iostream_temp_finish(&file->temp_output, IO_BLOCK_SIZE);
input = fs_metawrap_create_updated_istream(file, input);
i_stream_unref(&input2);
}
- file->super_output = fs_write_stream(file->super);
+ file->super_output = fs_write_stream(_file->parent);
(void)o_stream_send_istream(file->super_output, input);
if (input->stream_errno != 0) {
fs_set_error(_file->fs, "read(%s) failed: %s",
i_stream_get_name(input),
i_stream_get_error(input));
- fs_write_stream_abort(file->super, &file->super_output);
+ fs_write_stream_abort(_file->parent, &file->super_output);
ret = -1;
} else if (file->super_output->stream_errno != 0) {
fs_set_error(_file->fs, "write(%s) failed: %s",
o_stream_get_name(file->super_output),
o_stream_get_error(file->super_output));
- fs_write_stream_abort(file->super, &file->super_output);
+ fs_write_stream_abort(_file->parent, &file->super_output);
ret = -1;
} else {
i_assert(i_stream_is_eof(input));
- ret = fs_write_stream_finish(file->super, &file->super_output);
+ ret = fs_write_stream_finish(_file->parent, &file->super_output);
}
i_stream_unref(&input);
return ret;
}
-static int
-fs_metawrap_lock(struct fs_file *_file, unsigned int secs, struct fs_lock **lock_r)
-{
- struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
-
- return fs_lock(file->super, secs, lock_r);
-}
-
-static void fs_metawrap_unlock(struct fs_lock *_lock ATTR_UNUSED)
-{
- i_unreached();
-}
-
-static int fs_metawrap_exists(struct fs_file *_file)
-{
- struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
-
- return fs_exists(file->super);
-}
-
static int fs_metawrap_stat(struct fs_file *_file, struct stat *st_r)
{
struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
ssize_t ret;
if (!file->fs->wrap_metadata)
- return fs_stat(file->super, st_r);
+ return fs_stat(_file->parent, st_r);
if (file->metadata_write_size != 0) {
/* fs_stat() after a write. we can do this quickly. */
- if (fs_stat(file->super, st_r) < 0)
+ if (fs_stat(_file->parent, st_r) < 0)
return -1;
if ((uoff_t)st_r->st_size < file->metadata_write_size) {
fs_set_error(_file->fs,
return -1;
}
- if (fs_stat(file->super, st_r) < 0) {
+ if (fs_stat(_file->parent, st_r) < 0) {
i_assert(errno != EAGAIN); /* read should have caught this */
return -1;
}
static int fs_metawrap_copy(struct fs_file *_src, struct fs_file *_dest)
{
- struct metawrap_fs_file *src = (struct metawrap_fs_file *)_src;
- struct metawrap_fs_file *dest = (struct metawrap_fs_file *)_dest;
-
- if (!dest->fs->wrap_metadata || !_dest->metadata_changed) {
- if (_src != NULL)
- return fs_copy(src->super, dest->super);
- else
- return fs_copy_finish_async(dest->super);
- }
- return fs_default_copy(_src, _dest);
-}
-
-static int fs_metawrap_rename(struct fs_file *_src, struct fs_file *_dest)
-{
- struct metawrap_fs_file *src = (struct metawrap_fs_file *)_src;
struct metawrap_fs_file *dest = (struct metawrap_fs_file *)_dest;
- return fs_rename(src->super, dest->super);
-}
-
-static int fs_metawrap_delete(struct fs_file *_file)
-{
- struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file;
-
- return fs_delete(file->super);
-}
-
-static struct fs_iter *
-fs_metawrap_iter_init(struct fs *_fs, const char *path,
- enum fs_iter_flags flags)
-{
- struct metawrap_fs_iter *iter;
-
- iter = i_new(struct metawrap_fs_iter, 1);
- iter->iter.fs = _fs;
- iter->iter.flags = flags;
- iter->super = fs_iter_init(_fs->parent, path, flags);
- return &iter->iter;
-}
-
-static const char *fs_metawrap_iter_next(struct fs_iter *_iter)
-{
- struct metawrap_fs_iter *iter = (struct metawrap_fs_iter *)_iter;
- const char *fname;
-
- iter->super->async_callback = _iter->async_callback;
- iter->super->async_context = _iter->async_context;
-
- fname = fs_iter_next(iter->super);
- _iter->async_have_more = iter->super->async_have_more;
- return fname;
-}
-
-static int fs_metawrap_iter_deinit(struct fs_iter *_iter)
-{
- struct metawrap_fs_iter *iter = (struct metawrap_fs_iter *)_iter;
- int ret;
-
- ret = fs_iter_deinit(&iter->super);
- i_free(iter);
- return ret;
+ if (!dest->fs->wrap_metadata || !_dest->metadata_changed)
+ return fs_wrapper_copy(_src, _dest);
+ else
+ return fs_default_copy(_src, _dest);
}
const struct fs fs_class_metawrap = {
fs_metawrap_file_init,
fs_metawrap_file_deinit,
fs_metawrap_file_close,
- fs_metawrap_file_get_path,
- fs_metawrap_set_async_callback,
- fs_metawrap_wait_async,
+ fs_wrapper_file_get_path,
+ fs_wrapper_set_async_callback,
+ fs_wrapper_wait_async,
fs_metawrap_set_metadata,
fs_metawrap_get_metadata,
fs_metawrap_prefetch,
fs_metawrap_write,
fs_metawrap_write_stream,
fs_metawrap_write_stream_finish,
- fs_metawrap_lock,
- fs_metawrap_unlock,
- fs_metawrap_exists,
+ fs_wrapper_lock,
+ fs_wrapper_unlock,
+ fs_wrapper_exists,
fs_metawrap_stat,
fs_metawrap_copy,
- fs_metawrap_rename,
- fs_metawrap_delete,
- fs_metawrap_iter_init,
- fs_metawrap_iter_next,
- fs_metawrap_iter_deinit,
+ fs_wrapper_rename,
+ fs_wrapper_delete,
+ fs_wrapper_iter_init,
+ fs_wrapper_iter_next,
+ fs_wrapper_iter_deinit,
NULL
}
};