Merge commit '9276b3991ba20d5a5660887ba81b0bc7bed25a0c'
[unleashed.git] / share / man / man9f / bioclone.9f
blob7f4aaad771608159ecb08d232e526476f41fa3a0
1 '\" te
2 .\" Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
3 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
4 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
5 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
6 .TH BIOCLONE 9F "Jan 16, 2006"
7 .SH NAME
8 bioclone \- clone another buffer
9 .SH SYNOPSIS
10 .LP
11 .nf
12 #include <sys/ddi.h>
13 #include <sys/sunddi.h>
15 \fBstruct buf *\fR\fBbioclone\fR(\fBstruct buf\fR \fI*bp\fR, \fBoff_t\fR \fIoff\fR, \fBsize_t\fR \fIlen\fR, \fBdev_t\fR \fIdev\fR,
16      \fBdaddr_t\fR \fIblkno\fR, \fBint (\fR\fI*iodone\fR) (struct buf \fI*\fR), \fBstruct buf\fR \fI*bp_mem\fR,
17      \fBint\fR \fIsleepflag\fR);
18 .fi
20 .SH INTERFACE LEVEL
21 .sp
22 .LP
23 Solaris DDI specific (Solaris DDI).
24 .SH PARAMETERS
25 .sp
26 .ne 2
27 .na
28 \fB\fIbp\fR\fR
29 .ad
30 .RS 13n
31 Pointer to the \fBbuf\fR(9S) structure describing the original \fBI/O\fR
32 request.
33 .RE
35 .sp
36 .ne 2
37 .na
38 \fB\fIoff\fR\fR
39 .ad
40 .RS 13n
41 Offset within original \fBI/O\fR request where new \fBI/O\fR request should
42 start.
43 .RE
45 .sp
46 .ne 2
47 .na
48 \fB\fIlen\fR\fR
49 .ad
50 .RS 13n
51 Length of the \fBI/O \fRrequest.
52 .RE
54 .sp
55 .ne 2
56 .na
57 \fB\fIdev\fR\fR
58 .ad
59 .RS 13n
60 Device number.
61 .RE
63 .sp
64 .ne 2
65 .na
66 \fB\fIblkno\fR\fR
67 .ad
68 .RS 13n
69 Block number on device.
70 .RE
72 .sp
73 .ne 2
74 .na
75 \fB\fIiodone\fR\fR
76 .ad
77 .RS 13n
78 Specific \fBbiodone\fR(9F) routine.
79 .RE
81 .sp
82 .ne 2
83 .na
84 \fB\fIbp_mem\fR\fR
85 .ad
86 .RS 13n
87 Pointer to a buffer structure to be filled in or \fBNULL. \fR
88 .RE
90 .sp
91 .ne 2
92 .na
93 \fB\fIsleepflag\fR\fR
94 .ad
95 .RS 13n
96 Determines whether caller can sleep for memory. Possible flags are
97 \fBKM_SLEEP\fR to allow sleeping until memory is available, or \fBKM_NOSLEEP\fR
98 to return \fINULL\fR immediately if memory is not available.
99 .RE
101 .SH DESCRIPTION
104 The \fBbioclone()\fR function returns an initialized buffer to perform
105 \fBI/O\fR to a portion of another buffer. The new buffer will be set up to
106 perform \fBI/O\fR to the range within the original \fBI/O\fR request specified
107 by the parameters \fIoff\fR and \fIlen\fR. An offset \fB0\fR starts the new
108 \fBI/O\fR request at the same address as the original request. \fIoff\fR +
109 \fIlen\fR must not exceed \fIb_bcount,\fR the length of the original request.
110 The device number \fIdev\fR specifies the device to which the buffer is to
111 perform \fBI/O\fR. \fIblkno\fR is the block number on device. It will be
112 assigned to the \fIb_blkno\fR field of the cloned buffer structure.
113 \fIiodone\fR lets the driver identify a specific \fBbiodone\fR(9F) routine to
114 be called by the driver when the \fBI/O\fR is complete. \fIbp_mem\fR determines
115 from where the space for the buffer should be allocated. If \fIbp_mem\fR is
116 \fBNULL\fR, \fBbioclone()\fR will allocate a new buffer using
117 \fBgetrbuf\fR(9F). If \fIsleepflag\fR is set to \fBKM_SLEEP\fR, the driver may
118 sleep until space is freed up. If \fIsleepflag\fR is set to \fBKM_NOSLEEP\fR,
119 the driver will not sleep. In either case, a pointer to the allocated space is
120 returned or \fINULL\fR to indicate that no space was available. After the
121 transfer is completed, the buffer has to be freed using \fBfreerbuf\fR(9F). If
122 \fIbp_mem\fR is not \fINULL\fR, it will be used as the space for the buffer
123 structure. The driver has to ensure that \fIbp_mem\fR is initialized properly
124 either using \fBgetrbuf\fR(9F) or \fBbioinit\fR(9F).
127 If the original buffer is mapped into the kernel virtual address space using
128 \fBbp_mapin\fR(9F) before calling \fBbioclone()\fR, a clone buffer will share
129 the kernel mapping of the original buffer. An additional \fBbp_mapin()\fR to
130 get a kernel mapping for the clone buffer is not necessary.
133 The driver has to ensure that the original buffer is not freed while any of the
134 clone buffers is still performing \fBI/O\fR. The \fBbiodone()\fR function has
135 to be called on all clone buffers \fBbefore\fR it is called on the original
136 buffer.
137 .SH RETURN VALUES
140 The \fBbioclone()\fR function returns a pointer to the initialized buffer
141 header, or \fBNULL\fR if no space is available.
142 .SH CONTEXT
145 The \fBbioclone()\fR function can be called from user, interrup, or interrupt
146 context. Drivers must not allow \fBbioclone()\fR to sleep if called from an
147 interrupt routine.
148 .SH EXAMPLES
150 \fBExample 1 \fRUsing \fBbioclone()\fR for Disk Striping
153 A device driver can use \fBbioclone()\fR for disk striping. For each disk in
154 the stripe, a clone buffer is created which performs \fBI/O\fR to a portion of
155 the original buffer.
158 .in +2
160 static int
161 stripe_strategy(struct buf *bp)
163        ...
164        bp_orig = bp;
165        bp_1 = bioclone(bp_orig, 0, size_1, dev_1, blkno_1,
166                        stripe_done, NULL, KM_SLEEP);
167        fragment++;
168        ...
169        bp_n = bioclone(bp_orig, offset_n, size_n, dev_n,
170                      blkno_n, stripe_done, NULL, KM_SLEEP);
171        fragment++;
172        /* submit bp_1 ... bp_n to device */
173        xxstrategy(bp_x);
174        return (0);
177 static uint_t
178 xxintr(caddr_t arg)
180        ...
181        /*
182        * get bp of completed subrequest. biodone(9F) will
183        * call stripe_done()
184        */
185        biodone(bp);
186        return (0);
189 static int
190 stripe_done(struct buf *bp)
192        ...
193        freerbuf(bp);
194        fragment--;
195        if (fragment == 0) {
196                /* get bp_orig */
197                biodone(bp_orig);
198        }
199        return (0);
202 .in -2
204 .SH SEE ALSO
207 \fBbiodone\fR(9F), \fBbp_mapin\fR(9F), \fBfreerbuf\fR(9F), \fBgetrbuf\fR(9F),
208 \fBbuf\fR(9S)
211 \fIWriting Device Drivers\fR