dovecot-2.2: lib-fs API cleanups and improvements

dovecot at dovecot.org dovecot at dovecot.org
Fri Oct 12 00:22:36 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/ce57bacc3010
changeset: 15198:ce57bacc3010
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Oct 12 00:22:19 2012 +0300
description:
lib-fs API cleanups and improvements

diffstat:

 src/lib-fs/fs-api-private.h                      |   47 ++-
 src/lib-fs/fs-api.c                              |  127 +++++--
 src/lib-fs/fs-api.h                              |  122 +++++-
 src/lib-fs/fs-posix.c                            |  373 ++++++++++++++++------
 src/lib-fs/fs-sis-common.c                       |   25 +-
 src/lib-fs/fs-sis-common.h                       |    3 +-
 src/lib-fs/fs-sis-queue.c                        |  226 ++++++++-----
 src/lib-fs/fs-sis.c                              |  304 +++++++++++-------
 src/lib-storage/index/dbox-common/dbox-storage.c |    1 +
 src/lib-storage/index/dbox-single/sdbox-copy.c   |    9 +-
 src/lib-storage/index/dbox-single/sdbox-file.c   |   19 +-
 src/lib-storage/index/index-attachment.c         |   43 +-
 12 files changed, 855 insertions(+), 444 deletions(-)

diffs (truncated from 2319 to 300 lines):

diff -r 2ac184a82b9a -r ce57bacc3010 src/lib-fs/fs-api-private.h
--- a/src/lib-fs/fs-api-private.h	Thu Oct 11 23:01:13 2012 +0300
+++ b/src/lib-fs/fs-api-private.h	Fri Oct 12 00:22:19 2012 +0300
@@ -4,14 +4,29 @@
 #include "fs-api.h"
 
 struct fs_vfuncs {
-	int (*init)(const char *args, const struct fs_settings *set,
-		    struct fs **fs_r, const char **error_r);
+	struct fs *(*alloc)(void);
+	int (*init)(struct fs *fs, const char *args,
+		    const struct fs_settings *set);
 	void (*deinit)(struct fs *fs);
 
-	int (*open)(struct fs *fs, const char *path, enum fs_open_mode mode,
-		    enum fs_open_flags flags, struct fs_file **file_r);
-	void (*close)(struct fs_file *file);
+	enum fs_properties (*get_properties)(struct fs *fs);
 
+	struct fs_file *(*file_init)(struct fs *fs, const char *path,
+				     enum fs_open_mode mode,
+				     enum fs_open_flags flags);
+	void (*file_deinit)(struct fs_file *file);
+
+	void (*set_async_callback)(struct fs_file *file,
+				   fs_file_async_callback_t *callback,
+				   void *context);
+	void (*wait_async)(struct fs *fs);
+
+	void (*set_metadata)(struct fs_file *file, const char *key,
+			     const char *value);
+	int (*get_metadata)(struct fs_file *file,
+			    const ARRAY_TYPE(fs_metadata) **metadata_r);
+
+	bool (*prefetch)(struct fs_file *file, uoff_t length);
 	ssize_t (*read)(struct fs_file *file, void *buf, size_t size);
 	struct istream *(*read_stream)(struct fs_file *file,
 				       size_t max_buffer_size);
@@ -23,14 +38,16 @@
 	int (*lock)(struct fs_file *file, unsigned int secs,
 		    struct fs_lock **lock_r);
 	void (*unlock)(struct fs_lock *lock);
-	int (*fdatasync)(struct fs_file *file);
 
-	int (*exists)(struct fs *fs, const char *path);
-	int (*stat)(struct fs *fs, const char *path, struct stat *st_r);
-	int (*link)(struct fs *fs, const char *src, const char *dest);
-	int (*rename)(struct fs *fs, const char *src, const char *dest);
-	int (*unlink)(struct fs *fs, const char *path);
-	int (*rmdir)(struct fs *fs, const char *path);
+	int (*exists)(struct fs_file *file);
+	int (*stat)(struct fs_file *file, struct stat *st_r);
+	int (*copy)(struct fs_file *src, struct fs_file *dest);
+	int (*rename)(struct fs_file *src, struct fs_file *dest);
+	int (*delete_file)(struct fs_file *file);
+
+	struct fs_iter *(*iter_init)(struct fs *fs, const char *path);
+	const char *(*iter_next)(struct fs_iter *iter);
+	int (*iter_deinit)(struct fs_iter *iter);
 };
 
 struct fs {
@@ -53,6 +70,10 @@
 	struct fs_file *file;
 };
 
