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