Skip to content

Commit

Permalink
net: wwan: core: implement TIOCINQ ioctl
Browse files Browse the repository at this point in the history
It is quite common for a userpace program to fetch the buffered amount
of data in the rx queue to avoid the read block. Implement the TIOCINQ
ioctl to make the migration to the WWAN port usage smooth.

Despite the fact that the read call will return no more data than the
size of a first skb in the queue, TIOCINQ returns the entire amount of
buffered data (sum of all queued skbs). This is done to prevent the
breaking of programs that optimize reading, avoiding it if the buffered
amount of data is too small.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sergey Ryazanov authored and David S. Miller committed Jun 8, 2021
1 parent 72eedfc commit e263c5b
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions drivers/net/wwan/wwan_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/termios.h>
#include <linux/wwan.h>

/* Maximum number of minors in use */
Expand Down Expand Up @@ -618,13 +619,41 @@ static __poll_t wwan_port_fops_poll(struct file *filp, poll_table *wait)
return mask;
}

static long wwan_port_fops_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct wwan_port *port = filp->private_data;

switch (cmd) {
case TIOCINQ: { /* aka SIOCINQ aka FIONREAD */
unsigned long flags;
struct sk_buff *skb;
int amount = 0;

spin_lock_irqsave(&port->rxq.lock, flags);
skb_queue_walk(&port->rxq, skb)
amount += skb->len;
spin_unlock_irqrestore(&port->rxq.lock, flags);

return put_user(amount, (int __user *)arg);
}

default:
return -ENOIOCTLCMD;
}
}

static const struct file_operations wwan_port_fops = {
.owner = THIS_MODULE,
.open = wwan_port_fops_open,
.release = wwan_port_fops_release,
.read = wwan_port_fops_read,
.write = wwan_port_fops_write,
.poll = wwan_port_fops_poll,
.unlocked_ioctl = wwan_port_fops_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_ptr_ioctl,
#endif
.llseek = noop_llseek,
};

Expand Down

0 comments on commit e263c5b

Please sign in to comment.