changeset 4072:7e6acdd8d18d HEAD

If we reach the NFS_ESTALE_RETRY_COUNT, give an ESTALE error message as well.
author Timo Sirainen <tss@iki.fi>
date Sun, 26 Feb 2006 12:32:19 +0200
parents cd3d26cf124a
children cd701884900c
files src/lib-index/mail-index.c src/lib-index/mail-transaction-log.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/subscription-file/subscription-file.c
diffstat 4 files changed, 51 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index.c	Sun Feb 26 12:15:39 2006 +0200
+++ b/src/lib-index/mail-index.c	Sun Feb 26 12:32:19 2006 +0200
@@ -686,8 +686,9 @@
 	return ret;
 }
 
-static int mail_index_read_map(struct mail_index *index,
-			       struct mail_index_map *map, bool *retry_r)
+static int
+mail_index_read_map(struct mail_index *index, struct mail_index_map *map,
+		    bool *retry_r, bool try_retry)
 {
 	const struct mail_index_header *hdr;
 	unsigned char buf[512];
@@ -753,7 +754,7 @@
 	}
 
 	if (ret < 0) {
-		if (errno == ESTALE) {
+		if (errno == ESTALE && try_retry) {
 			/* a new index file was renamed over this one. */
 			*retry_r = TRUE;
 			return 0;
@@ -920,8 +921,9 @@
 		(*handlers[i])(index);
 
 	for (i = 0;; i++) {
-		ret = mail_index_read_map(index, *map, &retry);
-		if (ret != 0 || !retry || i == MAIL_INDEX_ESTALE_RETRY_COUNT)
+		ret = mail_index_read_map(index, *map, &retry,
+					  i < MAIL_INDEX_ESTALE_RETRY_COUNT);
+		if (ret != 0 || !retry)
 			return ret;
 
 		/* ESTALE - reopen index file */
@@ -1083,7 +1085,7 @@
 	for (i = 0;; i++) {
 		ret = mail_index_read_header(index, hdr_r, sizeof(*hdr_r),
 					     &pos);
-		if (ret >= 0 || errno != ESTALE ||
+		if (ret <= 0 || errno != ESTALE ||
 		    i == MAIL_INDEX_ESTALE_RETRY_COUNT)
 			break;
 
@@ -1102,6 +1104,9 @@
 			return -1;
 		}
 	}
+
+	if (ret < 0)
+		mail_index_set_syscall_error(index, "pread_full()");
 	return ret;
 }
 
--- a/src/lib-index/mail-transaction-log.c	Sun Feb 26 12:15:39 2006 +0200
+++ b/src/lib-index/mail-transaction-log.c	Sun Feb 26 12:32:19 2006 +0200
@@ -354,7 +354,7 @@
 
 static int
 mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file,
-				   int head)
+				   int head, bool ignore_estale)
 {
         struct mail_transaction_log_file *f;
 	int ret;
@@ -363,7 +363,7 @@
 
 	ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0);
 	if (ret < 0) {
-                if (errno != ESTALE) {
+                if (errno != ESTALE || !ignore_estale) {
                         mail_index_file_set_syscall_error(file->log->index,
                                                           file->filepath,
                                                           "pread_full()");
@@ -642,7 +642,8 @@
 static int
 mail_transaction_log_file_fd_open(struct mail_transaction_log *log,
                                   struct mail_transaction_log_file **file_r,
-				  const char *path, int fd, bool head)
+				  const char *path, int fd, bool head,
+				  bool ignore_estale)
 {
         struct mail_transaction_log_file *file;
 	struct stat st;
@@ -653,7 +654,7 @@
 	*file_r = NULL;
 
 	if (fstat(fd, &st) < 0) {
-                if (errno != ESTALE) {
+                if (errno != ESTALE || !ignore_estale) {
                         mail_index_file_set_syscall_error(log->index, path,
                                                           "fstat()");
                 }
@@ -671,7 +672,7 @@
 	file->last_mtime = st.st_mtime;
 	file->last_size = st.st_size;
 
-	ret = mail_transaction_log_file_read_hdr(file, head);
+	ret = mail_transaction_log_file_read_hdr(file, head, ignore_estale);
 	if (ret < 0) {
 		mail_transaction_log_file_free(file);
 		return -1;
@@ -685,7 +686,7 @@
 static struct mail_transaction_log_file *
 mail_transaction_log_file_fd_open_or_create(struct mail_transaction_log *log,
                                             const char *path, int fd,
-                                            bool *retry_r)
+                                            bool *retry_r, bool try_retry)
 {
 	struct mail_transaction_log_file *file;
 	struct stat st;
@@ -693,9 +694,10 @@
 
         *retry_r = FALSE;
 
-	ret = mail_transaction_log_file_fd_open(log, &file, path, fd, TRUE);
+	ret = mail_transaction_log_file_fd_open(log, &file, path, fd, TRUE,
+						!try_retry);
         if (ret < 0) {
-                *retry_r = errno == ESTALE;
+                *retry_r = errno == ESTALE && try_retry;
                 return NULL;
         }
 
@@ -724,11 +726,12 @@
 			file->last_size = st.st_size;
 
 			memset(&file->hdr, 0, sizeof(file->hdr));
-			ret = mail_transaction_log_file_read_hdr(file, TRUE);
+			ret = mail_transaction_log_file_read_hdr(file, TRUE,
+								 !try_retry);
 		}
 	}
 	if (ret <= 0) {
-                *retry_r = errno == ESTALE;
+                *retry_r = errno == ESTALE && try_retry;
 		mail_transaction_log_file_free(file);
 		return NULL;
 	}
@@ -790,9 +793,8 @@
                 }
 
                 file = mail_transaction_log_file_fd_open_or_create(log, path,
-                                                                   fd, &retry);
-                if (file != NULL || !retry ||
-                    i == MAIL_INDEX_ESTALE_RETRY_COUNT)
+                		fd, &retry, i == MAIL_INDEX_ESTALE_RETRY_COUNT);
+                if (file != NULL || !retry)
                         return file;
 
                 /* ESTALE - retry */
@@ -816,7 +818,7 @@
                 }
 
                 ret = mail_transaction_log_file_fd_open(log, &file, path,
-                                                        fd, TRUE);
+                		fd, TRUE, i < MAIL_INDEX_ESTALE_RETRY_COUNT);
                 if (ret > 0)
                         break;
 
@@ -880,13 +882,9 @@
 			return -1;
 
                 file = mail_transaction_log_file_fd_open_or_create(log, path,
-                                                                   fd, &retry);
+                					fd, &retry, FALSE);
                 if (file == NULL) {
-                        if (retry) {
-                                mail_index_set_error(log->index,
-                                	"%s: ESTALE unexpected while locked",
-                                        path);
-                        }
+			i_assert(!retry);
                         return -1;
                 }
 	}
