From 28a60c456bc52bbe949ad54c6b23917a651fc342 Mon Sep 17 00:00:00 2001
From: Ian Abbott <abbotti@mev.co.uk>
Date: Wed, 18 Nov 2015 17:55:11 +0000
Subject: [PATCH] staging: comedi: check for more errors for zero-length write

If the "write" file operation handler, `comedi_write()` is passed 0 for
the amount to write, some error conditions are currently skipped and the
function just returns 0.  Change it to check those error conditions and
return an error value if appropriate.  The trickiest case is the check
for when the previously set up asynchronous command has terminated with
an error.  In that case, `-EPIPE` is returned (as it is for a write of
non-zero length) and the subdevice gets marked as non-busy.

A zero-length write that returns 0 has no other effects, in particular,
it does not cause the subdevice to be marked as non-busy.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/comedi/comedi_fops.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 5a9c9d9782f3..d57fadef47fc 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2331,8 +2331,6 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
 	}
 
 	async = s->async;
-	if (!nbytes)
-		goto out;
 	if (s->busy != file || !(async->cmd.flags & CMDF_WRITE)) {
 		retval = -EINVAL;
 		goto out;
@@ -2349,9 +2347,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
 		if (!comedi_is_runflags_running(runflags)) {
 			if (comedi_is_runflags_in_error(runflags))
 				retval = -EPIPE;
-			become_nonbusy = true;
+			if (retval || nbytes)
+				become_nonbusy = true;
 			break;
 		}
+		if (nbytes == 0)
+			break;
 
 		/* Allocate all free buffer space. */
 		comedi_buf_write_alloc(s, async->prealloc_bufsz);
-- 
2.30.2