NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/60286: zfs sparse zvol reports wrong volume size
>Number: 60286
>Category: kern
>Synopsis: zfs sparse zvol reports wrong volume size
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri May 22 15:15:00 +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;
~
Home |
Main Index |
Thread Index |
Old Index