kern/92243: sendfile(2) returns early on files > 4GB
Yar Tikhiy
yar at comp.chem.msu.su
Tue Jan 31 06:10:13 PST 2006
The following reply was made to PR kern/92243; it has been noted by GNATS.
From: Yar Tikhiy <yar at comp.chem.msu.su>
To: bug-followup at FreeBSD.org, dkelly at hiwaay.net
Cc: "David G. Lawrence" <dg at dglawrence.com>, alc at FreeBSD.org, phk at FreeBSD.org
Subject: Re: kern/92243: sendfile(2) returns early on files > 4GB
Date: Tue, 31 Jan 2006 17:05:03 +0300
On Tue, Jan 31, 2006 at 03:49:48PM +0300, Yar Tikhiy wrote:
> Just experimented with the issue. It appears easily reproducable
> on a local filesystem. The problem boils down to the fact that in
> the following code:
>
> sys/kern/uipc_syscalls.c:do_sendfile()
> 1864: /*
> 1865: * Calculate the amount to transfer. Not to exceed a page,
> 1866: * the EOF, or the passed in nbytes.
> 1867: */
> 1868: xfsize = obj->un_pager.vnp.vnp_size - off;
>
> obj->un_pager.vnp.vnp_size is somehow truncated to 32 bits when the
> vnode comes from disk. I added a printf after line 1868 and I saw
> that for a recently created file, 2^32+10000 bytes in size,
> obj->un_pager.vnp.vnp_size was the full size of the file. The
> file's vnode was presumably still cached. However, after a reboot
> obj->un_pager.vnp.vnp_size for the same file was just 10000.
Quite curiously, changing the type of the size argument to
vnode_create_vobject() from size_t to off_t seems to remedy the
problem in my case. Let's ask Poul-Henning, who introduced the
kernel function a year ago, what he thinks about this -- adding him
to CC.
The proposed patch is attached below.
--
Yar
Index: sys/vnode.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/vnode.h,v
retrieving revision 1.312
diff -u -p -r1.312 vnode.h
--- sys/vnode.h 15 Jan 2006 02:01:51 -0000 1.312
+++ sys/vnode.h 31 Jan 2006 13:58:29 -0000
@@ -700,7 +700,7 @@ void vref(struct vnode *vp);
int vrefcnt(struct vnode *vp);
void v_addpollinfo(struct vnode *vp);
-int vnode_create_vobject(struct vnode *vp, size_t size, struct thread *td);
+int vnode_create_vobject(struct vnode *vp, off_t size, struct thread *td);
void vnode_destroy_vobject(struct vnode *vp);
extern struct vop_vector fifo_specops;
Index: vm/vnode_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v
retrieving revision 1.224
diff -u -p -r1.224 vnode_pager.c
--- vm/vnode_pager.c 1 Nov 2005 23:00:24 -0000 1.224
+++ vm/vnode_pager.c 31 Jan 2006 13:58:30 -0000
@@ -97,7 +97,7 @@ int vnode_pbuf_freecnt;
/* Create the VM system backing object for this vnode */
int
-vnode_create_vobject(struct vnode *vp, size_t isize, struct thread *td)
+vnode_create_vobject(struct vnode *vp, off_t isize, struct thread *td)
{
vm_object_t object;
vm_ooffset_t size = isize;
More information about the freebsd-bugs
mailing list