dovecot-2.2: lib-fs: Track how many different operations have be...

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 5 21:05:30 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/18721584583b
changeset: 18290:18721584583b
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 05 22:18:04 2015 +0200
description:
lib-fs: Track how many different operations have been done on the fs.

diffstat:

 src/lib-fs/fs-api-private.h |   7 +++++++
 src/lib-fs/fs-api.c         |  40 ++++++++++++++++++++++++++++++++++++++++
 src/lib-fs/fs-api.h         |  26 ++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 0 deletions(-)

diffs (206 lines):

diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api-private.h
--- a/src/lib-fs/fs-api-private.h	Thu Mar 05 22:17:09 2015 +0200
+++ b/src/lib-fs/fs-api-private.h	Thu Mar 05 22:18:04 2015 +0200
@@ -70,6 +70,8 @@
 	unsigned int files_open_count;
 	struct fs_file *files;
 	struct fs_iter *iters;
+
+	struct fs_stats stats;
 };
 
 struct fs_file {
@@ -96,6 +98,11 @@
 
 	unsigned int write_pending:1;
 	unsigned int metadata_changed:1;
+
+	unsigned int read_counted:1;
+	unsigned int prefetch_counted:1;
+	unsigned int lookup_metadata_counted:1;
+	unsigned int stat_counted:1;
 };
 
 struct fs_lock {
diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api.c
--- a/src/lib-fs/fs-api.c	Thu Mar 05 22:17:09 2015 +0200
+++ b/src/lib-fs/fs-api.c	Thu Mar 05 22:18:04 2015 +0200
@@ -269,6 +269,11 @@
 		fs_set_error(file->fs, "Metadata not supported by backend");
 		return -1;
 	}
+	if (!file->read_counted && !file->prefetch_counted &&
+	    !file->lookup_metadata_counted) {
+		file->lookup_metadata_counted = TRUE;
+		file->fs->stats.lookup_metadata_count++;
+	}
 	T_BEGIN {
 		ret = file->fs->v.get_metadata(file, metadata_r);
 	} T_END;
