fs-sis-queue.c revision 5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "lib.h"
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen#include "str.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "istream.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "ostream.h"
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen#include "fs-sis-common.h"
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#define QUEUE_DIR_NAME "queue"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstruct sis_queue_fs {
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen struct fs fs;
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen struct fs *super;
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen char *queue_dir;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen};
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstruct sis_queue_fs_file {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct fs_file file;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen struct sis_queue_fs *fs;
6b0e35b29f65a95fe8ae22ed8b5f0f36720c9f45Timo Sirainen struct fs_file *super;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen};
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainenstatic void fs_sis_queue_copy_error(struct sis_queue_fs *fs)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen fs_set_error(&fs->fs, "%s", fs_last_error(fs->super));
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen}
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic void fs_sis_queue_file_copy_error(struct sis_queue_fs_file *file)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct sis_queue_fs *fs = (struct sis_queue_fs *)file->file.fs;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen fs_sis_queue_copy_error(fs);
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov}
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitovstatic struct fs *fs_sis_queue_alloc(void)
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov{
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov struct sis_queue_fs *fs;
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen fs = i_new(struct sis_queue_fs, 1);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen fs->fs = fs_class_sis_queue;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return &fs->fs;
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen}
eca38954bcf972618f6b85932a3690acbd2b673aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic int
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitovfs_sis_queue_init(struct fs *_fs, const char *args,
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov const struct fs_settings *set)
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov{
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov const char *p, *parent_name, *parent_args, *error;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen /* <queue_dir>:<parent fs>[:<args>] */
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen p = strchr(args, ':');
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (p == NULL || p[1] == '\0') {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen fs_set_error(_fs, "Parent filesystem not given as parameter");
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return -1;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen fs->queue_dir = i_strdup_until(args, p);
fde14422caabc3c4ac4a6c5e3e5cf176cedd90a6Timo Sirainen parent_name = p + 1;
fde14422caabc3c4ac4a6c5e3e5cf176cedd90a6Timo Sirainen
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen parent_args = strchr(parent_name, ':');
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (parent_args == NULL)
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen parent_args = "";
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen else
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen parent_name = t_strdup_until(parent_name, parent_args++);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) {
f0339f522dc9c8e2e8a29ef9a3f937c431c6bd1bTimo Sirainen fs_set_error(_fs, "%s: %s", parent_name, error);
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen return -1;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen return 0;
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen}
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainenstatic void fs_sis_queue_deinit(struct fs *_fs)
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen{
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen
20e04227229970d148801c507946666e2a9bd838Timo Sirainen if (fs->super != NULL)
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen fs_deinit(&fs->super);
10399559650f552a23949772be79eb6a80198c5aTimo Sirainen i_free(fs->queue_dir);
eca38954bcf972618f6b85932a3690acbd2b673aTimo Sirainen i_free(fs);
10399559650f552a23949772be79eb6a80198c5aTimo Sirainen}
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic enum fs_properties fs_sis_queue_get_properties(struct fs *_fs)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen{
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return fs_get_properties(fs->super);
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen}
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomistatic struct fs_file *
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomifs_sis_queue_file_init(struct fs *_fs, const char *path,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen enum fs_open_mode mode, enum fs_open_flags flags)
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomi{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct sis_queue_fs_file *file;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen file = i_new(struct sis_queue_fs_file, 1);
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen file->file.fs = _fs;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen file->file.path = i_strdup(path);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen file->fs = fs;
e392fcb39a06609af20a9e79017683f194de3ddeTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (mode == FS_OPEN_MODE_APPEND)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen fs_set_error(_fs, "APPEND mode not supported");
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen else
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen file->super = fs_file_init(fs->super, path, mode | flags);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return &file->file;
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen}
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvistatic void fs_sis_queue_file_deinit(struct fs_file *_file)
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi{
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen if (file->super != NULL)
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi fs_file_deinit(&file->super);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_free(file->file.path);
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi i_free(file);
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi}
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenstatic const char *fs_sis_queue_file_get_path(struct fs_file *_file)
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi{
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi return fs_file_path(file->super);
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi}
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvistatic void
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvifs_sis_queue_set_async_callback(struct fs_file *_file,
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi fs_file_async_callback_t *callback,
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi void *context)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi{
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi fs_file_set_async_callback(file->super, callback, context);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen}
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainenstatic int fs_sis_queue_wait_async(struct fs *_fs)
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen{
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen return fs_wait_async(fs->super);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen}
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenstatic void
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenfs_sis_queue_set_metadata(struct fs_file *_file, const char *key,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const char *value)
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen{
a525be16a69367f43765d20c873b5f168c5b7ea3Martti Rannanjärvi struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
a525be16a69367f43765d20c873b5f168c5b7ea3Martti Rannanjärvi
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen fs_set_metadata(file->super, key, value);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen}
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
f8ead0942a9b7c8fcf91414ed1b534d5807ca555Timo Sirainenstatic int
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenfs_sis_queue_get_metadata(struct fs_file *_file,
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen const ARRAY_TYPE(fs_metadata) **metadata_r)
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen{
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen return fs_get_metadata(file->super, metadata_r);
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen}
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvistatic bool fs_sis_queue_prefetch(struct fs_file *_file, uoff_t length)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi{
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi return fs_prefetch(file->super, length);
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi}
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvistatic ssize_t fs_sis_queue_read(struct fs_file *_file, void *buf, size_t size)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi{
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi ssize_t ret;
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi if ((ret = fs_read(file->super, buf, size)) < 0)
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi fs_sis_queue_file_copy_error(file);
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi return ret;
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi}
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvistatic struct istream *
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvifs_sis_queue_read_stream(struct fs_file *_file, size_t max_buffer_size)
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi{
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return fs_read_stream(file->super, max_buffer_size);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen}
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainenstatic void fs_sis_queue_add(struct sis_queue_fs_file *file)
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen{
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi struct sis_queue_fs *fs = (struct sis_queue_fs *)file->file.fs;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen struct fs_file *queue_file;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen const char *fname, *path, *queue_path;
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi path = fs_file_path(&file->file);
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen fname = strrchr(path, '/');
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen if (fname != NULL)
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen fname++;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen else
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen fname = path;
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen queue_path = t_strdup_printf("%s/%s", fs->queue_dir, fname);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen queue_file = fs_file_init(fs->super, queue_path, FS_OPEN_MODE_CREATE);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen if (fs_write(queue_file, "", 0) < 0 && errno != EEXIST)
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen i_error("fs-sis-queue: %s", fs_last_error(fs->super));
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen fs_file_deinit(&queue_file);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen}
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainenstatic int fs_sis_queue_write(struct fs_file *_file, const void *data, size_t size)
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen{
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (file->super == NULL)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return -1;
7b3b617e946d5b32078baa821f5fc05f775e1dfeMartti Rannanjärvi if (fs_write(file->super, data, size) < 0) {
7b3b617e946d5b32078baa821f5fc05f775e1dfeMartti Rannanjärvi fs_sis_queue_file_copy_error(file);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return -1;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen T_BEGIN {
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen fs_sis_queue_add(file);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen } T_END;
39dea5f2e78f6bfc3adc0655176f596ee211938fTimo Sirainen return 0;
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi}
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainenstatic void fs_sis_queue_write_stream(struct fs_file *_file)
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen{
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen i_assert(_file->output == NULL);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen if (file->super == NULL)
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen _file->output = o_stream_create_error(EINVAL);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen else
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen _file->output = fs_write_stream(file->super);
8f7e81b327b8b5bf34262f6755df6d4481760d23Timo Sirainen o_stream_set_name(_file->output, _file->path);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen}
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenstatic int fs_sis_queue_write_stream_finish(struct fs_file *_file, bool success)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen if (!success) {
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen if (file->super != NULL) {
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen fs_write_stream_abort(file->super, &_file->output);
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen fs_sis_queue_file_copy_error(file);
c4478af52de63804efef2055580adf1dfc8679c6Timo Sirainen }
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen return -1;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen }
c4478af52de63804efef2055580adf1dfc8679c6Timo Sirainen
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen if (fs_write_stream_finish(file->super, &_file->output) < 0) {
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen fs_sis_queue_file_copy_error(file);
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen return -1;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen }
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi T_BEGIN {
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi fs_sis_queue_add(file);
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi } T_END;
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi return 1;
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi}
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvistatic int
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvifs_sis_queue_lock(struct fs_file *_file, unsigned int secs,
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi struct fs_lock **lock_r)
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
if (fs_lock(file->super, secs, lock_r) < 0) {
fs_sis_queue_file_copy_error(file);
return -1;
}
return 0;
}
static void fs_sis_queue_unlock(struct fs_lock *_lock ATTR_UNUSED)
{
i_unreached();
}
static int fs_sis_queue_exists(struct fs_file *_file)
{
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
if (fs_exists(file->super) < 0) {
fs_sis_queue_copy_error(file->fs);
return -1;
}
return 0;
}
static int fs_sis_queue_stat(struct fs_file *_file, struct stat *st_r)
{
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
if (fs_stat(file->super, st_r) < 0) {
fs_sis_queue_copy_error(file->fs);
return -1;
}
return 0;
}
static int fs_sis_queue_copy(struct fs_file *_src, struct fs_file *_dest)
{
struct sis_queue_fs_file *src = (struct sis_queue_fs_file *)_src;
struct sis_queue_fs_file *dest = (struct sis_queue_fs_file *)_dest;
if (fs_copy(src->super, dest->super) < 0) {
fs_sis_queue_copy_error(src->fs);
return -1;
}
return 0;
}
static int
fs_sis_queue_rename(struct fs_file *_src, struct fs_file *_dest)
{
struct sis_queue_fs_file *src = (struct sis_queue_fs_file *)_src;
struct sis_queue_fs_file *dest = (struct sis_queue_fs_file *)_dest;
if (fs_rename(src->super, dest->super) < 0) {
fs_sis_queue_copy_error(src->fs);
return -1;
}
return 0;
}
static int fs_sis_queue_delete(struct fs_file *_file)
{
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
T_BEGIN {
fs_sis_try_unlink_hash_file(_file->fs, file->super);
} T_END;
if (fs_delete(file->super) < 0) {
fs_sis_queue_copy_error(file->fs);
return -1;
}
return 0;
}
static struct fs_iter *
fs_sis_queue_iter_init(struct fs *_fs, const char *path,
enum fs_iter_flags flags)
{
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
return fs_iter_init(fs->super, path, flags);
}
const struct fs fs_class_sis_queue = {
.name = "sis-queue",
.v = {
fs_sis_queue_alloc,
fs_sis_queue_init,
fs_sis_queue_deinit,
fs_sis_queue_get_properties,
fs_sis_queue_file_init,
fs_sis_queue_file_deinit,
fs_sis_queue_file_get_path,
fs_sis_queue_set_async_callback,
fs_sis_queue_wait_async,
fs_sis_queue_set_metadata,
fs_sis_queue_get_metadata,
fs_sis_queue_prefetch,
fs_sis_queue_read,
fs_sis_queue_read_stream,
fs_sis_queue_write,
fs_sis_queue_write_stream,
fs_sis_queue_write_stream_finish,
fs_sis_queue_lock,
fs_sis_queue_unlock,
fs_sis_queue_exists,
fs_sis_queue_stat,
fs_sis_queue_copy,
fs_sis_queue_rename,
fs_sis_queue_delete,
fs_sis_queue_iter_init,
NULL,
NULL
}
};