2 * Copyright (c) 2001,2005 Russell Cattelan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
30 #include "xfs_types.h"
33 #include "xfs_trans.h"
38 #include "xfs_dmapi.h"
39 #include "xfs_mount.h"
41 #include "xfs_mountops.h"
43 #include <geom/geom.h>
44 #include <geom/geom_vfs.h>
47 xfs_buf_read_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
50 KASSERT((target != NULL), ("got NULL buftarg_t"));
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));
58 /* not really sure what B_MANAGED really does for us
59 * maybe we should drop this and just stick with a locked buf
62 if (flags & B_MANAGED)
63 bp->b_flags |= B_MANAGED;
64 xfs_buf_set_target(bp, target);
69 xfs_buf_get_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
71 struct buf *bp = NULL;
72 KASSERT((target != NULL), ("got NULL buftarg_t"));
73 bp = getblk(target->specvp, blkno, BBTOB(len), 0, 0, 0);
75 xfs_buf_set_target(bp, target);
80 xfs_buf_get_empty(size_t size, xfs_buftarg_t *target)
89 KASSERT(BUF_REFCNT(bp) == 1,
90 ("xfs_buf_get_empty: bp %p not locked",bp));
92 xfs_buf_set_target(bp, target);
98 xfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target)
106 KASSERT(BUF_REFCNT(bp) == 1,
107 ("xfs_buf_get_empty: bp %p not locked",bp));
109 xfs_buf_set_target(bp, target);
115 xfs_buf_free(xfs_buf_t *bp)
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;
130 xfs_buftarg_t *target,
133 xfs_buf_flags_t flags)
139 rabsize = BBTOB(isize);
140 breada(target->specvp, &rablkno, &rabsize, 1, NOCRED);
144 xfs_buf_set_target(xfs_buf_t *bp, xfs_buftarg_t *targ)
146 bp->b_bufobj = &targ->specvp->v_bufobj;
147 bp->b_caller1 = targ;
151 xfs_buf_get_target(xfs_buf_t *bp)
153 return (xfs_buftarg_t *)bp->b_caller1;
157 XFS_bwrite(xfs_buf_t *bp)
160 if (bp->b_vp == NULL) {
161 error = xfs_buf_iorequest(bp);
163 if ((bp->b_flags & B_ASYNC) == 0) {
166 if (BUF_REFCNT(bp) > 1)
180 xfs_buf_pin(xfs_buf_t *bp)
186 xfs_buf_unpin(xfs_buf_t *bp)
192 xfs_buf_ispin(xfs_buf_t *bp)
194 return bp->b_pin_count;
207 * Move data into or out of a buffer.
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 */
218 printf("xfs_buf_iomove NI\n");
220 size_t bend, cpoff, csize;
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);
230 ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
234 memset(page_address(page) + cpoff, 0, csize);
237 memcpy(data, page_address(page) + cpoff, csize);
240 memcpy(page_address(page) + cpoff, data, csize);
250 * Handling of buffer targets (buftargs).
254 * Wait for any bufs with callbacks that have been submitted but
255 * have not yet returned... walk the hash list for the target.
261 printf("xfs_wait_buftarg(%p) NI\n", bp);
271 error = vinvalbuf(btp->specvp, V_SAVE|V_NORMAL, curthread, 0, 0);
280 xfs_flush_buftarg(btp, /* wait */ 0);
281 kmem_free(btp, sizeof(*btp));
285 xfs_readonly_buftarg(
288 struct g_consumer *cp;
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);
301 printf("xfs_relse_buftargNI %p\n",btp);
309 struct g_consumer *cp;
310 cp = btp->specvp->v_bufobj.bo_private;
311 return (cp->provider->sectorsize);
317 unsigned int blocksize,
318 unsigned int sectorsize)
320 printf("xfs_setsize_buftarg NI %p\n",btp);
331 btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
333 btp->dev = bdev->v_rdev;