dovecot-2.2: Handle "out of disk space" and "out of user quota" ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Aug 15 11:43:28 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/286da24ada43
changeset: 17716:286da24ada43
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Aug 15 14:41:03 2014 +0300
description:
Handle "out of disk space" and "out of user quota" as separate cases.
"Out of disk space" is a temporary error that should be logged as error and
the failure should be sent to user as "Internal server error".

Obsolete the use of MAIL_ERROR_NOSPACE and MAIL_ERRSTR_NO_SPACE. Use the
clearer MAIL_ERROR_NOQUOTA and MAIL_ERRSTR_NO_QUOTA instead.

diffstat:

 src/doveadm/doveadm-mail.c                   |   2 +-
 src/imap/imap-commands-util.c                |   2 +-
 src/lda/main.c                               |   2 +-
 src/lib-storage/index/imapc/imapc-storage.c  |   2 +-
 src/lib-storage/index/maildir/maildir-copy.c |   4 ++--
 src/lib-storage/index/maildir/maildir-save.c |  14 +++++++-------
 src/lib-storage/index/mbox/mbox-storage.c    |   4 ++--
 src/lib-storage/mail-error.c                 |   6 +++---
 src/lib-storage/mail-error.h                 |  11 ++++++++---
 src/lib/compat.h                             |   4 ++++
 src/lmtp/commands.c                          |   4 ++--
 src/plugins/quota/quota-storage.c            |   6 +++---
 src/plugins/snarf/snarf-plugin.c             |   2 +-
 src/pop3/pop3-client.c                       |   2 +-
 14 files changed, 37 insertions(+), 28 deletions(-)

diffs (260 lines):

diff -r 5e818f1b376d -r 286da24ada43 src/doveadm/doveadm-mail.c
--- a/src/doveadm/doveadm-mail.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/doveadm/doveadm-mail.c	Fri Aug 15 14:41:03 2014 +0300
@@ -57,7 +57,7 @@
 	case MAIL_ERROR_PERM:
 		exit_code = EX_NOPERM;
 		break;
-	case MAIL_ERROR_NOSPACE:
+	case MAIL_ERROR_NOQUOTA:
 		exit_code = EX_CANTCREAT;
 		break;
 	case MAIL_ERROR_NOTFOUND:
diff -r 5e818f1b376d -r 286da24ada43 src/imap/imap-commands-util.c
--- a/src/imap/imap-commands-util.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/imap/imap-commands-util.c	Fri Aug 15 14:41:03 2014 +0300
@@ -133,7 +133,7 @@
 	case MAIL_ERROR_PERM:
 		resp_code = IMAP_RESP_CODE_NOPERM;
 		break;
-	case MAIL_ERROR_NOSPACE:
+	case MAIL_ERROR_NOQUOTA:
 		resp_code = IMAP_RESP_CODE_OVERQUOTA;
 		break;
 	case MAIL_ERROR_NOTFOUND:
diff -r 5e818f1b376d -r 286da24ada43 src/lda/main.c
--- a/src/lda/main.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lda/main.c	Fri Aug 15 14:41:03 2014 +0300
@@ -452,7 +452,7 @@
 			fprintf(stderr, "%s\n", errstr);
 		}
 
