2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
34 * $DragonFly: src/sys/vfs/hammer/hammer_ioctl.h,v 1.23 2008/11/13 02:18:43 dillon Exp $
37 * HAMMER ioctl's. This file can be #included from userland
40 #ifndef VFS_HAMMER_IOCTL_H_
41 #define VFS_HAMMER_IOCTL_H_
43 #include <sys/param.h>
44 #include <sys/ioccom.h>
46 #include "hammer_disk.h"
49 * Common HAMMER ioctl header
51 * Global flags are stored in the upper 16 bits.
53 struct hammer_ioc_head {
56 int32_t reserved02[4];
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 */
66 #define HAMMER_IOC_DO_FLAGS (HAMMER_IOC_DO_BTREE | \
67 HAMMER_IOC_DO_INODES | \
68 HAMMER_IOC_DO_DATA | \
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].
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 */
83 #define HAMMER_MAX_PRUNE_ELMS (1024*1024/24)
85 struct hammer_ioc_prune {
86 struct hammer_ioc_head head;
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 */
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 */
104 #define HAMMER_IOC_PRUNE_ALL 0x0001
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.
113 struct hammer_ioc_rebalance {
114 struct hammer_ioc_head head;
115 int saturation; /* saturation pt elements/node */
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 */
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 */
131 * HAMMERIOC_GETHISTORY
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
137 * If ATKEY is set the key field indicates a particular key within the
138 * inode to retrieve the history for.
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.
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.
154 #define HAMMER_MAX_HISTORY_ELMS 64
156 typedef struct hammer_ioc_hist_entry {
160 } *hammer_ioc_hist_entry_t;
162 struct hammer_ioc_history {
163 struct hammer_ioc_head head;
165 hammer_tid_t beg_tid;
166 hammer_tid_t nxt_tid;
167 hammer_tid_t end_tid;
172 struct hammer_ioc_hist_entry hist_ary[HAMMER_MAX_HISTORY_ELMS];
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 */
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;
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 */
193 int64_t btree_count; /* B-Tree nodes checked */
195 int64_t data_count; /* Data segments checked */
196 int64_t data_byte_count; /* Data bytes checked */
198 int64_t btree_moves; /* B-Tree nodes moved */
200 int64_t data_moves; /* Data segments moved */
201 int64_t data_byte_moves; /* Data bytes moved */
203 int16_t allpfs; /* Reblock all PFS if set */
204 int16_t vol_no; /* Volume to reblock if set */
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 */
218 struct hammer_ioc_synctid {
219 struct hammer_ioc_head head;
220 enum hammer_synctid_op op;
227 struct hammer_ioc_info {
228 struct hammer_ioc_head head;
240 int64_t freebigblocks;
241 int64_t rsvbigblocks;
244 int64_t reservedext[16];
248 * HAMMERIOC_PFS_ITERATE
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;
257 * HAMMERIOC_GET_PSEUDOFS
258 * HAMMERIOC_SET_PSEUDOFS
260 struct hammer_ioc_pseudofs_rw {
261 struct hammer_ioc_head head;
266 struct hammer_pseudofs_data *ondisk;
269 #define HAMMER_IOC_PSEUDOFS_VERSION 1
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
279 #define HAMMER_MAX_PFS 65536
282 * HAMMERIOC_MIRROR_READ/WRITE
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 */
296 uuid_t shared_uuid; /* validator for safety */
299 #define HAMMER_IOC_MIRROR_NODATA 0x0001 /* do not include bulk data */
302 * NOTE: crc is for the data block starting at rec_size, not including the
305 struct hammer_ioc_mrecord_head {
306 u_int32_t signature; /* signature for byte order */
313 typedef struct hammer_ioc_mrecord_head *hammer_ioc_mrecord_head_t;
315 struct hammer_ioc_mrecord_rec {
316 struct hammer_ioc_mrecord_head head;
317 struct hammer_btree_leaf_elm leaf;
318 /* extended by data */
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;
327 struct hammer_ioc_mrecord_update {
328 struct hammer_ioc_mrecord_head head;
332 struct hammer_ioc_mrecord_sync {
333 struct hammer_ioc_mrecord_head head;
336 struct hammer_ioc_mrecord_pfs {
337 struct hammer_ioc_mrecord_head head;
339 u_int32_t reserved01;
340 struct hammer_pseudofs_data pfsd;
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];
352 struct hammer_ioc_volume {
353 struct hammer_ioc_head head;
354 char device_name[MAXPATHLEN];
356 int64_t boot_area_size;
357 int64_t mem_area_size;
360 struct hammer_ioc_volume_list {
361 struct hammer_ioc_volume *vols;
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;
375 typedef union hammer_ioc_mrecord_any *hammer_ioc_mrecord_any_t;
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.
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.
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) */
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 | \
399 #define HAMMER_MRECF_TYPE_LOMASK 0x000000FF
400 #define HAMMER_MRECF_TYPE_MASK 0x800000FF
401 #define HAMMER_MRECF_CRC_ERROR 0x80000000
403 #define HAMMER_MRECF_DATA_CRC_BAD 0x40000000
404 #define HAMMER_MRECF_RECD_CRC_BAD 0x20000000
405 #define HAMMER_MRECF_NODATA 0x10000000
407 #define HAMMER_MREC_CRCOFF (offsetof(struct hammer_ioc_mrecord_head, rec_size))
408 #define HAMMER_MREC_HEADSIZE sizeof(struct hammer_ioc_mrecord_head)
410 #define HAMMER_IOC_MIRROR_SIGNATURE 0x4dd97272U
411 #define HAMMER_IOC_MIRROR_SIGNATURE_REV 0x7272d94dU
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)
419 * These are per-PFS operations.
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.
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.
427 #define HAMMER_SNAPS_PER_IOCTL 16
429 #define HAMMER_IOC_SNAPSHOT_EOF 0x0008 /* no more keys */
431 struct hammer_ioc_snapshot {
432 struct hammer_ioc_head head;
436 struct hammer_snapshot_data snaps[HAMMER_SNAPS_PER_IOCTL];
440 * HAMMERIOC_GET_CONFIG
441 * HAMMERIOC_SET_CONFIG
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.
446 * The configuration space is NOT mirrored. mirror-write will ignore
447 * configuration space records.
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;
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 */
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 */
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 */
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)
512 #endif /* !VFS_HAMMER_IOCTL_H_ */