Victor Latushkin wrote: > On Apr 18, 2011, at 11:22 AM, jeff.liu wrote: > >> Hello List, >> >> I am trying to fetch the data/hole info of a sparse file through the >> lseek(SEEK_HOLE/SEEK_DATA) >> stuff, the result of fpathconf(..., _PC_MIN_HOLE_SIZE) is ok, so I think >> this interface is supported >> on my testing ZFS, but SEEK_HOLE always return the sparse file total size >> instead of the desired >> first hole start offset. >> >> The whole process was shown as following, Could anyone give any hints? >> >> Create a sparse file("sparse2") as below, SEEK_HOLE should returns *ZERO* >> and SEEK_DATA should >> returns 40960 IMHO: >> bash-3.00@ python -c "f=open('sparse2', 'w'); f.seek(40960); f.write('BYE'); >> f.close()" > > With default settings you'll get single-block file without any holes from ZFS > perspective. > > Try somewhat bigger sparse file like this: > > dd if=/dev/urandom of=test.file count=1 bs=128k oseek=1024 Thanks for your quick response! It works for me now.
Regards, -Jeff > > >> A tiny program to examine the hole start offset of file "sparse2". >> #include <stdio.h> >> #include <string.h> >> #include <fcntl.h> >> #include <sys/stat.h> >> #include <sys/types.h> >> #include <unistd.h> >> #include <errno.h> >> >> int >> main(int argc, char *argv[]) >> { >> int ret = 0, fd; >> off_t data_pos, hole_pos; >> const char *filename = NULL; >> >> if (argc != 2) { >> fprintf(stderr, "Usage: %s file\n", argv[0]); >> return 1; >> } >> >> filename = strdup(argv[1]); >> if (!filename) { >> perror("strdup"); >> return -1; >> } >> >> fd = open(filename, O_RDONLY); >> if (fd < 0) { >> perror("open"); >> ret = -1; >> goto out; >> } >> >> if (fpathconf(fd, _PC_MIN_HOLE_SIZE) < 0) { >> fprintf(stderr, "The underlying filesystem does not support >> SEEK_HOLE.\n"); >> goto out; >> } >> >> hole_pos = lseek(fd, (off_t)0, SEEK_HOLE); >> if (hole_pos < 0) { >> if (errno == EINVAL || errno == ENOTSUP) { >> fprintf(stderr, "SEEK_HOLE does not support on OS or >> filesystem.\n"); >> goto out; >> } >> >> perror("lseek"); >> ret = -1; >> goto out; >> } >> >> if (hole_pos == 0) >> fprintf(stderr, "Oh, no!! hole start at offset 0?\n"); >> >> if (hole_pos > 0) >> fprintf(stderr, "detected a real hole at: %d.\n", hole_pos); >> >> out: >> free(filename); >> lseek(fd, (off_t)0, SEEK_SET); >> >> return 0; >> } >> >> My test env: >> ============ >> bash-3.00# uname -a >> SunOS unknown 5.10 Generic_142910-17 i86pc i386 i86pc >> >> man zfs(1): >> SunOS 5.10 Last change: 11 Jun 2010 >> >> bash-3.00# zfs list >> NAME USED AVAIL REFER MOUNTPOINT >> ... >> ... >> rpool/export/home 120K 139G 120K /export/home >> ... >> >> "sparse2" located at "/export/home": >> bash-3.00# zdb -dddddd rpool/export/home >> Object lvl iblk dblk dsize lsize %full type >> 104 1 16K 40.5K 40.5K 40.5K 100.00 ZFS plain file >> 264 bonus ZFS znode >> dnode flags: USED_BYTES USERUSED_ACCOUNTED >> dnode maxblkid: 0 >> path /sparse2 >> uid 0 >> gid 0 >> atime Mon Apr 18 14:50:46 2011 >> mtime Mon Apr 18 14:50:46 2011 >> ctime Mon Apr 18 14:50:46 2011 >> crtime Mon Apr 18 14:50:46 2011 >> gen 497 >> mode 100600 >> size 40963 >> parent 3 >> links 1 >> xattr 0 >> rdev 0x0000000000000000 >> Indirect blocks: >> 0 L0 0:1960ce000:a200 a200L/a200P F=1 B=497/497 >> >> segment [0000000000000000, 000000000000a200) size 40.5K >> >> bash-3.00# zdb -R rpool/export/home 0:1960ce000:a200 >> ..... >> 009ff0: 0000000000000000 0000000000000000 ................ >> 00a000: 0000000000455942 0000000000000000 BYE............. >> 00a010: 0000000000000000 0000000000000000 ................ >> .... >> ... >> >> Any comments are appreciated! >> >> Thanks, >> -Jeff >> _______________________________________________ >> zfs-discuss mailing list >> zfs-discuss@opensolaris.org >> http://mail.opensolaris.org/mailman/listinfo/zfs-discuss > _______________________________________________ zfs-discuss mailing list zfs-discuss@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/zfs-discuss