sys/vfs/hammer: Add ifndef/define/endif for headers
[dragonfly.git] / sys / vfs / hammer / hammer_ioctl.h
1 /*
2  * Copyright (c) 2008 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_ioctl.h,v 1.23 2008/11/13 02:18:43 dillon Exp $
35  */
36 /*
37  * HAMMER ioctl's.  This file can be #included from userland
38  */
39
40 #ifndef VFS_HAMMER_IOCTL_H_
41 #define VFS_HAMMER_IOCTL_H_
42
43 #include <sys/param.h>
44 #include <sys/ioccom.h>
45
46 #include "hammer_disk.h"
47
48 /*
49  * Common HAMMER ioctl header
50  *
51  * Global flags are stored in the upper 16 bits.
52  */
53 struct hammer_ioc_head {
54         int32_t         flags;
55         int32_t         error;
56         int32_t         reserved02[4];
57 };
58
59 #define HAMMER_IOC_HEAD_ERROR   0x00008000
60 #define HAMMER_IOC_HEAD_INTR    0x00010000
61 #define HAMMER_IOC_DO_BTREE     0x00020000      /* reblocker */
62 #define HAMMER_IOC_DO_INODES    0x00040000      /* reblocker */
63 #define HAMMER_IOC_DO_DATA      0x00080000      /* reblocker */
64 #define HAMMER_IOC_DO_DIRS      0x00100000      /* reblocker */
65
66 #define HAMMER_IOC_DO_FLAGS     (HAMMER_IOC_DO_BTREE |  \
67                                  HAMMER_IOC_DO_INODES | \
68                                  HAMMER_IOC_DO_DATA |   \
69                                  HAMMER_IOC_DO_DIRS)
70
71 /*
72  * HAMMERIOC_PRUNE
73  *
74  * beg/end TID ranges in the element array must be sorted in descending
75  * order, with the most recent (highest) range at elms[0].
76  */
77 struct hammer_ioc_prune_elm {
78         hammer_tid_t    beg_tid;        /* starting tid */
79         hammer_tid_t    end_tid;        /* ending tid (non inclusive) */
80         hammer_tid_t    mod_tid;        /* modulo */
81 };
82
83 #define HAMMER_MAX_PRUNE_ELMS   (1024*1024/24)
84
85 struct hammer_ioc_prune {
86         struct hammer_ioc_head head;
87         int             nelms;
88         int             reserved01;
89
90         struct hammer_base_elm key_beg; /* stop forward scan (reverse scan) */
91         struct hammer_base_elm key_end; /* start forward scan (reverse scan) */
92         struct hammer_base_elm key_cur; /* scan interruption point */
93
94         int64_t         stat_scanrecords;/* number of records scanned */
95         int64_t         stat_rawrecords; /* number of raw records pruned */
96         int64_t         stat_dirrecords; /* number of dir records pruned */
97         int64_t         stat_bytes;      /* number of data bytes pruned */
98         int64_t         stat_realignments; /* number of raw records realigned */
99         hammer_tid_t    stat_oldest_tid; /* oldest create_tid encountered */
100         int64_t         reserved02[6];
101         struct hammer_ioc_prune_elm *elms; /* user supplied array */
102 };
103
104 #define HAMMER_IOC_PRUNE_ALL    0x0001
105
106 /*
107  * HAMMERIOC_REPACK
108  *
109  * Forward scan leaf-up B-Tree packing.  The saturation point is typically
110  * set to HAMMER_BTREE_LEAF_ELMS * 2 / 3 for 2/3rds fill.  Referenced nodes
111  * have to be skipped, we can't track cursors through pack ops.
112  */
113 struct hammer_ioc_rebalance {
114         struct hammer_ioc_head head;
115         int             saturation;     /* saturation pt elements/node */
116         int             reserved02;
117
118         struct hammer_base_elm key_beg; /* start forward scan */
119         struct hammer_base_elm key_end; /* stop forward scan (inclusive) */
120         struct hammer_base_elm key_cur; /* current scan index */
121
122         int64_t         stat_ncount;    /* number of nodes scanned */
123         int64_t         stat_deletions; /* number of nodes deleted */
124         int64_t         stat_collisions;/* number of collision retries */
125         int64_t         stat_nrebal;    /* number of btree-nodes rebalanced */
126         int32_t         allpfs;         /* rebalance all PFS if set */
127         int32_t         unused04;
128 };
129
130 /*
131  * HAMMERIOC_GETHISTORY
132  *
133  * Retrieve an array of ordered transaction ids >= beg and < end indicating
134  * all changes made to the specified object's inode up to the
135  * maximum.
136  *
137  * If ATKEY is set the key field indicates a particular key within the
138  * inode to retrieve the history for.
139  *
140  * On return count is set to the number of elements returned, nxt_tid is
141  * set to the tid the caller should store in beg_tid to continue the
142  * iteration, and nxt_key is set to the nearest key boundary > key
143  * indicating the range key - nxt_key (nxt_key non-inclusive) the tid
144  * array represents.  Also obj_id is set to the object's inode number.
145  *
146  * nxt_key can be used to iterate the contents of a single file but should
147  * not be stored in key until all modifications at key have been retrieved.
148  * To work properly nxt_key should be initialized to HAMMER_MAX_KEY.
149  * Successive ioctl() calls will reduce nxt_key as appropriate so at the
150  * end of your iterating for 'key', key to nxt_key will represent the
151  * shortest range of keys that all returned TIDs apply to.
152  */
153
154 #define HAMMER_MAX_HISTORY_ELMS 64
155
156 typedef struct hammer_ioc_hist_entry {
157         hammer_tid_t    tid;
158         u_int32_t       time32;
159         u_int32_t       unused;
160 } *hammer_ioc_hist_entry_t;
161
162 struct hammer_ioc_history {
163         struct hammer_ioc_head head;
164         int64_t         obj_id;
165         hammer_tid_t    beg_tid;
166         hammer_tid_t    nxt_tid;
167         hammer_tid_t    end_tid;
168         int64_t         key;
169         int64_t         nxt_key;
170         int             count;
171         int             reserve01;
172         struct hammer_ioc_hist_entry hist_ary[HAMMER_MAX_HISTORY_ELMS];
173 };
174
175 #define HAMMER_IOC_HISTORY_ATKEY        0x0001
176 #define HAMMER_IOC_HISTORY_NEXT_TID     0x0002  /* iterate via nxt_tid */
177 #define HAMMER_IOC_HISTORY_NEXT_KEY     0x0004  /* iterate via nxt_key */
178 #define HAMMER_IOC_HISTORY_EOF          0x0008  /* no more keys */
179 #define HAMMER_IOC_HISTORY_UNSYNCED     0x0010  /* unsynced info in inode */
180
181 /*
182  * Reblock request
183  */
184 struct hammer_ioc_reblock {
185         struct hammer_ioc_head head;
186         int32_t         free_level;             /* 0 for maximum compaction */
187         u_int32_t       reserved01;
188
189         struct hammer_base_elm key_beg;         /* start forward scan */
190         struct hammer_base_elm key_end;         /* stop forward scan */
191         struct hammer_base_elm key_cur;         /* scan interruption point */
192
193         int64_t         btree_count;            /* B-Tree nodes checked */
194         int64_t         reserved02a;
195         int64_t         data_count;             /* Data segments checked */
196         int64_t         data_byte_count;        /* Data bytes checked */
197
198         int64_t         btree_moves;            /* B-Tree nodes moved */
199         int64_t         reserved02b;
200         int64_t         data_moves;             /* Data segments moved */
201         int64_t         data_byte_moves;        /* Data bytes moved */
202
203         int16_t         allpfs;                 /* Reblock all PFS if set */
204         int16_t         vol_no;                 /* Volume to reblock if set */
205         int32_t         unused03;
206 };
207
208 /*
209  * HAMMERIOC_SYNCTID
210  */
211 enum hammer_synctid_op {
212         HAMMER_SYNCTID_NONE,    /* no sync (TID will not be accurate) */
213         HAMMER_SYNCTID_ASYNC,   /* async (TID will not be accurate) */
214         HAMMER_SYNCTID_SYNC1,   /* single sync - might undo after crash */
215         HAMMER_SYNCTID_SYNC2    /* double sync - guarantee no undo */
216 };
217
218 struct hammer_ioc_synctid {
219         struct hammer_ioc_head  head;
220         enum hammer_synctid_op  op;
221         hammer_tid_t            tid;
222 };
223
224 /*
225  * HAMMERIOC_GET_INFO
226  */
227 struct hammer_ioc_info {
228         struct hammer_ioc_head          head;
229
230         char            vol_name[64];
231         uuid_t          vol_fsid;
232         uuid_t          vol_fstype;
233
234         int             version;
235         int             nvolumes;
236         int             reserved01;
237         int             reserved02;
238
239         int64_t         bigblocks;
240         int64_t         freebigblocks;
241         int64_t         rsvbigblocks;
242         int64_t         inodes;
243
244         int64_t         reservedext[16];
245 };
246
247 /*
248  * HAMMERIOC_PFS_ITERATE
249  */
250 struct hammer_ioc_pfs_iterate {
251         struct hammer_ioc_head  head;
252         uint32_t pos;  /* set PFS id here */
253         struct hammer_pseudofs_data *ondisk;
254 };
255
256 /*
257  * HAMMERIOC_GET_PSEUDOFS
258  * HAMMERIOC_SET_PSEUDOFS
259  */
260 struct hammer_ioc_pseudofs_rw {
261         struct hammer_ioc_head  head;
262         int                     pfs_id;
263         u_int32_t               bytes;
264         u_int32_t               version;
265         u_int32_t               flags;
266         struct hammer_pseudofs_data *ondisk;
267 };
268
269 #define HAMMER_IOC_PSEUDOFS_VERSION     1
270
271 #define HAMMER_IOC_PFS_SYNC_BEG         0x0001
272 #define HAMMER_IOC_PFS_SYNC_END         0x0002
273 #define HAMMER_IOC_PFS_SHARED_UUID      0x0004
274 #define HAMMER_IOC_PFS_MIRROR_UUID      0x0008
275 #define HAMMER_IOC_PFS_MASTER_ID        0x0010
276 #define HAMMER_IOC_PFS_MIRROR_FLAGS     0x0020
277 #define HAMMER_IOC_PFS_LABEL            0x0040
278
279 #define HAMMER_MAX_PFS                  65536
280
281 /*
282  * HAMMERIOC_MIRROR_READ/WRITE
283  */
284 struct hammer_ioc_mirror_rw {
285         struct hammer_ioc_head  head;
286         struct hammer_base_elm  key_beg;        /* start forward scan */
287         struct hammer_base_elm  key_end;        /* stop forward scan */
288         struct hammer_base_elm  key_cur;        /* interruption point */
289         hammer_tid_t            tid_beg;        /* filter modification range */
290         hammer_tid_t            tid_end;        /* filter modification range */
291         void                    *ubuf;          /* user buffer */
292         int                     count;          /* current size */
293         int                     size;           /* max size */
294         int                     pfs_id;         /* PFS id being read/written */
295         int                     reserved01;
296         uuid_t                  shared_uuid;    /* validator for safety */
297 };
298
299 #define HAMMER_IOC_MIRROR_NODATA        0x0001  /* do not include bulk data */
300
301 /*
302  * NOTE: crc is for the data block starting at rec_size, not including the
303  * data[] array.
304  */
305 struct hammer_ioc_mrecord_head {
306         u_int32_t               signature;      /* signature for byte order */
307         u_int32_t               rec_crc;
308         u_int32_t               rec_size;
309         u_int32_t               type;
310         /* extended */
311 };
312
313 typedef struct hammer_ioc_mrecord_head *hammer_ioc_mrecord_head_t;
314
315 struct hammer_ioc_mrecord_rec {
316         struct hammer_ioc_mrecord_head  head;
317         struct hammer_btree_leaf_elm    leaf;
318         /* extended by data */
319 };
320
321 struct hammer_ioc_mrecord_skip {
322         struct hammer_ioc_mrecord_head  head;
323         struct hammer_base_elm          skip_beg;
324         struct hammer_base_elm          skip_end;
325 };
326
327 struct hammer_ioc_mrecord_update {
328         struct hammer_ioc_mrecord_head  head;
329         hammer_tid_t                    tid;
330 };
331
332 struct hammer_ioc_mrecord_sync {
333         struct hammer_ioc_mrecord_head  head;
334 };
335
336 struct hammer_ioc_mrecord_pfs {
337         struct hammer_ioc_mrecord_head  head;
338         u_int32_t                       version;
339         u_int32_t                       reserved01;
340         struct hammer_pseudofs_data     pfsd;
341 };
342
343 struct hammer_ioc_version {
344         struct hammer_ioc_head head;
345         u_int32_t               cur_version;
346         u_int32_t               min_version;
347         u_int32_t               wip_version;
348         u_int32_t               max_version;
349         char                    description[64];
350 };
351
352 struct hammer_ioc_volume {
353         struct hammer_ioc_head head;
354         char                    device_name[MAXPATHLEN];
355         int64_t                 vol_size;
356         int64_t                 boot_area_size;
357         int64_t                 mem_area_size;
358 };
359
360 struct hammer_ioc_volume_list {
361         struct hammer_ioc_volume *vols;
362         int nvols;
363 };
364
365 union hammer_ioc_mrecord_any {
366         struct hammer_ioc_mrecord_head  head;
367         struct hammer_ioc_mrecord_rec   rec;
368         struct hammer_ioc_mrecord_skip  skip;
369         struct hammer_ioc_mrecord_update update;
370         struct hammer_ioc_mrecord_update sync;
371         struct hammer_ioc_mrecord_pfs   pfs;
372         struct hammer_ioc_version       version;
373 };
374
375 typedef union hammer_ioc_mrecord_any *hammer_ioc_mrecord_any_t;
376
377 /*
378  * MREC types.  Flags are in the upper 16 bits but some are also included
379  * in the type mask to force them into any switch() on the type.
380  *
381  * NOTE: Any record whos data is CRC-errored will have HAMMER_MRECF_CRC set,
382  *       and the bit is also part of the type mask.
383  */
384 #define HAMMER_MREC_TYPE_RESERVED       0
385 #define HAMMER_MREC_TYPE_REC            1       /* record w/ data */
386 #define HAMMER_MREC_TYPE_PFSD           2       /* (userland only) */
387 #define HAMMER_MREC_TYPE_UPDATE         3       /* (userland only) */
388 #define HAMMER_MREC_TYPE_SYNC           4       /* (userland only) */
389 #define HAMMER_MREC_TYPE_SKIP           5       /* skip-range */
390 #define HAMMER_MREC_TYPE_PASS           6       /* record for cmp only (pass) */
391 #define HAMMER_MREC_TYPE_TERM           7       /* (userland only) */
392 #define HAMMER_MREC_TYPE_IDLE           8       /* (userland only) */
393
394 #define HAMMER_MREC_TYPE_REC_BADCRC     (HAMMER_MREC_TYPE_REC | \
395                                          HAMMER_MRECF_CRC_ERROR)
396 #define HAMMER_MREC_TYPE_REC_NODATA     (HAMMER_MREC_TYPE_REC | \
397                                          HAMMER_MRECF_NODATA)
398
399 #define HAMMER_MRECF_TYPE_LOMASK        0x000000FF
400 #define HAMMER_MRECF_TYPE_MASK          0x800000FF
401 #define HAMMER_MRECF_CRC_ERROR          0x80000000
402
403 #define HAMMER_MRECF_DATA_CRC_BAD       0x40000000
404 #define HAMMER_MRECF_RECD_CRC_BAD       0x20000000
405 #define HAMMER_MRECF_NODATA             0x10000000
406
407 #define HAMMER_MREC_CRCOFF      (offsetof(struct hammer_ioc_mrecord_head, rec_size))
408 #define HAMMER_MREC_HEADSIZE    sizeof(struct hammer_ioc_mrecord_head)
409
410 #define HAMMER_IOC_MIRROR_SIGNATURE     0x4dd97272U
411 #define HAMMER_IOC_MIRROR_SIGNATURE_REV 0x7272d94dU
412
413 /*
414  * HAMMERIOC_ADD_SNAPSHOT - Add snapshot tid(s).
415  * HAMMERIOC_DEL_SNAPSHOT - Delete snapshot tids.
416  * HAMMERIOC_GET_SNAPSHOT - Get/continue retrieving snapshot tids.
417  *                          (finds restart point based on last snaps[] entry)
418  *
419  * These are per-PFS operations.
420  *
421  * NOTE: There is no limit on the number of snapshots, but there is a limit
422  *       on how many can be set or returned in each ioctl.
423  *
424  * NOTE: ADD and DEL start at snap->index.  If an error occurs the index will
425  *       point at the errored record.  snap->index must be set to 0 for GET.
426  */
427 #define HAMMER_SNAPS_PER_IOCTL          16
428
429 #define HAMMER_IOC_SNAPSHOT_EOF         0x0008  /* no more keys */
430
431 struct hammer_ioc_snapshot {
432         struct hammer_ioc_head  head;
433         int                     unused01;
434         u_int32_t               index;
435         u_int32_t               count;
436         struct hammer_snapshot_data snaps[HAMMER_SNAPS_PER_IOCTL];
437 };
438
439 /*
440  * HAMMERIOC_GET_CONFIG
441  * HAMMERIOC_SET_CONFIG
442  *
443  * The configuration space is a freeform nul-terminated string, typically
444  * a text file.  It is per-PFS and used by the 'hammer cleanup' utility.
445  *
446  * The configuration space is NOT mirrored.  mirror-write will ignore
447  * configuration space records.
448  */
449 struct hammer_ioc_config {
450         struct hammer_ioc_head  head;
451         u_int32_t               reserved01;
452         u_int32_t               reserved02;
453         u_int64_t               reserved03[4];
454         struct hammer_config_data config;
455 };
456
457 /*
458  * HAMMERIOC_DEDUP
459  */
460 struct hammer_ioc_dedup {
461         struct hammer_ioc_head  head;
462         struct hammer_base_elm  elm1;
463         struct hammer_base_elm  elm2; /* candidate for dedup */
464 };
465
466 #define HAMMER_IOC_DEDUP_CMP_FAILURE    0x0001 /* verification failed */
467 #define HAMMER_IOC_DEDUP_UNDERFLOW      0x0002 /* big-block underflow */
468 #define HAMMER_IOC_DEDUP_INVALID_ZONE   0x0004 /* we can't dedup all zones */
469
470 /*
471  * HAMMERIOC_GET_DATA
472  */
473 struct hammer_ioc_data {
474         struct hammer_ioc_head          head;
475         struct hammer_base_elm          elm;    /* btree key to lookup */
476         struct hammer_btree_leaf_elm    leaf;
477         void                            *ubuf;  /* user buffer */
478         int                             size;   /* max size */
479 };
480
481 /*
482  * Ioctl cmd ids
483  */
484 #define HAMMERIOC_PRUNE         _IOWR('h',1,struct hammer_ioc_prune)
485 #define HAMMERIOC_GETHISTORY    _IOWR('h',2,struct hammer_ioc_history)
486 #define HAMMERIOC_REBLOCK       _IOWR('h',3,struct hammer_ioc_reblock)
487 #define HAMMERIOC_SYNCTID       _IOWR('h',4,struct hammer_ioc_synctid)
488 #define HAMMERIOC_SET_PSEUDOFS  _IOWR('h',5,struct hammer_ioc_pseudofs_rw)
489 #define HAMMERIOC_GET_PSEUDOFS  _IOWR('h',6,struct hammer_ioc_pseudofs_rw)
490 #define HAMMERIOC_MIRROR_READ   _IOWR('h',7,struct hammer_ioc_mirror_rw)
491 #define HAMMERIOC_MIRROR_WRITE  _IOWR('h',8,struct hammer_ioc_mirror_rw)
492 #define HAMMERIOC_UPG_PSEUDOFS  _IOWR('h',9,struct hammer_ioc_pseudofs_rw)
493 #define HAMMERIOC_DGD_PSEUDOFS  _IOWR('h',10,struct hammer_ioc_pseudofs_rw)
494 #define HAMMERIOC_RMR_PSEUDOFS  _IOWR('h',11,struct hammer_ioc_pseudofs_rw)
495 #define HAMMERIOC_WAI_PSEUDOFS  _IOWR('h',12,struct hammer_ioc_pseudofs_rw)
496 #define HAMMERIOC_GET_VERSION   _IOWR('h',13,struct hammer_ioc_version)
497 #define HAMMERIOC_SET_VERSION   _IOWR('h',14,struct hammer_ioc_version)
498 #define HAMMERIOC_REBALANCE     _IOWR('h',15,struct hammer_ioc_rebalance)
499 #define HAMMERIOC_GET_INFO      _IOR('h',16,struct hammer_ioc_info)
500 #define HAMMERIOC_ADD_VOLUME    _IOWR('h',17,struct hammer_ioc_volume)
501 #define HAMMERIOC_ADD_SNAPSHOT  _IOWR('h',18,struct hammer_ioc_snapshot)
502 #define HAMMERIOC_DEL_SNAPSHOT  _IOWR('h',19,struct hammer_ioc_snapshot)
503 #define HAMMERIOC_GET_SNAPSHOT  _IOWR('h',20,struct hammer_ioc_snapshot)
504 #define HAMMERIOC_GET_CONFIG    _IOWR('h',21,struct hammer_ioc_config)
505 #define HAMMERIOC_SET_CONFIG    _IOWR('h',22,struct hammer_ioc_config)
506 #define HAMMERIOC_DEL_VOLUME    _IOWR('h',24,struct hammer_ioc_volume)
507 #define HAMMERIOC_DEDUP         _IOWR('h',25,struct hammer_ioc_dedup)
508 #define HAMMERIOC_GET_DATA      _IOWR('h',26,struct hammer_ioc_data)
509 #define HAMMERIOC_LIST_VOLUMES  _IOWR('h',27,struct hammer_ioc_volume_list)
510 #define HAMMERIOC_PFS_ITERATE   _IOWR('h',28,struct hammer_ioc_pfs_iterate)
511
512 #endif /* !VFS_HAMMER_IOCTL_H_ */
513