No empty .Rs/.Re
[netbsd-mini2440.git] / share / man / man9 / disk.9
blobfbe2c46921f25e4339623d8f5af82008f83682c8
1 .\"     $NetBSD: disk.9,v 1.34 2009/12/30 01:37:17 jnemeth Exp $
2 .\"
3 .\" Copyright (c) 1995, 1996 Jason R. Thorpe.
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\"    must display the following acknowledgement:
16 .\"     This product includes software developed for the NetBSD Project
17 .\"     by Jason R. Thorpe.
18 .\" 4. The name of the author may not be used to endorse or promote products
19 .\"    derived from this software without specific prior written permission.
20 .\"
21 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 .\" SUCH DAMAGE.
32 .\"
33 .Dd December 30, 2009
34 .Dt DISK 9
35 .Os
36 .Sh NAME
37 .Nm disk ,
38 .Nm disk_init ,
39 .Nm disk_attach ,
40 .Nm disk_begindetach ,
41 .Nm disk_detach ,
42 .Nm disk_destroy ,
43 .Nm disk_busy ,
44 .Nm disk_unbusy ,
45 .Nm disk_isbusy ,
46 .Nm disk_find ,
47 .Nm disk_blocksize
48 .Nd generic disk framework
49 .Sh SYNOPSIS
50 .In sys/types.h
51 .In sys/disklabel.h
52 .In sys/disk.h
53 .Ft void
54 .Fn disk_init "struct disk *" "const char *name" "const struct dkdriver *driver"
55 .Ft void
56 .Fn disk_attach "struct disk *"
57 .Ft void
58 .Fn disk_begindetach "struct disk *" "int (*lastclose)(device_t)" "device_t self" "int flags"
59 .Ft void
60 .Fn disk_detach "struct disk *"
61 .Ft void
62 .Fn disk_destroy "struct disk *"
63 .Ft void
64 .Fn disk_busy "struct disk *"
65 .Ft void
66 .Fn disk_unbusy "struct disk *" "long bcount" "int read"
67 .Ft bool
68 .Fn disk_isbusy "struct disk *"
69 .Ft struct disk *
70 .Fn disk_find "const char *"
71 .Ft void
72 .Fn disk_blocksize "struct disk *" "int blocksize"
73 .Sh DESCRIPTION
74 The
75 .Nx
76 generic disk framework is designed to provide flexible,
77 scalable, and consistent handling of disk state and metrics information.
78 The fundamental component of this framework is the
79 .Nm disk
80 structure, which is defined as follows:
81 .Bd -literal
82 struct disk {
83         TAILQ_ENTRY(disk) dk_link;      /* link in global disklist */
84         const char      *dk_name;       /* disk name */
85         prop_dictionary_t dk_info;      /* reference to disk-info dictionary */
86         int             dk_bopenmask;   /* block devices open */
87         int             dk_copenmask;   /* character devices open */
88         int             dk_openmask;    /* composite (bopen|copen) */
89         int             dk_state;       /* label state   ### */
90         int             dk_blkshift;    /* shift to convert DEV_BSIZE to blks */
91         int             dk_byteshift;   /* shift to convert bytes to blks */
93         /*
94          * Metrics data; note that some metrics may have no meaning
95          * on certain types of disks.
96          */
97         struct io_stats *dk_stats;
99         const struct dkdriver *dk_driver;       /* pointer to driver */
101         /*
102          * Information required to be the parent of a disk wedge.
103          */
104         kmutex_t        dk_rawlock;     /* lock on these fields */
105         u_int           dk_rawopens;    /* # of openes of rawvp */
106         struct vnode    *dk_rawvp;      /* vnode for the RAW_PART bdev */
108         kmutex_t        dk_openlock;    /* lock on these and openmask */
109         u_int           dk_nwedges;     /* # of configured wedges */
110                                         /* all wedges on this disk */
111         LIST_HEAD(, dkwedge_softc) dk_wedges;
113         /*
114          * Disk label information.  Storage for the in-core disk label
115          * must be dynamically allocated, otherwise the size of this
116          * structure becomes machine-dependent.
117          */
118         daddr_t         dk_labelsector;         /* sector containing label */
119         struct disklabel *dk_label;     /* label */
120         struct cpu_disklabel *dk_cpulabel;
124 The system maintains a global linked-list of all disks attached to the
125 system.
126 This list, called
127 .Nm disklist ,
128 may grow or shrink over time as disks are dynamically added and removed
129 from the system.
130 Drivers which currently make use of the detachment
131 capability of the framework are the
132 .Nm ccd ,
133 .Nm dm ,
135 .Nm vnd
136 pseudo-device drivers.
138 The following is a brief description of each function in the framework:
139 .Bl -tag -width ".Fn disk_blocksize"
140 .It Fn disk_init
141 Initialize the disk structure.
142 .It Fn disk_attach
143 Attach a disk; allocate storage for the disklabel, set the
144 .Dq attached time
145 timestamp, insert the disk into the disklist, and increment the
146 system disk count.
147 .It Fn disk_begindetach
148 Check whether the disk is open, and if not, return 0.
149 If the disk is open, and
150 .Dv DETACH_FORCE
151 is not set in
152 .Fa flags ,
153 return
154 .Dv EBUSY .
155 Otherwise, call the provided
156 .Fa lastclose
157 routine
159 if not
160 .Dv NULL
162 and return its exit code.
163 .It Fn disk_detach
164 Detach a disk; free storage for the disklabel, remove the disk
165 from the disklist, and decrement the system disk count.
166 If the count drops below zero, panic.
167 .It Fn disk_destroy
168 Release resources used by the disk structure when it is no longer
169 required.
170 .It Fn disk_busy
171 Increment the disk's
172 .Dq busy counter .
173 If this counter goes from 0 to 1, set the timestamp corresponding to
174 this transfer.
175 .It Fn disk_unbusy
176 Decrement a disk's busy counter.
177 If the count drops below zero, panic.
178 Get the current time, subtract it from the disk's timestamp, and add
179 the difference to the disk's running total.
180 Set the disk's timestamp to the current time.
181 If the provided byte count is greater than 0, add it to the disk's
182 running total and increment the number of transfers performed by the disk.
183 The third argument
184 .Ar read
185 specifies the direction of I/O;
186 if non-zero it means reading from the disk,
187 otherwise it means writing to the disk.
188 .It Fn disk_isbusy
189 Returns
190 .Ar true
191 if disk is marked as busy and false if it is not.
192 .It Fn disk_find
193 Return a pointer to the disk structure corresponding to the name provided,
194 or NULL if the disk does not exist.
195 .It Fn disk_blocksize
196 Initialize
197 .Fa dk_blkshift
199 .Fa dk_byteshift
200 members of
201 .Fa struct disk
202 with suitable values derived from the supplied physical blocksize.
203 It is only necessary to call this function if the device's physical blocksize
204 is not
205 .Dv DEV_BSIZE .
208 The functions typically called by device drivers are
209 .Fn disk_init
210 .Fn disk_attach ,
211 .Fn disk_begindetach ,
212 .Fn disk_detach ,
213 .Fn disk_destroy ,
214 .Fn disk_busy ,
215 .Fn disk_unbusy ,
217 .Fn disk_blocksize .
218 The function
219 .Fn disk_find
220 is provided as a utility function.
221 .Sh DISK IOCTLS
222 The following ioctls should be implemented by disk drivers:
223 .Bl -tag -width "xxxxxx"
224 .It Dv DIOCGDINFO "struct disklabel"
225 Get disklabel.
226 .It Dv DIOCSDINFO "struct disklabel"
227 Set in-memory disklabel.
228 .It Dv DIOCWDINFO "struct disklabel"
229 Set in-memory disklabel and write on-disk disklabel.
230 .It Dv DIOCGPART "struct partinfo"
231 Get partition information.
232 This is used internally.
233 .It Dv DIOCRFORMAT "struct format_op"
234 Read format.
235 .It Dv DIOCWFORMAT "struct format_op"
236 Write format.
237 .It Dv DIOCSSTEP "int"
238 Set step rate.
239 .It Dv DIOCSRETRIES "int"
240 Set number of retries.
241 .It Dv DIOCKLABEL "int"
242 Specify whether to keep or drop the in-memory disklabel
243 when the device is closed.
244 .It Dv DIOCWLABEL "int"
245 Enable or disable writing to the part of the disk that contains the label.
246 .It Dv DIOCSBAD "struct dkbad"
247 Set kernel dkbad.
248 .It Dv DIOCEJECT "int"
249 Eject removable disk.
250 .It Dv DIOCLOCK "int"
251 Lock or unlock disk pack.
252 For devices with removable media, locking is intended to prevent
253 the operator from removing the media.
254 .It Dv DIOCGDEFLABEL "struct disklabel"
255 Get default label.
256 .It Dv DIOCCLRLABEL
257 Clear disk label.
258 .It Dv DIOCGCACHE "int"
259 Get status of disk read and write caches.
260 The result is a bitmask containing the following values:
261 .Bl -tag -width DKCACHE_RCHANGE
262 .It Dv DKCACHE_READ
263 Read cache enabled.
264 .It Dv DKCACHE_WRITE
265 Write(back) cache enabled.
266 .It Dv DKCACHE_RCHANGE
267 Read cache enable is changeable.
268 .It Dv DKCACHE_WCHANGE
269 Write cache enable is changeable.
270 .It Dv DKCACHE_SAVE
271 Cache parameters may be saved, so that they persist across reboots
272 or device detach/attach cycles.
274 .It Dv DIOCSCACHE "int"
275 Set status of disk read and write caches.
276 The input is a bitmask in the same format as used for
277 .Dv DIOCGCACHE .
278 .It Dv DIOCCACHESYNC "int"
279 Synchronise the disk cache.
280 This causes information in the disk's write cache (if any)
281 to be flushed to stable storage.
282 The argument specifies whether or not to force a flush even if
283 the kernel believes that there is no outstanding data.
284 .It Dv DIOCBSLIST "struct disk_badsecinfo"
285 Get bad sector list.
286 .It Dv DIOCBSFLUSH
287 Flush bad sector list.
288 .It Dv DIOCAWEDGE "struct dkwedge_info"
289 Add wedge.
290 .It Dv DIOCGWEDGEINFO "struct dkwedge_info"
291 Get wedge information.
292 .It Dv DIOCDWEDGE "struct dkwedge_info"
293 Delete wedge.
294 .It Dv DIOCLWEDGES "struct dkwedge_list"
295 List wedges.
296 .It Dv DIOCGSTRATEGY "struct disk_strategy"
297 Get disk buffer queue strategy.
298 .It Dv DIOCSSTRATEGY "struct disk_strategy"
299 Set disk buffer queue strategy.
300 .It Dv DIOCGDISKINFO "struct plistref"
301 Get disk-info dictionary.
303 .Sh USING THE FRAMEWORK
304 This section includes a description on basic use of the framework
305 and example usage of its functions.
306 Actual implementation of a device driver which uses the framework
307 may vary.
309 Each device in the system uses a
310 .Dq softc
311 structure which contains autoconfiguration and state information for that
312 device.
313 In the case of disks, the softc should also contain one instance
314 of the disk structure, e.g.:
315 .Bd -literal
316 struct foo_softc {
317         device_t        sc_dev;         /* generic device information */
318         struct  disk    sc_dk;          /* generic disk information */
319         [ . . . more . . . ]
323 In order for the system to gather metrics data about a disk, the disk must
324 be registered with the system.
326 .Fn disk_attach
327 routine performs all of the functions currently required to register a disk
328 with the system including allocation of disklabel storage space,
329 recording of the time since boot that the disk was attached, and insertion
330 into the disklist.
331 Note that since this function allocates storage space for the disklabel,
332 it must be called before the disklabel is read from the media or used in
333 any other way.
334 Before
335 .Fn disk_attach
336 is called, a portions of the disk structure must be initialized with
337 data specific to that disk.
338 For example, in the
339 .Dq foo
340 disk driver, the following would be performed in the autoconfiguration
341 .Dq attach
342 routine:
343 .Bd -literal
344 void
345 fooattach(device_t parent, device_t self, void *aux)
347         struct foo_softc *sc = device_private(self);
348         [ . . . ]
350         /* Initialize and attach the disk structure. */
351         disk_init(\*[Am]sc-\*[Gt]sc_dk, device_xname(self), \*[Am]foodkdriver);
352         disk_attach(\*[Am]sc-\*[Gt]sc_dk);
354         /* Read geometry and fill in pertinent parts of disklabel. */
355         [ . . . ]
356         disk_blocksize(\*[Am]sc-\*[Gt]sc_dk, bytes_per_sector);
361 .Nm foodkdriver
362 above is the disk's
363 .Dq driver
364 switch.
365 This switch currently includes a pointer to the disk's
366 .Dq strategy
367 routine.
368 This switch needs to have global scope and should be initialized as follows:
369 .Bd -literal
370 void foostrategy(struct buf *);
372 const struct dkdriver foodkdriver = {
373         .d_strategy = foostrategy,
377 Once the disk is attached, metrics may be gathered on that disk.
378 In order to gather metrics data, the driver must tell the framework when
379 the disk starts and stops operations.
380 This functionality is provided by the
381 .Fn disk_busy
383 .Fn disk_unbusy
384 routines.
385 Because
386 .Nm struct disk
387 is part of device driver private data it needs to be guarded.
388 Mutual exclusion must be done by driver
389 .Fn disk_busy
391 .Fn disk_unbusy
392 are not thread safe.
394 .Fn disk_busy
395 routine should be called immediately before a command to the disk is
396 sent, e.g.:
397 .Bd -literal
398 void
399 foostart(sc)
400         struct foo_softc *sc;
402         [ . . . ]
404         /* Get buffer from drive's transfer queue. */
405         [ . . . ]
407         /* Build command to send to drive. */
408         [ . . . ]
410         /* Tell the disk framework we're going busy. */
411         mutex_enter(\*[Am]sc-\*[Gt]sc_dk_mtx);
412         disk_busy(\*[Am]sc-\*[Gt]sc_dk);
413         mutex_exit(\*[Am]sc-\*[Gt]sc_dk_mtx);
415         /* Send command to the drive. */
416         [ . . . ]
420 When
421 .Fn disk_busy
422 is called, a timestamp is taken if the disk's busy counter moves from
423 0 to 1, indicating the disk has gone from an idle to non-idle state.
424 At the end of a transaction, the
425 .Fn disk_unbusy
426 routine should be called.
427 This routine performs some consistency checks,
428 such as ensuring that the calls to
429 .Fn disk_busy
431 .Fn disk_unbusy
432 are balanced.
433 This routine also performs the actual metrics calculation.
434 A timestamp is taken and the difference from the timestamp taken in
435 .Fn disk_busy
436 is added to the disk's total running time.
437 The disk's timestamp is then updated in case there is more than one
438 pending transfer on the disk.
439 A byte count is also added to the disk's running total, and if greater than
440 zero, the number of transfers the disk has performed is incremented.
441 The third argument
442 .Ar read
443 specifies the direction of I/O;
444 if non-zero it means reading from the disk,
445 otherwise it means writing to the disk.
446 .Bd -literal
447 void
448 foodone(xfer)
449         struct foo_xfer *xfer;
451         struct foo_softc = (struct foo_softc *)xfer-\*[Gt]xf_softc;
452         struct buf *bp = xfer-\*[Gt]xf_buf;
453         long nbytes;
454         [ . . . ]
456         /*
457          * Get number of bytes transferred.  If there is no buf
458          * associated with the xfer, we are being called at the
459          * end of a non-I/O command.
460          */
461         if (bp == NULL)
462                 nbytes = 0;
463         else
464                 nbytes = bp-\*[Gt]b_bcount - bp-\*[Gt]b_resid;
466         [ . . . ]
468         mutex_enter(\*[Am]sc-\*[Gt]sc_dk_mtx);
469         /* Notify the disk framework that we've completed the transfer. */
470         disk_unbusy(\*[Am]sc-\*[Gt]sc_dk, nbytes,
471             bp != NULL ? bp-\*[Gt]b_flags \*[Am] B_READ : 0);
472         mutex_exit(\*[Am]sc-\*[Gt]sc_dk_mtx);
474         [ . . . ]
478 .Fn disk_isbusy
479 is used to get status of disk device it returns true if device is
480 currently busy and false if it is not.
481 Like
482 .Fn disk_busy
484 .Fn disk_unbusy
485 it requires explicit locking from user side.
486 .Sh CODE REFERENCES
487 This section describes places within the
489 source tree where actual
490 code implementing or using the disk framework can be found.
491 All pathnames are relative to
492 .Pa /usr/src .
494 The disk framework itself is implemented within the file
495 .Pa sys/kern/subr_disk.c .
496 Data structures and function prototypes for the framework are located in
497 .Pa sys/sys/disk.h .
501 machine-independent SCSI disk and CD-ROM drivers use the
502 disk framework.
503 They are located in
504 .Pa sys/scsi/sd.c
506 .Pa sys/scsi/cd.c .
510 .Nm ccd ,
511 .Nm dm ,
513 .Nm vnd
514 drivers use the detachment capability of the framework.
515 They are located in
516 .Pa sys/dev/ccd.c ,
517 .Pa sys/dev/vnd.c ,
519 .Pa sys/dev/dm/device-mapper.c .
520 .Sh SEE ALSO
521 .Xr ccd 4 ,
522 .Xr dm 4 ,
523 .Xr vnd 4
524 .Sh HISTORY
527 generic disk framework appeared in
528 .Nx 1.2 .
529 .Sh AUTHORS
532 generic disk framework was architected and implemented by
533 .An Jason R. Thorpe
534 .Aq thorpej@NetBSD.org .