Inconsistency between lseek(SEEK_HOLE) and lseek(SEEK_DATA)

Maxim Sobolev sobomax at sippysoft.com
Tue Feb 2 18:54:14 UTC 2016


P.S.  "hole = lseek(fd, 0, SEEK_HOLE)" is superfluous there.

On Tue, Feb 2, 2016 at 10:51 AM, Maxim Sobolev <sobomax at sippysoft.com>
wrote:

> Here it is, works on UFS no problems here.
> ----
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <errno.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, exval;
>     off_t hole, data;
>
>     fname = mktemp(tempname);
>     if (fname == NULL) {
>         exit (1);
>     }
>     fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
>     if (fd == -1) {
>         exit (1);
>     }
>     if (ftruncate(fd, 1024 * 128) < 0) {
>         exit (1);
>     }
>     hole = lseek(fd, 0, SEEK_HOLE);
>     data = lseek(fd, 0, SEEK_DATA);
>     if (ftruncate(fd, data) < 0) {
>         exit (1);
>     }
>     printf("%s: %jd %jd\n", fname, (intmax_t)hole, (intmax_t)data);
>     exval = 0;
> cleanup:
>     close(fd);
>     exit (exval);
> }
> ----
>
> On Tue, Feb 2, 2016 at 5:25 AM, Konstantin Belousov <kostikbel at gmail.com>
> wrote:
>
>> On Mon, Feb 01, 2016 at 09:17:00PM -0800, Maxim Sobolev wrote:
>> > WRT the:
>> >
>> > > 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.
>> >
>> > Ideed, the UFS resists putting a hole at the end of the file, yet, it's
>> > possible to arrange hole-only situation by first truncating an empty
>> file
>> > to some size that is greater than the target hole size, so that you get
>> > hole of the desired size following by the bit of data, and then
>> truncating
>> > the resulting file back to the offset where the data starts:
>> >
>> > -----
>> >     fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
>> >     if (fd == -1) {
>> >         exit (1);
>> >     }
>> >     if (ftruncate(fd, 1024 * 128) < 0) {
>> >         exit (1);
>> >     }
>> >     data = lseek(fd, 0, SEEK_DATA);
>> >     if (data >= 0 && ftruncate(fd, data) < 0) {
>> >         exit (1);
>> >     }
>> > -----
>> > [sobomax at rtpdev ~/projects/freebsd11/usr.bin/lsholes]$ ./lsholes
>> > /tmp/temp.MgoPPo
>> > Type Start   End  Size
>> > HOLE     0 98303 98304
>> >
>> > Total HOLE: 98304 (100.00%)
>> > Total DATA: 0 (0.00%)
>> > [sobomax at rtpdev ~/projects/freebsd11/usr.bin/lsholes]$ ls -l
>> > /tmp/temp.MgoPPo
>> > -rw-r--r--  1 sobomax  wheel  98304 Feb  1 21:06 /tmp/temp.MgoPPo
>> Is this on UFS ?
>>
>> Please provide me with the program to re-create it, if on UFS.
>> At least fsck is not ready for files with holes at tail, and several
>> kernel code fragments expect last byte to be allocated.  I once had
>> a patch to allow hole at tail for UFS, but I did not moved it to the
>> committable state.
>>
>> > -----
>> >
>> > I don't know if operating on that file would result in some data
>> > corruption, but I also seem have no issues creating hole-only files on
>> ZFS
>> > using my fallocate(2) syscall.
>>
>>
>
>
> --
> Maksym Sobolyev
> Sippy Software, Inc.
> Internet Telephony (VoIP) Experts
> Tel (Canada): +1-778-783-0474
> Tel (Toll-Free): +1-855-747-7779
> Fax: +1-866-857-6942
> Web: http://www.sippysoft.com
> MSN: sales at sippysoft.com
> Skype: SippySoft
>



-- 
Maksym Sobolyev
Sippy Software, Inc.
Internet Telephony (VoIP) Experts
Tel (Canada): +1-778-783-0474
Tel (Toll-Free): +1-855-747-7779
Fax: +1-866-857-6942
Web: http://www.sippysoft.com
MSN: sales at sippysoft.com
Skype: SippySoft


More information about the freebsd-fs mailing list