]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / gnu / fs / xfs / FreeBSD / xfs_buf.c
1 /*
2  * Copyright (c) 2001,2005 Russell Cattelan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include "xfs.h"
30 #include "xfs_types.h"
31 #include "xfs_inum.h"
32 #include "xfs_log.h"
33 #include "xfs_trans.h"
34 #include "xfs_sb.h"
35 #include "xfs_ag.h"
36 #include "xfs_dir.h"
37 #include "xfs_dir2.h"
38 #include "xfs_dmapi.h"
39 #include "xfs_mount.h"
40 #include "xfs_clnt.h"
41 #include "xfs_mountops.h"
42
43 #include <geom/geom.h>
44 #include <geom/geom_vfs.h>
45
46 xfs_buf_t *
47 xfs_buf_read_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
48 {
49         struct buf *bp;
50         KASSERT((target != NULL), ("got NULL buftarg_t"));
51
52         if (bread(target->specvp, blkno, BBTOB(len), NOCRED, &bp)) {
53                 printf("bread failed specvp %p blkno %qd BBTOB(len) %ld\n",
54                        target->specvp, blkno, (long)BBTOB(len));
55                 bp = NULL;
56         }
57
58         /* not really sure what B_MANAGED really does for us
59          * maybe we should drop this and just stick with a locked buf
60          */
61
62         if (flags & B_MANAGED)
63                 bp->b_flags |= B_MANAGED;
64         xfs_buf_set_target(bp, target);
65         return (bp);
66 }
67
68 xfs_buf_t *
69 xfs_buf_get_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
70 {
71         struct buf *bp = NULL;
72         KASSERT((target != NULL), ("got NULL buftarg_t"));
73         bp = getblk(target->specvp, blkno, BBTOB(len), 0, 0, 0);
74         if (bp != NULL)
75                 xfs_buf_set_target(bp, target);
76         return (bp);
77 }
78
79 xfs_buf_t*
80 xfs_buf_get_empty(size_t size,  xfs_buftarg_t *target)
81 {
82         struct buf *bp;
83
84         bp = geteblk(0, 0);
85         if (bp != NULL) {
86                 bp->b_bufsize = size;
87                 bp->b_bcount = size;
88
89                 BUF_ASSERT_HELD(bp);
90
91                 xfs_buf_set_target(bp, target);
92         }
93         return (bp);
94 }
95
96 xfs_buf_t*
97 xfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target)
98 {
99         struct buf *bp;
100         if (len >= MAXPHYS)
101                 return (NULL);
102
103         bp = geteblk(len, 0);
104         if (bp != NULL) {
105                 BUF_ASSERT_HELD(bp);
106
107                 xfs_buf_set_target(bp, target);
108         }
109         return (bp);
110 }
111
112 void
113 xfs_buf_free(xfs_buf_t *bp)
114 {
115         bp->b_flags |= B_INVAL;
116         BUF_KERNPROC(bp);                        /* ugly hack #1 */
117         if (bp->b_kvasize == 0) {
118                 bp->b_saveaddr = bp->b_kvabase;  /* ugly hack #2 */
119                 bp->b_data = bp->b_saveaddr;
120                 bp->b_bcount  = 0;
121                 bp->b_bufsize = 0;
122         }
123         brelse(bp);
124 }
125
126 void
127 xfs_buf_readahead(
128                   xfs_buftarg_t         *target,
129                   xfs_daddr_t           ioff,
130                   size_t                isize,
131                   xfs_buf_flags_t       flags)
132 {
133         daddr_t rablkno;
134         int rabsize;
135
136         rablkno = ioff;
137         rabsize = BBTOB(isize);
138         breada(target->specvp, &rablkno, &rabsize, 1, NOCRED);
139 }
140
141 void
142 xfs_buf_set_target(xfs_buf_t *bp, xfs_buftarg_t *targ)
143 {
144         bp->b_bufobj = &targ->specvp->v_bufobj;
145         bp->b_caller1 = targ;
146 }
147
148 xfs_buftarg_t *
149 xfs_buf_get_target(xfs_buf_t *bp)
150 {
151         return (xfs_buftarg_t *)bp->b_caller1;
152 }
153
154 int
155 XFS_bwrite(xfs_buf_t *bp)
156 {
157         int error;
158         if (bp->b_vp == NULL) {
159                 error = xfs_buf_iorequest(bp);
160
161                 if ((bp->b_flags & B_ASYNC) == 0) {
162                         error = bufwait(bp);
163 #if 0
164                         if (BUF_LOCKRECURSED(bp))
165                                 BUF_UNLOCK(bp);
166                         else
167                                 brelse(bp);
168 #endif
169                         brelse(bp);
170                 }
171                 return (error);
172         }
173         error = bwrite(bp);
174         return (error);
175 }
176
177 void
178 xfs_buf_pin(xfs_buf_t *bp)
179 {
180         bpin(bp);
181 }
182
183 void
184 xfs_buf_unpin(xfs_buf_t *bp)
185 {
186         bunpin(bp);
187 }
188
189 int
190 xfs_buf_ispin(xfs_buf_t *bp)
191 {
192         return bp->b_pin_count;
193 }
194
195 #if 0
196 void
197 xfs_buf_wait_unpin(
198         xfs_buf_t *bp)
199 {
200         bunpin_wait(bp);
201 }
202 #endif
203
204 /*
205  *      Move data into or out of a buffer.
206  */
207 void
208 xfs_buf_iomove(
209         xfs_buf_t               *bp,    /* buffer to process            */
210         size_t                  boff,   /* starting buffer offset       */
211         size_t                  bsize,  /* length to copy               */
212         caddr_t                 data,   /* data address                 */
213         xfs_buf_rw_t            mode)   /* read/write/zero flag         */
214 {
215
216   printf("xfs_buf_iomove NI\n");
217 #ifdef RMC
218         size_t                  bend, cpoff, csize;
219         struct page             *page;
220
221         bend = boff + bsize;
222         while (boff < bend) {
223                 page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
224                 cpoff = xfs_buf_poff(boff + bp->b_offset);
225                 csize = min_t(size_t,
226                               PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
227
228                 ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
229
230                 switch (mode) {
231                 case XBRW_ZERO:
232                         memset(page_address(page) + cpoff, 0, csize);
233                         break;
234                 case XBRW_READ:
235                         memcpy(data, page_address(page) + cpoff, csize);
236                         break;
237                 case XBRW_WRITE:
238                         memcpy(page_address(page) + cpoff, data, csize);
239                 }
240
241                 boff += csize;
242                 data += csize;
243         }
244 #endif
245 }
246
247 /*
248  *      Handling of buffer targets (buftargs).
249  */
250
251 /*
252  *      Wait for any bufs with callbacks that have been submitted but
253  *      have not yet returned... walk the hash list for the target.
254  */
255 void
256 xfs_wait_buftarg(
257                  xfs_buftarg_t *bp)
258 {
259         printf("xfs_wait_buftarg(%p) NI\n", bp);
260 }
261
262 int
263 xfs_flush_buftarg(
264         xfs_buftarg_t           *btp,
265         int wait)
266 {
267         int error = 0;
268
269         error = vinvalbuf(btp->specvp, V_SAVE | V_NORMAL, 0, 0);
270         return error;
271 }
272
273 void
274 xfs_free_buftarg(
275         xfs_buftarg_t           *btp,
276         int                     external)
277 {
278         xfs_flush_buftarg(btp, /* wait */ 0);
279         kmem_free(btp, sizeof(*btp));
280 }
281
282 int
283 xfs_readonly_buftarg(
284         xfs_buftarg_t           *btp)
285 {
286         struct g_consumer *cp;
287
288         KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_bo_ops,
289            ("Bogus xfs_buftarg_t pointer"));
290         cp = btp->specvp->v_bufobj.bo_private;
291         return (cp->acw == 0);
292 }
293
294 #if 0
295 void
296 xfs_relse_buftarg(
297         xfs_buftarg_t           *btp)
298 {
299         printf("xfs_relse_buftargNI %p\n",btp);
300 }
301 #endif
302
303 unsigned int
304 xfs_getsize_buftarg(
305         xfs_buftarg_t           *btp)
306 {
307         struct g_consumer       *cp;
308         cp = btp->specvp->v_bufobj.bo_private;
309         return (cp->provider->sectorsize);
310 }
311
312 int
313 xfs_setsize_buftarg(
314         xfs_buftarg_t           *btp,
315         unsigned int            blocksize,
316         unsigned int            sectorsize)
317 {
318         printf("xfs_setsize_buftarg NI %p\n",btp);
319         return 0;
320 }
321
322 xfs_buftarg_t *
323 xfs_alloc_buftarg(
324                   struct vnode  *bdev,
325                   int           external)
326 {
327         xfs_buftarg_t           *btp;
328
329         btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
330
331         btp->dev    = bdev->v_rdev;
332         btp->specvp = bdev;
333         return btp;
334 }