1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _BCACHEFS_IOCTL_H |
3 | #define _BCACHEFS_IOCTL_H |
4 | |
5 | #include <linux/uuid.h> |
6 | #include <asm/ioctl.h> |
7 | #include "bcachefs_format.h" |
8 | |
9 | /* |
10 | * Flags common to multiple ioctls: |
11 | */ |
12 | #define BCH_FORCE_IF_DATA_LOST (1 << 0) |
13 | #define BCH_FORCE_IF_METADATA_LOST (1 << 1) |
14 | #define BCH_FORCE_IF_DATA_DEGRADED (1 << 2) |
15 | #define BCH_FORCE_IF_METADATA_DEGRADED (1 << 3) |
16 | |
17 | #define BCH_FORCE_IF_LOST \ |
18 | (BCH_FORCE_IF_DATA_LOST| \ |
19 | BCH_FORCE_IF_METADATA_LOST) |
20 | #define BCH_FORCE_IF_DEGRADED \ |
21 | (BCH_FORCE_IF_DATA_DEGRADED| \ |
22 | BCH_FORCE_IF_METADATA_DEGRADED) |
23 | |
24 | /* |
25 | * If cleared, ioctl that refer to a device pass it as a pointer to a pathname |
26 | * (e.g. /dev/sda1); if set, the dev field is the device's index within the |
27 | * filesystem: |
28 | */ |
29 | #define BCH_BY_INDEX (1 << 4) |
30 | |
31 | /* |
32 | * For BCH_IOCTL_READ_SUPER: get superblock of a specific device, not filesystem |
33 | * wide superblock: |
34 | */ |
35 | #define BCH_READ_DEV (1 << 5) |
36 | |
37 | /* global control dev: */ |
38 | |
39 | /* These are currently broken, and probably unnecessary: */ |
40 | #if 0 |
41 | #define BCH_IOCTL_ASSEMBLE _IOW(0xbc, 1, struct bch_ioctl_assemble) |
42 | #define BCH_IOCTL_INCREMENTAL _IOW(0xbc, 2, struct bch_ioctl_incremental) |
43 | |
44 | struct bch_ioctl_assemble { |
45 | __u32 flags; |
46 | __u32 nr_devs; |
47 | __u64 pad; |
48 | __u64 devs[]; |
49 | }; |
50 | |
51 | struct bch_ioctl_incremental { |
52 | __u32 flags; |
53 | __u64 pad; |
54 | __u64 dev; |
55 | }; |
56 | #endif |
57 | |
58 | /* filesystem ioctls: */ |
59 | |
60 | #define BCH_IOCTL_QUERY_UUID _IOR(0xbc, 1, struct bch_ioctl_query_uuid) |
61 | |
62 | /* These only make sense when we also have incremental assembly */ |
63 | #if 0 |
64 | #define BCH_IOCTL_START _IOW(0xbc, 2, struct bch_ioctl_start) |
65 | #define BCH_IOCTL_STOP _IO(0xbc, 3) |
66 | #endif |
67 | |
68 | #define BCH_IOCTL_DISK_ADD _IOW(0xbc, 4, struct bch_ioctl_disk) |
69 | #define BCH_IOCTL_DISK_REMOVE _IOW(0xbc, 5, struct bch_ioctl_disk) |
70 | #define BCH_IOCTL_DISK_ONLINE _IOW(0xbc, 6, struct bch_ioctl_disk) |
71 | #define BCH_IOCTL_DISK_OFFLINE _IOW(0xbc, 7, struct bch_ioctl_disk) |
72 | #define BCH_IOCTL_DISK_SET_STATE _IOW(0xbc, 8, struct bch_ioctl_disk_set_state) |
73 | #define BCH_IOCTL_DATA _IOW(0xbc, 10, struct bch_ioctl_data) |
74 | #define BCH_IOCTL_FS_USAGE _IOWR(0xbc, 11, struct bch_ioctl_fs_usage) |
75 | #define BCH_IOCTL_DEV_USAGE _IOWR(0xbc, 11, struct bch_ioctl_dev_usage) |
76 | #define BCH_IOCTL_READ_SUPER _IOW(0xbc, 12, struct bch_ioctl_read_super) |
77 | #define BCH_IOCTL_DISK_GET_IDX _IOW(0xbc, 13, struct bch_ioctl_disk_get_idx) |
78 | #define BCH_IOCTL_DISK_RESIZE _IOW(0xbc, 14, struct bch_ioctl_disk_resize) |
79 | #define BCH_IOCTL_DISK_RESIZE_JOURNAL _IOW(0xbc,15, struct bch_ioctl_disk_resize_journal) |
80 | |
81 | #define BCH_IOCTL_SUBVOLUME_CREATE _IOW(0xbc, 16, struct bch_ioctl_subvolume) |
82 | #define BCH_IOCTL_SUBVOLUME_DESTROY _IOW(0xbc, 17, struct bch_ioctl_subvolume) |
83 | |
84 | #define BCH_IOCTL_DEV_USAGE_V2 _IOWR(0xbc, 18, struct bch_ioctl_dev_usage_v2) |
85 | |
86 | #define BCH_IOCTL_FSCK_OFFLINE _IOW(0xbc, 19, struct bch_ioctl_fsck_offline) |
87 | #define BCH_IOCTL_FSCK_ONLINE _IOW(0xbc, 20, struct bch_ioctl_fsck_online) |
88 | |
89 | /* ioctl below act on a particular file, not the filesystem as a whole: */ |
90 | |
91 | #define BCHFS_IOC_REINHERIT_ATTRS _IOR(0xbc, 64, const char __user *) |
92 | |
93 | /* |
94 | * BCH_IOCTL_QUERY_UUID: get filesystem UUID |
95 | * |
96 | * Returns user visible UUID, not internal UUID (which may not ever be changed); |
97 | * the filesystem's sysfs directory may be found under /sys/fs/bcachefs with |
98 | * this UUID. |
99 | */ |
100 | struct bch_ioctl_query_uuid { |
101 | __uuid_t uuid; |
102 | }; |
103 | |
104 | #if 0 |
105 | struct bch_ioctl_start { |
106 | __u32 flags; |
107 | __u32 pad; |
108 | }; |
109 | #endif |
110 | |
111 | /* |
112 | * BCH_IOCTL_DISK_ADD: add a new device to an existing filesystem |
113 | * |
114 | * The specified device must not be open or in use. On success, the new device |
115 | * will be an online member of the filesystem just like any other member. |
116 | * |
117 | * The device must first be prepared by userspace by formatting with a bcachefs |
118 | * superblock, which is only used for passing in superblock options/parameters |
119 | * for that device (in struct bch_member). The new device's superblock should |
120 | * not claim to be a member of any existing filesystem - UUIDs on it will be |
121 | * ignored. |
122 | */ |
123 | |
124 | /* |
125 | * BCH_IOCTL_DISK_REMOVE: permanently remove a member device from a filesystem |
126 | * |
127 | * Any data present on @dev will be permanently deleted, and @dev will be |
128 | * removed from its slot in the filesystem's list of member devices. The device |
129 | * may be either offline or offline. |
130 | * |
131 | * Will fail removing @dev would leave us with insufficient read write devices |
132 | * or degraded/unavailable data, unless the approprate BCH_FORCE_IF_* flags are |
133 | * set. |
134 | */ |
135 | |
136 | /* |
137 | * BCH_IOCTL_DISK_ONLINE: given a disk that is already a member of a filesystem |
138 | * but is not open (e.g. because we started in degraded mode), bring it online |
139 | * |
140 | * all existing data on @dev will be available once the device is online, |
141 | * exactly as if @dev was present when the filesystem was first mounted |
142 | */ |
143 | |
144 | /* |
145 | * BCH_IOCTL_DISK_OFFLINE: offline a disk, causing the kernel to close that |
146 | * block device, without removing it from the filesystem (so it can be brought |
147 | * back online later) |
148 | * |
149 | * Data present on @dev will be unavailable while @dev is offline (unless |
150 | * replicated), but will still be intact and untouched if @dev is brought back |
151 | * online |
152 | * |
153 | * Will fail (similarly to BCH_IOCTL_DISK_SET_STATE) if offlining @dev would |
154 | * leave us with insufficient read write devices or degraded/unavailable data, |
155 | * unless the approprate BCH_FORCE_IF_* flags are set. |
156 | */ |
157 | |
158 | struct bch_ioctl_disk { |
159 | __u32 flags; |
160 | __u32 pad; |
161 | __u64 dev; |
162 | }; |
163 | |
164 | /* |
165 | * BCH_IOCTL_DISK_SET_STATE: modify state of a member device of a filesystem |
166 | * |
167 | * @new_state - one of the bch_member_state states (rw, ro, failed, |
168 | * spare) |
169 | * |
170 | * Will refuse to change member state if we would then have insufficient devices |
171 | * to write to, or if it would result in degraded data (when @new_state is |
172 | * failed or spare) unless the appropriate BCH_FORCE_IF_* flags are set. |
173 | */ |
174 | struct bch_ioctl_disk_set_state { |
175 | __u32 flags; |
176 | __u8 new_state; |
177 | __u8 pad[3]; |
178 | __u64 dev; |
179 | }; |
180 | |
181 | #define BCH_DATA_OPS() \ |
182 | x(scrub, 0) \ |
183 | x(rereplicate, 1) \ |
184 | x(migrate, 2) \ |
185 | x(rewrite_old_nodes, 3) \ |
186 | x(drop_extra_replicas, 4) |
187 | |
188 | enum bch_data_ops { |
189 | #define x(t, n) BCH_DATA_OP_##t = n, |
190 | BCH_DATA_OPS() |
191 | #undef x |
192 | BCH_DATA_OP_NR |
193 | }; |
194 | |
195 | /* |
196 | * BCH_IOCTL_DATA: operations that walk and manipulate filesystem data (e.g. |
197 | * scrub, rereplicate, migrate). |
198 | * |
199 | * This ioctl kicks off a job in the background, and returns a file descriptor. |
200 | * Reading from the file descriptor returns a struct bch_ioctl_data_event, |
201 | * indicating current progress, and closing the file descriptor will stop the |
202 | * job. The file descriptor is O_CLOEXEC. |
203 | */ |
204 | struct bch_ioctl_data { |
205 | __u16 op; |
206 | __u8 start_btree; |
207 | __u8 end_btree; |
208 | __u32 flags; |
209 | |
210 | struct bpos start_pos; |
211 | struct bpos end_pos; |
212 | |
213 | union { |
214 | struct { |
215 | __u32 dev; |
216 | __u32 pad; |
217 | } migrate; |
218 | struct { |
219 | __u64 pad[8]; |
220 | }; |
221 | }; |
222 | } __packed __aligned(8); |
223 | |
224 | enum bch_data_event { |
225 | BCH_DATA_EVENT_PROGRESS = 0, |
226 | /* XXX: add an event for reporting errors */ |
227 | BCH_DATA_EVENT_NR = 1, |
228 | }; |
229 | |
230 | struct bch_ioctl_data_progress { |
231 | __u8 data_type; |
232 | __u8 btree_id; |
233 | __u8 pad[2]; |
234 | struct bpos pos; |
235 | |
236 | __u64 sectors_done; |
237 | __u64 sectors_total; |
238 | } __packed __aligned(8); |
239 | |
240 | struct bch_ioctl_data_event { |
241 | __u8 type; |
242 | __u8 pad[7]; |
243 | union { |
244 | struct bch_ioctl_data_progress p; |
245 | __u64 pad2[15]; |
246 | }; |
247 | } __packed __aligned(8); |
248 | |
249 | struct bch_replicas_usage { |
250 | __u64 sectors; |
251 | struct bch_replicas_entry_v1 r; |
252 | } __packed; |
253 | |
254 | static inline struct bch_replicas_usage * |
255 | replicas_usage_next(struct bch_replicas_usage *u) |
256 | { |
257 | return (void *) u + replicas_entry_bytes(&u->r) + 8; |
258 | } |
259 | |
260 | /* |
261 | * BCH_IOCTL_FS_USAGE: query filesystem disk space usage |
262 | * |
263 | * Returns disk space usage broken out by data type, number of replicas, and |
264 | * by component device |
265 | * |
266 | * @replica_entries_bytes - size, in bytes, allocated for replica usage entries |
267 | * |
268 | * On success, @replica_entries_bytes will be changed to indicate the number of |
269 | * bytes actually used. |
270 | * |
271 | * Returns -ERANGE if @replica_entries_bytes was too small |
272 | */ |
273 | struct bch_ioctl_fs_usage { |
274 | __u64 capacity; |
275 | __u64 used; |
276 | __u64 online_reserved; |
277 | __u64 persistent_reserved[BCH_REPLICAS_MAX]; |
278 | |
279 | __u32 replica_entries_bytes; |
280 | __u32 pad; |
281 | |
282 | struct bch_replicas_usage replicas[]; |
283 | }; |
284 | |
285 | /* |
286 | * BCH_IOCTL_DEV_USAGE: query device disk space usage |
287 | * |
288 | * Returns disk space usage broken out by data type - both by buckets and |
289 | * sectors. |
290 | */ |
291 | struct bch_ioctl_dev_usage { |
292 | __u64 dev; |
293 | __u32 flags; |
294 | __u8 state; |
295 | __u8 pad[7]; |
296 | |
297 | __u32 bucket_size; |
298 | __u64 nr_buckets; |
299 | |
300 | __u64 buckets_ec; |
301 | |
302 | struct bch_ioctl_dev_usage_type { |
303 | __u64 buckets; |
304 | __u64 sectors; |
305 | __u64 fragmented; |
306 | } d[10]; |
307 | }; |
308 | |
309 | struct bch_ioctl_dev_usage_v2 { |
310 | __u64 dev; |
311 | __u32 flags; |
312 | __u8 state; |
313 | __u8 nr_data_types; |
314 | __u8 pad[6]; |
315 | |
316 | __u32 bucket_size; |
317 | __u64 nr_buckets; |
318 | |
319 | struct bch_ioctl_dev_usage_type d[]; |
320 | }; |
321 | |
322 | /* |
323 | * BCH_IOCTL_READ_SUPER: read filesystem superblock |
324 | * |
325 | * Equivalent to reading the superblock directly from the block device, except |
326 | * avoids racing with the kernel writing the superblock or having to figure out |
327 | * which block device to read |
328 | * |
329 | * @sb - buffer to read into |
330 | * @size - size of userspace allocated buffer |
331 | * @dev - device to read superblock for, if BCH_READ_DEV flag is |
332 | * specified |
333 | * |
334 | * Returns -ERANGE if buffer provided is too small |
335 | */ |
336 | struct bch_ioctl_read_super { |
337 | __u32 flags; |
338 | __u32 pad; |
339 | __u64 dev; |
340 | __u64 size; |
341 | __u64 sb; |
342 | }; |
343 | |
344 | /* |
345 | * BCH_IOCTL_DISK_GET_IDX: give a path to a block device, query filesystem to |
346 | * determine if disk is a (online) member - if so, returns device's index |
347 | * |
348 | * Returns -ENOENT if not found |
349 | */ |
350 | struct bch_ioctl_disk_get_idx { |
351 | __u64 dev; |
352 | }; |
353 | |
354 | /* |
355 | * BCH_IOCTL_DISK_RESIZE: resize filesystem on a device |
356 | * |
357 | * @dev - member to resize |
358 | * @nbuckets - new number of buckets |
359 | */ |
360 | struct bch_ioctl_disk_resize { |
361 | __u32 flags; |
362 | __u32 pad; |
363 | __u64 dev; |
364 | __u64 nbuckets; |
365 | }; |
366 | |
367 | /* |
368 | * BCH_IOCTL_DISK_RESIZE_JOURNAL: resize journal on a device |
369 | * |
370 | * @dev - member to resize |
371 | * @nbuckets - new number of buckets |
372 | */ |
373 | struct bch_ioctl_disk_resize_journal { |
374 | __u32 flags; |
375 | __u32 pad; |
376 | __u64 dev; |
377 | __u64 nbuckets; |
378 | }; |
379 | |
380 | struct bch_ioctl_subvolume { |
381 | __u32 flags; |
382 | __u32 dirfd; |
383 | __u16 mode; |
384 | __u16 pad[3]; |
385 | __u64 dst_ptr; |
386 | __u64 src_ptr; |
387 | }; |
388 | |
389 | #define BCH_SUBVOL_SNAPSHOT_CREATE (1U << 0) |
390 | #define BCH_SUBVOL_SNAPSHOT_RO (1U << 1) |
391 | |
392 | /* |
393 | * BCH_IOCTL_FSCK_OFFLINE: run fsck from the 'bcachefs fsck' userspace command, |
394 | * but with the kernel's implementation of fsck: |
395 | */ |
396 | struct bch_ioctl_fsck_offline { |
397 | __u64 flags; |
398 | __u64 opts; /* string */ |
399 | __u64 nr_devs; |
400 | __u64 devs[] __counted_by(nr_devs); |
401 | }; |
402 | |
403 | /* |
404 | * BCH_IOCTL_FSCK_ONLINE: run fsck from the 'bcachefs fsck' userspace command, |
405 | * but with the kernel's implementation of fsck: |
406 | */ |
407 | struct bch_ioctl_fsck_online { |
408 | __u64 flags; |
409 | __u64 opts; /* string */ |
410 | }; |
411 | |
412 | #endif /* _BCACHEFS_IOCTL_H */ |
413 | |