1bioclone(9F)             Kernel Functions for Drivers             bioclone(9F)
2
3
4

NAME

6       bioclone - clone another buffer
7

SYNOPSIS

9       #include <sys/ddi.h>
10       #include <sys/sunddi.h>
11
12       struct buf *bioclone(struct buf *bp, off_t off, size_t len, dev_t dev,
13            daddr_t blkno, int (*iodone) (struct buf *), struct buf *bp_mem,
14            int sleepflag);
15
16

INTERFACE LEVEL

18       Solaris DDI specific (Solaris DDI).
19

PARAMETERS

21       bp           Pointer  to  the buf(9S) structure describing the original
22                    I/O request.
23
24
25       off          Offset within original I/O request where new  I/O  request
26                    should start.
27
28
29       len          Length of the I/O request.
30
31
32       dev          Device number.
33
34
35       blkno        Block number on device.
36
37
38       iodone       Specific biodone(9F) routine.
39
40
41       bp_mem       Pointer to a buffer structure to be filled in or NULL.
42
43
44       sleepflag    Determines  whether  caller can sleep for memory. Possible
45                    flags are KM_SLEEP  to  allow  sleeping  until  memory  is
46                    available,  or  KM_NOSLEEP  to  return NULL immediately if
47                    memory is not available.
48
49

DESCRIPTION

51       The bioclone() function returns an initialized buffer to perform I/O to
52       a  portion  of another buffer. The new buffer will be set up to perform
53       I/O to the range within the  original  I/O  request  specified  by  the
54       parameters  off  and len. An offset 0 starts the new I/O request at the
55       same address as the  original  request.  off  +  len  must  not  exceed
56       b_bcount,  the  length  of  the original request. The device number dev
57       specifies the device to which the buffer is to perform  I/O.  blkno  is
58       the block number on device. It will be assigned to the b_blkno field of
59       the cloned buffer structure. iodone lets the driver identify a specific
60       biodone(9F)  routine  to  be  called by the driver when the I/O is com‐
61       plete. bp_mem determines from where the space for the buffer should  be
62       allocated.  If  bp_mem  is  NULL, bioclone() will allocate a new buffer
63       using getrbuf(9F). If sleepflag is set  to  KM_SLEEP,  the  driver  may
64       sleep  until  space is freed up. If sleepflag is set to KM_NOSLEEP, the
65       driver will not sleep. In either case, a pointer to the allocated space
66       is  returned or NULL to indicate that no space was available. After the
67       transfer is completed, the buffer has to be freed  using  freerbuf(9F).
68       If  bp_mem  is  not  NULL,  it will be used as the space for the buffer
69       structure. The driver has to ensure that bp_mem is initialized properly
70       either using getrbuf(9F) or bioinit(9F).
71
72
73       If  the original buffer is mapped into the kernel virtual address space
74       using bp_mapin(9F) before calling bioclone(), a clone buffer will share
75       the  kernel mapping of the original buffer. An additional bp_mapin() to
76       get a kernel mapping for the clone buffer is not necessary.
77
78
79       The driver has to ensure that the original buffer is  not  freed  while
80       any  of  the clone buffers is still performing I/O. The biodone() func‐
81       tion has to be called on all clone buffers before it is called  on  the
82       original buffer.
83

RETURN VALUES

85       The  bioclone()  function  returns  a pointer to the initialized buffer
86       header, or NULL if no space is available.
87

CONTEXT

89       The bioclone() function can be called from user, interrup, or interrupt
90       context.  Drivers  must not allow bioclone() to sleep if called from an
91       interrupt routine.
92

EXAMPLES

94       Example 1 Using bioclone() for Disk Striping
95
96
97       A device driver can use bioclone() for disk striping. For each disk  in
98       the  stripe,  a clone buffer is created which performs I/O to a portion
99       of the original buffer.
100
101
102         static int
103         stripe_strategy(struct buf *bp)
104         {
105                ...
106                bp_orig = bp;
107                bp_1 = bioclone(bp_orig, 0, size_1, dev_1, blkno_1,
108                                stripe_done, NULL, KM_SLEEP);
109                fragment++;
110                ...
111                bp_n = bioclone(bp_orig, offset_n, size_n, dev_n,
112                              blkno_n, stripe_done, NULL, KM_SLEEP);
113                fragment++;
114                /* submit bp_1 ... bp_n to device */
115                xxstrategy(bp_x);
116                return (0);
117         }
118
119         static uint_t
120         xxintr(caddr_t arg)
121         {
122                ...
123                /*
124                * get bp of completed subrequest. biodone(9F) will
125                * call stripe_done()
126                */
127                biodone(bp);
128                return (0);
129         }
130
131         static int
132         stripe_done(struct buf *bp)
133         {
134                ...
135                freerbuf(bp);
136                fragment--;
137                if (fragment == 0) {
138                        /* get bp_orig */
139                        biodone(bp_orig);
140                }
141                return (0);
142         }
143
144

SEE ALSO

146       biodone(9F), bp_mapin(9F), freerbuf(9F), getrbuf(9F), buf(9S)
147
148
149       Writing Device Drivers
150
151
152
153SunOS 5.11                        16 Jan 2006                     bioclone(9F)
Impressum