30
32
fs_sis_queue_copy_error(fs);
34
fs_sis_queue_init(const char *args, const struct fs_settings *set)
35
static struct fs *fs_sis_queue_alloc(void)
36
37
struct sis_queue_fs *fs;
37
const char *p, *parent_fs;
39
39
fs = i_new(struct sis_queue_fs, 1);
40
40
fs->fs = fs_class_sis_queue;
45
fs_sis_queue_init(struct fs *_fs, const char *args,
46
const struct fs_settings *set)
48
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
49
const char *p, *parent_name, *parent_args, *error;
42
51
/* <queue_dir>:<parent fs>[:<args>] */
44
53
p = strchr(args, ':');
45
if (p == NULL || p[1] == '\0')
46
i_fatal("fs-sis-queue: Parent filesystem not given as parameter");
54
if (p == NULL || p[1] == '\0') {
55
fs_set_error(_fs, "Parent filesystem not given as parameter");
48
59
fs->queue_dir = i_strdup_until(args, p);
51
p = strchr(parent_fs, ':');
53
fs->super = fs_init(parent_fs, "", set);
62
parent_args = strchr(parent_name, ':');
63
if (parent_args == NULL)
55
fs->super = fs_init(t_strdup_until(parent_fs, p), p+1, set);
66
parent_name = t_strdup_until(parent_name, parent_args++);
67
if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) {
68
fs_set_error(_fs, "%s: %s", parent_name, error);
59
74
static void fs_sis_queue_deinit(struct fs *_fs)
61
76
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
63
fs_deinit(&fs->super);
78
if (fs->super != NULL)
79
fs_deinit(&fs->super);
64
80
i_free(fs->queue_dir);
69
fs_sis_queue_open(struct fs *_fs, const char *path, enum fs_open_mode mode,
70
enum fs_open_flags flags, struct fs_file **file_r)
84
static enum fs_properties fs_sis_queue_get_properties(struct fs *_fs)
86
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
88
return fs_get_properties(fs->super);
91
static struct fs_file *
92
fs_sis_queue_file_init(struct fs *_fs, const char *path,
93
enum fs_open_mode mode, enum fs_open_flags flags)
72
95
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
73
96
struct sis_queue_fs_file *file;
74
struct fs_file *super;
76
if (mode == FS_OPEN_MODE_APPEND) {
77
fs_set_error(_fs, "APPEND mode not supported");
81
if (fs_open(fs->super, path, mode | flags, &super) < 0) {
82
fs_sis_queue_copy_error(fs);
87
case FS_OPEN_MODE_RDONLY:
90
case FS_OPEN_MODE_CREATE:
91
case FS_OPEN_MODE_REPLACE:
93
case FS_OPEN_MODE_APPEND:
97
98
file = i_new(struct sis_queue_fs_file, 1);
98
99
file->file.fs = _fs;
99
file->file.path = i_strdup(fs_file_path(super));
101
*file_r = &file->file;
100
file->file.path = i_strdup(path);
103
if (mode == FS_OPEN_MODE_APPEND)
104
fs_set_error(_fs, "APPEND mode not supported");
106
file->super = fs_file_init(fs->super, path, mode | flags);
105
static void fs_sis_queue_close(struct fs_file *_file)
110
static void fs_sis_queue_file_deinit(struct fs_file *_file)
107
112
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
109
fs_close(&file->super);
114
if (file->super != NULL)
115
fs_file_deinit(&file->super);
110
116
i_free(file->file.path);
120
static void fs_sis_queue_file_close(struct fs_file *_file)
122
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
124
if (file->super != NULL)
125
fs_file_close(file->super);
128
static const char *fs_sis_queue_file_get_path(struct fs_file *_file)
130
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
132
return fs_file_path(file->super);
136
fs_sis_queue_set_async_callback(struct fs_file *_file,
137
fs_file_async_callback_t *callback,
140
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
142
fs_file_set_async_callback(file->super, callback, context);
145
static int fs_sis_queue_wait_async(struct fs *_fs)
147
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
149
return fs_wait_async(fs->super);
153
fs_sis_queue_set_metadata(struct fs_file *_file, const char *key,
156
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
158
fs_set_metadata(file->super, key, value);
162
fs_sis_queue_get_metadata(struct fs_file *_file,
163
const ARRAY_TYPE(fs_metadata) **metadata_r)
165
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
167
return fs_get_metadata(file->super, metadata_r);
170
static bool fs_sis_queue_prefetch(struct fs_file *_file, uoff_t length)
172
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
174
return fs_prefetch(file->super, length);
114
177
static ssize_t fs_sis_queue_read(struct fs_file *_file, void *buf, size_t size)
116
179
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
145
208
queue_path = t_strdup_printf("%s/%s", fs->queue_dir, fname);
146
if (fs_open(fs->super, queue_path,
147
FS_OPEN_MODE_CREATE | FS_OPEN_FLAG_MKDIR,
149
i_error("fs-sis-queue: %s", fs_last_error(fs->super));
209
queue_file = fs_file_init(fs->super, queue_path, FS_OPEN_MODE_CREATE);
152
210
if (fs_write(queue_file, "", 0) < 0 && errno != EEXIST)
153
211
i_error("fs-sis-queue: %s", fs_last_error(fs->super));
154
fs_close(&queue_file);
212
fs_file_deinit(&queue_file);
157
215
static int fs_sis_queue_write(struct fs_file *_file, const void *data, size_t size)
159
217
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
219
if (file->super == NULL)
161
221
if (fs_write(file->super, data, size) < 0) {
162
222
fs_sis_queue_file_copy_error(file);
218
static int fs_sis_queue_fdatasync(struct fs_file *_file)
220
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
222
if (fs_fdatasync(file->super) < 0) {
223
fs_sis_queue_file_copy_error(file);
229
static int fs_sis_queue_exists(struct fs *_fs, const char *path)
231
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
233
if (fs_exists(fs->super, path) < 0) {
234
fs_sis_queue_copy_error(fs);
240
static int fs_sis_queue_stat(struct fs *_fs, const char *path,
243
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
245
if (fs_stat(fs->super, path, st_r) < 0) {
246
fs_sis_queue_copy_error(fs);
252
static int fs_sis_queue_link(struct fs *_fs, const char *src, const char *dest)
254
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
256
if (fs_link(fs->super, src, dest) < 0) {
257
fs_sis_queue_copy_error(fs);
284
static int fs_sis_queue_exists(struct fs_file *_file)
286
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
288
if (fs_exists(file->super) < 0) {
289
fs_sis_queue_copy_error(file->fs);
295
static int fs_sis_queue_stat(struct fs_file *_file, struct stat *st_r)
297
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
299
if (fs_stat(file->super, st_r) < 0) {
300
fs_sis_queue_copy_error(file->fs);
306
static int fs_sis_queue_copy(struct fs_file *_src, struct fs_file *_dest)
308
struct sis_queue_fs_file *src = (struct sis_queue_fs_file *)_src;
309
struct sis_queue_fs_file *dest = (struct sis_queue_fs_file *)_dest;
311
if (fs_copy(src->super, dest->super) < 0) {
312
fs_sis_queue_copy_error(src->fs);
264
fs_sis_queue_rename(struct fs *_fs, const char *src, const char *dest)
319
fs_sis_queue_rename(struct fs_file *_src, struct fs_file *_dest)
266
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
321
struct sis_queue_fs_file *src = (struct sis_queue_fs_file *)_src;
322
struct sis_queue_fs_file *dest = (struct sis_queue_fs_file *)_dest;
268
if (fs_rename(fs->super, src, dest) < 0) {
269
fs_sis_queue_copy_error(fs);
324
if (fs_rename(src->super, dest->super) < 0) {
325
fs_sis_queue_copy_error(src->fs);
275
static int fs_sis_queue_unlink(struct fs *_fs, const char *path)
331
static int fs_sis_queue_delete(struct fs_file *_file)
277
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
333
struct sis_queue_fs_file *file = (struct sis_queue_fs_file *)_file;
280
fs_sis_try_unlink_hash_file(&fs->fs, fs->super, path);
336
fs_sis_try_unlink_hash_file(_file->fs, file->super);
282
if (fs_unlink(fs->super, path) < 0) {
283
fs_sis_queue_copy_error(fs);
338
if (fs_delete(file->super) < 0) {
339
fs_sis_queue_copy_error(file->fs);
289
static int fs_sis_queue_rmdir(struct fs *_fs, const char *path)
345
static struct fs_iter *
346
fs_sis_queue_iter_init(struct fs *_fs, const char *path,
347
enum fs_iter_flags flags)
291
349
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
293
if (fs_rmdir(fs->super, path) < 0) {
294
fs_sis_queue_copy_error(fs);
351
return fs_iter_init(fs->super, path, flags);
300
struct fs fs_class_sis_queue = {
354
const struct fs fs_class_sis_queue = {
301
355
.name = "sis-queue",
303
358
fs_sis_queue_init,
304
359
fs_sis_queue_deinit,
360
fs_sis_queue_get_properties,
361
fs_sis_queue_file_init,
362
fs_sis_queue_file_deinit,
363
fs_sis_queue_file_close,
364
fs_sis_queue_file_get_path,
365
fs_sis_queue_set_async_callback,
366
fs_sis_queue_wait_async,
367
fs_sis_queue_set_metadata,
368
fs_sis_queue_get_metadata,
369
fs_sis_queue_prefetch,
307
370
fs_sis_queue_read,
308
371
fs_sis_queue_read_stream,
309
372
fs_sis_queue_write,