41843bdb6cd96d761a18bab5d5825f344d02420cTimo Sirainen/* Metadata with this prefix shouldn't actually be sent to storage. */
41843bdb6cd96d761a18bab5d5825f344d02420cTimo Sirainen#define FS_METADATA_INTERNAL_PREFIX ":/X-Dovecot-fs-api-"
41843bdb6cd96d761a18bab5d5825f344d02420cTimo Sirainen/* fs_write*() may return a hex-encoded object ID after write is finished.
41843bdb6cd96d761a18bab5d5825f344d02420cTimo Sirainen This can be later on used to optimize reads by setting it before reading
41843bdb6cd96d761a18bab5d5825f344d02420cTimo Sirainen#define FS_METADATA_OBJECTID FS_METADATA_INTERNAL_PREFIX"ObjectID"
ece461287e52e22104e881313cea34bc77616a61Timo Sirainen/* Calling this before fs_write_stream_finish() allows renaming the filename.
ece461287e52e22104e881313cea34bc77616a61Timo Sirainen This can be useful if you don't know the final filename before writing it
ece461287e52e22104e881313cea34bc77616a61Timo Sirainen (e.g. filename contains the file size). */
ece461287e52e22104e881313cea34bc77616a61Timo Sirainen#define FS_METADATA_WRITE_FNAME FS_METADATA_INTERNAL_PREFIX"WriteFilename"
15fa038377f9e3da24d088aa8a908919581c60a6Timo Sirainen/* Original path of the file. The path that's eventually visible to a fs
15fa038377f9e3da24d088aa8a908919581c60a6Timo Sirainen backend may be something different, e.g. object ID. This allows the backend
15fa038377f9e3da24d088aa8a908919581c60a6Timo Sirainen to still access the original path. */
15fa038377f9e3da24d088aa8a908919581c60a6Timo Sirainen#define FS_METADATA_ORIG_PATH FS_METADATA_INTERNAL_PREFIX"OrigPath"
8804300e6c170eea0cab8e570bf5ebd3b2895c0aTimo Sirainen /* Iteration is possible */
8804300e6c170eea0cab8e570bf5ebd3b2895c0aTimo Sirainen /* Iteration always returns all of the files (instead of possibly
8804300e6c170eea0cab8e570bf5ebd3b2895c0aTimo Sirainen slightly out of date view) */
e298b836845e07c9c95b4f068244f6c24252687eTimo Sirainen /* Backend uses directories, which aren't automatically deleted
e298b836845e07c9c95b4f068244f6c24252687eTimo Sirainen when its children are deleted. */
392538eef147981f6d818cd14cabc94cf8049d8eTimo Sirainen /* fs_copy() will copy the metadata if fs_set_metadata() hasn't
392538eef147981f6d818cd14cabc94cf8049d8eTimo Sirainen been explicitly called. */
11a418b123cd6b4d5460023a2f1d7fd96e182446Timo Sirainen /* Backend support asynchronous file operations. */
8656b625c110d849ece2d040d7880eec20058694Timo Sirainen /* Backend supports FS_ITER_FLAG_OBJECTIDS. */
c24b4f9c4acc99d90aef8512ec1bd907f9e844b9Timo Sirainen /* fs_copy() is fast even when file's metadata is changed */
c24b4f9c4acc99d90aef8512ec1bd907f9e844b9Timo Sirainen FS_PROPERTY_FASTCOPY_CHANGED_METADATA = 0x2000,
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* Open only for reading, or fail with ENOENT if it doesn't exist */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* Create a new file, fail with EEXIST if it already exists */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen /* Create a new file with a new unique name. The generated name is a
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen 128bit hex-encoded string. The fs_open()'s path parameter specifies
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen only the directory where the file is created to. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* Create or replace a file */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* Append to existing file, fail with ENOENT if it doesn't exist */
d11111fc5356108b6408a58b4ff1811d5b5678edTimo Sirainen /* File is important and writing must call fsync() or have equivalent
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen /* Asynchronous writes: fs_write() will fail with EAGAIN if it needs to
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen be called again (the retries can use size=0). For streams
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen fs_write_stream_finish() may request retrying with 0.
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen Asynchronous reads: fs_read() will fail with EAGAIN if it's not
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen finished and fs_read_stream() returns a nonblocking stream. */
a06af8e117e14e2ddc5835bcbe0d2f0370cbc0a1Timo Sirainen /* fs_read_stream() must return a seekable input stream */
60fe2f162e61eae1c2821bf9705c7ff7987c8adeTimo Sirainen /* Backend should handle this file's operations immediately without
60fe2f162e61eae1c2821bf9705c7ff7987c8adeTimo Sirainen any additional command queueing. The caller is assumed to be the one
60fe2f162e61eae1c2821bf9705c7ff7987c8adeTimo Sirainen doing any rate limiting if needed. This flag can only be used with
60fe2f162e61eae1c2821bf9705c7ff7987c8adeTimo Sirainen ASYNC flag, synchronous requests are never queued. */
63e94e8f57920b510fcdc479c5482ba9f4337a5cTimo Sirainen /* Iterate only directories, not files */
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainen /* Request asynchronous iteration. */
8656b625c110d849ece2d040d7880eec20058694Timo Sirainen /* Instead of returning object names, return <objectid>/<object name>.
8656b625c110d849ece2d040d7880eec20058694Timo Sirainen If this isn't supported, the <objectid> is returned empty. The
8656b625c110d849ece2d040d7880eec20058694Timo Sirainen object IDs are always hex-encoded data. This flag can be used only
8656b625c110d849ece2d040d7880eec20058694Timo Sirainen if FS_PROPERTY_OBJECTIDS is enabled. */
a0d0650370dd88fb0efe1fd34b376839f74be875Timo Sirainen /* Explicitly disable all caching for this iteration (if anything
a0d0650370dd88fb0efe1fd34b376839f74be875Timo Sirainen happens to be enabled). This should be used only in situations where
a0d0650370dd88fb0efe1fd34b376839f74be875Timo Sirainen the iteration is used to fix something that is broken, e.g. doveadm
a0d0650370dd88fb0efe1fd34b376839f74be875Timo Sirainen force-resync. */
11538e79ae94be5143d0055d4635fcdfd79a3906Timo Sirainen /* Username and session ID are mainly used for debugging/logging,
11538e79ae94be5143d0055d4635fcdfd79a3906Timo Sirainen but may also be useful for other purposes if they exist (they
11538e79ae94be5143d0055d4635fcdfd79a3906Timo Sirainen may be NULL). */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen /* Dovecot instance's base_dir */
1680fed5026a52fa4f47eb4cc6d82ec8dddcc50bTimo Sirainen /* Directory where temporary files can be created at any time
1680fed5026a52fa4f47eb4cc6d82ec8dddcc50bTimo Sirainen (e.g. /tmp or mail_temp_dir) */
c4a629cd7110285f0046793e4d0b29dee327dfbfTimo Sirainen /* SSL client settings. */
c4a629cd7110285f0046793e4d0b29dee327dfbfTimo Sirainen const struct ssl_iostream_settings *ssl_client_set;
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen /* Automatically try to rmdir() directories up to this path when
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen deleting files. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen /* When creating temporary files, use this prefix
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen (to avoid conflicts with existing files). */
4f825be38fed479bbe54ca0a76b7d1256e70ce80Timo Sirainen /* If the backend needs to do DNS lookups, use this dns_client for
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen /* Parent event to use, unless overridden by
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen fs_file_init_with_event() */
1c31ad9a2e071bd8ac9b98ad8070209ff85f1351Timo Sirainen /* Enable debugging */
1c244f6fdbb509cca857982368f5d426e999f2d1Timo Sirainen /* Enable timing statistics */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_prefetch() calls. Counted only if fs_read*() hasn't
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen already been called for the file (which would be pretty pointless
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen /* Number of fs_read*() calls. Counted only if fs_prefetch() hasn't
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen already been called for the file. */
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen /* Number of fs_lookup_metadata() calls. Counted only if neither
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen fs_read*() nor fs_prefetch() has been called for the file. */
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen /* Number of fs_stat() calls. Counted only if none of the above
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen has been called (because the stat result should be cached). */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_write*() calls. */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_exists() calls, which actually went to the backend
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen instead of being handled by fs_stat() call due to fs_exists() not
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen being implemented. */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_delete() calls. */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_copy() calls. If backend doesn't implement copying
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen operation but falls back to regular read+write instead, this count
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen isn't increased but the read+write counters are. */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_rename() calls. */
c793a28b3a9549b89167fedca5f8a66ac82ab315Timo Sirainen /* Number of fs_iter_init() calls. */
507dcd9fee9b8f032a60af3ea35de4da0e5653c9Timo Sirainen /* Number of bytes written by fs_write*() calls. */
1c244f6fdbb509cca857982368f5d426e999f2d1Timo Sirainen /* Cumulative sum of usecs spent on calls - set only if
1c244f6fdbb509cca857982368f5d426e999f2d1Timo Sirainen fs_settings.enable_timing=TRUE */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo SirainenARRAY_DEFINE_TYPE(fs_metadata, struct fs_metadata);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainentypedef void fs_file_async_callback_t(void *context);
d4c3d55021bcbf2b062f4782b1cde9115d35aefcTimo Sirainenint fs_init(const char *driver, const char *args,
c69b62e5d86e153dfbbfcb99d115f34a25902908Aki Tuomi/* helper for fs_init, accepts a filesystem string
c69b62e5d86e153dfbbfcb99d115f34a25902908Aki Tuomi that can come directly from config */
c69b62e5d86e153dfbbfcb99d115f34a25902908Aki Tuomiint fs_init_from_string(const char *str, const struct fs_settings *set,
e853125eceafe8c3e286ce9b4176f6df4b806aceTimo Sirainen/* same as fs_unref() */
4c827a0925f5f77d1067e646fc2f615678c50d66Timo Sirainen/* Returns the parent filesystem (if this is a wrapper fs) or NULL if
4c827a0925f5f77d1067e646fc2f615678c50d66Timo Sirainen there's no parent. */
4c827a0925f5f77d1067e646fc2f615678c50d66Timo Sirainen/* Returns the filesystem's driver name. */
75a2a8361aafd27d01eef00c23d784e329b695c2Timo Sirainen/* Returns the root fs's driver name (bypassing all wrapper fses) */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenstruct fs_file *fs_file_init(struct fs *fs, const char *path, int mode_flags);
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainenstruct fs_file *fs_file_init_with_event(struct fs *fs, struct event *event,
0b32a8d139f6a4f2b18a6444fc66d31b4a1b0da6Timo Sirainen/* If the file has an input streams open, close them. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Return properties supported by backend. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenenum fs_properties fs_get_properties(struct fs *fs);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Add/replace metadata when saving a file. This makes sense only when the
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen file is being created/replaced. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenvoid fs_set_metadata(struct fs_file *file, const char *key, const char *value);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Return file's all metadata. */
9a1ab9488c75f8a68871d0fcdff4e0d0e3543299Timo Sirainen/* Wrapper to fs_get_metadata() to lookup a specific key. Returns 1 if value_r
9a1ab9488c75f8a68871d0fcdff4e0d0e3543299Timo Sirainen is set, 0 if key wasn't found, -1 if error. */
9a1ab9488c75f8a68871d0fcdff4e0d0e3543299Timo Sirainenint fs_lookup_metadata(struct fs_file *file, const char *key,
9a1ab9488c75f8a68871d0fcdff4e0d0e3543299Timo Sirainen const char **value_r);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Returns the path given to fs_open(). If file was opened with
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished,
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen return the path including the generated filename. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenconst char *fs_file_path(struct fs_file *file);
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainen/* Returns the file's fs. */
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainen/* Returns the file's event. */
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainenstruct event *fs_file_event(struct fs_file *file);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Return the error message for the last failed operation. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Convenience function for the above. Errors aren't preserved across files. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenconst char *fs_file_last_error(struct fs_file *file);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Try to asynchronously prefetch file into memory. Returns TRUE if file is
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen already in memory (i.e. caller should handle this file before prefetching
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen more), FALSE if not. The length is a hint of how much the caller expects
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen to read, but it may be more or less (0=whole file). */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenbool fs_prefetch(struct fs_file *file, uoff_t length);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Returns >0 if something was read, -1 if error (errno is set). */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenssize_t fs_read(struct fs_file *file, void *buf, size_t size);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Returns a stream for reading from file. Multiple streams can be opened,
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen and caller must destroy the streams before closing the file. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenstruct istream *fs_read_stream(struct fs_file *file, size_t max_buffer_size);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Returns 0 if ok, -1 if error (errno is set). Note: With CREATE/REPLACE mode
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen files you can call fs_write() only once, the file creation is finished by it.
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen CREATE can return EEXIST here, if the destination file was already created.
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen With APPEND mode each fs_write() atomically appends the given data to
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenint fs_write(struct fs_file *file, const void *data, size_t size);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Write to file via output stream. The stream will be destroyed by
372a9dd989813eb1a08e07b39987731e33045375Timo Sirainen fs_write_stream_finish/abort. The returned ostream is already corked and
372a9dd989813eb1a08e07b39987731e33045375Timo Sirainen it doesn't need to be uncorked. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenstruct ostream *fs_write_stream(struct fs_file *file);
d1ba8ecbb936ace90179d2292952546708d68f71Timo Sirainen/* Finish writing via stream, calling also o_stream_flush() on the stream and
372a9dd989813eb1a08e07b39987731e33045375Timo Sirainen handling any pending errors. The file will be created/replaced/appended only
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen after this call, same as with fs_write(). Anything written to the stream
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen won't be visible earlier. Returns 1 if ok, 0 if async write isn't finished
ba886767d3817d210b20e1d42983078d189fb13cTimo Sirainen yet (retry calling fs_write_stream_finish_async()), -1 if error */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenint fs_write_stream_finish(struct fs_file *file, struct ostream **output);
ba886767d3817d210b20e1d42983078d189fb13cTimo Sirainenint fs_write_stream_finish_async(struct fs_file *file);
372a9dd989813eb1a08e07b39987731e33045375Timo Sirainen/* Abort writing via stream. Anything written to the stream is discarded.
372a9dd989813eb1a08e07b39987731e33045375Timo Sirainen o_stream_ignore_last_errors() is called on the output stream so the caller
a0cf7d3924dec409e6eadaf3237fcecd4194ec75Timo Sirainen doesn't need to do it. This must not be called after
a0cf7d3924dec409e6eadaf3237fcecd4194ec75Timo Sirainen fs_write_stream_finish(), i.e. it can't be used to abort a pending async
be6fab2b1eded6b57d6688c6aa5a7c784f943865Aki Tuomivoid fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...) ATTR_FORMAT(3, 4);
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainen/* Set a hash to the following write. The storage can then verify that the
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainen input data matches the specified hash, or fail if it doesn't. Typically
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainen implemented by Content-MD5 header. */
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainenvoid fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
67a163f3a07593446fab1cbbb8f92a89d4c6cb57Timo Sirainen const void *digest);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Call the specified callback whenever the file can be read/written to.
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen May call the callback immediately. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenvoid fs_file_set_async_callback(struct fs_file *file,
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Wait until some file can be read/written to more before returning.
d34b8a75f3b74e26adc85b6436d033b1dcfaf9daTimo Sirainen It's an error to call this when there are no pending async operations. */
8296531314913c7f9d4ab1857c6f79ff1308a12fTimo Sirainen/* Switch the fs to the current ioloop. This can be used to do fs_wait_async()
8296531314913c7f9d4ab1857c6f79ff1308a12fTimo Sirainen among other IO work. Returns TRUE if there is actually some work that can
8296531314913c7f9d4ab1857c6f79ff1308a12fTimo Sirainen be waited on. */
8296531314913c7f9d4ab1857c6f79ff1308a12fTimo Sirainenbool fs_switch_ioloop(struct fs *fs) ATTR_NOWARN_UNUSED_RESULT;
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Returns 1 if file exists, 0 if not, -1 if error occurred. */
42d2fdfbe4047c0aab78c76a10f31766aa53ecd7Timo Sirainen/* Delete a file. Returns 0 if file was actually deleted by us, -1 if error. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT).
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen All fs backends may not support all stat fields. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenint fs_stat(struct fs_file *file, struct stat *st_r);
a63cd84128875485e40ed804dbf0b0945526989cTimo Sirainen/* Get number of links to the file. This is the same as using fs_stat()'s
a63cd84128875485e40ed804dbf0b0945526989cTimo Sirainen st_nlinks field, except not all backends support returning it via fs_stat().
a63cd84128875485e40ed804dbf0b0945526989cTimo Sirainen Returns 0 if ok, -1 if error occurred. */
a63cd84128875485e40ed804dbf0b0945526989cTimo Sirainenint fs_get_nlinks(struct fs_file *file, nlink_t *nlinks_r);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Copy an object with possibly updated metadata. Destination parent
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen directories are created automatically. Returns 0 if ok, -1 if error
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenint fs_copy(struct fs_file *src, struct fs_file *dest);
8bfb2ecbe654afe6893052959c42b4851119e76dTimo Sirainen/* Try to finish asynchronous fs_copy(). Returns the same as fs_copy(). */
ba886767d3817d210b20e1d42983078d189fb13cTimo Sirainenint fs_copy_finish_async(struct fs_file *dest);
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Atomically rename a file. Destination parent directories are created
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen automatically. Returns 0 if ok, -1 if error occurred. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenint fs_rename(struct fs_file *src, struct fs_file *dest);
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen/* Exclusively lock a file. If file is already locked, wait for it for given
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen number of seconds (0 = fail immediately). Returns 1 if locked, 0 if wait
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainen timed out, -1 if error. */
c33d3f93abf8392fdc60e12bea41ffd12cc85a8dTimo Sirainenint fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r);
63e94e8f57920b510fcdc479c5482ba9f4337a5cTimo Sirainen/* Iterate through all files or directories in the given directory.
a58b73c69e2d608843406b5809063d038ae67699Timo Sirainen Doesn't recurse to child directories. It's not an error to iterate a
a58b73c69e2d608843406b5809063d038ae67699Timo Sirainen nonexistent directory. */
63e94e8f57920b510fcdc479c5482ba9f4337a5cTimo Sirainenfs_iter_init(struct fs *fs, const char *path, enum fs_iter_flags flags);
fc59aba4be5d2f57908e84f0f7477c467a72d567Timo Sirainenfs_iter_init_with_event(struct fs *fs, struct event *event,
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Returns 0 if ok, -1 if iteration failed. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainen/* Returns the next filename. */
c59b9c273b41f7bcf51f6803110b67813879ff05Timo Sirainenconst char *fs_iter_next(struct fs_iter *iter);
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainen/* For asynchronous iterations: Specify the callback that is called whenever
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainen there's more data available for reading. */
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainenvoid fs_iter_set_async_callback(struct fs_iter *iter,
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainen/* For asynchronous iterations: If fs_iter_next() returns NULL, use this
9c45f33d0e0ca0b8f87f9a3318dd505a78fd198eTimo Sirainen function to determine if you should wait for more data or finish up. */
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen/* Return the filesystem's fs_stats. Note that each wrapper filesystem keeps
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen track of its own fs_stats calls. You can use fs_get_parent() to get to the
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainen filesystem whose stats you want to see. */
302167a8a77cf3597f0b33e644a1805aa3313a8cTimo Sirainenconst struct fs_stats *fs_get_stats(struct fs *fs);
3d2d3501736ff917f2de8a38f253c741c6f84e1eTimo Sirainen/* Helper functions to count number of usecs for read/write operations. */
3d2d3501736ff917f2de8a38f253c741c6f84e1eTimo Sirainenuint64_t fs_stats_get_read_usecs(const struct fs_stats *stats);