1235537Sgber/*- 2235537Sgber * Copyright (c) 2010-2012 Semihalf 3235537Sgber * Copyright (c) 2008, 2009 Reinoud Zandijk 4235537Sgber * All rights reserved. 5235537Sgber * 6235537Sgber * Redistribution and use in source and binary forms, with or without 7235537Sgber * modification, are permitted provided that the following conditions 8235537Sgber * are met: 9235537Sgber * 1. Redistributions of source code must retain the above copyright 10235537Sgber * notice, this list of conditions and the following disclaimer. 11235537Sgber * 2. Redistributions in binary form must reproduce the above copyright 12235537Sgber * notice, this list of conditions and the following disclaimer in the 13235537Sgber * documentation and/or other materials provided with the distribution. 14235537Sgber * 15235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16235537Sgber * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17235537Sgber * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18235537Sgber * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19235537Sgber * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20235537Sgber * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21235537Sgber * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22235537Sgber * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23235537Sgber * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24235537Sgber * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25235537Sgber * 26235537Sgber * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud 27235537Sgber */ 28235537Sgber 29235537Sgber#include <sys/cdefs.h> 30235537Sgber__FBSDID("$FreeBSD$"); 31235537Sgber 32235537Sgber#include <sys/param.h> 33235537Sgber#include <sys/systm.h> 34235537Sgber#include <sys/namei.h> 35235537Sgber#include <sys/kernel.h> 36235537Sgber#include <sys/stat.h> 37235537Sgber#include <sys/buf.h> 38235537Sgber#include <sys/bio.h> 39235537Sgber#include <sys/proc.h> 40235537Sgber#include <sys/mount.h> 41235537Sgber#include <sys/vnode.h> 42235537Sgber#include <sys/signalvar.h> 43235537Sgber#include <sys/malloc.h> 44235537Sgber#include <sys/dirent.h> 45235537Sgber#include <sys/lockf.h> 46235537Sgber#include <sys/ktr.h> 47235537Sgber 48235537Sgber#include <vm/vm.h> 49235537Sgber#include <vm/vm_extern.h> 50235537Sgber#include <vm/vm_object.h> 51235537Sgber#include <vm/vnode_pager.h> 52235537Sgber 53235537Sgber#include <machine/_inttypes.h> 54235537Sgber 55235537Sgber#include <vm/vm.h> 56235537Sgber#include <vm/vm_extern.h> 57235537Sgber#include <vm/vm_object.h> 58235537Sgber#include <vm/vnode_pager.h> 59235537Sgber 60235537Sgber#include "nandfs_mount.h" 61235537Sgber#include "nandfs.h" 62235537Sgber#include "nandfs_subr.h" 63235537Sgber#include "bmap.h" 64235537Sgber 65235537Sgbernandfs_lbn_t 66235537Sgbernandfs_get_maxfilesize(struct nandfs_device *fsdev) 67235537Sgber{ 68235537Sgber 69235537Sgber return (get_maxfilesize(fsdev)); 70235537Sgber} 71235537Sgber 72235537Sgberint 73235537Sgbernandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, 74235537Sgber nandfs_daddr_t *vblk) 75235537Sgber{ 76235537Sgber int error = 0; 77235537Sgber 78235537Sgber if (node->nn_ino == NANDFS_GC_INO && lblk >= 0) 79235537Sgber *vblk = lblk; 80235537Sgber else 81235537Sgber error = bmap_lookup(node, lblk, vblk); 82235537Sgber 83235537Sgber DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n", 84235537Sgber __func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk, 85235537Sgber (uintmax_t)*vblk)); 86235537Sgber 87235537Sgber if (error) 88235537Sgber nandfs_error("%s: returned %d", __func__, error); 89235537Sgber 90235537Sgber return (error); 91235537Sgber} 92235537Sgber 93235537Sgberint 94235537Sgbernandfs_bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, 95235537Sgber struct buf *bp) 96235537Sgber{ 97235537Sgber struct nandfs_device *fsdev; 98235537Sgber nandfs_daddr_t vblk; 99235537Sgber int error; 100235537Sgber 101235537Sgber fsdev = node->nn_nandfsdev; 102235537Sgber 103235537Sgber vblk = 0; 104235537Sgber if (node->nn_ino != NANDFS_DAT_INO) { 105235537Sgber error = nandfs_vblock_alloc(fsdev, &vblk); 106235537Sgber if (error) 107235537Sgber return (error); 108235537Sgber } 109235537Sgber 110235537Sgber nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED); 111235537Sgber nandfs_vblk_set(bp, vblk); 112235537Sgber 113235537Sgber error = bmap_insert_block(node, lblk, vblk); 114235537Sgber if (error) { 115235537Sgber nandfs_vblock_free(fsdev, vblk); 116235537Sgber return (error); 117235537Sgber } 118235537Sgber 119235537Sgber return (0); 120235537Sgber} 121235537Sgber 122235537Sgberint 123235537Sgbernandfs_bmap_dirty_blocks(struct nandfs_node *node, struct buf *bp, int force) 124235537Sgber{ 125235537Sgber int error; 126235537Sgber 127235537Sgber error = bmap_dirty_meta(node, bp->b_lblkno, force); 128235537Sgber if (error) 129235537Sgber nandfs_error("%s: cannot dirty buffer %p\n", 130235537Sgber __func__, bp); 131235537Sgber 132235537Sgber return (error); 133235537Sgber} 134235537Sgber 135235537Sgberstatic int 136235537Sgbernandfs_bmap_update_mapping(struct nandfs_node *node, nandfs_lbn_t lblk, 137235537Sgber nandfs_daddr_t blknr) 138235537Sgber{ 139235537Sgber int error; 140235537Sgber 141235537Sgber DPRINTF(BMAP, 142235537Sgber ("%s: node: %p ino: %#jx lblk: %#jx vblk: %#jx\n", 143235537Sgber __func__, node, (uintmax_t)node->nn_ino, (uintmax_t)lblk, 144235537Sgber (uintmax_t)blknr)); 145235537Sgber 146235537Sgber error = bmap_insert_block(node, lblk, blknr); 147235537Sgber 148235537Sgber return (error); 149235537Sgber} 150235537Sgber 151235537Sgberint 152235537Sgbernandfs_bmap_update_block(struct nandfs_node *node, struct buf *bp, 153235537Sgber nandfs_lbn_t blknr) 154235537Sgber{ 155235537Sgber nandfs_lbn_t lblk; 156235537Sgber int error; 157235537Sgber 158235537Sgber lblk = bp->b_lblkno; 159235537Sgber nandfs_vblk_set(bp, blknr); 160235537Sgber 161235537Sgber DPRINTF(BMAP, ("%s: node: %p ino: %#jx bp: %p lblk: %#jx blk: %#jx\n", 162235537Sgber __func__, node, (uintmax_t)node->nn_ino, bp, 163235537Sgber (uintmax_t)lblk, (uintmax_t)blknr)); 164235537Sgber 165235537Sgber error = nandfs_bmap_update_mapping(node, lblk, blknr); 166235537Sgber if (error) { 167235537Sgber nandfs_error("%s: cannot update lblk:%jx to blk:%jx for " 168235537Sgber "node:%p, error:%d\n", __func__, (uintmax_t)lblk, 169235537Sgber (uintmax_t)blknr, node, error); 170235537Sgber return (error); 171235537Sgber } 172235537Sgber 173235537Sgber return (error); 174235537Sgber} 175235537Sgber 176235537Sgberint 177235537Sgbernandfs_bmap_update_dat(struct nandfs_node *node, nandfs_daddr_t oldblk, 178235537Sgber struct buf *bp) 179235537Sgber{ 180235537Sgber struct nandfs_device *fsdev; 181235537Sgber nandfs_daddr_t vblk = 0; 182235537Sgber int error; 183235537Sgber 184235537Sgber if (node->nn_ino == NANDFS_DAT_INO) 185235537Sgber return (0); 186235537Sgber 187235537Sgber if (nandfs_buf_check(bp, NANDFS_VBLK_ASSIGNED)) { 188235537Sgber nandfs_buf_clear(bp, NANDFS_VBLK_ASSIGNED); 189235537Sgber return (0); 190235537Sgber } 191235537Sgber 192235537Sgber fsdev = node->nn_nandfsdev; 193235537Sgber 194235537Sgber /* First alloc new virtual block.... */ 195235537Sgber error = nandfs_vblock_alloc(fsdev, &vblk); 196235537Sgber if (error) 197235537Sgber return (error); 198235537Sgber 199235537Sgber error = nandfs_bmap_update_block(node, bp, vblk); 200235537Sgber if (error) 201235537Sgber return (error); 202235537Sgber 203235537Sgber /* Then we can end up with old one */ 204235537Sgber nandfs_vblock_end(fsdev, oldblk); 205235537Sgber 206235537Sgber DPRINTF(BMAP, 207235537Sgber ("%s: ino %#jx block %#jx: update vblk %#jx to %#jx\n", 208235537Sgber __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno, 209235537Sgber (uintmax_t)oldblk, (uintmax_t)vblk)); 210235537Sgber return (error); 211235537Sgber} 212235537Sgber 213235537Sgberint 214235537Sgbernandfs_bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t oblk, 215235537Sgber nandfs_lbn_t nblk) 216235537Sgber{ 217235537Sgber nandfs_lbn_t todo; 218235537Sgber int error; 219235537Sgber 220235537Sgber todo = oblk - nblk; 221235537Sgber 222235537Sgber DPRINTF(BMAP, ("%s: node %p oblk %jx nblk %jx truncate by %jx\n", 223235537Sgber __func__, node, oblk, nblk, todo)); 224235537Sgber 225235537Sgber error = bmap_truncate_mapping(node, oblk, todo); 226235537Sgber if (error) 227235537Sgber return (error); 228235537Sgber 229235537Sgber return (error); 230235537Sgber} 231