Skip to contentSkip to conversation

sendfile(2) behaviour has changed ?

DISCUSSION Zilvinas Valinskas 5 participants 7 messages Oct 16, 2002 – Oct 17, 2002

lore
Share & tools
lore
#0 lore raw

This sample code copies a file using sendfile(2) call works just fine on 2.2.x and 2.4.x kernels. On 2.5.x kernels (not sure starting which version) it stopped working. Program terminates with EINVAL error.

$ ./sendfile
sendfile: Invalid argument

Is this expected behaviour ? that sendfile(2) on 2.5.4x linux kernel requires socket as an output fd paramter ?

Was it ever legal to copy file(s) on filesystem using sendfile(2) ? (which was kindda nice feature ... )

#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()

{
	int fd_in  = 0;
	int fd_out = 0;
	struct stat stat_buf;
	off_t  offset = 0;
	ssize_t count = 0;

	if ((fd_in=open("sendfile.c",O_RDONLY))<0)
	{
		perror("open");
		exit(1);
	}
	if ((fd_out=open("sendfile.out",O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU))<0)
	{
		perror("open");
		exit(1);
	}

	if (fstat(fd_in,&stat_buf)) {
		perror("fstat");
	}


	count = sendfile(fd_out,fd_in,&offset,stat_buf.st_size);

	if (count < 0)
		perror("sendfile");
	
	if (close(fd_in) < 0)
		perror("close");
	if (close(fd_out) < 0)
		perror("close");
	return 0;
}
#1 lore raw
Quoted 9 lines · Zilvinas Valinskas

This sample code copies a file using sendfile(2) call works just fine on 2.2.x and 2.4.x kernels. On 2.5.x kernels (not sure starting which version) it stopped working. Program terminates with EINVAL error.

$ ./sendfile
sendfile: Invalid argument

Is this expected behaviour ? that sendfile(2) on 2.5.4x linux kernel requires socket as an output fd paramter ?

It has only been intended for output to a TCP stream socket.

Quoted 2 lines

Was it ever legal to copy file(s) on filesystem using sendfile(2) ? (which was kindda nice feature ... )

No. It was a nice misfeature.

/Matti Aarnio

#2 lore raw

From: Matti Aarnio <[email protected]>
Date: Wed, 16 Oct 2002 12:10:46 +0300

Quoted 2 lines · Zilvinas Valinskas

Is this expected behaviour ? that sendfile(2) on 2.5.4x linux kernel requires socket as an output fd paramter ?

It has only been intended for output to a TCP stream socket.

To be honest, I'm not so sure about this.

For example, I definitely see us supporting this in the opposite direction when commodity 10gbit hits the market.

Initially I thought "sys_receivefile()" but it makes no sense when we have a system call that is perfectly capable of describing the tcp_socket --> page_cache operation.

And I don't think the vfs copy operation using sendfile is such a bad thing either. It definitely opens the door for some interesting optimizations. For example, if the source page is not mapped by a process it could be possible to just unhash it, mark it dirty, then hash it into the destination file. Exactly 2 I/O operations and the cpu doesn't touch the data at all.

#3 lore raw
Quoted 3 lines · David S. Miller

It has only been intended for output to a TCP stream socket.

To be honest, I'm not so sure about this.

The old manpage did not state this properly. In November 2000 I tried to use sendfile as recvfile and discovered that it did not work. The ensuing discussion led to the modification of the manpage to state that it would only write to a socket and only read from a pagecache backed fd.

Regards,

bert hubert

Signature · 3 lines
http://www.PowerDNS.com          Versatile DNS Software & Services
http://www.tk                              the dot in .tk
http://lartc.org           Linux Advanced Routing & Traffic Control HOWTO
#4 lore raw
In reply to David S. Miller
Quoted 9 lines · David S. Miller

From: Matti Aarnio <[email protected]>
Date: Wed, 16 Oct 2002 12:10:46 +0300

Quoted 2 lines · Zilvinas Valinskas

Is this expected behaviour ? that sendfile(2) on 2.5.4x linux kernel requires socket as an output fd paramter ?

It has only been intended for output to a TCP stream socket.

Quoted 8 lines

To be honest, I'm not so sure about this.

For example, I definitely see us supporting this in the opposite direction when commodity 10gbit hits the market.

Initially I thought "sys_receivefile()" but it makes no sense when we have a system call that is perfectly capable of describing the tcp_socket --> page_cache operation.

It really needs a new interface for recvfile/copyfile/whatever
anyway, as you can only specify an off_t for the from fd at present.

Also consider that if you have 2 network sockets you really want a
way to see which did the EAGAIN.

Which leads to something like...

ssize_t copyfddata(int out_fd, off_t *offset,

                   int in_fd,  off_t *offset, size_t count, int *in_errno);

...and another for the off64_t API, the errno thing looks crappy but I think creating EREADAGAIN is even worse (and I just know that won't be the last if it's done that way) ... unless you can think of another way.

Signature · 4 lines
# James Antill -- [email protected]
:0:
* ^From: .*james@and\.org
/dev/null
#5 lore raw

From: James Antill <[email protected]>
Date: 17 Oct 2002 16:51:30 -0400

It really needs a new interface for recvfile/copyfile/whatever
anyway, as you can only specify an off_t for the from fd at present.

Ummm, you can use lseek() on the 'to' fd perhaps?

#6 lore raw
Quoted 7 lines · David S. Miller

From: James Antill <[email protected]>
Date: 17 Oct 2002 16:51:30 -0400

It really needs a new interface for recvfile/copyfile/whatever
anyway, as you can only specify an off_t for the from fd at present.

Ummm, you can use lseek() on the 'to' fd perhaps?

On the client side it's pretty useful to be able to write into the
same file from the network from multiple connections.

You could say that you are much more likely to have multiple
connections reading from one file than have them writing to the same file on the server, but then there the errno problem is much more obvious.

Signature · 4 lines
# James Antill -- [email protected]
:0:
* ^From: .*james@and\.org
/dev/null