-		if (error != MAIL_ERROR_NOSPACE ||
+		if (error != MAIL_ERROR_NOQUOTA ||
 		    ctx.set->quota_full_tempfail) {
 			/* Saving to INBOX should always work unless
 			   we're over quota. If it didn't, it's probably a
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Fri Aug 15 14:41:03 2014 +0300
@@ -45,7 +45,7 @@
 	/* { IMAP_RESP_CODE_CLIENTBUG, 0 }, */
 	{ IMAP_RESP_CODE_CANNOT, MAIL_ERROR_NOTPOSSIBLE },
 	{ IMAP_RESP_CODE_LIMIT, MAIL_ERROR_NOTPOSSIBLE },
-	{ IMAP_RESP_CODE_OVERQUOTA, MAIL_ERROR_NOSPACE },
+	{ IMAP_RESP_CODE_OVERQUOTA, MAIL_ERROR_NOQUOTA },
 	{ IMAP_RESP_CODE_ALREADYEXISTS, MAIL_ERROR_EXISTS },
 	{ IMAP_RESP_CODE_NONEXISTENT, MAIL_ERROR_NOTFOUND }
 };
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/index/maildir/maildir-copy.c
--- a/src/lib-storage/index/maildir/maildir-copy.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Fri Aug 15 14:41:03 2014 +0300
@@ -34,9 +34,9 @@
 		if (errno == ENOENT)
 			return 0;
 
-		if (ENOSPACE(errno)) {
+		if (ENOQUOTA(errno)) {
 			mail_storage_set_error(&mbox->storage->storage,
-				MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
+				MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA);
 			return -1;
 		}
 
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Fri Aug 15 14:41:03 2014 +0300
@@ -102,9 +102,9 @@
 	if (rename(tmp_path, new_path) == 0) {
 		mf->flags |= MAILDIR_FILENAME_FLAG_MOVED;
 		return 0;
-	} else if (ENOSPACE(errno)) {
-		mail_storage_set_error(storage, MAIL_ERROR_NOSPACE,
-				       MAIL_ERRSTR_NO_SPACE);
+	} else if (ENOQUOTA(errno)) {
+		mail_storage_set_error(storage, MAIL_ERROR_NOQUOTA,
+				       MAIL_ERRSTR_NO_QUOTA);
 		return -1;
 	} else {
 		mail_storage_set_critical(storage, "rename(%s, %s) failed: %m",
@@ -376,9 +376,9 @@
 
 	*fname_r = tmp_fname;
 	if (fd == -1) {
-		if (ENOSPACE(errno)) {
+		if (ENOQUOTA(errno)) {
 			mail_storage_set_error(box->storage,
-				MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
+				MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA);
 		} else {
 			mail_storage_set_critical(box->storage,
 				"open(%s) failed: %m", str_c(path));
@@ -630,9 +630,9 @@
 		}
 
 		errno = output_errno;
-		if (ENOSPACE(errno)) {
+		if (ENOQUOTA(errno)) {
 			mail_storage_set_error(storage,
-				MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
+				MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA);
 		} else if (errno != 0) {
 			mail_storage_set_critical(storage,
 				"write(%s) failed: %m", path);
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Fri Aug 15 14:41:03 2014 +0300
@@ -72,9 +72,9 @@
 {
 	i_assert(function != NULL);
 
-	if (ENOSPACE(errno)) {
+	if (ENOQUOTA(errno)) {
 		mail_storage_set_error(&mbox->storage->storage,
-			MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
+			MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA);
 	} else {
 		const char *toobig_error = errno != EFBIG ? "" :
 			" (process was started with ulimit -f limit)";
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/mail-error.c
--- a/src/lib-storage/mail-error.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/mail-error.c	Fri Aug 15 14:41:03 2014 +0300
@@ -10,9 +10,9 @@
 	if (ENOACCESS(errno)) {
 		*error_r = MAIL_ERROR_PERM;
 		*error_string_r = MAIL_ERRSTR_NO_PERMISSION;
-	} else if (ENOSPACE(errno)) {
-		*error_r = MAIL_ERROR_NOSPACE;
-		*error_string_r = MAIL_ERRSTR_NO_SPACE;
+	} else if (ENOQUOTA(errno)) {
+		*error_r = MAIL_ERROR_NOQUOTA;
+		*error_string_r = MAIL_ERRSTR_NO_QUOTA;
 	} else if (ENOTFOUND(errno)) {
 		*error_r = MAIL_ERROR_NOTFOUND;
 		*error_string_r = errno != ELOOP ? "Not found" :
diff -r 5e818f1b376d -r 286da24ada43 src/lib-storage/mail-error.h
--- a/src/lib-storage/mail-error.h	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib-storage/mail-error.h	Fri Aug 15 14:41:03 2014 +0300
@@ -7,7 +7,9 @@
 #define MAIL_ERRSTR_NO_PERMISSION "Permission denied"
 
 /* And just for making error strings consistent: */
-#define MAIL_ERRSTR_NO_SPACE "Not enough disk space"
+#define MAIL_ERRSTR_NO_QUOTA "Not enough disk quota"
+/* FIXME: Obsolete - remove for v2.3 */
+#define MAIL_ERRSTR_NO_SPACE MAIL_ERRSTR_NO_QUOTA
 #define MAIL_ERRSTR_LOCK_TIMEOUT "Timeout while waiting for lock"
 
 /* Message to show to users when critical error occurs */
@@ -30,8 +32,8 @@
 	MAIL_ERROR_PARAMS,
 	/* No permission to do the request */
 	MAIL_ERROR_PERM,
-	/* Out of disk space or quota */
-	MAIL_ERROR_NOSPACE,
+	/* Out of disk quota for user */
+	MAIL_ERROR_NOQUOTA,
 	/* Item (e.g. mailbox) doesn't exist or it's not visible to us */
 	MAIL_ERROR_NOTFOUND,
 	/* Item (e.g. mailbox) already exists */
@@ -47,6 +49,9 @@
 	/* Can't do the requested data conversion because the original data
 	   isn't valid. */
 	MAIL_ERROR_INVALIDDATA
+
+	/* FIXME: Obsolete - remove in v2.3 */
+	MAIL_ERROR_NOSPACE = MAIL_ERROR_NOQUOTA
 };
 
 /* Convert errno to mail_error and an error string. Returns TRUE if successful,
diff -r 5e818f1b376d -r 286da24ada43 src/lib/compat.h
--- a/src/lib/compat.h	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lib/compat.h	Fri Aug 15 14:41:03 2014 +0300
@@ -231,8 +231,12 @@
 
 #ifdef EDQUOT
 #  define ENOSPACE(errno) ((errno) == ENOSPC || (errno) == EDQUOT)
+#  define ENOQUOTA(errno) ((errno) == EDQUOT)
 #else
+/* probably all modern OSes have EDQUOT, but just in case one doesn't assume
+   that ENOSPC is the same as "over quota". */
 #  define ENOSPACE(errno) ((errno) == ENOSPC)
+#  define ENOQUOTA(errno) ((errno) == ENOSPC)
 #endif
 
 /* EPERM is returned sometimes if device doesn't support such modification */
diff -r 5e818f1b376d -r 286da24ada43 src/lmtp/commands.c
--- a/src/lmtp/commands.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/lmtp/commands.c	Fri Aug 15 14:41:03 2014 +0300
@@ -488,7 +488,7 @@
 	ret = mailbox_get_status(box, STATUS_CHECK_OVER_QUOTA, &status);
 	if (ret < 0) {
 		errstr = mailbox_get_last_error(box, &error);
-		if (error == MAIL_ERROR_NOSPACE) {
+		if (error == MAIL_ERROR_NOQUOTA) {
 			client_send_line(client, "552 5.2.2 <%s> %s",
 					 rcpt->address, errstr);
 			ret = 1;
@@ -690,7 +690,7 @@
 		ret = 0;
 	} else if (storage != NULL) {
 		error = mail_storage_get_last_error(storage, &mail_error);
-		if (mail_error == MAIL_ERROR_NOSPACE) {
+		if (mail_error == MAIL_ERROR_NOQUOTA) {
 			client_send_line(client, "%s <%s> %s",
 					 dctx.set->quota_full_tempfail ?
 					 "452 4.2.2" : "552 5.2.2",
diff -r 5e818f1b376d -r 286da24ada43 src/plugins/quota/quota-storage.c
--- a/src/plugins/quota/quota-storage.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/plugins/quota/quota-storage.c	Fri Aug 15 14:41:03 2014 +0300
@@ -87,7 +87,7 @@
 	if ((items & STATUS_CHECK_OVER_QUOTA) != 0) {
 		qt = quota_transaction_begin(box);
 		if ((ret = quota_test_alloc(qt, 0, &too_large)) == 0) {
-			mail_storage_set_error(box->storage, MAIL_ERROR_NOSPACE,
+			mail_storage_set_error(box->storage, MAIL_ERROR_NOQUOTA,
 					       qt->quota->set->quota_exceeded_msg);
 			ret = -1;
 		}
@@ -190,7 +190,7 @@
 	if (ret > 0)
 		return 0;
 	else if (ret == 0) {
-		mail_storage_set_error(t->box->storage, MAIL_ERROR_NOSPACE,
+		mail_storage_set_error(t->box->storage, MAIL_ERROR_NOQUOTA,
 				       qt->quota->set->quota_exceeded_msg);
 		return -1;
 	} else {
@@ -252,7 +252,7 @@
 		ret = quota_test_alloc(qt, size, &too_large);
 		if (ret == 0) {
 			mail_storage_set_error(t->box->storage,
-				MAIL_ERROR_NOSPACE,
+				MAIL_ERROR_NOQUOTA,
 				qt->quota->set->quota_exceeded_msg);
 			return -1;
 		} else if (ret < 0) {
diff -r 5e818f1b376d -r 286da24ada43 src/plugins/snarf/snarf-plugin.c
--- a/src/plugins/snarf/snarf-plugin.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/plugins/snarf/snarf-plugin.c	Fri Aug 15 14:41:03 2014 +0300
@@ -67,7 +67,7 @@
 			error = mailbox_get_last_mail_error(destbox);
 			/* if we failed because of out of disk space, just
 			   move those messages we managed to move so far. */
-			if (error != MAIL_ERROR_NOSPACE)
+			if (error != MAIL_ERROR_NOQUOTA)
 				ret = -1;
 			break;
 		}
diff -r 5e818f1b376d -r 286da24ada43 src/pop3/pop3-client.c
--- a/src/pop3/pop3-client.c	Fri Aug 15 14:05:21 2014 +0300
+++ b/src/pop3/pop3-client.c	Fri Aug 15 14:41:03 2014 +0300
@@ -714,7 +714,7 @@
 	errstr = mailbox_get_last_error(client->mailbox, &error);
 	switch (error) {
 	case MAIL_ERROR_TEMP:
-	case MAIL_ERROR_NOSPACE:
+	case MAIL_ERROR_NOQUOTA:
 	case MAIL_ERROR_INUSE:
 		client_send_line(client, "-ERR [SYS/TEMP] %s", errstr);
 		break;


More information about the dovecot-cvs mailing list