@@ -1007,7 +1005,8 @@
 		}
 	}
 
-	ret = mail_transaction_log_file_fd_open(log, &file, path, fd, FALSE);
+	ret = mail_transaction_log_file_fd_open(log, &file, path, fd,
+						FALSE, TRUE);
 	if (ret <= 0) {
 		if (ret == 0) {
 			/* corrupted, delete it */
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Feb 26 12:15:39 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Feb 26 12:32:19 2006 +0200
@@ -247,7 +247,8 @@
 }
 
 static int
-maildir_uidlist_update_read(struct maildir_uidlist *uidlist, bool *retry_r)
+maildir_uidlist_update_read(struct maildir_uidlist *uidlist,
+			    bool *retry_r, bool try_retry)
 {
 	struct mail_storage *storage = STORAGE(uidlist->mbox->storage);
 	const char *line;
@@ -270,7 +271,7 @@
 
 	if (fstat(fd, &st) < 0) {
                 close_keep_errno(fd);
-                if (errno == ESTALE) {
+                if (errno == ESTALE && try_retry) {
                         *retry_r = TRUE;
                         return -1;
                 }
@@ -334,8 +335,13 @@
 		uidlist->last_mtime = st.st_mtime;
         } else {
                 /* I/O error */
-                if (input->stream_errno == ESTALE)
-                        *retry_r = TRUE;
+                if (input->stream_errno == ESTALE && try_retry)
+			*retry_r = TRUE;
+		else {
+			errno = input->stream_errno;
+			mail_storage_set_critical(storage,
+				"read(%s) failed: %m", uidlist->fname);
+		}
         }
 
 	i_stream_destroy(&input);
@@ -367,8 +373,9 @@
 	}
 
         for (i = 0; ; i++) {
-                ret = maildir_uidlist_update_read(uidlist, &retry);
-                if (!retry || i == UIDLIST_ESTALE_RETRY_COUNT) {
+		ret = maildir_uidlist_update_read(uidlist, &retry,
+						i < UIDLIST_ESTALE_RETRY_COUNT);
+                if (!retry) {
                         if (ret >= 0)
                                 uidlist->initial_read = TRUE;
                         break;
--- a/src/lib-storage/subscription-file/subscription-file.c	Sun Feb 26 12:15:39 2006 +0200
+++ b/src/lib-storage/subscription-file/subscription-file.c	Sun Feb 26 12:32:19 2006 +0200
@@ -42,7 +42,8 @@
 }
 
 static const char *next_line(struct mail_storage *storage, const char *path,
-			     struct istream *input, bool *failed_r)
+			     struct istream *input, bool *failed_r,
+			     bool ignore_estale)
 {
 	const char *line;
 
@@ -54,7 +55,7 @@
                 switch (i_stream_read(input)) {
 		case -1:
                         if (input->stream_errno != 0 &&
-                            input->stream_errno != ESTALE) {
+                            (input->stream_errno != ESTALE || !ignore_estale)) {
                                 subsfile_set_syscall_error(storage,
                                                            "read()", path);
                                 *failed_r = TRUE;
@@ -118,7 +119,8 @@
 	output = o_stream_create_file(fd_out, default_pool,
 				      MAX_MAILBOX_LENGTH, FALSE);
 	found = FALSE;
-	while ((line = next_line(storage, path, input, &failed)) != NULL) {
+	while ((line = next_line(storage, path, input,
+				 &failed, FALSE)) != NULL) {
 		if (strcmp(line, name) == 0) {
 			found = TRUE;
 			if (!set)
@@ -212,7 +214,8 @@
 
         for (i = 0;; i++) {
                 line = next_line(ctx->storage, ctx->path, ctx->input,
-                                 &ctx->failed);
+				 &ctx->failed,
+				 i < SUBSCRIPTION_FILE_ESTALE_RETRY_COUNT);
                 if (ctx->input->stream_errno != ESTALE ||
                     i == SUBSCRIPTION_FILE_ESTALE_RETRY_COUNT)
                         break;