summaryrefslogtreecommitdiff
path: root/fs/bcachefs/bcachefs_ioctl.h
blob: c65104ed454a6ad6083dfac2cab3d3a2f83227d3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_IOCTL_H
#define _BCACHEFS_IOCTL_H

#include <linux/uuid.h>
#include <asm/ioctl.h>
#include "bcachefs_format.h"

/*
 * Flags common to multiple ioctls:
 */
#define BCH_FORCE_IF_DATA_LOST		(1 << 0)
#define BCH_FORCE_IF_METADATA_LOST	(1 << 1)
#define BCH_FORCE_IF_DATA_DEGRADED	(1 << 2)
#define BCH_FORCE_IF_METADATA_DEGRADED	(1 << 3)

#define BCH_FORCE_IF_DEGRADED			\
	(BCH_FORCE_IF_DATA_DEGRADED|		\
	 BCH_FORCE_IF_METADATA_DEGRADED)

/*
 * If cleared, ioctl that refer to a device pass it as a pointer to a pathname
 * (e.g. /dev/sda1); if set, the dev field is the device's index within the
 * filesystem:
 */
#define BCH_BY_INDEX			(1 << 4)

/*
 * For BCH_IOCTL_READ_SUPER: get superblock of a specific device, not filesystem
 * wide superblock:
 */
#define BCH_READ_DEV			(1 << 5)

/* global control dev: */

/* These are currently broken, and probably unnecessary: */
#if 0
#define BCH_IOCTL_ASSEMBLE	_IOW(0xbc, 1, struct bch_ioctl_assemble)
#define BCH_IOCTL_INCREMENTAL	_IOW(0xbc, 2, struct bch_ioctl_incremental)

struct bch_ioctl_assemble {
	__u32			flags;
	__u32			nr_devs;
	__u64			pad;
	__u64			devs[];
};

struct bch_ioctl_incremental {
	__u32			flags;
	__u64			pad;
	__u64			dev;
};
#endif

/* filesystem ioctls: */

#define BCH_IOCTL_QUERY_UUID	_IOR(0xbc,	1,  struct bch_ioctl_query_uuid)

/* These only make sense when we also have incremental assembly */
#if 0
#define BCH_IOCTL_START		_IOW(0xbc,	2,  struct bch_ioctl_start)
#define BCH_IOCTL_STOP		_IO(0xbc,	3)
#endif

#define BCH_IOCTL_DISK_ADD	_IOW(0xbc,	4,  struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_REMOVE	_IOW(0xbc,	5,  struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_ONLINE	_IOW(0xbc,	6,  struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_OFFLINE	_IOW(0xbc,	7,  struct bch_ioctl_disk)
#define BCH_IOCTL_DISK_SET_STATE _IOW(0xbc,	8,  struct bch_ioctl_disk_set_state)
#define BCH_IOCTL_DATA		_IOW(0xbc,	10, struct bch_ioctl_data)
#define BCH_IOCTL_USAGE		_IOWR(0xbc,	11, struct bch_ioctl_usage)
#define BCH_IOCTL_READ_SUPER	_IOW(0xbc,	12, struct bch_ioctl_read_super)
#define BCH_IOCTL_DISK_GET_IDX	_IOW(0xbc,	13,  struct bch_ioctl_disk_get_idx)
#define BCH_IOCTL_DISK_RESIZE	_IOW(0xbc,	13,  struct bch_ioctl_disk_resize)

/*
 * BCH_IOCTL_QUERY_UUID: get filesystem UUID
 *
 * Returns user visible UUID, not internal UUID (which may not ever be changed);
 * the filesystem's sysfs directory may be found under /sys/fs/bcachefs with
 * this UUID.
 */
struct bch_ioctl_query_uuid {
	__uuid_t		uuid;
};

#if 0
struct bch_ioctl_start {
	__u32			flags;
	__u32			pad;
};
#endif

/*
 * BCH_IOCTL_DISK_ADD: add a new device to an existing filesystem
 *
 * The specified device must not be open or in use. On success, the new device
 * will be an online member of the filesystem just like any other member.
 *
 * The device must first be prepared by userspace by formatting with a bcachefs
 * superblock, which is only used for passing in superblock options/parameters
 * for that device (in struct bch_member). The new device's superblock should
 * not claim to be a member of any existing filesystem - UUIDs on it will be
 * ignored.
 */

/*
 * BCH_IOCTL_DISK_REMOVE: permanently remove a member device from a filesystem
 *
 * Any data present on @dev will be permanently deleted, and @dev will be
 * removed from its slot in the filesystem's list of member devices. The device
 * may be either offline or offline.
 *
 * Will fail removing @dev would leave us with insufficient read write devices
 * or degraded/unavailable data, unless the approprate BCH_FORCE_IF_* flags are
 * set.
 */

/*
 * BCH_IOCTL_DISK_ONLINE: given a disk that is already a member of a filesystem
 * but is not open (e.g. because we started in degraded mode), bring it online
 *
 * all existing data on @dev will be available once the device is online,
 * exactly as if @dev was present when the filesystem was first mounted
 */

