Skip to content

Commit

Permalink
tun: honor IOCB_NOWAIT flag
Browse files Browse the repository at this point in the history
tun only checks the file O_NONBLOCK flag, but it should also be checking
the iocb IOCB_NOWAIT flag. Any fops using ->read/write_iter() should check
both, otherwise it breaks users that correctly expect O_NONBLOCK semantics
if IOCB_NOWAIT is set.

Signed-off-by: Jens Axboe <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
axboe authored and kuba-moo committed Nov 21, 2020
1 parent c5dab09 commit 5aac039
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1961,12 +1961,15 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct tun_file *tfile = file->private_data;
struct tun_struct *tun = tun_get(tfile);
ssize_t result;
int noblock = 0;

if (!tun)
return -EBADFD;

result = tun_get_user(tun, tfile, NULL, from,
file->f_flags & O_NONBLOCK, false);
if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
noblock = 1;

result = tun_get_user(tun, tfile, NULL, from, noblock, false);

tun_put(tun);
return result;
Expand Down Expand Up @@ -2185,10 +2188,15 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct tun_file *tfile = file->private_data;
struct tun_struct *tun = tun_get(tfile);
ssize_t len = iov_iter_count(to), ret;
int noblock = 0;

if (!tun)
return -EBADFD;
ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL);

if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT))
noblock = 1;

ret = tun_do_read(tun, tfile, to, noblock, NULL);
ret = min_t(ssize_t, ret, len);
if (ret > 0)
iocb->ki_pos = ret;
Expand Down

0 comments on commit 5aac039

Please sign in to comment.