310 lines
8.6 KiB
Groff
310 lines
8.6 KiB
Groff
.\" $NetBSD: dksubr.9,v 1.7 2019/12/08 12:23:00 mlelstv Exp $
|
|
.\"
|
|
.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
|
|
.\" 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.
|
|
.\"
|
|
.\" 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 November 28, 2016
|
|
.Dt DKSUBR 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm dk_softc ,
|
|
.Nm dk_init ,
|
|
.Nm dk_attach ,
|
|
.Nm dk_detach ,
|
|
.Nm dk_open ,
|
|
.Nm dk_close ,
|
|
.Nm dk_size ,
|
|
.Nm dk_dump ,
|
|
.Nm dk_ioctl ,
|
|
.Nm dk_strategy ,
|
|
.Nm dk_strategy_defer ,
|
|
.Nm dk_strategy_pending ,
|
|
.Nm dk_start ,
|
|
.Nm dk_done ,
|
|
.Nm dk_drain ,
|
|
.Nm dk_discard ,
|
|
.Nm dk_getdefaultlabel ,
|
|
.Nm dk_getdisklabel
|
|
.Nd disk driver subroutines
|
|
.Sh SYNOPSIS
|
|
.In sys/bufq.h
|
|
.In sys/disk.h
|
|
.In dev/dkvar.h
|
|
.Ft void
|
|
.Fn dk_init "struct dk_softc *" "device_t" "int dtype"
|
|
.Ft void
|
|
.Fn dk_attach "struct dk_softc *"
|
|
.Ft void
|
|
.Fn dk_detach "struct dk_softc *"
|
|
.Ft int
|
|
.Fn dk_open "struct dk_softc *" "dev_t" "int flags" "int fmt" "struct lwp *"
|
|
.Ft int
|
|
.Fn dk_close "struct dk_softc *" "dev_t" "int flags" "int fmt" "struct lwp *"
|
|
.Ft int
|
|
.Fn dk_discard "struct dk_softc *" "dev_t" "off_t pos" "off_t len"
|
|
.Ft int
|
|
.Fn dk_size "struct dk_softc *" "dev_t"
|
|
.Ft int
|
|
.Fn dk_dump "struct dk_softc *" "dev_t" "daddr_t blkno" "void *vav" "size_t size"
|
|
.Ft int
|
|
.Fn dk_ioctl "struct dk_softc *" "dev_t" "u_long cmd" "void *data" "int flag" "struct lwp *"
|
|
.Ft void
|
|
.Fn dk_strategy "struct dk_softc *" "struct buf *"
|
|
.Ft int
|
|
.Fn dk_strategy_defer "struct dk_softc *" "struct buf *"
|
|
.Ft int
|
|
.Fn dk_strategy_pending "struct dk_softc *"
|
|
.Ft void
|
|
.Fn dk_start "struct dk_softc *" "struct buf *"
|
|
.Ft void
|
|
.Fn dk_done "struct dk_softc *" "struct buf *"
|
|
.Ft int
|
|
.Fn dk_drain "struct dk_softc *"
|
|
.Ft void
|
|
.Fn dk_getdefaultlabel "struct dk_softc *" "struct disklabel *"
|
|
.Ft void
|
|
.Fn dk_getdisklabel "struct dk_softc *" "dev_t"
|
|
.Sh DESCRIPTION
|
|
The disk driver subroutines provide common functionality for all disk drivers
|
|
to reduce the amount of replicated code.
|
|
For many disk drivers, their
|
|
corresponding entry points can be made mostly stubs.
|
|
.Pp
|
|
The subroutines encapsulate data structures found in a driver's softc
|
|
into
|
|
.Bd -literal
|
|
struct dk_softc {
|
|
device_t sc_dev;
|
|
struct disk sc_dkdev;
|
|
struct bufq_state sc_bufq;
|
|
krndsource_t sc_rnd_source;
|
|
\&...
|
|
}
|
|
.Ed
|
|
The
|
|
.Nm dk_softc
|
|
structure therefore replaces the
|
|
.Nm device_t
|
|
member of the driver's softc struct.
|
|
.Pp
|
|
The following is a brief description of each function in the framework:
|
|
.Bl -tag -width ".Fn dk_strategy_pending"
|
|
.It Fn dk_init
|
|
Initialize the dk_softc structure.
|
|
.It Fn dk_attach
|
|
Attach framework after driver has attached the
|
|
.Xr disk 9
|
|
subsystem, created a
|
|
.Xr bufq 9
|
|
and is ready to handle I/O.
|
|
.It Fn dk_detach
|
|
Undo dk_attach.
|
|
.It Fn dk_open
|
|
Handles open steps for the
|
|
.Xr disk 9
|
|
framework, acquires the disklabel and validates open parameters.
|
|
The driver may provide the
|
|
.Nm d_firstopen
|
|
callback to handle initialization steps.
|
|
.It Fn dk_close
|
|
Handles close steps for the
|
|
.Xr disk 9
|
|
framework.
|
|
The driver may provide the
|
|
.Nm d_lastclose
|
|
callback to handle finalization steps.
|
|
.Nm dk_open
|
|
and
|
|
.Nm dk_close
|
|
are serialized by the openlock mutex.
|
|
.It Fn dk_discard
|
|
Validates parameters, computes raw block numbers and passes
|
|
these to the
|
|
.Nm d_discard
|
|
callback.
|
|
.It Fn dk_size
|
|
Returns dump size information from the
|
|
.Xr disklabel 9
|
|
and opens and closes the driver when necessary.
|
|
.It Fn dk_dump
|
|
Validates parameters, computes raw block numbers and iterates
|
|
over the
|
|
.Nm d_dumpblocks
|
|
callback in appropriate chunks determined by the
|
|
.Nm d_iosize
|
|
callback.
|
|
.It Fn dk_ioctl
|
|
Handles the ioctls
|
|
.Dv DIOCKLABEL ,
|
|
.Dv DIOCWLABEL ,
|
|
.Dv DIOCGDEFLABEL ,
|
|
.Dv DIOCGSTRATEGY ,
|
|
and
|
|
.Dv DIOCSSTRATEGY
|
|
and passes other disk ioctls through the
|
|
.Xr disk 9
|
|
framework.
|
|
Returns
|
|
.Nm ENOTTY
|
|
when an ioctl isn't implemented.
|
|
This routine is run as a fallback to
|
|
handle commands that are not specific to the driver.
|
|
.It Fn dk_strategy
|
|
Validates parameters, computes raw block numbers, queues a buffer for I/O
|
|
and triggers queue processing by calling
|
|
.Nm dk_start .
|
|
.It Fn dk_strategy_defer
|
|
Alternative to
|
|
.Nm dk_strategy
|
|
that only queues the buffer.
|
|
Drivers that implement a separate I/O thread
|
|
can use
|
|
.Nm dk_strategy_defer
|
|
within their own strategy routine and signal the thread through a private
|
|
interface.
|
|
.It Fn dk_strategy_pending
|
|
This function is called by an I/O thread to determine if work has been
|
|
queued by
|
|
.Nm dk_strategy_defer .
|
|
The driver must then call
|
|
.Nm dk_start
|
|
to trigger queue processing.
|
|
.It Fn dk_start
|
|
If
|
|
.Ar bp != Dv NULL
|
|
put it into the queue.
|
|
Run the
|
|
.Nm d_diskstart
|
|
callback for every buffer until the queue is empty or the callback returns
|
|
.Nm EAGAIN .
|
|
In the latter case, the buffer is saved and issued on the
|
|
next queue run.
|
|
This also calls
|
|
.Nm disk_busy
|
|
accordingly to handle I/O metrics.
|
|
.It Fn dk_done
|
|
Called by the driver when an I/O operation completed.
|
|
.Nm dk_done
|
|
logs errors, calls
|
|
.Nm disk_unbusy
|
|
to handle I/O metrics and collects entropy for the
|
|
.Xr cprng 9 .
|
|
.It Fn dk_drain
|
|
Aborts all queued I/O.
|
|
This function must be called instead of
|
|
.Fn bufq_drain
|
|
to cooperate with
|
|
.Nm dk_start .
|
|
.It Fn dk_getdefaultlabel
|
|
Compute a common default disklabel for all disk drivers.
|
|
Some drivers provide device specific information or assign specific
|
|
disk formats to partitions.
|
|
Such drivers may implement the
|
|
.Nm d_label
|
|
callback that is called by
|
|
.Nm dk_getdefaultlabel
|
|
after initializing the label with common values.
|
|
.It Fn dk_getdisklabel
|
|
Read disklabel with machine dependent low-level function
|
|
.Nm readdisklabel
|
|
and do sanity checks.
|
|
.El
|
|
.Sh DRIVER INTERFACE
|
|
The driver needs to provide a common set of entry points that are
|
|
used by the disk driver subroutines and the
|
|
.Xr disk 9
|
|
framework.
|
|
.Bd -literal
|
|
struct dkdriver {
|
|
void (*d_strategy)(struct buf *);
|
|
void (*d_minphys)(struct buf *);
|
|
int (*d_open)(dev_t, int, int, struct lwp *);
|
|
int (*d_close)(dev_t, int, int, struct lwp *);
|
|
int (*d_diskstart)(device_t, struct buf *);
|
|
void (*d_iosize)(device_t, int *);
|
|
int (*d_dumpblocks)(device_t, void *, daddr_t, int);
|
|
int (*d_lastclose)(device_t);
|
|
int (*d_discard)(device_t, off_t, off_t);
|
|
int (*d_firstopen)(device_t, dev_t, int, int);
|
|
void (*d_label)(device_t, struct disklabel *);
|
|
};
|
|
.Ed
|
|
.Bl -tag -width ".Fn dk_firstopen"
|
|
.It Fn d_strategy
|
|
The driver strategy routine queues a single buffer for I/O
|
|
and starts queue processing as appropriate.
|
|
.It Fn d_minphys
|
|
The driver minphys routine limits the buffer
|
|
.Nm b_bcount
|
|
to the maximum size for an I/O transfer supported by the driver
|
|
and hardware.
|
|
It also calls
|
|
.Nm minphys
|
|
to apply the platform limit.
|
|
.It Fn d_open
|
|
The driver open routine.
|
|
.It Fn d_close
|
|
The driver close routine.
|
|
.It Fn d_diskstart
|
|
Issues a single I/O request, called by
|
|
.Nm dk_start .
|
|
.It Fn d_iosize
|
|
Truncate I/O size to the driver limit.
|
|
This is similar to
|
|
.Nm minphys
|
|
but operates on an integer value instead of a buffer.
|
|
.It Fn d_dumpblocks
|
|
Issue a single I/O requests, called by
|
|
.Nm dk_dump .
|
|
.It Fn d_lastclose
|
|
Private cleanup after last user is finished.
|
|
Often used to flush write caches.
|
|
.It Fn d_discard
|
|
Issue a single I/O request to invalidate a disk region.
|
|
.It Fn d_firstopen
|
|
Private initialization when first user opens the driver.
|
|
.El
|
|
.Sh SEE ALSO
|
|
.Xr cgd 4 ,
|
|
.Xr ld 4 ,
|
|
.Xr cprng 9 ,
|
|
.Xr disk 9 ,
|
|
.Xr driver 9
|
|
.Sh HISTORY
|
|
The
|
|
.Nx
|
|
common disk driver subroutines appeared in
|
|
.Nx 2.0
|
|
as a base for the cryptographic disk driver and was extended
|
|
to handle disk wedges in
|
|
.Nx 4.0 .
|
|
Most functionality provided by
|
|
.Xr ld 4
|
|
was included and extended in
|
|
.Nx 8.0
|
|
to support other disk drivers.
|
|
The callback interface used by the
|
|
.Xr disk 9
|
|
framework has been merged as well.
|