Add quirk for SONY SMO drive. This (pre SCSI-2) drive returns a mystic
[dragonfly.git] / sys / vfs / hammer / hammer.h
CommitLineData
8750964d
MD
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 *
66325755 34 * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.5 2007/11/07 00:43:24 dillon Exp $
8750964d
MD
35 */
36/*
37 * This header file contains structures used internally by the HAMMERFS
c60bb2c5 38 * implementation. See hammer_disk.h for on-disk structures.
8750964d
MD
39 */
40
427e5fc6
MD
41#include <sys/param.h>
42#include <sys/types.h>
43#include <sys/kernel.h>
44#include <sys/systm.h>
8750964d
MD
45#include <sys/tree.h>
46#include <sys/malloc.h>
427e5fc6
MD
47#include <sys/mount.h>
48#include <sys/vnode.h>
49#include <sys/globaldata.h>
66325755
MD
50#include <sys/lockf.h>
51#include <sys/buf.h>
52#include <sys/globaldata.h>
53
54#include <sys/buf2.h>
55
c60bb2c5 56#include "hammer_alist.h"
427e5fc6 57#include "hammer_disk.h"
8750964d
MD
58#include "hammer_mount.h"
59
60#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
61
62MALLOC_DECLARE(M_HAMMER);
63
66325755
MD
64struct hammer_mount;
65
8750964d
MD
66/*
67 * Key structure used for custom RB tree inode lookups. This prototypes
68 * the function hammer_ino_rb_tree_RB_LOOKUP_INFO(root, info).
69 */
70typedef struct hammer_inode_info {
71 u_int64_t obj_id; /* (key) object identifier */
72 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */
73} *hammer_inode_info_t;
74
66325755
MD
75/*
76 * HAMMER Transaction tracking
77 */
78struct hammer_transaction {
79 struct hammer_mount *hmp;
80 hammer_tid_t tid;
81};
82
83/*
84 * HAMMER locks
85 */
427e5fc6
MD
86struct hammer_lock {
87 int refs;
88 int wanted;
89 struct thread *locktd;
8750964d
MD
90};
91
427e5fc6
MD
92static __inline int
93hammer_islocked(struct hammer_lock *lock)
94{
95 return(lock->refs > 0);
96}
97
98static __inline int
99hammer_islastref(struct hammer_lock *lock)
100{
101 return(lock->refs == 1);
102}
c60bb2c5 103
8750964d
MD
104/*
105 * Structures used to internally represent an inode
106 */
107struct hammer_ino_rb_tree;
108struct hammer_inode;
109RB_HEAD(hammer_ino_rb_tree, hammer_inode);
110RB_PROTOTYPEX(hammer_ino_rb_tree, INFO, hammer_inode, rb_node,
111 hammer_ino_rb_compare, hammer_inode_info_t);
112
113struct hammer_inode {
114 RB_ENTRY(hammer_inode) rb_node;
115 u_int64_t obj_id; /* (key) object identifier */
116 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */
66325755
MD
117 hammer_tid_t obj_lasttid; /* last modified tid (for fsync) */
118 struct hammer_mount *hmp;
119 int flags;
c60bb2c5 120 struct vnode *vp;
66325755 121 struct lockf advlock;
c60bb2c5
MD
122 struct hammer_inode_record ino_rec;
123 struct hammer_inode_data ino_data;
427e5fc6 124 struct hammer_lock lock;
8750964d
MD
125};
126
66325755
MD
127#define VTOI(vp) ((struct hammer_inode *)(vp)->v_data)
128
129#define HAMMER_INODE_DDIRTY 0x0001
130#define HAMMER_INODE_RDIRTY 0x0002
131#define HAMMER_INODE_ITIMES 0x0004 /* mtime or atime modified */
132
8750964d
MD
133/*
134 * Structures used to internally represent a volume and a cluster
135 */
136
137struct hammer_volume;
138struct hammer_cluster;
427e5fc6
MD
139struct hammer_supercl;
140struct hammer_buffer;
8750964d
MD
141RB_HEAD(hammer_vol_rb_tree, hammer_volume);
142RB_HEAD(hammer_clu_rb_tree, hammer_cluster);
427e5fc6
MD
143RB_HEAD(hammer_scl_rb_tree, hammer_supercl);
144RB_HEAD(hammer_buf_rb_tree, hammer_buffer);
8750964d
MD
145
146RB_PROTOTYPE2(hammer_vol_rb_tree, hammer_volume, rb_node,
147 hammer_vol_rb_compare, int32_t);
148RB_PROTOTYPE2(hammer_clu_rb_tree, hammer_cluster, rb_node,
149 hammer_clu_rb_compare, int32_t);
427e5fc6
MD
150RB_PROTOTYPE2(hammer_scl_rb_tree, hammer_supercl, rb_node,
151 hammer_scl_rb_compare, int32_t);
152RB_PROTOTYPE2(hammer_buf_rb_tree, hammer_buffer, rb_node,
153 hammer_buf_rb_compare, int32_t);
8750964d 154
66325755
MD
155/*
156 * IO management - embedded at the head of various in-memory structures
157 */
158enum hammer_io_type { HAMMER_STRUCTURE_VOLUME,
159 HAMMER_STRUCTURE_SUPERCL,
160 HAMMER_STRUCTURE_CLUSTER,
161 HAMMER_STRUCTURE_BUFFER };
162
163union hammer_io_structure;
164
165struct worklist {
166 LIST_ENTRY(worklist) node;
167};
168
169struct hammer_io {
170 struct worklist worklist;
171 struct hammer_lock lock;
172 enum hammer_io_type type;
173 struct buf *bp;
174 int64_t offset;
175 u_int modified : 1; /* bp's data was modified */
176 u_int released : 1; /* bp released (w/ B_LOCKED set) */
177};
178
179/*
180 * In-memory volume
181 */
8750964d 182struct hammer_volume {
66325755 183 struct hammer_io io;
8750964d
MD
184 RB_ENTRY(hammer_volume) rb_node;
185 struct hammer_clu_rb_tree rb_clus_root;
427e5fc6 186 struct hammer_scl_rb_tree rb_scls_root;
8750964d 187 struct hammer_volume_ondisk *ondisk;
427e5fc6 188 struct hammer_alist_live alist;
8750964d
MD
189 int32_t vol_no;
190 int32_t vol_clsize;
191 int64_t cluster_base; /* base offset of cluster 0 */
c60bb2c5 192 char *vol_name;
8750964d
MD
193 struct vnode *devvp;
194 struct hammer_mount *hmp;
427e5fc6 195 int vol_flags;
8750964d
MD
196};
197
66325755
MD
198/*
199 * In-memory super-cluster
200 */
427e5fc6 201struct hammer_supercl {
66325755 202 struct hammer_io io;
427e5fc6 203 RB_ENTRY(hammer_supercl) rb_node;
427e5fc6
MD
204 struct hammer_supercl_ondisk *ondisk;
205 struct hammer_volume *volume;
206 struct hammer_alist_live alist;
207 int32_t scl_no;
427e5fc6 208};
c60bb2c5 209
66325755
MD
210/*
211 * In-memory cluster
212 */
8750964d 213struct hammer_cluster {
66325755 214 struct hammer_io io;
8750964d 215 RB_ENTRY(hammer_cluster) rb_node;
427e5fc6 216 struct hammer_buf_rb_tree rb_bufs_root;
8750964d
MD
217 struct hammer_cluster_ondisk *ondisk;
218 struct hammer_volume *volume;
427e5fc6
MD
219 struct hammer_alist_live alist_master;
220 struct hammer_alist_live alist_btree;
221 struct hammer_alist_live alist_record;
222 struct hammer_alist_live alist_mdata;
8750964d 223 int32_t clu_no;
427e5fc6
MD
224};
225
66325755
MD
226/*
227 * In-memory buffer (other then volume, super-cluster, or cluster)
228 */
427e5fc6 229struct hammer_buffer {
66325755 230 struct hammer_io io;
427e5fc6 231 RB_ENTRY(hammer_buffer) rb_node;
427e5fc6
MD
232 hammer_fsbuf_ondisk_t ondisk;
233 struct hammer_cluster *cluster;
234 struct hammer_volume *volume;
235 struct hammer_alist_live alist;
236 int32_t buf_no;
66325755
MD
237};
238
239union hammer_io_structure {
240 struct hammer_io io;
241 struct hammer_volume volume;
242 struct hammer_supercl supercl;
243 struct hammer_cluster cluster;
244 struct hammer_buffer buffer;
8750964d
MD
245};
246
427e5fc6
MD
247#define HAMFS_CLUSTER_DIRTY 0x0001
248
8750964d
MD
249/*
250 * Internal hammer mount data structure
251 */
252struct hammer_mount {
253 struct mount *mp;
27ea2398 254 /*struct vnode *rootvp;*/
8750964d
MD
255 struct hammer_ino_rb_tree rb_inos_root;
256 struct hammer_vol_rb_tree rb_vols_root;
257 struct hammer_volume *rootvol;
258 struct hammer_cluster *rootcl;
427e5fc6
MD
259 /* struct hammer_volume *cache_volume */
260 /* struct hammer_cluster *cache_cluster */
261 /* struct hammer_buffer *cache_buffer */
66325755 262 char *zbuf; /* HAMMER_BUFSIZE bytes worth of all-zeros */
8750964d 263 uuid_t fsid;
66325755
MD
264 udev_t fsid_udev;
265 u_int32_t namekey_iterator;
266 hammer_tid_t last_tid;
8750964d
MD
267};
268
269
270#endif
271
272#if defined(_KERNEL)
273
274extern struct vop_ops hammer_vnode_vops;
427e5fc6
MD
275extern struct hammer_alist_config Buf_alist_config;
276extern struct hammer_alist_config Vol_normal_alist_config;
277extern struct hammer_alist_config Vol_super_alist_config;
278extern struct hammer_alist_config Supercl_alist_config;
279extern struct hammer_alist_config Clu_master_alist_config;
280extern struct hammer_alist_config Clu_slave_alist_config;
66325755 281extern struct bio_ops hammer_bioops;
427e5fc6 282
8750964d
MD
283int hammer_vop_inactive(struct vop_inactive_args *);
284int hammer_vop_reclaim(struct vop_reclaim_args *);
285int hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
286
66325755
MD
287int hammer_get_vnode(struct hammer_inode *ip, int lktype,
288 struct vnode **vpp);
289struct hammer_inode *hammer_get_inode(struct hammer_mount *hmp,
290 u_int64_t obj_id, int *errorp);
291void hammer_lock_inode(struct hammer_inode *ip);
292void hammer_put_inode(struct hammer_inode *ip);
293void hammer_put_inode_ref(struct hammer_inode *ip);
294
295int hammer_unload_inode(struct hammer_inode *ip, void *data __unused);
8750964d
MD
296int hammer_unload_volume(struct hammer_volume *volume, void *data __unused);
297int hammer_load_volume(struct hammer_mount *hmp, const char *volname);
8750964d 298
427e5fc6
MD
299void hammer_lock(struct hammer_lock *lock);
300void hammer_unlock(struct hammer_lock *lock);
66325755
MD
301void hammer_ref(struct hammer_lock *lock);
302void hammer_unref(struct hammer_lock *lock);
303void hammer_ref_to_lock(struct hammer_lock *lock);
304void hammer_lock_to_ref(struct hammer_lock *lock);
305u_int32_t hammer_to_unix_xid(uuid_t *uuid);
306void hammer_to_timespec(u_int64_t hammerts, struct timespec *ts);
307enum vtype hammer_get_vnode_type(u_int8_t obj_type);
308u_int8_t hammer_get_obj_type(enum vtype vtype);
309int64_t hammer_directory_namekey(void *name, int len);
427e5fc6
MD
310
311int hammer_btree_lookup(hammer_btree_info_t info,
312 hammer_base_elm_t key, int flags);
66325755
MD
313int hammer_btree_extract(hammer_btree_info_t info, int flags);
314int hammer_btree_iterate(hammer_btree_cursor_t cursor,
315 hammer_base_elm_t key);
427e5fc6
MD
316int hammer_btree_insert(hammer_btree_info_t info,
317 hammer_btree_leaf_elm_t elm);
318int hammer_btree_delete(hammer_btree_info_t info, hammer_base_elm_t key);
319int hammer_btree_cursor_init(hammer_btree_cursor_t cursor,
320 struct hammer_cluster *cluster);
321void hammer_btree_cursor_done(hammer_btree_cursor_t cusor);
322int hammer_btree_info_init(hammer_btree_info_t info,
323 struct hammer_cluster *cluster);
324void hammer_btree_info_done(hammer_btree_info_t info);
8750964d 325
c60bb2c5 326void *hammer_bread(struct hammer_cluster *cluster, int32_t cloff,
427e5fc6
MD
327 u_int64_t buf_type,
328 int *errorp, struct hammer_buffer **bufferp);
329
330struct hammer_volume *hammer_get_volume(struct hammer_mount *hmp,
331 int32_t vol_no, int *errorp);
332struct hammer_supercl *hammer_get_supercl(struct hammer_volume *volume,
333 int32_t scl_no, int *errorp, int isnew);
334struct hammer_cluster *hammer_get_cluster(struct hammer_volume *volume,
335 int32_t clu_no, int *errorp, int isnew);
336struct hammer_buffer *hammer_get_buffer(struct hammer_cluster *cluster,
337 int32_t buf_no, int64_t buf_type, int *errorp);
66325755 338struct hammer_cluster *hammer_get_rootcl(struct hammer_mount *hmp);
427e5fc6
MD
339void hammer_dup_buffer(struct hammer_buffer **bufferp,
340 struct hammer_buffer *buffer);
341void hammer_dup_cluster(struct hammer_cluster **clusterp,
342 struct hammer_cluster *cluster);
343void *hammer_alloc_btree(struct hammer_cluster *cluster,
344 int *errorp, struct hammer_buffer **bufferp);
345void *hammer_alloc_data(struct hammer_cluster *cluster, int32_t bytes,
346 int *errorp, struct hammer_buffer **bufferp);
347void *hammer_alloc_record(struct hammer_cluster *cluster,
348 int *errorp, struct hammer_buffer **bufferp);
349void hammer_free_btree_ptr(struct hammer_buffer *buffer,
350 hammer_btree_node_t node);
351void hammer_free_data_ptr(struct hammer_buffer *buffer,
352 void *data, int bytes);
353void hammer_free_record_ptr(struct hammer_buffer *buffer,
354 union hammer_record_ondisk *rec);
355void hammer_free_btree(struct hammer_cluster *cluster, int32_t bclu_offset);
356void hammer_free_data(struct hammer_cluster *cluster, int32_t bclu_offset,
357 int32_t bytes);
358void hammer_free_record(struct hammer_cluster *cluster, int32_t bclu_offset);
359
66325755
MD
360void hammer_put_volume(struct hammer_volume *volume, int flush);
361void hammer_put_supercl(struct hammer_supercl *supercl, int flush);
362void hammer_put_cluster(struct hammer_cluster *cluster, int flush);
363void hammer_put_buffer(struct hammer_buffer *buffer, int flush);
427e5fc6
MD
364
365void hammer_init_alist_config(void);
8750964d 366
66325755
MD
367void hammer_start_transaction(struct hammer_mount *hmp,
368 struct hammer_transaction *trans);
369void hammer_commit_transaction(struct hammer_transaction *trans);
370void hammer_abort_transaction(struct hammer_transaction *trans);
371
372void hammer_modify_inode(struct hammer_transaction *trans,
373 struct hammer_inode *ip, int flags);
374int hammer_alloc_inode(struct hammer_transaction *trans, struct vattr *vap,
375 struct ucred *cred, struct hammer_inode **ipp);
376int hammer_add_directory(struct hammer_transaction *trans,
377 struct hammer_inode *dip, struct namecache *ncp,
378 struct hammer_inode *nip);
379
380int hammer_io_read(struct vnode *devvp, struct hammer_io *io);
381int hammer_io_new(struct vnode *devvp, struct hammer_io *io);
382void hammer_io_release(struct hammer_io *io, int flush);
383
8750964d
MD
384#endif
385
427e5fc6
MD
386/*
387 * Inline support functions (not kernel specific)
388 */
389static __inline void
390hammer_modify_volume(struct hammer_volume *volume)
391{
66325755 392 volume->io.modified = 1;
427e5fc6
MD
393}
394
395static __inline void
396hammer_modify_supercl(struct hammer_supercl *supercl)
397{
66325755 398 supercl->io.modified = 1;
427e5fc6
MD
399}
400
401static __inline void
402hammer_modify_cluster(struct hammer_cluster *cluster)
403{
66325755 404 cluster->io.modified = 1;
427e5fc6
MD
405}
406
407static __inline void
408hammer_modify_buffer(struct hammer_buffer *buffer)
409{
66325755 410 buffer->io.modified = 1;
427e5fc6
MD
411}
412
413/*
414 * Return the cluster-relative byte offset of an element within a buffer
415 */
416static __inline int
417hammer_bclu_offset(struct hammer_buffer *buffer, void *ptr)
418{
419 int bclu_offset;
420
421 bclu_offset = buffer->buf_no * HAMMER_BUFSIZE +
422 ((char *)ptr - (char *)buffer->ondisk);
423 return(bclu_offset);
424}
425