diff options
Diffstat (limited to 'usr/src/boot/lib/libstand/zfs')
-rw-r--r-- | usr/src/boot/lib/libstand/zfs/zfs.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/usr/src/boot/lib/libstand/zfs/zfs.c b/usr/src/boot/lib/libstand/zfs/zfs.c index 665d0b4a48..34c1b7c23e 100644 --- a/usr/src/boot/lib/libstand/zfs/zfs.c +++ b/usr/src/boot/lib/libstand/zfs/zfs.c @@ -401,7 +401,7 @@ vdev_read(vdev_t *vdev __unused, void *priv, off_t offset, void *buf, full_sec_size -= secsz; /* Return of partial sector data requires a bounce buffer. */ - if ((head > 0) || do_tail_read) { + if ((head > 0) || do_tail_read || bytes < secsz) { bouncebuf = malloc(secsz); if (bouncebuf == NULL) { printf("vdev_read: out of memory\n"); @@ -427,12 +427,21 @@ vdev_read(vdev_t *vdev __unused, void *priv, off_t offset, void *buf, /* Full data return from read sectors */ if (full_sec_size > 0) { - res = read(fd, outbuf, full_sec_size); - if (res != full_sec_size) { - ret = EIO; - goto error; + if (bytes < full_sec_size) { + res = read(fd, bouncebuf, secsz); + if (res != secsz) { + ret = EIO; + goto error; + } + memcpy(outbuf, bouncebuf, bytes); + } else { + res = read(fd, outbuf, full_sec_size); + if (res != full_sec_size) { + ret = EIO; + goto error; + } + outbuf += full_sec_size; } - outbuf += full_sec_size; } /* Partial data return from last sector */ |