xref: /dragonfly/sys/vfs/hammer/hammer.h (revision 8e9b4bd4)
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