From dd087896285da9e160e13ee9f7d75381b67895e3 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 26 Jul 2007 16:30:46 -0400 Subject: [PATCH] Use __fpurge to ensure single-line writes to cache files On a recent Debian/Sid machine, I saw libc retrying stdio writes that returned write errors. The result is that if an export downcall returns an error (which it can in normal operation, since it currently (incorrectly) returns -ENOENT on any negative downcall), then subsequent downcalls will write multiple lines (including the original line that received the error). The result is that the server fails to respond to any rpc call that refers to an unexported mount point (such as a readdir of a directory containing such a mountpoint), so client commands hang. I don't know whether this libc behavior is correct or expected, but it seems safest to add the __fpurge() (suggested by Neil) to ensure data is thrown away. Signed-off-by: "J. Bruce Fields" Signed-off-by: Neil Brown --- support/nfs/cacheio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c index a76915b..9d271cd 100644 --- a/support/nfs/cacheio.c +++ b/support/nfs/cacheio.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -111,7 +112,18 @@ void qword_printint(FILE *f, int num) int qword_eol(FILE *f) { + int err; + fprintf(f,"\n"); + err = fflush(f); + /* + * We must send one line (and one line only) in a single write + * call. In case of a write error, libc may accumulate the + * unwritten data and try to write it again later, resulting in a + * multi-line write. So we must explicitly ask it to throw away + * any such cached data: + */ + __fpurge(f); return fflush(f); } -- 2.39.5