+struct fs_iter {
+	struct fs *fs;
+};
+
 extern struct fs fs_class_posix;
 extern struct fs fs_class_sis;
 extern struct fs fs_class_sis_queue;
@@ -60,4 +81,6 @@
 void fs_set_error(struct fs *fs, const char *fmt, ...) ATTR_FORMAT(2, 3);
 void fs_set_critical(struct fs *fs, const char *fmt, ...) ATTR_FORMAT(2, 3);
 
+void fs_set_error_async(struct fs *fs);
+
 #endif
diff -r 2ac184a82b9a -r ce57bacc3010 src/lib-fs/fs-api.c
--- a/src/lib-fs/fs-api.c	Thu Oct 11 23:01:13 2012 +0300
+++ b/src/lib-fs/fs-api.c	Fri Oct 12 00:22:19 2012 +0300
@@ -14,26 +14,24 @@
 fs_alloc(const struct fs *fs_class, const char *args,
 	 const struct fs_settings *set, struct fs **fs_r, const char **error_r)
 {
-	struct fs *fs = NULL;
-	char *error_dup = NULL;
+	struct fs *fs;
 	int ret;
 
+	fs = fs_class->v.alloc();
+	fs->last_error = str_new(default_pool, 64);
+
 	T_BEGIN {
-		const char *error;
-
-		ret = fs_class->v.init(args, set, &fs, &error);
-		if (ret < 0)
-			error_dup = i_strdup(error);
+		ret = fs_class->v.init(fs, args, set);
 	} T_END;
 	if (ret < 0) {
 		/* a bit kludgy way to allow data stack frame usage in normal
 		   conditions but still be able to return error message from
 		   data stack. */
-		*error_r = t_strdup_printf("%s: %s", fs_class->name, error_dup);
-		i_free(error_dup);
+		*error_r = t_strdup_printf("%s: %s", fs_class->name,
+					   fs_last_error(fs));
+		fs_deinit(&fs);
 		return -1;
 	}
-	fs->last_error = str_new(default_pool, 64);
 	*fs_r = fs;
 	return 0;
 }
@@ -57,6 +55,7 @@
 void fs_deinit(struct fs **_fs)
 {
 	struct fs *fs = *_fs;
+	string_t *last_error = fs->last_error;
 
 	*_fs = NULL;
 
@@ -65,25 +64,25 @@
 			fs->name, fs->files_open_count);
 	}
 
-	str_free(&fs->last_error);
 	fs->v.deinit(fs);
+	str_free(&last_error);
 }
 
-int fs_open(struct fs *fs, const char *path, int mode_flags,
-	    struct fs_file **file_r)
+struct fs_file *fs_file_init(struct fs *fs, const char *path, int mode_flags)
 {
-	int ret;
+	struct fs_file *file;
+
+	i_assert(path != NULL);
 
 	T_BEGIN {
-		ret = fs->v.open(fs, path, mode_flags & FS_OPEN_MODE_MASK,
-				 mode_flags & ~FS_OPEN_MODE_MASK, file_r);
+		file = fs->v.file_init(fs, path, mode_flags & FS_OPEN_MODE_MASK,
+				       mode_flags & ~FS_OPEN_MODE_MASK);
 	} T_END;
-	if (ret == 0)
-		fs->files_open_count++;
-	return ret;
+	fs->files_open_count++;
+	return file;
 }
 
