summaryrefslogtreecommitdiff
path: root/drivers/net/tap.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2023-03-07 21:18:21 -0700
committerJakub Kicinski <kuba@kernel.org>2023-03-10 16:48:32 -0800
commitf758bfec377ad2f15d7683473b1db1cfbf8e1bb0 (patch)
tree2b4b43a5327e1805e96ac7d8b7f187ec208f1034 /drivers/net/tap.c
parent438b406055cd21105aad77db7938ee4720b09bee (diff)
tap: add support for IOCB_NOWAIT
The tap driver already supports passing in nonblocking state based on O_NONBLOCK, add support for checking IOCB_NOWAIT as well. With that done, we can flag it with FMODE_NOWAIT as well. Signed-off-by: Jens Axboe <axboe@kernel.dk> Link: https://lore.kernel.org/r/8f859870-e6e2-09ca-9c0f-a2aa7c984fb2@kernel.dk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/tap.c')
-rw-r--r--drivers/net/tap.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 8941aa199ea3..ce993cc75bf3 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -555,6 +555,9 @@ static int tap_open(struct inode *inode, struct file *file)
goto err_put;
}
+ /* tap groks IOCB_NOWAIT just fine, mark it as such */
+ file->f_mode |= FMODE_NOWAIT;
+
dev_put(tap->dev);
rtnl_unlock();
@@ -771,8 +774,12 @@ static ssize_t tap_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct file *file = iocb->ki_filp;
struct tap_queue *q = file->private_data;
+ int noblock = 0;
+
+ if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
+ noblock = 1;
- return tap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK);
+ return tap_get_user(q, NULL, from, noblock);
}
/* Put packet to the user space buffer */
@@ -888,8 +895,12 @@ static ssize_t tap_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct file *file = iocb->ki_filp;
struct tap_queue *q = file->private_data;
ssize_t len = iov_iter_count(to), ret;
+ int noblock = 0;
+
+ if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
+ noblock = 1;
- ret = tap_do_read(q, to, file->f_flags & O_NONBLOCK, NULL);
+ ret = tap_do_read(q, to, noblock, NULL);
ret = min_t(ssize_t, ret, len);
if (ret > 0)
iocb->ki_pos = ret;