1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #ifndef __BTRFS_VOLUMES_H__
4 #define __BTRFS_VOLUMES_H__
5 
6 #include <fs_internal.h>
7 #include "ctree.h"
8 
9 #define BTRFS_STRIPE_LEN	SZ_64K
10 
11 struct btrfs_device {
12 	struct list_head dev_list;
13 	struct btrfs_root *dev_root;
14 	struct btrfs_fs_devices *fs_devices;
15 
16 	struct blk_desc *desc;
17 	struct disk_partition *part;
18 
19 	u64 total_devs;
20 	u64 super_bytes_used;
21 
22 	u64 generation;
23 
24 	/* the internal btrfs device id */
25 	u64 devid;
26 
27 	/* size of the device */
28 	u64 total_bytes;
29 
30 	/* bytes used */
31 	u64 bytes_used;
32 
33 	/* optimal io alignment for this device */
34 	u32 io_align;
35 
36 	/* optimal io width for this device */
37 	u32 io_width;
38 
39 	/* minimal io size for this device */
40 	u32 sector_size;
41 
42 	/* type and info about this device */
43 	u64 type;
44 
45 	/* physical drive uuid (or lvm uuid) */
46 	u8 uuid[BTRFS_UUID_SIZE];
47 };
48 
49 struct btrfs_fs_devices {
50 	u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
51 	u8 metadata_uuid[BTRFS_FSID_SIZE]; /* FS specific uuid */
52 
53 	u64 latest_devid;
54 	u64 lowest_devid;
55 	u64 latest_trans;
56 
57 	u64 total_rw_bytes;
58 
59 	struct list_head devices;
60 	struct list_head list;
61 
62 	int seeding;
63 	struct btrfs_fs_devices *seed;
64 };
65 
66 struct btrfs_bio_stripe {
67 	struct btrfs_device *dev;
68 	u64 physical;
69 };
70 
71 struct btrfs_multi_bio {
72 	int error;
73 	int num_stripes;
74 	struct btrfs_bio_stripe stripes[];
75 };
76 
77 struct map_lookup {
78 	struct cache_extent ce;
79 	u64 type;
80 	int io_align;
81 	int io_width;
82 	int stripe_len;
83 	int sector_size;
84 	int num_stripes;
85 	int sub_stripes;
86 	struct btrfs_bio_stripe stripes[];
87 };
88 
89 struct btrfs_raid_attr {
90 	int sub_stripes;	/* sub_stripes info for map */
91 	int dev_stripes;	/* stripes per dev */
92 	int devs_max;		/* max devs to use */
93 	int devs_min;		/* min devs needed */
94 	int tolerated_failures; /* max tolerated fail devs */
95 	int devs_increment;	/* ndevs has to be a multiple of this */
96 	int ncopies;		/* how many copies to data has */
97 	int nparity;		/* number of stripes worth of bytes to store
98 				 * parity information */
99 	const char raid_name[8]; /* name of the raid */
100 	u64 bg_flag;		/* block group flag of the raid */
101 };
102 
103 extern const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES];
104 
btrfs_bg_flags_to_raid_index(u64 flags)105 static inline enum btrfs_raid_types btrfs_bg_flags_to_raid_index(u64 flags)
106 {
107 	if (flags & BTRFS_BLOCK_GROUP_RAID10)
108 		return BTRFS_RAID_RAID10;
109 	else if (flags & BTRFS_BLOCK_GROUP_RAID1)
110 		return BTRFS_RAID_RAID1;
111 	else if (flags & BTRFS_BLOCK_GROUP_RAID1C3)
112 		return BTRFS_RAID_RAID1C3;
113 	else if (flags & BTRFS_BLOCK_GROUP_RAID1C4)
114 		return BTRFS_RAID_RAID1C4;
115 	else if (flags & BTRFS_BLOCK_GROUP_DUP)
116 		return BTRFS_RAID_DUP;
117 	else if (flags & BTRFS_BLOCK_GROUP_RAID0)
118 		return BTRFS_RAID_RAID0;
119 	else if (flags & BTRFS_BLOCK_GROUP_RAID5)
120 		return BTRFS_RAID_RAID5;
121 	else if (flags & BTRFS_BLOCK_GROUP_RAID6)
122 		return BTRFS_RAID_RAID6;
123 
124 	return BTRFS_RAID_SINGLE; /* BTRFS_BLOCK_GROUP_SINGLE */
125 }
126 
127 #define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
128 			    (sizeof(struct btrfs_bio_stripe) * (n)))
129 #define btrfs_map_lookup_size(n) (sizeof(struct map_lookup) + \
130 				 (sizeof(struct btrfs_bio_stripe) * (n)))
131 
132 #define BTRFS_RAID5_P_STRIPE ((u64)-2)
133 #define BTRFS_RAID6_Q_STRIPE ((u64)-1)
134 
calc_stripe_length(u64 type,u64 length,int num_stripes)135 static inline u64 calc_stripe_length(u64 type, u64 length, int num_stripes)
136 {
137 	u64 stripe_size;
138 
139 	if (type & BTRFS_BLOCK_GROUP_RAID0) {
140 		stripe_size = length;
141 		stripe_size /= num_stripes;
142 	} else if (type & BTRFS_BLOCK_GROUP_RAID10) {
143 		stripe_size = length * 2;
144 		stripe_size /= num_stripes;
145 	} else if (type & BTRFS_BLOCK_GROUP_RAID5) {
146 		stripe_size = length;
147 		stripe_size /= (num_stripes - 1);
148 	} else if (type & BTRFS_BLOCK_GROUP_RAID6) {
149 		stripe_size = length;
150 		stripe_size /= (num_stripes - 2);
151 	} else {
152 		stripe_size = length;
153 	}
154 	return stripe_size;
155 }
156 
157 #ifndef READ
158 #define READ 0
159 #define WRITE 1
160 #define READA 2
161 #endif
162 
163 int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
164 		      u64 logical, u64 *length, u64 *type,
165 		      struct btrfs_multi_bio **multi_ret, int mirror_num,
166 		      u64 **raid_map);
167 int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
168 		    u64 logical, u64 *length,
169 		    struct btrfs_multi_bio **multi_ret, int mirror_num,
170 		    u64 **raid_map_ret);
171 int btrfs_next_bg(struct btrfs_fs_info *map_tree, u64 *logical,
172 		     u64 *size, u64 type);
btrfs_next_bg_metadata(struct btrfs_fs_info * fs_info,u64 * logical,u64 * size)173 static inline int btrfs_next_bg_metadata(struct btrfs_fs_info *fs_info,
174 					 u64 *logical, u64 *size)
175 {
176 	return btrfs_next_bg(fs_info, logical, size,
177 			BTRFS_BLOCK_GROUP_METADATA);
178 }
btrfs_next_bg_system(struct btrfs_fs_info * fs_info,u64 * logical,u64 * size)179 static inline int btrfs_next_bg_system(struct btrfs_fs_info *fs_info,
180 				       u64 *logical, u64 *size)
181 {
182 	return btrfs_next_bg(fs_info, logical, size,
183 			BTRFS_BLOCK_GROUP_SYSTEM);
184 }
185 int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
186 int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
187 int btrfs_open_devices(struct btrfs_fs_devices *fs_devices);
188 int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
189 void btrfs_close_all_devices(void);
190 int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
191 int btrfs_scan_one_device(struct blk_desc *desc, struct disk_partition *part,
192 			  struct btrfs_fs_devices **fs_devices_ret,
193 			  u64 *total_devs);
194 struct list_head *btrfs_scanned_uuids(void);
195 struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
196 				       u8 *uuid, u8 *fsid);
197 int btrfs_check_chunk_valid(struct btrfs_fs_info *fs_info,
198 			    struct extent_buffer *leaf,
199 			    struct btrfs_chunk *chunk,
200 			    int slot, u64 logical);
201 u64 btrfs_stripe_length(struct btrfs_fs_info *fs_info,
202 			struct extent_buffer *leaf,
203 			struct btrfs_chunk *chunk);
204 #endif
205