[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080916042442.GC23389@verge.net.au>
Date: Tue, 16 Sep 2008 14:24:43 +1000
From: Simon Horman <horms@...ge.net.au>
To: Johann Baudy <johaahn@...il.com>
Cc: netdev@...r.kernel.org, David Miller <davem@...emloft.net>
Subject: Re: [PATCH] sendfile() and UDP socket
On Tue, Sep 16, 2008 at 02:17:05PM +1000, Simon Horman wrote:
> On Sun, Sep 14, 2008 at 12:25:56PM +0200, Johann Baudy wrote:
> > Hi All,
> >
> > Sendfile() over UDP socket are currently limited to ~ 64KBytes file (max cork.length).
> > Indeed, if you run sendfile() with a file size > 64KBytes over UDP socket, system call will stop and return ~64KBytes without sending anything on the network.
> > This patch is pushing ongoing frames when frames buffer is full, to prevent overflow.
> >
> > Signed-off-by: Johann Baudy <johann.baudy@...il.com>
> >
> > net/ipv4/udp.c | 15 +++++++++++++++
> > 1 files changed, 15 insertions(+), 0 deletions(-)
> >
> > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> > index 8e42fbb..64e0857 100644
> > --- a/net/ipv4/udp.c
> > +++ b/net/ipv4/udp.c
> > @@ -743,7 +743,22 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
> > size_t size, int flags)
> > {
> > struct udp_sock *up = udp_sk(sk);
> > + struct inet_sock *inet = inet_sk(sk);
> > int ret;
> > + int fragheaderlen;
> > + struct ip_options *opt = NULL;
> > +
> > + lock_sock(sk);
> > + if (inet->cork.flags & IPCORK_OPT)
> > + opt = inet->cork.opt;
> > + fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
> > +
> > + if (inet->cork.length + size >= 0xFFFF - fragheaderlen) {
> > + ret = udp_push_pending_frames(sk);
> > + if (ret)
> > + goto out;
> > + }
> > + release_sock(sk);
> >
> > if (!up->pending) {
> > struct msghdr msg = { .msg_flags = flags|MSG_MORE };
>
> Hi,
>
> I wonder if it is slightly nicer to do without the opt variable.
> I _think_ its safe to access inet->cork.opt->optlen based
> on the (inet->cork.flags & IPCORK_OPT) check.
>
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index 8e42fbb..969f6cd 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -743,7 +743,21 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
> size_t size, int flags)
> {
> struct udp_sock *up = udp_sk(sk);
> + struct inet_sock *inet = inet_sk(sk);
> int ret;
> + int fragheaderlen;
Also, I wonder if this should be an unsigned int
as both sizeof(struct iphdr) and inet->cork.opt->optlen are unsigned,
though of different width.
> +
> + fragheaderlen = sizeof(struct iphdr);
> + lock_sock(sk);
> + if (inet->cork.flags & IPCORK_OPT)
> + fragheaderlen += inet->cork.opt->optlen;
> +
> + if (inet->cork.length + size >= 0xFFFF - fragheaderlen) {
> + ret = udp_push_pending_frames(sk);
> + if (ret)
> + goto out;
> + }
> + release_sock(sk);
>
> if (!up->pending) {
> struct msghdr msg = { .msg_flags = flags|MSG_MORE };
--
Simon Horman
VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
H: www.vergenet.net/~horms/ W: www.valinux.co.jp/en
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists