Inconsistency between lseek(SEEK_HOLE) and lseek(SEEK_DATA)

Maxim Sobolev sobomax at FreeBSD.org
Mon Feb 1 17:17:51 UTC 2016


Here it is:

The expected outcome is return code 0, the failure condition is in the
lseek() returning 4 (i.e. sizeof(int)), not -1.

------
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
        char tempname[] = "/tmp/temp.XXXXXX";
        char *fname;
        int fd;
        off_t hole;

        fname = mktemp(tempname);
        if (fname == NULL) {
            exit (1);
        }
        fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
        if (fd == -1) {
            exit (1);
        }
        if (write(fd, &fd, sizeof(fd)) <= 0) {
            exit (1);
        }
        hole = lseek(fd, 0, SEEK_HOLE);
        close(fd);
        unlink(fname);
        if (hole >= 0) {
            fprintf(stderr, "lseek() returned %jd, not -1\n",
(intmax_t)hole);
            exit (1);
        }
        exit (0);
}
------


On Mon, Feb 1, 2016 at 8:56 AM, Konstantin Belousov <kostikbel at gmail.com>
wrote:

> On Mon, Feb 01, 2016 at 07:57:40AM -0800, Maxim Sobolev wrote:
> > Hi,
> >
> > I've noticed that lseek() behaved inconsistently with regards to
> SEEK_HOLE
> > and SEEK_DATA operations. The SEEK_HOLE on a data-only file returns
> st_size
> > (i.e. EOF + 1), while the SEEK_DATA on a hole-only file returns -1 and
> sets
> > errno to ENXIO. The latter seems to be a documented way to indicate that
> > the file has no more data sections past this point.
> >
> > My first idea was that somehow most files has a hole attached to its end
> to
> > fill up the FS block, but that does not seem to be a case. Trying to
> > SEEK_HOLE past the end of any of those data-only files produces an error
> > (i.e. lseek(fd, st_size, SEEK_HOLE) == -1).
> >
> > In short, for some reason I cannot get proper ENXIO from the SEEK_HOLE.
> > What currently returned implies that there is 1-byte hole attached to
> each
> > file past its EOF and that does not smell right.
> >
> > All tests are done on UFS, fairly recent 11-current.
> >
>
> There is no 'hole-only' files on UFS, the last byte in the UFS file must
> be populated, either by allocated fragment if the last byte is in the
> direct blocks range, or by the full block if in the indirect range.
>
> Please show an exact minimal test case which reproduces what you
> consider the bug, with the comment about the expected outcome in the
> failing location.
>
>


More information about the freebsd-fs mailing list