fs-api.h revision 2766f1de8141c09767a959d2d2c3065c5a300bf0
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen#ifndef FS_API_H
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen#define FS_API_H
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenstruct stat;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenstruct fs;
00bf64c70c231f647c12c2fd49925ef73cb07f07Timo Sirainenstruct fs_file;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenstruct fs_lock;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenenum fs_properties {
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen FS_PROPERTY_METADATA = 0x01,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_PROPERTY_LOCKS = 0x02,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_PROPERTY_FASTCOPY = 0x04,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_PROPERTY_RENAME = 0x08,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_PROPERTY_STAT = 0x10
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen};
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenenum fs_open_mode {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Open only for reading, or fail with ENOENT if it doesn't exist */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_MODE_READONLY,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Create a new file, fail with EEXIST if it already exists */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_MODE_CREATE,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Create a new file with a new unique name. The generated name is a
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen 128bit hex-encoded string. The fs_open()'s path parameter specifies
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen only the directory where the file is created to. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_MODE_CREATE_UNIQUE_128,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Create or replace a file */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_MODE_REPLACE,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Append to existing file, fail with ENOENT if it doesn't exist */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_MODE_APPEND
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen#define FS_OPEN_MODE_MASK 0x0f
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen};
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenenum fs_open_flags {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* File being written isn't very important, performance is more
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen important than actually guaranteeing that the file gets saved */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_FLAG_UNIMPORTANT = 0x10,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Asynchronous writes: fs_write() will fail with EAGAIN if it needs to
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen be called again (the retries can use size=0). For streams
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen fs_write_stream_finish() may request retrying with 0.
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen Asynchronous reads: fs_read() will fail with EAGAIN if it's not
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen finished and fs_read_stream() returns a nonblocking stream. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen FS_OPEN_FLAG_ASYNC = 0x20
063254ba79239f1c0a78ea08d4aa22f8f11d984cTimo Sirainen};
063254ba79239f1c0a78ea08d4aa22f8f11d984cTimo Sirainen
063254ba79239f1c0a78ea08d4aa22f8f11d984cTimo Sirainenstruct fs_settings {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* Dovecot instance's base_dir */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen const char *base_dir;
e809db9220c804b16d4d74782433a1075da12274Timo Sirainen /* Automatically try to rmdir() directories up to this path when
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen deleting files. */
6ac48a4295edbeb6b962700be3c563ad015c0a4eTimo Sirainen const char *root_path;
8e1dbcb9b249c37d00b420705777b103ffa6145dTimo Sirainen /* When creating temporary files, use this prefix
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen (to avoid conflicts with existing files). */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen const char *temp_file_prefix;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen};
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenstruct fs_metadata {
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const char *key;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const char *value;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen};
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo SirainenARRAY_DEFINE_TYPE(fs_metadata, struct fs_metadata);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainentypedef void fs_file_async_callback_t(void *context);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenint fs_init(const char *driver, const char *args,
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const struct fs_settings *set,
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen struct fs **fs_r, const char **error_r);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenvoid fs_deinit(struct fs **fs);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenstruct fs_file *fs_file_init(struct fs *fs, const char *path, int mode_flags);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenvoid fs_file_deinit(struct fs_file **file);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Return properties supported by backend. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenenum fs_properties fs_get_properties(struct fs *fs);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Add/replace metadata when saving a file. This makes sense only when the
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen file is being created/replaced. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenvoid fs_set_metadata(struct fs_file *file, const char *key, const char *value);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Return file's all metadata. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenint fs_get_metadata(struct fs_file *file,
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const ARRAY_TYPE(fs_metadata) **metadata_r);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Returns the path given to fs_open(). If file was opened with
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished,
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen return the path including the generated filename. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenconst char *fs_file_path(struct fs_file *file);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Return the error message for the last failed operation. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenconst char *fs_last_error(struct fs *fs);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Convenience function for the above. Errors aren't preserved across files. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenconst char *fs_file_last_error(struct fs_file *file);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Try to asynchronously prefetch file into memory. Returns TRUE if file is
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen already in memory (i.e. caller should handle this file before prefetching
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen more), FALSE if not. The length is a hint of how much the caller expects
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen to read, but it may be more or less (0=whole file). */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenbool fs_prefetch(struct fs_file *file, uoff_t length);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Returns >0 if something was read, -1 if error (errno is set). */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenssize_t fs_read(struct fs_file *file, void *buf, size_t size);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen/* Returns a stream for reading from file. Multiple streams can be opened,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen and caller must destroy the streams before closing the file. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenstruct istream *fs_read_stream(struct fs_file *file, size_t max_buffer_size);
81d3c215bb1fdbda2cf7ccd9519f6b4fd03c3791Timo Sirainen
8ddc45fe2080010715c212ecbb2b12b6734f6d4bTimo Sirainen/* Returns 0 if ok, -1 if error (errno is set). Note: With CREATE/REPLACE mode
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen files you can call fs_write() only once, the file creation is finished by it.
8ddc45fe2080010715c212ecbb2b12b6734f6d4bTimo Sirainen CREATE can return EEXIST here, if the destination file was already created.
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen With APPEND mode each fs_write() atomically appends the given data to
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen file. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenint fs_write(struct fs_file *file, const void *data, size_t size);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen/* Write to file via output stream. The stream will be destroyed by
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen fs_write_stream_finish/abort. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenstruct ostream *fs_write_stream(struct fs_file *file);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Finish writing via stream. The file will be created/replaced/appended only
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen after this call, same as with fs_write(). Anything written to the stream
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen won't be visible earlier. Returns 1 if ok, 0 if async write isn't finished
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen yet (retry calling fs_write_stream_finish_async()), -1 if error */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenint fs_write_stream_finish(struct fs_file *file, struct ostream **output);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainenint fs_write_stream_finish_async(struct fs_file *file);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen/* Abort writing via stream. Anything written to the stream is discarded. */
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainenvoid fs_write_stream_abort(struct fs_file *file, struct ostream **output);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen/* Call the specified callback whenever the file can be read/written to.
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen May call the callback immediately. */
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainenvoid fs_file_set_async_callback(struct fs_file *file,
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen fs_file_async_callback_t *callback,
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen void *context);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen/* Wait until some file can be read/written to more before returning.
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen It's an error to call this when there are no pending async operations.
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen Returns 0 if ok, -1 if timed out. */
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainenint fs_wait_async(struct fs *fs);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen
530f80fcbfa8be7378ff0d36ec7ecef41f198e2cTimo Sirainen/* Returns 1 if file exists, 0 if not, -1 if error occurred. */
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainenint fs_exists(struct fs_file *file);
13f6c879a84b3edd2fcc8f9832812be1f8c5d3b6Timo Sirainen/* Delete a file. Returns 1 if file was actually deleted by us,
8ddc45fe2080010715c212ecbb2b12b6734f6d4bTimo Sirainen 0 if file didn't exist, -1 if error. */
8ddc45fe2080010715c212ecbb2b12b6734f6d4bTimo Sirainenint fs_delete(struct fs_file *file);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen/* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT).
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen All fs backends may not support all stat fields. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenint fs_stat(struct fs_file *file, struct stat *st_r);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen/* Copy an object with possibly updated metadata. Destination parent
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen directories are created automatically. Returns 0 if ok, -1 if error
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen occurred. */
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainenint fs_copy(struct fs_file *src, struct fs_file *dest);
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen/* Try to finish asynchronous fs_copy() */
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainenint fs_copy_finish_async(struct fs_file *dest);
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen/* Atomically rename a file. Destination parent directories are created
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen automatically. Returns 0 if ok, -1 if error occurred. */
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainenint fs_rename(struct fs_file *src, struct fs_file *dest);
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen/* Exclusively lock a file. If file is already locked, wait for it for given
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen number of seconds (0 = fail immediately). Returns 1 if locked, 0 if wait
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen timed out, -1 if error. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenint fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenvoid fs_unlock(struct fs_lock **lock);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Iterate through all files (but not directories) in the given directory.
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen Doesn't recurse to child directories. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenstruct fs_iter *fs_iter_init(struct fs *fs, const char *path);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Returns 0 if ok, -1 if iteration failed. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenint fs_iter_deinit(struct fs_iter **iter);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen/* Returns the next filename. */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainenconst char *fs_iter_next(struct fs_iter *iter);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen#endif
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen