NetBSD Problem Report #60286

From www@netbsd.org  Fri May 22 15:10:44 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.netbsd.org", Issuer "R13" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 101C51A9239
	for <gnats-bugs@gnats.NetBSD.org>; Fri, 22 May 2026 15:10:44 +0000 (UTC)
Message-Id: <20260522151043.2FF461A923C@mollari.NetBSD.org>
Date: Fri, 22 May 2026 15:10:43 +0000 (UTC)
From: nervoso@k1.com.br
Reply-To: nervoso@k1.com.br
To: gnats-bugs@NetBSD.org
Subject: zfs sparse zvol reports wrong volume size
X-Send-Pr-Version: www-1.0
X-From4GNATS: "nervoso@k1.com.br via gnats" <gnats-admin@NetBSD.org>

>Number:         60286
>Category:       kern
>Synopsis:       zfs sparse zvol reports wrong volume size
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    mlelstv
>State:          analyzed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri May 22 15:15:00 +0000 2026
>Closed-Date:    
>Last-Modified:  Sat May 23 23:13:58 +0000 2026
>Originator:     sergio lenzi
>Release:        10.1_STABLE
>Organization:
k1 sistemas
>Environment:
NetBSD desktop2.lenzicasa 10.1_STABLE NetBSD 10.1_STABLE (LZT_2048_USERS) #1: Fri May  1 15:07:14 -03 2026  NetBSD@lztdev.lenzicasa:/home/NetBSD/BUILD/10/amd64/OBJ/sys/arch/amd64/compile/GENERIC amd64
>Description:
# Fix zvol DIOCGWEDGEINFO reporting wrong disk size to userland (QEMU)
#     
# Bug: dkw_size in DIOCGWEDGEINFO is set from dg_secperunit, which counts
# sectors in dg_secsize units (typically 4096 bytes when spa_max_ashift=12).
# However, dkw_size is defined as "size of wedge in blocks" where blocks
# are DEV_BSIZE (512 bytes).  QEMU and other userland tools read dkw_size
# and multiply by 512 to get the device size in bytes, resulting in a
# device that appears 1/8th its actual size on pools with ashift=12.
#     
# Example: a 1TB zvol reports as 128GB, a 2TB zvol reports as 256GB.
#    
# Fix: convert dg_secperunit from dg_secsize sectors to DEV_BSIZE blocks
# by multiplying by (dg_secsize / DEV_BSIZE).
#    
# Tested on NetBSD 10.1_STABLE with QEMU 10.2.2 and ZFS pool ashift=1
>How-To-Repeat:
create a sparse zvol of 2TB buit qemu only sees 128G
>Fix:
# Fix zvol DIOCGWEDGEINFO reporting wrong disk size to userland (QEMU)
#
# Bug: dkw_size in DIOCGWEDGEINFO is set from dg_secperunit, which counts
# sectors in dg_secsize units (typically 4096 bytes when spa_max_ashift=12).
# However, dkw_size is defined as "size of wedge in blocks" where blocks
# are DEV_BSIZE (512 bytes).  QEMU and other userland tools read dkw_size
# and multiply by 512 to get the device size in bytes, resulting in a
# device that appears 1/8th its actual size on pools with ashift=12.
#
# Example: a 1TB zvol reports as 128GB, a 2TB zvol reports as 256GB.
#
# Fix: convert dg_secperunit from dg_secsize sectors to DEV_BSIZE blocks
# by multiplying by (dg_secsize / DEV_BSIZE).
#
# Tested on NetBSD 10.1_STABLE with QEMU 10.2.2 and ZFS pool ashift=12.

--- usr/src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c.orig      2026-05-22 11:10:15.900492779 -0300
+++ usr/src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c   2026-05-22 11:10:28.101264922 -0300
@@ -3621,7 +3621,13 @@
                strlcpy(dkw->dkw_parent, "ZFS", sizeof(dkw->dkw_parent));

                dkw->dkw_offset = 0;
-               dkw->dkw_size = dg->dg_secperunit;
+               /*
+                * dkw_size is in DEV_BSIZE (512) blocks, but dg_secperunit
+                * counts in dg_secsize blocks (which may be 4096 or larger
+                * depending on the pool's ashift).  Convert to DEV_BSIZE.
+                */
+               dkw->dkw_size = dg->dg_secperunit *
+                   (dg->dg_secsize / DEV_BSIZE);
                strcpy(dkw->dkw_ptype, DKW_PTYPE_FFS);

                break;
~

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->mlelstv
Responsible-Changed-By: riastradh@NetBSD.org
Responsible-Changed-When: Fri, 22 May 2026 16:47:19 +0000
Responsible-Changed-Why:
Can you take a look?  Looks like you added the original dkw_size =
dg_secperunit assignment.


From: lenzi himself <nervoso@k1.com.br>
To: gnats-bugs@netbsd.org, mlelstv@netbsd.org, kern-bug-people@netbsd.org,
        netbsd-bugs@netbsd.org, gnats-admin@netbsd.org, riastradh@NetBSD.org
Cc: 
Subject: Re: kern/60286 (zfs sparse zvol reports wrong volume size)
Date: Fri, 22 May 2026 15:19:35 -0300

 --=-MbbHCv8L/rRh9t16a8LQ
 Content-Type: multipart/alternative; boundary="=-CIGlX2ihs60Pv9Z/o/R4"

 --=-CIGlX2ihs60Pv9Z/o/R4
 Content-Type: text/plain; charset="UTF-8"
 Content-Transfer-Encoding: quoted-printable

 Em sex, 2026-05-22 =C3=A0s 16:47 +0000, riastradh@NetBSD.org escreveu:
 > Synopsis: zfs sparse zvol reports wrong volume size
 >=20
 > Responsible-Changed-From-To: kern-bug-people->mlelstv
 > Responsible-Changed-By: riastradh@NetBSD.org
 > Responsible-Changed-When: Fri, 22 May 2026 16:47:19 +0000
 > Responsible-Changed-Why:
 > Can you take a look?  Looks like you added the original dkw_size =3D
 > dg_secperunit assignment.
 >=20
 >=20
 >=20
 I have also being playing with zfs... and I found this patch very useful be=
 cause it limits
 ARC to take all avail memory....
 Are there any zfs guru out there???
 Claude-code point these changes... =C2=A0I have been using it for a long ti=
 me and my zfs sometimes perform better than
 FreeBSD...



 --=-CIGlX2ihs60Pv9Z/o/R4
 Content-Type: text/html; charset="utf-8"
 Content-Transfer-Encoding: quoted-printable

 <html><head><style>pre,code,address {
   margin: 0px;
 }
 h1,h2,h3,h4,h5,h6 {
   margin-top: 0.2em;
   margin-bottom: 0.2em;
 }
 ol,ul {
   margin-top: 0em;
   margin-bottom: 0em;
 }
 blockquote {
   margin-top: 0em;
   margin-bottom: 0em;
 }
 </style></head><body><div>Em sex, 2026-05-22 =C3=A0s 16:47 +0000, riastradh=
 @NetBSD.org escreveu:</div><blockquote type=3D"cite" style=3D"margin:0 0 0 =
 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pre>Synopsis: zfs sp=
 arse zvol reports wrong volume size</pre><pre><br></pre><pre>Responsible-Ch=
 anged-From-To: kern-bug-people-&gt;mlelstv</pre><pre>Responsible-Changed-By=
 : <a href=3D"mailto:riastradh@NetBSD.org">riastradh@NetBSD.org</a></pre><pr=
 e>Responsible-Changed-When: Fri, 22 May 2026 16:47:19 +0000</pre><pre>Respo=
 nsible-Changed-Why:</pre><pre>Can you take a look?  Looks like you added th=
 e original dkw_size =3D</pre><pre>dg_secperunit assignment.</pre><pre><br><=
 /pre><pre><br></pre><pre><br></pre></blockquote><div>I have also being play=
 ing with zfs... and I found this patch very useful because it limits</div><=
 div>ARC to take all avail memory....</div><div>Are there any zfs guru out t=
 here???</div><div>Claude-code point these changes... &nbsp;I have been usin=
 g it for a long time and my zfs sometimes perform better than FreeBSD...</d=
 iv><div><br></div><div><br></div><div><br></div><div><span></span></div></b=
 ody></html>

 --=-CIGlX2ihs60Pv9Z/o/R4--

 --=-MbbHCv8L/rRh9t16a8LQ
 Content-Disposition: attachment; filename="patch-zfs"
 Content-Type: text/x-patch; name="patch-zfs"; charset="UTF-8"
 Content-Transfer-Encoding: base64

 SW5kZXg6IHVzci9zcmMvZXh0ZXJuYWwvY2RkbC9vc25ldC9kaXN0L3V0cy9jb21tb24vZnMvemZz
 L2FyYy5jCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT0KUkNTIGZpbGU6IC9jdnNyb290L3NyYy9leHRlcm5hbC9jZGRsL29z
 bmV0L2Rpc3QvdXRzL2NvbW1vbi9mcy96ZnMvYXJjLmMsdgpyZXRyaWV2aW5nIHJldmlzaW9uIDEu
 MjIKZGlmZiAtdSAtcjEuMjIgYXJjLmMKLS0tIHVzci9zcmMvZXh0ZXJuYWwvY2RkbC9vc25ldC9k
 aXN0L3V0cy9jb21tb24vZnMvemZzL2FyYy5jCTMgQXVnIDIwMjIgMDE6NTM6MDYgLTAwMDAJMS4y
 MgorKysgdXNyL3NyYy9leHRlcm5hbC9jZGRsL29zbmV0L2Rpc3QvdXRzL2NvbW1vbi9mcy96ZnMv
 YXJjLmMJMTIgU2VwIDIwMjMgMTY6NDQ6NDggLTAwMDAKQEAgLTM4MCw4ICszODAsMTYgQEAKIC8q
 CiAgKiBUaGVzZSB0dW5hYmxlcyBhcmUgZm9yIHBlcmZvcm1hbmNlIGFuYWx5c2lzLgogICovCisv
 KgorICogemZzX2FyY19tYXggYW5kIHpmc19hcmNfbWluIGNvbnRyb2wgYXJjX2NfbWF4IGFuZCBh
 cmNfY19taW4gYXQKKyAqIGluaXRpYWxpemF0aW9uIGFuZCBhcmUgdGhlbiBzZXQgdG8gdGhlIGNv
 bXB1dGVkIHZhbHVlcy4KKyAqLwogdWludDY0X3QgemZzX2FyY19tYXg7CiB1aW50NjRfdCB6ZnNf
 YXJjX21pbjsKKy8qCisgKiB6ZnNfYXJjX21ldGFfe2xpbWl0LG1pbn0gY29udHJvbCBhcmNfbWV0
 YV8qIGF0IGluaXRpYWxpemF0aW9uIGJ1dAorICogZm9yIHVuY2xlYXIgcmVhc29ucyBhcmUgbm90
 IHNldCB0byB0aGUgY29tcHV0ZWQgdmFsdWVzLgorICovCiB1aW50NjRfdCB6ZnNfYXJjX21ldGFf
 bGltaXQgPSAwOwogdWludDY0X3QgemZzX2FyY19tZXRhX21pbiA9IDA7CiBpbnQgemZzX2FyY19n
 cm93X3JldHJ5ID0gMDsKQEAgLTc1NywxMSArNzY1LDMyIEBACiAJa3N0YXRfbmFtZWRfdCBhcmNz
 dGF0X2wyX3dyaXRlX2J1ZmZlcl9saXN0X2l0ZXI7CiAJa3N0YXRfbmFtZWRfdCBhcmNzdGF0X2wy
 X3dyaXRlX2J1ZmZlcl9saXN0X251bGxfaXRlcjsKIAlrc3RhdF9uYW1lZF90IGFyY3N0YXRfbWVt
 b3J5X3Rocm90dGxlX2NvdW50OworCS8qCisJICogTnVtYmVyIG9mIGJ5dGVzIG9mIG1ldGFkYXRh
 IGJ1ZmZlcnMgaW4gQVJDLgorCSAqLwogCWtzdGF0X25hbWVkX3QgYXJjc3RhdF9tZXRhX3VzZWQ7
 CisJLyoKKwkgKiBOdW1iZXIgb2YgYnl0ZXMgdG8gd2hpY2ggdGhhdCBtZXRhIHVzYWdlIHdpbGwg
 YmUgcmVkdWNlZAorCSAqIGR1cmluZyByb3V0aW5lIGFkanVzdG1lbnQuCisJICovCiAJa3N0YXRf
 bmFtZWRfdCBhcmNzdGF0X21ldGFfbGltaXQ7CisJLyoKKwkgKiBNYXhpbXVtIHNpemUgKGJ5dGVz
 KSBvZiBzdG9yZWQgbWV0YSBkYXRhIGZvciB0aGlzCisJICogaW5zdGFudGlhdGlvbiBvZiB6ZnMu
 ICBUaGlzIGlzIGEgbWVhc3VyZW1lbnQsIG5vdCBjb250cm9sLAorCSAqIGFuZCBwcm9iYWJseSBz
 aG91bGQgYmUgbmFtZWQgX2hpd2F0IGluc3RlYWQuCisJICovCiAJa3N0YXRfbmFtZWRfdCBhcmNz
 dGF0X21ldGFfbWF4OworCS8qCisJICogTnVtYmVyIG9mIGJ5dGVzIG9mIG1ldGFkYXRhIGluIEFS
 QyBiZWxvdyB3aGljaCBkYXRhIGlzCisJICogcHJlZmVyZW50aWFsbHkgZXZpY3RlZC4KKwkgKi8K
 IAlrc3RhdF9uYW1lZF90IGFyY3N0YXRfbWV0YV9taW47CisJLyogQXBwYXJlbnRseSB1bnVzZWQu
 ICovCiAJa3N0YXRfbmFtZWRfdCBhcmNzdGF0X3N5bmNfd2FpdF9mb3JfYXN5bmM7CisJLyoKKwkg
 KiBDb3VudCBvZiByZWFkcyB0aGF0IHN1Y2NlZWQgYmVjYXVzZSBhIHByaW9yIHByZWRpY3RpdmUK
 KwkgKiBwcmVmZXRjaCBoYXMgYWxyZWFkeSBjb21wbGV0ZWQuCisJICovCiAJa3N0YXRfbmFtZWRf
 dCBhcmNzdGF0X2RlbWFuZF9oaXRfcHJlZGljdGl2ZV9wcmVmZXRjaDsKIH0gYXJjX3N0YXRzX3Q7
 CiAKQEAgLTM1ODIsNiArMzYxMSwxMyBAQAogCiAJdG90YWxfZXZpY3RlZCArPSBhcmNfYWRqdXN0
 X2ltcGwoYXJjX21mdSwgMCwgdGFyZ2V0LCBBUkNfQlVGQ19NRVRBREFUQSk7CiAKKyNpZiAwCisJ
 aWYgKHRvdGFsX2V2aWN0ZWQgIT0gMCkgeworCQlwcmludGYoImFyY19hZGp1c3RfbWV0YTogZXZp
 Y3RlZCAlIiBQUkl1NjQgIiB3aXRoIHRhcmdldCAlIiBQUklkNjQgIlxuIiwKKwkJICAgICAgIHRv
 dGFsX2V2aWN0ZWQsIHRhcmdldCk7CisJfQorI2VuZGlmCisKIAlyZXR1cm4gKHRvdGFsX2V2aWN0
 ZWQpOwogfQogCkBAIC0zNzUzLDcgKzM3ODksNyBAQAogCiAJCS8qCiAJCSAqIElmIHdlIGNvdWxk
 bid0IGV2aWN0IG91ciB0YXJnZXQgbnVtYmVyIG9mIGJ5dGVzIGZyb20KLQkJICogZGF0YSwgd2Ug
 dHJ5IHRvIGdldCB0aGUgcmVzdCBmcm9tIGRhdGEuCisJCSAqIGRhdGEsIHdlIHRyeSB0byBnZXQg
 dGhlIHJlc3QgZnJvbSBtZXRhZGF0YS4KIAkJICovCiAJCXRhcmdldCAtPSBieXRlczsKIApAQCAt
 MzgwMiw2ICszODM4LDExIEBACiAJdG90YWxfZXZpY3RlZCArPQogCSAgICBhcmNfYWRqdXN0X2lt
 cGwoYXJjX21mdV9naG9zdCwgMCwgdGFyZ2V0LCBBUkNfQlVGQ19NRVRBREFUQSk7CiAKKwkvKiBM
 b2cgaWYgbGlrZWx5IHRvIGJlIGludGVyZXN0aW5nLgorCWlmICh0b3RhbF9ldmljdGVkID49IDQg
 KiAxMDI0ICogMTAyNCkgeworCQlwcmludGYoImFyY19hZGp1c3QgZXZpY3RlZCAlIiBQUkl1NjQg
 IlxuIiwgdG90YWxfZXZpY3RlZCk7CisJfQorCSovCiAJcmV0dXJuICh0b3RhbF9ldmljdGVkKTsK
 IH0KIApAQCAtMzgzMSw2ICszODcyLDggQEAKIAogCSh2b2lkKSBhcmNfZmx1c2hfc3RhdGUoYXJj
 X21mdV9naG9zdCwgZ3VpZCwgQVJDX0JVRkNfREFUQSwgcmV0cnkpOwogCSh2b2lkKSBhcmNfZmx1
 c2hfc3RhdGUoYXJjX21mdV9naG9zdCwgZ3VpZCwgQVJDX0JVRkNfTUVUQURBVEEsIHJldHJ5KTsK
 KworCS8vcHJpbnRmKCJhcmNfZmx1c2ggY29tcGxldGVkXG4iKTsKIH0KIAogdm9pZApAQCAtNDE1
 OCw2ICs0MjAxLDkgQEAKIAkJCWFyY19ub19ncm93ID0gQl9UUlVFOwogCQkJYXJjX3dhcm0gPSBC
 X1RSVUU7CiAKKwkJCS8qcHJpbnRmKCJhcmNfcmVjbGFpbV90aHJlYWQ6IG5lZ2F0aXZlIGZyZWVf
 bWVtb3J5ICUiIFBSSWQ2NCAiXG4iLAorCQkJICAgICAgIGZyZWVfbWVtb3J5KTsKKwkJCSovCiAJ
 CQkvKgogCQkJICogV2FpdCBhdCBsZWFzdCB6ZnNfZ3Jvd19yZXRyeSAoZGVmYXVsdCA2MCkgc2Vj
 b25kcwogCQkJICogYmVmb3JlIGNvbnNpZGVyaW5nIGdyb3dpbmcuCkBAIC02MDgxLDYgKzYxMjcs
 OSBAQAogCiAJLyogU3RhcnQgb3V0IHdpdGggMS84IG9mIGFsbCBtZW1vcnkgKi8KIAlhcmNfYyA9
 IGttZW1fc2l6ZSgpIC8gODsKKyNpZiAwCisJcHJpbnRmKCJBUkNJIDAwMSBhcmNfYyAlIiBQUkl1
 NjQgIlxuIiwgYXJjX2MpOworI2VuZGlmCiAKICNpZmRlZiBpbGx1bW9zCiAjaWZkZWYgX0tFUk5F
 TApAQCAtNjA5NCwxMiArNjE0MywzMiBAQAogI2VuZGlmCS8qIGlsbHVtb3MgKi8KIAkvKiBzZXQg
 bWluIGNhY2hlIHRvIDEvMzIgb2YgYWxsIG1lbW9yeSwgb3IgYXJjX2Fic19taW4sIHdoaWNoZXZl
 ciBpcyBtb3JlICovCiAJYXJjX2NfbWluID0gTUFYKGFyY19jIC8gNCwgYXJjX2Fic19taW4pOwor
 CXByaW50ZigiQVJDSSAwMDIgYXJjX2Fic19taW4gJSIgUFJJdTY0ICJcbiIsIGFyY19hYnNfbWlu
 KTsKKwlwcmludGYoIkFSQ0kgMDAyIGFyY19jX21pbiAlIiBQUkl1NjQgIlxuIiwgYXJjX2NfbWlu
 KTsKKworI2lmIGRlZmluZWQoX19OZXRCU0RfXykgJiYgZGVmaW5lZChfS0VSTkVMKQorCS8qCisJ
 ICogQmVjYXVzZSBOZXRCU0QvemZzIGxhY2tzIGFuIGVmZmVjdGl2ZSBtZWNoYW5pc20gZm9yIG1l
 bW9yeQorCSAqIHByZXNzdXJlIHRvIHJlY2xhaW0gZnJvbSBBUkMsIGtlZXAgYXJjX2NfbWF4IG1v
 ZGVyYXRlCisJICogcmF0aGVyIHRoYW4gYWxsb3dpbmcgQVJDIHRvIGNvbnN1bWUgbmVhcmx5IGFs
 bCBtZW1vcnkuCisJICogWFhYIFJldmlzaXQgd2hlbiByZWNsYWltIHdvcmtzLgorCSAqLworCWFy
 Y19jX21heCA9IE1JTihhcmNfYywgdm1lbV9zaXplKGhlYXBfYXJlbmEsIFZNRU1fQUxMT0MgfCBW
 TUVNX0ZSRUUpIC8gOCk7CisJcHJpbnRmKCJBUkNJIDAwNSBhcmNfY19tYXggJSIgUFJJdTY0ICJc
 biIsIGFyY19jX21heCk7CisjZWxzZQorCS8qIFhYWAorCSAqIFRoaXMgY29tbWVudCBkb2VzIG5v
 dCBtYXRjaCB0aGUgY29kZSBhdCBhbGwhCisJICogUGx1cywgaXQncyBkYW5nZXJvdXMgdG8gYXNz
 dW1lIHRoYXQgYXJjX2MgaXMgc3RpbGwgMS84IG9mIFJBTSBhdCB0aGlzIHBvaW50LgorCSAqLwog
 CS8qIHNldCBtYXggdG8gMS8yIG9mIGFsbCBtZW1vcnksIG9yIGFsbCBidXQgMUdCLCB3aGljaGV2
 ZXIgaXMgbW9yZSAqLwogCWlmIChhcmNfYyAqIDggPj0gMSA8PCAzMCkKIAkJYXJjX2NfbWF4ID0g
 KGFyY19jICogOCkgLSAoMSA8PCAzMCk7CiAJZWxzZQogCQlhcmNfY19tYXggPSBhcmNfY19taW47
 CisJcHJpbnRmKCJBUkNJIDAwMyBhcmNfY19tYXggJSIgUFJJdTY0ICJcbiIsIGFyY19jX21heCk7
 CiAJYXJjX2NfbWF4ID0gTUFYKGFyY19jICogNSwgYXJjX2NfbWF4KTsKKwlwcmludGYoIkFSQ0kg
 MDA0IGFyY19jX21heCAlIiBQUkl1NjQgIlxuIiwgYXJjX2NfbWF4KTsKKyNlbmRpZgogCiAJLyoK
 IAkgKiBJbiB1c2VybGFuZCwgdGhlcmUncyBvbmx5IHRoZSBtZW1vcnkgcHJlc3N1cmUgdGhhdCB3
 ZSBhcnRpZmljaWFsbHkKQEAgLTYxMjQsMTAgKzYxOTMsMjQgQEAKIAkJYXJjX2NfbWluID0gemZz
 X2FyY19taW47CiAjZW5kaWYKIAorCS8qCisJICogU3RhcnQgb3V0IHdpdGggdGhlIHRhcmdldCB1
 c2FnZSBmb3IgQVJDIGFzIGhpZ2ggYXMgd2UgYXJlCisJICogd2lsbGluZyB0byBnby4gIChUaGlz
 IGxpa2VseSByZWxpZXMgb24gc29tZSBtZW1vcnkgcHJlc3N1cmUKKwkgKiBtZWNoYW5pc20gdG8g
 cmVkdWNlIGl0IHdoZW4gZnJlZWluZyBpcyByZXF1ZXN0ZWQuCisJICovCiAJYXJjX2MgPSBhcmNf
 Y19tYXg7CisKKwkvKgorCSAqIENvbXB1dGUgdGhlIE1SVSdzIHBvcnRpb24gb2YgdGFyZ2V0IChh
 bmQgaW1wbGljaXRseSBNRlUncykuCisJICovCiAJYXJjX3AgPSAoYXJjX2MgPj4gMSk7CiAJYXJj
 X3NpemUgPSAwOwogCisJcHJpbnRmKCJBUkNJIDAxMCBhcmNfY19taW4gJSIgUFJJdTY0ICJcbiIs
 IGFyY19jX21pbik7CisJcHJpbnRmKCJBUkNJIDAxMCBhcmNfcCAgICAgJSIgUFJJdTY0ICJcbiIs
 IGFyY19wKTsKKwlwcmludGYoIkFSQ0kgMDEwIGFyY19jICAgICAlIiBQUkl1NjQgIlxuIiwgYXJj
 X2MpOworCXByaW50ZigiQVJDSSAwMTAgYXJjX2NfbWF4ICUiIFBSSXU2NCAiXG4iLCBhcmNfY19t
 YXgpOworCiAJLyogbGltaXQgbWV0YS1kYXRhIHRvIDEvNCBvZiB0aGUgYXJjIGNhcGFjaXR5ICov
 CiAJYXJjX21ldGFfbGltaXQgPSBhcmNfY19tYXggLyA0OwogCkBAIC02MTM1LDkgKzYyMTgsMjMg
 QEAKIAlpZiAoemZzX2FyY19tZXRhX2xpbWl0ID4gMCAmJiB6ZnNfYXJjX21ldGFfbGltaXQgPD0g
 YXJjX2NfbWF4KQogCQlhcmNfbWV0YV9saW1pdCA9IHpmc19hcmNfbWV0YV9saW1pdDsKIAorCS8q
 cHJpbnRmKCJBUkNJIDAxMSBhcmNfbWV0YV9saW1pdCAlIiBQUkl1NjQgIlxuIiwgYXJjX21ldGFf
 bGltaXQpOyovCisKKyNpZiBkZWZpbmVkKF9fTmV0QlNEX18pCisJLyoKKwkgKiBYWFggRXhwbGFp
 biB3aHkgdGhpcyBpcyByZWFzb25hYmxlOyBpdCBhcHBlYXJzIHRvIHByb3RlY3QKKwkgKiB0aGUg
 Y2FjaGUgZnJvbSBnb2luZyBiZWxvdyBoYWxmIHRoZSBtYXggYWxsb3dlZCBhbW91bnQgb2YKKwkg
 KiBtZXRhZGF0YSwgYW5kIHRoYXQgaXMgbm90IG9idmlvdXNseSBzZW5zaWJsZS4KKwkgKi8KKyNl
 bHNlCiAJaWYgKGFyY19jX21pbiA8IGFyY19tZXRhX2xpbWl0IC8gMiAmJiB6ZnNfYXJjX21pbiA9
 PSAwKQogCQlhcmNfY19taW4gPSBhcmNfbWV0YV9saW1pdCAvIDI7CisjZW5kaWYKIAorCS8qCisJ
 ICogUmVzcGVjdCB0dW5hYmxlLCBhbmQgZGVmYXVsdCBtZXRhIG1pbmltdW0gdG8gaGFsZiB0aGUK
 KwkgKiBvdmVyYWxsIG1pbmltdW0uCisJICovCiAJaWYgKHpmc19hcmNfbWV0YV9taW4gPiAwKSB7
 CiAJCWFyY19tZXRhX21pbiA9IHpmc19hcmNfbWV0YV9taW47CiAJfSBlbHNlIHsKQEAgLTYxNjMs
 NiArNjI2MCw3IEBACiAJCXpmc19hcmNfbnVtX3N1Ymxpc3RzX3Blcl9zdGF0ZSA9IE1BWChtYXhf
 bmNwdXMsIDEpOwogCiAJLyogaWYga21lbV9mbGFncyBhcmUgc2V0LCBsZXRzIHRyeSB0byB1c2Ug
 bGVzcyBtZW1vcnkgKi8KKwkvKiBYWFggU2hvdWxkIHRoaXMgY2hhbmdlIGFyY19jX21heD8gIEV4
 cGxhaW4geWVzL25vLiAqLwogCWlmIChrbWVtX2RlYnVnZ2luZygpKQogCQlhcmNfYyA9IGFyY19j
 IC8gMjsKIAlpZiAoYXJjX2MgPCBhcmNfY19taW4pCkBAIC02MTcwLDYgKzYyNjgsNyBAQAogCiAJ
 emZzX2FyY19taW4gPSBhcmNfY19taW47CiAJemZzX2FyY19tYXggPSBhcmNfY19tYXg7CisJLyog
 V2h5IGFyZSB6ZnNfYXJjX21ldGFfbGltaXQgYW5kIHpmc19hcmNfbWV0YV9taW4gbm90IHdyaXR0
 ZW4/ICovCiAKIAlhcmNfc3RhdGVfaW5pdCgpOwogCWJ1Zl9pbml0KCk7CkBAIC02MjE5LDYgKzYz
 MTgsMTIgQEAKIAkJICAgIHpmc19kaXJ0eV9kYXRhX21heF9tYXgpOwogCX0KIAorI2lmIGRlZmlu
 ZWQoX19OZXRCU0RfXykKKwkvKgorCSAqIFhYWCBEaXNhYmxlIHByZWZldGNoIGlmIFJBTSBpcyBs
 b3cuCisJICovCisjZW5kaWYKKwogI2lmZGVmIF9LRVJORUwKICNpZmRlZiBfX0ZyZWVCU0RfXwog
 CWlmIChUVU5BQkxFX0lOVF9GRVRDSCgidmZzLnpmcy5wcmVmZXRjaF9kaXNhYmxlIiwgJnpmc19w
 cmVmZXRjaF9kaXNhYmxlKSkK


 --=-MbbHCv8L/rRh9t16a8LQ--

From: lenzi himself <nervoso@k1.com.br>
To: gnats-bugs@netbsd.org, mlelstv@netbsd.org, kern-bug-people@netbsd.org,
        netbsd-bugs@netbsd.org, gnats-admin@netbsd.org, riastradh@NetBSD.org
Cc: 
Subject: Re: kern/60286 (zfs sparse zvol reports wrong volume size)
Date: Fri, 22 May 2026 15:03:58 -0300

 --=-uA9EvUJxW/yJXC2bR53D
 Content-Type: text/plain; charset="UTF-8"
 Content-Transfer-Encoding: quoted-printable

 Em sex, 2026-05-22 =C3=A0s 16:47 +0000, riastradh@NetBSD.org escreveu:
 > Synopsis: zfs sparse zvol reports wrong volume size
 >=20
 > Responsible-Changed-From-To: kern-bug-people->mlelstv
 > Responsible-Changed-By: riastradh@NetBSD.org
 > Responsible-Changed-When: Fri, 22 May 2026 16:47:19 +0000
 > Responsible-Changed-Why:
 > Can you take a look?  Looks like you added the original dkw_size =3D
 > dg_secperunit assignment.
 >=20
 >=20
 >=20
 this is the patch... for me it looks like it removes the dkw->dwk_size =C2=
 =A0and recompute it with new value... 6 lines
 later...
 Unless the code I put on the bug report is messed I think this is correct


 17 --- usr/src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c.orig 2026-=
 05-22 11:10:15.900492779 -0300
 18 +++ usr/src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c 2026-05-22=
  11:10:28.101264922 -0300
 19 @@ -3621,7 +3621,13 @@
 20 strlcpy(dkw->dkw_parent, "ZFS", sizeof(dkw->dkw_parent));
 21
 22 dkw->dkw_offset =3D 0;
 23 - dkw->dkw_size =3D dg->dg_secperunit;
 24 + /*
 25 + * dkw_size is in DEV_BSIZE (512) blocks, but dg_secperunit
 26 + * counts in dg_secsize blocks (which may be 4096 or larger
 27 + * depending on the pool's ashift). Convert to DEV_BSIZE.
 28 + */
 29 + dkw->dkw_size =3D dg->dg_secperunit *
 30 + (dg->dg_secsize / DEV_BSIZE);
 31 strcpy(dkw->dkw_ptype, DKW_PTYPE_FFS);

 --=-uA9EvUJxW/yJXC2bR53D
 Content-Type: text/html; charset="utf-8"
 Content-Transfer-Encoding: quoted-printable

 <html><head><style>pre,code,address {
   margin: 0px;
 }
 h1,h2,h3,h4,h5,h6 {
   margin-top: 0.2em;
   margin-bottom: 0.2em;
 }
 ol,ul {
   margin-top: 0em;
   margin-bottom: 0em;
 }
 blockquote {
   margin-top: 0em;
   margin-bottom: 0em;
 }
 </style></head><body><div>Em sex, 2026-05-22 =C3=A0s 16:47 +0000, riastradh=
 @NetBSD.org escreveu:</div><blockquote type=3D"cite" style=3D"margin:0 0 0 =
 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pre>Synopsis: zfs sp=
 arse zvol reports wrong volume size</pre><pre><br></pre><pre>Responsible-Ch=
 anged-From-To: kern-bug-people-&gt;mlelstv</pre><pre>Responsible-Changed-By=
 : <a href=3D"mailto:riastradh@NetBSD.org">riastradh@NetBSD.org</a></pre><pr=
 e>Responsible-Changed-When: Fri, 22 May 2026 16:47:19 +0000</pre><pre>Respo=
 nsible-Changed-Why:</pre><pre>Can you take a look?  Looks like you added th=
 e original dkw_size =3D</pre><pre>dg_secperunit assignment.</pre><pre><br><=
 /pre><pre><br></pre><pre><br></pre></blockquote><div>this is the patch... f=
 or me it looks like it removes the dkw-&gt;dwk_size &nbsp;and recompute it =
 with new value... 6 lines later...</div><div>Unless the code I put on the b=
 ug report is messed I think this is correct</div><div><br></div><div><br></=
 div><div>     17 --- usr/src/external/cddl/osnet/dist/uts/common/fs/zfs/zvo=
 l.c.orig      2026-05-22 11:10:15.900492779 -0300</div><div>     18 +++ usr=
 /src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c   2026-05-22 11:10:2=
 8.101264922 -0300</div><div>     19 @@ -3621,7 +3621,13 @@</div><div>     2=
 0                 strlcpy(dkw-&gt;dkw_parent, "ZFS", sizeof(dkw-&gt;dkw_par=
 ent));</div><div>     21</div><div>     22                 dkw-&gt;dkw_offs=
 et =3D 0;</div><div>     23 -               dkw-&gt;dkw_size =3D dg-&gt;dg_=
 secperunit;</div><div>     24 +               /*</div><div>     25 +       =
          * dkw_size is in DEV_BSIZE (512) blocks, but dg_secperunit</div><d=
 iv>     26 +                * counts in dg_secsize blocks (which may be 409=
 6 or larger</div><div>     27 +                * depending on the pool's as=
 hift).  Convert to DEV_BSIZE.</div><div>     28 +                */</div><d=
 iv>     29 +               dkw-&gt;dkw_size =3D dg-&gt;dg_secperunit *</div=
 ><div>     30 +                   (dg-&gt;dg_secsize / DEV_BSIZE);</div><di=
 v>     31                 strcpy(dkw-&gt;dkw_ptype, DKW_PTYPE_FFS);</div><d=
 iv><br></div><div><span></span></div></body></html>

 --=-uA9EvUJxW/yJXC2bR53D--

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/60286: zfs sparse zvol reports wrong volume size
Date: Fri, 22 May 2026 21:56:25 -0000 (UTC)

 gnats-admin@NetBSD.org ("nervoso@k1.com.br via gnats") writes:

 ># Bug: dkw_size in DIOCGWEDGEINFO is set from dg_secperunit, which counts
 ># sectors in dg_secsize units (typically 4096 bytes when spa_max_ashift=12).
 ># However, dkw_size is defined as "size of wedge in blocks" where blocks
 ># are DEV_BSIZE (512 bytes).

 DIOCGWEDGEINFO uses the sector size as units for dkw_offset
 and dkw_size. You need to query the sector size of the wedge
 parent device to get information in bytes.


 Have a look at what the dk driver does. Internally it
 stores the data that you can read as dkw_offset/dkw_size
 as sc_offset/sc_size (dkwedge_size reads the value with locking).

         p_offset = sc->sc_offset << sc->sc_parent->dk_blkshift;
         p_size = dkwedge_size(sc) << sc->sc_parent->dk_blkshift;

 -> the data is transformed into DEV_BSIZE coordinates by adjusting
    them with dk_blkshift of the parent device. dk_blkshift is how
    many bits you need to shift left to get to DEV_BSIZE units, a
    disk with 4k sectors would have a dk_blkshift value of 12-9 = 3.

         /* Make sure it's in-range. */
         if (bounds_check_with_mediasize(bp, DEV_BSIZE, p_size) <= 0)
                 goto done;

 -> Now the DEV_BSIZE units are validated

         /* Translate it to the parent's raw LBA. */
         bp->b_rawblkno = bp->b_blkno + p_offset;

 -> And the actual block inside the wedge is addressed.


 >  QEMU and other userland tools read dkw_size

 There are surely programs that do things incorrectly. And
 yes, I just looked at qemu, it's also doing things wrong
 by multipling dkw_size with a constant 512.

 A zvol of 1G returns:

 #zfs list
 NAME         USED  AVAIL  REFER  MOUNTPOINT
 tank        3.45T  10.6T  2.16T  /tank
 tank/myvol  1.03G  10.6T    56K  -

 #dkctl /dev/zvol/rdsk/tank/myvol getwedgeinfo
 tank/myvol at ZFS: 
 tank/myvol: 262144 blocks at 0, type: ffs

 #dkctl /dev/zvol/rdsk/tank/myvol getgeometry
 /dev/zvol/rdsk/tank/myvol: 1073741824 bytes in 262144 blocks of 4096 bytes

State-Changed-From-To: open->analyzed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Sat, 23 May 2026 23:13:58 +0000
State-Changed-Why:
Underlying problem has been analyzed, and I see a _lot_ of places
that might need some changes here:
1. documentation -- no man page describes this structure;
2. sys/disk.h -- comments are not clear on what the units mean
3. pkgsrc emulators/qemu -- needs patch to use right units,
4. lib/librumpuser/rumpuser_file.c -- dkw.dkw_size << DEV_BSHIFT
5. sbin/blkdiscard/blkdiscard.c -- dkw.dkw_size * DEV_BSIZE
6. dozens of other references that might be issues, found at
   https://nxr.netbsd.org/search?q=dkw_size&project=src


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.