1 /* 2 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.4 2007/11/02 00:57:15 dillon Exp $ 35 */ 36 /* 37 * This header file contains structures used internally by the HAMMERFS 38 * implementation. See hammer_disk.h for on-disk structures. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/types.h> 43 #include <sys/kernel.h> 44 #include <sys/systm.h> 45 #include <sys/tree.h> 46 #include <sys/malloc.h> 47 #include <sys/mount.h> 48 #include <sys/vnode.h> 49 #include <sys/globaldata.h> 50 #include "hammer_alist.h" 51 #include "hammer_disk.h" 52 #include "hammer_mount.h" 53 54 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) 55 56 MALLOC_DECLARE(M_HAMMER); 57 58 /* 59 * Key structure used for custom RB tree inode lookups. This prototypes 60 * the function hammer_ino_rb_tree_RB_LOOKUP_INFO(root, info). 61 */ 62 typedef struct hammer_inode_info { 63 u_int64_t obj_id; /* (key) object identifier */ 64 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */ 65 } *hammer_inode_info_t; 66 67 struct hammer_lock { 68 int refs; 69 int wanted; 70 struct thread *locktd; 71 }; 72 73 static __inline int 74 hammer_islocked(struct hammer_lock *lock) 75 { 76 return(lock->refs > 0); 77 } 78 79 static __inline int 80 hammer_islastref(struct hammer_lock *lock) 81 { 82 return(lock->refs == 1); 83 } 84 85 /* 86 * Structures used to internally represent an inode 87 */ 88 struct hammer_ino_rb_tree; 89 struct hammer_inode; 90 RB_HEAD(hammer_ino_rb_tree, hammer_inode); 91 RB_PROTOTYPEX(hammer_ino_rb_tree, INFO, hammer_inode, rb_node, 92 hammer_ino_rb_compare, hammer_inode_info_t); 93 94 struct hammer_inode { 95 RB_ENTRY(hammer_inode) rb_node; 96 u_int64_t obj_id; /* (key) object identifier */ 97 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */ 98 struct vnode *vp; 99 struct hammer_inode_record ino_rec; 100 struct hammer_inode_data ino_data; 101 struct hammer_lock lock; 102 }; 103 104 /* 105 * Structures used to internally represent a volume and a cluster 106 */ 107 108 struct hammer_volume; 109 struct hammer_cluster; 110 struct hammer_supercl; 111 struct hammer_buffer; 112 RB_HEAD(hammer_vol_rb_tree, hammer_volume); 113 RB_HEAD(hammer_clu_rb_tree, hammer_cluster); 114 RB_HEAD(hammer_scl_rb_tree, hammer_supercl); 115 RB_HEAD(hammer_buf_rb_tree, hammer_buffer); 116 117 RB_PROTOTYPE2(hammer_vol_rb_tree, hammer_volume, rb_node, 118 hammer_vol_rb_compare, int32_t); 119 RB_PROTOTYPE2(hammer_clu_rb_tree, hammer_cluster, rb_node, 120 hammer_clu_rb_compare, int32_t); 121 RB_PROTOTYPE2(hammer_scl_rb_tree, hammer_supercl, rb_node, 122 hammer_scl_rb_compare, int32_t); 123 RB_PROTOTYPE2(hammer_buf_rb_tree, hammer_buffer, rb_node, 124 hammer_buf_rb_compare, int32_t); 125 126 struct hammer_volume { 127 RB_ENTRY(hammer_volume) rb_node; 128 struct hammer_clu_rb_tree rb_clus_root; 129 struct hammer_scl_rb_tree rb_scls_root; 130 struct buf *bp; 131 struct hammer_volume_ondisk *ondisk; 132 struct hammer_alist_live alist; 133 int32_t vol_no; 134 int32_t vol_clsize; 135 int64_t cluster_base; /* base offset of cluster 0 */ 136 char *vol_name; 137 struct vnode *devvp; 138 struct hammer_mount *hmp; 139 struct hammer_lock lock; 140 int vol_flags; 141 int modified; 142 }; 143 144 struct hammer_supercl { 145 RB_ENTRY(hammer_supercl) rb_node; 146 struct buf *bp; 147 struct hammer_supercl_ondisk *ondisk; 148 struct hammer_volume *volume; 149 struct hammer_alist_live alist; 150 int32_t scl_no; 151 int64_t scl_offset; 152 struct hammer_lock lock; 153 int modified; 154 }; 155 156 struct hammer_cluster { 157 RB_ENTRY(hammer_cluster) rb_node; 158 struct hammer_buf_rb_tree rb_bufs_root; 159 struct buf *bp; 160 struct hammer_cluster_ondisk *ondisk; 161 struct hammer_volume *volume; 162 struct hammer_alist_live alist_master; 163 struct hammer_alist_live alist_btree; 164 struct hammer_alist_live alist_record; 165 struct hammer_alist_live alist_mdata; 166 int32_t clu_no; 167 int64_t clu_offset; 168 struct hammer_lock lock; 169 int modified; 170 }; 171 172 struct hammer_buffer { 173 RB_ENTRY(hammer_buffer) rb_node; 174 struct buf *bp; 175 hammer_fsbuf_ondisk_t ondisk; 176 struct hammer_cluster *cluster; 177 struct hammer_volume *volume; 178 struct hammer_alist_live alist; 179 int32_t buf_no; 180 int64_t buf_offset; 181 struct hammer_lock lock; 182 int modified; 183 }; 184 185 #define HAMFS_CLUSTER_DIRTY 0x0001 186 187 /* 188 * Internal hammer mount data structure 189 */ 190 struct hammer_mount { 191 struct mount *mp; 192 /*struct vnode *rootvp;*/ 193 struct hammer_ino_rb_tree rb_inos_root; 194 struct hammer_vol_rb_tree rb_vols_root; 195 struct hammer_volume *rootvol; 196 struct hammer_cluster *rootcl; 197 /* struct hammer_volume *cache_volume */ 198 /* struct hammer_cluster *cache_cluster */ 199 /* struct hammer_buffer *cache_buffer */ 200 uuid_t fsid; 201 }; 202 203 204 #endif 205 206 #if defined(_KERNEL) 207 208 extern struct vop_ops hammer_vnode_vops; 209 extern struct hammer_alist_config Buf_alist_config; 210 extern struct hammer_alist_config Vol_normal_alist_config; 211 extern struct hammer_alist_config Vol_super_alist_config; 212 extern struct hammer_alist_config Supercl_alist_config; 213 extern struct hammer_alist_config Clu_master_alist_config; 214 extern struct hammer_alist_config Clu_slave_alist_config; 215 216 int hammer_vop_inactive(struct vop_inactive_args *); 217 int hammer_vop_reclaim(struct vop_reclaim_args *); 218 int hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp); 219 220 int hammer_unload_inode(struct hammer_inode *ip, void *data); 221 int hammer_unload_volume(struct hammer_volume *volume, void *data __unused); 222 int hammer_load_volume(struct hammer_mount *hmp, const char *volname); 223 struct hammer_cluster *hammer_load_cluster(struct hammer_volume *volume, 224 int clu_no, int *errorp); 225 226 void hammer_lock(struct hammer_lock *lock); 227 void hammer_unlock(struct hammer_lock *lock); 228 229 int hammer_btree_lookup(hammer_btree_info_t info, 230 hammer_base_elm_t key, int flags); 231 int hammer_btree_insert(hammer_btree_info_t info, 232 hammer_btree_leaf_elm_t elm); 233 int hammer_btree_delete(hammer_btree_info_t info, hammer_base_elm_t key); 234 int hammer_btree_cursor_init(hammer_btree_cursor_t cursor, 235 struct hammer_cluster *cluster); 236 void hammer_btree_cursor_done(hammer_btree_cursor_t cusor); 237 int hammer_btree_info_init(hammer_btree_info_t info, 238 struct hammer_cluster *cluster); 239 void hammer_btree_info_done(hammer_btree_info_t info); 240 241 void *hammer_bread(struct hammer_cluster *cluster, int32_t cloff, 242 u_int64_t buf_type, 243 int *errorp, struct hammer_buffer **bufferp); 244 245 struct hammer_volume *hammer_get_volume(struct hammer_mount *hmp, 246 int32_t vol_no, int *errorp); 247 struct hammer_supercl *hammer_get_supercl(struct hammer_volume *volume, 248 int32_t scl_no, int *errorp, int isnew); 249 struct hammer_cluster *hammer_get_cluster(struct hammer_volume *volume, 250 int32_t clu_no, int *errorp, int isnew); 251 struct hammer_buffer *hammer_get_buffer(struct hammer_cluster *cluster, 252 int32_t buf_no, int64_t buf_type, int *errorp); 253 void hammer_dup_buffer(struct hammer_buffer **bufferp, 254 struct hammer_buffer *buffer); 255 void hammer_dup_cluster(struct hammer_cluster **clusterp, 256 struct hammer_cluster *cluster); 257 void *hammer_alloc_btree(struct hammer_cluster *cluster, 258 int *errorp, struct hammer_buffer **bufferp); 259 void *hammer_alloc_data(struct hammer_cluster *cluster, int32_t bytes, 260 int *errorp, struct hammer_buffer **bufferp); 261 void *hammer_alloc_record(struct hammer_cluster *cluster, 262 int *errorp, struct hammer_buffer **bufferp); 263 void hammer_free_btree_ptr(struct hammer_buffer *buffer, 264 hammer_btree_node_t node); 265 void hammer_free_data_ptr(struct hammer_buffer *buffer, 266 void *data, int bytes); 267 void hammer_free_record_ptr(struct hammer_buffer *buffer, 268 union hammer_record_ondisk *rec); 269 void hammer_free_btree(struct hammer_cluster *cluster, int32_t bclu_offset); 270 void hammer_free_data(struct hammer_cluster *cluster, int32_t bclu_offset, 271 int32_t bytes); 272 void hammer_free_record(struct hammer_cluster *cluster, int32_t bclu_offset); 273 274 void hammer_put_volume(struct hammer_volume *volume); 275 void hammer_put_supercl(struct hammer_supercl *supercl); 276 void hammer_put_cluster(struct hammer_cluster *cluster); 277 void hammer_put_buffer(struct hammer_buffer *buffer); 278 279 void hammer_init_alist_config(void); 280 281 #endif 282 283 /* 284 * Inline support functions (not kernel specific) 285 */ 286 static __inline void 287 hammer_modify_volume(struct hammer_volume *volume) 288 { 289 volume->modified = 1; 290 } 291 292 static __inline void 293 hammer_modify_supercl(struct hammer_supercl *supercl) 294 { 295 supercl->modified = 1; 296 } 297 298 static __inline void 299 hammer_modify_cluster(struct hammer_cluster *cluster) 300 { 301 cluster->modified = 1; 302 } 303 304 static __inline void 305 hammer_modify_buffer(struct hammer_buffer *buffer) 306 { 307 buffer->modified = 1; 308 } 309 310 /* 311 * Return the cluster-relative byte offset of an element within a buffer 312 */ 313 static __inline int 314 hammer_bclu_offset(struct hammer_buffer *buffer, void *ptr) 315 { 316 int bclu_offset; 317 318 bclu_offset = buffer->buf_no * HAMMER_BUFSIZE + 319 ((char *)ptr - (char *)buffer->ondisk); 320 return(bclu_offset); 321 } 322 323