From nobody@FreeBSD.org  Tue Jan 24 14:54:33 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id DD7A11065675
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 24 Jan 2012 14:54:33 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id B9CAC8FC13
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 24 Jan 2012 14:54:33 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q0OEsXdn032536
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 24 Jan 2012 14:54:33 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q0OEsXcb032519;
	Tue, 24 Jan 2012 14:54:33 GMT
	(envelope-from nobody)
Message-Id: <201201241454.q0OEsXcb032519@red.freebsd.org>
Date: Tue, 24 Jan 2012 14:54:33 GMT
From: Luis Garcs-Erice <lge@ieee.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: lseek() always returns ENXIO with SEEK_DATA/SEEK_HOLE on 9.0 64bit ZFS
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         164445
>Category:       kern
>Synopsis:       [libc] lseek(2) always returns ENXIO with SEEK_DATA/SEEK_HOLE on 9.0 64bit ZFS
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    avg
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jan 24 15:00:21 UTC 2012
>Closed-Date:    Mon Apr 16 12:10:12 UTC 2012
>Last-Modified:  Mon Apr 16 12:10:12 UTC 2012
>Originator:     Luis Garcs-Erice
>Release:        9.0
>Organization:
>Environment:
FreeBSD XXX 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
Trying to find holes on a sparse file on 9.0-RELEASE x86_64 ZFS, lseek() with whence=SEEK_DATA or SEEK_HOLE always returns ENXIO. In particular, this code:

offset=lseek(fd,0,SEEK_DATA);
if (offset==-1) {
  if (errno==ENXIO) {
     // No more data
     printf("no more data\n");
     close(fd);
     exit(-1);
  }
}

always prints "no more data". Same thing if seeking with SEEK_HOLE.

The expected behavior is for lseek in this case to return 0, because the first block of data starts at 0.
This works fine on 8.2-RELEASE i386 ZFS.
>How-To-Repeat:
This code works as expected (offset equals 0 after the call to lseek()) on 8.2-RELEASE i386, but not on 9.0-RELEASE x86_64

offset=lseek(fd,0,SEEK_DATA);
if (offset==-1) {
  if (errno==ENXIO) {
     // No more data
     printf("no more data\n");
     close(fd);
     exit(-1);
  }
}
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-amd64->freebsd-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Tue Jan 24 17:02:52 UTC 2012 
Responsible-Changed-Why:  
reclassify. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=164445 

From: Andriy Gapon <avg@FreeBSD.org>
To: bug-followup@FreeBSD.org, lge@ieee.org
Cc: Pawel Jakub Dawidek <pjd@FreeBSD.org>
Subject: Re: kern/164445: [libc] lseek(2) always returns ENXIO with SEEK_DATA/SEEK_HOLE
 on 9.0 64bit ZFS
Date: Wed, 07 Mar 2012 22:54:48 +0200

 I think that you hit the nail on the head.
 On FreeBSD the ioctl(2) system call does copyin/copyout of the data argument and
 thus those extra copyin/copuout calls in  zfs_ioctl are harmful.
 
 -- 
 Andriy Gapon