/*
 * BCH_IOCTL_DISK_OFFLINE: offline a disk, causing the kernel to close that
 * block device, without removing it from the filesystem (so it can be brought
 * back online later)
 *
 * Data present on @dev will be unavailable while @dev is offline (unless
 * replicated), but will still be intact and untouched if @dev is brought back
 * online
 *
 * Will fail (similarly to BCH_IOCTL_DISK_SET_STATE) if offlining @dev would
 * leave us with insufficient read write devices or degraded/unavailable data,
 * unless the approprate BCH_FORCE_IF_* flags are set.
 */

struct bch_ioctl_disk {
	__u32			flags;
	__u32			pad;
	__u64			dev;
};

/*
 * BCH_IOCTL_DISK_SET_STATE: modify state of a member device of a filesystem
 *
 * @new_state		- one of the bch_member_state states (rw, ro, failed,
 *			  spare)
 *
 * Will refuse to change member state if we would then have insufficient devices
 * to write to, or if it would result in degraded data (when @new_state is
 * failed or spare) unless the appropriate BCH_FORCE_IF_* flags are set.
 */
struct bch_ioctl_disk_set_state {
	__u32			flags;
	__u8			new_state;
	__u8			pad[3];
	__u64			dev;
};

enum bch_data_ops {
	BCH_DATA_OP_SCRUB	= 0,
	BCH_DATA_OP_REREPLICATE	= 1,
	BCH_DATA_OP_MIGRATE	= 2,
	BCH_DATA_OP_NR		= 3,
};

/*
 * BCH_IOCTL_DATA: operations that walk and manipulate filesystem data (e.g.
 * scrub, rereplicate, migrate).
 *
 * This ioctl kicks off a job in the background, and returns a file descriptor.
 * Reading from the file descriptor returns a struct bch_ioctl_data_event,
 * indicating current progress, and closing the file descriptor will stop the
 * job. The file descriptor is O_CLOEXEC.
 */
struct bch_ioctl_data {
	__u32			op;
	__u32			flags;

	struct bpos		start;
	struct bpos		end;

	union {
	struct {
		__u32		dev;
		__u32		pad;
	}			migrate;
	struct {
		__u64		pad[8];
	};
	};
} __attribute__((packed, aligned(8)));

enum bch_data_event {
	BCH_DATA_EVENT_PROGRESS	= 0,
	/* XXX: add an event for reporting errors */
	BCH_DATA_EVENT_NR	= 1,
};

struct bch_ioctl_data_progress {
	__u8			data_type;
	__u8			btree_id;
	__u8			pad[2];
	struct bpos		pos;

	__u64			sectors_done;
	__u64			sectors_total;
} __attribute__((packed, aligned(8)));

struct bch_ioctl_data_event {
	__u8			type;
	__u8			pad[7];
	union {
	struct bch_ioctl_data_progress p;
	__u64			pad2[15];
	};
} __attribute__((packed, aligned(8)));

struct bch_ioctl_dev_usage {
	__u8			state;
	__u8			alive;
	__u8			pad[6];
	__u32			dev;

	__u32			bucket_size;
	__u64			nr_buckets;

	__u64			buckets[BCH_DATA_NR];
	__u64			sectors[BCH_DATA_NR];
};

struct bch_ioctl_fs_usage {
	__u64			capacity;
	__u64			used;
	__u64			online_reserved;
	__u64			persistent_reserved[BCH_REPLICAS_MAX];
	__u64			sectors[BCH_DATA_NR][BCH_REPLICAS_MAX];
};

/*
 * BCH_IOCTL_USAGE: query filesystem disk space usage
 *
 * Returns disk space usage broken out by data type, number of replicas, and
 * by component device
 *
 * @nr_devices	- number of devices userspace allocated space for in @devs
 *
 * On success, @fs and @devs will be filled out appropriately and devs[i].alive
 * will indicate if a device was present in that slot
 *
 * Returns -ERANGE if @nr_devices was too small
 */
struct bch_ioctl_usage {
	__u16			nr_devices;
	__u16			pad[3];

	struct bch_ioctl_fs_usage fs;
	struct bch_ioctl_dev_usage devs[0];
};

/*
 * BCH_IOCTL_READ_SUPER: read filesystem superblock
 *
 * Equivalent to reading the superblock directly from the block device, except
 * avoids racing with the kernel writing the superblock or having to figure out
 * which block device to read
 *
 * @sb		- buffer to read into
 * @size	- size of userspace allocated buffer
 * @dev		- device to read superblock for, if BCH_READ_DEV flag is
 *		  specified
 *
 * Returns -ERANGE if buffer provided is too small
 */
struct bch_ioctl_read_super {
	__u32			flags;
	__u32			pad;
	__u64			dev;
	__u64			size;
	__u64			sb;
};

/*
 * BCH_IOCTL_DISK_GET_IDX: give a path to a block device, query filesystem to
 * determine if disk is a (online) member - if so, returns device's index
 *
 * Returns -ENOENT if not found
 */
struct bch_ioctl_disk_get_idx {
	__u64			dev;
};

/*
 * BCH_IOCTL_DISK_RESIZE: resize filesystem on a device
 *
 * @dev		- member to resize
 * @nbuckets	- new number of buckets
 */
struct bch_ioctl_disk_resize {
	__u32			flags;
	__u32			pad;
	__u64			dev;
	__u64			nbuckets;
};

#endif /* _BCACHEFS_IOCTL_H */