linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tmpfs: let lseek return ENXIO with a negative offset
@ 2018-10-25  2:22 Yufen Yu
  2018-11-01  7:13 ` William Kucharski
  2018-11-07 23:19 ` Andrew Morton
  0 siblings, 2 replies; 6+ messages in thread
From: Yufen Yu @ 2018-10-25  2:22 UTC (permalink / raw)
  To: viro, hughd; +Cc: linux-mm, linux-fsdevel, linux-unionfs

For now, the others filesystems, such as ext4, f2fs, ubifs,
all of them return ENXIO when lseek with a negative offset.
It is better to let tmpfs return ENXIO too. After that, tmpfs
can also pass generic/448.

Signed-off-by: Yufen Yu <yuyufen@huawei.com>
---
 mm/shmem.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 0376c124..f37bf06 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2608,9 +2608,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
 	inode_lock(inode);
 	/* We're holding i_mutex so we can access i_size directly */
 
-	if (offset < 0)
-		offset = -EINVAL;
-	else if (offset >= inode->i_size)
+	if (offset < 0 || offset >= inode->i_size)
 		offset = -ENXIO;
 	else {
 		start = offset >> PAGE_SHIFT;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] tmpfs: let lseek return ENXIO with a negative offset
  2018-10-25  2:22 [PATCH] tmpfs: let lseek return ENXIO with a negative offset Yufen Yu
@ 2018-11-01  7:13 ` William Kucharski
  2018-11-07 23:19 ` Andrew Morton
  1 sibling, 0 replies; 6+ messages in thread
From: William Kucharski @ 2018-11-01  7:13 UTC (permalink / raw)
  To: Yufen Yu; +Cc: viro, hughd, linux-mm, linux-fsdevel, linux-unionfs



