HAMMER 60I/Many: Mirroring
[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.18 2008/07/09 10:29:20 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/types.h>
44 #include <sys/ioccom.h>
45 #include "hammer_disk.h"
46
47 /*
48  * Common HAMMER ioctl header
49  *
50  * Global flags are stored in the upper 16 bits.
51  */
52 struct hammer_ioc_head {
53         int32_t         flags;
54         int32_t         reserved01;
55         int32_t         reserved02[4];
56 };
57
58 #define HAMMER_IOC_HEAD_INTR    0x00010000
59 #define HAMMER_IOC_DO_BTREE     0x00020000      /* reblocker */
60 #define HAMMER_IOC_DO_INODES    0x00040000      /* reblocker */
61 #define HAMMER_IOC_DO_DATA      0x00080000      /* reblocker */
62 #define HAMMER_IOC_DO_DIRS      0x00100000      /* reblocker */
63
64 #define HAMMER_IOC_DO_FLAGS     (HAMMER_IOC_DO_BTREE |  \
65                                  HAMMER_IOC_DO_INODES | \
66                                  HAMMER_IOC_DO_DATA |   \
67                                  HAMMER_IOC_DO_DIRS)
68
69 /*
70  * HAMMERIOC_PRUNE
71  *
72  * beg/end TID ranges in the element array must be sorted in descending
73  * order, with the most recent (highest) range at elms[0].
74  */
75 struct hammer_ioc_prune_elm {
76         hammer_tid_t    beg_tid;        /* starting tid */
77         hammer_tid_t    end_tid;        /* ending tid (non inclusive) */
78         hammer_tid_t    mod_tid;        /* modulo */
79 };
80
81 #define HAMMER_MAX_PRUNE_ELMS   (1024*1024/24)
82
83 struct hammer_ioc_prune {
84         struct hammer_ioc_head head;
85         int             nelms;
86         int             reserved01;
87
88         struct hammer_base_elm key_beg; /* stop forward scan (reverse scan) */
89         struct hammer_base_elm key_end; /* start forward scan (reverse scan) */
90         struct hammer_base_elm key_cur; /* scan interruption point */
91
92         int64_t         stat_scanrecords;/* number of records scanned */
93         int64_t         stat_rawrecords; /* number of raw records pruned */
94         int64_t         stat_dirrecords; /* number of dir records pruned */
95         int64_t         stat_bytes;      /* number of data bytes pruned */
96         int64_t         stat_realignments; /* number of raw records realigned */
97         hammer_tid_t    stat_oldest_tid; /* oldest create_tid encountered */
98         int64_t         reserved02[6];
99         struct hammer_ioc_prune_elm *elms; /* user supplied array */
100 };
101
102 #define HAMMER_IOC_PRUNE_ALL    0x0001
103
104
105 /*
106  * HAMMERIOC_GETHISTORY
107  *
108  * Retrieve an array of ordered transaction ids >= beg and < end indicating
109  * all changes made to the specified object's inode up to the
110  * maximum.
111  *
112  * If ATKEY is set the key field indicates a particular key within the
113  * inode to retrieve the history for.
114  *
115  * On return count is set to the number of elements returned, nxt_tid is
116  * set to the tid the caller should store in beg_tid to continue the
117  * iteration, and nxt_key is set to the nearest key boundary > key
118  * indicating the range key - nxt_key (nxt_key non-inclusive) the tid
119  * array represents.  Also obj_id is set to the object's inode number.
120  *
121  * nxt_key can be used to iterate the contents of a single file but should
122  * not be stored in key until all modifications at key have been retrieved.
123  * To work properly nxt_key should be initialized to HAMMER_MAX_KEY.
124  * Successive ioctl() calls will reduce nxt_key as appropriate so at the
125  * end of your iterating for 'key', key to nxt_key will represent the
126  * shortest range of keys that all returned TIDs apply to.
127  */
128
129 #define HAMMER_MAX_HISTORY_ELMS 64
130
131 typedef struct hammer_ioc_hist_entry {
132         hammer_tid_t    tid;
133         u_int32_t       time32;
134         u_int32_t       unused;
135 } *hammer_ioc_hist_entry_t;
136
137 struct hammer_ioc_history {
138         struct hammer_ioc_head head;
139         int64_t         obj_id;
140         hammer_tid_t    beg_tid;
141         hammer_tid_t    nxt_tid;
142         hammer_tid_t    end_tid;
143         int64_t         key;
144         int64_t         nxt_key;
145         int             count;
146         int             reserve01;
147         struct hammer_ioc_hist_entry hist_ary[HAMMER_MAX_HISTORY_ELMS];
148 };
149
150 #define HAMMER_IOC_HISTORY_ATKEY        0x0001
151 #define HAMMER_IOC_HISTORY_NEXT_TID     0x0002  /* iterate via nxt_tid */
152 #define HAMMER_IOC_HISTORY_NEXT_KEY     0x0004  /* iterate via nxt_key */
153 #define HAMMER_IOC_HISTORY_EOF          0x0008  /* no more keys */
154 #define HAMMER_IOC_HISTORY_UNSYNCED     0x0010  /* unsynced info in inode */
155
156 /*
157  * Reblock request
158  */
159 struct hammer_ioc_reblock {
160         struct hammer_ioc_head head;
161         int32_t         free_level;             /* 0 for maximum compaction */
162         u_int32_t       reserved01;
163
164         struct hammer_base_elm key_beg;         /* start forward scan */
165         struct hammer_base_elm key_end;         /* stop forward scan */
166         struct hammer_base_elm key_cur;         /* scan interruption point */
167
168         int64_t         btree_count;            /* B-Tree nodes checked */
169         int64_t         record_count;           /* Records checked */
170         int64_t         data_count;             /* Data segments checked */
171         int64_t         data_byte_count;        /* Data bytes checked */
172
173         int64_t         btree_moves;            /* B-Tree nodes moved */
174         int64_t         record_moves;           /* Records moved */
175         int64_t         data_moves;             /* Data segments moved */
176         int64_t         data_byte_moves;        /* Data bytes moved */
177
178         int32_t         unused02;
179         int32_t         unused03;
180 };
181
182 /*
183  * HAMMERIOC_SYNCTID
184  */
185 enum hammer_synctid_op {
186         HAMMER_SYNCTID_NONE,    /* no sync (TID will not be accurate) */
187         HAMMER_SYNCTID_ASYNC,   /* async (TID will not be accurate) */
188         HAMMER_SYNCTID_SYNC1,   /* single sync - might undo after crash */
189         HAMMER_SYNCTID_SYNC2    /* double sync - guarantee no undo */
190 };
191
192 struct hammer_ioc_synctid {
193         struct hammer_ioc_head  head;
194         enum hammer_synctid_op  op;
195         hammer_tid_t            tid;
196 };
197
198 /*
199  * HAMMERIOC_GET_PSEUDOFS
200  * HAMMERIOC_SET_PSEUDOFS
201  */
202 struct hammer_ioc_pseudofs_rw {
203         struct hammer_ioc_head  head;
204         int                     pfs_id;
205         u_int32_t               bytes;
206         u_int32_t               version;
207         u_int32_t               flags;
208         struct hammer_pseudofs_data *ondisk;
209 };
210
211 #define HAMMER_IOC_PSEUDOFS_VERSION     1
212
213 #define HAMMER_IOC_PFS_SYNC_BEG         0x0001
214 #define HAMMER_IOC_PFS_SYNC_END         0x0002
215 #define HAMMER_IOC_PFS_SHARED_UUID      0x0004
216 #define HAMMER_IOC_PFS_MIRROR_UUID      0x0008
217 #define HAMMER_IOC_PFS_MASTER_ID        0x0010
218 #define HAMMER_IOC_PFS_MIRROR_FLAGS     0x0020
219 #define HAMMER_IOC_PFS_LABEL            0x0040
220
221 #define HAMMER_MAX_PFS                  65536
222
223 /*
224  * HAMMERIOC_MIRROR_READ/WRITE
225  */
226 struct hammer_ioc_mirror_rw {
227         struct hammer_ioc_head  head;
228         struct hammer_base_elm  key_beg;        /* start forward scan */
229         struct hammer_base_elm  key_end;        /* stop forward scan */
230         struct hammer_base_elm  key_cur;        /* interruption point */
231         hammer_tid_t            tid_beg;        /* filter modification range */
232         hammer_tid_t            tid_end;        /* filter modification range */
233         void                    *ubuf;          /* user buffer */
234         int                     count;          /* current size */
235         int                     size;           /* max size */
236         int                     pfs_id;         /* PFS id being read/written */
237         int                     reserved01;
238         uuid_t                  shared_uuid;    /* validator for safety */
239 };
240
241 /*
242  * NOTE: crc is for the data block starting at rec_size, not including the
243  * data[] array.
244  */
245 typedef struct hammer_ioc_mrecord {
246         u_int32_t               signature;      /* signature for byte order */
247         u_int32_t               rec_crc;
248         u_int32_t               rec_size;
249         u_int32_t               type;
250         struct hammer_btree_leaf_elm leaf;
251         /* extended by data */
252 } *hammer_ioc_mrecord_t;
253
254 #define HAMMER_MREC_TYPE_RESERVED       0
255 #define HAMMER_MREC_TYPE_REC            1
256 #define HAMMER_MREC_TYPE_PFSD           2
257 #define HAMMER_MREC_TYPE_UPDATE         3
258 #define HAMMER_MREC_TYPE_SYNC           4
259
260 #define HAMMER_MREC_CRCOFF      (offsetof(struct hammer_ioc_mrecord, rec_size))
261 #define HAMMER_MREC_HEADSIZE    sizeof(struct hammer_ioc_mrecord)
262
263 #define HAMMER_IOC_MIRROR_SIGNATURE     0x4dd97272U
264 #define HAMMER_IOC_MIRROR_SIGNATURE_REV 0x7272d94dU
265
266 /*
267  * Ioctl cmd ids
268  */
269
270 #define HAMMERIOC_PRUNE         _IOWR('h',1,struct hammer_ioc_prune)
271 #define HAMMERIOC_GETHISTORY    _IOWR('h',2,struct hammer_ioc_history)
272 #define HAMMERIOC_REBLOCK       _IOWR('h',3,struct hammer_ioc_reblock)
273 #define HAMMERIOC_SYNCTID       _IOWR('h',4,struct hammer_ioc_synctid)
274 #define HAMMERIOC_SET_PSEUDOFS  _IOWR('h',5,struct hammer_ioc_pseudofs_rw)
275 #define HAMMERIOC_GET_PSEUDOFS  _IOWR('h',6,struct hammer_ioc_pseudofs_rw)
276 #define HAMMERIOC_MIRROR_READ   _IOWR('h',7,struct hammer_ioc_mirror_rw)
277 #define HAMMERIOC_MIRROR_WRITE  _IOWR('h',8,struct hammer_ioc_mirror_rw)
278
279 #endif
280