hammer2 - more indirect block work, add advlock
[dragonfly.git] / sys / vfs / hammer2 / hammer2.h
CommitLineData
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>
57#include <sys/globaldata.h>
58#include <sys/lockf.h>
59#include <sys/buf.h>
60#include <sys/queue.h>
61#include <sys/limits.h>
62#include <sys/buf2.h>
63#include <sys/signal2.h>
64#include <sys/tree.h>
65
66#include "hammer2_disk.h"
67#include "hammer2_mount.h"
68
5c23d7f1 69struct hammer2_chain;
703720e4
MD
70struct hammer2_inode;
71struct hammer2_mount;
72
703720e4 73/*
50e4f8f4
MD
74 * The chain structure tracks blockref recursions all the way to
75 * the root volume. These consist of indirect blocks, inodes,
76 * and eventually the volume header.
77 *
7cfa8da5
MD
78 * The chain structure is embedded in the hammer2_mount, hammer2_inode,
79 * and other system memory structures. The chain structure typically
80 * implements the reference count and busy flag for the larger structure.
81 *
82 * It is always possible to track a chain element all the way back to the
83 * root by following the (parent) links. (index) is a type-dependent index
84 * in the parent indicating where in the parent the chain element resides.
5c23d7f1
MD
85 *
86 * When a blockref is added or deleted the related chain element is marked
87 * modified and all of its parents are marked SUBMODIFIED (the parent
88 * recursion can stop once we hit a node that is already marked SUBMODIFIED).
89 * A deleted chain element must remain intact until synchronized against
90 * its parent.
91 *
92 * The blockref at (parent, index) is not adjusted until the modified chain
93 * element is flushed and unmarked. Until then the child's blockref may
94 * not match the blockref at (parent, index).
50e4f8f4 95 */
5c23d7f1
MD
96SPLAY_HEAD(hammer2_chain_splay, hammer2_chain);
97
50e4f8f4
MD
98struct hammer2_chain {
99 struct hammer2_blockref bref;
7cfa8da5 100 struct hammer2_chain *parent; /* return chain to root */
5c23d7f1
MD
101 struct hammer2_chain_splay shead;
102 SPLAY_ENTRY(hammer2_chain) snode;
7cfa8da5
MD
103 union {
104 struct hammer2_inode *ip;
5c23d7f1
MD
105 struct hammer2_indblock *np;
106 struct hammer2_data *dp;
107 void *mem;
7cfa8da5 108 } u;
5c23d7f1
MD
109
110 struct buf *bp; /* buffer cache (ro) */
111 hammer2_media_data_t *data; /* modified copy of data (rw) */
112
113 struct lock lk; /* lockmgr lock */
114 int index; /* index in parent */
115 u_int refs;
116 u_int busy; /* soft-busy */
117 u_int flags;
50e4f8f4
MD
118};
119
120typedef struct hammer2_chain hammer2_chain_t;
121
5c23d7f1
MD
122int hammer2_chain_cmp(hammer2_chain_t *chain1, hammer2_chain_t *chain2);
123SPLAY_PROTOTYPE(hammer2_chain_splay, hammer2_chain, snode, hammer2_chain_cmp);
124
125#define HAMMER2_CHAIN_MODIFIED 0x00000001 /* this elm modified */
b7926f31
MD
126#define HAMMER2_CHAIN_COMMITTING 0x00000002 /* mods committing */
127#define HAMMER2_CHAIN_SUBMODIFIED 0x00000004 /* 1+ subs modified */
128#define HAMMER2_CHAIN_SUBCOMMITTING 0x00000008 /* 1+ subs committing */
129#define HAMMER2_CHAIN_DELETED 0x00000010
130#define HAMMER2_CHAIN_INITIAL 0x00000020 /* initial write */
c667909f 131#define HAMMER2_CHAIN_FLUSHED 0x00000040 /* flush on unlock */
995e78dc 132#define HAMMER2_CHAIN_MOVED 0x00000080 /* moved */
37aa19df 133#define HAMMER2_CHAIN_IOFLUSH 0x00000100 /* bawrite on put */
c667909f
MD
134
135/*
136 * Flags passed to hammer2_chain_lookup() and hammer2_chain_next()
137 */
138#define HAMMER2_LOOKUP_NOLOCK 0x00000001 /* ref only */
5c23d7f1 139
50e4f8f4 140/*
5c23d7f1 141 * HAMMER2 IN-MEMORY CACHE OF MEDIA STRUCTURES
7cfa8da5 142 *
5c23d7f1
MD
143 * There is an in-memory representation of all on-media data structure.
144 *
145 * When accessed read-only the data will be mapped to the related buffer
146 * cache buffer.
147 *
148 * When accessed read-write (marked modified) a kmalloc()'d copy of the
149 * is created which can then be modified. The copy is destroyed when a
150 * filesystem block is allocated to replace it.
151 *
152 * Active inodes (those with vnodes attached) will maintain the kmalloc()'d
153 * copy for both the read-only and the read-write case. The combination of
154 * (bp) and (data) determines whether (data) was allocated or not.
155 *
156 * The in-memory representation may remain cached (for example in order to
157 * placemark clustering locks) even after the related data has been
158 * detached.
159 */
160
161/*
162 * A hammer2 inode.
703720e4
MD
163 */
164struct hammer2_inode {
54eb943b 165 struct hammer2_mount *hmp;
e028fa74 166 struct hammer2_inode *pip; /* parent inode */
703720e4 167 struct vnode *vp;
50e4f8f4 168 hammer2_chain_t chain;
5c23d7f1 169 struct hammer2_inode_data ip_data;
37aa19df 170 struct lockf advlock;
703720e4
MD
171};
172
54eb943b
MD
173typedef struct hammer2_inode hammer2_inode_t;
174
703720e4 175/*
7cfa8da5
MD
176 * A hammer2 indirect block
177 */
178struct hammer2_indblock {
179 hammer2_chain_t chain;
7cfa8da5
MD
180};
181
182typedef struct hammer2_indblock hammer2_indblock_t;
183
5c23d7f1
MD
184#define np_data chain.data->npdata
185
186/*
187 * A hammer2 data block
188 */
189struct hammer2_data {
190 hammer2_chain_t chain;
191};
192
193#define dp_data chain.data->buf
194
195typedef struct hammer2_data hammer2_data_t;
196
7cfa8da5 197/*
703720e4
MD
198 * Governing mount structure for filesystem (aka vp->v_mount)
199 */
200struct hammer2_mount {
50e4f8f4
MD
201 struct mount *mp; /* kernel mount */
202 struct vnode *devvp; /* device vnode */
50e4f8f4
MD
203 struct netexport export; /* nfs export */
204 int ronly; /* read-only mount */
703720e4 205
5c23d7f1 206 struct malloc_type *minode;
54eb943b
MD
207 int ninodes;
208 int maxinodes;
703720e4 209
5c23d7f1 210 struct malloc_type *mchain;
54eb943b
MD
211 int nipstacks;
212 int maxipstacks;
7cfa8da5
MD
213 hammer2_chain_t vchain; /* anchor chain */
214 hammer2_chain_t *schain; /* super-root */
215 hammer2_chain_t *rchain; /* label-root */
216 struct hammer2_inode *iroot;
703720e4 217
54eb943b 218 hammer2_volume_data_t voldata;
df9ea374 219 hammer2_off_t freecache[HAMMER2_MAX_RADIX];
703720e4
MD
220};
221
54eb943b
MD
222typedef struct hammer2_mount hammer2_mount_t;
223
703720e4
MD
224#if defined(_KERNEL)
225
226MALLOC_DECLARE(M_HAMMER2);
227
e118c14f
MD
228static __inline
229struct mount *
703720e4
MD
230H2TOMP(struct hammer2_mount *hmp)
231{
54eb943b 232 return (struct mount *) hmp->mp;
703720e4
MD
233}
234
54eb943b 235#define VTOI(vp) ((hammer2_inode_t *)(vp)->v_data)
703720e4
MD
236#define ITOV(ip) ((ip)->vp)
237
e118c14f
MD
238static __inline
239struct hammer2_mount *
47902fef
VS
240MPTOH2(struct mount *mp)
241{
54eb943b 242 return (hammer2_mount_t *) mp->mnt_data;
47902fef
VS
243}
244
703720e4
MD
245extern struct vop_ops hammer2_vnode_vops;
246extern struct vop_ops hammer2_spec_vops;
247extern struct vop_ops hammer2_fifo_vops;
248
37aa19df
MD
249extern int hammer2_debug;
250
7cfa8da5
MD
251/*
252 * hammer2_subr.c
253 */
54eb943b
MD
254void hammer2_inode_lock_ex(hammer2_inode_t *ip);
255void hammer2_inode_unlock_ex(hammer2_inode_t *ip);
9c2e0de0 256void hammer2_inode_lock_sh(hammer2_inode_t *ip);
54eb943b 257void hammer2_inode_unlock_sh(hammer2_inode_t *ip);
9c2e0de0
MD
258void hammer2_inode_busy(hammer2_inode_t *ip);
259void hammer2_inode_unbusy(hammer2_inode_t *ip);
e118c14f 260
54eb943b
MD
261void hammer2_mount_exlock(hammer2_mount_t *hmp);
262void hammer2_mount_shlock(hammer2_mount_t *hmp);
263void hammer2_mount_unlock(hammer2_mount_t *hmp);
703720e4 264
e028fa74 265int hammer2_get_dtype(hammer2_inode_t *ip);
cd4b3d92 266int hammer2_get_vtype(hammer2_inode_t *ip);
37494cab 267u_int8_t hammer2_get_obj_type(enum vtype vtype);
cd4b3d92 268void hammer2_time_to_timespec(u_int64_t xtime, struct timespec *ts);
37494cab 269u_int32_t hammer2_to_unix_xid(uuid_t *uuid);
e028fa74 270
7cfa8da5
MD
271hammer2_key_t hammer2_dirhash(const unsigned char *name, size_t len);
272
273/*
274 * hammer2_inode.c
275 */
54eb943b 276struct vnode *hammer2_igetv(hammer2_inode_t *ip, int *errorp);
232a50f9 277hammer2_inode_t *hammer2_inode_alloc(hammer2_mount_t *hmp, void *data);
7cfa8da5
MD
278void hammer2_inode_free(hammer2_inode_t *ip);
279void hammer2_inode_ref(hammer2_inode_t *ip);
280void hammer2_inode_drop(hammer2_inode_t *ip);
37494cab
MD
281int hammer2_create_inode(hammer2_mount_t *hmp,
282 struct vattr *vap, struct ucred *cred,
283 hammer2_inode_t *dip,
284 const uint8_t *name, size_t name_len,
285 hammer2_inode_t **nipp);
703720e4 286
7cfa8da5
MD
287/*
288 * hammer2_chain.c
289 */
5c23d7f1
MD
290hammer2_chain_t *hammer2_chain_alloc(hammer2_mount_t *hmp,
291 hammer2_blockref_t *bref);
292void hammer2_chain_free(hammer2_mount_t *hmp, hammer2_chain_t *chain);
7cfa8da5
MD
293void hammer2_chain_ref(hammer2_mount_t *hmp, hammer2_chain_t *chain);
294void hammer2_chain_drop(hammer2_mount_t *hmp, hammer2_chain_t *chain);
5c23d7f1
MD
295int hammer2_chain_lock(hammer2_mount_t *hmp, hammer2_chain_t *chain);
296void hammer2_chain_modify(hammer2_mount_t *hmp, hammer2_chain_t *chain);
297void hammer2_chain_unlock(hammer2_mount_t *hmp, hammer2_chain_t *chain);
b7926f31
MD
298hammer2_chain_t *hammer2_chain_find(hammer2_mount_t *hmp,
299 hammer2_chain_t *parent, int index);
232a50f9 300hammer2_chain_t *hammer2_chain_get(hammer2_mount_t *hmp,
c667909f
MD
301 hammer2_chain_t *parent,
302 int index, int flags);
232a50f9 303void hammer2_chain_put(hammer2_mount_t *hmp, hammer2_chain_t *chain);
5c23d7f1 304hammer2_chain_t *hammer2_chain_lookup(hammer2_mount_t *hmp,
e028fa74 305 hammer2_chain_t **parentp,
c667909f
MD
306 hammer2_key_t key_beg, hammer2_key_t key_end,
307 int flags);
7cfa8da5 308hammer2_chain_t *hammer2_chain_next(hammer2_mount_t *hmp,
5c23d7f1
MD
309 hammer2_chain_t **parentp,
310 hammer2_chain_t *chain,
c667909f
MD
311 hammer2_key_t key_beg, hammer2_key_t key_end,
312 int flags);
5c23d7f1
MD
313hammer2_chain_t *hammer2_chain_create(hammer2_mount_t *hmp,
314 hammer2_chain_t *parent,
315 hammer2_key_t key, int keybits,
316 int type, size_t bytes);
317void hammer2_chain_delete(hammer2_mount_t *hmp, hammer2_chain_t **parentp,
318 hammer2_chain_t *chain);
b7926f31
MD
319void hammer2_chain_flush(hammer2_mount_t *hmp, hammer2_chain_t *chain,
320 hammer2_blockref_t *parent_bref);
321void hammer2_chain_commit(hammer2_mount_t *hmp, hammer2_chain_t *chain);
50e4f8f4 322
df9ea374
MD
323/*
324 * hammer2_freemap.c
325 */
5c23d7f1 326hammer2_off_t hammer2_freemap_alloc(hammer2_mount_t *hmp, size_t bytes);
c667909f 327int hammer2_freemap_bytes_to_radix(size_t bytes);
df9ea374 328
47902fef
VS
329#endif /* !_KERNEL */
330#endif /* !_VFS_HAMMER2_HAMMER2_H_ */