Index: compat/linux/common/linux_blkio.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_blkio.c,v retrieving revision 1.17 diff -u -u -r1.17 linux_blkio.c --- compat/linux/common/linux_blkio.c 21 Mar 2008 21:54:58 -0000 1.17 +++ compat/linux/common/linux_blkio.c 8 Dec 2015 19:04:10 -0000 @@ -68,7 +68,7 @@ int error; file_t *fp; int (*ioctlf)(file_t *, u_long, void *); - struct partinfo partp; + struct partinfo pi; struct disklabel label; if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) @@ -85,7 +85,7 @@ * fails, it may be a disk without label; try to get * the default label and compute the size from it. */ - error = ioctlf(fp, DIOCGPART, &partp); + error = ioctlf(fp, DIOCGPART, &pi); if (error != 0) { error = ioctlf(fp, DIOCGDEFLABEL, &label); if (error != 0) @@ -93,7 +93,7 @@ size = label.d_nsectors * label.d_ntracks * label.d_ncylinders; } else - size = partp.part->p_size; + size = pi.pi_size; error = copyout(&size, SCARG(uap, data), sizeof size); break; case LINUX_BLKSECTGET: Index: compat/linux/common/linux_hdio.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_hdio.c,v retrieving revision 1.16 diff -u -u -r1.16 linux_hdio.c --- compat/linux/common/linux_hdio.c 21 Mar 2008 21:54:58 -0000 1.16 +++ compat/linux/common/linux_hdio.c 8 Dec 2015 19:04:10 -0000 @@ -72,8 +72,8 @@ struct file *fp; int (*ioctlf)(struct file *, u_long, void *); struct atareq req; - struct disklabel label, *labp; - struct partinfo partp; + struct disklabel label; + struct partinfo pi; struct linux_hd_geometry hdg; struct linux_hd_big_geometry hdg_big; @@ -107,17 +107,16 @@ error = linux_machdepioctl(l, uap, retval); if (error == 0) break; - error = ioctlf(fp, DIOCGDEFLABEL, &label); - error1 = ioctlf(fp, DIOCGPART, &partp); + error = ioctlf(fp, DIOCGDINFO, &label); + error1 = ioctlf(fp, DIOCGPART, &pi); if (error != 0 && error1 != 0) { error = error1; break; } - labp = error != 0 ? &label : partp.disklab; - hdg.start = error1 != 0 ? partp.part->p_offset : 0; - hdg.heads = labp->d_ntracks; - hdg.cylinders = labp->d_ncylinders; - hdg.sectors = labp->d_nsectors; + hdg.start = error1 != 0 ? pi.pi_offset : 0; + hdg.heads = label.d_ntracks; + hdg.cylinders = label.d_ncylinders; + hdg.sectors = label.d_nsectors; error = copyout(&hdg, SCARG(uap, data), sizeof hdg); break; case LINUX_HDIO_GETGEO_BIG: @@ -125,17 +124,16 @@ if (error == 0) break; case LINUX_HDIO_GETGEO_BIG_RAW: - error = ioctlf(fp, DIOCGDEFLABEL, &label); - error1 = ioctlf(fp, DIOCGPART, &partp); + error = ioctlf(fp, DIOCGDINFO, &label); + error1 = ioctlf(fp, DIOCGPART, &pi); if (error != 0 && error1 != 0) { error = error1; break; } - labp = error != 0 ? &label : partp.disklab; - hdg_big.start = error1 != 0 ? partp.part->p_offset : 0; - hdg_big.heads = labp->d_ntracks; - hdg_big.cylinders = labp->d_ncylinders; - hdg_big.sectors = labp->d_nsectors; + hdg_big.start = error1 != 0 ? pi.pi_offset : 0; + hdg_big.heads = label.d_ntracks; + hdg_big.cylinders = label.d_ncylinders; + hdg_big.sectors = label.d_nsectors; error = copyout(&hdg_big, SCARG(uap, data), sizeof hdg_big); break; case LINUX_HDIO_GET_UNMASKINTR: Index: compat/netbsd32/netbsd32_ioctl.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_ioctl.c,v retrieving revision 1.82 diff -u -u -r1.82 netbsd32_ioctl.c --- compat/netbsd32/netbsd32_ioctl.c 2 Aug 2015 07:37:57 -0000 1.82 +++ compat/netbsd32/netbsd32_ioctl.c 8 Dec 2015 19:04:10 -0000 @@ -87,14 +87,6 @@ /* convert to/from different structures */ -static inline void -netbsd32_to_partinfo(struct netbsd32_partinfo *s32p, struct partinfo *p, u_long cmd) -{ - - p->disklab = (struct disklabel *)NETBSD32PTR64(s32p->disklab); - p->part = (struct partition *)NETBSD32PTR64(s32p->part); -} - #if 0 static inline void netbsd32_to_format_op(struct netbsd32_format_op *s32p, struct format_op *p, u_long cmd) @@ -487,14 +479,6 @@ * handle ioctl conversions from 64-bit kernel -> netbsd32 */ -static inline void -netbsd32_from_partinfo(struct partinfo *p, struct netbsd32_partinfo *s32p, u_long cmd) -{ - - NETBSD32PTR32(s32p->disklab, p->disklab); - NETBSD32PTR32(s32p->part, p->part); -} - #if 0 static inline void netbsd32_from_format_op(struct format_op *p, struct netbsd32_format_op *s32p, u_long cmd) @@ -1066,8 +1050,6 @@ case AUDIO_WSEEK32: IOCTL_CONV_TO(AUDIO_WSEEK, u_long); - case DIOCGPART32: - IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo); #if 0 /* not implemented by anything */ case DIOCRFORMAT32: IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op); Index: compat/netbsd32/netbsd32_ioctl.h =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_ioctl.h,v retrieving revision 1.52 diff -u -u -r1.52 netbsd32_ioctl.h --- compat/netbsd32/netbsd32_ioctl.h 1 Jun 2015 16:07:27 -0000 1.52 +++ compat/netbsd32/netbsd32_ioctl.h 8 Dec 2015 19:04:10 -0000 @@ -71,13 +71,6 @@ /* from <sys/dkio.h> */ typedef netbsd32_pointer_t netbsd32_disklabel_tp_t; typedef netbsd32_pointer_t netbsd32_partition_tp_t; -struct netbsd32_partinfo { - netbsd32_disklabel_tp_t disklab; - netbsd32_partition_tp_t part; -}; -#if 1 -#define DIOCGPART32 _IOW('d', 104, struct netbsd32_partinfo) /* get partition */ -#endif #if 0 /* not implemented by anything */ struct netbsd32_format_op { Index: dev/pud/pud_dev.c =================================================================== RCS file: /cvsroot/src/sys/dev/pud/pud_dev.c,v retrieving revision 1.6 diff -u -u -r1.6 pud_dev.c --- dev/pud/pud_dev.c 22 Dec 2009 17:32:03 -0000 1.6 +++ dev/pud/pud_dev.c 8 Dec 2015 19:04:18 -0000 @@ -58,36 +58,13 @@ } #include <sys/disklabel.h> -/* - * XXX: this is not "reentrant". But then again, partinfo isn't - * exactly safe in any case. - */ -static struct disklabel dl_partinfo; - static int doioctl(dev_t dev, u_long cmd, void *data, int flag, int class, int type) { struct pud_req_ioctl *pc_ioctl; size_t dlen, allocsize; - u_long origcmd = cmd; - void *origdata = NULL; /* XXXgcc */ int error; - /* - * XXX: kludge. This is a horrible abstraction violation, but - * then again DIOCGPART is a horrible ioctl (even more horrible - * than the generic ioctl). We handle it specially here since - * the server in userspace has no chance to handle it. And it's - * a common operation used by most file systems. But really, it - * should be replaced by something a bit more ... transactional. - */ - if (cmd == DIOCGPART) { - cmd = DIOCGDINFO; - origdata = data; - flag = 0; - data = &dl_partinfo; - } - dlen = IOCPARM_LEN(cmd); allocsize = sizeof(struct pud_req_ioctl) + dlen; pc_ioctl = kmem_zalloc(allocsize, KM_SLEEP); @@ -103,39 +80,6 @@ if (cmd & IOC_OUT) memcpy(data, pc_ioctl->pm_data, dlen); - /* - * In case doing the infamous DIOCGPART, issue the real - * ioctl and do pointer arithmetic to figure out the right - * partition. We could use DISKPART() too, but this seems - * "better". - */ - if (origcmd == DIOCGPART) { - struct partinfo *pi, *pi_user; - int labidx; - - CTASSERT(sizeof(struct partinfo) <= sizeof(struct disklabel)); - - pc_ioctl->pm_iocmd = DIOCGPART; - pc_ioctl->pm_flag = 0; - - error = pud_request(dev, pc_ioctl, allocsize, class, type); - if (error) - goto out; - - pi_user = (struct partinfo *)pc_ioctl->pm_data; - labidx = pi_user->part - &pi_user->disklab->d_partitions[0]; - /* userspace error, but punish caller, since we have no infra */ - if (labidx >= MAXPARTITIONS) { - error = E2BIG; - goto out; - } - - pi = origdata; - pi->disklab = &dl_partinfo; - pi->part = &dl_partinfo.d_partitions[labidx]; - - } - out: kmem_free(pc_ioctl, allocsize); return error; Index: kern/init_main.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_main.c,v retrieving revision 1.476 diff -u -u -r1.476 init_main.c --- kern/init_main.c 7 Dec 2015 11:38:46 -0000 1.476 +++ kern/init_main.c 8 Dec 2015 19:04:28 -0000 @@ -794,7 +794,7 @@ static void rootconf_handle_wedges(void) { - struct partinfo dpart; + struct disklabel label; struct partition *p; struct vnode *vp; daddr_t startblk; @@ -827,7 +827,7 @@ if (vp == NULL) return; - error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED); + error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED); VOP_CLOSE(vp, FREAD, NOCRED); vput(vp); if (error) @@ -836,7 +836,7 @@ KASSERT(booted_partition >= 0 && booted_partition < MAXPARTITIONS); - p = &dpart.disklab->d_partitions[booted_partition]; + p = &label.d_partitions[booted_partition]; dev = booted_device; startblk = p->p_offset; Index: kern/subr_disk.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_disk.c,v retrieving revision 1.114 diff -u -u -r1.114 subr_disk.c --- kern/subr_disk.c 28 Nov 2015 14:36:00 -0000 1.114 +++ kern/subr_disk.c 8 Dec 2015 19:04:28 -0000 @@ -502,7 +502,8 @@ struct lwp *l) { struct dkwedge_info *dkw; - struct partinfo *pt; + struct partinfo *pi; + struct partition *dp; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif @@ -531,11 +532,15 @@ /* The following should be moved to dk_ioctl */ switch (cmd) { case DIOCGDINFO: + if (dk->dk_label == NULL) + return EBUSY; memcpy(data, dk->dk_label, sizeof (*dk->dk_label)); return 0; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDINFO: + if (dk->dk_label == NULL) + return EBUSY; memcpy(&newlabel, dk->dk_label, sizeof(newlabel)); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; @@ -544,11 +549,45 @@ #endif case DIOCGPART: + pi = data; + memset(pi, 0, sizeof(*pi)); + pi->pi_secsize = dk->dk_geom.dg_secsize; + pi->pi_bsize = BLKDEV_IOSIZE; + + if (DISKPART(dev) == RAW_PART) { + pi->pi_size = dk->dk_geom.dg_secperunit; + return 0; + } + if (dk->dk_label == NULL) return EBUSY; - pt = data; - pt->disklab = dk->dk_label; - pt->part = &dk->dk_label->d_partitions[DISKPART(dev)]; + + dp = &dk->dk_label->d_partitions[DISKPART(dev)]; + pi->pi_offset = dp->p_offset; + pi->pi_size = dp->p_size; + + pi->pi_fstype = dp->p_fstype; + pi->pi_frag = dp->p_frag; + pi->pi_fsize = dp->p_fsize; + pi->pi_cpg = dp->p_cpg; + + /* + * dholland 20130616: XXX this logic should not be + * here. It is here because the old buffer cache + * demands that all accesses to the same blocks need + * to be the same size; but it only works for FFS and + * nowadays I think it'll fail silently if the size + * info in the disklabel is wrong. (Or missing.) The + * buffer cache needs to be smarter; or failing that + * we need a reliable way here to get the right block + * size; or a reliable way to guarantee that (a) the + * fs is not mounted when we get here and (b) any + * buffers generated here will get purged when the fs + * does get mounted. + */ + if (dp->p_fstype == FS_BSDFFS && + dp->p_frag != 0 && dp->p_fsize != 0) + pi->pi_bsize = dp->p_frag * dp->p_fsize; return 0; case DIOCAWEDGE: Index: kern/subr_disk_open.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_disk_open.c,v retrieving revision 1.12 diff -u -u -r1.12 subr_disk_open.c --- kern/subr_disk_open.c 31 Dec 2014 19:50:14 -0000 1.12 +++ kern/subr_disk_open.c 8 Dec 2015 19:04:28 -0000 @@ -91,7 +91,7 @@ int getdisksize(struct vnode *vp, uint64_t *numsecp, unsigned int *secsizep) { - struct partinfo dpart; + struct partinfo pi; struct dkwedge_info dkw; struct disk *pdk; unsigned int secsize; @@ -113,10 +113,10 @@ } if (error) { - error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED); + error = VOP_IOCTL(vp, DIOCGPART, &pi, FREAD, NOCRED); if (error == 0) { - secsize = dpart.disklab->d_secsize; - numsec = dpart.part->p_size; + secsize = pi.pi_secsize; + numsec = pi.pi_size; } } @@ -143,14 +143,14 @@ int getdiskinfo(struct vnode *vp, struct dkwedge_info *dkw) { - struct partinfo dpart; + struct partinfo pi; int error; dev_t dev = vp->v_specnode->sn_rdev; if (VOP_IOCTL(vp, DIOCGWEDGEINFO, dkw, FREAD, NOCRED) == 0) return 0; - if ((error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED)) != 0) + if ((error = VOP_IOCTL(vp, DIOCGPART, &pi, FREAD, NOCRED)) != 0) return error; snprintf(dkw->dkw_devname, sizeof(dkw->dkw_devname), "%s%" PRId32 "%c", @@ -161,10 +161,9 @@ strlcpy(dkw->dkw_parent, dkw->dkw_devname, sizeof(dkw->dkw_parent)); - dkw->dkw_size = dpart.part->p_size; - dkw->dkw_offset = dpart.part->p_offset; - - strlcpy(dkw->dkw_ptype, getfstypename(dpart.part->p_fstype), + dkw->dkw_size = pi.pi_size; + dkw->dkw_offset = pi.pi_offset; + strlcpy(dkw->dkw_ptype, getfstypename(pi.pi_fstype), sizeof(dkw->dkw_ptype)); return 0; Index: miscfs/specfs/spec_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v retrieving revision 1.156 diff -u -u -r1.156 spec_vnops.c --- miscfs/specfs/spec_vnops.c 8 Dec 2015 01:57:13 -0000 1.156 +++ miscfs/specfs/spec_vnops.c 8 Dec 2015 19:04:29 -0000 @@ -502,9 +502,9 @@ specnode_t *sn; specdev_t *sd; spec_ioctl_t ioctl; - off_t off; u_int gen; const char *name; + struct partinfo pi; l = curlwp; vp = ap->a_vp; @@ -660,29 +660,9 @@ ioctl = vp->v_type == VCHR ? cdev_ioctl : bdev_ioctl; - - // XXX: DIOCGPART is not 64 bit friendly so we avoid it fot the - // raw partition - if (DISKPART(vp->v_rdev) == RAW_PART) - error = (*ioctl)(vp->v_rdev, DIOCGMEDIASIZE, - &off, FREAD, curlwp); - else - error = EINVAL; - if (error) { - struct partinfo pi; - error = (*ioctl)(vp->v_rdev, DIOCGPART, &pi, FREAD, curlwp); - if (error == 0) { - off = (off_t)pi.disklab->d_secsize * pi.part->p_size; -#ifdef DIAGNOSTIC - if (pi.disklab->d_secsize == UINT_MAX) - printf("overflow in DIOCGPART dev=%jx\n", - (uintmax_t)vp->v_rdev); -#endif - } - } - + error = (*ioctl)(vp->v_rdev, DIOCGPART, &pi, FREAD, curlwp); if (error == 0) - uvm_vnp_setsize(vp, (voff_t)off); + uvm_vnp_setsize(vp, (voff_t)pi.pi_secsize * pi.pi_size); return 0; } @@ -706,7 +686,7 @@ struct buf *bp; daddr_t bn; int bsize, bscale; - struct partinfo dpart; + struct partinfo pi; int n, on; int error = 0; @@ -732,28 +712,11 @@ KASSERT(vp == vp->v_specnode->sn_dev->sd_bdevvp); if (uio->uio_offset < 0) return (EINVAL); - bsize = BLKDEV_IOSIZE; - /* - * dholland 20130616: XXX this logic should not be - * here. It is here because the old buffer cache - * demands that all accesses to the same blocks need - * to be the same size; but it only works for FFS and - * nowadays I think it'll fail silently if the size - * info in the disklabel is wrong. (Or missing.) The - * buffer cache needs to be smarter; or failing that - * we need a reliable way here to get the right block - * size; or a reliable way to guarantee that (a) the - * fs is not mounted when we get here and (b) any - * buffers generated here will get purged when the fs - * does get mounted. - */ - if (bdev_ioctl(vp->v_rdev, DIOCGPART, &dpart, FREAD, l) == 0) { - if (dpart.part->p_fstype == FS_BSDFFS && - dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) - bsize = dpart.part->p_frag * - dpart.part->p_fsize; - } + if (bdev_ioctl(vp->v_rdev, DIOCGPART, &pi, FREAD, l) == 0) + bsize = pi.pi_bsize; + else + bsize = BLKDEV_IOSIZE; bscale = bsize >> DEV_BSHIFT; do { @@ -795,7 +758,7 @@ struct buf *bp; daddr_t bn; int bsize, bscale; - struct partinfo dpart; + struct partinfo pi; int n, on; int error = 0; @@ -821,13 +784,12 @@ return (0); if (uio->uio_offset < 0) return (EINVAL); - bsize = BLKDEV_IOSIZE; - if (bdev_ioctl(vp->v_rdev, DIOCGPART, &dpart, FREAD, l) == 0) { - if (dpart.part->p_fstype == FS_BSDFFS && - dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) - bsize = dpart.part->p_frag * - dpart.part->p_fsize; - } + + if (bdev_ioctl(vp->v_rdev, DIOCGPART, &pi, FREAD, l) == 0) + bsize = pi.pi_bsize; + else + bsize = BLKDEV_IOSIZE; + bscale = bsize >> DEV_BSHIFT; do { bn = (uio->uio_offset >> DEV_BSHIFT) &~ (bscale - 1); Index: rump/librump/rumpvfs/rumpblk.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpblk.c,v retrieving revision 1.60 diff -u -u -r1.60 rumpblk.c --- rump/librump/rumpvfs/rumpblk.c 26 May 2015 16:48:05 -0000 1.60 +++ rump/librump/rumpvfs/rumpblk.c 8 Dec 2015 19:04:49 -0000 @@ -421,6 +421,7 @@ devminor_t dmin = minor(dev); struct rblkdev *rblk = &minors[dmin]; struct partinfo *pi; + struct diskpart *dp; int error = 0; /* well, me should support a few more, but we don't for now */ @@ -430,9 +431,16 @@ break; case DIOCGPART: + dp = &rblk->rblk_label.d_partitions[DISKPART(dmin)]; pi = addr; - pi->part = &rblk->rblk_label.d_partitions[DISKPART(dmin)]; - pi->disklab = &rblk->rblk_label; + pi->pi_offset = dp->p_offset; + pi->pi_size = dp->p_size; + pi->pi_secsize = rblk->rblk_label.d_secsize; + pi->pi_bsize = BLKDEV_IOSIZE; + pi->pi_fstype = dp->p_fstype; + pi->pi_fsize = dp->p_fsize; + pi->pi_frag = dp->p_frag; + pi->pi_cpg = dp->p_cpg; break; /* it's synced enough along the write path */ Index: sys/disklabel.h =================================================================== RCS file: /cvsroot/src/sys/sys/disklabel.h,v retrieving revision 1.118 diff -u -u -r1.118 disklabel.h --- sys/disklabel.h 2 Jan 2015 19:42:07 -0000 1.118 +++ sys/disklabel.h 8 Dec 2015 19:04:50 -0000 @@ -444,8 +444,14 @@ * on a disk. */ struct partinfo { - struct disklabel *disklab; - struct partition *part; + uint64_t pi_offset; + uint64_t pi_size; + uint32_t pi_secsize; + uint32_t pi_bsize; + uint8_t pi_fstype; + uint8_t pi_frag; + uint16_t pi_cpg; + uint32_t pi_fsize; }; struct disk; Index: sys/param.h =================================================================== RCS file: /cvsroot/src/sys/sys/param.h,v retrieving revision 1.488 diff -u -u -r1.488 param.h --- sys/param.h 30 Nov 2015 22:47:19 -0000 1.488 +++ sys/param.h 8 Dec 2015 19:04:50 -0000 @@ -67,7 +67,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 799002300 /* NetBSD 7.99.23 */ +#define __NetBSD_Version__ 799002400 /* NetBSD 7.99.24 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)