summaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi
diff options
context:
space:
mode:
authorIan Abbott2015-10-12 18:21:29 +0200
committerGreg Kroah-Hartman2015-10-13 19:29:48 +0200
commit3c3bea26ad3037924fd066c14fd391a69103dd63 (patch)
tree6c2b3a9ac242f1d31a484b8e340def66eefdc7b8 /drivers/staging/comedi
parentstaging: comedi: simplify returned errors for comedi_read() (diff)
downloadkernel-qcow2-linux-3c3bea26ad3037924fd066c14fd391a69103dd63.tar.gz
kernel-qcow2-linux-3c3bea26ad3037924fd066c14fd391a69103dd63.tar.xz
kernel-qcow2-linux-3c3bea26ad3037924fd066c14fd391a69103dd63.zip
staging: comedi: check for more errors for zero-length read
If the "read" file operation handler, `comedi_read()` is passed 0 for the amount to read, 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 read of non-zero length) and the subdevice gets marked as non-busy. A zero-length read that returns 0 has no other effects, in particular, it does not cause the subdevice to be marked as non-busy, and the return value does not indicate an "end-of-file" condition. 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>
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r--drivers/staging/comedi/comedi_fops.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 466dc95d5611..7b4af519e17e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2478,15 +2478,13 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
}
async = s->async;
- if (!nbytes)
- goto out;
if (s->busy != file || (async->cmd.flags & CMDF_WRITE)) {
retval = -EINVAL;
goto out;
}
add_wait_queue(&async->wait_head, &wait);
- while (nbytes > 0 && !retval) {
+ while (count == 0 && !retval) {
unsigned int rp, n1, n2;
set_current_state(TASK_INTERRUPTIBLE);
@@ -2500,9 +2498,12 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
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;
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
@@ -2539,7 +2540,6 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
nbytes -= n;
buf += n;
- break; /* makes device work like a pipe */
}
remove_wait_queue(&async->wait_head, &wait);
set_current_state(TASK_RUNNING);