Date: Sun, 6 May 2007 12:05:27 -0500 From: "Scot Hetzel" <swhetzel@gmail.com> To: emulation@freebsd.org Subject: Re: linuxolator: LTP lseek03 failure Message-ID: <790a9fff0705061005v1a1a883ehc155bac7f747c3eb@mail.gmail.com> In-Reply-To: <790a9fff0705040819u24e4c2f0s5c9fc34b93770e13@mail.gmail.com> References: <790a9fff0705021345j2ad9ae98o56aaf357d556fe27@mail.gmail.com> <790a9fff0705040004oab16ed8q1a1c476386379ea9@mail.gmail.com> <20070504190007.Y37951@besplex.bde.org> <790a9fff0705040819u24e4c2f0s5c9fc34b93770e13@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On 5/4/07, Scot Hetzel <swhetzel@gmail.com> wrote:
> > The main bug is in the implementation of SEEK_HOLE and SEEK_DATA. This
> > uses fo_ioctl() and fo_ioctl() returns ENOTTY if the file system doesn't
> > support these seeks, but ENOTTY (Inappropriate ioctl for device) is a
> > very inappropriate errno for a syscall that is not ioctl(), especially
> > on a file that is not a device. POSIX requires EINVAL if the `whence'
> > arg is not a standard POSIX one, and I think ENOTTY should be translated
> > to this.
> >
>
> I see three places where this could be fixed:
>
> kern/vfs_vnops.c:vn_ioctl(...)
> kern/vfs_syscalls.c:lseek(...)
> compat/linux/linux_file.c:(linux_lseek and linux_llseek)
>
> Would the best fix be to change the native lseek to return EINVAL when
> fo_ioctl returns ENOTTY?
>
I had a look at the OpenSolaris implementation of lseek and found that
we are returning the wrong error code for the ENOTTY case. When
ENOTTY is returned by fo_ioctl, we should be checking for the
following cases:
SEEK_DATA - Is offset past end of file
SEEK_HOLE - Return virtual hole at end of file, if offset is valid
on error, SEEK_DATA and SEEK_HOLE should be returning ENXIO for these
cases. OpenSolaris also checks offset > OFF_MAX, and returns
EOVERFLOW.
When the lseek03 test is run, with these changes, it returns with ENXIO.
I sent the attached patch for kern/vfs_syscalls.c to pjd for review.
Scot
--
DISCLAIMER:
No electrons were mamed while sending this message. Only slightly bruised.
[-- Attachment #2 --]
Index: vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.438
diff -u -r1.438 vfs_syscalls.c
--- vfs_syscalls.c 4 May 2007 14:23:28 -0000 1.438
+++ vfs_syscalls.c 6 May 2007 15:37:39 -0000
@@ -1755,9 +1755,36 @@
break;
case SEEK_DATA:
error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td);
+ if (error == ENOTTY) {
+ /*
+ * The ioctl is not supported. Is the offset
+ * past the end of the file.
+ */
+ error = VOP_GETATTR(vp, &vattr, fp->f_cred, td);
+ if (error == 0 &&
+ (offset >= (uoff_t)vattr.va_size))
+ error = ENXIO;
+ }
+ if (noneg && (offset > OFF_MAX))
+ error = EOVERFLOW;
break;
case SEEK_HOLE:
error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td);
+ if (error == ENOTTY) {
+ /*
+ * The ioctl is not supported. Return virtual
+ * hole at end of file, if offset is valid.
+ */
+ error = VOP_GETATTR(vp, &vattr, fp->f_cred, td);
+ if (error == 0) {
+ if (uap->offset < (off_t)vattr.va_size)
+ offset = (uoff_t)vattr.va_size;
+ else
+ error = ENXIO;
+ }
+ }
+ if (noneg && (offset > OFF_MAX))
+ error = EOVERFLOW;
break;
default:
error = EINVAL;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?790a9fff0705061005v1a1a883ehc155bac7f747c3eb>
