mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-30 22:03:17 +01: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 <[email protected]>
This commit is contained in:
1 parent
af73a21a8e
commit
42bc693533
1 file changed
+30
-10
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user