diff options
author | marcel <marcel@FreeBSD.org> | 2014-11-12 00:10:27 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2014-11-12 00:10:27 +0000 |
commit | 8f846e9bc422c37795791b95b05bfe2429187be4 (patch) | |
tree | fe6b68ea79eb63fec9e5f9a26dc796b7c603fbb9 /usr.bin | |
parent | b9caa445798bbe19357b93305d7a77e1a5a05dd4 (diff) | |
download | FreeBSD-src-8f846e9bc422c37795791b95b05bfe2429187be4.zip FreeBSD-src-8f846e9bc422c37795791b95b05bfe2429187be4.tar.gz |
SEEK_DATA has interesting behaviour for sparse files on ZFS. A sparse file
with 128K of random data and truncated to 800K can have SEEK_DATA return -1
when given an offset of 128K. On UFS, the SEEK_DATA returns 800K (the size
of the file). SEEK_HOLE on ZFS seems to behave the same as UFS.
To handle this, map -1 to the size of the file (`end') when lseek returns
this for either SEEK_HOLE or SEEK_DATA. When sparse files are not supported
by the file system both `hole' and `data' will now be equal to `end' and we
will treat the entire file as data. This way, the -1 return for SEEK_DATA
on ZFS will end up doing the right thing.
Reported by: gjb@
MFC after: 3 days
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mkimg/image.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/usr.bin/mkimg/image.c b/usr.bin/mkimg/image.c index 3e7c7d2..be1c2e9 100644 --- a/usr.bin/mkimg/image.c +++ b/usr.bin/mkimg/image.c @@ -405,16 +405,18 @@ image_copyin_mapped(lba_t blk, int fd, uint64_t *sizep) error = 0; while (!error && cur < end) { hole = lseek(fd, cur, SEEK_HOLE); + if (hole == -1) + hole = end; data = lseek(fd, cur, SEEK_DATA); + if (data == -1) + data = end; /* * Treat the entire file as data if sparse files * are not supported by the underlying file system. */ - if (hole == -1 && data == -1) { + if (hole == end && data == end) data = cur; - hole = end; - } if (cur == hole && data > hole) { hole = pos; |