* Re: sendfile -EOVERFLOW on AMD64 [not found] <1XuW9-3G0-23@gated-at.bofh.it> @ 2004-05-19 9:29 ` Andi Kleen 2004-05-19 10:38 ` Jan Kasprzak 0 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-05-19 9:29 UTC (permalink / raw) To: Jan Kasprzak; +Cc: linux-kernel Jan Kasprzak <kas@informatics.muni.cz> writes: > > The image (FC2-i386-DVD.iso) has 4370640896 bytes. The FTP server is native > x86_64 binary, not a 32-bit one. sys_sendfile limits itself dumbly to 2GB even on 64bit architectures. This patch should fix it on x86-64, although other 64bit ports may need a similar patch. Just removing the limit in read_write is not easy, because it would need fixes in all the 32bit emulation layers. -Andi diff -u linux-2.6.6-amd64/include/asm-x86_64/unistd.h-o linux-2.6.6-amd64/include/asm-x86_64/unistd.h --- linux-2.6.6-amd64/include/asm-x86_64/unistd.h-o 2004-05-09 14:30:09.000000000 +0200 +++ linux-2.6.6-amd64/include/asm-x86_64/unistd.h 2004-05-19 11:27:00.000000000 +0200 @@ -98,7 +98,7 @@ __SYSCALL(__NR_getpid, sys_getpid) #define __NR_sendfile 40 -__SYSCALL(__NR_sendfile, sys_sendfile) +__SYSCALL(__NR_sendfile, sys_sendfile64) #define __NR_socket 41 __SYSCALL(__NR_socket, sys_socket) #define __NR_connect 42 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 9:29 ` sendfile -EOVERFLOW on AMD64 Andi Kleen @ 2004-05-19 10:38 ` Jan Kasprzak 2004-05-19 10:58 ` Jakub Jelinek 0 siblings, 1 reply; 11+ messages in thread From: Jan Kasprzak @ 2004-05-19 10:38 UTC (permalink / raw) To: Andi Kleen; +Cc: linux-kernel Andi Kleen wrote: : Jan Kasprzak <kas@informatics.muni.cz> writes: : > : > The image (FC2-i386-DVD.iso) has 4370640896 bytes. The FTP server is native : > x86_64 binary, not a 32-bit one. : : sys_sendfile limits itself dumbly to 2GB even on 64bit architectures. : This patch should fix it on x86-64, although other 64bit ports may : need a similar patch. Just removing the limit in read_write : is not easy, because it would need fixes in all the 32bit emulation : layers. : It partly helped, thanks. But there is still one more problem - it looks like sendfile() returns 32-bit value instead of 64-bit. My debug info looks like this: sendfile(offset=0, count=4370640896) = -767073160, offset=3527894136 where I do long val = sendfile(...); printf(...%ld..., val); -Yenya -- | Jan "Yenya" Kasprzak <kas at {fi.muni.cz - work | yenya.net - private}> | | GPG: ID 1024/D3498839 Fingerprint 0D99A7FB206605D7 8B35FCDE05B18A5E | | http://www.fi.muni.cz/~kas/ Czech Linux Homepage: http://www.linux.cz/ | Any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel. --Linus Torvalds ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 10:38 ` Jan Kasprzak @ 2004-05-19 10:58 ` Jakub Jelinek 2004-05-19 11:01 ` Jan Kasprzak ` (3 more replies) 0 siblings, 4 replies; 11+ messages in thread From: Jakub Jelinek @ 2004-05-19 10:58 UTC (permalink / raw) To: Jan Kasprzak; +Cc: Andi Kleen, linux-kernel On Wed, May 19, 2004 at 12:38:56PM +0200, Jan Kasprzak wrote: > Andi Kleen wrote: > : Jan Kasprzak <kas@informatics.muni.cz> writes: > : > > : > The image (FC2-i386-DVD.iso) has 4370640896 bytes. The FTP server is native > : > x86_64 binary, not a 32-bit one. > : > : sys_sendfile limits itself dumbly to 2GB even on 64bit architectures. > : This patch should fix it on x86-64, although other 64bit ports may > : need a similar patch. Just removing the limit in read_write > : is not easy, because it would need fixes in all the 32bit emulation > : layers. > : > It partly helped, thanks. But there is still one more problem > - it looks like sendfile() returns 32-bit value instead of 64-bit. > My debug info looks like this: > > sendfile(offset=0, count=4370640896) > = -767073160, offset=3527894136 > > where I do > > long val = sendfile(...); printf(...%ld..., val); What filesystem you're using? For XFS I'd expect this: STATIC ssize_t linvfs_sendfile( struct file *filp, loff_t *ppos, size_t count, read_actor_t actor, void *target) { vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode); int error; VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, error); return error; } (note error is int, not ssize_t), but I don't see anything obvious for other filesystems. Jakub ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 10:58 ` Jakub Jelinek @ 2004-05-19 11:01 ` Jan Kasprzak 2004-05-19 11:22 ` Nathan Scott 2004-05-19 11:13 ` Nathan Scott ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Jan Kasprzak @ 2004-05-19 11:01 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Andi Kleen, linux-kernel Jakub Jelinek wrote: : For XFS I'd expect this: : STATIC ssize_t : linvfs_sendfile( : struct file *filp, : loff_t *ppos, : size_t count, : read_actor_t actor, : void *target) : { : vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode); : int error; : : VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, error); : return error; : } : : (note error is int, not ssize_t), but I don't see anything obvious : for other filesystems. : Yes, XFS. I will look at it in the evening. Thanks, -Yenya -- | Jan "Yenya" Kasprzak <kas at {fi.muni.cz - work | yenya.net - private}> | | GPG: ID 1024/D3498839 Fingerprint 0D99A7FB206605D7 8B35FCDE05B18A5E | | http://www.fi.muni.cz/~kas/ Czech Linux Homepage: http://www.linux.cz/ | Any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel. --Linus Torvalds ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 11:01 ` Jan Kasprzak @ 2004-05-19 11:22 ` Nathan Scott 0 siblings, 0 replies; 11+ messages in thread From: Nathan Scott @ 2004-05-19 11:22 UTC (permalink / raw) To: Jan Kasprzak; +Cc: Jakub Jelinek, Andi Kleen, linux-kernel On Wed, May 19, 2004 at 01:01:05PM +0200, Jan Kasprzak wrote: > ... > Yes, XFS. I will look at it in the evening. > > Thanks, The only spot needing fixing is that one pointed out above; from a quick look ssize_t seems to be used correctly in the rest of the XFS sendfile code. cheers. -- Nathan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 10:58 ` Jakub Jelinek 2004-05-19 11:01 ` Jan Kasprzak @ 2004-05-19 11:13 ` Nathan Scott 2004-05-19 12:44 ` Andi Kleen 2004-05-19 19:48 ` Jan Kasprzak 3 siblings, 0 replies; 11+ messages in thread From: Nathan Scott @ 2004-05-19 11:13 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jan Kasprzak, Andi Kleen, linux-kernel On Wed, May 19, 2004 at 06:58:06AM -0400, Jakub Jelinek wrote: > ... > (note error is int, not ssize_t), but I don't see anything obvious > for other filesystems. Thanks, I'll fix that up. cheers. -- Nathan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 10:58 ` Jakub Jelinek 2004-05-19 11:01 ` Jan Kasprzak 2004-05-19 11:13 ` Nathan Scott @ 2004-05-19 12:44 ` Andi Kleen 2004-05-19 12:50 ` Jakub Jelinek 2004-05-19 19:48 ` Jan Kasprzak 3 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-05-19 12:44 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jan Kasprzak, Andi Kleen, linux-kernel, akpm > (note error is int, not ssize_t), but I don't see anything obvious > for other filesystems. sendfile64 on 32bit hosts seems to be quite fishy too. It works with ssize_t, which is 32bit only, but there are no checks that the transfered file is not >4GB. It would just wrap in this case. It would be better to add such checks for 32bit hosts to sendfile64. Or am I missing something? -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 12:44 ` Andi Kleen @ 2004-05-19 12:50 ` Jakub Jelinek 2004-05-19 12:57 ` Andi Kleen 0 siblings, 1 reply; 11+ messages in thread From: Jakub Jelinek @ 2004-05-19 12:50 UTC (permalink / raw) To: Andi Kleen; +Cc: Jan Kasprzak, linux-kernel, akpm On Wed, May 19, 2004 at 02:44:27PM +0200, Andi Kleen wrote: > > (note error is int, not ssize_t), but I don't see anything obvious > > for other filesystems. > > sendfile64 on 32bit hosts seems to be quite fishy too. > > It works with ssize_t, which is 32bit only, but there are no checks > that the transfered file is not >4GB. It would just wrap in this case. > It would be better to add such checks for 32bit hosts to sendfile64. > > Or am I missing something? The userland prototypes are: extern ssize_t sendfile (int __out_fd, int __in_fd, off_t *__offset, size_t __count) __THROW; extern ssize_t sendfile64 (int __out_fd, int __in_fd, __off64_t *__offset, size_t __count) __THROW; Thus you really cannot transfer more than 4G-1 bytes in one call on 32-bit arches. Actually, already any counts >= 2GB-1 might be problematic, but we are there on the same boat as with e.g. read(2). For read, POSIX says: "If the value of nbyte is greater than {SSIZE_MAX}, the result is implementation-defined." so portable programs really shouldn't try to transfer more than that in one go but the kernel certainly should try to handle sizes up to SIZE_MAX-4096 or something like that. Jakub ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 12:50 ` Jakub Jelinek @ 2004-05-19 12:57 ` Andi Kleen 0 siblings, 0 replies; 11+ messages in thread From: Andi Kleen @ 2004-05-19 12:57 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Andi Kleen, Jan Kasprzak, linux-kernel, akpm > The userland prototypes are: > extern ssize_t sendfile (int __out_fd, int __in_fd, off_t *__offset, > size_t __count) __THROW; > extern ssize_t sendfile64 (int __out_fd, int __in_fd, __off64_t *__offset, > size_t __count) __THROW; > Thus you really cannot transfer more than 4G-1 bytes in one call on 32-bit > arches. True. > Actually, already any counts >= 2GB-1 might be problematic, but we are > there on the same boat as with e.g. read(2). For read, POSIX says: > "If the value of nbyte is greater than {SSIZE_MAX}, the result is > implementation-defined." > so portable programs really shouldn't try to transfer more than that > in one go but the kernel certainly should try to handle sizes up to > SIZE_MAX-4096 or something like that. Hmm, ssize_t is signed. If there are any if (ret < 0) checks in the kernel it will fail too. So the real limit would be 0x7fffffff Perhaps that should be enforced like this? diff -u linux/fs/read_write.c-o linux/fs/read_write.c --- linux/fs/read_write.c-o 2004-05-18 10:55:54.000000000 +0200 +++ linux/fs/read_write.c 2004-05-19 14:57:06.000000000 +0200 @@ -700,6 +700,9 @@ off_t off; ssize_t ret; + if (sizeof(size_t) == 4 && (int)count < 0) + return -EOVERFLOW; + if (offset) { if (unlikely(get_user(off, offset))) return -EFAULT; @@ -718,6 +721,9 @@ loff_t pos; ssize_t ret; + if (sizeof(size_t) == 4 && (int)count < 0) + return -EOVERFLOW; + if (offset) { if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) return -EFAULT; -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sendfile -EOVERFLOW on AMD64 2004-05-19 10:58 ` Jakub Jelinek ` (2 preceding siblings ...) 2004-05-19 12:44 ` Andi Kleen @ 2004-05-19 19:48 ` Jan Kasprzak 3 siblings, 0 replies; 11+ messages in thread From: Jan Kasprzak @ 2004-05-19 19:48 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Andi Kleen, linux-kernel Jakub Jelinek wrote: : int error; : : VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, error); : return error; : } : : (note error is int, not ssize_t), but I don't see anything obvious : for other filesystems. : Yes, this fixed the problem - now I can sendfile() the whole DVD image without problem. Thanks, and send both these fixes to Linus. -Yenya -- | Jan "Yenya" Kasprzak <kas at {fi.muni.cz - work | yenya.net - private}> | | GPG: ID 1024/D3498839 Fingerprint 0D99A7FB206605D7 8B35FCDE05B18A5E | | http://www.fi.muni.cz/~kas/ Czech Linux Homepage: http://www.linux.cz/ | Any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel. --Linus Torvalds ^ permalink raw reply [flat|nested] 11+ messages in thread
* sendfile -EOVERFLOW on AMD64
@ 2004-05-19 8:44 Jan Kasprzak
0 siblings, 0 replies; 11+ messages in thread
From: Jan Kasprzak @ 2004-05-19 8:44 UTC (permalink / raw)
To: linux-kernel
Hello,
today (after the Fedora Core 2 release) I have discovered that my FTP
server (running AMD64) cannot correctly send the >2GB files using sendfile().
The server is ProFTPd, and the strace looks like this:
[...]
alarm(288) = 0
sendfile(14, 11, [139377240], 4231263656) = 2008106407
alarm(0) = 117
alarm(117) = 0
alarm(0) = 117
alarm(117) = 0
sendfile(14, 11, [2147483647], 2223157249) = -1 EOVERFLOW (Value too large for defined data type)
The image (FC2-i386-DVD.iso) has 4370640896 bytes. The FTP server is native
x86_64 binary, not a 32-bit one.
Thanks for any hints.
-Yenya
--
| Jan "Yenya" Kasprzak <kas at {fi.muni.cz - work | yenya.net - private}> |
| GPG: ID 1024/D3498839 Fingerprint 0D99A7FB206605D7 8B35FCDE05B18A5E |
| http://www.fi.muni.cz/~kas/ Czech Linux Homepage: http://www.linux.cz/ |
Any compiler or language that likes to hide things like memory allocations
behind your back just isn't a good choice for a kernel. --Linus Torvalds
^ permalink raw reply [flat|nested] 11+ messages in threadend of thread, other threads:[~2004-05-19 19:48 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1XuW9-3G0-23@gated-at.bofh.it>
2004-05-19 9:29 ` sendfile -EOVERFLOW on AMD64 Andi Kleen
2004-05-19 10:38 ` Jan Kasprzak
2004-05-19 10:58 ` Jakub Jelinek
2004-05-19 11:01 ` Jan Kasprzak
2004-05-19 11:22 ` Nathan Scott
2004-05-19 11:13 ` Nathan Scott
2004-05-19 12:44 ` Andi Kleen
2004-05-19 12:50 ` Jakub Jelinek
2004-05-19 12:57 ` Andi Kleen
2004-05-19 19:48 ` Jan Kasprzak
2004-05-19 8:44 Jan Kasprzak
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.