From: Timo Sirainen Date: Fri, 15 Aug 2014 11:41:03 +0000 (+0300) Subject: Handle "out of disk space" and "out of user quota" as separate cases. X-Git-Tag: 2.2.14.rc1~154 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ed2459dbd183bb371da4a0aecb2d2b74ae7c815;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 796dece827..f62fb4c1c8 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -57,7 +57,7 @@ void doveadm_mail_failed_error(struct doveadm_mail_cmd_context *ctx, 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 --git a/src/imap/imap-commands-util.c b/src/imap/imap-commands-util.c index 902fa36525..52843d88f6 100644 --- a/src/imap/imap-commands-util.c +++ b/src/imap/imap-commands-util.c @@ -133,7 +133,7 @@ imap_get_error_string(struct client_command_context *cmd, 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 --git a/src/lda/main.c b/src/lda/main.c index 581b1bfa95..12ff72478b 100644 --- a/src/lda/main.c +++ b/src/lda/main.c @@ -452,7 +452,7 @@ int main(int argc, char *argv[]) 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 --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 8bf578d58c..25095057f8 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -45,7 +45,7 @@ static struct imapc_resp_code_map imapc_resp_code_map[] = { /* { 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 --git a/src/lib-storage/index/maildir/maildir-copy.c b/src/lib-storage/index/maildir/maildir-copy.c index a94c83a332..289f8580f0 100644 --- a/src/lib-storage/index/maildir/maildir-copy.c +++ b/src/lib-storage/index/maildir/maildir-copy.c @@ -34,9 +34,9 @@ static int do_hardlink(struct maildir_mailbox *mbox, const char *path, 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 --git a/src/lib-storage/index/maildir/maildir-save.c b/src/lib-storage/index/maildir/maildir-save.c index d8e09476c9..df6309120a 100644 --- a/src/lib-storage/index/maildir/maildir-save.c +++ b/src/lib-storage/index/maildir/maildir-save.c @@ -102,9 +102,9 @@ static int maildir_file_move(struct maildir_save_context *ctx, 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 @@ static int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir, *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 @@ static int maildir_save_finish_real(struct mail_save_context *_ctx) } 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 --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 3774da526f..350a2b247a 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -72,9 +72,9 @@ void mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function) { 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 --git a/src/lib-storage/mail-error.c b/src/lib-storage/mail-error.c index 66c95edc15..aad98b200b 100644 --- a/src/lib-storage/mail-error.c +++ b/src/lib-storage/mail-error.c @@ -10,9 +10,9 @@ bool mail_error_from_errno(enum mail_error *error_r, 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 --git a/src/lib-storage/mail-error.h b/src/lib-storage/mail-error.h index d7a3b2cdb2..9251ccec35 100644 --- a/src/lib-storage/mail-error.h +++ b/src/lib-storage/mail-error.h @@ -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 @@ enum mail_error { 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 @@ enum mail_error { /* 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 --git a/src/lib/compat.h b/src/lib/compat.h index df27a7768c..e13165620a 100644 --- a/src/lib/compat.h +++ b/src/lib/compat.h @@ -231,8 +231,12 @@ int i_my_clock_gettime(int clk_id, struct timespec *tp); #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 --git a/src/lmtp/commands.c b/src/lmtp/commands.c index 8f890c4b71..5f3b284925 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -488,7 +488,7 @@ lmtp_rcpt_to_is_over_quota(struct client *client, 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 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt, 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 --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index 6140219628..4f015e025c 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -87,7 +87,7 @@ quota_get_status(struct mailbox *box, enum mailbox_status_items items, 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 @@ static int quota_check(struct mail_save_context *ctx) 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 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input) 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 --git a/src/plugins/snarf/snarf-plugin.c b/src/plugins/snarf/snarf-plugin.c index 7074e07cb2..0ea86b6bab 100644 --- a/src/plugins/snarf/snarf-plugin.c +++ b/src/plugins/snarf/snarf-plugin.c @@ -67,7 +67,7 @@ static int snarf(struct mailbox *srcbox, struct mailbox *destbox) 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 --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c index 76f4ec3311..a59dc68d69 100644 --- a/src/pop3/pop3-client.c +++ b/src/pop3/pop3-client.c @@ -714,7 +714,7 @@ void client_send_storage_error(struct client *client) 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;