1 1.31 riastrad /* $NetBSD: filecore_node.c,v 1.31 2017/05/26 14:34:19 riastradh Exp $ */ 2 1.1 jdolecek 3 1.1 jdolecek /*- 4 1.6 perry * Copyright (c) 1982, 1986, 1989, 1994 5 1.1 jdolecek * The Regents of the University of California. 6 1.1 jdolecek * All rights reserved. 7 1.1 jdolecek * 8 1.1 jdolecek * Redistribution and use in source and binary forms, with or without 9 1.1 jdolecek * modification, are permitted provided that the following conditions 10 1.1 jdolecek * are met: 11 1.1 jdolecek * 1. Redistributions of source code must retain the above copyright 12 1.1 jdolecek * notice, this list of conditions and the following disclaimer. 13 1.1 jdolecek * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 jdolecek * notice, this list of conditions and the following disclaimer in the 15 1.1 jdolecek * documentation and/or other materials provided with the distribution. 16 1.2 agc * 3. Neither the name of the University nor the names of its contributors 17 1.2 agc * may be used to endorse or promote products derived from this software 18 1.2 agc * without specific prior written permission. 19 1.2 agc * 20 1.2 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 1.2 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 1.2 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 1.2 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 1.2 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 1.2 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 1.2 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.2 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.2 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.2 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.2 agc * SUCH DAMAGE. 31 1.2 agc * 32 1.2 agc * filecore_node.c 1.0 1998/6/4 33 1.2 agc */ 34 1.2 agc 35 1.2 agc /*- 36 1.2 agc * Copyright (c) 1998 Andrew McMurry 37 1.2 agc * 38 1.2 agc * Redistribution and use in source and binary forms, with or without 39 1.2 agc * modification, are permitted provided that the following conditions 40 1.2 agc * are met: 41 1.2 agc * 1. Redistributions of source code must retain the above copyright 42 1.2 agc * notice, this list of conditions and the following disclaimer. 43 1.2 agc * 2. Redistributions in binary form must reproduce the above copyright 44 1.2 agc * notice, this list of conditions and the following disclaimer in the 45 1.2 agc * documentation and/or other materials provided with the distribution. 46 1.1 jdolecek * 3. All advertising materials mentioning features or use of this software 47 1.1 jdolecek * must display the following acknowledgement: 48 1.1 jdolecek * This product includes software developed by the University of 49 1.1 jdolecek * California, Berkeley and its contributors. 50 1.1 jdolecek * 4. Neither the name of the University nor the names of its contributors 51 1.1 jdolecek * may be used to endorse or promote products derived from this software 52 1.1 jdolecek * without specific prior written permission. 53 1.1 jdolecek * 54 1.1 jdolecek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 1.1 jdolecek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 1.1 jdolecek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 1.1 jdolecek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 1.1 jdolecek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 1.1 jdolecek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 1.1 jdolecek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 1.1 jdolecek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 1.1 jdolecek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 1.1 jdolecek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 1.1 jdolecek * SUCH DAMAGE. 65 1.1 jdolecek * 66 1.1 jdolecek * filecore_node.c 1.0 1998/6/4 67 1.1 jdolecek */ 68 1.1 jdolecek 69 1.1 jdolecek #include <sys/cdefs.h> 70 1.31 riastrad __KERNEL_RCSID(0, "$NetBSD: filecore_node.c,v 1.31 2017/05/26 14:34:19 riastradh Exp $"); 71 1.1 jdolecek 72 1.1 jdolecek #include <sys/param.h> 73 1.1 jdolecek #include <sys/systm.h> 74 1.1 jdolecek #include <sys/mount.h> 75 1.1 jdolecek #include <sys/proc.h> 76 1.1 jdolecek #include <sys/file.h> 77 1.1 jdolecek #include <sys/buf.h> 78 1.1 jdolecek #include <sys/vnode.h> 79 1.1 jdolecek #include <sys/namei.h> 80 1.1 jdolecek #include <sys/kernel.h> 81 1.1 jdolecek #include <sys/pool.h> 82 1.1 jdolecek #include <sys/stat.h> 83 1.24 rmind #include <sys/mutex.h> 84 1.1 jdolecek 85 1.1 jdolecek #include <fs/filecorefs/filecore.h> 86 1.1 jdolecek #include <fs/filecorefs/filecore_extern.h> 87 1.1 jdolecek #include <fs/filecorefs/filecore_node.h> 88 1.1 jdolecek #include <fs/filecorefs/filecore_mount.h> 89 1.1 jdolecek 90 1.24 rmind struct pool filecore_node_pool; 91 1.1 jdolecek 92 1.27 hannken static const struct genfs_ops filecore_genfsops = { 93 1.27 hannken .gop_size = genfs_size, 94 1.27 hannken }; 95 1.27 hannken 96 1.1 jdolecek /* 97 1.1 jdolecek * Initialize hash links for inodes and dnodes. 98 1.1 jdolecek */ 99 1.1 jdolecek void 100 1.19 cegger filecore_init(void) 101 1.1 jdolecek { 102 1.10 pooka 103 1.5 atatat pool_init(&filecore_node_pool, sizeof(struct filecore_node), 0, 0, 0, 104 1.9 ad "filecrnopl", &pool_allocator_nointr, IPL_NONE); 105 1.1 jdolecek } 106 1.1 jdolecek 107 1.1 jdolecek /* 108 1.1 jdolecek * Reinitialize inode hash table. 109 1.1 jdolecek */ 110 1.1 jdolecek void 111 1.19 cegger filecore_reinit(void) 112 1.1 jdolecek { 113 1.27 hannken 114 1.1 jdolecek } 115 1.1 jdolecek 116 1.1 jdolecek /* 117 1.1 jdolecek * Destroy node pool and hash table. 118 1.1 jdolecek */ 119 1.1 jdolecek void 120 1.19 cegger filecore_done(void) 121 1.1 jdolecek { 122 1.24 rmind 123 1.5 atatat pool_destroy(&filecore_node_pool); 124 1.1 jdolecek } 125 1.1 jdolecek 126 1.1 jdolecek /* 127 1.27 hannken * Initialize this vnode / filecore node pair. 128 1.27 hannken * Caller assures no other thread will try to load this node. 129 1.1 jdolecek */ 130 1.27 hannken int 131 1.27 hannken filecore_loadvnode(struct mount *mp, struct vnode *vp, 132 1.27 hannken const void *key, size_t key_len, const void **new_key) 133 1.1 jdolecek { 134 1.27 hannken ino_t ino; 135 1.27 hannken struct filecore_mnt *fcmp; 136 1.1 jdolecek struct filecore_node *ip; 137 1.27 hannken struct buf *bp; 138 1.27 hannken int error; 139 1.1 jdolecek 140 1.27 hannken KASSERT(key_len == sizeof(ino)); 141 1.27 hannken memcpy(&ino, key, key_len); 142 1.27 hannken fcmp = VFSTOFILECORE(mp); 143 1.27 hannken 144 1.27 hannken ip = pool_get(&filecore_node_pool, PR_WAITOK); 145 1.27 hannken memset(ip, 0, sizeof(struct filecore_node)); 146 1.27 hannken ip->i_vnode = vp; 147 1.27 hannken ip->i_dev = fcmp->fc_dev; 148 1.27 hannken ip->i_number = ino; 149 1.27 hannken ip->i_block = -1; 150 1.27 hannken ip->i_parent = -2; 151 1.27 hannken 152 1.27 hannken if (ino == FILECORE_ROOTINO) { 153 1.27 hannken /* Here we need to construct a root directory inode */ 154 1.27 hannken memcpy(ip->i_dirent.name, "root", 4); 155 1.27 hannken ip->i_dirent.load = 0; 156 1.27 hannken ip->i_dirent.exec = 0; 157 1.27 hannken ip->i_dirent.len = FILECORE_DIR_SIZE; 158 1.27 hannken ip->i_dirent.addr = fcmp->drec.root; 159 1.27 hannken ip->i_dirent.attr = FILECORE_ATTR_DIR | FILECORE_ATTR_READ; 160 1.27 hannken 161 1.27 hannken } else { 162 1.27 hannken /* Read in Data from Directory Entry */ 163 1.27 hannken if ((error = filecore_bread(fcmp, ino & FILECORE_INO_MASK, 164 1.27 hannken FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) { 165 1.27 hannken pool_put(&filecore_node_pool, ip); 166 1.27 hannken return error; 167 1.1 jdolecek } 168 1.27 hannken 169 1.27 hannken memcpy(&ip->i_dirent, 170 1.27 hannken fcdirentry(bp->b_data, ino >> FILECORE_INO_INDEX), 171 1.27 hannken sizeof(struct filecore_direntry)); 172 1.27 hannken #ifdef FILECORE_DEBUG_BR 173 1.27 hannken printf("brelse(%p) vf5\n", bp); 174 1.27 hannken #endif 175 1.27 hannken brelse(bp, 0); 176 1.1 jdolecek } 177 1.1 jdolecek 178 1.27 hannken ip->i_mnt = fcmp; 179 1.27 hannken ip->i_devvp = fcmp->fc_devvp; 180 1.27 hannken ip->i_diroff = 0; 181 1.27 hannken vref(ip->i_devvp); 182 1.27 hannken 183 1.27 hannken /* 184 1.27 hannken * Initialize the associated vnode 185 1.27 hannken */ 186 1.1 jdolecek 187 1.27 hannken vp->v_tag = VT_FILECORE; 188 1.27 hannken vp->v_op = filecore_vnodeop_p; 189 1.27 hannken vp->v_data = ip; 190 1.27 hannken if (ip->i_dirent.attr & FILECORE_ATTR_DIR) 191 1.27 hannken vp->v_type = VDIR; 192 1.27 hannken else 193 1.27 hannken vp->v_type = VREG; 194 1.27 hannken if (ino == FILECORE_ROOTINO) 195 1.27 hannken vp->v_vflag |= VV_ROOT; 196 1.27 hannken genfs_node_init(vp, &filecore_genfsops); 197 1.1 jdolecek 198 1.27 hannken /* 199 1.27 hannken * XXX need generation number? 200 1.27 hannken */ 201 1.1 jdolecek 202 1.27 hannken uvm_vnp_setsize(vp, ip->i_size); 203 1.27 hannken *new_key = &ip->i_number; 204 1.27 hannken return 0; 205 1.1 jdolecek } 206 1.1 jdolecek 207 1.1 jdolecek /* 208 1.1 jdolecek * Last reference to an inode, write the inode out and if necessary, 209 1.1 jdolecek * truncate and deallocate the file. 210 1.1 jdolecek */ 211 1.1 jdolecek int 212 1.18 dsl filecore_inactive(void *v) 213 1.1 jdolecek { 214 1.29 riastrad struct vop_inactive_v2_args /* { 215 1.1 jdolecek struct vnode *a_vp; 216 1.13 ad bool *a_recycle; 217 1.1 jdolecek } */ *ap = v; 218 1.1 jdolecek struct vnode *vp = ap->a_vp; 219 1.1 jdolecek struct filecore_node *ip = VTOI(vp); 220 1.1 jdolecek int error = 0; 221 1.6 perry 222 1.1 jdolecek /* 223 1.1 jdolecek * If we are done with the inode, reclaim it 224 1.1 jdolecek * so that it can be reused immediately. 225 1.1 jdolecek */ 226 1.13 ad ip->i_flag = 0; 227 1.13 ad *ap->a_recycle = (filecore_staleinode(ip) != 0); 228 1.29 riastrad 229 1.1 jdolecek return error; 230 1.1 jdolecek } 231 1.1 jdolecek 232 1.1 jdolecek /* 233 1.1 jdolecek * Reclaim an inode so that it can be used for other purposes. 234 1.1 jdolecek */ 235 1.1 jdolecek int 236 1.18 dsl filecore_reclaim(void *v) 237 1.1 jdolecek { 238 1.30 riastrad struct vop_reclaim_v2_args /* { 239 1.1 jdolecek struct vnode *a_vp; 240 1.7 christos struct lwp *a_l; 241 1.1 jdolecek } */ *ap = v; 242 1.1 jdolecek struct vnode *vp = ap->a_vp; 243 1.1 jdolecek struct filecore_node *ip = VTOI(vp); 244 1.6 perry 245 1.30 riastrad VOP_UNLOCK(vp); 246 1.30 riastrad 247 1.1 jdolecek /* 248 1.1 jdolecek * Purge old data structures associated with the inode. 249 1.1 jdolecek */ 250 1.1 jdolecek if (ip->i_devvp) { 251 1.1 jdolecek vrele(ip->i_devvp); 252 1.1 jdolecek ip->i_devvp = 0; 253 1.1 jdolecek } 254 1.8 ad genfs_node_destroy(vp); 255 1.1 jdolecek pool_put(&filecore_node_pool, vp->v_data); 256 1.1 jdolecek vp->v_data = NULL; 257 1.1 jdolecek return (0); 258 1.1 jdolecek } 259