Mercurial > dovecot > core-2.2
changeset 22336:8f674d4111cf
lib-storage: When index dir rmdir() fails with ENOTEMPTY, retry it for 1 second
This helps to avoid leaving those index directories lying around with NFS.
Hopefully within the 1 second any existing processes that have been keeping those
files open have finished their task. Especially IMAP IDLE will take 0.5 seconds
to start syncing indexes and realize that they're deleted.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Fri, 14 Jul 2017 02:11:56 +0300 |
parents | 510ee47cc21f |
children | 31d2459cfcf2 |
files | src/lib-storage/list/mailbox-list-delete.c |
diffstat | 1 files changed, 14 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-delete.c Fri Jul 14 01:54:31 2017 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Fri Jul 14 02:11:56 2017 +0300 @@ -205,6 +205,9 @@ mailbox_list_set_critical(list, "unlink(%s) failed: %m", str_c(full_path)); ret = -1; + } else { + /* child directories still exist */ + rmdir_path = FALSE; } } if (errno != 0) { @@ -220,6 +223,17 @@ return -1; if (rmdir_path) { + unsigned int try_count = 0; + int ret = rmdir(path); + while (ret < 0 && errno == ENOTEMPTY && try_count++ < 10) { + /* We didn't see any child directories, so this is + either a race condition or .nfs* files were left + lying around. In case it's .nfs* files, retry after + waiting a bit. Hopefully all processes keeping those + files open will have closed them by then. */ + usleep(100000); + ret = rmdir(path); + } if (rmdir(path) == 0) unlinked_something = TRUE; else if (errno == ENOENT) {