11
FS_PROPERTY_METADATA = 0x01,
12
FS_PROPERTY_LOCKS = 0x02,
13
FS_PROPERTY_FASTCOPY = 0x04,
14
FS_PROPERTY_RENAME = 0x08,
15
FS_PROPERTY_STAT = 0x10,
16
/* Iteration is possible */
17
FS_PROPERTY_ITER = 0x20,
18
/* Iteration always returns all of the files (instead of possibly
19
slightly out of date view) */
20
FS_PROPERTY_RELIABLEITER= 0x40,
21
/* Backend uses directories, which aren't automatically deleted
22
when its children are deleted. */
23
FS_PROPERTY_DIRECTORIES = 0x80,
24
FS_PROPERTY_WRITE_HASH_MD5 = 0x100,
25
FS_PROPERTY_WRITE_HASH_SHA256 = 0x200
9
29
/* Open only for reading, or fail with ENOENT if it doesn't exist */
30
FS_OPEN_MODE_READONLY,
11
31
/* Create a new file, fail with EEXIST if it already exists */
12
32
FS_OPEN_MODE_CREATE,
33
/* Create a new file with a new unique name. The generated name is a
34
128bit hex-encoded string. The fs_open()'s path parameter specifies
35
only the directory where the file is created to. */
36
FS_OPEN_MODE_CREATE_UNIQUE_128,
13
37
/* Create or replace a file */
14
38
FS_OPEN_MODE_REPLACE,
15
39
/* Append to existing file, fail with ENOENT if it doesn't exist */
21
45
enum fs_open_flags {
22
/* Call fdatasync() on files after writes */
23
FS_OPEN_FLAG_FDATASYNC = 0x10,
24
/* Create any missing parent directories for new files */
25
FS_OPEN_FLAG_MKDIR = 0x20
46
/* File is important and writing must call fsync() or have equivalent
48
FS_OPEN_FLAG_FSYNC = 0x10,
49
/* Asynchronous writes: fs_write() will fail with EAGAIN if it needs to
50
be called again (the retries can use size=0). For streams
51
fs_write_stream_finish() may request retrying with 0.
53
Asynchronous reads: fs_read() will fail with EAGAIN if it's not
54
finished and fs_read_stream() returns a nonblocking stream. */
55
FS_OPEN_FLAG_ASYNC = 0x20,
56
/* fs_read_stream() must return a seekable input stream */
57
FS_OPEN_FLAG_SEEKABLE = 0x40,
58
/* Backend should handle this file's operations immediately without
59
any additional command queueing. The caller is assumed to be the one
60
doing any rate limiting if needed. This flag can only be used with
61
ASYNC flag, synchronous requests are never queued. */
62
FS_OPEN_FLAG_ASYNC_NOQUEUE = 0x80
66
/* Iterate only directories, not files */
67
FS_ITER_FLAG_DIRS = 0x01,
68
/* Request asynchronous iteration. */
69
FS_ITER_FLAG_ASYNC = 0x02
28
72
struct fs_settings {
73
/* Dovecot instance's base_dir */
75
/* Directory where temporary files can be created at any time
76
(e.g. /tmp or mail_temp_dir) */
78
/* SSL client settings. */
79
const struct ssl_iostream_settings *ssl_client_set;
81
/* Automatically try to rmdir() directories up to this path when
83
const char *root_path;
29
84
/* When creating temporary files, use this prefix
30
85
(to avoid conflicts with existing files). */
31
86
const char *temp_file_prefix;
34
struct fs *fs_init(const char *driver, const char *args,
35
const struct fs_settings *set);
87
/* If the backend needs to do DNS lookups, use this dns_client for
89
struct dns_client *dns_client;
91
/* Enable debugging */
99
ARRAY_DEFINE_TYPE(fs_metadata, struct fs_metadata);
101
typedef void fs_file_async_callback_t(void *context);
103
int fs_init(const char *driver, const char *args,
104
const struct fs_settings *set,
105
struct fs **fs_r, const char **error_r);
36
106
void fs_deinit(struct fs **fs);
38
/* Returns 0 if opened, -1 if error (errno is set). */
39
int fs_open(struct fs *fs, const char *path, int mode_flags,
40
struct fs_file **file_r);
41
void fs_close(struct fs_file **file);
43
/* Returns the path given to fs_open(). */
108
/* Returns the root fs's driver name (bypassing all wrapper fses) */
109
const char *fs_get_root_driver(struct fs *fs);
111
struct fs_file *fs_file_init(struct fs *fs, const char *path, int mode_flags);
112
void fs_file_deinit(struct fs_file **file);
114
/* If the file has an input streams open, close them. */
115
void fs_file_close(struct fs_file *file);
117
/* Return properties supported by backend. */
118
enum fs_properties fs_get_properties(struct fs *fs);
120
/* Add/replace metadata when saving a file. This makes sense only when the
121
file is being created/replaced. */
122
void fs_set_metadata(struct fs_file *file, const char *key, const char *value);
123
/* Return file's all metadata. */
124
int fs_get_metadata(struct fs_file *file,
125
const ARRAY_TYPE(fs_metadata) **metadata_r);
127
/* Returns the path given to fs_open(). If file was opened with
128
FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished,
129
return the path including the generated filename. */
44
130
const char *fs_file_path(struct fs_file *file);
131
/* Returns the file's fs. */
132
struct fs *fs_file_fs(struct fs_file *file);
46
134
/* Return the error message for the last failed operation. */
47
135
const char *fs_last_error(struct fs *fs);
48
136
/* Convenience function for the above. Errors aren't preserved across files. */
49
137
const char *fs_file_last_error(struct fs_file *file);
139
/* Try to asynchronously prefetch file into memory. Returns TRUE if file is
140
already in memory (i.e. caller should handle this file before prefetching
141
more), FALSE if not. The length is a hint of how much the caller expects
142
to read, but it may be more or less (0=whole file). */
143
bool fs_prefetch(struct fs_file *file, uoff_t length);
51
144
/* Returns >0 if something was read, -1 if error (errno is set). */
52
145
ssize_t fs_read(struct fs_file *file, void *buf, size_t size);
53
146
/* Returns a stream for reading from file. Multiple streams can be opened,
66
159
struct ostream *fs_write_stream(struct fs_file *file);
67
160
/* Finish writing via stream. The file will be created/replaced/appended only
68
161
after this call, same as with fs_write(). Anything written to the stream
69
won't be visible earlier. */
162
won't be visible earlier. Returns 1 if ok, 0 if async write isn't finished
163
yet (retry calling fs_write_stream_finish_async()), -1 if error */
70
164
int fs_write_stream_finish(struct fs_file *file, struct ostream **output);
165
int fs_write_stream_finish_async(struct fs_file *file);
71
166
/* Abort writing via stream. Anything written to the stream is discarded. */
72
167
void fs_write_stream_abort(struct fs_file *file, struct ostream **output);
169
/* Set a hash to the following write. The storage can then verify that the
170
input data matches the specified hash, or fail if it doesn't. Typically
171
implemented by Content-MD5 header. */
172
void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
175
/* Call the specified callback whenever the file can be read/written to.
176
May call the callback immediately. */
177
void fs_file_set_async_callback(struct fs_file *file,
178
fs_file_async_callback_t *callback,
180
/* Wait until some file can be read/written to more before returning.
181
It's an error to call this when there are no pending async operations.
182
Returns 0 if ok, -1 if timed out. */
183
int fs_wait_async(struct fs *fs);
185
/* Returns 1 if file exists, 0 if not, -1 if error occurred. */
186
int fs_exists(struct fs_file *file);
187
/* Delete a file. Returns 0 if file was actually deleted by us, -1 if error. */
188
int fs_delete(struct fs_file *file);
190
/* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT).
191
All fs backends may not support all stat fields. */
192
int fs_stat(struct fs_file *file, struct stat *st_r);
193
/* Copy an object with possibly updated metadata. Destination parent
194
directories are created automatically. Returns 0 if ok, -1 if error
196
int fs_copy(struct fs_file *src, struct fs_file *dest);
197
/* Try to finish asynchronous fs_copy(). Returns the same as fs_copy(). */
198
int fs_copy_finish_async(struct fs_file *dest);
199
/* Atomically rename a file. Destination parent directories are created
200
automatically. Returns 0 if ok, -1 if error occurred. */
201
int fs_rename(struct fs_file *src, struct fs_file *dest);
74
203
/* Exclusively lock a file. If file is already locked, wait for it for given
75
204
number of seconds (0 = fail immediately). Returns 1 if locked, 0 if wait
76
205
timed out, -1 if error. */
77
206
int fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r);
78
207
void fs_unlock(struct fs_lock **lock);
80
/* Make sure all written data is flushed to disk. */
81
int fs_fdatasync(struct fs_file *file);
209
/* Iterate through all files or directories in the given directory.
210
Doesn't recurse to child directories. It's not an error to iterate a
211
nonexistent directory. */
213
fs_iter_init(struct fs *fs, const char *path, enum fs_iter_flags flags);
214
/* Returns 0 if ok, -1 if iteration failed. */
215
int fs_iter_deinit(struct fs_iter **iter);
216
/* Returns the next filename. */
217
const char *fs_iter_next(struct fs_iter *iter);
83
/* Returns 1 if file exists, 0 if not, -1 if error occurred. */
84
int fs_exists(struct fs *fs, const char *path);
85
/* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT).
86
All fs backends may not support all stat fields. */
87
int fs_stat(struct fs *fs, const char *path, struct stat *st_r);
88
/* Create a hard link. Destination parent directories are created
89
automatically. Returns 0 if ok, -1 if error occurred
90
(errno=EXDEV if hard links not supported by backend). */
91
int fs_link(struct fs *fs, const char *src, const char *dest);
92
/* Atomically rename a file. Destination parent directories are created
93
automatically. Returns 0 if ok, -1 if error occurred
94
(errno=EXDEV if hard links not supported by backend). */
95
int fs_rename(struct fs *fs, const char *src, const char *dest);
97
int fs_unlink(struct fs *fs, const char *path);
98
/* Delete a directory. Returns 0 if ok, -1 if error occurred. */
99
int fs_rmdir(struct fs *fs, const char *path);
219
/* For asynchronous iterations: Specify the callback that is called whenever
220
there's more data available for reading. */
221
void fs_iter_set_async_callback(struct fs_iter *iter,
222
fs_file_async_callback_t *callback,
224
/* For asynchronous iterations: If fs_iter_next() returns NULL, use this
225
function to determine if you should wait for more data or finish up. */
226
bool fs_iter_have_more(struct fs_iter *iter);