lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <BANLkTiknb+hzFAjpwESwMcqMVtkFc0HFQQ@mail.gmail.com>
Date:	Thu, 21 Apr 2011 21:22:55 -0400
From:	Josef Bacik <josef@...icpanda.com>
To:	Eric Blake <eblake@...hat.com>
Cc:	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/2] fs: add SEEK_HOLE and SEEK_DATA flags

On Thu, Apr 21, 2011 at 6:28 PM, Eric Blake <eblake@...hat.com> wrote:
> Josef Bacik <josef <at> redhat.com> writes:
>
>> This just gets us ready to support the SEEK_HOLE and SEEK_DATA flags.  Turns
>> out using fiemap in things like cp cause more problems than it solves, so
>> lets try and give userspace an interface that doesn't suck.  So we have
>>
>> -SEEK_HOLE: this moves the file pos to the nearest hole in the file from the
>> given position.  If the given position is a hole then pos won't move.  A "hole"
>> is defined by whatever the fs feels like defining it to be.
>
> You absolutely need to match Solaris semantics, which are documented as follows:
>
>         �  If whence is SEEK_HOLE, the offset of the start of the  next  hole
>            greater than or equal to the supplied offset is returned. The def-
>            inition of a hole is provided near the end of the DESCRIPTION.
>
>         �  If whence is SEEK_DATA, the file pointer is set to  the  start  of
>            the  next  non-hole  file region greater than or equal to the sup-
>            plied offset.
>
>       A  "hole" is defined as a contiguous range of bytes in a file, all hav-
>       ing the value of zero, but not all zeros in a file are guaranteed to be
>       represented  as  holes returned with SEEK_HOLE. Filesystems are allowed
>       to expose ranges of zeros with SEEK_HOLE, but not required to. Applica-
>       tions can use SEEK_HOLE to optimise their behavior for ranges of zeros,
>       but must not depend on it to find all such ranges in a file. The  exis-
>       tence  of  a  hole at the end of every data region allows for easy pro-
>       gramming and implies that a virtual hole exists at the end of the file.
>       Applications   should   use   fpathconf(_PC_MIN_HOLE_SIZE)   or   path-
>       conf(_PC_MIN_HOLE_SIZE)  to  determine   if   a   filesystem   supports
>       SEEK_HOLE. See fpathconf(2).
>
>       For  filesystems  that  do not supply information about holes, the file
>       will be represented as one entire data region.
>
>       ENXIO           For SEEK_DATA, there are no more data regions past  the
>                       supplied offset. For SEEK_HOLE, there are no more holes
>                       past the supplied offset.
>
> Note that in that definition, SEEK_HOLE does _not_ reposition the file offset
> (it returns the offset of the next hole, which might be at the end of the file
> since all files have a virtual hole at the end, but leaves the position
> unchanged).  I'd have to write a test program on Solaris to see whether that
> definition is actually true, or if it is a bug in the Solaris man page.
>

lseek's purpose is to reposition the file position, so I'd imagine
this is just a bug in the man page.

> Making SEEK_HOLE blindly fail is therefore not useful; you could just as
> easily make it succeed and return the offset of the last byte of the file for
> all file systems (if the offset requested is within bounds, or fail with
> ENXIO if it is out of bounds), and have a valid, working, and minimal
> implementation already in place.
>

Except you can have blocks allocated past i_size, so returning i_size
isn't necessarily correct.  Obviously the idea is to have most of the
filesystems doing the correct thing, but for my first go around I just
was going to do one since I expect quite a bit of repainting for this
bikeshed is yet to be done.  But I guess if you have data past i_size
doing this would encourage the various fs people to fix it.

>>
>> -SEEK_DATA: this is obviously a little more self-explanatory.  Again the only
>> ambiguity comes in with preallocated extents.  If you have an fs that can't
>> reliably tell that the preallocated extent is in the process of turning into a
>> real extent, it is correct for SEEK_DATA to park you at a preallocated extent.
>
> In contrast to SEEK_HOLE, SEEK_DATA _does_ reposition the file, or fail with
> ENXIO.  Back to your minimal implementation, it would be valid to always fail
> with ENXIO (treating every file as a single block of data followed by a single
> virtual hole at file end, so there is no next data after any current position).
>
>> +++ b/fs/read_write.c
>> @@ -64,6 +64,9 @@ generic_file_llseek_unlocked(struct file *file, loff_t
> offset, int origin)
>>                       return file->f_pos;
>>               offset += file->f_pos;
>>               break;
>> +     case SEEK_DATA:
>> +     case SEEK_HOLE:
>> +             return -EINVAL;
>
> Whatever you do, returning EINVAL is not nice, especially when it seems pretty
> easy to provide a working alternative that assumes all files are a single data
> block until fine-tuned otherwise on a per-filesystem basis.
>

Agreed, I'll fix it.  Thanks,

Josef
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