Line 0
Link Here
|
|
|
1 |
/* btrfs.h - an extraction from btrfs-progs-0.18/ctree.h into one file |
2 |
* |
3 |
* Copyright (C) 2007 Oracle. All rights reserved. |
4 |
* |
5 |
* This program is free software; you can redistribute it and/or |
6 |
* modify it under the terms of the GNU General Public |
7 |
* License v2 as published by the Free Software Foundation. |
8 |
* |
9 |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 |
* General Public License for more details. |
13 |
* |
14 |
* You should have received a copy of the GNU General Public |
15 |
* License along with this program; if not, write to the |
16 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
17 |
* Boston, MA 021110-1307, USA. |
18 |
*/ |
19 |
|
20 |
/* include/asm-i386/types.h */ |
21 |
|
22 |
typedef __signed__ char __s8; |
23 |
typedef unsigned char __u8; |
24 |
typedef __signed__ short __s16; |
25 |
typedef unsigned short __u16; |
26 |
typedef __signed__ int __s32; |
27 |
typedef unsigned int __u32; |
28 |
typedef unsigned long long __u64; |
29 |
typedef __signed__ long long __s64; |
30 |
|
31 |
typedef __s8 s8; |
32 |
typedef __u8 u8; |
33 |
typedef __u16 u16; |
34 |
typedef __u32 u32; |
35 |
typedef __u64 u64; |
36 |
typedef __s64 s64; |
37 |
|
38 |
#define __bitwise |
39 |
|
40 |
typedef u16 __bitwise __le16; |
41 |
typedef u32 __bitwise __le32; |
42 |
typedef u64 __bitwise __le64; |
43 |
|
44 |
/* linux/posix_type.h */ |
45 |
typedef long linux_off_t; |
46 |
|
47 |
/* linux/little_endian.h */ |
48 |
#define cpu_to_le64(x) ((__u64) (x)) |
49 |
#define le64_to_cpu(x) ((__u64) (x)) |
50 |
#define cpu_to_le32(x) ((__u32) (x)) |
51 |
#define le32_to_cpu(x) ((__u32) (x)) |
52 |
#define cpu_to_le16(x) ((__u16) (x)) |
53 |
#define le16_to_cpu(x) ((__u16) (x)) |
54 |
#define le8_to_cpu(x) ((__u8) (x)) |
55 |
#define cpu_to_le8(x) ((__u8) (x)) |
56 |
|
57 |
/* linux/stat.h */ |
58 |
#define S_IFMT 00170000 |
59 |
#define S_IFLNK 0120000 |
60 |
#define S_IFREG 0100000 |
61 |
#define S_IFDIR 0040000 |
62 |
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) |
63 |
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) |
64 |
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
65 |
|
66 |
struct btrfs_root; |
67 |
#define BTRFS_MAGIC "_BHRfS_M" |
68 |
|
69 |
#define BTRFS_SUPER_INFO_OFFSET (64 * 1024) |
70 |
#define BTRFS_SUPER_INFO_SIZE 4096 |
71 |
|
72 |
#define BTRFS_SUPER_MIRROR_MAX 3 |
73 |
#define BTRFS_SUPER_MIRROR_SHIFT 12 |
74 |
|
75 |
#define PATH_MAX 1024 /* include/linux/limits.h */ |
76 |
#define MAX_LINK_COUNT 5 /* number of symbolic links |
77 |
to follow */ |
78 |
#define BTRFS_MAX_LEVEL 8 |
79 |
#define BTRFS_ROOT_TREE_OBJECTID 1ULL |
80 |
#define BTRFS_EXTENT_TREE_OBJECTID 2ULL |
81 |
#define BTRFS_CHUNK_TREE_OBJECTID 3ULL |
82 |
#define BTRFS_DEV_TREE_OBJECTID 4ULL |
83 |
#define BTRFS_FS_TREE_OBJECTID 5ULL |
84 |
#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL |
85 |
#define BTRFS_CSUM_TREE_OBJECTID 7ULL |
86 |
|
87 |
#define BTRFS_ORPHAN_OBJECTID -5ULL |
88 |
#define BTRFS_TREE_LOG_OBJECTID -6ULL |
89 |
#define BTRFS_TREE_LOG_FIXUP_OBJECTID -7ULL |
90 |
#define BTRFS_TREE_RELOC_OBJECTID -8ULL |
91 |
#define BTRFS_DATA_RELOC_TREE_OBJECTID -9ULL |
92 |
#define BTRFS_EXTENT_CSUM_OBJECTID -10ULL |
93 |
|
94 |
#define BTRFS_MULTIPLE_OBJECTIDS -255ULL |
95 |
#define BTRFS_FIRST_FREE_OBJECTID 256ULL |
96 |
#define BTRFS_LAST_FREE_OBJECTID -256ULL |
97 |
#define BTRFS_FIRST_CHUNK_TREE_OBJECTID 256ULL |
98 |
#define BTRFS_DEV_ITEMS_OBJECTID 1ULL |
99 |
|
100 |
|
101 |
#define BTRFS_NAME_LEN 255 |
102 |
#define BTRFS_CSUM_SIZE 32 |
103 |
#define BTRFS_CSUM_TYPE_CRC32 0 |
104 |
|
105 |
static int btrfs_csum_sizes[] = { 4, 0 }; |
106 |
|
107 |
/* four bytes for CRC32 */ |
108 |
#define BTRFS_CRC32_SIZE 4 |
109 |
#define BTRFS_EMPTY_DIR_SIZE 0 |
110 |
|
111 |
#define BTRFS_FT_UNKNOWN 0 |
112 |
#define BTRFS_FT_REG_FILE 1 |
113 |
#define BTRFS_FT_DIR 2 |
114 |
#define BTRFS_FT_CHRDEV 3 |
115 |
#define BTRFS_FT_BLKDEV 4 |
116 |
#define BTRFS_FT_FIFO 5 |
117 |
#define BTRFS_FT_SOCK 6 |
118 |
#define BTRFS_FT_SYMLINK 7 |
119 |
#define BTRFS_FT_XATTR 8 |
120 |
#define BTRFS_FT_MAX 9 |
121 |
|
122 |
#define BTRFS_UUID_SIZE 16 |
123 |
|
124 |
#define BTRFS_DEFAULT_NUM_DEVICES 1 |
125 |
#define BTRFS_DEFAULT_NODE_SIZE 4096 |
126 |
#define BTRFS_DEFAULT_LEAF_SIZE 4096 |
127 |
#define BTRFS_NUM_CACHED_DEVICES 128 |
128 |
|
129 |
#define WARN_ON(c) |
130 |
#define cassert(cond) ({ switch (-1) { case (cond): case 0: break; } }) |
131 |
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
132 |
|
133 |
#define offsetof(type, memb) \ |
134 |
((unsigned long)(&((type *)0)->memb)) |
135 |
|
136 |
struct btrfs_disk_key { |
137 |
__le64 objectid; |
138 |
u8 type; |
139 |
__le64 offset; |
140 |
} __attribute__ ((__packed__)); |
141 |
|
142 |
/* cpu key */ |
143 |
struct btrfs_key { |
144 |
u64 objectid; |
145 |
u8 type; |
146 |
u64 offset; |
147 |
} __attribute__ ((__packed__)); |
148 |
|
149 |
/* this represents a divice in a chunk tree */ |
150 |
struct btrfs_dev_item { |
151 |
__le64 devid; /* internal device id */ |
152 |
__le64 total_bytes; /* size of the device */ |
153 |
__le64 bytes_used; |
154 |
__le32 io_align; /* optimal io alignment */ |
155 |
__le32 io_width; /* optimal io width */ |
156 |
__le32 sector_size; /* minimal io size */ |
157 |
__le64 type; /* type and info about this device */ |
158 |
__le64 generation; /* expected generation */ |
159 |
__le64 start_offset; /* of the partition on a device */ |
160 |
|
161 |
/* info for allocation decisions */ |
162 |
__le32 dev_group; |
163 |
|
164 |
u8 seek_speed; /* 0-100 (100 is fastest) */ |
165 |
u8 bandwidth; /* 0-100 (100 is fastest) */ |
166 |
|
167 |
u8 uuid[BTRFS_UUID_SIZE]; /* dev uuid generated by btrfs */ |
168 |
u8 fsid[BTRFS_UUID_SIZE]; /* uuid of the host FS */ |
169 |
} __attribute__ ((__packed__)); |
170 |
|
171 |
struct btrfs_stripe { |
172 |
__le64 devid; |
173 |
__le64 offset; |
174 |
u8 dev_uuid[BTRFS_UUID_SIZE]; |
175 |
} __attribute__ ((__packed__)); |
176 |
|
177 |
struct btrfs_chunk { |
178 |
/* size of this chunk in bytes */ |
179 |
__le64 length; |
180 |
__le64 owner; /* objectid of the root referincing this chunk */ |
181 |
__le64 stripe_len; |
182 |
__le64 type; |
183 |
__le32 io_align; /* optimal io alignment for this chunk */ |
184 |
__le32 io_width; /* optimal io width for this chunk */ |
185 |
__le32 sector_size; /* minimal io size for this chunk */ |
186 |
__le16 num_stripes; |
187 |
__le16 sub_stripes; /* sub stripes (for raid10) */ |
188 |
struct btrfs_stripe stripe; |
189 |
} __attribute__ ((__packed__)); |
190 |
|
191 |
static inline unsigned long btrfs_chunk_item_size(int num_stripes) |
192 |
{ |
193 |
return sizeof(struct btrfs_chunk) + |
194 |
sizeof(struct btrfs_stripe) * (num_stripes - 1); |
195 |
} |
196 |
|
197 |
#define BTRFS_FSID_SIZE 16 |
198 |
#define BTRFS_HEADER_FLAG_WRITTEN (1 << 0) |
199 |
|
200 |
struct btrfs_header { |
201 |
/* these first four must match the super block */ |
202 |
u8 csum[BTRFS_CSUM_SIZE]; |
203 |
u8 fsid[BTRFS_FSID_SIZE]; /* uuid of the host fs */ |
204 |
__le64 bytenr; /* which block this node is supposed to live in */ |
205 |
__le64 flags; |
206 |
|
207 |
/* allowed to be different from the super from here on down */ |
208 |
u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; |
209 |
__le64 generation; |
210 |
__le64 owner; |
211 |
__le32 nritems; |
212 |
u8 level; |
213 |
} __attribute__ ((__packed__)); |
214 |
|
215 |
#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \ |
216 |
sizeof(struct btrfs_header)) / \ |
217 |
sizeof(struct btrfs_key_ptr)) |
218 |
#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) |
219 |
#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize)) |
220 |
#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ |
221 |
sizeof(struct btrfs_item) - \ |
222 |
sizeof(struct btrfs_file_extent_item)) |
223 |
|
224 |
#define BTRFS_SUPER_FLAG_SEEDING (1ULL << 32) |
225 |
#define BTRFS_SUPER_FLAG_METADUMP (1ULL << 33) |
226 |
|
227 |
/* |
228 |
* a portion of superblock which is used |
229 |
* for chunk translation (up to 14 chunks |
230 |
* with 3 stripes each. |
231 |
*/ |
232 |
#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048 |
233 |
#define BTRFS_LABEL_SIZE 256 |
234 |
|
235 |
/* |
236 |
* the super block basically lists the main trees of the FS |
237 |
* it currently lacks any block count etc etc |
238 |
*/ |
239 |
|
240 |
struct btrfs_super_block { |
241 |
u8 csum[BTRFS_CSUM_SIZE]; |
242 |
/* the first 3 fields must match struct btrfs_header */ |
243 |
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ |
244 |
__le64 bytenr; /* this block number */ |
245 |
__le64 flags; |
246 |
|
247 |
/* allowed to be different from the btrfs_header from here own down */ |
248 |
__le64 magic; |
249 |
__le64 generation; |
250 |
__le64 root; /* tree root */ |
251 |
__le64 chunk_root; |
252 |
__le64 log_root; |
253 |
|
254 |
/* this will help find the new super based on the log root */ |
255 |
__le64 log_root_transid; |
256 |
__le64 total_bytes; |
257 |
__le64 bytes_used; |
258 |
__le64 root_dir_objectid; |
259 |
__le64 num_devices; |
260 |
__le32 sectorsize; |
261 |
__le32 nodesize; |
262 |
__le32 leafsize; |
263 |
__le32 stripesize; |
264 |
__le32 sys_chunk_array_size; |
265 |
__le64 chunk_root_generation; |
266 |
__le64 compat_flags; |
267 |
__le64 compat_ro_flags; |
268 |
__le64 incompat_flags; |
269 |
__le16 csum_type; |
270 |
u8 root_level; |
271 |
u8 chunk_root_level; |
272 |
u8 log_root_level; |
273 |
struct btrfs_dev_item dev_item; |
274 |
|
275 |
char label[BTRFS_LABEL_SIZE]; |
276 |
|
277 |
/* future expansion */ |
278 |
__le64 reserved[32]; |
279 |
u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; |
280 |
} __attribute__ ((__packed__)); |
281 |
|
282 |
/* |
283 |
* Compat flags that we support. If any incompat flags are set other than the |
284 |
* ones specified below then we will fail to mount |
285 |
*/ |
286 |
#define BTRFS_FEATURE_COMPAT_SUPP 0x0 |
287 |
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0x0 |
288 |
#define BTRFS_FEATURE_INCOMPAT_SUPP 0x0 |
289 |
|
290 |
/* Item header for per-leaf lookup */ |
291 |
struct btrfs_item { |
292 |
struct btrfs_disk_key key; |
293 |
__le32 offset; |
294 |
__le32 size; |
295 |
} __attribute__ ((__packed__)); |
296 |
|
297 |
/* |
298 |
* Format of the leaves: |
299 |
* [item0, item1....itemN] [free space] [dataN...data1, data0] |
300 |
*/ |
301 |
struct btrfs_leaf { |
302 |
struct btrfs_header header; |
303 |
struct btrfs_item items[]; |
304 |
} __attribute__ ((__packed__)); |
305 |
|
306 |
/* |
307 |
* keys-pointers pairs for per-node (non-leaf) lookup |
308 |
*/ |
309 |
struct btrfs_key_ptr { |
310 |
struct btrfs_disk_key key; |
311 |
__le64 blockptr; |
312 |
__le64 generation; |
313 |
} __attribute__ ((__packed__)); |
314 |
|
315 |
struct btrfs_node { |
316 |
struct btrfs_header header; |
317 |
struct btrfs_key_ptr ptrs[]; |
318 |
} __attribute__ ((__packed__)); |
319 |
|
320 |
struct btrfs_device { |
321 |
/* the internal btrfs device id */ |
322 |
u64 devid; |
323 |
/* the internal grub device representation */ |
324 |
unsigned long drive; |
325 |
unsigned long part; |
326 |
unsigned long length; |
327 |
}; |
328 |
|
329 |
struct extent_buffer { |
330 |
/* metadata */ |
331 |
struct btrfs_device dev; |
332 |
u64 start; |
333 |
u64 dev_bytenr; |
334 |
u32 len; |
335 |
/* data */ |
336 |
char *data; |
337 |
}; |
338 |
|
339 |
static inline void read_extent_buffer(struct extent_buffer *eb, |
340 |
void *dst, unsigned long start, |
341 |
unsigned long len) |
342 |
{ |
343 |
memcpy(dst, eb->data + start, len); |
344 |
} |
345 |
|
346 |
static inline void write_extent_buffer(struct extent_buffer *eb, |
347 |
const void *src, unsigned long start, |
348 |
unsigned long len) |
349 |
{ |
350 |
memcpy(eb->data + start, src, len); |
351 |
} |
352 |
|
353 |
/* |
354 |
* NOTE: |
355 |
* don't increase a number of levels for grub-0.97! |
356 |
*/ |
357 |
typedef enum { |
358 |
FIRST_EXTERNAL_LOOKUP_POOL, |
359 |
SECOND_EXTERNAL_LOOKUP_POOL, |
360 |
INTERNAL_LOOKUP_POOL, |
361 |
LAST_LOOKUP_POOL |
362 |
} lookup_pool_id; |
363 |
|
364 |
/* Relationship between lookup pools: |
365 |
* depth |
366 |
* |
367 |
* ^ +----> INTERNAL <----+ |
368 |
* | | | |
369 |
* | | | |
370 |
* - FIRST_EXTERNAL SECOND_EXTERNAL |
371 |
*/ |
372 |
|
373 |
struct btrfs_path { |
374 |
lookup_pool_id lpid; |
375 |
struct extent_buffer nodes[BTRFS_MAX_LEVEL]; |
376 |
int slots[BTRFS_MAX_LEVEL]; |
377 |
}; |
378 |
|
379 |
/* |
380 |
* items in the extent btree are used to record the objectid of the |
381 |
* owner of the block and the number of references |
382 |
*/ |
383 |
struct btrfs_extent_item { |
384 |
__le32 refs; |
385 |
} __attribute__ ((__packed__)); |
386 |
|
387 |
struct btrfs_extent_ref { |
388 |
__le64 root; |
389 |
__le64 generation; |
390 |
__le64 objectid; |
391 |
__le32 num_refs; |
392 |
} __attribute__ ((__packed__)); |
393 |
|
394 |
/* dev extents record free space on individual devices. The owner |
395 |
* field points back to the chunk allocation mapping tree that allocated |
396 |
* the extent. The chunk tree uuid field is a way to double check the owner |
397 |
*/ |
398 |
struct btrfs_dev_extent { |
399 |
__le64 chunk_tree; |
400 |
__le64 chunk_objectid; |
401 |
__le64 chunk_offset; |
402 |
__le64 length; |
403 |
u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; |
404 |
} __attribute__ ((__packed__)); |
405 |
|
406 |
struct btrfs_inode_ref { |
407 |
__le64 index; |
408 |
__le16 name_len; |
409 |
/* name goes here */ |
410 |
} __attribute__ ((__packed__)); |
411 |
|
412 |
struct btrfs_timespec { |
413 |
__le64 sec; |
414 |
__le32 nsec; |
415 |
} __attribute__ ((__packed__)); |
416 |
|
417 |
typedef enum { |
418 |
BTRFS_COMPRESS_NONE = 0, |
419 |
BTRFS_COMPRESS_ZLIB = 1, |
420 |
BTRFS_COMPRESS_LAST = 2, |
421 |
} btrfs_compression_type; |
422 |
|
423 |
/* we don't understand any encryption methods right now */ |
424 |
typedef enum { |
425 |
BTRFS_ENCRYPTION_NONE = 0, |
426 |
BTRFS_ENCRYPTION_LAST = 1, |
427 |
} btrfs_encryption_type; |
428 |
|
429 |
struct btrfs_inode_item { |
430 |
/* nfs style generation number */ |
431 |
__le64 generation; |
432 |
/* transid that last touched this inode */ |
433 |
__le64 transid; |
434 |
__le64 size; |
435 |
__le64 nbytes; |
436 |
__le64 block_group; |
437 |
__le32 nlink; |
438 |
__le32 uid; |
439 |
__le32 gid; |
440 |
__le32 mode; |
441 |
__le64 rdev; |
442 |
__le64 flags; |
443 |
|
444 |
/* modification sequence number for NFS */ |
445 |
__le64 sequence; |
446 |
|
447 |
/* |
448 |
* a little future expansion, for more than this we can |
449 |
* just grow the inode item and version it |
450 |
*/ |
451 |
__le64 reserved[4]; |
452 |
struct btrfs_timespec atime; |
453 |
struct btrfs_timespec ctime; |
454 |
struct btrfs_timespec mtime; |
455 |
struct btrfs_timespec otime; |
456 |
} __attribute__ ((__packed__)); |
457 |
|
458 |
struct btrfs_dir_item { |
459 |
struct btrfs_disk_key location; |
460 |
__le64 transid; |
461 |
__le16 data_len; |
462 |
__le16 name_len; |
463 |
u8 type; |
464 |
} __attribute__ ((__packed__)); |
465 |
|
466 |
struct btrfs_root_item { |
467 |
struct btrfs_inode_item inode; |
468 |
__le64 generation; |
469 |
__le64 root_dirid; |
470 |
__le64 bytenr; |
471 |
__le64 byte_limit; |
472 |
__le64 bytes_used; |
473 |
__le64 last_snapshot; |
474 |
__le64 flags; |
475 |
__le32 refs; |
476 |
struct btrfs_disk_key drop_progress; |
477 |
u8 drop_level; |
478 |
u8 level; |
479 |
} __attribute__ ((__packed__)); |
480 |
|
481 |
/* |
482 |
* this is used for both forward and backward root refs |
483 |
*/ |
484 |
struct btrfs_root_ref { |
485 |
__le64 dirid; |
486 |
__le64 sequence; |
487 |
__le16 name_len; |
488 |
} __attribute__ ((__packed__)); |
489 |
|
490 |
#define BTRFS_FILE_EXTENT_INLINE 0 |
491 |
#define BTRFS_FILE_EXTENT_REG 1 |
492 |
#define BTRFS_FILE_EXTENT_PREALLOC 2 |
493 |
|
494 |
struct btrfs_file_extent_item { |
495 |
/* |
496 |
* transaction id that created this extent |
497 |
*/ |
498 |
__le64 generation; |
499 |
/* |
500 |
* max number of bytes to hold this extent in ram |
501 |
* when we split a compressed extent we can't know how big |
502 |
* each of the resulting pieces will be. So, this is |
503 |
* an upper limit on the size of the extent in ram instead of |
504 |
* an exact limit. |
505 |
*/ |
506 |
__le64 ram_bytes; |
507 |
|
508 |
/* |
509 |
* 32 bits for the various ways we might encode the data, |
510 |
* including compression and encryption. If any of these |
511 |
* are set to something a given disk format doesn't understand |
512 |
* it is treated like an incompat flag for reading and writing, |
513 |
* but not for stat. |
514 |
*/ |
515 |
u8 compression; |
516 |
u8 encryption; |
517 |
__le16 other_encoding; /* spare for later use */ |
518 |
|
519 |
/* are we inline data or a real extent? */ |
520 |
u8 type; |
521 |
|
522 |
/* |
523 |
* disk space consumed by the extent, checksum blocks are included |
524 |
* in these numbers |
525 |
*/ |
526 |
__le64 disk_bytenr; |
527 |
__le64 disk_num_bytes; |
528 |
/* |
529 |
* the logical offset in file blocks (no csums) |
530 |
* this extent record is for. This allows a file extent to point |
531 |
* into the middle of an existing extent on disk, sharing it |
532 |
* between two snapshots (useful if some bytes in the middle of the |
533 |
* extent have changed |
534 |
*/ |
535 |
__le64 offset; |
536 |
/* |
537 |
* the logical number of file blocks (no csums included) |
538 |
*/ |
539 |
__le64 num_bytes; |
540 |
|
541 |
} __attribute__ ((__packed__)); |
542 |
|
543 |
struct btrfs_csum_item { |
544 |
u8 csum; |
545 |
} __attribute__ ((__packed__)); |
546 |
|
547 |
/* tag for the radix tree of block groups in ram */ |
548 |
#define BTRFS_BLOCK_GROUP_DATA (1 << 0) |
549 |
#define BTRFS_BLOCK_GROUP_SYSTEM (1 << 1) |
550 |
#define BTRFS_BLOCK_GROUP_METADATA (1 << 2) |
551 |
#define BTRFS_BLOCK_GROUP_RAID0 (1 << 3) |
552 |
#define BTRFS_BLOCK_GROUP_RAID1 (1 << 4) |
553 |
#define BTRFS_BLOCK_GROUP_DUP (1 << 5) |
554 |
#define BTRFS_BLOCK_GROUP_RAID10 (1 << 6) |
555 |
|
556 |
struct btrfs_block_group_item { |
557 |
__le64 used; |
558 |
__le64 chunk_objectid; |
559 |
__le64 flags; |
560 |
} __attribute__ ((__packed__)); |
561 |
|
562 |
/* |
563 |
* in ram representation of the tree. extent_root is used for all allocations |
564 |
* and for the extent tree extent_root root. |
565 |
*/ |
566 |
struct btrfs_root { |
567 |
struct extent_buffer node; |
568 |
char data[4096]; |
569 |
struct btrfs_root_item root_item; |
570 |
u64 objectid; |
571 |
|
572 |
/* data allocations are done in sectorsize units */ |
573 |
u32 sectorsize; |
574 |
|
575 |
/* node allocations are done in nodesize units */ |
576 |
u32 nodesize; |
577 |
|
578 |
/* leaf allocations are done in leafsize units */ |
579 |
u32 leafsize; |
580 |
|
581 |
/* leaf allocations are done in leafsize units */ |
582 |
u32 stripesize; |
583 |
}; |
584 |
|
585 |
struct btrfs_file_info { |
586 |
struct btrfs_key key; |
587 |
}; |
588 |
|
589 |
struct btrfs_root; |
590 |
struct btrfs_fs_devices; |
591 |
struct btrfs_fs_info { |
592 |
u8 fsid[BTRFS_FSID_SIZE]; |
593 |
struct btrfs_root fs_root; |
594 |
struct btrfs_root tree_root; |
595 |
struct btrfs_root chunk_root; |
596 |
|
597 |
struct btrfs_file_info file_info; /* currently opened file */ |
598 |
struct btrfs_path paths [LAST_LOOKUP_POOL]; |
599 |
|
600 |
char mbr[SECTOR_SIZE]; |
601 |
|
602 |
int sb_mirror; |
603 |
u64 sb_transid; |
604 |
struct btrfs_device sb_dev; |
605 |
struct btrfs_super_block sb_copy; |
606 |
|
607 |
struct btrfs_device devices[BTRFS_NUM_CACHED_DEVICES + 1]; |
608 |
}; |
609 |
|
610 |
/* |
611 |
* inode items have the data typically returned from stat and store other |
612 |
* info about object characteristics. There is one for every file and dir in |
613 |
* the FS |
614 |
*/ |
615 |
#define BTRFS_INODE_ITEM_KEY 1 |
616 |
#define BTRFS_INODE_REF_KEY 12 |
617 |
#define BTRFS_XATTR_ITEM_KEY 24 |
618 |
#define BTRFS_ORPHAN_ITEM_KEY 48 |
619 |
|
620 |
#define BTRFS_DIR_LOG_ITEM_KEY 60 |
621 |
#define BTRFS_DIR_LOG_INDEX_KEY 72 |
622 |
/* |
623 |
* dir items are the name -> inode pointers in a directory. There is one |
624 |
* for every name in a directory. |
625 |
*/ |
626 |
#define BTRFS_DIR_ITEM_KEY 84 |
627 |
#define BTRFS_DIR_INDEX_KEY 96 |
628 |
|
629 |
/* |
630 |
* extent data is for file data |
631 |
*/ |
632 |
#define BTRFS_EXTENT_DATA_KEY 108 |
633 |
|
634 |
/* |
635 |
* csum items have the checksums for data in the extents |
636 |
*/ |
637 |
#define BTRFS_CSUM_ITEM_KEY 120 |
638 |
/* |
639 |
* extent csums are stored in a separate tree and hold csums for |
640 |
* an entire extent on disk. |
641 |
*/ |
642 |
#define BTRFS_EXTENT_CSUM_KEY 128 |
643 |
|
644 |
/* |
645 |
* root items point to tree roots. There are typically in the root |
646 |
* tree used by the super block to find all the other trees |
647 |
*/ |
648 |
#define BTRFS_ROOT_ITEM_KEY 132 |
649 |
|
650 |
/* |
651 |
* root backrefs tie subvols and snapshots to the directory entries that |
652 |
* reference them |
653 |
*/ |
654 |
#define BTRFS_ROOT_BACKREF_KEY 144 |
655 |
|
656 |
/* |
657 |
* root refs make a fast index for listing all of the snapshots and |
658 |
* subvolumes referenced by a given root. They point directly to the |
659 |
* directory item in the root that references the subvol |
660 |
*/ |
661 |
#define BTRFS_ROOT_REF_KEY 156 |
662 |
|
663 |
/* |
664 |
+ * extent items are in the extent map tree. These record which blocks |
665 |
+ * are used, and how many references there are to each block |
666 |
+ */ |
667 |
#define BTRFS_EXTENT_ITEM_KEY 168 |
668 |
#define BTRFS_EXTENT_REF_KEY 180 |
669 |
|
670 |
/* |
671 |
* block groups give us hints into the extent allocation trees. Which |
672 |
* blocks are free etc etc |
673 |
*/ |
674 |
#define BTRFS_BLOCK_GROUP_ITEM_KEY 192 |
675 |
|
676 |
#define BTRFS_DEV_EXTENT_KEY 204 |
677 |
#define BTRFS_DEV_ITEM_KEY 216 |
678 |
#define BTRFS_CHUNK_ITEM_KEY 228 |
679 |
|
680 |
/* |
681 |
* string items are for debugging. They just store a short string of |
682 |
* data in the FS |
683 |
*/ |
684 |
#define BTRFS_STRING_ITEM_KEY 253 |
685 |
/* |
686 |
* Inode flags |
687 |
*/ |
688 |
#define BTRFS_INODE_NODATASUM (1 << 0) |
689 |
#define BTRFS_INODE_NODATACOW (1 << 1) |
690 |
#define BTRFS_INODE_READONLY (1 << 2) |
691 |
|
692 |
#define read_eb_member(eb, ptr, type, member, result) ( \ |
693 |
read_extent_buffer(eb, (char *)(result), \ |
694 |
((unsigned long)(ptr)) + \ |
695 |
offsetof(type, member), \ |
696 |
sizeof(((type *)0)->member))) |
697 |
|
698 |
#define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ |
699 |
static inline u##bits btrfs_##name(struct extent_buffer *eb) \ |
700 |
{ \ |
701 |
struct btrfs_header *h = (struct btrfs_header *)eb->data; \ |
702 |
return le##bits##_to_cpu(h->member); \ |
703 |
} \ |
704 |
static inline void btrfs_set_##name(struct extent_buffer *eb, \ |
705 |
u##bits val) \ |
706 |
{ \ |
707 |
struct btrfs_header *h = (struct btrfs_header *)eb->data; \ |
708 |
h->member = cpu_to_le##bits(val); \ |
709 |
} |
710 |
|
711 |
#define BTRFS_SETGET_FUNCS(name, type, member, bits) \ |
712 |
static inline u##bits btrfs_##name(struct extent_buffer *eb, \ |
713 |
type *s) \ |
714 |
{ \ |
715 |
unsigned long offset = (unsigned long)s; \ |
716 |
type *p = (type *) (eb->data + offset); \ |
717 |
return le##bits##_to_cpu(p->member); \ |
718 |
} \ |
719 |
static inline void btrfs_set_##name(struct extent_buffer *eb, \ |
720 |
type *s, u##bits val) \ |
721 |
{ \ |
722 |
unsigned long offset = (unsigned long)s; \ |
723 |
type *p = (type *) (eb->data + offset); \ |
724 |
p->member = cpu_to_le##bits(val); \ |
725 |
} |
726 |
|
727 |
#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ |
728 |
static inline u##bits btrfs_##name(type *s) \ |
729 |
{ \ |
730 |
return le##bits##_to_cpu(s->member); \ |
731 |
} \ |
732 |
static inline void btrfs_set_##name(type *s, u##bits val) \ |
733 |
{ \ |
734 |
s->member = cpu_to_le##bits(val); \ |
735 |
} |
736 |
|
737 |
BTRFS_SETGET_FUNCS(device_type, struct btrfs_dev_item, type, 64); |
738 |
BTRFS_SETGET_FUNCS(device_total_bytes, struct btrfs_dev_item, total_bytes, 64); |
739 |
BTRFS_SETGET_FUNCS(device_bytes_used, struct btrfs_dev_item, bytes_used, 64); |
740 |
BTRFS_SETGET_FUNCS(device_io_align, struct btrfs_dev_item, io_align, 32); |
741 |
BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32); |
742 |
BTRFS_SETGET_FUNCS(device_start_offset, struct btrfs_dev_item, |
743 |
start_offset, 64); |
744 |
BTRFS_SETGET_FUNCS(device_sector_size, struct btrfs_dev_item, sector_size, 32); |
745 |
BTRFS_SETGET_FUNCS(device_id, struct btrfs_dev_item, devid, 64); |
746 |
BTRFS_SETGET_FUNCS(device_group, struct btrfs_dev_item, dev_group, 32); |
747 |
BTRFS_SETGET_FUNCS(device_seek_speed, struct btrfs_dev_item, seek_speed, 8); |
748 |
BTRFS_SETGET_FUNCS(device_bandwidth, struct btrfs_dev_item, bandwidth, 8); |
749 |
BTRFS_SETGET_FUNCS(device_generation, struct btrfs_dev_item, generation, 64); |
750 |
|
751 |
BTRFS_SETGET_STACK_FUNCS(stack_device_type, struct btrfs_dev_item, type, 64); |
752 |
BTRFS_SETGET_STACK_FUNCS(stack_device_total_bytes, struct btrfs_dev_item, |
753 |
total_bytes, 64); |
754 |
BTRFS_SETGET_STACK_FUNCS(stack_device_bytes_used, struct btrfs_dev_item, |
755 |
bytes_used, 64); |
756 |
BTRFS_SETGET_STACK_FUNCS(stack_device_io_align, struct btrfs_dev_item, |
757 |
io_align, 32); |
758 |
BTRFS_SETGET_STACK_FUNCS(stack_device_io_width, struct btrfs_dev_item, |
759 |
io_width, 32); |
760 |
BTRFS_SETGET_STACK_FUNCS(stack_device_sector_size, struct btrfs_dev_item, |
761 |
sector_size, 32); |
762 |
BTRFS_SETGET_STACK_FUNCS(stack_device_id, struct btrfs_dev_item, devid, 64); |
763 |
BTRFS_SETGET_STACK_FUNCS(stack_device_group, struct btrfs_dev_item, |
764 |
dev_group, 32); |
765 |
BTRFS_SETGET_STACK_FUNCS(stack_device_seek_speed, struct btrfs_dev_item, |
766 |
seek_speed, 8); |
767 |
BTRFS_SETGET_STACK_FUNCS(stack_device_bandwidth, struct btrfs_dev_item, |
768 |
bandwidth, 8); |
769 |
BTRFS_SETGET_STACK_FUNCS(stack_device_generation, struct btrfs_dev_item, |
770 |
generation, 64); |
771 |
|
772 |
static inline char *btrfs_device_uuid(struct btrfs_dev_item *d) |
773 |
{ |
774 |
return (char *)d + offsetof(struct btrfs_dev_item, uuid); |
775 |
} |
776 |
|
777 |
static inline char *btrfs_device_fsid(struct btrfs_dev_item *d) |
778 |
{ |
779 |
return (char *)d + offsetof(struct btrfs_dev_item, fsid); |
780 |
} |
781 |
|
782 |
BTRFS_SETGET_FUNCS(chunk_length, struct btrfs_chunk, length, 64); |
783 |
BTRFS_SETGET_FUNCS(chunk_owner, struct btrfs_chunk, owner, 64); |
784 |
BTRFS_SETGET_FUNCS(chunk_stripe_len, struct btrfs_chunk, stripe_len, 64); |
785 |
BTRFS_SETGET_FUNCS(chunk_io_align, struct btrfs_chunk, io_align, 32); |
786 |
BTRFS_SETGET_FUNCS(chunk_io_width, struct btrfs_chunk, io_width, 32); |
787 |
BTRFS_SETGET_FUNCS(chunk_sector_size, struct btrfs_chunk, sector_size, 32); |
788 |
BTRFS_SETGET_FUNCS(chunk_type, struct btrfs_chunk, type, 64); |
789 |
BTRFS_SETGET_FUNCS(chunk_num_stripes, struct btrfs_chunk, num_stripes, 16); |
790 |
BTRFS_SETGET_FUNCS(chunk_sub_stripes, struct btrfs_chunk, sub_stripes, 16); |
791 |
BTRFS_SETGET_FUNCS(stripe_devid, struct btrfs_stripe, devid, 64); |
792 |
BTRFS_SETGET_FUNCS(stripe_offset, struct btrfs_stripe, offset, 64); |
793 |
|
794 |
static inline char *btrfs_stripe_dev_uuid(struct btrfs_stripe *s) |
795 |
{ |
796 |
return (char *)s + offsetof(struct btrfs_stripe, dev_uuid); |
797 |
} |
798 |
|
799 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_length, struct btrfs_chunk, length, 64); |
800 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_owner, struct btrfs_chunk, owner, 64); |
801 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_stripe_len, struct btrfs_chunk, |
802 |
stripe_len, 64); |
803 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_io_align, struct btrfs_chunk, |
804 |
io_align, 32); |
805 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_io_width, struct btrfs_chunk, |
806 |
io_width, 32); |
807 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_sector_size, struct btrfs_chunk, |
808 |
sector_size, 32); |
809 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_type, struct btrfs_chunk, type, 64); |
810 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_num_stripes, struct btrfs_chunk, |
811 |
num_stripes, 16); |
812 |
BTRFS_SETGET_STACK_FUNCS(stack_chunk_sub_stripes, struct btrfs_chunk, |
813 |
sub_stripes, 16); |
814 |
BTRFS_SETGET_STACK_FUNCS(stack_stripe_devid, struct btrfs_stripe, devid, 64); |
815 |
BTRFS_SETGET_STACK_FUNCS(stack_stripe_offset, struct btrfs_stripe, offset, 64); |
816 |
|
817 |
static inline struct btrfs_stripe *btrfs_stripe_nr(struct btrfs_chunk *c, |
818 |
int nr) |
819 |
{ |
820 |
unsigned long offset = (unsigned long)c; |
821 |
offset += offsetof(struct btrfs_chunk, stripe); |
822 |
offset += nr * sizeof(struct btrfs_stripe); |
823 |
return (struct btrfs_stripe *)offset; |
824 |
} |
825 |
|
826 |
static inline char *btrfs_stripe_dev_uuid_nr(struct btrfs_chunk *c, int nr) |
827 |
{ |
828 |
return btrfs_stripe_dev_uuid(btrfs_stripe_nr(c, nr)); |
829 |
} |
830 |
|
831 |
static inline u64 btrfs_stripe_offset_nr(struct extent_buffer *eb, |
832 |
struct btrfs_chunk *c, int nr) |
833 |
{ |
834 |
return btrfs_stripe_offset(eb, btrfs_stripe_nr(c, nr)); |
835 |
} |
836 |
|
837 |
static inline void btrfs_set_stripe_offset_nr(struct extent_buffer *eb, |
838 |
struct btrfs_chunk *c, int nr, |
839 |
u64 val) |
840 |
{ |
841 |
btrfs_set_stripe_offset(eb, btrfs_stripe_nr(c, nr), val); |
842 |
} |
843 |
|
844 |
static inline u64 btrfs_stripe_devid_nr(struct extent_buffer *eb, |
845 |
struct btrfs_chunk *c, int nr) |
846 |
{ |
847 |
return btrfs_stripe_devid(eb, btrfs_stripe_nr(c, nr)); |
848 |
} |
849 |
|
850 |
static inline void btrfs_set_stripe_devid_nr(struct extent_buffer *eb, |
851 |
struct btrfs_chunk *c, int nr, |
852 |
u64 val) |
853 |
{ |
854 |
btrfs_set_stripe_devid(eb, btrfs_stripe_nr(c, nr), val); |
855 |
} |
856 |
|
857 |
/* struct btrfs_block_group_item */ |
858 |
BTRFS_SETGET_STACK_FUNCS(block_group_used, struct btrfs_block_group_item, |
859 |
used, 64); |
860 |
BTRFS_SETGET_FUNCS(disk_block_group_used, struct btrfs_block_group_item, |
861 |
used, 64); |
862 |
BTRFS_SETGET_STACK_FUNCS(block_group_chunk_objectid, |
863 |
struct btrfs_block_group_item, chunk_objectid, 64); |
864 |
|
865 |
BTRFS_SETGET_FUNCS(disk_block_group_chunk_objectid, |
866 |
struct btrfs_block_group_item, chunk_objectid, 64); |
867 |
BTRFS_SETGET_FUNCS(disk_block_group_flags, |
868 |
struct btrfs_block_group_item, flags, 64); |
869 |
BTRFS_SETGET_STACK_FUNCS(block_group_flags, |
870 |
struct btrfs_block_group_item, flags, 64); |
871 |
|
872 |
/* struct btrfs_inode_ref */ |
873 |
BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16); |
874 |
BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64); |
875 |
|
876 |
/* struct btrfs_inode_item */ |
877 |
BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); |
878 |
BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64); |
879 |
BTRFS_SETGET_FUNCS(inode_transid, struct btrfs_inode_item, transid, 64); |
880 |
BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64); |
881 |
BTRFS_SETGET_FUNCS(inode_nbytes, struct btrfs_inode_item, nbytes, 64); |
882 |
BTRFS_SETGET_FUNCS(inode_block_group, struct btrfs_inode_item, block_group, 64); |
883 |
BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32); |
884 |
BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32); |
885 |
BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32); |
886 |
BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32); |
887 |
BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64); |
888 |
BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64); |
889 |
|
890 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_generation, |
891 |
struct btrfs_inode_item, generation, 64); |
892 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_sequence, |
893 |
struct btrfs_inode_item, generation, 64); |
894 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_size, |
895 |
struct btrfs_inode_item, size, 64); |
896 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_nbytes, |
897 |
struct btrfs_inode_item, nbytes, 64); |
898 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_block_group, |
899 |
struct btrfs_inode_item, block_group, 64); |
900 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_nlink, |
901 |
struct btrfs_inode_item, nlink, 32); |
902 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_uid, |
903 |
struct btrfs_inode_item, uid, 32); |
904 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_gid, |
905 |
struct btrfs_inode_item, gid, 32); |
906 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_mode, |
907 |
struct btrfs_inode_item, mode, 32); |
908 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_rdev, |
909 |
struct btrfs_inode_item, rdev, 64); |
910 |
BTRFS_SETGET_STACK_FUNCS(stack_inode_flags, |
911 |
struct btrfs_inode_item, flags, 64); |
912 |
|
913 |
BTRFS_SETGET_FUNCS(timespec_sec, struct btrfs_timespec, sec, 64); |
914 |
BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_timespec, nsec, 32); |
915 |
BTRFS_SETGET_STACK_FUNCS(stack_timespec_sec, struct btrfs_timespec, |
916 |
sec, 64); |
917 |
BTRFS_SETGET_STACK_FUNCS(stack_timespec_nsec, struct btrfs_timespec, |
918 |
nsec, 32); |
919 |
|
920 |
/* struct btrfs_dev_extent */ |
921 |
BTRFS_SETGET_FUNCS(dev_extent_chunk_tree, struct btrfs_dev_extent, |
922 |
chunk_tree, 64); |
923 |
BTRFS_SETGET_FUNCS(dev_extent_chunk_objectid, struct btrfs_dev_extent, |
924 |
chunk_objectid, 64); |
925 |
BTRFS_SETGET_FUNCS(dev_extent_chunk_offset, struct btrfs_dev_extent, |
926 |
chunk_offset, 64); |
927 |
BTRFS_SETGET_FUNCS(dev_extent_length, struct btrfs_dev_extent, length, 64); |
928 |
|
929 |
static inline u8 *btrfs_dev_extent_chunk_tree_uuid(struct btrfs_dev_extent *dev) |
930 |
{ |
931 |
unsigned long ptr = offsetof(struct btrfs_dev_extent, chunk_tree_uuid); |
932 |
return (u8 *)((unsigned long)dev + ptr); |
933 |
} |
934 |
|
935 |
/* struct btrfs_extent_ref */ |
936 |
BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64); |
937 |
BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64); |
938 |
BTRFS_SETGET_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64); |
939 |
BTRFS_SETGET_FUNCS(ref_num_refs, struct btrfs_extent_ref, num_refs, 32); |
940 |
|
941 |
BTRFS_SETGET_STACK_FUNCS(stack_ref_root, struct btrfs_extent_ref, root, 64); |
942 |
BTRFS_SETGET_STACK_FUNCS(stack_ref_generation, struct btrfs_extent_ref, |
943 |
generation, 64); |
944 |
BTRFS_SETGET_STACK_FUNCS(stack_ref_objectid, struct btrfs_extent_ref, |
945 |
objectid, 64); |
946 |
BTRFS_SETGET_STACK_FUNCS(stack_ref_num_refs, struct btrfs_extent_ref, |
947 |
num_refs, 32); |
948 |
|
949 |
/* struct btrfs_extent_item */ |
950 |
BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); |
951 |
BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item, |
952 |
refs, 32); |
953 |
|
954 |
/* struct btrfs_node */ |
955 |
BTRFS_SETGET_FUNCS(key_blockptr, struct btrfs_key_ptr, blockptr, 64); |
956 |
BTRFS_SETGET_FUNCS(key_generation, struct btrfs_key_ptr, generation, 64); |
957 |
|
958 |
static inline u64 btrfs_node_blockptr(struct extent_buffer *eb, int nr) |
959 |
{ |
960 |
unsigned long ptr; |
961 |
ptr = offsetof(struct btrfs_node, ptrs) + |
962 |
sizeof(struct btrfs_key_ptr) * nr; |
963 |
return btrfs_key_blockptr(eb, (struct btrfs_key_ptr *)ptr); |
964 |
} |
965 |
|
966 |
static inline void btrfs_set_node_blockptr(struct extent_buffer *eb, |
967 |
int nr, u64 val) |
968 |
{ |
969 |
unsigned long ptr; |
970 |
ptr = offsetof(struct btrfs_node, ptrs) + |
971 |
sizeof(struct btrfs_key_ptr) * nr; |
972 |
btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); |
973 |
} |
974 |
|
975 |
static inline u64 btrfs_node_ptr_generation(struct extent_buffer *eb, int nr) |
976 |
{ |
977 |
unsigned long ptr; |
978 |
ptr = offsetof(struct btrfs_node, ptrs) + |
979 |
sizeof(struct btrfs_key_ptr) * nr; |
980 |
return btrfs_key_generation(eb, (struct btrfs_key_ptr *)ptr); |
981 |
} |
982 |
|
983 |
static inline void btrfs_set_node_ptr_generation(struct extent_buffer *eb, |
984 |
int nr, u64 val) |
985 |
{ |
986 |
unsigned long ptr; |
987 |
ptr = offsetof(struct btrfs_node, ptrs) + |
988 |
sizeof(struct btrfs_key_ptr) * nr; |
989 |
btrfs_set_key_generation(eb, (struct btrfs_key_ptr *)ptr, val); |
990 |
} |
991 |
|
992 |
static inline unsigned long btrfs_node_key_ptr_offset(int nr) |
993 |
{ |
994 |
return offsetof(struct btrfs_node, ptrs) + |
995 |
sizeof(struct btrfs_key_ptr) * nr; |
996 |
} |
997 |
|
998 |
static inline void btrfs_node_key(struct extent_buffer *eb, |
999 |
struct btrfs_disk_key *disk_key, int nr) |
1000 |
{ |
1001 |
unsigned long ptr; |
1002 |
ptr = btrfs_node_key_ptr_offset(nr); |
1003 |
read_eb_member(eb, (struct btrfs_key_ptr *)ptr, |
1004 |
struct btrfs_key_ptr, key, disk_key); |
1005 |
} |
1006 |
|
1007 |
/* struct btrfs_item */ |
1008 |
BTRFS_SETGET_FUNCS(item_offset, struct btrfs_item, offset, 32); |
1009 |
BTRFS_SETGET_FUNCS(item_size, struct btrfs_item, size, 32); |
1010 |
|
1011 |
static inline unsigned long btrfs_item_nr_offset(int nr) |
1012 |
{ |
1013 |
return offsetof(struct btrfs_leaf, items) + |
1014 |
sizeof(struct btrfs_item) * nr; |
1015 |
} |
1016 |
|
1017 |
static inline struct btrfs_item *btrfs_item_nr(struct extent_buffer *eb, |
1018 |
int nr) |
1019 |
{ |
1020 |
return (struct btrfs_item *)btrfs_item_nr_offset(nr); |
1021 |
} |
1022 |
|
1023 |
static inline u32 btrfs_item_end(struct extent_buffer *eb, |
1024 |
struct btrfs_item *item) |
1025 |
{ |
1026 |
return btrfs_item_offset(eb, item) + btrfs_item_size(eb, item); |
1027 |
} |
1028 |
|
1029 |
static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) |
1030 |
{ |
1031 |
return btrfs_item_end(eb, btrfs_item_nr(eb, nr)); |
1032 |
} |
1033 |
|
1034 |
static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) |
1035 |
{ |
1036 |
return btrfs_item_offset(eb, btrfs_item_nr(eb, nr)); |
1037 |
} |
1038 |
|
1039 |
static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) |
1040 |
{ |
1041 |
return btrfs_item_size(eb, btrfs_item_nr(eb, nr)); |
1042 |
} |
1043 |
|
1044 |
static inline void btrfs_item_key(struct extent_buffer *eb, |
1045 |
struct btrfs_disk_key *disk_key, int nr) |
1046 |
{ |
1047 |
struct btrfs_item *item = btrfs_item_nr(eb, nr); |
1048 |
read_eb_member(eb, item, struct btrfs_item, key, disk_key); |
1049 |
} |
1050 |
|
1051 |
/* |
1052 |
* struct btrfs_root_ref |
1053 |
*/ |
1054 |
BTRFS_SETGET_FUNCS(root_ref_dirid, struct btrfs_root_ref, dirid, 64); |
1055 |
BTRFS_SETGET_FUNCS(root_ref_sequence, struct btrfs_root_ref, sequence, 64); |
1056 |
BTRFS_SETGET_FUNCS(root_ref_name_len, struct btrfs_root_ref, name_len, 16); |
1057 |
|
1058 |
/* struct btrfs_dir_item */ |
1059 |
BTRFS_SETGET_FUNCS(dir_data_len, struct btrfs_dir_item, data_len, 16); |
1060 |
BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); |
1061 |
BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); |
1062 |
BTRFS_SETGET_FUNCS(dir_transid, struct btrfs_dir_item, transid, 64); |
1063 |
|
1064 |
static inline void btrfs_dir_item_key(struct extent_buffer *eb, |
1065 |
struct btrfs_dir_item *item, |
1066 |
struct btrfs_disk_key *key) |
1067 |
{ |
1068 |
read_eb_member(eb, item, struct btrfs_dir_item, location, key); |
1069 |
} |
1070 |
|
1071 |
/* struct btrfs_disk_key */ |
1072 |
BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key, |
1073 |
objectid, 64); |
1074 |
BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64); |
1075 |
BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8); |
1076 |
|
1077 |
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, |
1078 |
struct btrfs_disk_key *disk) |
1079 |
{ |
1080 |
cpu->offset = le64_to_cpu(disk->offset); |
1081 |
cpu->type = disk->type; |
1082 |
cpu->objectid = le64_to_cpu(disk->objectid); |
1083 |
} |
1084 |
|
1085 |
static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, |
1086 |
struct btrfs_key *cpu) |
1087 |
{ |
1088 |
disk->offset = cpu_to_le64(cpu->offset); |
1089 |
disk->type = cpu->type; |
1090 |
disk->objectid = cpu_to_le64(cpu->objectid); |
1091 |
} |
1092 |
|
1093 |
static inline void btrfs_node_key_to_cpu(struct extent_buffer *eb, |
1094 |
struct btrfs_key *key, int nr) |
1095 |
{ |
1096 |
struct btrfs_disk_key disk_key; |
1097 |
btrfs_node_key(eb, &disk_key, nr); |
1098 |
btrfs_disk_key_to_cpu(key, &disk_key); |
1099 |
} |
1100 |
|
1101 |
static inline void btrfs_item_key_to_cpu(struct extent_buffer *eb, |
1102 |
struct btrfs_key *key, int nr) |
1103 |
{ |
1104 |
struct btrfs_disk_key disk_key; |
1105 |
btrfs_item_key(eb, &disk_key, nr); |
1106 |
btrfs_disk_key_to_cpu(key, &disk_key); |
1107 |
} |
1108 |
|
1109 |
static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, |
1110 |
struct btrfs_dir_item *item, |
1111 |
struct btrfs_key *key) |
1112 |
{ |
1113 |
struct btrfs_disk_key disk_key; |
1114 |
btrfs_dir_item_key(eb, item, &disk_key); |
1115 |
btrfs_disk_key_to_cpu(key, &disk_key); |
1116 |
} |
1117 |
|
1118 |
static inline u8 btrfs_key_type(struct btrfs_key *key) |
1119 |
{ |
1120 |
return key->type; |
1121 |
} |
1122 |
|
1123 |
static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val) |
1124 |
{ |
1125 |
key->type = val; |
1126 |
} |
1127 |
|
1128 |
static inline u64 btrfs_super_devid(struct btrfs_super_block *disk_super) |
1129 |
{ |
1130 |
return le64_to_cpu(disk_super->dev_item.devid); |
1131 |
} |
1132 |
|
1133 |
/* struct btrfs_header */ |
1134 |
BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64); |
1135 |
BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header, |
1136 |
generation, 64); |
1137 |
BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64); |
1138 |
BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32); |
1139 |
BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64); |
1140 |
BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8); |
1141 |
|
1142 |
/* struct btrfs_root_item */ |
1143 |
BTRFS_SETGET_FUNCS(disk_root_generation, struct btrfs_root_item, |
1144 |
generation, 64); |
1145 |
BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); |
1146 |
BTRFS_SETGET_FUNCS(disk_root_bytenr, struct btrfs_root_item, bytenr, 64); |
1147 |
BTRFS_SETGET_FUNCS(disk_root_level, struct btrfs_root_item, level, 8); |
1148 |
|
1149 |
BTRFS_SETGET_STACK_FUNCS(root_generation, struct btrfs_root_item, |
1150 |
generation, 64); |
1151 |
BTRFS_SETGET_STACK_FUNCS(root_bytenr, struct btrfs_root_item, bytenr, 64); |
1152 |
BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); |
1153 |
BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); |
1154 |
BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); |
1155 |
BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 64); |
1156 |
BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); |
1157 |
BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); |
1158 |
BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, |
1159 |
last_snapshot, 64); |
1160 |
|
1161 |
/* struct btrfs_super_block */ |
1162 |
|
1163 |
BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); |
1164 |
BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64); |
1165 |
BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, |
1166 |
generation, 64); |
1167 |
BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); |
1168 |
BTRFS_SETGET_STACK_FUNCS(super_sys_array_size, |
1169 |
struct btrfs_super_block, sys_chunk_array_size, 32); |
1170 |
BTRFS_SETGET_STACK_FUNCS(super_chunk_root_generation, |
1171 |
struct btrfs_super_block, chunk_root_generation, 64); |
1172 |
BTRFS_SETGET_STACK_FUNCS(super_root_level, struct btrfs_super_block, |
1173 |
root_level, 8); |
1174 |
BTRFS_SETGET_STACK_FUNCS(super_chunk_root, struct btrfs_super_block, |
1175 |
chunk_root, 64); |
1176 |
BTRFS_SETGET_STACK_FUNCS(super_chunk_root_level, struct btrfs_super_block, |
1177 |
chunk_root_level, 8); |
1178 |
BTRFS_SETGET_STACK_FUNCS(super_log_root, struct btrfs_super_block, |
1179 |
log_root, 64); |
1180 |
BTRFS_SETGET_STACK_FUNCS(super_log_root_transid, struct btrfs_super_block, |
1181 |
log_root_transid, 64); |
1182 |
BTRFS_SETGET_STACK_FUNCS(super_log_root_level, struct btrfs_super_block, |
1183 |
log_root_level, 8); |
1184 |
BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block, |
1185 |
total_bytes, 64); |
1186 |
BTRFS_SETGET_STACK_FUNCS(super_bytes_used, struct btrfs_super_block, |
1187 |
bytes_used, 64); |
1188 |
BTRFS_SETGET_STACK_FUNCS(super_sectorsize, struct btrfs_super_block, |
1189 |
sectorsize, 32); |
1190 |
BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, |
1191 |
nodesize, 32); |
1192 |
BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, |
1193 |
leafsize, 32); |
1194 |
BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block, |
1195 |
stripesize, 32); |
1196 |
BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, |
1197 |
root_dir_objectid, 64); |
1198 |
BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block, |
1199 |
num_devices, 64); |
1200 |
BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block, |
1201 |
compat_flags, 64); |
1202 |
BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block, |
1203 |
compat_flags, 64); |
1204 |
BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, |
1205 |
incompat_flags, 64); |
1206 |
BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block, |
1207 |
csum_type, 16); |
1208 |
|
1209 |
static inline int btrfs_super_csum_size(struct btrfs_super_block *s) |
1210 |
{ |
1211 |
int t = btrfs_super_csum_type(s); |
1212 |
//BUG_ON(t >= ARRAY_SIZE(btrfs_csum_sizes)); |
1213 |
return btrfs_csum_sizes[t]; |
1214 |
} |
1215 |
|
1216 |
static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) |
1217 |
{ |
1218 |
return offsetof(struct btrfs_leaf, items); |
1219 |
} |
1220 |
|
1221 |
/* struct btrfs_file_extent_item */ |
1222 |
BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); |
1223 |
|
1224 |
static inline unsigned long btrfs_file_extent_inline_start(struct |
1225 |
btrfs_file_extent_item *e) |
1226 |
{ |
1227 |
unsigned long offset = (unsigned long)e; |
1228 |
offset += offsetof(struct btrfs_file_extent_item, disk_bytenr); |
1229 |
return offset; |
1230 |
} |
1231 |
|
1232 |
static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) |
1233 |
{ |
1234 |
return offsetof(struct btrfs_file_extent_item, disk_bytenr) + datasize; |
1235 |
} |
1236 |
|
1237 |
BTRFS_SETGET_FUNCS(file_extent_disk_bytenr, struct btrfs_file_extent_item, |
1238 |
disk_bytenr, 64); |
1239 |
BTRFS_SETGET_FUNCS(file_extent_generation, struct btrfs_file_extent_item, |
1240 |
generation, 64); |
1241 |
BTRFS_SETGET_FUNCS(file_extent_disk_num_bytes, struct btrfs_file_extent_item, |
1242 |
disk_num_bytes, 64); |
1243 |
BTRFS_SETGET_FUNCS(file_extent_offset, struct btrfs_file_extent_item, |
1244 |
offset, 64); |
1245 |
BTRFS_SETGET_FUNCS(file_extent_num_bytes, struct btrfs_file_extent_item, |
1246 |
num_bytes, 64); |
1247 |
BTRFS_SETGET_FUNCS(file_extent_ram_bytes, struct btrfs_file_extent_item, |
1248 |
ram_bytes, 64); |
1249 |
BTRFS_SETGET_FUNCS(file_extent_compression, struct btrfs_file_extent_item, |
1250 |
compression, 8); |
1251 |
BTRFS_SETGET_FUNCS(file_extent_encryption, struct btrfs_file_extent_item, |
1252 |
encryption, 8); |
1253 |
BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, |
1254 |
other_encoding, 16); |
1255 |
|
1256 |
/* this returns the number of file bytes represented by the inline item. |
1257 |
* If an item is compressed, this is the uncompressed size |
1258 |
*/ |
1259 |
static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, |
1260 |
struct btrfs_file_extent_item *e) |
1261 |
{ |
1262 |
return btrfs_file_extent_ram_bytes(eb, e); |
1263 |
} |
1264 |
|
1265 |
/* |
1266 |
* this returns the number of bytes used by the item on disk, minus the |
1267 |
* size of any extent headers. If a file is compressed on disk, this is |
1268 |
* the compressed size |
1269 |
*/ |
1270 |
static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, |
1271 |
struct btrfs_item *e) |
1272 |
{ |
1273 |
unsigned long offset; |
1274 |
offset = offsetof(struct btrfs_file_extent_item, disk_bytenr); |
1275 |
return btrfs_item_size(eb, e) - offset; |
1276 |
} |
1277 |
|
1278 |
static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { |
1279 |
if (level == 0) |
1280 |
return root->leafsize; |
1281 |
return root->nodesize; |
1282 |
} |
1283 |
|
1284 |
static inline u32 btrfs_root_level_size(struct btrfs_super_block *sb) { |
1285 |
return btrfs_super_root_level(sb) == 0 ? |
1286 |
btrfs_super_leafsize(sb) : |
1287 |
btrfs_super_nodesize(sb); |
1288 |
} |
1289 |
|
1290 |
static inline u32 btrfs_chunk_root_level_size(struct btrfs_super_block *sb) { |
1291 |
return btrfs_super_chunk_root_level(sb) == 0 ? |
1292 |
btrfs_super_leafsize(sb) : |
1293 |
btrfs_super_nodesize(sb); |
1294 |
} |
1295 |
|
1296 |
/* helper function to cast into the data area of the leaf. */ |
1297 |
#define btrfs_item_ptr(leaf, slot, type) \ |
1298 |
((type *)(btrfs_leaf_data(leaf) + \ |
1299 |
btrfs_item_offset_nr(leaf, slot))) |
1300 |
|
1301 |
#define btrfs_item_ptr_offset(leaf, slot) \ |
1302 |
((unsigned long)(btrfs_leaf_data(leaf) + \ |
1303 |
btrfs_item_offset_nr(leaf, slot))) |
1304 |
|
1305 |
/*volumes.h */ |
1306 |
|
1307 |
struct btrfs_fs_devices { |
1308 |
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ |
1309 |
|
1310 |
/* the device with this id has the most recent coyp of the super */ |
1311 |
u64 latest_devid; |
1312 |
u64 latest_trans; |
1313 |
u64 lowest_devid; |
1314 |
int latest_bdev; |
1315 |
int lowest_bdev; |
1316 |
int seeding; |
1317 |
struct btrfs_fs_devices *seed; |
1318 |
}; |
1319 |
|
1320 |
struct btrfs_bio_stripe { |
1321 |
struct btrfs_device dev; |
1322 |
u64 physical; |
1323 |
}; |
1324 |
|
1325 |
#define MAX_NRSTRIPES 8 |
1326 |
struct btrfs_multi_bio { |
1327 |
int error; |
1328 |
int num_stripes; |
1329 |
struct btrfs_bio_stripe stripes[MAX_NRSTRIPES]; |
1330 |
}; |
1331 |
|
1332 |
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \ |
1333 |
(sizeof(struct btrfs_bio_stripe) * (n))) |
1334 |
|
1335 |
static int aux_tree_lookup(struct btrfs_root *root, |
1336 |
struct btrfs_key *key, |
1337 |
struct btrfs_path *path); |
1338 |
|
1339 |
struct cache_extent { |
1340 |
u64 start; |
1341 |
u64 size; |
1342 |
}; |
1343 |
|
1344 |
struct map_lookup { |
1345 |
struct cache_extent ce; |
1346 |
u64 type; |
1347 |
int io_align; |
1348 |
int io_width; |
1349 |
int stripe_len; |
1350 |
int sector_size; |
1351 |
int num_stripes; |
1352 |
int sub_stripes; |
1353 |
struct btrfs_bio_stripe stripes[MAX_NRSTRIPES]; |
1354 |
}; |
1355 |
|
1356 |
/* "VFS" things */ |
1357 |
|
1358 |
/* file types recognized by grub */ |
1359 |
typedef enum { |
1360 |
BTRFS_REGULAR_FILE, |
1361 |
BTRFS_DIRECTORY_FILE, |
1362 |
BTRFS_SYMLINK_FILE, |
1363 |
BTRFS_UNKNOWN_FILE |
1364 |
} btrfs_file_type; |
1365 |
|
1366 |
static inline int coord_is_root(struct btrfs_root *root, |
1367 |
struct btrfs_path *path) |
1368 |
{ |
1369 |
return btrfs_header_bytenr(&path->nodes[0]) == |
1370 |
btrfs_header_bytenr(&root->node); |
1371 |
} |
1372 |
|
1373 |
static inline btrfs_file_type btrfs_get_file_type (int mode) |
1374 |
{ |
1375 |
if (S_ISLNK(mode)) |
1376 |
return BTRFS_SYMLINK_FILE; |
1377 |
if (S_ISREG(mode)) |
1378 |
return BTRFS_REGULAR_FILE; |
1379 |
if (S_ISDIR(mode)) |
1380 |
return BTRFS_DIRECTORY_FILE; |
1381 |
return BTRFS_UNKNOWN_FILE; |
1382 |
} |
1383 |
|
1384 |
#define min_t(type,x,y) \ |
1385 |
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) |
1386 |
#define max_t(type,x,y) \ |
1387 |
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) |
1388 |
|
1389 |
|
1390 |
int sys_array_lookup(struct map_lookup *map, u64 logical); |
1391 |
int tree_chunk_lookup(struct map_lookup *map, |
1392 |
u64 logical); |
1393 |
int __btrfs_map_block(u64 logical, u64 *length, |
1394 |
struct btrfs_multi_bio *multi_ret, int mirror_num); |
1395 |
int read_tree_block(struct btrfs_root *root, |
1396 |
struct extent_buffer *eb, |
1397 |
u64 bytenr, /* logical */ |
1398 |
u32 blocksize, |
1399 |
u64 parent_transid, |
1400 |
lookup_pool_id lpid); |
1401 |
int check_read_chunk(struct btrfs_key *key, |
1402 |
struct extent_buffer *leaf, |
1403 |
struct btrfs_chunk *chunk, |
1404 |
struct map_lookup *map, |
1405 |
u64 logical); |
1406 |
/* |
1407 |
Local variables: |
1408 |
c-indentation-style: "K&R" |
1409 |
mode-name: "LC" |
1410 |
c-basic-offset: 8 |
1411 |
tab-width: 8 |
1412 |
fill-column: 80 |
1413 |
scroll-step: 1 |
1414 |
End: |
1415 |
*/ |