199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
199767f8919635c4928607450d9e0abb932109ceToomas Soome entry = (struct dentry *)malloc(sizeof(struct dentry));
199767f8919635c4928607450d9e0abb932109ceToomas Soome entry->od = (struct open_disk *)dev->d_opendata;
199767f8919635c4928607450d9e0abb932109ceToomas Soome STAILQ_INSERT_TAIL(&opened_disks, entry, entry);
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCOMMAND_SET(dcachestat, "dcachestat", "get disk cache stats",
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("%s %d => %p [%d]\n", disk_fmtdev(&dev), entry->count,
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif /* DISK_DEBUG */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Convert size to a human-readable number. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *
199767f8919635c4928607450d9e0abb932109ceToomas Soomeptblread(void *d, void *buf, size_t blocks, off_t offset)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (dev->d_dev->dv_strategy(dev, F_READ, offset, 0,
199767f8919635c4928607450d9e0abb932109ceToomas Soomeptable_print(void *arg, const char *pname, const struct ptable_entry *part)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (part->type == PART_FREEBSD || part->type == PART_SOLARIS2) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Open slice with BSD or VTOC label */
199767f8919635c4928607450d9e0abb932109ceToomas Soome table = ptable_open(pa->dev, part->end - part->start + 1,
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = ptable_iterate(table, &bsd, ptable_print);
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_print(struct disk_devdesc *dev, char *prefix, int verbose)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Disk should be opened */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (ptable_iterate(od->table, &pa, ptable_print));
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_read(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = dev->d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset, 0,
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_write(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = dev->d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset, 0,
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ((*dev->d_dev->dv_ioctl)(dev->d_opendata, cmd, buf));
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * While we are reading disk metadata, make sure we do it relative
199767f8919635c4928607450d9e0abb932109ceToomas Soome * to the start of the disk
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This entire disk was already opened and there is no
199767f8919635c4928607450d9e0abb932109ceToomas Soome * need to allocate new open_disk structure and open the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * main partition table.
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%s unit %d, slice %d, partition %d => %p (cached)",
199767f8919635c4928607450d9e0abb932109ceToomas Soome od = (struct open_disk *)malloc(sizeof(struct open_disk));
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%s unit %d, slice %d, partition %d => %p",
199767f8919635c4928607450d9e0abb932109ceToomas Soome disk_fmtdev(dev), dev->d_unit, dev->d_slice, dev->d_partition, od);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Determine disk layout. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome od->table = ptable_open(dev, mediasize / sectorsize, sectorsize,
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* It doesn't matter what value has d_slice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = ptable_getpart(od->table, &part, partition);
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if (slice >= 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Try to get information about partition */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * When we try to open GPT partition, but partition
199767f8919635c4928607450d9e0abb932109ceToomas Soome * table isn't GPT, reset d_partition value to -1
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and try to autodetect appropriate value.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If d_partition < 0 and we are looking at a BSD/VTOC slice,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * then try to read label, otherwise return the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * whole MBR slice.
199767f8919635c4928607450d9e0abb932109ceToomas Soome (part.type != PART_FREEBSD || part.type != PART_SOLARIS2))
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Try to read label */
199767f8919635c4928607450d9e0abb932109ceToomas Soome table = ptable_open(dev, part.end - part.start + 1,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If slice contains BSD/VTOC label and d_partition < 0, then
199767f8919635c4928607450d9e0abb932109ceToomas Soome * assume the 'a' partition. Otherwise just return the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * whole MBR slice, because it can contain ZFS.
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Save the slice and partition number to the dev */
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%s offset %lld => %p", disk_fmtdev(dev),
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%s closed => %p [%d]", disk_fmtdev(dev), od, od->rcnt);
199767f8919635c4928607450d9e0abb932109ceToomas Soome STAILQ_FOREACH_SAFE(entry, &opened_disks, entry, tmp) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%s was freed => %p [%d]", disk_fmtdev(&dev),
199767f8919635c4928607450d9e0abb932109ceToomas Soome STAILQ_REMOVE(&opened_disks, entry, dentry, entry);
199767f8919635c4928607450d9e0abb932109ceToomas Soome cp = buf + sprintf(buf, "%s%d", dev->d_dev->dv_name, dev->d_unit);
199767f8919635c4928607450d9e0abb932109ceToomas Soome cp += sprintf(cp, "%c", dev->d_partition + 'a');
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we don't support nested partitions on GPT */