138494Sobrien/* 2174294Sobrien * Copyright (c) 2001,2005 Russell Cattelan 338494Sobrien * All rights reserved. 438494Sobrien * 538494Sobrien * Redistribution and use in source and binary forms, with or without 638494Sobrien * modification, are permitted provided that the following conditions 738494Sobrien * are met: 838494Sobrien * 1. Redistributions of source code must retain the above copyright 938494Sobrien * notice, this list of conditions and the following disclaimer. 1038494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1138494Sobrien * notice, this list of conditions and the following disclaimer in the 1238494Sobrien * documentation and/or other materials provided with the distribution. 1338494Sobrien * 1438494Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1538494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1638494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1738494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1838494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1938494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2042629Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2138494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2238494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2338494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2438494Sobrien * SUCH DAMAGE. 2538494Sobrien * 2638494Sobrien * $FreeBSD$ 2738494Sobrien */ 2838494Sobrien 2938494Sobrien#include "xfs.h" 3038494Sobrien#include "xfs_types.h" 3138494Sobrien#include "xfs_inum.h" 3238494Sobrien#include "xfs_log.h" 3338494Sobrien#include "xfs_trans.h" 3438494Sobrien#include "xfs_sb.h" 3538494Sobrien#include "xfs_ag.h" 3638494Sobrien#include "xfs_dir.h" 3738494Sobrien#include "xfs_dir2.h" 3838494Sobrien#include "xfs_dmapi.h" 3938494Sobrien#include "xfs_mount.h" 40174294Sobrien#include "xfs_clnt.h" 4138494Sobrien#include "xfs_mountops.h" 4238494Sobrien 4338494Sobrien#include <geom/geom.h> 4438494Sobrien#include <geom/geom_vfs.h> 4538494Sobrien 4638494Sobrienxfs_buf_t * 4738494Sobrienxfs_buf_read_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags) 4838494Sobrien{ 4938494Sobrien struct buf *bp; 5038494Sobrien KASSERT((target != NULL), ("got NULL buftarg_t")); 5138494Sobrien 5238494Sobrien if (bread(target->specvp, blkno, BBTOB(len), NOCRED, &bp)) { 5338494Sobrien printf("bread failed specvp %p blkno %qd BBTOB(len) %ld\n", 5438494Sobrien target->specvp, blkno, (long)BBTOB(len)); 5538494Sobrien bp = NULL; 5638494Sobrien } 5738494Sobrien 5838494Sobrien /* not really sure what B_MANAGED really does for us 5938494Sobrien * maybe we should drop this and just stick with a locked buf 6038494Sobrien */ 6138494Sobrien 6238494Sobrien if (flags & B_MANAGED) 6338494Sobrien bp->b_flags |= B_MANAGED; 6438494Sobrien xfs_buf_set_target(bp, target); 6538494Sobrien return (bp); 66174294Sobrien} 6738494Sobrien 6838494Sobrienxfs_buf_t * 6938494Sobrienxfs_buf_get_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags) 7038494Sobrien{ 7138494Sobrien struct buf *bp = NULL; 7238494Sobrien KASSERT((target != NULL), ("got NULL buftarg_t")); 7338494Sobrien bp = getblk(target->specvp, blkno, BBTOB(len), 0, 0, 0); 7438494Sobrien if (bp != NULL) 7538494Sobrien xfs_buf_set_target(bp, target); 7638494Sobrien return (bp); 7738494Sobrien} 7838494Sobrien 7938494Sobrienxfs_buf_t* 8038494Sobrienxfs_buf_get_empty(size_t size, xfs_buftarg_t *target) 8138494Sobrien{ 8238494Sobrien struct buf *bp; 8338494Sobrien 8438494Sobrien bp = geteblk(0, 0); 8538494Sobrien if (bp != NULL) { 8638494Sobrien bp->b_bufsize = size; 8738494Sobrien bp->b_bcount = size; 8838494Sobrien 8938494Sobrien BUF_ASSERT_HELD(bp); 9038494Sobrien 9138494Sobrien xfs_buf_set_target(bp, target); 9238494Sobrien } 9338494Sobrien return (bp); 94174294Sobrien} 9538494Sobrien 9638494Sobrienxfs_buf_t* 9738494Sobrienxfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target) 9838494Sobrien{ 9938494Sobrien struct buf *bp; 100174294Sobrien if (len >= MAXPHYS) 10138494Sobrien return (NULL); 10238494Sobrien 10338494Sobrien bp = geteblk(len, 0); 10438494Sobrien if (bp != NULL) { 10538494Sobrien BUF_ASSERT_HELD(bp); 10638494Sobrien 107174294Sobrien xfs_buf_set_target(bp, target); 108174294Sobrien } 109174294Sobrien return (bp); 110174294Sobrien} 111174294Sobrien 112174294Sobrienvoid 113174294Sobrienxfs_buf_free(xfs_buf_t *bp) 11438494Sobrien{ 11538494Sobrien bp->b_flags |= B_INVAL; 11638494Sobrien BUF_KERNPROC(bp); /* ugly hack #1 */ 11738494Sobrien if (bp->b_kvasize == 0) { 11838494Sobrien bp->b_saveaddr = bp->b_kvabase; /* ugly hack #2 */ 11938494Sobrien bp->b_data = bp->b_saveaddr; 12038494Sobrien bp->b_bcount = 0; 12138494Sobrien bp->b_bufsize = 0; 12238494Sobrien } 12338494Sobrien brelse(bp); 12438494Sobrien} 12538494Sobrien 12638494Sobrienvoid 12738494Sobrienxfs_buf_readahead( 128174294Sobrien xfs_buftarg_t *target, 129174294Sobrien xfs_daddr_t ioff, 130174294Sobrien size_t isize, 131174294Sobrien xfs_buf_flags_t flags) 13238494Sobrien{ 13338494Sobrien daddr_t rablkno; 13438494Sobrien int rabsize; 13538494Sobrien 13638494Sobrien rablkno = ioff; 137174294Sobrien rabsize = BBTOB(isize); 138174294Sobrien breada(target->specvp, &rablkno, &rabsize, 1, NOCRED); 139174294Sobrien} 140174294Sobrien 141174294Sobrienvoid 14238494Sobrienxfs_buf_set_target(xfs_buf_t *bp, xfs_buftarg_t *targ) 14338494Sobrien{ 14438494Sobrien bp->b_bufobj = &targ->specvp->v_bufobj; 14538494Sobrien bp->b_caller1 = targ; 146174294Sobrien} 14738494Sobrien 14838494Sobrienxfs_buftarg_t * 149174294Sobrienxfs_buf_get_target(xfs_buf_t *bp) 15038494Sobrien{ 15138494Sobrien return (xfs_buftarg_t *)bp->b_caller1; 15238494Sobrien} 15338494Sobrien 15438494Sobrienint 15538494SobrienXFS_bwrite(xfs_buf_t *bp) 15638494Sobrien{ 15738494Sobrien int error; 15838494Sobrien if (bp->b_vp == NULL) { 15951292Sobrien error = xfs_buf_iorequest(bp); 16038494Sobrien 16138494Sobrien if ((bp->b_flags & B_ASYNC) == 0) { 16238494Sobrien error = bufwait(bp); 16338494Sobrien#if 0 16438494Sobrien if (BUF_LOCKRECURSED(bp)) 16538494Sobrien BUF_UNLOCK(bp); 16638494Sobrien else 16738494Sobrien brelse(bp); 16838494Sobrien#endif 16938494Sobrien brelse(bp); 17038494Sobrien } 17138494Sobrien return (error); 17238494Sobrien } 17338494Sobrien error = bwrite(bp); 174174294Sobrien return (error); 17538494Sobrien} 17638494Sobrien 177174294Sobrienvoid 17838494Sobrienxfs_buf_pin(xfs_buf_t *bp) 17938494Sobrien{ 180174294Sobrien bpin(bp); 181174294Sobrien} 182174294Sobrien 183174294Sobrienvoid 18438494Sobrienxfs_buf_unpin(xfs_buf_t *bp) 185174294Sobrien{ 18638494Sobrien bunpin(bp); 18738494Sobrien} 18838494Sobrien 18938494Sobrienint 19038494Sobrienxfs_buf_ispin(xfs_buf_t *bp) 19138494Sobrien{ 19238494Sobrien return bp->b_pin_count; 19338494Sobrien} 194174294Sobrien 195174294Sobrien#if 0 196174294Sobrienvoid 197174294Sobrienxfs_buf_wait_unpin( 198174294Sobrien xfs_buf_t *bp) 199174294Sobrien{ 200174294Sobrien bunpin_wait(bp); 201174294Sobrien} 202174294Sobrien#endif 203174294Sobrien 204174294Sobrien/* 20538494Sobrien * Move data into or out of a buffer. 206174294Sobrien */ 207174294Sobrienvoid 20838494Sobrienxfs_buf_iomove( 209174294Sobrien xfs_buf_t *bp, /* buffer to process */ 210174294Sobrien size_t boff, /* starting buffer offset */ 211174294Sobrien size_t bsize, /* length to copy */ 212174294Sobrien caddr_t data, /* data address */ 213174294Sobrien xfs_buf_rw_t mode) /* read/write/zero flag */ 21438494Sobrien{ 21538494Sobrien 21638494Sobrien printf("xfs_buf_iomove NI\n"); 217174294Sobrien#ifdef RMC 218174294Sobrien size_t bend, cpoff, csize; 219174294Sobrien struct page *page; 220174294Sobrien 221174294Sobrien bend = boff + bsize; 222174294Sobrien while (boff < bend) { 223174294Sobrien page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)]; 224174294Sobrien cpoff = xfs_buf_poff(boff + bp->b_offset); 225174294Sobrien csize = min_t(size_t, 22638494Sobrien PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff); 227174294Sobrien 228174294Sobrien ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE)); 229174294Sobrien 230174294Sobrien switch (mode) { 231174294Sobrien case XBRW_ZERO: 232174294Sobrien memset(page_address(page) + cpoff, 0, csize); 233174294Sobrien break; 234174294Sobrien case XBRW_READ: 235174294Sobrien memcpy(data, page_address(page) + cpoff, csize); 236174294Sobrien break; 237174294Sobrien case XBRW_WRITE: 238174294Sobrien memcpy(page_address(page) + cpoff, data, csize); 239174294Sobrien } 240174294Sobrien 241174294Sobrien boff += csize; 242174294Sobrien data += csize; 243174294Sobrien } 244174294Sobrien#endif 245174294Sobrien} 246174294Sobrien 247174294Sobrien/* 248174294Sobrien * Handling of buffer targets (buftargs). 249174294Sobrien */ 250174294Sobrien 251174294Sobrien/* 252174294Sobrien * Wait for any bufs with callbacks that have been submitted but 253174294Sobrien * have not yet returned... walk the hash list for the target. 254174294Sobrien */ 255174294Sobrienvoid 256174294Sobrienxfs_wait_buftarg( 257174294Sobrien xfs_buftarg_t *bp) 258174294Sobrien{ 259174294Sobrien printf("xfs_wait_buftarg(%p) NI\n", bp); 260174294Sobrien} 261174294Sobrien 262174294Sobrienint 263174294Sobrienxfs_flush_buftarg( 264174294Sobrien xfs_buftarg_t *btp, 265174294Sobrien int wait) 266174294Sobrien{ 267174294Sobrien int error = 0; 268174294Sobrien 269174294Sobrien error = vinvalbuf(btp->specvp, V_SAVE | V_NORMAL, 0, 0); 270174294Sobrien return error; 271174294Sobrien} 272174294Sobrien 273174294Sobrienvoid 274174294Sobrienxfs_free_buftarg( 275174294Sobrien xfs_buftarg_t *btp, 276174294Sobrien int external) 277174294Sobrien{ 278174294Sobrien xfs_flush_buftarg(btp, /* wait */ 0); 279174294Sobrien kmem_free(btp, sizeof(*btp)); 280174294Sobrien} 281174294Sobrien 282174294Sobrienint 28338494Sobrienxfs_readonly_buftarg( 284174294Sobrien xfs_buftarg_t *btp) 285174294Sobrien{ 286174294Sobrien struct g_consumer *cp; 28738494Sobrien 288174294Sobrien KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_bo_ops, 28938494Sobrien ("Bogus xfs_buftarg_t pointer")); 290174294Sobrien cp = btp->specvp->v_bufobj.bo_private; 291174294Sobrien return (cp->acw == 0); 292174294Sobrien} 293174294Sobrien 294174294Sobrien#if 0 295174294Sobrienvoid 296174294Sobrienxfs_relse_buftarg( 297174294Sobrien xfs_buftarg_t *btp) 29838494Sobrien{ 29938494Sobrien printf("xfs_relse_buftargNI %p\n",btp); 30038494Sobrien} 30138494Sobrien#endif 30238494Sobrien 30338494Sobrienunsigned int 30438494Sobrienxfs_getsize_buftarg( 30538494Sobrien xfs_buftarg_t *btp) 30638494Sobrien{ 307174294Sobrien struct g_consumer *cp; 308174294Sobrien cp = btp->specvp->v_bufobj.bo_private; 309174294Sobrien return (cp->provider->sectorsize); 310174294Sobrien} 311174294Sobrien 312174294Sobrienint 31338494Sobrienxfs_setsize_buftarg( 31438494Sobrien xfs_buftarg_t *btp, 31538494Sobrien unsigned int blocksize, 31638494Sobrien unsigned int sectorsize) 31738494Sobrien{ 31838494Sobrien printf("xfs_setsize_buftarg NI %p\n",btp); 31938494Sobrien return 0; 320174294Sobrien} 32138494Sobrien 322174294Sobrienxfs_buftarg_t * 32338494Sobrienxfs_alloc_buftarg( 32438494Sobrien struct vnode *bdev, 32538494Sobrien int external) 32638494Sobrien{ 32738494Sobrien xfs_buftarg_t *btp; 32838494Sobrien 32938494Sobrien btp = kmem_zalloc(sizeof(*btp), KM_SLEEP); 33038494Sobrien 33138494Sobrien btp->dev = bdev->v_rdev; 33238494Sobrien btp->specvp = bdev; 33338494Sobrien return btp; 33438494Sobrien} 33538494Sobrien