X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fbcachefs_format.h;h=4d142b2e3bf6691dc136b10d22ed1f61f7b47f51;hb=17d1c4f4fe29453fbb4087eb5de8aa6f9e6605c7;hp=bfcb75a361cb4c1edf231ca0fce8ae235dad2984;hpb=188b6d0c8ef1c02462a744b176557c27220112c9;p=bcachefs-tools-debian diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h index bfcb75a..4d142b2 100644 --- a/libbcachefs/bcachefs_format.h +++ b/libbcachefs/bcachefs_format.h @@ -147,7 +147,7 @@ struct bpos { #else #error edit for your odd byteorder. #endif -} __attribute__((packed, aligned(4))); +} __packed __aligned(4); #define KEY_INODE_MAX ((__u64)~0ULL) #define KEY_OFFSET_MAX ((__u64)~0ULL) @@ -181,7 +181,7 @@ struct bversion { __u32 hi; __u64 lo; #endif -} __attribute__((packed, aligned(4))); +} __packed __aligned(4); struct bkey { /* Size of combined key and value, in u64s */ @@ -214,7 +214,7 @@ struct bkey { __u8 pad[1]; #endif -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bkey_packed { __u64 _data[0]; @@ -248,7 +248,12 @@ struct bkey_packed { * to the same size as struct bkey should hopefully be safest. */ __u8 pad[sizeof(struct bkey) - 3]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); + +typedef struct { + __le64 lo; + __le64 hi; +} bch_le128; #define BKEY_U64s (sizeof(struct bkey) / sizeof(__u64)) #define BKEY_U64s_MAX U8_MAX @@ -290,16 +295,8 @@ enum bch_bkey_fields { struct bkey_i { __u64 _data[0]; - union { - struct { - /* Size of combined key and value, in u64s */ - __u8 u64s; - }; - struct { - struct bkey k; - struct bch_val v; - }; - }; + struct bkey k; + struct bch_val v; }; #define KEY(_inode, _offset, _size) \ @@ -318,7 +315,7 @@ static inline void bkey_init(struct bkey *k) #define bkey_bytes(_k) ((_k)->u64s * sizeof(__u64)) #define __BKEY_PADDED(key, pad) \ - struct { struct bkey_i key; __u64 key ## _pad[pad]; } + struct bkey_i key; __u64 key ## _pad[pad] /* * - DELETED keys are used internally to mark keys that should be ignored but @@ -367,7 +364,9 @@ static inline void bkey_init(struct bkey *k) x(lru, 26) \ x(alloc_v4, 27) \ x(backpointer, 28) \ - x(inode_v3, 29) + x(inode_v3, 29) \ + x(bucket_gens, 30) \ + x(snapshot_tree, 31) enum bch_bkey_type { #define x(name, nr) KEY_TYPE_##name = nr, @@ -478,7 +477,7 @@ struct bch_set { struct bch_csum { __le64 lo; __le64 hi; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define BCH_EXTENT_ENTRY_TYPES() \ x(ptr, 0) \ @@ -515,7 +514,7 @@ struct bch_extent_crc32 { _compressed_size:7, type:2; #endif -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define CRC32_SIZE_MAX (1U << 7) #define CRC32_NONCE_MAX 0 @@ -541,7 +540,7 @@ struct bch_extent_crc64 { type:3; #endif __u64 csum_lo; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define CRC64_SIZE_MAX (1U << 9) #define CRC64_NONCE_MAX ((1U << 10) - 1) @@ -565,7 +564,7 @@ struct bch_extent_crc128 { type:4; #endif struct bch_csum csum; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define CRC128_SIZE_MAX (1U << 13) #define CRC128_NONCE_MAX ((1U << 13) - 1) @@ -578,7 +577,7 @@ struct bch_extent_ptr { __u64 type:1, cached:1, unused:1, - reservation:1, + unwritten:1, offset:44, /* 8 petabytes */ dev:8, gen:8; @@ -586,12 +585,12 @@ struct bch_extent_ptr { __u64 gen:8, dev:8, offset:44, - reservation:1, + unwritten:1, unused:1, cached:1, type:1; #endif -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_extent_stripe_ptr { #if defined(__LITTLE_ENDIAN_BITFIELD) @@ -643,7 +642,7 @@ struct bch_btree_ptr { __u64 _data[0]; struct bch_extent_ptr start[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_btree_ptr_v2 { struct bch_val v; @@ -655,7 +654,7 @@ struct bch_btree_ptr_v2 { struct bpos min_key; __u64 _data[0]; struct bch_extent_ptr start[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE16_BITMASK(BTREE_PTR_RANGE_UPDATED, struct bch_btree_ptr_v2, flags, 0, 1); @@ -664,7 +663,7 @@ struct bch_extent { __u64 _data[0]; union bch_extent_entry start[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_reservation { struct bch_val v; @@ -672,7 +671,7 @@ struct bch_reservation { __le32 generation; __u8 nr_replicas; __u8 pad[3]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* Maximum size (in u64s) a single pointer could be: */ #define BKEY_EXTENT_PTR_U64s_MAX\ @@ -706,7 +705,7 @@ struct bch_inode { __le32 bi_flags; __le16 bi_mode; __u8 fields[0]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_inode_v2 { struct bch_val v; @@ -716,7 +715,7 @@ struct bch_inode_v2 { __le64 bi_flags; __le16 bi_mode; __u8 fields[0]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_inode_v3 { struct bch_val v; @@ -728,7 +727,7 @@ struct bch_inode_v3 { __le64 bi_size; __le64 bi_version; __u8 fields[0]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define INODEv3_FIELDS_START_INITIAL 6 #define INODEv3_FIELDS_START_CUR (offsetof(struct bch_inode_v3, fields) / sizeof(u64)) @@ -738,7 +737,7 @@ struct bch_inode_generation { __le32 bi_generation; __le32 pad; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* * bi_subvol and bi_parent_subvol are only set for subvolume roots: @@ -794,7 +793,8 @@ struct bch_inode_generation { x(bi_dir, 64) \ x(bi_dir_offset, 64) \ x(bi_subvol, 32) \ - x(bi_parent_subvol, 32) + x(bi_parent_subvol, 32) \ + x(bi_nocow, 8) /* subset of BCH_INODE_FIELDS */ #define BCH_INODE_OPTS() \ @@ -806,7 +806,8 @@ struct bch_inode_generation { x(promote_target, 16) \ x(foreground_target, 16) \ x(background_target, 16) \ - x(erasure_code, 16) + x(erasure_code, 16) \ + x(nocow, 8) enum inode_opt_id { #define x(name, ...) \ @@ -891,7 +892,7 @@ struct bch_dirent { __u8 d_type; __u8 d_name[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define DT_SUBVOL 16 #define BCH_DT_MAX 17 @@ -914,7 +915,7 @@ struct bch_xattr { __u8 x_name_len; __le16 x_val_len; __u8 x_name[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* Bucket/allocation information: */ @@ -923,7 +924,7 @@ struct bch_alloc { __u8 fields; __u8 gen; __u8 data[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define BCH_ALLOC_FIELDS_V1() \ x(read_time, 16) \ @@ -948,7 +949,7 @@ struct bch_alloc_v2 { __u8 oldest_gen; __u8 data_type; __u8 data[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define BCH_ALLOC_FIELDS_V2() \ x(read_time, 64) \ @@ -967,7 +968,7 @@ struct bch_alloc_v3 { __u8 oldest_gen; __u8 data_type; __u8 data[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE32_BITMASK(BCH_ALLOC_V3_NEED_DISCARD,struct bch_alloc_v3, flags, 0, 1) LE32_BITMASK(BCH_ALLOC_V3_NEED_INC_GEN,struct bch_alloc_v3, flags, 1, 2) @@ -985,7 +986,8 @@ struct bch_alloc_v4 { __u64 io_time[2]; __u32 stripe; __u32 nr_external_backpointers; -} __attribute__((packed, aligned(8))); + __u64 fragmentation_lru; +} __packed __aligned(8); #define BCH_ALLOC_V4_U64s_V0 6 #define BCH_ALLOC_V4_U64s (sizeof(struct bch_alloc_v4) / sizeof(u64)) @@ -1005,7 +1007,16 @@ struct bch_backpointer { __u64 bucket_offset:40; __u32 bucket_len; struct bpos pos; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); + +#define KEY_TYPE_BUCKET_GENS_BITS 8 +#define KEY_TYPE_BUCKET_GENS_NR (1U << KEY_TYPE_BUCKET_GENS_BITS) +#define KEY_TYPE_BUCKET_GENS_MASK (KEY_TYPE_BUCKET_GENS_NR - 1) + +struct bch_bucket_gens { + struct bch_val v; + u8 gens[KEY_TYPE_BUCKET_GENS_NR]; +} __packed __aligned(8); /* Quotas: */ @@ -1030,7 +1041,7 @@ struct bch_quota_counter { struct bch_quota { struct bch_val v; struct bch_quota_counter c[Q_COUNTERS]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* Erasure coding */ @@ -1046,7 +1057,7 @@ struct bch_stripe { __u8 pad; struct bch_extent_ptr ptrs[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* Reflink: */ @@ -1063,14 +1074,14 @@ struct bch_reflink_p { */ __le32 front_pad; __le32 back_pad; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_reflink_v { struct bch_val v; __le64 refcount; union bch_extent_entry start[0]; __u64 _data[0]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_indirect_inline_data { struct bch_val v; @@ -1096,6 +1107,9 @@ struct bch_subvolume { __le32 flags; __le32 snapshot; __le64 inode; + __le32 parent; + __le32 pad; + bch_le128 otime; }; LE32_BITMASK(BCH_SUBVOLUME_RO, struct bch_subvolume, flags, 0, 1) @@ -1114,7 +1128,7 @@ struct bch_snapshot { __le32 parent; __le32 children[2]; __le32 subvol; - __le32 pad; + __le32 tree; }; LE32_BITMASK(BCH_SNAPSHOT_DELETED, struct bch_snapshot, flags, 0, 1) @@ -1122,12 +1136,25 @@ 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) +/* + * Snapshot trees: + * + * The snapshot_trees btree gives us persistent indentifier for each tree of + * bch_snapshot nodes, and allow us to record and easily find the root/master + * subvolume that other snapshots were created from: + */ +struct bch_snapshot_tree { + struct bch_val v; + __le32 master_subvol; + __le32 root_snapshot; +}; + /* LRU btree: */ struct bch_lru { struct bch_val v; __le64 idx; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define LRU_ID_STRIPES (1U << 16) @@ -1326,27 +1353,27 @@ struct bch_replicas_entry_v0 { __u8 data_type; __u8 nr_devs; __u8 devs[]; -} __attribute__((packed)); +} __packed; struct bch_sb_field_replicas_v0 { struct bch_sb_field field; struct bch_replicas_entry_v0 entries[]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); struct bch_replicas_entry { __u8 data_type; __u8 nr_devs; __u8 nr_required; __u8 devs[]; -} __attribute__((packed)); +} __packed; #define replicas_entry_bytes(_i) \ (offsetof(typeof(*(_i)), devs) + (_i)->nr_devs) struct bch_sb_field_replicas { struct bch_sb_field field; - struct bch_replicas_entry entries[0]; -} __attribute__((packed, aligned(8))); + struct bch_replicas_entry entries[]; +} __packed __aligned(8); /* BCH_SB_FIELD_quota: */ @@ -1363,7 +1390,7 @@ struct bch_sb_quota_type { struct bch_sb_field_quota { struct bch_sb_field field; struct bch_sb_quota_type q[QTYP_NR]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* BCH_SB_FIELD_disk_groups: */ @@ -1372,7 +1399,7 @@ struct bch_sb_field_quota { struct bch_disk_group { __u8 label[BCH_SB_LABEL_SIZE]; __le64 flags[2]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE64_BITMASK(BCH_GROUP_DELETED, struct bch_disk_group, flags[0], 0, 1) LE64_BITMASK(BCH_GROUP_DATA_ALLOWED, struct bch_disk_group, flags[0], 1, 6) @@ -1381,7 +1408,7 @@ LE64_BITMASK(BCH_GROUP_PARENT, struct bch_disk_group, flags[0], 6, 24) struct bch_sb_field_disk_groups { struct bch_sb_field field; struct bch_disk_group entries[0]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* BCH_SB_FIELD_counters */ @@ -1424,7 +1451,7 @@ struct bch_sb_field_disk_groups { x(move_extent_read, 35) \ x(move_extent_write, 36) \ x(move_extent_finish, 37) \ - x(move_extent_race, 38) \ + x(move_extent_fail, 38) \ x(move_extent_alloc_mem_fail, 39) \ x(copygc, 40) \ x(copygc_wait, 41) \ @@ -1460,7 +1487,9 @@ struct bch_sb_field_disk_groups { x(trans_traverse_all, 71) \ x(transaction_commit, 72) \ x(write_super, 73) \ - x(trans_restart_would_deadlock_recursion_limit, 74) + x(trans_restart_would_deadlock_recursion_limit, 74) \ + x(trans_restart_write_buffer_flush, 75) \ + x(trans_restart_split_race, 76) enum bch_persistent_counters { #define x(t, n, ...) BCH_COUNTER_##t, @@ -1543,7 +1572,13 @@ struct bch_sb_field_journal_seq_blacklist { x(alloc_v4, 20) \ x(new_data_types, 21) \ x(backpointers, 22) \ - x(inode_v3, 23) + x(inode_v3, 23) \ + x(unwritten_extents, 24) \ + x(bucket_gens, 25) \ + x(lru_v2, 26) \ + x(fragmentation_lru, 27) \ + x(no_bps_in_alloc_keys, 28) \ + x(snapshot_trees, 29) enum bcachefs_metadata_version { bcachefs_metadata_version_min = 9, @@ -1553,6 +1588,8 @@ enum bcachefs_metadata_version { bcachefs_metadata_version_max }; +static const unsigned bcachefs_metadata_required_upgrade_below = bcachefs_metadata_version_snapshot_trees; + #define bcachefs_metadata_version_current (bcachefs_metadata_version_max - 1) #define BCH_SB_SECTOR 8 @@ -1565,7 +1602,7 @@ struct bch_sb_layout { __u8 nr_superblocks; __u8 pad[5]; __le64 sb_offset[61]; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #define BCH_SB_LAYOUT_SECTOR 7 @@ -1575,7 +1612,7 @@ struct bch_sb_layout { * @version_min - Oldest metadata version this filesystem contains; so we can * safely drop compatibility code and refuse to mount filesystems * we'd need it for - * @magic - identifies as a bcachefs superblock (BCACHE_MAGIC) + * @magic - identifies as a bcachefs superblock (BCHFS_MAGIC) * @seq - incremented each time superblock is written * @uuid - used for generating various magic numbers and identifying * member devices, never changes @@ -1616,7 +1653,7 @@ struct bch_sb { struct bch_sb_field start[0]; __le64 _data[0]; }; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); /* * Flags: @@ -1690,8 +1727,9 @@ LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63); LE64_BITMASK(BCH_SB_JOURNAL_RECLAIM_DELAY,struct bch_sb, flags[4], 0, 32); -/* Obsolete, always enabled: */ LE64_BITMASK(BCH_SB_JOURNAL_TRANSACTION_NAMES,struct bch_sb, flags[4], 32, 33); +LE64_BITMASK(BCH_SB_NOCOW, struct bch_sb, flags[4], 33, 34); +LE64_BITMASK(BCH_SB_WRITE_BUFFER_SIZE, struct bch_sb, flags[4], 34, 54); /* * Features: @@ -1890,6 +1928,9 @@ enum bch_compression_opts { #define BCACHE_MAGIC \ UUID_LE(0xf67385c6, 0x1a4e, 0xca45, \ 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81) +#define BCHFS_MAGIC \ + UUID_LE(0xf67385c6, 0xce66, 0xa990, \ + 0xd9, 0x6a, 0x60, 0xcf, 0x80, 0x3d, 0xf7, 0xef) #define BCACHEFS_STATFS_MAGIC 0xca451a4e @@ -1899,6 +1940,7 @@ enum bch_compression_opts { static inline __le64 __bch2_sb_magic(struct bch_sb *sb) { __le64 ret; + memcpy(&ret, &sb->uuid, sizeof(ret)); return ret; } @@ -1973,26 +2015,26 @@ enum { struct jset_entry_usage { struct jset_entry entry; __le64 v; -} __attribute__((packed)); +} __packed; struct jset_entry_data_usage { struct jset_entry entry; __le64 v; struct bch_replicas_entry r; -} __attribute__((packed)); +} __packed; struct jset_entry_clock { struct jset_entry entry; __u8 rw; __u8 pad[7]; __le64 time; -} __attribute__((packed)); +} __packed; struct jset_entry_dev_usage_type { __le64 buckets; __le64 sectors; __le64 fragmented; -} __attribute__((packed)); +} __packed; struct jset_entry_dev_usage { struct jset_entry entry; @@ -2003,7 +2045,7 @@ struct jset_entry_dev_usage { __le64 _buckets_unavailable; /* No longer used */ struct jset_entry_dev_usage_type d[]; -} __attribute__((packed)); +} __packed; static inline unsigned jset_entry_dev_usage_nr_types(struct jset_entry_dev_usage *u) { @@ -2014,7 +2056,7 @@ static inline unsigned jset_entry_dev_usage_nr_types(struct jset_entry_dev_usage struct jset_entry_log { struct jset_entry entry; u8 d[]; -} __attribute__((packed)); +} __packed; /* * On disk format for a journal entry: @@ -2049,7 +2091,7 @@ struct jset { struct jset_entry start[0]; __u64 _data[0]; }; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE32_BITMASK(JSET_CSUM_TYPE, struct jset, flags, 0, 4); LE32_BITMASK(JSET_BIG_ENDIAN, struct jset, flags, 4, 5); @@ -2060,20 +2102,22 @@ LE32_BITMASK(JSET_NO_FLUSH, struct jset, flags, 5, 6); /* Btree: */ #define BCH_BTREE_IDS() \ - x(extents, 0) \ - x(inodes, 1) \ - x(dirents, 2) \ - x(xattrs, 3) \ - x(alloc, 4) \ - x(quotas, 5) \ - x(stripes, 6) \ - x(reflink, 7) \ - x(subvolumes, 8) \ - x(snapshots, 9) \ - x(lru, 10) \ - x(freespace, 11) \ - x(need_discard, 12) \ - x(backpointers, 13) + x(extents, 0) \ + x(inodes, 1) \ + x(dirents, 2) \ + x(xattrs, 3) \ + x(alloc, 4) \ + x(quotas, 5) \ + x(stripes, 6) \ + x(reflink, 7) \ + x(subvolumes, 8) \ + x(snapshots, 9) \ + x(lru, 10) \ + x(freespace, 11) \ + x(need_discard, 12) \ + x(backpointers, 13) \ + x(bucket_gens, 14) \ + x(snapshot_trees, 15) enum btree_id { #define x(kwd, val) BTREE_ID_##kwd = val, @@ -2112,7 +2156,7 @@ struct bset { struct bkey_packed start[0]; __u64 _data[0]; }; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE32_BITMASK(BSET_CSUM_TYPE, struct bset, flags, 0, 4); @@ -2145,7 +2189,7 @@ struct btree_node { }; }; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); LE64_BITMASK(BTREE_NODE_ID, struct btree_node, flags, 0, 4); LE64_BITMASK(BTREE_NODE_LEVEL, struct btree_node, flags, 4, 8); @@ -2166,6 +2210,6 @@ struct btree_node_entry { }; }; -} __attribute__((packed, aligned(8))); +} __packed __aligned(8); #endif /* _BCACHEFS_FORMAT_H */