diff options
| author | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 15:32:58 -0400 |
|---|---|---|
| committer | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 15:32:58 -0400 |
| commit | 5cb84ec742fd33f78c8022863fadaa8d0d93e176 (patch) | |
| tree | 1a81ca3665e6153923e40db7b0d988f8573ab59c /static/netbsd/man9/disk.9 | |
| parent | a59214f344567c037d5776879bcfc5fcc1d4d5f6 (diff) | |
feat: Added NetBSD man pages
Diffstat (limited to 'static/netbsd/man9/disk.9')
| -rw-r--r-- | static/netbsd/man9/disk.9 | 574 |
1 files changed, 574 insertions, 0 deletions
diff --git a/static/netbsd/man9/disk.9 b/static/netbsd/man9/disk.9 new file mode 100644 index 00000000..1bd4d195 --- /dev/null +++ b/static/netbsd/man9/disk.9 @@ -0,0 +1,574 @@ +.\" $NetBSD: disk.9,v 1.46 2017/07/03 21:28:48 wiz Exp $ +.\" +.\" Copyright (c) 1995, 1996 Jason R. Thorpe. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed for the NetBSD Project +.\" by Jason R. Thorpe. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd March 5, 2017 +.Dt DISK 9 +.Os +.Sh NAME +.Nm disk , +.Nm disk_init , +.Nm disk_attach , +.Nm disk_begindetach , +.Nm disk_detach , +.Nm disk_destroy , +.Nm disk_wait , +.Nm disk_busy , +.Nm disk_unbusy , +.Nm disk_isbusy , +.Nm disk_find , +.Nm disk_set_info +.Nd generic disk framework +.Sh SYNOPSIS +.In sys/types.h +.In sys/disklabel.h +.In sys/disk.h +.Ft void +.Fn disk_init "struct disk *" "const char *name" "const struct dkdriver *driver" +.Ft void +.Fn disk_attach "struct disk *" +.Ft void +.Fn disk_begindetach "struct disk *" "int (*lastclose)(device_t)" "device_t self" "int flags" +.Ft void +.Fn disk_detach "struct disk *" +.Ft void +.Fn disk_destroy "struct disk *" +.Ft void +.Fn disk_wait "struct disk *" +.Ft void +.Fn disk_busy "struct disk *" +.Ft void +.Fn disk_unbusy "struct disk *" "long bcount" "int read" +.Ft bool +.Fn disk_isbusy "struct disk *" +.Ft struct disk * +.Fn disk_find "const char *" +.Ft void +.Fn disk_set_info "device_t" "struct disk *" "const char *type" +.Sh DESCRIPTION +The +.Nx +generic disk framework is designed to provide flexible, +scalable, and consistent handling of disk state and metrics information. +The fundamental component of this framework is the +.Nm disk +structure, which is defined as follows: +.Bd -literal +struct disk { + TAILQ_ENTRY(disk) dk_link; /* link in global disklist */ + const char *dk_name; /* disk name */ + prop_dictionary_t dk_info; /* reference to disk-info dictionary */ + int dk_bopenmask; /* block devices open */ + int dk_copenmask; /* character devices open */ + int dk_openmask; /* composite (bopen|copen) */ + int dk_state; /* label state ### */ + int dk_blkshift; /* shift to convert DEV_BSIZE to blks */ + int dk_byteshift; /* shift to convert bytes to blks */ + + /* + * Metrics data; note that some metrics may have no meaning + * on certain types of disks. + */ + struct io_stats *dk_stats; + + const struct dkdriver *dk_driver; /* pointer to driver */ + + /* + * Information required to be the parent of a disk wedge. + */ + kmutex_t dk_rawlock; /* lock on these fields */ + u_int dk_rawopens; /* # of opens of rawvp */ + struct vnode *dk_rawvp; /* vnode for the RAW_PART bdev */ + + kmutex_t dk_openlock; /* lock on these and openmask */ + u_int dk_nwedges; /* # of configured wedges */ + /* all wedges on this disk */ + LIST_HEAD(, dkwedge_softc) dk_wedges; + + /* + * Disk label information. Storage for the in-core disk label + * must be dynamically allocated, otherwise the size of this + * structure becomes machine-dependent. + */ + daddr_t dk_labelsector; /* sector containing label */ + struct disklabel *dk_label; /* label */ + struct cpu_disklabel *dk_cpulabel; +}; +.Ed +.Pp +The system maintains a global linked-list of all disks attached to the +system. +This list, called +.Nm disklist , +may grow or shrink over time as disks are dynamically added and removed +from the system. +Drivers which currently make use of the detachment +capability of the framework are the +.Nm ccd , +.Nm dm , +and +.Nm vnd +pseudo-device drivers. +.Pp +The following is a brief description of each function in the framework: +.Bl -tag -width ".Fn disk_set_info" +.It Fn disk_init +Initialize the disk structure. +.It Fn disk_attach +Attach a disk; allocate storage for the disklabel, set the +.Dq attached time +timestamp, insert the disk into the disklist, and increment the +system disk count. +.It Fn disk_begindetach +Check whether the disk is open, and if not, return 0. +If the disk is open, and +.Dv DETACH_FORCE +is not set in +.Fa flags , +return +.Dv EBUSY . +Otherwise, call the provided +.Fa lastclose +routine +.Po +if not +.Dv NULL +.Pc +and return its exit code. +.It Fn disk_detach +Detach a disk; free storage for the disklabel, remove the disk +from the disklist, and decrement the system disk count. +If the count drops below zero, panic. +.It Fn disk_destroy +Release resources used by the disk structure when it is no longer +required. +.It Fn disk_wait +Disk timings are measured by counting the number of queued +requests (wait counter) and requests issued to the hardware (busy counter) +and keeping timestamp when the counters change. +The time interval between +two changes of a counter is accumulated into a total and also multiplied +by the counter value and the accumulated into a sum. +Both values can be +used to determine how much time is spent in the driver queue or in-flight +to the hardware as well as the average number of requests in either state. +.Fn disk_wait +increment the disk's wait counter and handles the accumulation. +.It Fn disk_busy +Decrements the disk's wait counter and increments the disk's +.Dq busy counter , +and handles either accumulation. +If the wait counter is still zero, it +is assumed that the driver hasn't been updated to call +.Fn disk_wait , +then only the values from the busy counter are available. +.It Fn disk_unbusy +Decrement the disk's busy counter and handles the accumulation. +The third argument +.Ar read +specifies the direction of I/O; +if non-zero it means reading from the disk, +otherwise it means writing to the disk. +.It Fn disk_isbusy +Returns +.Ar true +if disk is marked as busy and false if it is not. +.It Fn disk_find +Return a pointer to the disk structure corresponding to the name provided, +or +.Dv NULL +if the disk does not exist. +.It Fn disk_set_info +Setup disk-info dictionary and other dependent values of the disk structure, +the driver must have initialized the dk_geom member of +.Fa struct disk +with suitable values. +If +.Fa type +is not +.Dv NULL , +it will be added to the dictionary. +.El +.Pp +The functions typically called by device drivers are +.Fn disk_init +.Fn disk_attach , +.Fn disk_begindetach , +.Fn disk_detach , +.Fn disk_destroy , +.Fn disk_wait , +.Fn disk_busy , +.Fn disk_unbusy , +and +.Fn disk_set_info . +The function +.Fn disk_find +is provided as a utility function. +.Sh DISK IOCTLS +The following ioctls should be implemented by disk drivers: +.Bl -tag -width "xxxxxx" +.It Dv DIOCGDINFO "struct disklabel" +Get disklabel. +.It Dv DIOCSDINFO "struct disklabel" +Set in-memory disklabel. +.It Dv DIOCWDINFO "struct disklabel" +Set in-memory disklabel and write on-disk disklabel. +.It Dv DIOCGPART "struct partinfo" +Get partition information. +This is used internally. +.It Dv DIOCRFORMAT "struct format_op" +Read format. +.It Dv DIOCWFORMAT "struct format_op" +Write format. +.It Dv DIOCSSTEP "int" +Set step rate. +.It Dv DIOCSRETRIES "int" +Set number of retries. +.It Dv DIOCKLABEL "int" +Specify whether to keep or drop the in-memory disklabel +when the device is closed. +.It Dv DIOCWLABEL "int" +Enable or disable writing to the part of the disk that contains the label. +.It Dv DIOCSBAD "struct dkbad" +Set kernel dkbad. +.It Dv DIOCEJECT "int" +Eject removable disk. +.It Dv DIOCLOCK "int" +Lock or unlock disk pack. +For devices with removable media, locking is intended to prevent +the operator from removing the media. +.It Dv DIOCGDEFLABEL "struct disklabel" +Get default label. +.It Dv DIOCCLRLABEL +Clear disk label. +.It Dv DIOCGCACHE "int" +Get status of disk read and write caches. +The result is a bitmask containing the following values: +.Bl -tag -width DKCACHE_RCHANGE +.It Dv DKCACHE_READ +Read cache enabled. +.It Dv DKCACHE_WRITE +Write(back) cache enabled. +.It Dv DKCACHE_RCHANGE +Read cache enable is changeable. +.It Dv DKCACHE_WCHANGE +Write cache enable is changeable. +.It Dv DKCACHE_SAVE +Cache parameters may be saved, so that they persist across reboots +or device detach/attach cycles. +.El +.It Dv DIOCSCACHE "int" +Set status of disk read and write caches. +The input is a bitmask in the same format as used for +.Dv DIOCGCACHE . +.It Dv DIOCCACHESYNC "int" +Synchronise the disk cache. +This causes information in the disk's write cache (if any) +to be flushed to stable storage. +The argument specifies whether or not to force a flush even if +the kernel believes that there is no outstanding data. +.It Dv DIOCBSLIST "struct disk_badsecinfo" +Get bad sector list. +.It Dv DIOCBSFLUSH +Flush bad sector list. +.It Dv DIOCAWEDGE "struct dkwedge_info" +Add wedge. +.It Dv DIOCGWEDGEINFO "struct dkwedge_info" +Get wedge information. +.It Dv DIOCDWEDGE "struct dkwedge_info" +Delete wedge. +.It Dv DIOCLWEDGES "struct dkwedge_list" +List wedges. +.It Dv DIOCGSTRATEGY "struct disk_strategy" +Get disk buffer queue strategy. +.It Dv DIOCSSTRATEGY "struct disk_strategy" +Set disk buffer queue strategy. +.It Dv DIOCGDISKINFO "struct plistref" +Get disk-info dictionary. +.It Dv DIOCGMEDIASIZE "off_t" +Get disk size in bytes. +.It Dv DIOCGSECTORSIZE "u_int" +Get sector size in bytes. +.El +.Sh USING THE FRAMEWORK +This section includes a description on basic use of the framework +and example usage of its functions. +Actual implementation of a device driver which uses the framework +may vary. +.Pp +Each device in the system uses a +.Dq softc +structure which contains autoconfiguration and state information for that +device. +In the case of disks, the softc should also contain one instance +of the disk structure, e.g.: +.Bd -literal +struct foo_softc { + device_t sc_dev; /* generic device information */ + struct disk sc_dk; /* generic disk information */ + [ . . . more . . . ] +}; +.Ed +.Pp +In order for the system to gather metrics data about a disk, the disk must +be registered with the system. +The +.Fn disk_attach +routine performs all of the functions currently required to register a disk +with the system including allocation of disklabel storage space, +recording of the time since boot that the disk was attached, and insertion +into the disklist. +Note that since this function allocates storage space for the disklabel, +it must be called before the disklabel is read from the media or used in +any other way. +Before +.Fn disk_attach +is called, a portions of the disk structure must be initialized with +data specific to that disk. +For example, in the +.Dq foo +disk driver, the following would be performed in the autoconfiguration +.Dq attach +routine: +.Bd -literal +void +fooattach(device_t parent, device_t self, void *aux) +{ + struct foo_softc *sc = device_private(self); + [ . . . ] + + /* Initialize and attach the disk structure. */ + disk_init(&sc->sc_dk, device_xname(self), &foodkdriver); + disk_attach(&sc->sc_dk); + + /* Read geometry and fill in pertinent parts of disklabel. */ + /* Initialize geometry values of the disk structure */ + [ . . . ] + disk_set_info(&self>, &sc->sc_dk, type); +} +.Ed +.Pp +The +.Nm foodkdriver +above is the disk's +.Dq driver +switch. +This switch currently includes pointers to several driver entry points, +where only the +.Nm d_strategy +entry point is used by the disk framework. +This switch needs to have global scope and should be initialized as follows: +.Bd -literal +void (foostrategy)(struct buf *); +void (foominphys)(struct buf *); +int (fooopen)(dev_t, int, int, struct lwp *); +int (fooclose)(dev_t, int, int, struct lwp *); +int (foo_discard)(device_t, off_t, off_t); +int (foo_diskstart)(device_t, struct buf *); +void (foo_iosize)(device_t, int *); +int (foo_dumpblocks)(device_t, void *, daddr_t, int); +int (foo_lastclose)(device_t); +int (foo_firstopen)(device_t, dev_t, int, int); +int (foo_label)(device_t, struct disklabel *); + +const struct dkdriver foodkdriver = { + .d_open = fooopen, + .d_close = fooclose, + .d_strategy = foostrategy, + .d_minphys = foominphys, + .d_discard = foo_discard, + .d_diskstart = foo_diskstart, /* optional */ + .d_dumpblocks = foo_dumpblocks, /* optional */ + .d_iosize = foo_iosize, /* optional */ + .d_firstopen = foo_firstopen, /* optional */ + .d_lastclose = foo_lastclose, /* optional */ + .d_label = foo_label, /* optional */ +}; +.Ed +.Pp +Once the disk is attached, metrics may be gathered on that disk. +In order to gather metrics data, the driver must tell the framework when +the disk queues, starts and stops operations. +This functionality is provided by the +.Fn disk_wait , +.Fn disk_busy +and +.Fn disk_unbusy +routines. +Because +.Nm struct disk +is part of device driver private data it needs to be guarded. +Mutual exclusion must be done by driver +.Fn disk_wait , +.Fn disk_busy +and +.Fn disk_unbusy +are not thread safe. +The +.Fn disk_busy +routine should be called immediately before a command to the disk is +sent, e.g.: +.Bd -literal +void +foostrategy(struct buf *bp) +{ + [ . . . ] + + mutex_enter(&sc->sc_dk_mtx); + disk_wait(&sc->sc_dk); + + /* Put buffer onto drive's transfer queue */ + + mutex_exit(&sc->sc_dk_mtx); + + foostart(sc); +} + +void +foostart(struct foo_softc *sc) +{ + [ . . . ] + + /* Get buffer from drive's transfer queue. */ + [ . . . ] + + /* Build command to send to drive. */ + [ . . . ] + + /* Tell the disk framework we're going busy. */ + mutex_enter(&sc->sc_dk_mtx); + disk_busy(&sc->sc_dk); + mutex_exit(&sc->sc_dk_mtx); + + /* Send command to the drive. */ + [ . . . ] +} +.Ed +.Pp +The routine +.Fn disk_unbusy +performs some consistency checks, such as ensuring that the calls to +.Fn disk_busy +and +.Fn disk_unbusy +are balanced. +It also performs the final steps of the metrics calcuation. +A byte count is added to the disk's running total, and if greater than +zero, the number of transfers the disk has performed is incremented. +The third argument +.Ar read +specifies the direction of I/O; +if non-zero it means reading from the disk, +otherwise it means writing to the disk. +.Bd -literal +void +foodone(xfer) + struct foo_xfer *xfer; +{ + struct foo_softc = (struct foo_softc *)xfer->xf_softc; + struct buf *bp = xfer->xf_buf; + long nbytes; + [ . . . ] + + /* + * Get number of bytes transferred. If there is no buf + * associated with the xfer, we are being called at the + * end of a non-I/O command. + */ + if (bp == NULL) + nbytes = 0; + else + nbytes = bp->b_bcount - bp->b_resid; + + [ . . . ] + + mutex_enter(&sc->sc_dk_mtx); + /* Notify the disk framework that we've completed the transfer. */ + disk_unbusy(&sc->sc_dk, nbytes, + bp != NULL ? bp->b_flags & B_READ : 0); + mutex_exit(&sc->sc_dk_mtx); + + [ . . . ] +} +.Ed +.Pp +.Fn disk_isbusy +is used to get status of disk device it returns true if device is +currently busy and false if it is not. +Like +.Fn disk_wait , +.Fn disk_busy +and +.Fn disk_unbusy +it requires explicit locking from user side. +.Sh CODE REFERENCES +The disk framework itself is implemented within the file +.Pa sys/kern/subr_disk.c . +Data structures and function prototypes for the framework are located in +.Pa sys/sys/disk.h . +.Pp +The +.Nx +machine-independent SCSI disk and CD-ROM drivers use the +disk framework. +They are located in +.Pa sys/scsi/sd.c +and +.Pa sys/scsi/cd.c . +.Pp +The +.Nx +.Nm ccd , +.Nm dm , +and +.Nm vnd +drivers use the detachment capability of the framework. +They are located in +.Pa sys/dev/ccd.c , +.Pa sys/dev/vnd.c , +and +.Pa sys/dev/dm/device-mapper.c . +.Sh SEE ALSO +.Xr ccd 4 , +.Xr dm 4 , +.Xr vnd 4 , +.Xr dksubr 9 +.Sh HISTORY +The +.Nx +generic disk framework appeared in +.Nx 1.2 . +.Sh AUTHORS +The +.Nx +generic disk framework was architected and implemented by +.An Jason R. Thorpe +.Aq Mt thorpej@NetBSD.org . |