@@ -336,6 +341,10 @@
 {
 	bool ret;
 
+	if (!file->read_counted && !file->prefetch_counted) {
+		file->prefetch_counted = TRUE;
+		file->fs->stats.prefetch_count++;
+	}
 	T_BEGIN {
 		ret = file->fs->v.prefetch(file, length);
 	} T_END;
@@ -374,6 +383,11 @@
 {
 	int ret;
 
+	if (!file->read_counted && !file->prefetch_counted) {
+		file->read_counted = TRUE;
+		file->fs->stats.read_count++;
+	}
+
 	if (file->fs->v.read != NULL) {
 		T_BEGIN {
 			ret = file->fs->v.read(file, buf, size);
@@ -394,6 +408,11 @@
 	ssize_t ret;
 	bool want_seekable = FALSE;
 
+	if (!file->read_counted && !file->prefetch_counted) {
+		file->read_counted = TRUE;
+		file->fs->stats.read_count++;
+	}
+
 	if (file->seekable_input != NULL) {
 		i_stream_seek(file->seekable_input, 0);
 		i_stream_ref(file->seekable_input);
@@ -476,6 +495,7 @@
 {
 	int ret;
 
+	file->fs->stats.write_count++;
 	if (file->fs->v.write != NULL) {
 		T_BEGIN {
 			ret = file->fs->v.write(file, data, size);
@@ -490,6 +510,7 @@
 
 struct ostream *fs_write_stream(struct fs_file *file)
 {
+	file->fs->stats.write_count++;
 	T_BEGIN {
 		file->fs->v.write_stream(file);
 	} T_END;
@@ -607,6 +628,7 @@
 		else
 			return errno == ENOENT ? 0 : -1;
 	}
+	file->fs->stats.exists_count++;
 	T_BEGIN {
 		ret = file->fs->v.exists(file);
 	} T_END;
@@ -617,6 +639,11 @@
 {
 	int ret;
 
+	if (!file->read_counted && !file->prefetch_counted &&
+	    !file->lookup_metadata_counted && !file->stat_counted) {
+		file->stat_counted = TRUE;
+		file->fs->stats.stat_count++;
+	}
 	T_BEGIN {
 		ret = file->fs->v.stat(file, st_r);
 	} T_END;
@@ -625,6 +652,10 @@
 
 int fs_default_copy(struct fs_file *src, struct fs_file *dest)
 {
+	/* we're going to be counting this as read+write, so remove the
+	   copy_count we just added */
+	dest->fs->stats.copy_count--;
+
 	if (dest->copy_src != NULL) {
 		i_assert(src == NULL || src == dest->copy_src);
 		if (dest->copy_output == NULL) {
@@ -675,6 +706,7 @@
 
 	i_assert(src->fs == dest->fs);
 
+	dest->fs->stats.copy_count++;
 	T_BEGIN {
 		ret = src->fs->v.copy(src, dest);
 	} T_END;
@@ -701,6 +733,7 @@
 
 	i_assert(src->fs == dest->fs);
 
+	dest->fs->stats.rename_count++;
 	T_BEGIN {
 		ret = src->fs->v.rename(src, dest);
 	} T_END;
@@ -711,6 +744,7 @@
 {
 	int ret;
 
+	file->fs->stats.delete_count++;
 	T_BEGIN {
 		ret = file->fs->v.delete_file(file);
 	} T_END;
@@ -725,6 +759,7 @@
 	i_assert((flags & FS_ITER_FLAG_OBJECTIDS) == 0 ||
 		 (fs_get_properties(fs) & FS_PROPERTY_OBJECTIDS) != 0);
 
+	fs->stats.iter_count++;
 	T_BEGIN {
 		iter = fs->v.iter_init(fs, path, flags);
 	} T_END;
@@ -768,6 +803,11 @@
 	return iter->async_have_more;
 }
 
+const struct fs_stats *fs_get_stats(struct fs *fs)
+{
+	return &fs->stats;
+}
+
 void fs_set_error(struct fs *fs, const char *fmt, ...)
 {
 	va_list args;
diff -r 422b5a01d18e -r 18721584583b src/lib-fs/fs-api.h
--- a/src/lib-fs/fs-api.h	Thu Mar 05 22:17:09 2015 +0200
+++ b/src/lib-fs/fs-api.h	Thu Mar 05 22:18:04 2015 +0200
@@ -122,6 +122,27 @@
 	bool debug;
 };
 
+struct fs_stats {
+	/* Number of fs_prefetch() calls. */
+	unsigned int prefetch_count;
+	/* Number of fs_read*() calls. Counted only if fs_prefetch() hasn't
+	   been called for the file. */
+	unsigned int read_count;
+	/* Number of fs_lookup_metadata() calls. Counted only if neither
+	   fs_read*() nor fs_prefetch() has been called for the file. */
+	unsigned int lookup_metadata_count;
+	/* Number of fs_stat() calls. Counted only if none of the above
+	   has been called (because the stat result should be cached). */
+	unsigned int stat_count;
+
+	unsigned int write_count;
+	unsigned int exists_count;
+	unsigned int delete_count;
+	unsigned int copy_count;
+	unsigned int rename_count;
+	unsigned int iter_count;
+};
+
 struct fs_metadata {
 	const char *key;
 	const char *value;
@@ -264,4 +285,9 @@
    function to determine if you should wait for more data or finish up. */
 bool fs_iter_have_more(struct fs_iter *iter);
 
+/* Return the filesystem's fs_stats. Note that each wrapper filesystem keeps
+   track of its own fs_stats calls. You can use fs_get_parent() to get to the
+   filesystem whose stats you want to see. */
+const struct fs_stats *fs_get_stats(struct fs *fs);
+
 #endif


More information about the dovecot-cvs mailing list