Index: sys/cam/ata/ata_da.c =================================================================== --- sys/cam/ata/ata_da.c +++ sys/cam/ata/ata_da.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #endif /* _KERNEL */ @@ -1758,15 +1759,18 @@ */ adasetflags(softc, cgd); + softc->disk = disk_alloc(); + /* Disable queue sorting for non-rotational media by default. */ if (cgd->ident_data.media_rotation_rate == ATA_RATE_NON_ROTATING) { + softc->disk->d_mediaword = _PC_MEDIA_SOLID | _PC_MEDIA_ATA; softc->rotating = 0; } else { + softc->disk->d_mediaword = _PC_MEDIA_SPINNING | _PC_MEDIA_ATA; softc->rotating = 1; } cam_iosched_set_sort_queue(softc->cam_iosched, softc->rotating ? -1 : 0); adagetparams(periph, cgd); - softc->disk = disk_alloc(); softc->disk->d_rotation_rate = cgd->ident_data.media_rotation_rate; softc->disk->d_devstat = devstat_new_entry(periph->periph_name, periph->unit_number, softc->params.secsize, Index: sys/cam/mmc/mmc_da.c =================================================================== --- sys/cam/mmc/mmc_da.c +++ sys/cam/mmc/mmc_da.c @@ -1410,6 +1410,7 @@ part->disk = disk_alloc(); part->disk->d_rotation_rate = DISK_RR_NON_ROTATING; + part->disk->d_mediaword = _PC_MEDIA_SOLID | _PC_MEDIA_MMCSD part->disk->d_devstat = devstat_new_entry(part->name, cnt, 512, DEVSTAT_ALL_SUPPORTED, Index: sys/cam/nvme/nvme_da.c =================================================================== --- sys/cam/nvme/nvme_da.c +++ sys/cam/nvme/nvme_da.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #endif /* _KERNEL */ @@ -764,6 +765,7 @@ strlcpy(softc->disk->d_ident, cd->sn, MIN(sizeof(softc->disk->d_ident), sizeof(cd->sn))); disk->d_rotation_rate = DISK_RR_NON_ROTATING; + disk->d_mediaword = _PC_MEDIA_SOLID | _PC_MEDIA_NVME; disk->d_open = ndaopen; disk->d_close = ndaclose; disk->d_strategy = ndastrategy; Index: sys/cam/scsi/scsi_cd.c =================================================================== --- sys/cam/scsi/scsi_cd.c +++ sys/cam/scsi/scsi_cd.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -651,6 +652,7 @@ softc->disk->d_gone = cddiskgonecb; softc->disk->d_ioctl = cdioctl; softc->disk->d_name = "cd"; + softc->disk->d_mediaword = _PC_MEDIA_CDROM | _PC_MEDIA_SCSI; cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor, sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr)); strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr)); Index: sys/dev/md/md.c =================================================================== --- sys/dev/md/md.c +++ sys/dev/md/md.c @@ -91,7 +91,7 @@ #include #include #include -#include +#include #include #include @@ -1229,7 +1229,22 @@ error = -1; else if (g_handleattr_int(bp, "MNT::verified", isv)) error = -1; - else + else if (strcmp("GEOM::media", bp->bio_attribute) + == 0) { + switch (sc->type) { + case MD_MALLOC: + case MD_SWAP: + case MD_PRELOAD: + case MD_NULL: + atomic_set_long((long *)bp->bio_data, + _PC_MEDIA_MEMORY); + break; + case MD_VNODE: + error = VOP_PATHCONF(sc->vnode, + _PC_MEDIA, (long *)bp->bio_data); + break; + } + } else error = EOPNOTSUPP; } else { error = sc->start(sc, bp); Index: sys/dev/mmc/mmcsd.c =================================================================== --- sys/dev/mmc/mmcsd.c +++ sys/dev/mmc/mmcsd.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include @@ -561,6 +562,7 @@ strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr)); d->d_rotation_rate = DISK_RR_NON_ROTATING; + d->d_mediaword = _PC_MEDIA_SOLID | _PC_MEDIA_MMCSD; disk_create(d, DISK_VERSION); bioq_init(&part->bio_queue); Index: sys/dev/nvd/nvd.c =================================================================== --- sys/dev/nvd/nvd.c +++ sys/dev/nvd/nvd.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -333,6 +334,7 @@ if (disk->d_delmaxsize > nvd_delete_max) disk->d_delmaxsize = nvd_delete_max; disk->d_stripesize = nvme_ns_get_stripesize(ns); + disk->d_mediaword = _PC_MEDIA_SOLID | _PC_MEDIA_NVME; if (TAILQ_EMPTY(&disk_head)) disk->d_unit = 0; Index: sys/dev/virtio/block/virtio_blk.c =================================================================== --- sys/dev/virtio/block/virtio_blk.c +++ sys/dev/virtio/block/virtio_blk.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -678,6 +679,7 @@ dp->d_hba_device = virtio_get_device(dev); dp->d_hba_subvendor = virtio_get_subvendor(dev); dp->d_hba_subdevice = virtio_get_subdevice(dev); + dp->d_mediaword = _PC_MEDIA_VIRTUAL; if ((sc->vtblk_flags & VTBLK_FLAG_READONLY) == 0) dp->d_dump = vtblk_dump; Index: sys/dev/xen/blkfront/blkfront.c =================================================================== --- sys/dev/xen/blkfront/blkfront.c +++ sys/dev/xen/blkfront/blkfront.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -1029,7 +1030,7 @@ sc->xbd_disk->d_sectorsize = sector_size; sc->xbd_disk->d_stripesize = phys_sector_size; sc->xbd_disk->d_stripeoffset = 0; - + sc->xbd_disk->d_mediaword = _PC_MEDIA_VIRTUAL; sc->xbd_disk->d_mediasize = sectors * sector_size; sc->xbd_disk->d_maxsize = sc->xbd_max_request_size; sc->xbd_disk->d_flags = DISKFLAG_UNMAPPED_BIO; Index: sys/fs/tmpfs/tmpfs_vnops.c =================================================================== --- sys/fs/tmpfs/tmpfs_vnops.c +++ sys/fs/tmpfs/tmpfs_vnops.c @@ -1381,6 +1381,10 @@ *retval = 64; break; + case _PC_MEDIA: + *retval = _PC_MEDIA_MEMORY; + break; + default: error = vop_stdpathconf(v); } Index: sys/geom/geom_disk.h =================================================================== --- sys/geom/geom_disk.h +++ sys/geom/geom_disk.h @@ -103,6 +103,7 @@ disk_gone_t *d_gone; /* Info fields from driver to geom_disk.c. Valid when open */ + long d_mediaword; u_int d_sectorsize; off_t d_mediasize; u_int d_fwsectors; @@ -151,7 +152,8 @@ #define DISK_VERSION_03 0x5856105c #define DISK_VERSION_04 0x5856105d #define DISK_VERSION_05 0x5856105e -#define DISK_VERSION DISK_VERSION_05 +#define DISK_VERSION_06 0x5856105f +#define DISK_VERSION DISK_VERSION_06 #endif /* _KERNEL */ #endif /* _GEOM_GEOM_DISK_H_ */ Index: sys/geom/geom_disk.c =================================================================== --- sys/geom/geom_disk.c +++ sys/geom/geom_disk.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -525,7 +526,10 @@ g_disk_kerneldump(bp, dp); else if (!strcmp(bp->bio_attribute, "GEOM::setstate")) g_disk_setstate(bp, sc); - else if (g_handleattr_uint16_t(bp, "GEOM::rotation_rate", + else if (!strcmp(bp->bio_attribute, "GEOM::media")) { + atomic_set_long((long *)bp->bio_data, dp->d_mediaword); + g_io_deliver(bp, 0); + } else if (g_handleattr_uint16_t(bp, "GEOM::rotation_rate", dp->d_rotation_rate)) break; else Index: sys/geom/mirror/g_mirror.c =================================================================== --- sys/geom/mirror/g_mirror.c +++ sys/geom/mirror/g_mirror.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -1120,6 +1121,27 @@ } static void +g_mirror_media(struct bio *bp) +{ + struct g_mirror_softc *sc; + struct g_mirror_disk *disk; + struct bio *cbp; + + atomic_set_long((long *)bp->bio_data, _PC_MEDIA_MIRROR); + + sc = bp->bio_to->private; + LIST_FOREACH(disk, &sc->sc_disks, d_next) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + } +} + +static void g_mirror_start(struct bio *bp) { struct g_mirror_softc *sc; @@ -1146,6 +1168,9 @@ return; } else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { g_mirror_kernel_dump(bp); + return; + } else if (strcmp("GEOM::media", bp->bio_attribute) == 0) { + g_mirror_media(bp); return; } /* FALLTHROUGH */ Index: sys/geom/stripe/g_stripe.c =================================================================== --- sys/geom/stripe/g_stripe.c +++ sys/geom/stripe/g_stripe.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -569,6 +570,27 @@ } static void +g_stripe_media(struct bio *bp) +{ + struct g_stripe_softc *sc; + struct bio *cbp; + u_int no; + + atomic_set_long((long *)bp->bio_data, _PC_MEDIA_STRIPE); + + sc = bp->bio_to->geom->softc; + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, sc->sc_disks[no]); + } +} + +static void g_stripe_start(struct bio *bp) { off_t offset, start, length, nstripe; @@ -596,6 +618,10 @@ g_stripe_flush(sc, bp); return; case BIO_GETATTR: + if (strcmp("GEOM::media", bp->bio_attribute) == 0) { + g_stripe_media(bp); + return; + } /* To which provider it should be delivered? */ default: g_io_deliver(bp, EOPNOTSUPP); Index: sys/sys/unistd.h =================================================================== --- sys/sys/unistd.h +++ sys/sys/unistd.h @@ -156,6 +156,21 @@ #define _PC_INF_PRESENT 62 #define _PC_MAC_PRESENT 63 #define _PC_ACL_NFS4 64 +#define _PC_MEDIA 65 + +/* Value bits for _PC_MEDIA */ +#define _PC_MEDIA_SPINNING 0x00000001 +#define _PC_MEDIA_SOLID 0x00000002 +#define _PC_MEDIA_VIRTUAL 0x00000004 +#define _PC_MEDIA_MEMORY 0x00000008 +#define _PC_MEDIA_CDROM 0x00000010 +#define _PC_MEDIA_ATA 0x00001000 +#define _PC_MEDIA_SCSI 0x00002000 +#define _PC_MEDIA_NVME 0x00004000 +#define _PC_MEDIA_MMCSD 0x00008000 +#define _PC_MEDIA_MIRROR 0x00010000 +#define _PC_MEDIA_STRIPE 0x00020000 +#define _PC_MEDIA_RAID 0x00040000 #endif /* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */ Index: sys/ufs/ufs/ufs_vnops.c =================================================================== --- sys/ufs/ufs/ufs_vnops.c +++ sys/ufs/ufs/ufs_vnops.c @@ -71,6 +71,8 @@ #include #include +#include + #include #include #include @@ -2416,10 +2418,11 @@ struct vop_pathconf_args /* { struct vnode *a_vp; int a_name; - int *a_retval; + long *a_retval; } */ *ap; { - int error; + struct ufsmount *ump; + int len, error; error = 0; switch (ap->a_name) { @@ -2512,6 +2515,12 @@ break; case _PC_SYMLINK_MAX: *ap->a_retval = MAXPATHLEN; + break; + case _PC_MEDIA: + ump = VFSTOUFS(ap->a_vp->v_mount); + len = sizeof(long); + *ap->a_retval = 0; + error = g_io_getattr("GEOM::media", ump->um_cp, &len, ap->a_retval); break; default: