mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
thunderbolt: stream: Support IOCB_NOWAIT in non-blocking I/O as well
For read_iter/write_iter() it is also possible to pass IOCB_NOWAIT with the kiocb to indicate non-blocking read/write. For instance io_uring does this. So take this into account on read and write paths. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
af73a21a8e
commit
42bc693533
|
|
@ -633,10 +633,23 @@ static void tbstream_dev_stop(struct tbstream_dev *sdev)
|
|||
sdev->tx_ring.ring = NULL;
|
||||
}
|
||||
|
||||
static int tbstream_dev_lock(struct tbstream_dev *sdev, bool nowait)
|
||||
{
|
||||
if (nowait) {
|
||||
if (!mutex_trylock(&sdev->lock))
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
if (mutex_lock_interruptible(&sdev->lock))
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tbstream_dev_fops_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
||||
{
|
||||
struct file *file = kiocb->ki_filp;
|
||||
bool nowait = file->f_flags & O_NONBLOCK || kiocb->ki_flags & IOCB_NOWAIT;
|
||||
struct tbstream_dev *sdev = to_tbstream_dev(file->private_data);
|
||||
size_t nbytes;
|
||||
int ret;
|
||||
|
|
@ -645,14 +658,16 @@ tbstream_dev_fops_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mutex_lock_interruptible(&sdev->lock))
|
||||
return -ERESTARTSYS;
|
||||
ret = tbstream_dev_lock(sdev, nowait);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (!tbstream_ring_available(&sdev->rx_ring)) {
|
||||
mutex_unlock(&sdev->lock);
|
||||
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
if (nowait)
|
||||
return -EAGAIN;
|
||||
|
||||
ret = wait_event_interruptible(sdev->wait,
|
||||
tbstream_ring_available(&sdev->rx_ring) ||
|
||||
tbstream_dev_valid(sdev) != 0 ||
|
||||
|
|
@ -668,8 +683,9 @@ tbstream_dev_fops_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
|||
if (tbstream_dev_closed(sdev) || tbstream_dev_removed(sdev))
|
||||
return 0;
|
||||
|
||||
if (mutex_lock_interruptible(&sdev->lock))
|
||||
return -ERESTARTSYS;
|
||||
ret = tbstream_dev_lock(sdev, nowait);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
nbytes = 0;
|
||||
|
|
@ -729,6 +745,7 @@ static ssize_t
|
|||
tbstream_dev_fops_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
||||
{
|
||||
struct file *file = kiocb->ki_filp;
|
||||
bool nowait = file->f_flags & O_NONBLOCK || kiocb->ki_flags & IOCB_NOWAIT;
|
||||
struct tbstream_dev *sdev = to_tbstream_dev(file->private_data);
|
||||
size_t nbytes;
|
||||
int ret;
|
||||
|
|
@ -737,14 +754,16 @@ tbstream_dev_fops_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mutex_lock_interruptible(&sdev->lock))
|
||||
return -ERESTARTSYS;
|
||||
ret = tbstream_dev_lock(sdev, nowait);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (!tbstream_ring_available(&sdev->tx_ring)) {
|
||||
mutex_unlock(&sdev->lock);
|
||||
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
if (nowait)
|
||||
return -EAGAIN;
|
||||
|
||||
ret = wait_event_interruptible(sdev->wait,
|
||||
tbstream_ring_available(&sdev->tx_ring) ||
|
||||
tbstream_dev_valid(sdev) != 0 ||
|
||||
|
|
@ -760,8 +779,9 @@ tbstream_dev_fops_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
|||
if (tbstream_dev_closed(sdev) || tbstream_dev_removed(sdev))
|
||||
return -ENXIO;
|
||||
|
||||
if (mutex_lock_interruptible(&sdev->lock))
|
||||
return -ERESTARTSYS;
|
||||
ret = tbstream_dev_lock(sdev, nowait);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
nbytes = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user