| Commit | Line | Data |
|---|---|---|
| 703720e4 MD |
1 | /* |
| 2 | * Copyright (c) 2011-2012 The DragonFly Project. All rights reserved. | |
| 3 | * | |
| 4 | * This code is derived from software contributed to The DragonFly Project | |
| 5 | * by Matthew Dillon <dillon@dragonflybsd.org> | |
| 6 | * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> | |
| 7 | * | |
| 8 | * Redistribution and use in source and binary forms, with or without | |
| 9 | * modification, are permitted provided that the following conditions | |
| 10 | * are met: | |
| 11 | * | |
| 12 | * 1. Redistributions of source code must retain the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer. | |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 15 | * notice, this list of conditions and the following disclaimer in | |
| 16 | * the documentation and/or other materials provided with the | |
| 17 | * distribution. | |
| 18 | * 3. Neither the name of The DragonFly Project nor the names of its | |
| 19 | * contributors may be used to endorse or promote products derived | |
| 20 | * from this software without specific, prior written permission. | |
| 21 | * | |
| 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| 25 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
| 26 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 27 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
| 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
| 30 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
| 32 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 33 | * SUCH DAMAGE. | |
| 34 | */ | |
| 35 | ||
| 36 | /* | |
| 37 | * This header file contains structures used internally by the HAMMER2 | |
| 38 | * implementation. See hammer2_disk.h for on-disk structures. | |
| 39 | */ | |
| 40 | ||
| 41 | #ifndef _VFS_HAMMER2_HAMMER2_H_ | |
| 42 | #define _VFS_HAMMER2_HAMMER2_H_ | |
| 43 | ||
| 44 | #include <sys/param.h> | |
| 45 | #include <sys/types.h> | |
| 46 | #include <sys/kernel.h> | |
| 47 | #include <sys/conf.h> | |
| 48 | #include <sys/systm.h> | |
| 49 | #include <sys/tree.h> | |
| 50 | #include <sys/malloc.h> | |
| 51 | #include <sys/mount.h> | |
| 52 | #include <sys/vnode.h> | |
| 53 | #include <sys/proc.h> | |
| 54 | #include <sys/mountctl.h> | |
| 55 | #include <sys/priv.h> | |
| 56 | #include <sys/stat.h> | |
| 46558838 | 57 | #include <sys/thread.h> |
| 703720e4 MD |
58 | #include <sys/globaldata.h> |
| 59 | #include <sys/lockf.h> | |
| 60 | #include <sys/buf.h> | |
| 61 | #include <sys/queue.h> | |
| 62 | #include <sys/limits.h> | |
| 63 | #include <sys/buf2.h> | |
| 64 | #include <sys/signal2.h> | |
| 65 | #include <sys/tree.h> | |
| 66 | ||
| 67 | #include "hammer2_disk.h" | |
| 68 | #include "hammer2_mount.h" | |
| 2910a90c | 69 | #include "hammer2_ioctl.h" |
| 1ad77ed9 | 70 | #include "hammer2_ccms.h" |
| 26bf1a36 | 71 | #include "hammer2_network.h" |
| 703720e4 | 72 | |
| 5c23d7f1 | 73 | struct hammer2_chain; |
| 703720e4 MD |
74 | struct hammer2_inode; |
| 75 | struct hammer2_mount; | |
| e4e20f48 | 76 | struct hammer2_pfsmount; |
| 10c86c4e | 77 | struct hammer2_span; |
| 26bf1a36 MD |
78 | struct hammer2_state; |
| 79 | struct hammer2_msg; | |
| 703720e4 | 80 | |
| 703720e4 | 81 | /* |
| 50e4f8f4 MD |
82 | * The chain structure tracks blockref recursions all the way to |
| 83 | * the root volume. These consist of indirect blocks, inodes, | |
| 84 | * and eventually the volume header. | |
| 85 | * | |
| 7cfa8da5 MD |
86 | * The chain structure is embedded in the hammer2_mount, hammer2_inode, |
| 87 | * and other system memory structures. The chain structure typically | |
| 88 | * implements the reference count and busy flag for the larger structure. | |
| 89 | * | |
| 90 | * It is always possible to track a chain element all the way back to the | |
| 91 | * root by following the (parent) links. (index) is a type-dependent index | |
| 92 | * in the parent indicating where in the parent the chain element resides. | |
| 5c23d7f1 MD |
93 | * |
| 94 | * When a blockref is added or deleted the related chain element is marked | |
| 95 | * modified and all of its parents are marked SUBMODIFIED (the parent | |
| 96 | * recursion can stop once we hit a node that is already marked SUBMODIFIED). | |
| 97 | * A deleted chain element must remain intact until synchronized against | |
| 98 | * its parent. | |
| 99 | * | |
| 100 | * The blockref at (parent, index) is not adjusted until the modified chain | |
| 101 | * element is flushed and unmarked. Until then the child's blockref may | |
| 102 | * not match the blockref at (parent, index). | |
| 50e4f8f4 | 103 | */ |
| ecc33e71 | 104 | RB_HEAD(hammer2_chain_tree, hammer2_chain); |
| 26bf1a36 | 105 | RB_HEAD(hammer2_state_tree, hammer2_state); |
| a0ed3c24 | 106 | TAILQ_HEAD(flush_deferral_list, hammer2_chain); |
| 5c23d7f1 | 107 | |
| 50e4f8f4 | 108 | struct hammer2_chain { |
| 46558838 | 109 | ccms_cst_t cst; /* attr or data cst */ |
| 50e4f8f4 | 110 | struct hammer2_blockref bref; |
| 004f88b4 | 111 | struct hammer2_blockref bref_flush; /* synchronized w/MOVED bit */ |
| 26bf1a36 | 112 | struct hammer2_chain *parent; /* return chain to root */ |
| ecc33e71 | 113 | struct hammer2_chain_tree rbhead; |
| 26bf1a36 | 114 | struct hammer2_state *state; /* if active cache msg */ |
| ecc33e71 | 115 | RB_ENTRY(hammer2_chain) rbnode; |
| 1c9f601e | 116 | TAILQ_ENTRY(hammer2_chain) flush_node; /* flush deferral list */ |
| 7cfa8da5 MD |
117 | union { |
| 118 | struct hammer2_inode *ip; | |
| 5c23d7f1 MD |
119 | struct hammer2_indblock *np; |
| 120 | struct hammer2_data *dp; | |
| 121 | void *mem; | |
| 7cfa8da5 | 122 | } u; |
| 5c23d7f1 MD |
123 | |
| 124 | struct buf *bp; /* buffer cache (ro) */ | |
| 125 | hammer2_media_data_t *data; /* modified copy of data (rw) */ | |
| 866d5273 | 126 | u_int bytes; /* physical size of data */ |
| 5c23d7f1 MD |
127 | int index; /* index in parent */ |
| 128 | u_int refs; | |
| 5c23d7f1 | 129 | u_int flags; |
| 50e4f8f4 MD |
130 | }; |
| 131 | ||
| 132 | typedef struct hammer2_chain hammer2_chain_t; | |
| 133 | ||
| 5c23d7f1 | 134 | int hammer2_chain_cmp(hammer2_chain_t *chain1, hammer2_chain_t *chain2); |
| ecc33e71 | 135 | RB_PROTOTYPE(hammer2_chain_tree, hammer2_chain, rbnode, hammer2_chain_cmp); |
| 5c23d7f1 | 136 | |
| 28ee5f14 MD |
137 | /* |
| 138 | * MOVED - This bit is set during the flush when the MODIFIED bit is cleared, | |
| 139 | * indicating that the parent's blocktable must inherit a change to | |
| 140 | * the bref (typically a block reallocation) | |
| 141 | * | |
| 142 | * It must also be set in situations where a chain is not MODIFIED | |
| 143 | * but whos bref has changed (typically due to fields other than | |
| 144 | * a block reallocation). | |
| 145 | */ | |
| 2910a90c | 146 | #define HAMMER2_CHAIN_MODIFIED 0x00000001 /* active mods */ |
| 214f4a77 | 147 | #define HAMMER2_CHAIN_DIRTYEMBED 0x00000002 /* inode embedded */ |
| a92f82c4 | 148 | #define HAMMER2_CHAIN_DIRTYBP 0x00000004 /* dirty on unlock */ |
| 73e441b9 | 149 | #define HAMMER2_CHAIN_SUBMODIFIED 0x00000008 /* 1+ subs modified */ |
| b7926f31 | 150 | #define HAMMER2_CHAIN_DELETED 0x00000010 |
| 01eabad4 | 151 | #define HAMMER2_CHAIN_INITIAL 0x00000020 /* initial create */ |
| c667909f | 152 | #define HAMMER2_CHAIN_FLUSHED 0x00000040 /* flush on unlock */ |
| 28ee5f14 | 153 | #define HAMMER2_CHAIN_MOVED 0x00000080 /* bref changed */ |
| 37aa19df | 154 | #define HAMMER2_CHAIN_IOFLUSH 0x00000100 /* bawrite on put */ |
| 1c9f601e | 155 | #define HAMMER2_CHAIN_DEFERRED 0x00000200 /* on a deferral list*/ |
| 222d9e22 | 156 | #define HAMMER2_CHAIN_DESTROYED 0x00000400 /* destroying */ |
| 2910a90c | 157 | #define HAMMER2_CHAIN_MODIFIED_AUX 0x00000800 /* hmp->vchain only */ |
| 4d5318eb MD |
158 | #define HAMMER2_CHAIN_MODIFY_TID 0x00001000 /* mod updates field */ |
| 159 | #define HAMMER2_CHAIN_MOUNTED 0x00002000 /* PFS is mounted */ | |
| c667909f MD |
160 | |
| 161 | /* | |
| 162 | * Flags passed to hammer2_chain_lookup() and hammer2_chain_next() | |
| 163 | */ | |
| 164 | #define HAMMER2_LOOKUP_NOLOCK 0x00000001 /* ref only */ | |
| 8cce658d | 165 | #define HAMMER2_LOOKUP_NODATA 0x00000002 /* data left NULL */ |
| a0ed3c24 | 166 | #define HAMMER2_LOOKUP_SHARED 0x00000100 |
| 5c23d7f1 | 167 | |
| 50e4f8f4 | 168 | /* |
| 01eabad4 MD |
169 | * Flags passed to hammer2_chain_modify() and hammer2_chain_resize() |
| 170 | * | |
| 171 | * NOTE: OPTDATA allows us to avoid instantiating buffers for INDIRECT | |
| 172 | * blocks in the INITIAL-create state. | |
| 4d5318eb MD |
173 | * |
| 174 | * NOTE: NO_MODIFY_TID tells the function to not set HAMMER2_CHAIN_MODIFY_TID | |
| 175 | * when marking the chain modified (used when a sub-chain modification | |
| 176 | * propagates upward). | |
| 01eabad4 MD |
177 | */ |
| 178 | #define HAMMER2_MODIFY_NOSUB 0x00000001 /* do not set SUBMOD */ | |
| 179 | #define HAMMER2_MODIFY_OPTDATA 0x00000002 /* data can be NULL */ | |
| 4d5318eb | 180 | #define HAMMER2_MODIFY_NO_MODIFY_TID 0x00000004 |
| 01eabad4 MD |
181 | |
| 182 | /* | |
| 183 | * Flags passed to hammer2_chain_lock() | |
| 184 | */ | |
| 185 | #define HAMMER2_RESOLVE_NEVER 1 | |
| 186 | #define HAMMER2_RESOLVE_MAYBE 2 | |
| 187 | #define HAMMER2_RESOLVE_ALWAYS 3 | |
| a0ed3c24 MD |
188 | #define HAMMER2_RESOLVE_MASK 0x0F |
| 189 | ||
| 190 | #define HAMMER2_RESOLVE_SHARED 0x10 | |
| 01eabad4 MD |
191 | |
| 192 | /* | |
| 6ba3b984 MD |
193 | * Cluster different types of storage together for allocations |
| 194 | */ | |
| 195 | #define HAMMER2_FREECACHE_INODE 0 | |
| 196 | #define HAMMER2_FREECACHE_INDIR 1 | |
| 197 | #define HAMMER2_FREECACHE_DATA 2 | |
| 198 | #define HAMMER2_FREECACHE_UNUSED3 3 | |
| 199 | #define HAMMER2_FREECACHE_TYPES 4 | |
| 200 | ||
| 201 | /* | |
| 202 | * BMAP read-ahead maximum parameters | |
| 203 | */ | |
| 204 | #define HAMMER2_BMAP_COUNT 16 /* max bmap read-ahead */ | |
| 205 | #define HAMMER2_BMAP_BYTES (HAMMER2_PBUFSIZE * HAMMER2_BMAP_COUNT) | |
| 206 | ||
| 207 | /* | |
| 1c9f601e MD |
208 | * Misc |
| 209 | */ | |
| 210 | #define HAMMER2_FLUSH_DEPTH_LIMIT 40 /* stack recursion limit */ | |
| 211 | ||
| 212 | /* | |
| 5c23d7f1 | 213 | * HAMMER2 IN-MEMORY CACHE OF MEDIA STRUCTURES |
| 7cfa8da5 | 214 | * |
| 5c23d7f1 MD |
215 | * There is an in-memory representation of all on-media data structure. |
| 216 | * | |
| 217 | * When accessed read-only the data will be mapped to the related buffer | |
| 218 | * cache buffer. | |
| 219 | * | |
| 220 | * When accessed read-write (marked modified) a kmalloc()'d copy of the | |
| 221 | * is created which can then be modified. The copy is destroyed when a | |
| 222 | * filesystem block is allocated to replace it. | |
| 223 | * | |
| 224 | * Active inodes (those with vnodes attached) will maintain the kmalloc()'d | |
| 225 | * copy for both the read-only and the read-write case. The combination of | |
| 226 | * (bp) and (data) determines whether (data) was allocated or not. | |
| 227 | * | |
| 228 | * The in-memory representation may remain cached (for example in order to | |
| 229 | * placemark clustering locks) even after the related data has been | |
| 230 | * detached. | |
| 231 | */ | |
| 232 | ||
| 233 | /* | |
| 234 | * A hammer2 inode. | |
| 46558838 MD |
235 | * |
| 236 | * NOTE: The inode's attribute CST which is also used to lock the inode | |
| 237 | * is embedded in the chain (chain.cst) and aliased w/ attr_cst. | |
| 703720e4 MD |
238 | */ |
| 239 | struct hammer2_inode { | |
| e4e20f48 MD |
240 | struct hammer2_mount *hmp; /* Global mount */ |
| 241 | struct hammer2_pfsmount *pmp; /* PFS mount */ | |
| e028fa74 | 242 | struct hammer2_inode *pip; /* parent inode */ |
| 703720e4 | 243 | struct vnode *vp; |
| 46558838 | 244 | ccms_cst_t topo_cst; /* directory topology cst */ |
| 50e4f8f4 | 245 | hammer2_chain_t chain; |
| 5c23d7f1 | 246 | struct hammer2_inode_data ip_data; |
| 37aa19df | 247 | struct lockf advlock; |
| 99535653 | 248 | u_int depth; /* directory depth */ |
| 28ee5f14 MD |
249 | hammer2_off_t delta_dcount; /* adjust data_count */ |
| 250 | hammer2_off_t delta_icount; /* adjust inode_count */ | |
| 703720e4 MD |
251 | }; |
| 252 | ||
| 54eb943b MD |
253 | typedef struct hammer2_inode hammer2_inode_t; |
| 254 | ||
| 703720e4 | 255 | /* |
| 7cfa8da5 MD |
256 | * A hammer2 indirect block |
| 257 | */ | |
| 258 | struct hammer2_indblock { | |
| 259 | hammer2_chain_t chain; | |
| 7cfa8da5 MD |
260 | }; |
| 261 | ||
| 262 | typedef struct hammer2_indblock hammer2_indblock_t; | |
| 263 | ||
| 5c23d7f1 MD |
264 | /* |
| 265 | * A hammer2 data block | |
| 266 | */ | |
| 267 | struct hammer2_data { | |
| 268 | hammer2_chain_t chain; | |
| 269 | }; | |
| 270 | ||
| 5c23d7f1 MD |
271 | typedef struct hammer2_data hammer2_data_t; |
| 272 | ||
| 004f88b4 MD |
273 | struct hammer2_freecache { |
| 274 | hammer2_off_t bulk; | |
| 275 | hammer2_off_t single; | |
| 276 | }; | |
| 277 | ||
| 278 | typedef struct hammer2_freecache hammer2_freecache_t; | |
| 279 | ||
| 7cfa8da5 | 280 | /* |
| 10c86c4e MD |
281 | * Structure used to represent a virtual circuit for a messaging |
| 282 | * route. Typically associated from hammer2_state but the hammer2_pfsmount | |
| 283 | * structure also has one to represent the point-to-point link. | |
| 284 | */ | |
| 285 | struct hammer2_router { | |
| 286 | struct hammer2_pfsmount *pmp; | |
| 287 | struct hammer2_state *state; /* received LNK_SPAN state */ | |
| 288 | uint64_t target; /* target */ | |
| 289 | }; | |
| 290 | ||
| 291 | typedef struct hammer2_router hammer2_router_t; | |
| 292 | ||
| 293 | /* | |
| e4e20f48 | 294 | * Global (per device) mount structure for device (aka vp->v_mount->hmp) |
| 703720e4 MD |
295 | */ |
| 296 | struct hammer2_mount { | |
| 50e4f8f4 | 297 | struct vnode *devvp; /* device vnode */ |
| 50e4f8f4 | 298 | int ronly; /* read-only mount */ |
| e4e20f48 MD |
299 | int pmp_count; /* PFS mounts backed by us */ |
| 300 | TAILQ_ENTRY(hammer2_mount) mntentry; /* hammer2_mntlist */ | |
| 703720e4 | 301 | |
| 5c23d7f1 | 302 | struct malloc_type *minode; |
| 54eb943b MD |
303 | int ninodes; |
| 304 | int maxinodes; | |
| 703720e4 | 305 | |
| 5c23d7f1 | 306 | struct malloc_type *mchain; |
| 54eb943b MD |
307 | int nipstacks; |
| 308 | int maxipstacks; | |
| 7cfa8da5 MD |
309 | hammer2_chain_t vchain; /* anchor chain */ |
| 310 | hammer2_chain_t *schain; /* super-root */ | |
| 01eabad4 | 311 | struct lock alloclk; /* lockmgr lock */ |
| 2910a90c | 312 | struct lock voldatalk; /* lockmgr lock */ |
| 703720e4 | 313 | |
| 54eb943b | 314 | hammer2_volume_data_t voldata; |
| bfc3a7b1 MD |
315 | hammer2_freecache_t freecache[HAMMER2_FREECACHE_TYPES] |
| 316 | [HAMMER2_MAX_RADIX+1]; | |
| 703720e4 MD |
317 | }; |
| 318 | ||
| 54eb943b MD |
319 | typedef struct hammer2_mount hammer2_mount_t; |
| 320 | ||
| e4e20f48 MD |
321 | /* |
| 322 | * Per-PFS mount structure for device (aka vp->v_mount) | |
| 323 | */ | |
| 324 | struct hammer2_pfsmount { | |
| 325 | struct mount *mp; /* kernel mount */ | |
| 326 | struct hammer2_mount *hmp; /* device global mount */ | |
| 327 | hammer2_chain_t *rchain; /* PFS root chain */ | |
| 328 | hammer2_inode_t *iroot; /* PFS root inode */ | |
| 26bf1a36 | 329 | struct malloc_type *mmsg; |
| 609a8021 | 330 | ccms_domain_t ccms_dom; |
| e4e20f48 MD |
331 | struct netexport export; /* nfs export */ |
| 332 | int ronly; /* read-only mount */ | |
| bfc3a7b1 MD |
333 | struct file *msg_fp; /* cluster pipe->userland */ |
| 334 | thread_t msgrd_td; /* cluster thread */ | |
| 335 | thread_t msgwr_td; /* cluster thread */ | |
| 336 | int msg_ctl; /* wakeup flags */ | |
| 8c280d5d | 337 | int msg_seq; /* cluster msg sequence id */ |
| 70c3c3b7 | 338 | uint32_t reserved01; |
| 26bf1a36 MD |
339 | struct lock msglk; /* lockmgr lock */ |
| 340 | TAILQ_HEAD(, hammer2_msg) msgq; /* transmit queue */ | |
| 1a34728c | 341 | struct hammer2_state *conn_state; /* active LNK_CONN state */ |
| 26bf1a36 MD |
342 | struct hammer2_state *freerd_state; /* allocation cache */ |
| 343 | struct hammer2_state *freewr_state; /* allocation cache */ | |
| 344 | struct hammer2_state_tree staterd_tree; /* active messages */ | |
| 345 | struct hammer2_state_tree statewr_tree; /* active messages */ | |
| 10c86c4e | 346 | struct hammer2_router router; |
| e4e20f48 MD |
347 | }; |
| 348 | ||
| 349 | typedef struct hammer2_pfsmount hammer2_pfsmount_t; | |
| 350 | ||
| 1a34728c MD |
351 | /* |
| 352 | * msg_ctl flags (atomic) | |
| 353 | */ | |
| 354 | #define HAMMER2_CLUSTERCTL_KILL 0x00000001 | |
| 70c3c3b7 MD |
355 | #define HAMMER2_CLUSTERCTL_KILLRX 0x00000002 /* staged helper exit */ |
| 356 | #define HAMMER2_CLUSTERCTL_KILLTX 0x00000004 /* staged helper exit */ | |
| 357 | #define HAMMER2_CLUSTERCTL_SLEEPING 0x00000008 /* interlocked w/msglk */ | |
| bfc3a7b1 | 358 | |
| 26bf1a36 | 359 | /* |
| 10c86c4e MD |
360 | * Transactional state structure, representing an open transaction. The |
| 361 | * transaction might represent a cache state (and thus have a chain | |
| 362 | * association), or a VOP op, LNK_SPAN, or other things. | |
| 26bf1a36 MD |
363 | */ |
| 364 | struct hammer2_state { | |
| 365 | RB_ENTRY(hammer2_state) rbnode; /* indexed by msgid */ | |
| 366 | struct hammer2_pfsmount *pmp; | |
| 10c86c4e | 367 | struct hammer2_router *router; /* related LNK_SPAN route */ |
| 26bf1a36 MD |
368 | uint32_t txcmd; /* mostly for CMDF flags */ |
| 369 | uint32_t rxcmd; /* mostly for CMDF flags */ | |
| 8c280d5d | 370 | uint64_t msgid; /* {spanid,msgid} uniq */ |
| 26bf1a36 MD |
371 | int flags; |
| 372 | int error; | |
| 373 | struct hammer2_chain *chain; /* msg associated w/chain */ | |
| 374 | struct hammer2_msg *msg; | |
| 8c280d5d MD |
375 | int (*func)(struct hammer2_state *, struct hammer2_msg *); |
| 376 | union { | |
| 377 | void *any; | |
| 378 | hammer2_pfsmount_t *pmp; | |
| 379 | } any; | |
| 26bf1a36 MD |
380 | }; |
| 381 | ||
| 382 | #define HAMMER2_STATE_INSERTED 0x0001 | |
| 383 | #define HAMMER2_STATE_DYNAMIC 0x0002 | |
| 70c3c3b7 | 384 | #define HAMMER2_STATE_DELPEND 0x0004 /* transmit delete pending */ |
| 26bf1a36 MD |
385 | |
| 386 | struct hammer2_msg { | |
| 387 | TAILQ_ENTRY(hammer2_msg) qentry; /* serialized queue */ | |
| 10c86c4e | 388 | struct hammer2_router *router; |
| 26bf1a36 MD |
389 | struct hammer2_state *state; |
| 390 | size_t hdr_size; | |
| 391 | size_t aux_size; | |
| 392 | char *aux_data; | |
| 42e2a62e | 393 | hammer2_msg_any_t any; |
| 26bf1a36 MD |
394 | }; |
| 395 | ||
| 10c86c4e | 396 | typedef struct hammer2_link hammer2_link_t; |
| 26bf1a36 MD |
397 | typedef struct hammer2_state hammer2_state_t; |
| 398 | typedef struct hammer2_msg hammer2_msg_t; | |
| 399 | ||
| 400 | int hammer2_state_cmp(hammer2_state_t *state1, hammer2_state_t *state2); | |
| 401 | RB_PROTOTYPE(hammer2_state_tree, hammer2_state, rbnode, hammer2_state_cmp); | |
| 402 | ||
| 403 | ||
| 703720e4 MD |
404 | #if defined(_KERNEL) |
| 405 | ||
| 406 | MALLOC_DECLARE(M_HAMMER2); | |
| 407 | ||
| e4e20f48 MD |
408 | #define VTOI(vp) ((hammer2_inode_t *)(vp)->v_data) |
| 409 | #define ITOV(ip) ((ip)->vp) | |
| 410 | ||
| e118c14f | 411 | static __inline |
| e4e20f48 MD |
412 | hammer2_pfsmount_t * |
| 413 | MPTOPMP(struct mount *mp) | |
| 703720e4 | 414 | { |
| e4e20f48 | 415 | return ((hammer2_pfsmount_t *)mp->mnt_data); |
| 703720e4 MD |
416 | } |
| 417 | ||
| e118c14f | 418 | static __inline |
| e4e20f48 MD |
419 | hammer2_mount_t * |
| 420 | MPTOHMP(struct mount *mp) | |
| 47902fef | 421 | { |
| e4e20f48 | 422 | return (((hammer2_pfsmount_t *)mp->mnt_data)->hmp); |
| 47902fef VS |
423 | } |
| 424 | ||
| 703720e4 MD |
425 | extern struct vop_ops hammer2_vnode_vops; |
| 426 | extern struct vop_ops hammer2_spec_vops; | |
| 427 | extern struct vop_ops hammer2_fifo_vops; | |
| 428 | ||
| 37aa19df | 429 | extern int hammer2_debug; |
| 01eabad4 | 430 | extern int hammer2_cluster_enable; |
| e708f8b9 | 431 | extern int hammer2_hardlink_enable; |
| 01eabad4 MD |
432 | extern long hammer2_iod_file_read; |
| 433 | extern long hammer2_iod_meta_read; | |
| 434 | extern long hammer2_iod_indr_read; | |
| 435 | extern long hammer2_iod_file_write; | |
| 436 | extern long hammer2_iod_meta_write; | |
| 437 | extern long hammer2_iod_indr_write; | |
| 438 | extern long hammer2_iod_volu_write; | |
| 439 | extern long hammer2_ioa_file_read; | |
| 440 | extern long hammer2_ioa_meta_read; | |
| 441 | extern long hammer2_ioa_indr_read; | |
| 442 | extern long hammer2_ioa_file_write; | |
| 443 | extern long hammer2_ioa_meta_write; | |
| 444 | extern long hammer2_ioa_indr_write; | |
| 445 | extern long hammer2_ioa_volu_write; | |
| 37aa19df | 446 | |
| 7cfa8da5 MD |
447 | /* |
| 448 | * hammer2_subr.c | |
| 449 | */ | |
| 54eb943b MD |
450 | void hammer2_inode_lock_ex(hammer2_inode_t *ip); |
| 451 | void hammer2_inode_unlock_ex(hammer2_inode_t *ip); | |
| 9c2e0de0 | 452 | void hammer2_inode_lock_sh(hammer2_inode_t *ip); |
| 54eb943b | 453 | void hammer2_inode_unlock_sh(hammer2_inode_t *ip); |
| 9c2e0de0 MD |
454 | void hammer2_inode_busy(hammer2_inode_t *ip); |
| 455 | void hammer2_inode_unbusy(hammer2_inode_t *ip); | |
| 2910a90c MD |
456 | void hammer2_voldata_lock(hammer2_mount_t *hmp); |
| 457 | void hammer2_voldata_unlock(hammer2_mount_t *hmp); | |
| e118c14f | 458 | |
| 54eb943b MD |
459 | void hammer2_mount_exlock(hammer2_mount_t *hmp); |
| 460 | void hammer2_mount_shlock(hammer2_mount_t *hmp); | |
| 461 | void hammer2_mount_unlock(hammer2_mount_t *hmp); | |
| 703720e4 | 462 | |
| e028fa74 | 463 | int hammer2_get_dtype(hammer2_inode_t *ip); |
| cd4b3d92 | 464 | int hammer2_get_vtype(hammer2_inode_t *ip); |
| 37494cab | 465 | u_int8_t hammer2_get_obj_type(enum vtype vtype); |
| cd4b3d92 | 466 | void hammer2_time_to_timespec(u_int64_t xtime, struct timespec *ts); |
| b2b78aaa | 467 | u_int64_t hammer2_timespec_to_time(struct timespec *ts); |
| 37494cab | 468 | u_int32_t hammer2_to_unix_xid(uuid_t *uuid); |
| b2b78aaa | 469 | void hammer2_guid_to_uuid(uuid_t *uuid, u_int32_t guid); |
| e028fa74 | 470 | |
| 7cfa8da5 | 471 | hammer2_key_t hammer2_dirhash(const unsigned char *name, size_t len); |
| 6ba3b984 | 472 | int hammer2_bytes_to_radix(size_t bytes); |
| 7cfa8da5 | 473 | |
| 8cce658d MD |
474 | int hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff, |
| 475 | hammer2_key_t *lbasep, hammer2_key_t *leofp); | |
| b2b78aaa | 476 | void hammer2_update_time(uint64_t *timep); |
| 8cce658d | 477 | |
| 7cfa8da5 MD |
478 | /* |
| 479 | * hammer2_inode.c | |
| 480 | */ | |
| 54eb943b | 481 | struct vnode *hammer2_igetv(hammer2_inode_t *ip, int *errorp); |
| ae183399 | 482 | |
| e708f8b9 MD |
483 | void hammer2_inode_lock_nlinks(hammer2_inode_t *ip); |
| 484 | void hammer2_inode_unlock_nlinks(hammer2_inode_t *ip); | |
| e4e20f48 | 485 | hammer2_inode_t *hammer2_inode_alloc(hammer2_pfsmount_t *pmp, void *data); |
| 7cfa8da5 MD |
486 | void hammer2_inode_free(hammer2_inode_t *ip); |
| 487 | void hammer2_inode_ref(hammer2_inode_t *ip); | |
| 488 | void hammer2_inode_drop(hammer2_inode_t *ip); | |
| 866d5273 | 489 | int hammer2_inode_calc_alloc(hammer2_key_t filesize); |
| 6934ae32 | 490 | |
| e4e20f48 | 491 | int hammer2_inode_create(hammer2_inode_t *dip, |
| e708f8b9 MD |
492 | struct vattr *vap, struct ucred *cred, |
| 493 | const uint8_t *name, size_t name_len, | |
| 494 | hammer2_inode_t **nipp); | |
| 6934ae32 | 495 | |
| 99535653 MD |
496 | int hammer2_inode_duplicate(hammer2_inode_t *dip, |
| 497 | hammer2_inode_t *oip, hammer2_inode_t **nipp, | |
| 498 | const uint8_t *name, size_t name_len); | |
| 499 | int hammer2_inode_connect(hammer2_inode_t *dip, hammer2_inode_t *oip, | |
| db0c2eb3 MD |
500 | const uint8_t *name, size_t name_len); |
| 501 | ||
| ae183399 | 502 | int hammer2_unlink_file(hammer2_inode_t *dip, |
| 004f88b4 MD |
503 | const uint8_t *name, size_t name_len, |
| 504 | int isdir, hammer2_inode_t *retain_ip); | |
| 99535653 | 505 | int hammer2_hardlink_consolidate(hammer2_inode_t **ipp, hammer2_inode_t *tdip); |
| e708f8b9 MD |
506 | int hammer2_hardlink_deconsolidate(hammer2_inode_t *dip, |
| 507 | hammer2_chain_t **chainp, hammer2_inode_t **ipp); | |
| 508 | int hammer2_hardlink_find(hammer2_inode_t *dip, hammer2_chain_t **chainp, | |
| 509 | hammer2_inode_t **ipp); | |
| ae183399 | 510 | |
| 7cfa8da5 MD |
511 | /* |
| 512 | * hammer2_chain.c | |
| 513 | */ | |
| 2910a90c | 514 | void hammer2_modify_volume(hammer2_mount_t *hmp); |
| 5c23d7f1 MD |
515 | hammer2_chain_t *hammer2_chain_alloc(hammer2_mount_t *hmp, |
| 516 | hammer2_blockref_t *bref); | |
| 517 | void hammer2_chain_free(hammer2_mount_t *hmp, hammer2_chain_t *chain); | |
| 7cfa8da5 MD |
518 | void hammer2_chain_ref(hammer2_mount_t *hmp, hammer2_chain_t *chain); |
| 519 | void hammer2_chain_drop(hammer2_mount_t *hmp, hammer2_chain_t *chain); | |
| 01eabad4 MD |
520 | int hammer2_chain_lock(hammer2_mount_t *hmp, hammer2_chain_t *chain, int how); |
| 521 | void hammer2_chain_moved(hammer2_mount_t *hmp, hammer2_chain_t *chain); | |
| 214f4a77 | 522 | void hammer2_chain_modify(hammer2_mount_t *hmp, hammer2_chain_t *chain, |
| 01eabad4 | 523 | int flags); |
| 28ee5f14 | 524 | void hammer2_chain_resize(hammer2_inode_t *ip, hammer2_chain_t *chain, |
| 01eabad4 | 525 | int nradix, int flags); |
| 5c23d7f1 | 526 | void hammer2_chain_unlock(hammer2_mount_t *hmp, hammer2_chain_t *chain); |
| b7926f31 MD |
527 | hammer2_chain_t *hammer2_chain_find(hammer2_mount_t *hmp, |
| 528 | hammer2_chain_t *parent, int index); | |
| 232a50f9 | 529 | hammer2_chain_t *hammer2_chain_get(hammer2_mount_t *hmp, |
| c667909f MD |
530 | hammer2_chain_t *parent, |
| 531 | int index, int flags); | |
| 5c23d7f1 | 532 | hammer2_chain_t *hammer2_chain_lookup(hammer2_mount_t *hmp, |
| e028fa74 | 533 | hammer2_chain_t **parentp, |
| c667909f MD |
534 | hammer2_key_t key_beg, hammer2_key_t key_end, |
| 535 | int flags); | |
| 7cfa8da5 | 536 | hammer2_chain_t *hammer2_chain_next(hammer2_mount_t *hmp, |
| 5c23d7f1 MD |
537 | hammer2_chain_t **parentp, |
| 538 | hammer2_chain_t *chain, | |
| c667909f MD |
539 | hammer2_key_t key_beg, hammer2_key_t key_end, |
| 540 | int flags); | |
| 5c23d7f1 MD |
541 | hammer2_chain_t *hammer2_chain_create(hammer2_mount_t *hmp, |
| 542 | hammer2_chain_t *parent, | |
| 6934ae32 | 543 | hammer2_chain_t *chain, |
| 5c23d7f1 MD |
544 | hammer2_key_t key, int keybits, |
| 545 | int type, size_t bytes); | |
| 3ac6a319 | 546 | void hammer2_chain_delete(hammer2_mount_t *hmp, hammer2_chain_t *parent, |
| 004f88b4 | 547 | hammer2_chain_t *chain, int retain); |
| 4d5318eb MD |
548 | void hammer2_chain_flush(hammer2_mount_t *hmp, hammer2_chain_t *chain, |
| 549 | hammer2_tid_t modify_tid); | |
| b7926f31 | 550 | void hammer2_chain_commit(hammer2_mount_t *hmp, hammer2_chain_t *chain); |
| 50e4f8f4 | 551 | |
| df9ea374 | 552 | /* |
| 2910a90c MD |
553 | * hammer2_ioctl.c |
| 554 | */ | |
| 555 | int hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, | |
| 556 | int fflag, struct ucred *cred); | |
| 557 | ||
| 558 | /* | |
| 26bf1a36 MD |
559 | * hammer2_msg.c |
| 560 | */ | |
| 10c86c4e MD |
561 | int hammer2_state_msgrx(hammer2_msg_t *msg); |
| 562 | int hammer2_state_msgtx(hammer2_msg_t *msg); | |
| 563 | void hammer2_state_cleanuprx(hammer2_msg_t *msg); | |
| 564 | void hammer2_state_cleanuptx(hammer2_msg_t *msg); | |
| 565 | int hammer2_msg_execute(hammer2_msg_t *msg); | |
| 26bf1a36 | 566 | void hammer2_state_free(hammer2_state_t *state); |
| 10c86c4e | 567 | void hammer2_msg_free(hammer2_msg_t *msg); |
| 1a34728c | 568 | hammer2_msg_t *hammer2_msg_alloc(hammer2_router_t *router, uint32_t cmd, |
| 8c280d5d MD |
569 | int (*func)(hammer2_state_t *, hammer2_msg_t *), |
| 570 | void *data); | |
| 1a34728c | 571 | void hammer2_msg_write(hammer2_msg_t *msg); |
| 10c86c4e MD |
572 | void hammer2_msg_reply(hammer2_msg_t *msg, uint32_t error); |
| 573 | void hammer2_msg_result(hammer2_msg_t *msg, uint32_t error); | |
| 9b8b748f MD |
574 | |
| 575 | /* | |
| 576 | * hammer2_msgops.c | |
| 577 | */ | |
| 10c86c4e MD |
578 | int hammer2_msg_dbg_rcvmsg(hammer2_msg_t *msg); |
| 579 | int hammer2_msg_adhoc_input(hammer2_msg_t *msg); | |
| 26bf1a36 MD |
580 | |
| 581 | /* | |
| 1a34728c MD |
582 | * hammer2_vfsops.c |
| 583 | */ | |
| 584 | void hammer2_clusterctl_wakeup(hammer2_pfsmount_t *pmp); | |
| 585 | void hammer2_volconf_update(hammer2_pfsmount_t *pmp, int index); | |
| 586 | void hammer2_cluster_reconnect(hammer2_pfsmount_t *pmp, struct file *fp); | |
| 587 | ||
| 588 | /* | |
| df9ea374 MD |
589 | * hammer2_freemap.c |
| 590 | */ | |
| 6ba3b984 MD |
591 | hammer2_off_t hammer2_freemap_alloc(hammer2_mount_t *hmp, |
| 592 | int type, size_t bytes); | |
| 004f88b4 MD |
593 | void hammer2_freemap_free(hammer2_mount_t *hmp, hammer2_off_t data_off, |
| 594 | int type); | |
| df9ea374 | 595 | |
| 47902fef VS |
596 | #endif /* !_KERNEL */ |
| 597 | #endif /* !_VFS_HAMMER2_HAMMER2_H_ */ |