> On Oct 24, 2018, at 8:22 PM, Yufen Yu <yuyufen@huawei.com> wrote:
> 
> For now, the others filesystems, such as ext4, f2fs, ubifs,
> all of them return ENXIO when lseek with a negative offset.
> It is better to let tmpfs return ENXIO too. After that, tmpfs
> can also pass generic/448.
> 
> Signed-off-by: Yufen Yu <yuyufen@huawei.com>
> ---
> mm/shmem.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 0376c124..f37bf06 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -2608,9 +2608,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
> 	inode_lock(inode);
> 	/* We're holding i_mutex so we can access i_size directly */
> 
> -	if (offset < 0)
> -		offset = -EINVAL;
> -	else if (offset >= inode->i_size)
> +	if (offset < 0 || offset >= inode->i_size)
> 		offset = -ENXIO;
> 	else {
> 		start = offset >> PAGE_SHIFT;
> --

It's not at all clear what the proper thing to do is if a negative offset is passed.

The man page for lseek(2) states:

       SEEK_DATA
              Adjust the file offset to the next location in the file
              greater than or equal to offset containing data.  If offset
              points to data, then the file offset is set to offset.
       
       SEEK_HOLE
              Adjust the file offset to the next hole in the file greater
              than or equal to offset.  If offset points into the middle of
              a hole, then the file offset is set to offset.  If there is no
              hole past offset, then the file offset is adjusted to the end
              of the file (i.e., there is an implicit hole at the end of any
              file).

This seems to indicate that if passed a negative offset, a whence of either SEEK_DATA
or SEEK_HOLE should operate the same as if passed an offset of 0.

ENXIO just seems to be the wrong error code to return for a passed negative offset in
these cases (also from lseek(2)):

       ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is
              beyond the end of the file.

but EINVAL isn't technically appropriate either:

       EINVAL whence is not valid.  Or: the resulting file offset would be
              negative, or beyond the end of a seekable device.

At the very least it seems the man page should be updated to reflect that ENXIO may be
returned if whence is SEEK_DATA or SEEK_HOLE and the passed offset is negative.

    William Kucharski

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tmpfs: let lseek return ENXIO with a negative offset
  2018-10-25  2:22 [PATCH] tmpfs: let lseek return ENXIO with a negative offset Yufen Yu
  2018-11-01  7:13 ` William Kucharski
@ 2018-11-07 23:19 ` Andrew Morton
  2018-11-08 10:46   ` William Kucharski
  1 sibling, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2018-11-07 23:19 UTC (permalink / raw)
  To: Yufen Yu; +Cc: viro, hughd, linux-mm, linux-fsdevel, linux-unionfs

On Thu, 25 Oct 2018 10:22:56 +0800 Yufen Yu <yuyufen@huawei.com> wrote:

> For now, the others filesystems, such as ext4, f2fs, ubifs,
> all of them return ENXIO when lseek with a negative offset.

When using SEEK_DATA and/or SEEK_HOLE, yes?

> It is better to let tmpfs return ENXIO too. After that, tmpfs
> can also pass generic/448.

generic/448 is, I assume, part of xfstests?

So I'll rewrite the changelog as follows.  Please review carefully.



Subject: tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset

Other filesystems such as ext4, f2fs and ubifs all return ENXIO when
lseek (SEEK_DATA or SEEK_HOLE) requests a negative offset.

man 2 lseek says

:      EINVAL whence  is  not  valid.   Or: the resulting file offset would be
:             negative, or beyond the end of a seekable device.
:
:      ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is  beyond
:             the end of the file.


Make tmpfs return ENXIO under these circumstances as well.  After this,
tmpfs also passes xfstests's generic/448.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tmpfs: let lseek return ENXIO with a negative offset
  2018-11-07 23:19 ` Andrew Morton
@ 2018-11-08 10:46   ` William Kucharski
  2018-11-08 23:07     ` Andrew Morton
  0 siblings, 1 reply; 6+ messages in thread
From: William Kucharski @ 2018-11-08 10:46 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Yufen Yu, viro, hughd, linux-mm, linux-fsdevel, linux-unionfs



> On Nov 7, 2018, at 4:19 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> 
> man 2 lseek says
> 
> :      EINVAL whence  is  not  valid.   Or: the resulting file offset would be
> :             negative, or beyond the end of a seekable device.
> :
> :      ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is  beyond
> :             the end of the file.
> 
> 
> Make tmpfs return ENXIO under these circumstances as well.  After this,
> tmpfs also passes xfstests's generic/448.

As I objected to last week, despite the fact that other file systems do this, is
this in fact the desired behavior?

I'll let you reread that message rather than repeat it in its entirety here, but
certainly a negative offset is not "beyond the end of the file," and the end
result is errno is set to ENXIO for a reason that does not match what the
lseek(2) man page describes.

I also mentioned if a negative offset is used with SEEK_CUR or SEEK_WHENCE,
arguably the negative offset should actually be treated as "0" given lseek(2)
also states:

      SEEK_DATA
             Adjust the file offset to the next location in the file
             greater than or equal to offset containing data.  If offset
             points to data, then the file offset is set to offset.

      SEEK_HOLE
             Adjust the file offset to the next hole in the file greater
             than or equal to offset.  If offset points into the middle of
             a hole, then the file offset is set to offset.  If there is no
             hole past offset, then the file offset is adjusted to the end
             of the file (i.e., there is an implicit hole at the end of any
             file).

Since the "next location" or "next hole" will never be at a negative offset, the
"greater than" clause of both descriptions would mean the resulting offset should
be treated as if it were passed as zero.

However, if xfstest-compliant behavior is desired, the lseek(2) man page
description for ENXIO should be updated to something like:

       ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is negative or
              beyond the end of the file.

I don't mean to be pedantic, but I also know how frustrating it can be when a system
call returns with errno set for a reason that doesn't correspond to the man page.

    Thanks,
         William Kucharski

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tmpfs: let lseek return ENXIO with a negative offset
  2018-11-08 10:46   ` William Kucharski
@ 2018-11-08 23:07     ` Andrew Morton
  2018-11-09  3:52       ` William Kucharski
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2018-11-08 23:07 UTC (permalink / raw)
  To: William Kucharski
  Cc: Yufen Yu, viro, hughd, linux-mm, linux-fsdevel, linux-unionfs

On Thu, 8 Nov 2018 03:46:35 -0700 William Kucharski <william.kucharski@oracle.com> wrote:

> 
> 
> > On Nov 7, 2018, at 4:19 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > 
> > man 2 lseek says
> > 
> > :      EINVAL whence  is  not  valid.   Or: the resulting file offset would be
> > :             negative, or beyond the end of a seekable device.
> > :
> > :      ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is  beyond
> > :             the end of the file.
> > 
> > 
> > Make tmpfs return ENXIO under these circumstances as well.  After this,
> > tmpfs also passes xfstests's generic/448.
> 
> As I objected to last week, despite the fact that other file systems do this, is
> this in fact the desired behavior?
> 
> I'll let you reread that message rather than repeat it in its entirety here, but
> certainly a negative offset is not "beyond the end of the file," and the end
> result is errno is set to ENXIO for a reason that does not match what the
> lseek(2) man page describes.
> 
> I also mentioned if a negative offset is used with SEEK_CUR or SEEK_WHENCE,
> arguably the negative offset should actually be treated as "0" given lseek(2)
> also states:
> 
>       SEEK_DATA
>              Adjust the file offset to the next location in the file
>              greater than or equal to offset containing data.  If offset
>              points to data, then the file offset is set to offset.
> 
>       SEEK_HOLE
>              Adjust the file offset to the next hole in the file greater
>              than or equal to offset.  If offset points into the middle of
>              a hole, then the file offset is set to offset.  If there is no
>              hole past offset, then the file offset is adjusted to the end
>              of the file (i.e., there is an implicit hole at the end of any
>              file).
> 
> Since the "next location" or "next hole" will never be at a negative offset, the
> "greater than" clause of both descriptions would mean the resulting offset should
> be treated as if it were passed as zero.
> 
> However, if xfstest-compliant behavior is desired, the lseek(2) man page
> description for ENXIO should be updated to something like:
> 
>        ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is negative or
>               beyond the end of the file.
> 
> I don't mean to be pedantic, but I also know how frustrating it can be when a system
> call returns with errno set for a reason that doesn't correspond to the man page.

I think that at this stage we should make tmpfs behaviour match the
other filesystems.

If the manpage doesn't match the kernel's behaviour for this
linux-specific feature(?) then we should fix the manpage.

If we find that the behaviour should actually change (and there's a way
of doing that in a reasonably back-compatible manner) then let's change
all filesystems and the manpage.

OK?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tmpfs: let lseek return ENXIO with a negative offset
  2018-11-08 23:07     ` Andrew Morton
@ 2018-11-09  3:52       ` William Kucharski
  0 siblings, 0 replies; 6+ messages in thread
From: William Kucharski @ 2018-11-09  3:52 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Yufen Yu, viro, hughd, linux-mm, linux-fsdevel, linux-unionfs


> On Nov 8, 2018, at 4:07 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> 
> I think that at this stage we should make tmpfs behaviour match the
> other filesystems.
> 
> If the manpage doesn't match the kernel's behaviour for this
> linux-specific feature(?) then we should fix the manpage.
> 
> If we find that the behaviour should actually change (and there's a way
> of doing that in a reasonably back-compatible manner) then let's change
> all filesystems and the manpage.
> 
> OK?

I did a little research, and according to lseek(2):

       SEEK_DATA and SEEK_HOLE are nonstandard extensions also present in
       Solaris, FreeBSD, and DragonFly BSD; they are proposed for inclusion
       in the next POSIX revision (Issue 8).
 
I wrote a brief test program that operated on a file of 1024 zeroes and found
that on an ext4 file system, lseek(2) matches Solaris' behavior on ZFS:

Solaris/ZFS
===========
lseek(3, -1, SEEK_HOLE) error, errno 6 (ENXIO)
lseek(3, 0, SEEK_HOLE) returned 1024
lseek(3, 1, SEEK_HOLE) returned 1024

lseek(3, -1, SEEK_DATA) error, errno 6 (ENXIO)
lseek(3, 0, SEEK_DATA) returned 0
lseek(3, 1, SEEK_DATA) returned 1

Linux/ext4
==========
lseek(3, -1, SEEK_HOLE) error, errno 6 (ENXIO)
lseek(3, 0, SEEK_HOLE) returned 1024
lseek(3, 1, SEEK_HOLE) returned 1024

lseek(3, -1, SEEK_DATA) error, errno 6 (ENXIO)
lseek(3, 0, SEEK_DATA) returned 0
lseek(3, 1, SEEK_DATA) returned 1

That validates the xfstest expectations that a negative passed offset should
return ENXIO.

I suggest the man page wording be changed to read:

       ENXIO  whence is SEEK_DATA or SEEK_HOLE, and the file offset is negative or
              beyond the end of the file.

unless you'd prefer an alternative statement.

Thanks!!

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-11-09  3:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-25  2:22 [PATCH] tmpfs: let lseek return ENXIO with a negative offset Yufen Yu
2018-11-01  7:13 ` William Kucharski
2018-11-07 23:19 ` Andrew Morton
2018-11-08 10:46   ` William Kucharski
2018-11-08 23:07     ` Andrew Morton
2018-11-09  3:52       ` William Kucharski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).