]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.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);
85         if (bp != NULL) {
86                 bp->b_bufsize = size;
87                 bp->b_bcount = size;
88
89                 KASSERT(BUF_REFCNT(bp) == 1,
90                         ("xfs_buf_get_empty: bp %p not locked",bp));
91
92                 xfs_buf_set_target(bp, target);
93         }
94         return (bp);
95 }
96
97 xfs_buf_t*
98 xfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target)
99 {
100         struct buf *bp;
101         if (len >= MAXPHYS)
102                 return (NULL);
103
104         bp = geteblk(len);
105         if (bp != NULL) {
106                 KASSERT(BUF_REFCNT(bp) == 1,
107                         ("xfs_buf_get_empty: bp %p not locked",bp));
108
109                 xfs_buf_set_target(bp, target);
110         }
111         return (bp);
112 }
113
114 void
115 xfs_buf_free(xfs_buf_t *bp)
116 {
117         bp->b_flags |= B_INVAL;
118         BUF_KERNPROC(bp);                        /* ugly hack #1 */
119         if (bp->b_kvasize == 0) {
120                 bp->b_saveaddr = bp->b_kvabase;  /* ugly hack #2 */
121                 bp->b_data = bp->b_saveaddr;
122                 bp->b_bcount  = 0;
123                 bp->b_bufsize = 0;
124         }
125         brelse(bp);
126 }
127
128 void
129 xfs_buf_readahead(
130                   xfs_buftarg_t         *target,
131                   xfs_daddr_t           ioff,
132                   size_t                isize,
133                   xfs_buf_flags_t       flags)
134 {
135         daddr_t rablkno;
136         int rabsize;
137
138         rablkno = ioff;
139         rabsize = BBTOB(isize);
140         breada(target->specvp, &rablkno, &rabsize, 1, NOCRED);
141 }
142
143 void
144 xfs_buf_set_target(xfs_buf_t *bp, xfs_buftarg_t *targ)
145 {
146         bp->b_bufobj = &targ->specvp->v_bufobj;
147         bp->b_caller1 = targ;
148 }
149
150 xfs_buftarg_t *
151 xfs_buf_get_target(xfs_buf_t *bp)
152 {
153         return (xfs_buftarg_t *)bp->b_caller1;
154 }
155
156 int
157 XFS_bwrite(xfs_buf_t *bp)
158 {
159         int error;
160         if (bp->b_vp == NULL) {
161                 error = xfs_buf_iorequest(bp);
162
163                 if ((bp->b_flags & B_ASYNC) == 0) {
164                         error = bufwait(bp);
165 #if 0
166                         if (BUF_REFCNT(bp) > 1)
167                                 BUF_UNLOCK(bp);
168                         else
169                                 brelse(bp);
170 #endif
171                         brelse(bp);
172                 }
173                 return (error);
174         }
175         error = bwrite(bp);
176         return (error);
177 }
178
179 void
180 xfs_buf_pin(xfs_buf_t *bp)
181 {
182         bpin(bp);
183 }
184
185 void
186 xfs_buf_unpin(xfs_buf_t *bp)
187 {
188         bunpin(bp);
189 }
190
191 int
192 xfs_buf_ispin(xfs_buf_t *bp)
193 {
194         return bp->b_pin_count;
195 }
196
197 #if 0
198 void
199 xfs_buf_wait_unpin(
200         xfs_buf_t *bp)
201 {
202         bunpin_wait(bp);
203 }
204 #endif
205
206 /*
207  *      Move data into or out of a buffer.
208  */
209 void
210 xfs_buf_iomove(
211         xfs_buf_t               *bp,    /* buffer to process            */
212         size_t                  boff,   /* starting buffer offset       */
213         size_t                  bsize,  /* length to copy               */
214         caddr_t                 data,   /* data address                 */
215         xfs_buf_rw_t            mode)   /* read/write/zero flag         */
216 {
217
218   printf("xfs_buf_iomove NI\n");
219 #ifdef RMC
220         size_t                  bend, cpoff, csize;
221         struct page             *page;
222
223         bend = boff + bsize;
224         while (boff < bend) {
225                 page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
226                 cpoff = xfs_buf_poff(boff + bp->b_offset);
227                 csize = min_t(size_t,
228                               PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
229
230                 ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
231
232                 switch (mode) {
233                 case XBRW_ZERO:
234                         memset(page_address(page) + cpoff, 0, csize);
235                         break;
236                 case XBRW_READ:
237                         memcpy(data, page_address(page) + cpoff, csize);
238                         break;
239                 case XBRW_WRITE:
240                         memcpy(page_address(page) + cpoff, data, csize);
241                 }
242
243                 boff += csize;
244                 data += csize;
245         }
246 #endif
247 }
248
249 /*
250  *      Handling of buffer targets (buftargs).
251  */
252
253 /*
254  *      Wait for any bufs with callbacks that have been submitted but
255  *      have not yet returned... walk the hash list for the target.
256  */
257 void
258 xfs_wait_buftarg(
259                  xfs_buftarg_t *bp)
260 {
261         printf("xfs_wait_buftarg(%p) NI\n", bp);
262 }
263
264 int
265 xfs_flush_buftarg(
266         xfs_buftarg_t           *btp,
267         int wait)
268 {
269         int error = 0;
270
271         error = vinvalbuf(btp->specvp, V_SAVE|V_NORMAL, curthread, 0, 0);
272         return error;
273 }
274
275 void
276 xfs_free_buftarg(
277         xfs_buftarg_t           *btp,
278         int                     external)
279 {
280         xfs_flush_buftarg(btp, /* wait */ 0);
281         kmem_free(btp, sizeof(*btp));
282 }
283
284 int
285 xfs_readonly_buftarg(
286         xfs_buftarg_t           *btp)
287 {
288         struct g_consumer *cp;
289
290         KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_bo_ops,
291            ("Bogus xfs_buftarg_t pointer"));
292         cp = btp->specvp->v_bufobj.bo_private;
293         return (cp->acw == 0);
294 }
295
296 #if 0
297 void
298 xfs_relse_buftarg(
299         xfs_buftarg_t           *btp)
300 {
301         printf("xfs_relse_buftargNI %p\n",btp);
302 }
303 #endif
304
305 unsigned int
306 xfs_getsize_buftarg(
307         xfs_buftarg_t           *btp)
308 {
309         struct g_consumer       *cp;
310         cp = btp->specvp->v_bufobj.bo_private;
311         return (cp->provider->sectorsize);
312 }
313
314 int
315 xfs_setsize_buftarg(
316         xfs_buftarg_t           *btp,
317         unsigned int            blocksize,
318         unsigned int            sectorsize)
319 {
320         printf("xfs_setsize_buftarg NI %p\n",btp);
321         return 0;
322 }
323
324 xfs_buftarg_t *
325 xfs_alloc_buftarg(
326                   struct vnode  *bdev,
327                   int           external)
328 {
329         xfs_buftarg_t           *btp;
330
331         btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
332
333         btp->dev    = bdev->v_rdev;
334         btp->specvp = bdev;
335         return btp;
336 }