X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ctree.h;h=c76849d8deb79336ce225b8e3aa66e10e7ee5754;hb=82a1442e9cd025436be8ae65e684fd6b2701efbb;hp=b3c22bb9b4234a5278507380523a02b0a644da34;hpb=260675657767bf6cc90cff762efcf9091674ccaf;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/ctree.h b/ctree.h index b3c22bb..c76849d 100644 --- a/ctree.h +++ b/ctree.h @@ -16,8 +16,10 @@ * Boston, MA 021110-1307, USA. */ -#ifndef __BTRFS__ -#define __BTRFS__ +#ifndef __BTRFS_CTREE_H__ +#define __BTRFS_CTREE_H__ + +#include #if BTRFS_FLAT_INCLUDES #include "list.h" @@ -26,6 +28,7 @@ #include "extent-cache.h" #include "extent_io.h" #include "ioctl.h" +#include "sizes.h" #else #include #include @@ -33,6 +36,7 @@ #include #include #include +#include #endif /* BTRFS_FLAT_INCLUDES */ struct btrfs_root; @@ -40,6 +44,12 @@ struct btrfs_trans_handle; struct btrfs_free_space_ctl; #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ +/* + * Fake signature for an unfinalized filesystem, structures might be partially + * created or missing. + */ +#define BTRFS_MAGIC_PARTIAL 0x4D5F536652484221ULL /* ascii !BHRfS_M, no null */ + #define BTRFS_MAX_MIRRORS 3 #define BTRFS_MAX_LEVEL 8 @@ -76,6 +86,12 @@ struct btrfs_free_space_ctl; /* for storing items that use the BTRFS_UUID_KEY* */ #define BTRFS_UUID_TREE_OBJECTID 9ULL +/* tracks free space in block groups. */ +#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL + +/* device stats in the device tree */ +#define BTRFS_DEV_STATS_OBJECTID 0ULL + /* for storing balance parameters in the root tree */ #define BTRFS_BALANCE_OBJECTID -4ULL @@ -124,6 +140,8 @@ struct btrfs_free_space_ctl; */ #define BTRFS_DEV_ITEMS_OBJECTID 1ULL +#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2ULL + /* * the max metadata block size. This limit is somewhat artificial, * but the memmove costs go through the roof for larger blocks. @@ -149,7 +167,7 @@ struct btrfs_free_space_ctl; /* csum types */ #define BTRFS_CSUM_TYPE_CRC32 0 -static int btrfs_csum_sizes[] = { 4, 0 }; +static int btrfs_csum_sizes[] = { 4 }; /* four bytes for CRC32 */ #define BTRFS_CRC32_SIZE 4 @@ -170,7 +188,7 @@ static int btrfs_csum_sizes[] = { 4, 0 }; /* * the key defines the order in the tree, and so it also defines (optimal) - * block layout. objectid corresonds to the inode number. The flags + * block layout. objectid corresponds to the inode number. The flags * tells us things about the object, and is a kind of stream selector. * so for a given inode, keys with flags of 1 might refer to the inode * data, flags of 2 may point to file data in the btree and flags == 3 @@ -226,7 +244,7 @@ struct btrfs_dev_item { /* * starting byte of this partition on the device, - * to allowr for stripe alignment in the future + * to allow for stripe alignment in the future */ __le64 start_offset; @@ -309,6 +327,8 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes) #define BTRFS_HEADER_FLAG_RELOC (1ULL << 1) #define BTRFS_SUPER_FLAG_SEEDING (1ULL << 32) #define BTRFS_SUPER_FLAG_METADUMP (1ULL << 33) +#define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34) +#define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35) #define BTRFS_BACKREF_REV_MAX 256 #define BTRFS_BACKREF_REV_SHIFT 56 @@ -336,18 +356,9 @@ struct btrfs_header { u8 level; } __attribute__ ((__packed__)); -#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \ - sizeof(struct btrfs_header)) / \ - sizeof(struct btrfs_key_ptr)) #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) -#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize)) -#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ - sizeof(struct btrfs_item) - \ - sizeof(struct btrfs_file_extent_item)) -#define BTRFS_MAX_XATTR_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ - sizeof(struct btrfs_item) -\ - sizeof(struct btrfs_dir_item)) - +#define BTRFS_LEAF_DATA_SIZE(fs_info) \ + (__BTRFS_LEAF_DATA_SIZE(fs_info->nodesize)) /* * this is a very generous portion of the super block, giving us @@ -423,7 +434,8 @@ struct btrfs_super_block { __le64 num_devices; __le32 sectorsize; __le32 nodesize; - __le32 leafsize; + /* Unused and must be equal to nodesize */ + __le32 __unused_leafsize; __le32 stripesize; __le32 sys_chunk_array_size; __le64 chunk_root_generation; @@ -451,18 +463,21 @@ struct btrfs_super_block { * Compat flags that we support. If any incompat flags are set other than the * ones specified below then we will fail to mount */ +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) +/* + * Older kernels on big-endian systems produced broken free space tree bitmaps, + * and btrfs-progs also used to corrupt the free space tree. If this bit is + * clear, then the free space tree cannot be trusted. btrfs-progs can also + * intentionally clear this bit to ask the kernel to rebuild the free space + * tree. + */ +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1) + #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) #define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3) - -/* - * some patches floated around with a second compression method - * lets save that incompat here for when they do get in - * Note we don't actually support it, we're just reserving the - * number - */ -#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4) +#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD (1ULL << 4) /* * older kernels tried to do bigger metadata blocks, but the @@ -474,13 +489,20 @@ struct btrfs_super_block { #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8) #define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9) - #define BTRFS_FEATURE_COMPAT_SUPP 0ULL + +/* + * The FREE_SPACE_TREE and FREE_SPACE_TREE_VALID compat_ro bits must not be + * added here until read-write support for the free space tree is implemented in + * btrfs-progs. + */ #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL + #define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \ BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \ + BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD | \ BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \ BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \ BTRFS_FEATURE_INCOMPAT_RAID56 | \ @@ -537,18 +559,20 @@ struct btrfs_node { struct btrfs_path { struct extent_buffer *nodes[BTRFS_MAX_LEVEL]; int slots[BTRFS_MAX_LEVEL]; - /* if there is real range locking, this locks field will change */ +#if 0 + /* The kernel locking sheme is not done in userspace. */ int locks[BTRFS_MAX_LEVEL]; - int reada; +#endif + signed char reada; /* keep some upper locks as we walk down */ - int lowest_level; + u8 lowest_level; /* * set by btrfs_split_item, tells search_slot to keep all locks * and to force calls to keep space in the nodes */ - unsigned int search_for_split:1; - unsigned int skip_check_block:1; + u8 search_for_split; + u8 skip_check_block; }; /* @@ -566,8 +590,10 @@ struct btrfs_extent_item_v0 { __le32 refs; } __attribute__ ((__packed__)); -#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r) >> 4) - \ +#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) \ + ((BTRFS_LEAF_DATA_SIZE(r->fs_info) >> 4) - \ sizeof(struct btrfs_item)) +#define BTRFS_MAX_EXTENT_SIZE SZ_128M #define BTRFS_EXTENT_FLAG_DATA (1ULL << 0) #define BTRFS_EXTENT_FLAG_TREE_BLOCK (1ULL << 1) @@ -639,8 +665,9 @@ typedef enum { BTRFS_COMPRESS_NONE = 0, BTRFS_COMPRESS_ZLIB = 1, BTRFS_COMPRESS_LZO = 2, - BTRFS_COMPRESS_TYPES = 2, - BTRFS_COMPRESS_LAST = 3, + BTRFS_COMPRESS_ZSTD = 3, + BTRFS_COMPRESS_TYPES = 3, + BTRFS_COMPRESS_LAST = 4, } btrfs_compression_type; /* we don't understand any encryption methods right now */ @@ -736,7 +763,7 @@ struct btrfs_root_item { /* * This generation number is used to test if the new fields are valid - * and up to date while reading the root item. Everytime the root item + * and up to date while reading the root item. Every time the root item * is written out, the "generation" field is copied into this field. If * anyone ever mounted the fs with an older kernel, we will have * mismatching generation values here and thus must invalidate the @@ -769,6 +796,84 @@ struct btrfs_root_ref { __le16 name_len; } __attribute__ ((__packed__)); +struct btrfs_disk_balance_args { + /* + * profiles to operate on, single is denoted by + * BTRFS_AVAIL_ALLOC_BIT_SINGLE + */ + __le64 profiles; + + /* + * usage filter + * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N' + * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max + */ + union { + __le64 usage; + struct { + __le32 usage_min; + __le32 usage_max; + }; + }; + + /* devid filter */ + __le64 devid; + + /* devid subset filter [pstart..pend) */ + __le64 pstart; + __le64 pend; + + /* btrfs virtual address space subset filter [vstart..vend) */ + __le64 vstart; + __le64 vend; + + /* + * profile to convert to, single is denoted by + * BTRFS_AVAIL_ALLOC_BIT_SINGLE + */ + __le64 target; + + /* BTRFS_BALANCE_ARGS_* */ + __le64 flags; + + /* + * BTRFS_BALANCE_ARGS_LIMIT with value 'limit' + * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum + * and maximum + */ + union { + __le64 limit; + struct { + __le32 limit_min; + __le32 limit_max; + }; + }; + + /* + * Process chunks that cross stripes_min..stripes_max devices, + * BTRFS_BALANCE_ARGS_STRIPES_RANGE + */ + __le32 stripes_min; + __le32 stripes_max; + + __le64 unused[6]; +} __attribute__ ((__packed__)); + +/* + * store balance parameters to disk so that balance can be properly + * resumed after crash or unmount + */ +struct btrfs_balance_item { + /* BTRFS_BALANCE_* */ + __le64 flags; + + struct btrfs_disk_balance_args data; + struct btrfs_disk_balance_args meta; + struct btrfs_disk_balance_args sys; + + __le64 unused[4]; +} __attribute__ ((__packed__)); + #define BTRFS_FILE_EXTENT_INLINE 0 #define BTRFS_FILE_EXTENT_REG 1 #define BTRFS_FILE_EXTENT_PREALLOC 2 @@ -822,6 +927,14 @@ struct btrfs_file_extent_item { } __attribute__ ((__packed__)); +struct btrfs_dev_stats_item { + /* + * grow this item struct at the end for future enhancements and keep + * the existing values unchanged + */ + __le64 values[BTRFS_DEV_STAT_VALUES_MAX]; +} __attribute__ ((__packed__)); + struct btrfs_csum_item { u8 csum; } __attribute__ ((__packed__)); @@ -832,7 +945,7 @@ struct btrfs_csum_item { * - the first 64k blank is useful for some boot loader/manager * - the first 1M could be scratched by buggy partitioner or somesuch */ -#define BTRFS_BLOCK_RESERVED_1M_FOR_SUPER ((u64)1024 * 1024) +#define BTRFS_BLOCK_RESERVED_1M_FOR_SUPER ((u64)SZ_1M) /* tag for the radix tree of block groups in ram */ #define BTRFS_BLOCK_GROUP_DATA (1ULL << 0) @@ -845,7 +958,17 @@ struct btrfs_csum_item { #define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7) #define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8) #define BTRFS_BLOCK_GROUP_RESERVED BTRFS_AVAIL_ALLOC_BIT_SINGLE -#define BTRFS_NR_RAID_TYPES 7 + +enum btrfs_raid_types { + BTRFS_RAID_RAID10, + BTRFS_RAID_RAID1, + BTRFS_RAID_DUP, + BTRFS_RAID_RAID0, + BTRFS_RAID_SINGLE, + BTRFS_RAID_RAID5, + BTRFS_RAID_RAID6, + BTRFS_NR_RAID_TYPES +}; #define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | \ BTRFS_BLOCK_GROUP_SYSTEM | \ @@ -867,17 +990,27 @@ struct btrfs_csum_item { */ #define BTRFS_SPACE_INFO_GLOBAL_RSV (1ULL << 49) -#define BTRFS_QGROUP_STATUS_OFF 0 -#define BTRFS_QGROUP_STATUS_ON 1 -#define BTRFS_QGROUP_STATUS_SCANNING 2 +#define BTRFS_QGROUP_LEVEL_SHIFT 48 -#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1 << 0) +static inline u64 btrfs_qgroup_level(u64 qgroupid) +{ + return qgroupid >> BTRFS_QGROUP_LEVEL_SHIFT; +} + +static inline u64 btrfs_qgroup_subvid(u64 qgroupid) +{ + return qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1); +} + +#define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1) +#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1ULL << 2) struct btrfs_qgroup_status_item { __le64 version; __le64 generation; __le64 flags; - __le64 scan; /* progress during scanning */ + __le64 rescan; /* progress during scanning */ } __attribute__ ((__packed__)); struct btrfs_block_group_item { @@ -886,6 +1019,13 @@ struct btrfs_block_group_item { __le64 flags; } __attribute__ ((__packed__)); +struct btrfs_free_space_info { + __le32 extent_count; + __le32 flags; +} __attribute__ ((__packed__)); + +#define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0) + struct btrfs_qgroup_info_item { __le64 generation; __le64 referenced; @@ -925,24 +1065,20 @@ struct btrfs_block_group_cache { struct btrfs_block_group_item item; struct btrfs_space_info *space_info; struct btrfs_free_space_ctl *free_space_ctl; + u64 bytes_super; u64 pinned; u64 flags; int cached; int ro; }; -struct btrfs_extent_ops { - int (*alloc_extent)(struct btrfs_root *root, u64 num_bytes, - u64 hint_byte, struct btrfs_key *ins); - int (*free_extent)(struct btrfs_root *root, u64 bytenr, - u64 num_bytes); -}; - struct btrfs_device; struct btrfs_fs_devices; struct btrfs_fs_info { u8 fsid[BTRFS_FSID_SIZE]; + u8 *new_fsid; u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; + u8 *new_chunk_tree_uuid; struct btrfs_root *fs_root; struct btrfs_root *extent_root; struct btrfs_root *tree_root; @@ -950,6 +1086,7 @@ struct btrfs_fs_info { struct btrfs_root *dev_root; struct btrfs_root *csum_root; struct btrfs_root *quota_root; + struct btrfs_root *free_space_root; struct rb_root fs_root_tree; @@ -962,6 +1099,7 @@ struct btrfs_fs_info { struct extent_io_tree pinned_extents; struct extent_io_tree pending_del; struct extent_io_tree extent_ins; + struct extent_io_tree *excluded_extents; /* logical->physical extent mapping */ struct btrfs_mapping_tree mapping_tree; @@ -984,18 +1122,25 @@ struct btrfs_fs_info { u64 super_bytenr; u64 total_pinned; - struct btrfs_extent_ops *extent_ops; struct list_head dirty_cowonly_roots; struct list_head recow_ebs; struct btrfs_fs_devices *fs_devices; struct list_head space_info; - int system_allocs; + unsigned int system_allocs:1; unsigned int readonly:1; unsigned int on_restoring:1; unsigned int is_chunk_recover:1; unsigned int quota_enabled:1; + unsigned int suppress_check_block_errors:1; + unsigned int ignore_fsid_mismatch:1; + unsigned int ignore_chunk_tree_error:1; + unsigned int avoid_meta_chunk_alloc:1; + unsigned int avoid_sys_chunk_alloc:1; + unsigned int finalize_on_close:1; + + int transaction_aborted; int (*free_extent_hook)(struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -1004,6 +1149,11 @@ struct btrfs_fs_info { int refs_to_drop); struct cache_tree *fsck_extent_cache; struct cache_tree *corrupt_blocks; + + /* Cached block sizes */ + u32 nodesize; + u32 sectorsize; + u32 stripesize; }; /* @@ -1019,31 +1169,51 @@ struct btrfs_root { u64 objectid; u64 last_trans; - /* data allocations are done in sectorsize units */ - u32 sectorsize; - - /* node allocations are done in nodesize units */ - u32 nodesize; - - /* leaf allocations are done in leafsize units */ - u32 leafsize; - - /* leaf allocations are done in leafsize units */ - u32 stripesize; - int ref_cows; int track_dirty; u32 type; - u64 highest_inode; u64 last_inode_alloc; + /* + * Record orphan data extent ref + * + * TODO: Don't restore things in btrfs_root. + * Directly record it into inode_record, which needs a lot of + * infrastructure change to allow cooperation between extent + * and fs tree scan. + */ + struct list_head orphan_data_extents; + /* the dirty list is only used by non-reference counted roots */ struct list_head dirty_list; struct rb_node rb_node; }; +static inline u32 BTRFS_MAX_ITEM_SIZE(const struct btrfs_fs_info *info) +{ + return BTRFS_LEAF_DATA_SIZE(info) - sizeof(struct btrfs_item); +} + +static inline u32 BTRFS_NODEPTRS_PER_BLOCK(const struct btrfs_fs_info *info) +{ + return BTRFS_LEAF_DATA_SIZE(info) / sizeof(struct btrfs_key_ptr); +} + +#define BTRFS_FILE_EXTENT_INLINE_DATA_START \ + (offsetof(struct btrfs_file_extent_item, disk_bytenr)) +static inline u32 BTRFS_MAX_INLINE_DATA_SIZE(const struct btrfs_fs_info *info) +{ + return BTRFS_MAX_ITEM_SIZE(info) - + BTRFS_FILE_EXTENT_INLINE_DATA_START; +} + +static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info) +{ + return BTRFS_MAX_ITEM_SIZE(info) - sizeof(struct btrfs_dir_item); +} + /* * inode items have the data typically returned from stat and store other * info about object characteristics. There is one for every file and dir in @@ -1128,6 +1298,27 @@ struct btrfs_root { */ #define BTRFS_BLOCK_GROUP_ITEM_KEY 192 +/* + * Every block group is represented in the free space tree by a free space info + * item, which stores some accounting information. It is keyed on + * (block_group_start, FREE_SPACE_INFO, block_group_length). + */ +#define BTRFS_FREE_SPACE_INFO_KEY 198 + +/* + * A free space extent tracks an extent of space that is free in a block group. + * It is keyed on (start, FREE_SPACE_EXTENT, length). + */ +#define BTRFS_FREE_SPACE_EXTENT_KEY 199 + +/* + * When a block group becomes very fragmented, we convert it to use bitmaps + * instead of extents. A free space bitmap is keyed on + * (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with + * (length / sectorsize) bits. + */ +#define BTRFS_FREE_SPACE_BITMAP_KEY 200 + #define BTRFS_DEV_EXTENT_KEY 204 #define BTRFS_DEV_ITEM_KEY 216 #define BTRFS_CHUNK_ITEM_KEY 228 @@ -1143,10 +1334,42 @@ struct btrfs_root { #define BTRFS_QGROUP_RELATION_KEY 246 /* - * Persistently stores the io stats in the device tree. - * One key for all stats, (0, BTRFS_DEV_STATS_KEY, devid). + * Obsolete name, see BTRFS_TEMPORARY_ITEM_KEY. */ -#define BTRFS_DEV_STATS_KEY 249 +#define BTRFS_BALANCE_ITEM_KEY 248 + +/* + * The key type for tree items that are stored persistently, but do not need to + * exist for extended period of time. The items can exist in any tree. + * + * [subtype, BTRFS_TEMPORARY_ITEM_KEY, data] + * + * Existing items: + * + * - balance status item + * (BTRFS_BALANCE_OBJECTID, BTRFS_TEMPORARY_ITEM_KEY, 0) + */ +#define BTRFS_TEMPORARY_ITEM_KEY 248 + +/* + * Obsolete name, see BTRFS_PERSISTENT_ITEM_KEY + */ +#define BTRFS_DEV_STATS_KEY 249 + +/* + * The key type for tree items that are stored persistently and usually exist + * for a long period, eg. filesystem lifetime. The item kinds can be status + * information, stats or preference values. The item can exist in any tree. + * + * [subtype, BTRFS_PERSISTENT_ITEM_KEY, data] + * + * Existing items: + * + * - device statistics, store IO stats in the device tree, one key for all + * stats + * (BTRFS_DEV_STATS_OBJECTID, BTRFS_DEV_STATS_KEY, 0) + */ +#define BTRFS_PERSISTENT_ITEM_KEY 249 /* * Persistently stores the device replace state in the device tree. @@ -1178,6 +1401,15 @@ struct btrfs_root { #define BTRFS_INODE_NODATASUM (1 << 0) #define BTRFS_INODE_NODATACOW (1 << 1) #define BTRFS_INODE_READONLY (1 << 2) +#define BTRFS_INODE_NOCOMPRESS (1 << 3) +#define BTRFS_INODE_PREALLOC (1 << 4) +#define BTRFS_INODE_SYNC (1 << 5) +#define BTRFS_INODE_IMMUTABLE (1 << 6) +#define BTRFS_INODE_APPEND (1 << 7) +#define BTRFS_INODE_NODUMP (1 << 8) +#define BTRFS_INODE_NOATIME (1 << 9) +#define BTRFS_INODE_DIRSYNC (1 << 10) +#define BTRFS_INODE_COMPRESS (1 << 11) #define read_eb_member(eb, ptr, type, member, result) ( \ read_extent_buffer(eb, (char *)(result), \ @@ -1365,6 +1597,11 @@ BTRFS_SETGET_FUNCS(disk_block_group_flags, BTRFS_SETGET_STACK_FUNCS(block_group_flags, struct btrfs_block_group_item, flags, 64); +/* struct btrfs_free_space_info */ +BTRFS_SETGET_FUNCS(free_space_extent_count, struct btrfs_free_space_info, + extent_count, 32); +BTRFS_SETGET_FUNCS(free_space_flags, struct btrfs_free_space_info, flags, 32); + /* struct btrfs_inode_ref */ BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16); BTRFS_SETGET_STACK_FUNCS(stack_inode_ref_name_len, struct btrfs_inode_ref, name_len, 16); @@ -1394,7 +1631,9 @@ BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64); BTRFS_SETGET_STACK_FUNCS(stack_inode_generation, struct btrfs_inode_item, generation, 64); BTRFS_SETGET_STACK_FUNCS(stack_inode_sequence, - struct btrfs_inode_item, generation, 64); + struct btrfs_inode_item, sequence, 64); +BTRFS_SETGET_STACK_FUNCS(stack_inode_transid, + struct btrfs_inode_item, transid, 64); BTRFS_SETGET_STACK_FUNCS(stack_inode_size, struct btrfs_inode_item, size, 64); BTRFS_SETGET_STACK_FUNCS(stack_inode_nbytes, @@ -1462,6 +1701,9 @@ BTRFS_SETGET_FUNCS(dev_extent_chunk_offset, struct btrfs_dev_extent, chunk_offset, 64); BTRFS_SETGET_FUNCS(dev_extent_length, struct btrfs_dev_extent, length, 64); +BTRFS_SETGET_STACK_FUNCS(stack_dev_extent_length, struct btrfs_dev_extent, + length, 64); + static inline u8 *btrfs_dev_extent_chunk_tree_uuid(struct btrfs_dev_extent *dev) { unsigned long ptr = offsetof(struct btrfs_dev_extent, chunk_tree_uuid); @@ -1625,7 +1867,7 @@ static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) return btrfs_item_end(eb, btrfs_item_nr(nr)); } -static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) +static inline u32 btrfs_item_offset_nr(const struct extent_buffer *eb, int nr) { return btrfs_item_offset(eb, btrfs_item_nr(nr)); } @@ -1668,7 +1910,10 @@ BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); BTRFS_SETGET_FUNCS(dir_transid, struct btrfs_dir_item, transid, 64); +BTRFS_SETGET_STACK_FUNCS(stack_dir_data_len, struct btrfs_dir_item, data_len, 16); +BTRFS_SETGET_STACK_FUNCS(stack_dir_type, struct btrfs_dir_item, type, 8); BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, name_len, 16); +BTRFS_SETGET_STACK_FUNCS(stack_dir_transid, struct btrfs_dir_item, transid, 64); static inline void btrfs_dir_item_key(struct extent_buffer *eb, struct btrfs_dir_item *item, @@ -1753,17 +1998,6 @@ static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, btrfs_disk_key_to_cpu(key, &disk_key); } - -static inline u8 btrfs_key_type(struct btrfs_key *key) -{ - return key->type; -} - -static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val) -{ - key->type = val; -} - /* struct btrfs_header */ BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64); BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header, @@ -1823,33 +2057,12 @@ static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *e return offsetof(struct btrfs_header, chunk_tree_uuid); } -static inline u8 *btrfs_super_fsid(struct extent_buffer *eb) -{ - unsigned long ptr = offsetof(struct btrfs_super_block, fsid); - return (u8 *)ptr; -} - static inline u8 *btrfs_header_csum(struct extent_buffer *eb) { unsigned long ptr = offsetof(struct btrfs_header, csum); return (u8 *)ptr; } -static inline struct btrfs_node *btrfs_buffer_node(struct extent_buffer *eb) -{ - return NULL; -} - -static inline struct btrfs_leaf *btrfs_buffer_leaf(struct extent_buffer *eb) -{ - return NULL; -} - -static inline struct btrfs_header *btrfs_buffer_header(struct extent_buffer *eb) -{ - return NULL; -} - static inline int btrfs_is_leaf(struct extent_buffer *eb) { return (btrfs_header_level(eb) == 0); @@ -1884,6 +2097,38 @@ BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item, BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, rtransid, 64); +static inline struct btrfs_timespec* btrfs_root_ctime( + struct btrfs_root_item *root_item) +{ + unsigned long ptr = (unsigned long)root_item; + ptr += offsetof(struct btrfs_root_item, ctime); + return (struct btrfs_timespec *)ptr; +} + +static inline struct btrfs_timespec* btrfs_root_otime( + struct btrfs_root_item *root_item) +{ + unsigned long ptr = (unsigned long)root_item; + ptr += offsetof(struct btrfs_root_item, otime); + return (struct btrfs_timespec *)ptr; +} + +static inline struct btrfs_timespec* btrfs_root_stime( + struct btrfs_root_item *root_item) +{ + unsigned long ptr = (unsigned long)root_item; + ptr += offsetof(struct btrfs_root_item, stime); + return (struct btrfs_timespec *)ptr; +} + +static inline struct btrfs_timespec* btrfs_root_rtime( + struct btrfs_root_item *root_item) +{ + unsigned long ptr = (unsigned long)root_item; + ptr += offsetof(struct btrfs_root_item, rtime); + return (struct btrfs_timespec *)ptr; +} + /* struct btrfs_root_backup */ BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup, tree_root, 64); @@ -1964,8 +2209,6 @@ BTRFS_SETGET_STACK_FUNCS(super_sectorsize, struct btrfs_super_block, sectorsize, 32); BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, nodesize, 32); -BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, - leafsize, 32); BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block, stripesize, 32); BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, @@ -2053,8 +2296,17 @@ BTRFS_SETGET_FUNCS(qgroup_status_generation, struct btrfs_qgroup_status_item, generation, 64); BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64); -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, - scan, 64); +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, + rescan, 64); + +BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_version, + struct btrfs_qgroup_status_item, version, 64); +BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_generation, + struct btrfs_qgroup_status_item, generation, 64); +BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_flags, + struct btrfs_qgroup_status_item, flags, 64); +BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_rescan, + struct btrfs_qgroup_status_item, rescan, 64); /* btrfs_qgroup_info_item */ BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, @@ -2102,6 +2354,49 @@ BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_referenced, BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_exclusive, struct btrfs_qgroup_limit_item, rsv_exclusive, 64); +/* btrfs_balance_item */ +BTRFS_SETGET_FUNCS(balance_item_flags, struct btrfs_balance_item, flags, 64); + +static inline struct btrfs_disk_balance_args* btrfs_balance_item_data( + struct extent_buffer *eb, struct btrfs_balance_item *bi) +{ + unsigned long offset = (unsigned long)bi; + struct btrfs_balance_item *p; + p = (struct btrfs_balance_item *)(eb->data + offset); + return &p->data; +} + +static inline struct btrfs_disk_balance_args* btrfs_balance_item_meta( + struct extent_buffer *eb, struct btrfs_balance_item *bi) +{ + unsigned long offset = (unsigned long)bi; + struct btrfs_balance_item *p; + p = (struct btrfs_balance_item *)(eb->data + offset); + return &p->meta; +} + +static inline struct btrfs_disk_balance_args* btrfs_balance_item_sys( + struct extent_buffer *eb, struct btrfs_balance_item *bi) +{ + unsigned long offset = (unsigned long)bi; + struct btrfs_balance_item *p; + p = (struct btrfs_balance_item *)(eb->data + offset); + return &p->sys; +} + +/* + * btrfs_dev_stats_item helper, returns pointer to the raw array, do the + * endiannes conversion, @dsi is offset to eb data + */ +static inline __le64* btrfs_dev_stats_values(struct extent_buffer *eb, + struct btrfs_dev_stats_item *dsi) +{ + unsigned long offset = (unsigned long)dsi; + struct btrfs_dev_stats_item *p; + p = (struct btrfs_dev_stats_item *)(eb->data + offset); + return p->values; +} + /* * this returns the number of bytes used by the item on disk, minus the * size of any extent headers. If a file is compressed on disk, this is @@ -2115,6 +2410,32 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, return btrfs_item_size(eb, e) - offset; } +/* struct btrfs_ioctl_search_header */ +static inline u64 btrfs_search_header_transid(struct btrfs_ioctl_search_header *sh) +{ + return get_unaligned_64(&sh->transid); +} + +static inline u64 btrfs_search_header_objectid(struct btrfs_ioctl_search_header *sh) +{ + return get_unaligned_64(&sh->objectid); +} + +static inline u64 btrfs_search_header_offset(struct btrfs_ioctl_search_header *sh) +{ + return get_unaligned_64(&sh->offset); +} + +static inline u32 btrfs_search_header_type(struct btrfs_ioctl_search_header *sh) +{ + return get_unaligned_32(&sh->type); +} + +static inline u32 btrfs_search_header_len(struct btrfs_ioctl_search_header *sh) +{ + return get_unaligned_32(&sh->len); +} + /* this returns the number of file bytes represented by the inline item. * If an item is compressed, this is the uncompressed size */ @@ -2137,19 +2458,26 @@ static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, return btrfs_file_extent_ram_bytes(eb, fi); } -static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { - if (level == 0) - return root->leafsize; - return root->nodesize; -} +#define btrfs_fs_incompat(fs_info, opt) \ + __btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt) -static inline int btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag) +static inline int __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag) { struct btrfs_super_block *disk_super; disk_super = fs_info->super_copy; return !!(btrfs_super_incompat_flags(disk_super) & flag); } +#define btrfs_fs_compat_ro(fs_info, opt) \ + __btrfs_fs_compat_ro((fs_info), BTRFS_FEATURE_COMPAT_RO_##opt) + +static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag) +{ + struct btrfs_super_block *disk_super; + disk_super = fs_info->super_copy; + return !!(btrfs_super_compat_ro_flags(disk_super) & flag); +} + /* helper function to cast into the data area of the leaf. */ #define btrfs_item_ptr(leaf, slot, type) \ ((type *)(btrfs_leaf_data(leaf) + \ @@ -2164,7 +2492,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 num_bytes, u64 empty_size, u64 hint_byte, u64 search_end, - struct btrfs_key *ins, int data); + struct btrfs_key *ins, bool is_data); int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans, struct btrfs_root *root); void btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes); @@ -2183,12 +2511,6 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u32 blocksize, u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); -int btrfs_alloc_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 num_bytes, u64 parent, - u64 root_objectid, u64 ref_generation, - u64 owner, u64 empty_size, u64 hint_byte, - u64 search_end, struct btrfs_key *ins, int data); int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 offset, int metadata, u64 *refs, u64 *flags); @@ -2199,6 +2521,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int record_parent); int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int record_parent); +int btrfs_free_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + u64 parent, int last_ref); int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, @@ -2222,25 +2548,33 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info); int btrfs_read_block_groups(struct btrfs_root *root); struct btrfs_block_group_cache * btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type, - u64 chunk_objectid, u64 chunk_offset, u64 size); + u64 chunk_offset, u64 size); int btrfs_make_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytes_used, - u64 type, u64 chunk_objectid, u64 chunk_offset, - u64 size); + struct btrfs_fs_info *fs_info, u64 bytes_used, + u64 type, u64 chunk_offset, u64 size); int btrfs_make_block_groups(struct btrfs_trans_handle *trans, - struct btrfs_root *root); -int btrfs_update_block_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, u64 num, + struct btrfs_fs_info *fs_info); +int btrfs_update_block_group(struct btrfs_root *root, u64 bytenr, u64 num, int alloc, int mark_free); int btrfs_record_file_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid, struct btrfs_inode_item *inode, u64 file_pos, u64 disk_bytenr, u64 num_bytes); +int btrfs_free_block_group(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 len); +void free_excluded_extents(struct btrfs_root *root, + struct btrfs_block_group_cache *cache); +int exclude_super_stripes(struct btrfs_root *root, + struct btrfs_block_group_cache *cache); +u64 add_new_free_space(struct btrfs_block_group_cache *block_group, + struct btrfs_fs_info *info, u64 start, u64 end); +u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset); + /* ctree.c */ int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2); -int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_path *path, int level, int slot); +int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, + int level, int slot); enum btrfs_tree_block_status btrfs_check_node(struct btrfs_root *root, struct btrfs_disk_key *parent_key, struct extent_buffer *buf); @@ -2249,13 +2583,15 @@ btrfs_check_leaf(struct btrfs_root *root, struct btrfs_disk_key *parent_key, struct extent_buffer *buf); void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, int level, int slot, u64 objectid); -struct extent_buffer *read_node_slot(struct btrfs_root *root, +struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info, struct extent_buffer *parent, int slot); int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, int type); int btrfs_previous_extent_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid); +int btrfs_next_extent_item(struct btrfs_root *root, + struct btrfs_path *path, u64 max_objectid); int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, @@ -2270,11 +2606,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer **cow_ret, u64 new_root_objectid); -int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_path *path, u32 data_size); -int btrfs_truncate_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, +int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, + u32 data_size); +int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -2347,6 +2681,8 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item); +int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_key *key); int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item); @@ -2403,6 +2739,13 @@ int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, u64 inode_objectid, u64 ref_objectid, u64 index); +struct btrfs_inode_ref *btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + const char *name, int namelen, u64 ino, u64 parent_ino, + int ins_len); +int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, const char *name, int name_len, + u64 ino, u64 parent_ino, u64 *index); /* file-item.c */ int btrfs_del_csums(struct btrfs_trans_handle *trans, @@ -2414,7 +2757,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, u64 num_bytes); int btrfs_insert_inline_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid, - u64 offset, char *buffer, size_t size); + u64 offset, const char *buffer, size_t size); int btrfs_csum_file_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 alloc_end, u64 bytenr, char *data, size_t len); @@ -2434,4 +2777,37 @@ static inline int is_fstree(u64 rootid) return 1; return 0; } + +/* inode.c */ +int check_dir_conflict(struct btrfs_root *root, char *name, int namelen, + u64 dir, u64 index); +int btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, + u64 ino, u32 mode); +int btrfs_change_inode_flags(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 ino, u64 flags); +int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root, + u64 ino, u64 parent_ino, char *name, int namelen, + u8 type, u64 *index, int add_backref, int ignore_existed); +int btrfs_unlink(struct btrfs_trans_handle *trans, struct btrfs_root *root, + u64 ino, u64 parent_ino, u64 index, const char *name, + int namelen, int add_orphan); +int btrfs_add_orphan_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + u64 ino); +int btrfs_mkdir(struct btrfs_trans_handle *trans, struct btrfs_root *root, + char *name, int namelen, u64 parent_ino, u64 *ino, int mode); +struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root, const char *base, + u64 root_objectid, bool convert); + +/* file.c */ +int btrfs_get_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + u64 ino, u64 offset, u64 len, int ins_len); +int btrfs_punch_hole(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 ino, u64 offset, u64 len); +int btrfs_read_file(struct btrfs_root *root, u64 ino, u64 start, int len, + char *dest); + #endif