1235537Sgber/*- 2235537Sgber * Copyright (c) 2010-2012 Semihalf. 3235537Sgber * All rights reserved. 4235537Sgber * 5235537Sgber * Redistribution and use in source and binary forms, with or without 6235537Sgber * modification, are permitted provided that the following conditions 7235537Sgber * are met: 8235537Sgber * 1. Redistributions of source code must retain the above copyright 9235537Sgber * notice, this list of conditions and the following disclaimer. 10235537Sgber * 2. Redistributions in binary form must reproduce the above copyright 11235537Sgber * notice, this list of conditions and the following disclaimer in the 12235537Sgber * documentation and/or other materials provided with the distribution. 13235537Sgber * 14235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15235537Sgber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16235537Sgber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17235537Sgber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18235537Sgber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19235537Sgber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20235537Sgber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21235537Sgber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22235537Sgber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23235537Sgber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24235537Sgber * SUCH DAMAGE. 25235537Sgber */ 26235537Sgber 27235537Sgber#include <sys/cdefs.h> 28235537Sgber__FBSDID("$FreeBSD$"); 29235537Sgber 30235537Sgber#include <sys/param.h> 31235537Sgber#include <sys/systm.h> 32235537Sgber#include <sys/conf.h> 33235537Sgber#include <sys/kernel.h> 34235537Sgber#include <sys/lock.h> 35235537Sgber#include <sys/malloc.h> 36235537Sgber#include <sys/mount.h> 37235537Sgber#include <sys/mutex.h> 38235537Sgber#include <sys/namei.h> 39235537Sgber#include <sys/sysctl.h> 40235537Sgber#include <sys/vnode.h> 41235537Sgber#include <sys/buf.h> 42235537Sgber#include <sys/bio.h> 43235537Sgber 44235537Sgber#include <vm/vm.h> 45235537Sgber#include <vm/vm_param.h> 46235537Sgber#include <vm/vm_kern.h> 47235537Sgber#include <vm/vm_page.h> 48235537Sgber 49235537Sgber#include <fs/nandfs/nandfs_mount.h> 50235537Sgber#include <fs/nandfs/nandfs.h> 51235537Sgber#include <fs/nandfs/nandfs_subr.h> 52235537Sgber 53235537Sgberint 54235537Sgbernandfs_node_create(struct nandfsmount *nmp, struct nandfs_node **node, 55235537Sgber uint16_t mode) 56235537Sgber{ 57235537Sgber struct nandfs_alloc_request req; 58235537Sgber struct nandfs_device *nandfsdev; 59235537Sgber struct nandfs_mdt *mdt; 60235537Sgber struct nandfs_node *ifile; 61235537Sgber struct nandfs_inode *inode; 62235537Sgber struct vnode *vp; 63235537Sgber uint32_t entry; 64235537Sgber int error = 0; 65235537Sgber 66235537Sgber nandfsdev = nmp->nm_nandfsdev; 67235537Sgber mdt = &nandfsdev->nd_ifile_mdt; 68235537Sgber ifile = nmp->nm_ifile_node; 69235537Sgber vp = NTOV(ifile); 70235537Sgber 71235537Sgber VOP_LOCK(vp, LK_EXCLUSIVE); 72235537Sgber /* Allocate new inode in ifile */ 73235537Sgber req.entrynum = nandfsdev->nd_last_ino + 1; 74235537Sgber error = nandfs_find_free_entry(mdt, ifile, &req); 75235537Sgber if (error) { 76235537Sgber VOP_UNLOCK(vp, 0); 77235537Sgber return (error); 78235537Sgber } 79235537Sgber 80235537Sgber error = nandfs_get_entry_block(mdt, ifile, &req, &entry, 1); 81235537Sgber if (error) { 82235537Sgber VOP_UNLOCK(vp, 0); 83235537Sgber return (error); 84235537Sgber } 85235537Sgber 86235537Sgber /* Inode initialization */ 87235537Sgber inode = ((struct nandfs_inode *) req.bp_entry->b_data) + entry; 88235537Sgber nandfs_inode_init(inode, mode); 89235537Sgber 90235537Sgber error = nandfs_alloc_entry(mdt, &req); 91235537Sgber if (error) { 92235537Sgber VOP_UNLOCK(vp, 0); 93235537Sgber return (error); 94235537Sgber } 95235537Sgber 96235537Sgber VOP_UNLOCK(vp, 0); 97235537Sgber 98235537Sgber nandfsdev->nd_last_ino = req.entrynum; 99235537Sgber error = nandfs_get_node(nmp, req.entrynum, node); 100235537Sgber DPRINTF(IFILE, ("%s: node: %p ino: %#jx\n", 101235537Sgber __func__, node, (uintmax_t)((*node)->nn_ino))); 102235537Sgber 103235537Sgber return (error); 104235537Sgber} 105235537Sgber 106235537Sgberint 107235537Sgbernandfs_node_destroy(struct nandfs_node *node) 108235537Sgber{ 109235537Sgber struct nandfs_alloc_request req; 110235537Sgber struct nandfsmount *nmp; 111235537Sgber struct nandfs_mdt *mdt; 112235537Sgber struct nandfs_node *ifile; 113235537Sgber struct vnode *vp; 114235537Sgber int error = 0; 115235537Sgber 116235537Sgber nmp = node->nn_nmp; 117235537Sgber req.entrynum = node->nn_ino; 118235537Sgber mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; 119235537Sgber ifile = nmp->nm_ifile_node; 120235537Sgber vp = NTOV(ifile); 121235537Sgber 122235537Sgber DPRINTF(IFILE, ("%s: destroy node: %p ino: %#jx\n", 123235537Sgber __func__, node, (uintmax_t)node->nn_ino)); 124235537Sgber VOP_LOCK(vp, LK_EXCLUSIVE); 125235537Sgber 126235537Sgber error = nandfs_find_entry(mdt, ifile, &req); 127235537Sgber if (error) { 128235537Sgber nandfs_error("%s: finding entry error:%d node %p(%jx)", 129235537Sgber __func__, error, node, node->nn_ino); 130235537Sgber VOP_UNLOCK(vp, 0); 131235537Sgber return (error); 132235537Sgber } 133235537Sgber 134235537Sgber nandfs_inode_destroy(&node->nn_inode); 135235537Sgber 136235537Sgber error = nandfs_free_entry(mdt, &req); 137235537Sgber if (error) { 138235537Sgber nandfs_error("%s: freing entry error:%d node %p(%jx)", 139235537Sgber __func__, error, node, node->nn_ino); 140235537Sgber VOP_UNLOCK(vp, 0); 141235537Sgber return (error); 142235537Sgber } 143235537Sgber 144235537Sgber VOP_UNLOCK(vp, 0); 145235537Sgber DPRINTF(IFILE, ("%s: freed node %p ino %#jx\n", 146235537Sgber __func__, node, (uintmax_t)node->nn_ino)); 147235537Sgber return (error); 148235537Sgber} 149235537Sgber 150235537Sgberint 151235537Sgbernandfs_node_update(struct nandfs_node *node) 152235537Sgber{ 153235537Sgber struct nandfs_alloc_request req; 154235537Sgber struct nandfsmount *nmp; 155235537Sgber struct nandfs_mdt *mdt; 156235537Sgber struct nandfs_node *ifile; 157235537Sgber struct nandfs_inode *inode; 158235537Sgber uint32_t index; 159235537Sgber int error = 0; 160235537Sgber 161235537Sgber nmp = node->nn_nmp; 162235537Sgber ifile = nmp->nm_ifile_node; 163235537Sgber ASSERT_VOP_LOCKED(NTOV(ifile), __func__); 164235537Sgber 165235537Sgber req.entrynum = node->nn_ino; 166235537Sgber mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; 167235537Sgber 168235537Sgber DPRINTF(IFILE, ("%s: node:%p ino:%#jx\n", 169235537Sgber __func__, &node->nn_inode, (uintmax_t)node->nn_ino)); 170235537Sgber 171235537Sgber error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0); 172235537Sgber if (error) { 173235537Sgber printf("nandfs_get_entry_block returned with ERROR=%d\n", 174235537Sgber error); 175235537Sgber return (error); 176235537Sgber } 177235537Sgber 178235537Sgber inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index; 179235537Sgber memcpy(inode, &node->nn_inode, sizeof(*inode)); 180235537Sgber error = nandfs_dirty_buf(req.bp_entry, 0); 181235537Sgber 182235537Sgber return (error); 183235537Sgber} 184235537Sgber 185235537Sgberint 186235537Sgbernandfs_get_node_entry(struct nandfsmount *nmp, struct nandfs_inode **inode, 187235537Sgber uint64_t ino, struct buf **bp) 188235537Sgber{ 189235537Sgber struct nandfs_alloc_request req; 190235537Sgber struct nandfs_mdt *mdt; 191235537Sgber struct nandfs_node *ifile; 192235537Sgber struct vnode *vp; 193235537Sgber uint32_t index; 194235537Sgber int error = 0; 195235537Sgber 196235537Sgber req.entrynum = ino; 197235537Sgber mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; 198235537Sgber ifile = nmp->nm_ifile_node; 199235537Sgber vp = NTOV(ifile); 200235537Sgber 201235537Sgber VOP_LOCK(vp, LK_EXCLUSIVE); 202235537Sgber error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0); 203235537Sgber if (error) { 204235537Sgber VOP_UNLOCK(vp, 0); 205235537Sgber return (error); 206235537Sgber } 207235537Sgber 208235537Sgber *inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index; 209235537Sgber *bp = req.bp_entry; 210235537Sgber VOP_UNLOCK(vp, 0); 211235537Sgber return (0); 212235537Sgber} 213235537Sgber 214