Module Name: src
Committed By: mlelstv
Date: Sat Feb 29 17:03:33 UTC 2020
Modified Files:
src/external/cddl/osnet/dist/uts/common/fs/zfs: zvol.c
Log Message:
Fix disk geometry calculation. Add DIOCGPARTINFO to support
getdisksize() used by other drivers, filesystems and specfs.
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 \
src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.12 src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.13
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.12 Wed May 22 08:47:02 2019
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c Sat Feb 29 17:03:33 2020
@@ -72,6 +72,9 @@
#include <sys/dnode.h>
#include <sys/dsl_dataset.h>
#include <sys/dsl_prop.h>
+#ifdef __NetBSD__
+#include <sys/disklabel.h>
+#endif
#include <sys/dkio.h>
#include <sys/byteorder.h>
#include <sys/sunddi.h>
@@ -316,12 +319,17 @@ zvol_size_changed(zvol_state_t *zv, uint
#endif /* __FreeBSD__ */
#ifdef __NetBSD__
struct disk_geom *dg = &zv->zv_dk.dk_geom;
+ objset_t *os = zv->zv_objset;
+ spa_t *spa = dmu_objset_spa(os);
+ unsigned secsize;
zv->zv_volsize = volsize;
+ secsize = MAX(DEV_BSIZE, 1U << spa->spa_max_ashift);
+
memset(dg, 0, sizeof(*dg));
- dg->dg_secsize = DEV_BSIZE; /* XXX 512? */
- dg->dg_secperunit = zv->zv_volsize / dg->dg_secsize;;
+ dg->dg_secsize = secsize;
+ dg->dg_secperunit = volsize / secsize;
disk_set_info(NULL, &zv->zv_dk, "ZVOL");
#endif
}
@@ -3589,19 +3597,47 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t
case DIOCGWEDGEINFO:
{
struct dkwedge_info *dkw = (void *) arg;
-
+ struct disk_geom *dg = &zv->zv_dk.dk_geom;
+
memset(dkw, 0, sizeof(*dkw));
strlcpy(dkw->dkw_devname, zv->zv_name,
sizeof(dkw->dkw_devname));
+
+ /*
+ * dkw_parent is interpreted as disk device name by the kernel
+ * to locate the disk driver and its geometry data. The faked
+ * name "ZFS" must never match a device name. The kernel will
+ * then call DIOCGPARTINFO below to retrieve the missing
+ * information.
+ *
+ * Userland will also be confused, but it can use the
+ * proplib based DIOCGDISKINFO to get the geometry
+ * information.
+ */
strlcpy(dkw->dkw_parent, "ZFS", sizeof(dkw->dkw_parent));
-
+
dkw->dkw_offset = 0;
- dkw->dkw_size = zv->zv_volsize / DEV_BSIZE;
+ dkw->dkw_size = dg->dg_secperunit;
strcpy(dkw->dkw_ptype, DKW_PTYPE_FFS);
break;
}
+ case DIOCGPARTINFO:
+ {
+ struct partinfo *pi = (void *) arg;
+ struct disk_geom *dg = &zv->zv_dk.dk_geom;
+
+ memset(pi, 0, sizeof(*pi));
+ pi->pi_offset = 0;
+ pi->pi_secsize = dg->dg_secsize;
+ pi->pi_size = dg->dg_secperunit;
+ pi->pi_fstype = FS_OTHER;
+ pi->pi_bsize = MAX(BLKDEV_IOSIZE, pi->pi_secsize);
+
+ break;
+ }
+
default:
dprintf("unknown disk_ioctl called\n");
error = ENOTTY;