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 46xfs_buf_t * 47xfs_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 68xfs_buf_t * 69xfs_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 79xfs_buf_t* 80xfs_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 96xfs_buf_t* 97xfs_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 112void 113xfs_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 126void 127xfs_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 141void 142xfs_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 148xfs_buftarg_t * 149xfs_buf_get_target(xfs_buf_t *bp) 150{ 151 return (xfs_buftarg_t *)bp->b_caller1; 152} 153 154int 155XFS_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 177void 178xfs_buf_pin(xfs_buf_t *bp) 179{ 180 bpin(bp); 181} 182 183void 184xfs_buf_unpin(xfs_buf_t *bp) 185{ 186 bunpin(bp); 187} 188 189int 190xfs_buf_ispin(xfs_buf_t *bp) 191{ 192 return bp->b_pin_count; 193} 194 195#if 0 196void 197xfs_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 */ 207void 208xfs_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 */ 255void 256xfs_wait_buftarg( 257 xfs_buftarg_t *bp) 258{ 259 printf("xfs_wait_buftarg(%p) NI\n", bp); 260} 261 262int 263xfs_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 273void 274xfs_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 282int 283xfs_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 295void 296xfs_relse_buftarg( 297 xfs_buftarg_t *btp) 298{ 299 printf("xfs_relse_buftargNI %p\n",btp); 300} 301#endif 302 303unsigned int 304xfs_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 312int 313xfs_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 322xfs_buftarg_t * 323xfs_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} 335