

If at the end of direct_io_worker, dio->result is non-zero then we
unconditionally copy that into the return value, potentially ignoring any I/O
errors which were accumulated into local variable `ret'.

Only do the assignment if `ret' is zero.


 direct-io.c |   23 ++++++++++-------------
 1 files changed, 10 insertions(+), 13 deletions(-)

diff -puN fs/direct-io.c~direct-io-retval-fix fs/direct-io.c
--- 25/fs/direct-io.c~direct-io-retval-fix	2003-02-12 21:28:06.000000000 -0800
+++ 25-akpm/fs/direct-io.c	2003-02-12 21:28:30.000000000 -0800
@@ -927,20 +927,17 @@ direct_io_worker(int rw, struct kiocb *i
 			ret = dio->result;	/* Bytes written */
 		finished_one_bio(dio);		/* This can free the dio */
 		blk_run_queues();
-		goto out;
+	} else {
+		finished_one_bio(dio);
+		ret2 = dio_await_completion(dio);
+		if (ret == 0)
+			ret = ret2;
+		if (ret == 0)
+			ret = dio->page_errors;
+		if (ret == 0 && dio->result)
+			ret = dio->result;
+		kfree(dio);
 	}
-
-	finished_one_bio(dio);
-	ret2 = dio_await_completion(dio);
-	if (ret == 0)
-		ret = ret2;
-	if (ret == 0)
-		ret = dio->page_errors;
-
-	if (dio->result)
-		ret = dio->result;
-	kfree(dio);
-out:
 	return ret;
 }
 

_
