[dovecot-cvs] dovecot/src/plugins/quota quota-dict.c, 1.1, 1.2 quota-dirsize.c, 1.1, 1.2 quota-private.h, 1.1, 1.2

cras at dovecot.org cras at dovecot.org
Wed Dec 28 22:17:55 EET 2005


Update of /var/lib/cvs/dovecot/src/plugins/quota
In directory talvi:/tmp/cvs-serv27235

Modified Files:
	quota-dict.c quota-dirsize.c quota-private.h 
Log Message:
Make dirsize backend read the directory only once at the beginning of
transaction. Added some more variables to struct quota_transaction_context
so dict and quota backends can both use it directly.



Index: quota-dict.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-dict.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- quota-dict.c	10 Dec 2005 19:44:46 -0000	1.1
+++ quota-dict.c	28 Dec 2005 20:17:51 -0000	1.2
@@ -26,13 +26,6 @@
 	int sent;
 };
 
-struct dict_quota_transaction_context {
-	struct quota_transaction_context ctx;
-
-	uint64_t storage_limit;
-	uint64_t storage_current;
-};
-
 extern struct quota dict_quota;
 
 static struct quota *dict_quota_init(const char *data)
@@ -179,11 +172,11 @@
 dict_quota_transaction_begin(struct quota *_quota)
 {
 	struct dict_quota *quota = (struct dict_quota *)_quota;
-	struct dict_quota_transaction_context *ctx;
+	struct quota_transaction_context *ctx;
 	const char *value;
 
-	ctx = i_new(struct dict_quota_transaction_context, 1);
-	ctx->ctx.quota = _quota;
+	ctx = i_new(struct quota_transaction_context, 1);
+	ctx->quota = _quota;
 
 	if (quota->dict != NULL) {
 		t_push();
@@ -201,22 +194,20 @@
 		ctx->storage_limit = (uint64_t)-1;
 	}
 
-	return &ctx->ctx;
+	return ctx;
 }
 
 static int
-dict_quota_transaction_commit(struct quota_transaction_context *_ctx)
+dict_quota_transaction_commit(struct quota_transaction_context *ctx)
 {
-	struct dict_quota_transaction_context *ctx =
-		(struct dict_quota_transaction_context *)_ctx;
-	struct dict_quota *quota = (struct dict_quota *)_ctx->quota;
+	struct dict_quota *quota = (struct dict_quota *)ctx->quota;
 
 	if (quota->dict != NULL) {
 		struct dict_transaction_context *dt;
 
 		dt = dict_transaction_begin(quota->dict);
 		dict_atomic_inc(dt, DICT_QUOTA_CURRENT_PATH"storage",
-				_ctx->bytes_diff);
+				ctx->bytes_diff);
 		if (dict_transaction_commit(dt) < 0)
 			i_error("dict_quota: Couldn't update quota");
 	}
@@ -232,20 +223,18 @@
 }
 
 static int
-dict_quota_try_alloc(struct quota_transaction_context *_ctx,
+dict_quota_try_alloc(struct quota_transaction_context *ctx,
 		     struct mail *mail, int *too_large_r)
 {
-	struct dict_quota_transaction_context *ctx =
-		(struct dict_quota_transaction_context *)_ctx;
 	uoff_t size;
 
 	size = mail_get_physical_size(mail);
 	*too_large_r = size > ctx->storage_limit;
 
-	if (ctx->storage_current + _ctx->bytes_diff + size > ctx->storage_limit)
+	if (ctx->storage_current + ctx->bytes_diff + size > ctx->storage_limit)
 		return 0;
 
-	_ctx->bytes_diff += size;
+	ctx->bytes_diff += size;
 	return 1;
 }
 

Index: quota-dirsize.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-dirsize.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- quota-dirsize.c	10 Dec 2005 19:44:46 -0000	1.1
+++ quota-dirsize.c	28 Dec 2005 20:17:51 -0000	1.2
@@ -223,20 +223,34 @@
 }
 
 static struct quota_transaction_context *
-dirsize_quota_transaction_begin(struct quota *quota)
+dirsize_quota_transaction_begin(struct quota *_quota)
 {
+	struct dirsize_quota *quota = (struct dirsize_quota *)_quota;
 	struct quota_transaction_context *ctx;
 
 	ctx = i_new(struct quota_transaction_context, 1);
-	ctx->quota = quota;
+	ctx->quota = _quota;
+
+	/* Get dir usage only once at the beginning of transaction.
+	   When copying/appending lots of mails we don't want to re-read the
+	   entire directory structure after each mail. */
+	if (get_dir_usage(quota->path, &ctx->storage_current) < 0 ||
+	    ctx->storage_current == (uoff_t)-1) {
+                ctx->storage_current = (uoff_t)-1;
+		quota->error = "Internal quota calculation error";
+	}
+
+	ctx->storage_limit = quota->storage_limit * 1024;
 	return ctx;
 }
 
 static int
 dirsize_quota_transaction_commit(struct quota_transaction_context *ctx)
 {
+	int ret = ctx->storage_current == (uoff_t)-1 ? -1 : 0;
+
 	i_free(ctx);
-	return 0;
+	return ret;
 }
 
 static void
@@ -249,20 +263,15 @@
 dirsize_quota_try_alloc(struct quota_transaction_context *ctx,
 			struct mail *mail, int *too_large_r)
 {
-	struct dirsize_quota *quota = (struct dirsize_quota *)ctx->quota;
-	uint64_t value = 0;
 	uoff_t size;
 
-	size = mail_get_physical_size(mail);
-	*too_large_r = size / 1024 > quota->storage_limit;
-
-	if (get_dir_usage(quota->path, &value) < 0 || size == (uoff_t)-1) {
-		quota->error = "Internal quota calculation error";
+	if (ctx->storage_current == (uoff_t)-1)
 		return -1;
-	}
-	value += ctx->bytes_diff;
 
-	if ((value + size) / 1024 > quota->storage_limit)
+	size = mail_get_physical_size(mail);
+	*too_large_r = size > ctx->storage_limit;
+
+	if (ctx->storage_current + ctx->bytes_diff + size > ctx->storage_limit)
 		return 0;
 
 	ctx->bytes_diff += size;

Index: quota-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/quota/quota-private.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- quota-private.h	10 Dec 2005 19:44:46 -0000	1.1
+++ quota-private.h	28 Dec 2005 20:17:51 -0000	1.2
@@ -61,6 +61,9 @@
 
 	int count_diff;
 	int64_t bytes_diff;
+
+	uint64_t storage_limit;
+	uint64_t storage_current;
 };
 
 #endif



More information about the dovecot-cvs mailing list