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
This commit is contained in:
parent
bea71143ed
commit
9ba57342c9
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user