Date: Sun, 11 Mar 2012 19:36:41 -0500
From: Mark Linimon <linimon@lonesome.com>
To: bug-followup@FreeBSD.org
Cc: freebsd-fs@FreeBSD.org
Subject: Re: kern/164445: [zfs][patch] WAS: lseek(2) always returns ENXIO with SEEK_DATA/SEEK_HOLE on 9.0 64bit ZFS

 ----- Forwarded message from Luis Garces-Erice <luis.garces@gmail.com> -----
 
 Date: Wed, 7 Mar 2012 20:53:35 +0100
 From: Luis Garces-Erice <luis.garces@gmail.com>
 To: freebsd-bugs@freebsd.org
 Subject: kern/164445: [zfs][patch] WAS: lseek(2) always returns ENXIO with
 	SEEK_DATA/SEEK_HOLE on 9.0 64bit ZFS
 
 Hi all
 
 after digging a bit more into this
 (http://www.freebsd.org/cgi/query-pr.cgi?pr=164445), I've found the
 problem to be in ZFS or below. The patch attached addresses the
 symptom, but the problem remains.
 
 When invoking SEEK_DATA/SEEK_HOLE on a file on ZFS in FreeBSD 9.0 64
 bit, the functions ddi_copyin and ddi_copyout in zfs_ioctl() do not
 copy the offset passed from the application to the ioctl. The offset
 is passed correctly to zfs_ioctl(), though, but those functions copy
 garbage into the offset used by zfs_holey(). The corrupted offset is
 often bigger than the file, and thus the ioctl returns ENXIO.
 
 The patch does the copy of the offset passed from the application
 correctly, and allows lseek(2) with SEEK_DATA/SEEK_HOLE to be used on
 ZFS, but it is not a solution. I couldn't see a problem in the
 assembler of the copyin and copyout functions in
 sys/amd64/amd64/support.S, but I might be wrong, I'm no assembler
 expert.
 
 
 -- 
 Luis
 ****
 
 diff -w -u -r sys.orig/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
 --- sys.orig/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	2012-01-03 04:27:03.000000000 +0100
 +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	2012-03-06 11:26:27.000000000 +0100
 @@ -296,6 +296,8 @@
  		if (ddi_copyin((void *)data, &off, sizeof (off), flag))
  			return (EFAULT);
  
 +		// ddi_copyin did not copy the offset
 +		off = (offset_t)*((offset_t *)data);
  		zp = VTOZ(vp);
  		zfsvfs = zp->z_zfsvfs;
  		ZFS_ENTER(zfsvfs);
 @@ -308,6 +310,8 @@
  			return (error);
  		if (ddi_copyout(&off, (void *)data, sizeof (off), flag))
  			return (EFAULT);
 +		// ddi_copyout did not copy the offset
 +		*((offset_t *)data)=off;
  		return (0);
  	}
  	return (ENOTTY);
 
 ----- End forwarded message -----
State-Changed-From-To: open->patched 
State-Changed-By: avg 
State-Changed-When: Thu Apr 5 08:00:28 UTC 2012 
State-Changed-Why:  
The patch is committed to head. 


Responsible-Changed-From-To: freebsd-bugs->avg 
Responsible-Changed-By: avg 
Responsible-Changed-When: Thu Apr 5 08:00:28 UTC 2012 
Responsible-Changed-Why:  
I am handling this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=164445 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/164445: commit references a PR
Date: Thu,  5 Apr 2012 08:00:40 +0000 (UTC)

 Author: avg
 Date: Thu Apr  5 07:59:59 2012
 New Revision: 233918
 URL: http://svn.freebsd.org/changeset/base/233918
 
 Log:
   zfs_ioctl: no need for ddi_copyin/out here because sys_ioctl handles that
   
   On FreeBSD the direct ioctl argument is automatically copied in/out
   as necesary by the kernel ioctl entry point.
   
   PR:		kern/164445
   Submitted by:	Luis Garces-Erice <lge@ieee.org>
   Tested by:	Attila Nagy <bra@fsn.hu>
   MFC after:	5 days
 
 Modified:
   head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
 
 Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
 ==============================================================================
 --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Apr  5 04:41:06 2012	(r233917)
 +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Apr  5 07:59:59 2012	(r233918)
 @@ -293,9 +293,12 @@ zfs_ioctl(vnode_t *vp, u_long com, intpt
  
  	case _FIO_SEEK_DATA:
  	case _FIO_SEEK_HOLE:
 +#ifdef sun
  		if (ddi_copyin((void *)data, &off, sizeof (off), flag))
  			return (EFAULT);
 -
 +#else
 +		off = *(offset_t *)data;
 +#endif
  		zp = VTOZ(vp);
  		zfsvfs = zp->z_zfsvfs;
  		ZFS_ENTER(zfsvfs);
 @@ -306,8 +309,12 @@ zfs_ioctl(vnode_t *vp, u_long com, intpt
  		ZFS_EXIT(zfsvfs);
  		if (error)
  			return (error);
 +#ifdef sun
  		if (ddi_copyout(&off, (void *)data, sizeof (off), flag))
  			return (EFAULT);
 +#else
 +		*(offset_t *)data = off;
 +#endif
  		return (0);
  	}
  	return (ENOTTY);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: avg 
State-Changed-When: Mon Apr 16 12:09:42 UTC 2012 
State-Changed-Why:  
The fix is put into all relevant supported branches. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=164445 
>Unformatted:
