summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2014-11-12 00:10:27 +0000
committermarcel <marcel@FreeBSD.org>2014-11-12 00:10:27 +0000
commit8f846e9bc422c37795791b95b05bfe2429187be4 (patch)
treefe6b68ea79eb63fec9e5f9a26dc796b7c603fbb9 /usr.bin
parentb9caa445798bbe19357b93305d7a77e1a5a05dd4 (diff)
downloadFreeBSD-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.c8
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;
OpenPOWER on IntegriCloud