Message ID | 20230216101452.591805-3-nuno.sa@analog.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | output buffer write fops fixes | expand |
On 2/16/23 02:14, Nuno Sá wrote: > For output buffers, there's no guarantee that the buffer won't be full > in the first iteration of the loop in which case we would block > independently of userspace passing O_NONBLOCK or not. Fix it by always > checking the flag before going to sleep. > > While at it (and as it's a bit related), refactored the loop so that the > stop condition is 'written != n', i.e, run the loop until all data has > been copied into the IIO buffers. This makes the code a bit simpler. > > Fixes: 9eeee3b0bf190 ("iio: Add output buffer support") > Signed-off-by: Nuno Sá <nuno.sa@analog.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
On Thu, 16 Feb 2023 06:00:00 -0800 Lars-Peter Clausen <lars@metafoo.de> wrote: > On 2/16/23 02:14, Nuno Sá wrote: > > For output buffers, there's no guarantee that the buffer won't be full > > in the first iteration of the loop in which case we would block > > independently of userspace passing O_NONBLOCK or not. Fix it by always > > checking the flag before going to sleep. > > > > While at it (and as it's a bit related), refactored the loop so that the > > stop condition is 'written != n', i.e, run the loop until all data has > > been copied into the IIO buffers. This makes the code a bit simpler. > > > > Fixes: 9eeee3b0bf190 ("iio: Add output buffer support") > > Signed-off-by: Nuno Sá <nuno.sa@analog.com> > > Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> > Applied to the fixes-togreg branch of iio.git and marked for stable. Thanks, Jonathan
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c56cf748fde1..7e7ee307a3f7 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -203,21 +203,24 @@ static ssize_t iio_buffer_write(struct file *filp, const char __user *buf, break; } + if (filp->f_flags & O_NONBLOCK) { + if (!written) + ret = -EAGAIN; + break; + } + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); continue; } ret = rb->access->write(rb, n - written, buf + written); - if (ret == 0 && (filp->f_flags & O_NONBLOCK)) - ret = -EAGAIN; + if (ret < 0) + break; - if (ret > 0) { - written += ret; - if (written != n && !(filp->f_flags & O_NONBLOCK)) - continue; - } - } while (ret == 0); + written += ret; + + } while (written != n); remove_wait_queue(&rb->pollq, &wait); return ret < 0 ? ret : written;
For output buffers, there's no guarantee that the buffer won't be full in the first iteration of the loop in which case we would block independently of userspace passing O_NONBLOCK or not. Fix it by always checking the flag before going to sleep. While at it (and as it's a bit related), refactored the loop so that the stop condition is 'written != n', i.e, run the loop until all data has been copied into the IIO buffers. This makes the code a bit simpler. Fixes: 9eeee3b0bf190 ("iio: Add output buffer support") Signed-off-by: Nuno Sá <nuno.sa@analog.com> --- drivers/iio/industrialio-buffer.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)