aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2022-04-21 19:57:24 +0000
committerKyle Evans <kevans@FreeBSD.org>2022-04-24 03:49:22 +0000
commit9a1efa766781c9dd1eb5975ce3a5c8a64d89cd18 (patch)
treedde681045d1685f9b05367115912fc7dc3db9c9e
parenta605ca25ef681452e25622a44917cbb5033eaae4 (diff)
downloadsrc-9a1efa766781c9dd1eb5975ce3a5c8a64d89cd18.tar.gz
src-9a1efa766781c9dd1eb5975ce3a5c8a64d89cd18.zip
stand: zfs: handle holes at the tail end correctly
This mirrors dmu_read_impl(), zeroing out the tail end of the buffer and clipping the read to what's contained by the block that exists. This fixes an issue that arose during the 13.1 release process; in 13.1-RC1 and later, setting up GELI+ZFS will result in a failure to boot. The culprit is this, which causes us to fail to load geom_eli.ko as there's a residual portion after the single datablk that should be zeroed out. PR: 263407 Reviewed by: tsoome (cherry picked from commit 914dc91d12198352b7878a88d30e2a6373a936e1)
-rw-r--r--stand/libsa/zfs/zfsimpl.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index 6c46bfdaea9c..33f23f88f13a 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -2066,6 +2066,19 @@ dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset,
}
/*
+ * Handle odd block sizes, mirrors dmu_read_impl(). Data can't exist
+ * past the first block, so we'll clip the read to the portion of the
+ * buffer within bsize and zero out the remainder.
+ */
+ if (dnode->dn_maxblkid == 0) {
+ size_t newbuflen;
+
+ newbuflen = offset > bsize ? 0 : MIN(buflen, bsize - offset);
+ bzero((char *)buf + newbuflen, buflen - newbuflen);
+ buflen = newbuflen;
+ }
+
+ /*
* Note: bsize may not be a power of two here so we need to do an
* actual divide rather than a bitshift.
*/