changeset 22289:471c8c88c5d1

lib-storage: mailbox_list_delete_mailbox_nonrecursive() - Fix error handling It should return error on unexpected readdir(), closedir() and unlink() failures. Also fix handling a race condition with another process deleting the mailbox at the same time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 27 Jun 2017 15:39:12 +0300
parents 7adf8266c54b
children f01b39a6d3b4
files src/lib-storage/list/mailbox-list-delete.c
diffstat 1 files changed, 14 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-delete.c	Tue Jun 27 16:56:08 2017 +0300
+++ b/src/lib-storage/list/mailbox-list-delete.c	Tue Jun 27 15:39:12 2017 +0300
@@ -146,6 +146,7 @@
 	string_t *full_path;
 	size_t dir_len;
 	bool mailbox_dir, unlinked_something = FALSE;
+	int ret = 0;
 
 	if (mailbox_list_check_root_delete(list, name, path) < 0)
 		return -1;
@@ -203,20 +204,30 @@
 		else if (errno != ENOENT && !UNLINK_EISDIR(errno)) {
 			mailbox_list_set_critical(list,
 				"unlink(%s) failed: %m", str_c(full_path));
+			ret = -1;
 		}
 	}
-	if (errno != 0)
+	if (errno != 0) {
 		mailbox_list_set_critical(list, "readdir(%s) failed: %m", path);
+		ret = -1;
+	}
 	if (closedir(dir) < 0) {
 		mailbox_list_set_critical(list, "closedir(%s) failed: %m",
 					  path);
+		ret = -1;
 	}
+	if (ret < 0)
+		return -1;
 
 	if (rmdir_path) {
 		if (rmdir(path) == 0)
 			unlinked_something = TRUE;
-		else if (errno != ENOENT &&
-			 errno != ENOTEMPTY && errno != EEXIST) {
+		else if (errno == ENOENT) {
+			/* race condition with another process, which finished
+			   deleting it first. */
+			mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
+				T_MAILBOX_LIST_ERR_NOT_FOUND(list, name));
+		} else if (errno != ENOTEMPTY && errno != EEXIST) {
 			mailbox_list_set_critical(list, "rmdir(%s) failed: %m",
 						  path);
 			return -1;