-void fs_close(struct fs_file **_file)
+void fs_file_deinit(struct fs_file **_file)
 {
 	struct fs_file *file = *_file;
 
@@ -92,7 +91,28 @@
 	*_file = NULL;
 
 	file->fs->files_open_count--;
-	file->fs->v.close(file);
+	file->fs->v.file_deinit(file);
+}
+
+enum fs_properties fs_get_properties(struct fs *fs)
+{
+	return fs->v.get_properties(fs);
+}
+
+void fs_set_metadata(struct fs_file *file, const char *key, const char *value)
+{
+	if (file->fs->v.set_metadata != NULL)
+		file->fs->v.set_metadata(file, key, value);
+}
+
+int fs_get_metadata(struct fs_file *file,
+		    const ARRAY_TYPE(fs_metadata) **metadata_r)
+{
+	if (file->fs->v.get_metadata == NULL) {
+		fs_set_error(file->fs, "Metadata not supported by backend");
+		return -1;
+	}
+	return file->fs->v.get_metadata(file, metadata_r);
 }
 
 const char *fs_file_path(struct fs_file *file)
@@ -112,6 +132,11 @@
 	return fs_last_error(file->fs);
 }
 
+bool fs_prefetch(struct fs_file *file, uoff_t length)
+{
+	return file->fs->v.prefetch(file, length);
+}
+
 ssize_t fs_read(struct fs_file *file, void *buf, size_t size)
 {
 	return file->fs->v.read(file, buf, size);
@@ -150,6 +175,22 @@
 	(void)file->fs->v.write_stream_finish(file, FALSE);
 }
 
+void fs_file_set_async_callback(struct fs_file *file,
+				fs_file_async_callback_t *callback,
+				void *context)
+{
+	if (file->fs->v.set_async_callback != NULL)
+		file->fs->v.set_async_callback(file, callback, context);
+	else
+		callback(context);
+}
+
+void fs_wait_async(struct fs *fs)
+{
+	if (fs->v.wait_async != NULL)
+		fs->v.wait_async(fs);
+}
+
 int fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r)
 {
 	return file->fs->v.lock(file, secs, lock_r);
@@ -163,39 +204,49 @@
 	lock->file->fs->v.unlock(lock);
 }
 
-int fs_fdatasync(struct fs_file *file)
+int fs_exists(struct fs_file *file)
 {
-	return file->fs->v.fdatasync(file);
+	return file->fs->v.exists(file);
 }
 
-int fs_exists(struct fs *fs, const char *path)
+int fs_stat(struct fs_file *file, struct stat *st_r)
 {
-	return fs->v.exists(fs, path);
+	return file->fs->v.stat(file, st_r);
 }
 
-int fs_stat(struct fs *fs, const char *path, struct stat *st_r)
+int fs_copy(struct fs_file *src, struct fs_file *dest)
 {
-	return fs->v.stat(fs, path, st_r);
+	i_assert(src->fs == dest->fs);
+	return src->fs->v.copy(src, dest);
 }
 
-int fs_link(struct fs *fs, const char *src, const char *dest)
+int fs_rename(struct fs_file *src, struct fs_file *dest)
 {
-	return fs->v.link(fs, src, dest);
+	i_assert(src->fs == dest->fs);
+	return src->fs->v.rename(src, dest);
 }
 
-int fs_rename(struct fs *fs, const char *src, const char *dest)
+int fs_delete(struct fs_file *file)
 {
-	return fs->v.rename(fs, src, dest);
+	return file->fs->v.delete_file(file);
 }
 
-int fs_unlink(struct fs *fs, const char *path)
+struct fs_iter *fs_iter_init(struct fs *fs, const char *path)
 {
-	return fs->v.unlink(fs, path);
+	return fs->v.iter_init(fs, path);
 }
 
-int fs_rmdir(struct fs *fs, const char *path)
+int fs_iter_deinit(struct fs_iter **_iter)
 {
-	return fs->v.rmdir(fs, path);
+	struct fs_iter *iter = *_iter;
+
+	*_iter = NULL;
+	return iter->fs->v.iter_deinit(iter);
+}
+
+const char *fs_iter_next(struct fs_iter *iter)
+{
+	return iter->fs->v.iter_next(iter);
 }
 
 void fs_set_error(struct fs *fs, const char *fmt, ...)
@@ -218,3 +269,9 @@
 	i_error("fs-%s: %s", fs->name, str_c(fs->last_error));
 	va_end(args);
 }
+
+void fs_set_error_async(struct fs *fs)
+{
+	fs_set_error(fs, "Asynchronous operation in progress");
+	errno = EAGAIN;


More information about the dovecot-cvs mailing list