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