Commit 14b393ee authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet
Browse files

bcachefs: Subvolumes, snapshots



This patch adds subvolume.c - support for the subvolumes and snapshots
btrees and related data types and on disk data structures. The next
patches will start hooking up this new code to existing code.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent 8948fc8f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ bcachefs-y := \
	replicas.o		\
	siphash.o		\
	six.o			\
	subvolume.o		\
	super.o			\
	super-io.o		\
	sysfs.o			\
+23 −0
Original line number Diff line number Diff line
@@ -381,6 +381,8 @@ enum gc_phase {
	GC_PHASE_BTREE_alloc,
	GC_PHASE_BTREE_quotas,
	GC_PHASE_BTREE_reflink,
	GC_PHASE_BTREE_subvolumes,
	GC_PHASE_BTREE_snapshots,

	GC_PHASE_PENDING_DELETE,
};
@@ -564,6 +566,21 @@ struct btree_path_buf {

#define REPLICAS_DELTA_LIST_MAX	(1U << 16)

struct snapshot_t {
	u32			parent;
	u32			children[2];
	u32			subvol; /* Nonzero only if a subvolume points to this node: */
	u32			equiv;
};

typedef struct {
	u32		subvol;
	u64		inum;
} subvol_inum;

#define BCACHEFS_ROOT_SUBVOL_INUM					\
	((subvol_inum) { BCACHEFS_ROOT_SUBVOL,	BCACHEFS_ROOT_INO })

struct bch_fs {
	struct closure		cl;

@@ -635,6 +652,12 @@ struct bch_fs {
	struct closure		sb_write;
	struct mutex		sb_lock;

	/* snapshot.c: */
	GENRADIX(struct snapshot_t) snapshots;
	struct bch_snapshot_table __rcu *snapshot_table;
	struct mutex		snapshot_table_lock;
	struct work_struct	snapshot_delete_work;

	/* BTREE CACHE */
	struct bio_set		btree_bio;
	struct workqueue_struct	*io_complete_wq;
+52 −3
Original line number Diff line number Diff line
@@ -346,7 +346,9 @@ static inline void bkey_init(struct bkey *k)
	x(inline_data,		17)			\
	x(btree_ptr_v2,		18)			\
	x(indirect_inline_data,	19)			\
	x(alloc_v2,		20)
	x(alloc_v2,		20)			\
	x(subvolume,		21)			\
	x(snapshot,		22)

enum bch_bkey_type {
#define x(name, nr) KEY_TYPE_##name	= nr,
@@ -690,6 +692,10 @@ struct bch_inode_generation {
	__le32			pad;
} __attribute__((packed, aligned(8)));

/*
 * bi_subvol and bi_parent_subvol are only set for subvolume roots:
 */

#define BCH_INODE_FIELDS()			\
	x(bi_atime,			96)	\
	x(bi_ctime,			96)	\
@@ -713,7 +719,9 @@ struct bch_inode_generation {
	x(bi_erasure_code,		16)	\
	x(bi_fields_set,		16)	\
	x(bi_dir,			64)	\
	x(bi_dir_offset,		64)
	x(bi_dir_offset,		64)	\
	x(bi_subvol,			32)	\
	x(bi_parent_subvol,		32)

/* subset of BCH_INODE_FIELDS */
#define BCH_INODE_OPTS()			\
@@ -796,6 +804,9 @@ struct bch_dirent {
	__u8			d_name[];
} __attribute__((packed, aligned(8)));

#define DT_SUBVOL	16
#define BCH_DT_MAX	17

#define BCH_NAME_MAX	(U8_MAX * sizeof(u64) -				\
			 sizeof(struct bkey) -				\
			 offsetof(struct bch_dirent, d_name))
@@ -932,6 +943,42 @@ struct bch_inline_data {
	u8			data[0];
};

/* Subvolumes: */

#define SUBVOL_POS_MIN		POS(0, 1)
#define SUBVOL_POS_MAX		POS(0, S32_MAX)
#define BCACHEFS_ROOT_SUBVOL	1

struct bch_subvolume {
	struct bch_val		v;
	__le32			flags;
	__le32			snapshot;
	__le64			inode;
};

LE32_BITMASK(BCH_SUBVOLUME_RO,		struct bch_subvolume, flags,  0,  1)
/*
 * We need to know whether a subvolume is a snapshot so we can know whether we
 * can delete it (or whether it should just be rm -rf'd)
 */
LE32_BITMASK(BCH_SUBVOLUME_SNAP,	struct bch_subvolume, flags,  1,  2)

/* Snapshots */

struct bch_snapshot {
	struct bch_val		v;
	__le32			flags;
	__le32			parent;
	__le32			children[2];
	__le32			subvol;
	__le32			pad;
};

LE32_BITMASK(BCH_SNAPSHOT_DELETED,	struct bch_snapshot, flags,  0,  1)

/* True if a subvolume points to this snapshot node: */
LE32_BITMASK(BCH_SNAPSHOT_SUBVOL,	struct bch_snapshot, flags,  1,  2)

/* Optional/variable size superblock sections: */

struct bch_sb_field {
@@ -1702,7 +1749,9 @@ LE32_BITMASK(JSET_NO_FLUSH, struct jset, flags, 5, 6);
	x(alloc,	4)			\
	x(quotas,	5)			\
	x(stripes,	6)			\
	x(reflink,	7)
	x(reflink,	7)			\
	x(subvolumes,	8)			\
	x(snapshots,	9)

enum btree_id {
#define x(kwd, val) BTREE_ID_##kwd = val,
+15 −0
Original line number Diff line number Diff line
@@ -78,6 +78,9 @@ struct bch_ioctl_incremental {
#define BCH_IOCTL_DISK_RESIZE	_IOW(0xbc,	14,  struct bch_ioctl_disk_resize)
#define BCH_IOCTL_DISK_RESIZE_JOURNAL _IOW(0xbc,15,  struct bch_ioctl_disk_resize_journal)

#define BCH_IOCTL_SUBVOLUME_CREATE _IOW(0xbc,	16,  struct bch_ioctl_subvolume)
#define BCH_IOCTL_SUBVOLUME_DESTROY _IOW(0xbc,	17,  struct bch_ioctl_subvolume)

/* ioctl below act on a particular file, not the filesystem as a whole: */

#define BCHFS_IOC_REINHERIT_ATTRS	_IOR(0xbc, 64, const char __user *)
@@ -349,4 +352,16 @@ struct bch_ioctl_disk_resize_journal {
	__u64			nbuckets;
};

struct bch_ioctl_subvolume {
	__u32			flags;
	__u32			dirfd;
	__u16			mode;
	__u16			pad[3];
	__u64			dst_ptr;
	__u64			src_ptr;
};

#define BCH_SUBVOL_SNAPSHOT_CREATE	(1U << 0)
#define BCH_SUBVOL_SNAPSHOT_RO		(1U << 1)

#endif /* _BCACHEFS_IOCTL_H */
+5 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "inode.h"
#include "quota.h"
#include "reflink.h"
#include "subvolume.h"
#include "xattr.h"

const char * const bch2_bkey_types[] = {
@@ -126,6 +127,10 @@ static unsigned bch2_key_types_allowed[] = {
	[BKEY_TYPE_reflink] =
		(1U << KEY_TYPE_reflink_v)|
		(1U << KEY_TYPE_indirect_inline_data),
	[BKEY_TYPE_subvolumes] =
		(1U << KEY_TYPE_subvolume),
	[BKEY_TYPE_snapshots] =
		(1U << KEY_TYPE_snapshot),
	[BKEY_TYPE_btree] =
		(1U << KEY_TYPE_btree_ptr)|
		(1U << KEY_TYPE_btree_ptr_v2),
Loading