Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 283637 | Differences between
and this patch

Collapse All | Expand All

(-)grub-0.97-r9/AUTHORS (+2 lines)
Lines 41-46 Link Here
41
41
42
Serguei Tzukanov added JFS and XFS support.
42
Serguei Tzukanov added JFS and XFS support.
43
43
44
Edward Shishkin added Btrfs support.
45
44
Jason Thomas added Linux DAC960 support and support for hiding/unhiding
46
Jason Thomas added Linux DAC960 support and support for hiding/unhiding
45
logical partitions, and did a significant bugfix for the terminal stuff.
47
logical partitions, and did a significant bugfix for the terminal stuff.
46
48
(-)grub-0.97-r9/configure.ac (+7 lines)
Lines 269-274 Link Here
269
  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_REISERFS=1"
269
  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_REISERFS=1"
270
fi
270
fi
271
271
272
AC_ARG_ENABLE(btrfs,
273
  [  --disable-btrfs         disable BtrFS support in Stage 2])
274
275
if test x"$enable_btrfs" != xno; then
276
  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_BTRFS=1"
277
fi
278
272
AC_ARG_ENABLE(vstafs,
279
AC_ARG_ENABLE(vstafs,
273
  [  --disable-vstafs        disable VSTa FS support in Stage 2])
280
  [  --disable-vstafs        disable VSTa FS support in Stage 2])
274
281
(-)grub-0.97-r9/docs/grub.texi (+1 lines)
Lines 1761-1766 Link Here
1761
@itemx jfs_stage1_5
1761
@itemx jfs_stage1_5
1762
@itemx minix_stage1_5
1762
@itemx minix_stage1_5
1763
@itemx reiserfs_stage1_5
1763
@itemx reiserfs_stage1_5
1764
@itemx btrfs_stage1_5
1764
@itemx vstafs_stage1_5
1765
@itemx vstafs_stage1_5
1765
@itemx xfs_stage1_5
1766
@itemx xfs_stage1_5
1766
1767
(-)grub-0.97-r9/grub/Makefile.am (-1 / +1 lines)
Lines 8-14 Link Here
8
8
9
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
9
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
10
	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
10
	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
11
	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
11
	-DFSYS_BTRFS=1 -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
12
	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
12
	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
13
	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
13
	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
14
	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
14
	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
(-)grub-0.97-r9/INSTALL (+3 lines)
Lines 207-212 Link Here
207
`--disable-reiserfs'
207
`--disable-reiserfs'
208
     Omit the ReiserFS support in Stage 2.
208
     Omit the ReiserFS support in Stage 2.
209
209
210
`--disable-btrfs'
211
     Omit the BtrFS support in Stage 2.
212
210
`--disable-vstafs'
213
`--disable-vstafs'
211
     Omit the VSTa filesystem support in Stage 2.
214
     Omit the VSTa filesystem support in Stage 2.
212
215
(-)grub-0.97-r9/stage2/btrfs.h (+1415 lines)
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
*/
(-)grub-0.97-r9/stage2/builtins.c (+11 lines)
Lines 2370-2375 Link Here
2370
	  else
2370
	  else
2371
#endif /* GRUB_UTIL */
2371
#endif /* GRUB_UTIL */
2372
	    {
2372
	    {
2373
	      /*
2374
+	       * FIXME: Ugly hack.
2375
+	       * Do not write to btrfs partition
2376
+	       * without a help of the file system!
2377
+	       */
2378
	      if (!strcmp(fsys_table[fsys_type].name, "btrfs"))
2379
		{
2380
		  errnum = ERR_BAD_ARGUMENT;
2381
		  goto fail;
2382
		}
2373
	      if (! devwrite (*saved_sector - part_start, 1, stage2_buffer))
2383
	      if (! devwrite (*saved_sector - part_start, 1, stage2_buffer))
2374
		goto fail;
2384
		goto fail;
2375
	    }
2385
	    }
Lines 4077-4082 Link Here
4077
    {"jfs",      "/jfs_stage1_5"},
4087
    {"jfs",      "/jfs_stage1_5"},
4078
    {"minix",    "/minix_stage1_5"},
4088
    {"minix",    "/minix_stage1_5"},
4079
    {"reiserfs", "/reiserfs_stage1_5"},
4089
    {"reiserfs", "/reiserfs_stage1_5"},
4090
    {"btrfs",    "/btrfs_stage1_5"},
4080
    {"vstafs",   "/vstafs_stage1_5"},
4091
    {"vstafs",   "/vstafs_stage1_5"},
4081
    {"xfs",      "/xfs_stage1_5"}
4092
    {"xfs",      "/xfs_stage1_5"}
4082
  };
4093
  };
(-)grub-0.97-r9/stage2/disk_io.c (+3 lines)
Lines 79-84 Link Here
79
# ifdef FSYS_ISO9660
79
# ifdef FSYS_ISO9660
80
  {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0},
80
  {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0},
81
# endif
81
# endif
82
# ifdef FSYS_BTRFS
83
  {"btrfs", btrfs_mount, btrfs_read, btrfs_dir, 0, btrfs_embed},
84
# endif
82
  /* XX FFS should come last as it's superblock is commonly crossing tracks
85
  /* XX FFS should come last as it's superblock is commonly crossing tracks
83
     on floppies from track 1 to 2, while others only use 1.  */
86
     on floppies from track 1 to 2, while others only use 1.  */
84
# ifdef FSYS_FFS
87
# ifdef FSYS_FFS
(-)grub-0.97-r9/stage2/filesys.h (-2 / +12 lines)
Lines 77-82 Link Here
77
#define FSYS_REISERFS_NUM 0
77
#define FSYS_REISERFS_NUM 0
78
#endif
78
#endif
79
79
80
#ifdef FSYS_BTRFS
81
#define FSYS_BTRFS_NUM 1
82
int btrfs_mount (void);
83
int btrfs_read (char *buf, int len);
84
int btrfs_dir (char *dirname);
85
int btrfs_embed (int *start_sector, int needed_sectors);
86
#else
87
#define FSYS_BTRFS_NUM 0
88
#endif
89
80
#ifdef FSYS_VSTAFS
90
#ifdef FSYS_VSTAFS
81
#define FSYS_VSTAFS_NUM 1
91
#define FSYS_VSTAFS_NUM 1
82
int vstafs_mount (void);
92
int vstafs_mount (void);
Lines 127-134 Link Here
127
#ifndef NUM_FSYS
137
#ifndef NUM_FSYS
128
#define NUM_FSYS	\
138
#define NUM_FSYS	\
129
  (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
139
  (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
130
   + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
140
   + FSYS_REISERFS_NUM + FSYS_BTRFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM \
131
   + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
141
   + FSYS_XFS_NUM + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
132
#endif
142
#endif
133
143
134
/* defines for the block filesystem info area */
144
/* defines for the block filesystem info area */
(-)grub-0.97-r9/stage2/fsys_btrfs.c (+1820 lines)
Line 0 Link Here
1
/* fsys_btrfs.c - an implementation for the Btrfs filesystem
2
 *
3
 * Copyright 2009 Red Hat, Inc.  All rights reserved.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#ifdef FSYS_BTRFS
20
21
#include "shared.h"
22
#include "filesys.h"
23
#include "btrfs.h"
24
25
#define BTRFS_VERBOSE 0
26
27
/* Cache layouts */
28
29
#define LOOKUP_CACHE_BUF_SIZE   (4096)
30
#define LOOKUP_CACHE_SIZE       (LOOKUP_CACHE_BUF_SIZE * LAST_LOOKUP_POOL)
31
#define BTRFS_FS_INFO							\
32
	((struct btrfs_fs_info *)((unsigned long)FSYS_BUF +		\
33
				  LOOKUP_CACHE_SIZE))
34
#define BTRFS_CACHE_SIZE         (sizeof(struct btrfs_fs_info) +	\
35
				  LOOKUP_CACHE_SIZE)
36
#define BTRFS_TREE_ROOT          (&BTRFS_FS_INFO->tree_root)
37
#define BTRFS_CHUNK_ROOT         (&BTRFS_FS_INFO->chunk_root)
38
#define BTRFS_FS_ROOT            (&BTRFS_FS_INFO->fs_root)
39
#define BTRFS_SUPER              (&BTRFS_FS_INFO->sb_copy)
40
#define BTRFS_DEVICES            (&BTRFS_FS_INFO->devices[0])
41
#define BTRFS_FILE_INFO          (&BTRFS_FS_INFO->file_info)
42
#define BTRFS_FILE_INFO_KEY      (&BTRFS_FILE_INFO->key)
43
44
#define BTRFS_VOLATILE_DEV_CACHE				        \
45
	(&BTRFS_FS_INFO->devices[BTRFS_NUM_CACHED_DEVICES])
46
47
#define LOOKUP_CACHE_BUF(id) ((char *)((unsigned long)FSYS_BUF +	\
48
				       id * LOOKUP_CACHE_BUF_SIZE))
49
50
#define noop   do {; } while (0)
51
52
#if BTRFS_VERBOSE
53
#define btrfs_msg(format, ...) printf(format , ## __VA_ARGS__)
54
#else
55
#define btrfs_msg(format, args...) noop
56
#endif
57
58
/* compile-time check to make sure we don't overlap
59
   filesystem buffer */
60
static inline void check_btrfs_cache_size(void)
61
{
62
	cassert(BTRFS_CACHE_SIZE <= FSYS_BUFLEN);
63
}
64
65
static inline u64 btrfs_sb_offset(int mirror)
66
{
67
	u64 start = 16 * 1024;
68
	if (mirror)
69
		return start << (BTRFS_SUPER_MIRROR_SHIFT * mirror);
70
	return BTRFS_SUPER_INFO_OFFSET;
71
}
72
73
static inline char *grab_lookup_cache(lookup_pool_id lpid)
74
{
75
	char *buf = LOOKUP_CACHE_BUF(lpid);
76
	memset(buf, 0, LOOKUP_CACHE_BUF_SIZE);
77
	return buf;
78
}
79
80
static inline struct btrfs_path *btrfs_grab_path(lookup_pool_id lpid)
81
{
82
	return &BTRFS_FS_INFO->paths[lpid];
83
}
84
85
static inline void btrfs_set_path_key(struct btrfs_path *path,
86
				      struct btrfs_key *key)
87
{
88
	btrfs_item_key_to_cpu(&path->nodes[0],
89
			      key,
90
			      path->slots[0]);
91
}
92
93
static inline void btrfs_update_file_info(struct btrfs_path *path)
94
{
95
	btrfs_set_path_key(path, BTRFS_FILE_INFO_KEY);
96
}
97
98
static inline void btrfs_set_root_dir_key(struct btrfs_key *key)
99
{
100
	key->objectid = BTRFS_FIRST_FREE_OBJECTID;
101
	btrfs_set_key_type(key, BTRFS_INODE_ITEM_KEY);
102
	key->offset = 0;
103
}
104
105
static inline void copy_extent_buffer(struct extent_buffer *dst,
106
				      struct extent_buffer *src)
107
{
108
	char *data = dst->data;
109
	memcpy(dst, src, sizeof(*dst));
110
	memcpy(data, src->data, 4096);
111
	dst->data = data;
112
}
113
114
static inline void move_extent_buffer(struct extent_buffer *dst,
115
				      struct extent_buffer *src)
116
{
117
	memcpy(dst, src, sizeof(*dst));
118
}
119
120
static inline void init_btrfs_root (struct btrfs_root *root)
121
{
122
	root->node.data = root->data;
123
}
124
125
static inline void init_btrfs_path(lookup_pool_id lpid)
126
{
127
	struct btrfs_path *path;
128
	path = btrfs_grab_path(lpid);
129
	path->lpid = lpid;
130
}
131
132
static inline void init_btrfs_info(void)
133
{
134
	int i;
135
	
136
	memset(BTRFS_FS_INFO, 0, sizeof(struct btrfs_fs_info));
137
	for(i = 0; i < LAST_LOOKUP_POOL; i++)
138
		init_btrfs_path(i);
139
	init_btrfs_root(BTRFS_TREE_ROOT);
140
	init_btrfs_root(BTRFS_CHUNK_ROOT);
141
	init_btrfs_root(BTRFS_FS_ROOT);
142
}
143
144
static void setup_root(struct btrfs_root *root,
145
		       u32 nodesize,
146
		       u32 leafsize,
147
		       u32 sectorsize,
148
		       u32 stripesize,
149
		       u64 objectid)
150
{
151
	root->nodesize = nodesize;
152
	root->leafsize = leafsize;
153
	root->sectorsize = sectorsize;
154
	root->stripesize = stripesize;
155
	root->objectid = objectid;
156
}
157
158
/*
159
 * Pick up the latest root of a
160
 * tree with specified @objectid
161
 */
162
static int btrfs_find_last_root(struct btrfs_root *tree_root,
163
				u64 objectid,
164
				struct btrfs_root_item *item,
165
				lookup_pool_id lpid)
166
{
167
	int ret;
168
	int slot;
169
	struct btrfs_key search_key;
170
	struct btrfs_key found_key;
171
	struct btrfs_path *path;
172
173
	search_key.objectid = objectid;
174
	search_key.type = BTRFS_ROOT_ITEM_KEY;
175
	search_key.offset = (u64)-1;
176
	path = btrfs_grab_path(lpid);
177
178
	ret = aux_tree_lookup(tree_root, &search_key, path);
179
	if (ret < 0)
180
		return 1;
181
	slot = path->slots[0];
182
	WARN_ON(slot == 0);
183
	slot -= 1;
184
	btrfs_item_key_to_cpu(&path->nodes[0], &found_key, slot);
185
	if (found_key.objectid != objectid)
186
		return 1;
187
	
188
	read_extent_buffer(&path->nodes[0], item,
189
			   btrfs_item_ptr_offset(&path->nodes[0], slot),
190
			   sizeof(*item));
191
	return 0;
192
}
193
194
static int find_setup_root(struct btrfs_root *tree_root,
195
			   u32 nodesize,
196
			   u32 leafsize,
197
			   u32 sectorsize,
198
			   u32 stripesize,
199
			   u64 objectid,
200
			   struct btrfs_root *dest_root,
201
			   u64 bytenr,
202
			   u32 blocksize,
203
			   u64 generation,
204
			   lookup_pool_id lpid)
205
{
206
	int ret;
207
	struct extent_buffer eb;
208
209
	setup_root(dest_root,
210
		   nodesize,
211
		   leafsize,
212
		   sectorsize,
213
		   stripesize,
214
		   objectid);
215
	if (tree_root) {
216
		/*
217
		 * pick up the latest version
218
		 * of the root we want to set up
219
		 */
220
		ret = btrfs_find_last_root(tree_root, objectid,
221
					   &dest_root->root_item,
222
					   lpid);
223
		if (ret)
224
			return ret;
225
		bytenr = btrfs_root_bytenr(&dest_root->root_item);
226
		blocksize = btrfs_level_size(dest_root,
227
				       btrfs_root_level(&dest_root->root_item));
228
		generation = btrfs_root_generation(&dest_root->root_item);
229
	}
230
	ret = read_tree_block(dest_root,
231
			      &eb,
232
			      bytenr,
233
			      blocksize,
234
			      generation,
235
			      lpid);
236
	if (!ret)
237
		return 1;
238
	copy_extent_buffer(&dest_root->node, &eb);
239
	return 0;
240
}
241
242
static inline int btrfs_strncmp(const char *cs, const char *ct, int count)
243
{
244
	signed char __res = 0;
245
246
	while (count) {
247
		if ((__res = *cs - *ct++) != 0 || !*cs++)
248
			break;
249
		count--;
250
	}
251
	return __res;
252
}
253
254
/*
255
 * the same as devread, but accepts
256
 * device number, start and length.
257
 */
258
static int btrfs_devread(unsigned long drive, unsigned long part,
259
			 unsigned long dev_len, int sector,
260
			 int byte_offset, int byte_len, char *buf)
261
{
262
	if (sector < 0
263
	    || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
264
		>= dev_len)) {
265
		errnum = ERR_OUTSIDE_PART;
266
		return 0;
267
	}
268
	sector += byte_offset >> SECTOR_BITS;
269
	byte_offset &= SECTOR_SIZE - 1;
270
#if !defined(STAGE1_5)
271
	if (disk_read_hook && debug)
272
		printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
273
#endif /* !STAGE1_5 */
274
	return rawread(drive, part + sector, byte_offset,
275
		       byte_len, buf);
276
}
277
278
static int btrfs_check_super(void)
279
{
280
	struct btrfs_super_block *sb = BTRFS_SUPER;
281
282
	if (sb->nodesize != BTRFS_DEFAULT_NODE_SIZE) {
283
		btrfs_msg("Btrfs node size (%d) != %d unsupported\n",
284
			  sb->nodesize, BTRFS_DEFAULT_NODE_SIZE);
285
		goto error;
286
	}
287
	if (sb->leafsize != BTRFS_DEFAULT_LEAF_SIZE) {
288
 	        btrfs_msg("Btrfs leaf size (%d) != %d unsupported\n",
289
			  sb->leafsize, BTRFS_DEFAULT_LEAF_SIZE);
290
		goto error;
291
	}
292
	
293
 	return 0;
294
error:
295
	return 1;
296
}
297
298
/* lift the super block */
299
static int btrfs_uptodate_super_copy(struct btrfs_fs_info *fs)
300
{
301
	errnum = ERR_NONE;
302
	btrfs_devread(BTRFS_FS_INFO->sb_dev.drive,
303
		      BTRFS_FS_INFO->sb_dev.part,
304
		      BTRFS_FS_INFO->sb_dev.length,
305
		      btrfs_sb_offset(BTRFS_FS_INFO->sb_mirror) >> SECTOR_BITS,
306
		      0,
307
		      sizeof(struct btrfs_super_block),
308
		      (char *)BTRFS_SUPER);
309
	return btrfs_check_super();
310
}
311
  
312
/*
313
 * Looking for a btrfs super block by magic, @fsid and @devid
314
 * (the last two ones are optional). Update latest transid (if
315
 * any). Return 0, if such super block was found. Otherwise,
316
 * return 1.
317
 *
318
 * NOTE:
319
 * After calling this function the sb_copy of global btrfs_fs_info
320
 * can contain garbage, so the caller is responsible for this to be
321
 * uptodate (see the function btrfs_uptodate_super_copy()).
322
 */
323
static int btrfs_find_super(struct btrfs_device *dev, char *fsid, u64 *devid)
324
{
325
	int i, ret;
326
	int found = 0;
327
328
	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
329
		ret = btrfs_devread(dev->drive,
330
				    dev->part,
331
				    dev->length,
332
				    btrfs_sb_offset(i) >> SECTOR_BITS,
333
				    0,
334
				    sizeof(struct btrfs_super_block),
335
				    (char *)BTRFS_SUPER);
336
		if (!ret) {
337
			if (errnum == ERR_OUTSIDE_PART) {
338
				errnum = ERR_NONE;
339
				break;
340
			} else {
341
				errnum = ERR_NONE;
342
				continue;
343
			}
344
		}
345
		if (btrfs_super_bytenr(BTRFS_SUPER) != btrfs_sb_offset(i) ||
346
		    btrfs_strncmp((char *)(&BTRFS_SUPER->magic),
347
				  BTRFS_MAGIC,
348
				  sizeof(BTRFS_SUPER->magic)))
349
			continue;
350
		if (fsid &&
351
		    btrfs_strncmp(fsid,
352
				  (char *)BTRFS_SUPER->fsid,
353
				  BTRFS_FSID_SIZE))
354
			return 1;
355
		if (devid &&
356
		    *devid != btrfs_super_devid(BTRFS_SUPER))
357
			return 1;
358
		found = 1;
359
		dev->devid = btrfs_super_devid(BTRFS_SUPER);
360
361
		if (btrfs_super_generation(BTRFS_SUPER) >
362
		    BTRFS_FS_INFO->sb_transid) {
363
			BTRFS_FS_INFO->sb_transid =
364
				btrfs_super_generation(BTRFS_SUPER);
365
			BTRFS_FS_INFO->sb_mirror = i;
366
			BTRFS_FS_INFO->sb_dev.devid =
367
				btrfs_super_devid(BTRFS_SUPER);
368
			BTRFS_FS_INFO->sb_dev.drive = dev->drive;
369
			BTRFS_FS_INFO->sb_dev.part = dev->part;
370
			BTRFS_FS_INFO->sb_dev.length = dev->length;
371
		}
372
	}
373
	return !found;
374
}
375
376
/*
377
 * "Discern" a btrfs device by fsid and
378
 * optionaly by devid (if lookup is set).
379
 * Populate persistent device cache (if
380
 * there are free slots).
381
 */
382
static int btrfs_discerner(struct btrfs_device **dev, int lookup)
383
{
384
	if (btrfs_find_super(*dev,
385
			     (char *)BTRFS_FS_INFO->fsid,
386
			     (lookup ? &(*dev)->devid : 0)))
387
		/* not found */
388
		return 0;
389
	if (*dev < BTRFS_VOLATILE_DEV_CACHE) {
390
		/* populate persistent device cache */
391
		memcpy(*dev + 1, *dev, sizeof(struct btrfs_device));
392
		(*dev)++;
393
	}
394
	return 1;
395
}
396
397
/*
398
 * Scan available grub devices and call discerner
399
 * for them. Return a number of discerned devices
400
 * The scanner was stolen from print_completions().
401
 *
402
 * Preconditions:
403
 * The global structure btrfs_fs_info contains
404
 * the latest valid version of btrfs superblock
405
 * (the field @sb_copy)
406
 */
407
static u64 scan_grub_devices(struct btrfs_device *dev,
408
			     int (*discerner)(struct btrfs_device **, int),
409
			     int lookup)
410
{
411
	int i, j;
412
	u64 count = 0;
413
	struct geometry geom;
414
415
	for (i = 0; i < 2; i++)
416
		for (j = 0; j < 8; j++) {
417
			unsigned long part = 0xFFFFFF;
418
			int type, entry, gpt_count, gpt_size;
419
			unsigned long offset, ext_offset, gpt_offset;
420
421
			dev->drive = (i * 0x80) + j;
422
			if (get_diskinfo(dev->drive, &geom))
423
				continue;
424
			while (1) {
425
				int ret;
426
				buf_drive = -1;
427
				errnum = ERR_NONE;
428
				ret = next_partition(dev->drive, 0xFFFFFF,
429
						     &part, &type, &dev->part,
430
						     &dev->length, &offset,
431
						     &entry, &ext_offset,
432
						     &gpt_offset, &gpt_count,
433
						     &gpt_size,
434
						     BTRFS_FS_INFO->mbr);
435
				if (!ret)
436
					break;
437
				if (discerner(&dev, lookup)) {
438
					count++;
439
					if (lookup)
440
						goto exit;
441
				}
442
			}
443
		}
444
#if 0
445
	errnum = ERR_NONE;
446
	if (cdrom_drive != GRUB_INVALID_DRIVE &&
447
	    !get_diskinfo(cdrom_drive, &geom)) {
448
		dev->drive = cdrom_drive;
449
		dev->part = 0;
450
		dev->length = geom.total_sectors;
451
		if (discerner(&dev, lookup)) {
452
			count++;
453
			if (lookup)
454
				goto exit;
455
		}
456
	}
457
#ifdef SUPPORT_NETBOOT
458
	errnum = ERR_NONE;
459
	if (network_ready &&
460
	    !get_diskinfo(NETWORK_DRIVE, &geom)) {
461
		dev->drive = NETWORK_DRIVE;
462
		dev->part = 0;
463
		dev->length = geom.total_sectors;
464
		if (discerner(&dev, lookup)) {
465
			count++;
466
			if (lookup)
467
				goto exit;
468
		}
469
	}
470
#endif /* SUPPORT_NETBOOT */
471
#endif /* 0 */
472
 exit:
473
	return count;
474
}
475
476
#if 0
477
static int btrfs_next_item(struct btrfs_root *root,
478
			   struct btrfs_path *path);
479
480
/*
481
 * Scan the chunk tree for dev items
482
 * and call a seeker for all of them.
483
 * Preconditions: chunk root is installed
484
 * to the global btrfs_fs_info.
485
 */
486
static int scan_dev_tree(struct btrfs_device* (*seeker)(u64))
487
{
488
	int ret;
489
	u64 num_devices = 0;
490
	struct btrfs_key key;
491
	struct btrfs_key found_key;
492
	struct btrfs_path *path;
493
	struct btrfs_root *root;
494
495
	root = BTRFS_CHUNK_ROOT;
496
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
497
	key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
498
	key.type = 0;
499
	key.offset = 0;
500
501
	ret = aux_tree_lookup(root, &key, path);
502
	if (ret == -1)
503
		goto corrupted;
504
	while (1) {
505
		struct btrfs_device *result;
506
		struct btrfs_dev_item *dev_item;
507
508
		btrfs_item_key_to_cpu(&path->nodes[0],
509
				      &found_key,
510
				      path->slots[0]);
511
		if (found_key.objectid != BTRFS_DEV_ITEMS_OBJECTID)
512
			break;
513
		dev_item = btrfs_item_ptr(&path->nodes[0],
514
					  path->slots[0],
515
					  struct btrfs_dev_item);
516
		result = seeker(btrfs_device_id(&path->nodes[0], dev_item));
517
		if (result == NULL) {
518
			btrfs_msg("Btrfs device %llu is not available\n",
519
				  btrfs_device_id(&path->nodes[0], dev_item));
520
			goto missed_dev;
521
		}
522
		num_devices++;
523
		ret = btrfs_next_item(root, path);
524
		if (ret)
525
			break;
526
	}
527
	if (num_devices == btrfs_super_num_devices(BTRFS_SUPER))
528
		return 0;
529
 corrupted:
530
	errnum = ERR_FSYS_CORRUPT;
531
	return 1;
532
 missed_dev:
533
	errnum = ERR_FSYS_MOUNT;
534
	return 1;
535
}
536
#endif /* 0 */
537
538
/*
539
 * Find a grub btrfs device by devid.
540
 * Preconditions: global btrfs_fs_info
541
 * contains a copy of btrfs super block.
542
 *
543
 * Return pointer to the cached device on success.
544
 * Otherwise return NULL.
545
 */
546
static struct btrfs_device *btrfs_lookup_device(u64 devid)
547
{
548
	int i, result;
549
	struct btrfs_device *cdev;
550
551
	for (i = 0; i < BTRFS_NUM_CACHED_DEVICES; i++) {
552
		cdev = &BTRFS_DEVICES[i];
553
		if (cdev->devid == devid)
554
			goto found_in_cache;
555
		if (cdev->devid == 0)
556
			goto not_found_in_cache;
557
	}
558
not_found_in_cache:
559
	cdev = BTRFS_VOLATILE_DEV_CACHE;
560
	cdev->devid = devid;
561
	result = scan_grub_devices(cdev,
562
				   btrfs_discerner,
563
				   1);
564
	if (result == 0)
565
		/*
566
		 * At mount time we have figured out that
567
		 * number of available devices is not less
568
		 * then number of devices recorded in the
569
		 * super block. Hence we treat this case as
570
		 * file system corruption.
571
		 */
572
		goto corrupt;
573
	result = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
574
	if (result)
575
		goto corrupt;
576
found_in_cache:
577
	return cdev;
578
corrupt:
579
	errnum = ERR_FSYS_CORRUPT;
580
	return NULL;
581
}
582
583
static int btrfs_find_device(struct btrfs_device *dev)
584
{
585
	struct btrfs_device *cdev;
586
587
	if (btrfs_super_num_devices(BTRFS_SUPER) == 1) {
588
		dev->drive = current_drive;
589
		dev->part = part_start;
590
		dev->length = part_length;
591
		return 0;
592
	}
593
	cdev = btrfs_lookup_device(dev->devid);
594
	if (cdev == NULL)
595
		return 1;
596
	dev->drive  = cdev->drive;
597
	dev->part   = cdev->part;
598
	dev->length = cdev->length;
599
	return 0;
600
}
601
602
static inline void init_btrfs_volatile_dev_cache(void)
603
{
604
	BTRFS_VOLATILE_DEV_CACHE->devid = 0;
605
	BTRFS_VOLATILE_DEV_CACHE->drive = current_drive;
606
	BTRFS_VOLATILE_DEV_CACHE->part = part_start;
607
	BTRFS_VOLATILE_DEV_CACHE->length = part_length;
608
}
609
610
/*
611
 * check availability of btrfs devices
612
 * and populate the persistent device cache
613
 */
614
static int btrfs_check_devices(void)
615
{
616
	u64 num_dev;
617
618
	if (btrfs_super_num_devices(BTRFS_SUPER) == 1)
619
		return 0;
620
	num_dev = scan_grub_devices(BTRFS_DEVICES,
621
				    btrfs_discerner, 0);
622
	if (btrfs_uptodate_super_copy(BTRFS_FS_INFO))
623
		return 1;
624
	if (num_dev < btrfs_super_num_devices(BTRFS_SUPER)) {
625
		btrfs_msg("Some (%llu) Btrfs devices is not available\n",
626
			  btrfs_super_num_devices(BTRFS_SUPER) - num_dev);
627
	        return 1;
628
	}
629
	return 0;
630
}
631
632
int btrfs_mount(void)
633
{
634
	int ret;
635
636
	check_btrfs_cache_size();
637
	init_btrfs_info();
638
	init_btrfs_volatile_dev_cache();
639
640
	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
641
	if (ret) {
642
		btrfs_msg("Drive %lu, partition %lu: no Btrfs metadata\n",
643
			  current_drive, part_start);
644
		goto error;
645
	}
646
	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
647
	if (ret)
648
		goto error;
649
	BTRFS_FS_INFO->sb_transid =
650
		btrfs_super_generation(BTRFS_SUPER);
651
	memcpy(BTRFS_FS_INFO->fsid,
652
	       BTRFS_SUPER->fsid,
653
	       BTRFS_FSID_SIZE);
654
	ret = btrfs_check_devices();
655
	if (ret)
656
		goto error;
657
	/* setup chunk root */
658
	ret = find_setup_root(NULL,
659
			      btrfs_super_nodesize(BTRFS_SUPER),
660
			      btrfs_super_leafsize(BTRFS_SUPER),
661
			      btrfs_super_sectorsize(BTRFS_SUPER),
662
			      btrfs_super_stripesize(BTRFS_SUPER),
663
			      BTRFS_CHUNK_TREE_OBJECTID,
664
			      BTRFS_CHUNK_ROOT,
665
			      btrfs_super_chunk_root(BTRFS_SUPER),
666
			      btrfs_chunk_root_level_size(BTRFS_SUPER),
667
			      btrfs_super_chunk_root_generation(BTRFS_SUPER),
668
			      FIRST_EXTERNAL_LOOKUP_POOL);
669
	if (ret)
670
		return 0;
671
	/* setup tree root */
672
	ret = find_setup_root(NULL,
673
			      btrfs_super_nodesize(BTRFS_SUPER),
674
			      btrfs_super_leafsize(BTRFS_SUPER),
675
			      btrfs_super_sectorsize(BTRFS_SUPER),
676
			      btrfs_super_stripesize(BTRFS_SUPER),
677
			      BTRFS_ROOT_TREE_OBJECTID,
678
			      BTRFS_TREE_ROOT,
679
			      btrfs_super_root(BTRFS_SUPER),
680
			      btrfs_root_level_size(BTRFS_SUPER),
681
			      btrfs_super_generation(BTRFS_SUPER),
682
			      FIRST_EXTERNAL_LOOKUP_POOL);
683
	if (ret)
684
		return 0;
685
	/* setup fs_root */
686
	ret = find_setup_root(BTRFS_TREE_ROOT,
687
			      btrfs_super_nodesize(BTRFS_SUPER),
688
			      btrfs_super_leafsize(BTRFS_SUPER),
689
			      btrfs_super_sectorsize(BTRFS_SUPER),
690
			      btrfs_super_stripesize(BTRFS_SUPER),
691
			      BTRFS_FS_TREE_OBJECTID,
692
			      BTRFS_FS_ROOT,
693
			      0,
694
			      0,
695
			      0,
696
			      FIRST_EXTERNAL_LOOKUP_POOL);
697
	return !ret;
698
699
error:
700
	errnum = ERR_FSYS_MOUNT;
701
	return 0;
702
}
703
704
/*
705
 * Check, whether @chunk is the map for a
706
 * block with @logical block number.
707
 * If yes, then fill the @map.
708
 * Return 1 on affirmative result,
709
 * otherwise return 0.
710
 */
711
int check_read_chunk(struct btrfs_key *key,
712
			    struct extent_buffer *leaf,
713
			    struct btrfs_chunk *chunk,
714
			    struct map_lookup *map,
715
			    u64 logical)
716
{
717
	int i, ret;
718
	u64 chunk_start;
719
	u64 chunk_size;
720
	int num_stripes;
721
722
	chunk_start = key->offset;
723
	chunk_size = btrfs_chunk_length(leaf, chunk);
724
725
	if (logical + 1 > chunk_start + chunk_size ||
726
	    logical < chunk_start)
727
		/* not a fit */
728
		return 0;
729
	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
730
	map->ce.start = chunk_start;
731
	map->ce.size = chunk_size;
732
	map->num_stripes = num_stripes;
733
	map->io_width = btrfs_chunk_io_width(leaf, chunk);
734
	map->io_align = btrfs_chunk_io_align(leaf, chunk);
735
	map->sector_size = btrfs_chunk_sector_size(leaf, chunk);
736
	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
737
	map->type = btrfs_chunk_type(leaf, chunk);
738
	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
739
740
	for (i = 0; i < num_stripes; i++) {
741
		map->stripes[i].physical =
742
			btrfs_stripe_offset_nr(leaf, chunk, i);
743
		map->stripes[i].dev.devid =
744
			btrfs_stripe_devid_nr(leaf, chunk, i);
745
		ret = btrfs_find_device(&map->stripes[i].dev);
746
		if (ret)
747
			return 0;
748
	}
749
	return 1;
750
}
751
752
static void init_extent_buffer(struct extent_buffer *eb,
753
			       struct btrfs_device *dev,
754
			       u64 logical,
755
			       u32 blocksize,
756
			       u64 physical,
757
			       lookup_pool_id lpid)
758
{
759
	if (dev)
760
		memcpy(&eb->dev, dev, sizeof(*dev));
761
	eb->start = logical;
762
	eb->len = blocksize;
763
	eb->dev_bytenr = physical;
764
	eb->data = grab_lookup_cache(lpid);
765
}
766
767
/*
768
 * Search for a map by logical offset in sys array.
769
 * Return -1 on errors;
770
 * Return 1 if the map is found,
771
 * Return 0 if the map is not found.
772
 */
773
int sys_array_lookup(struct map_lookup *map, u64 logical)
774
{
775
	struct extent_buffer sb;
776
	struct btrfs_disk_key *disk_key;
777
	struct btrfs_chunk *chunk;
778
	struct btrfs_key key;
779
	u32 num_stripes;
780
	u32 array_size;
781
	u32 len = 0;
782
	u8 *ptr;
783
	unsigned long sb_ptr;
784
	u32 cur;
785
	int ret;
786
	int i = 0;
787
788
	sb.data = (char *)BTRFS_SUPER;
789
	array_size = btrfs_super_sys_array_size(BTRFS_SUPER);
790
791
	ptr = BTRFS_SUPER->sys_chunk_array;
792
	sb_ptr = offsetof(struct btrfs_super_block, sys_chunk_array);
793
	cur = 0;
794
795
	while (cur < array_size) {
796
		disk_key = (struct btrfs_disk_key *)ptr;
797
		btrfs_disk_key_to_cpu(&key, disk_key);
798
799
		len = sizeof(*disk_key);
800
		ptr += len;
801
		sb_ptr += len;
802
		cur += len;
803
804
		if (key.type == BTRFS_CHUNK_ITEM_KEY) {
805
			chunk = (struct btrfs_chunk *)sb_ptr;
806
			ret = check_read_chunk(&key, &sb,
807
					       chunk, map, logical);
808
			if (ret)
809
				/* map is found */
810
				return ret;
811
			num_stripes = btrfs_chunk_num_stripes(&sb, chunk);
812
			len = btrfs_chunk_item_size(num_stripes);
813
		} else {
814
			errnum = ERR_FSYS_CORRUPT;
815
			return -1;
816
		}
817
		ptr += len;
818
		sb_ptr += len;
819
		cur += len;
820
		i++;
821
	}
822
	return 0;
823
}
824
825
/*
826
 * Search for a map by logical offset in the chunk tree.
827
 * Return 1 if map is found, otherwise return 0.
828
 */
829
static int chunk_tree_lookup(struct map_lookup *map,
830
			     u64 logical)
831
{
832
	int ret;
833
	int slot;
834
	struct extent_buffer *leaf;
835
	struct btrfs_key key;
836
	struct btrfs_key found_key;
837
	struct btrfs_chunk *chunk;
838
	struct btrfs_path *path;
839
840
	path = btrfs_grab_path(INTERNAL_LOOKUP_POOL);
841
842
	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
843
	key.offset = logical;
844
	key.type = BTRFS_CHUNK_ITEM_KEY;
845
846
	ret = aux_tree_lookup(BTRFS_CHUNK_ROOT, &key, path);
847
	if (ret < 0)
848
		return 0;
849
	leaf = &path->nodes[0];
850
	slot = path->slots[0];
851
	if (ret == 1) {
852
		WARN_ON(slot == 0);
853
		slot -= 1;
854
	}
855
	btrfs_item_key_to_cpu(leaf, &found_key, slot);
856
	if (found_key.type != BTRFS_CHUNK_ITEM_KEY)
857
		return 0;
858
	chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
859
	return check_read_chunk(&found_key, leaf,
860
				chunk, map, logical);
861
}
862
863
/*
864
 * Btrfs logical/physical block mapper.
865
 * Look for an appropriate map-extent and
866
 * perform a translation. Return 1 on errors.
867
 */
868
static int btrfs_map_block(u64 logical, u64 *length,
869
			   struct btrfs_multi_bio *multi,
870
			   int mirror_num)
871
{
872
	struct map_lookup map;
873
	u64 offset;
874
	u64 stripe_offset;
875
	u64 stripe_nr;
876
	struct cache_extent *ce;
877
	int stripe_index;
878
	int i;
879
	int ret;
880
881
	memset(&map, 0, sizeof(map));
882
	ret = sys_array_lookup(&map, logical);
883
	if (ret == -1) {
884
		errnum = ERR_FSYS_CORRUPT;
885
		return 1;
886
	}
887
	if (ret == 0) {
888
		ret = chunk_tree_lookup(&map, logical);
889
		if (!ret) {
890
			/* something should be found! */
891
			errnum = ERR_FSYS_CORRUPT;
892
			return 1;
893
		}
894
	}
895
	/* do translation */
896
	ce = &map.ce;
897
898
	offset = logical - ce->start;
899
	stripe_nr = offset / map.stripe_len;
900
	stripe_offset = stripe_nr * map.stripe_len;
901
	WARN_ON(offset < stripe_offset);
902
903
	stripe_offset = offset - stripe_offset;
904
905
	if (map.type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
906
			 BTRFS_BLOCK_GROUP_RAID10 |
907
			 BTRFS_BLOCK_GROUP_DUP)) {
908
		*length = min_t(u64, ce->size - offset,
909
			      map.stripe_len - stripe_offset);
910
	} else {
911
		*length = ce->size - offset;
912
	}
913
	multi->num_stripes = 1;
914
	stripe_index = 0;
915
	if (map.type & BTRFS_BLOCK_GROUP_RAID1) {
916
		if (mirror_num)
917
			stripe_index = mirror_num - 1;
918
		else
919
			stripe_index = stripe_nr % map.num_stripes;
920
	} else if (map.type & BTRFS_BLOCK_GROUP_RAID10) {
921
		int factor = map.num_stripes / map.sub_stripes;
922
923
		stripe_index = stripe_nr % factor;
924
		stripe_index *= map.sub_stripes;
925
926
		if (mirror_num)
927
			stripe_index += mirror_num - 1;
928
		else
929
			stripe_index = stripe_nr % map.sub_stripes;
930
931
		stripe_nr = stripe_nr / factor;
932
	} else if (map.type & BTRFS_BLOCK_GROUP_DUP) {
933
		if (mirror_num)
934
			stripe_index = mirror_num - 1;
935
	} else {
936
		stripe_index = stripe_nr % map.num_stripes;
937
		stripe_nr = stripe_nr / map.num_stripes;
938
	}
939
	WARN_ON(stripe_index >= map.num_stripes);
940
941
	for (i = 0; i < multi->num_stripes; i++) {
942
		asm("" : "+r"(multi));
943
		multi->stripes[i].physical =
944
			map.stripes[stripe_index].physical + stripe_offset +
945
			stripe_nr * map.stripe_len;
946
		memcpy(&multi->stripes[i].dev,
947
		       &map.stripes[stripe_index].dev,
948
		       sizeof(struct btrfs_device));
949
		stripe_index++;
950
	}
951
	return 0;
952
}
953
954
static u64 read_data_extent(u64 logical_start, u64 to_read, char *pos)
955
{
956
	int ret;
957
	u64 length;
958
	struct btrfs_multi_bio multi;
959
960
	while (to_read) {
961
		ret = btrfs_map_block(logical_start, &length, &multi, 0);
962
		if (ret) {
963
			errnum = ERR_FSYS_CORRUPT;
964
			return ret;
965
		}
966
		if (length > to_read)
967
			length = to_read;
968
		disk_read_func = disk_read_hook;
969
		ret = btrfs_devread(multi.stripes[0].dev.drive,
970
				    multi.stripes[0].dev.part,
971
				    multi.stripes[0].dev.length,
972
				    multi.stripes[0].physical >> SECTOR_BITS,
973
				    logical_start & ((u64)SECTOR_SIZE - 1),
974
				    length,
975
				    pos);
976
		disk_read_func = NULL;
977
		if (!ret)
978
			return 1;
979
		btrfs_msg("BTRFS data extent: read %llu bytes\n", length);
980
		to_read -= length;
981
		pos += length;
982
		logical_start += length;
983
	}
984
	return 0;
985
}
986
987
static int read_extent_from_disk(struct extent_buffer *eb)
988
{
989
	WARN_ON(eb->dev_bytenr % SECTOR_BITS);
990
	return btrfs_devread(eb->dev.drive,
991
			     eb->dev.part,
992
			     eb->dev.length,
993
			     eb->dev_bytenr >> SECTOR_BITS,
994
			     0,
995
			     eb->len,
996
			     eb->data);
997
}
998
999
static int verify_parent_transid(struct extent_buffer *eb, u64 parent_transid)
1000
{
1001
	return parent_transid && (btrfs_header_generation(eb) != parent_transid);
1002
}
1003
1004
static int btrfs_num_copies(u64 logical, u64 len)
1005
{
1006
	return 1;
1007
}
1008
1009
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
1010
{
1011
	return 0;
1012
}
1013
1014
static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
1015
		    int verify)
1016
{
1017
	return 0;
1018
}
1019
1020
/*
1021
 * Read a block of logical number @bytenr
1022
 * from disk to buffer @eb.
1023
 * Return 1 on success.
1024
 */
1025
int read_tree_block(struct btrfs_root *root,
1026
		    struct extent_buffer *eb,
1027
		    u64 bytenr, /* logical */
1028
		    u32 blocksize,
1029
		    u64 parent_transid,
1030
		    lookup_pool_id lpid)
1031
{
1032
	int ret;
1033
	int dev_nr;
1034
	u64 length;
1035
	struct btrfs_multi_bio multi;
1036
	int mirror_num = 0;
1037
	int num_copies;
1038
1039
	dev_nr = 0;
1040
	length = blocksize;
1041
	while (1) {
1042
		ret = btrfs_map_block(bytenr,
1043
				      &length, &multi, mirror_num);
1044
		if (ret) {
1045
			errnum = ERR_FSYS_CORRUPT;
1046
			return 0;
1047
		}
1048
		init_extent_buffer(eb,
1049
				   &multi.stripes[0].dev,
1050
				   bytenr,
1051
				   blocksize,
1052
				   multi.stripes[0].physical,
1053
				   lpid);
1054
1055
		ret = read_extent_from_disk(eb);
1056
		if (ret &&
1057
		    check_tree_block(root, eb) == 0 &&
1058
		    csum_tree_block(root, eb, 1) == 0 &&
1059
		    verify_parent_transid(eb, parent_transid) == 0)
1060
			return 1;
1061
1062
		num_copies = btrfs_num_copies(eb->start, eb->len);
1063
		if (num_copies == 1)
1064
			break;
1065
		mirror_num++;
1066
		if (mirror_num > num_copies)
1067
			break;
1068
	}
1069
	return 0;
1070
}
1071
1072
/*
1073
 * Read a child pointed by @slot node pointer
1074
 * of @parent. Put the result to @parent.
1075
 * Return 1 on success.
1076
 */
1077
static int parent2child(struct btrfs_root *root,
1078
			struct extent_buffer *parent,
1079
			int slot,
1080
			lookup_pool_id lpid)
1081
{
1082
	int level;
1083
1084
	WARN_ON(slot < 0);
1085
	WARN_ON(slot >= btrfs_header_nritems(parent));
1086
1087
	level = btrfs_header_level(parent);
1088
	WARN_ON(level <= 0);
1089
1090
	return read_tree_block(root,
1091
			       parent,
1092
			       btrfs_node_blockptr(parent, slot),
1093
			       btrfs_level_size(root, level - 1),
1094
			       btrfs_node_ptr_generation(parent, slot),
1095
			       lpid);
1096
}
1097
1098
static int btrfs_comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
1099
{
1100
	struct btrfs_key k1;
1101
1102
	btrfs_disk_key_to_cpu(&k1, disk);
1103
1104
	if (k1.objectid > k2->objectid)
1105
		return 1;
1106
	if (k1.objectid < k2->objectid)
1107
		return -1;
1108
	if (k1.type > k2->type)
1109
		return 1;
1110
	if (k1.type < k2->type)
1111
		return -1;
1112
	if (k1.offset > k2->offset)
1113
		return 1;
1114
	if (k1.offset < k2->offset)
1115
		return -1;
1116
	return 0;
1117
}
1118
1119
static int bin_search(struct extent_buffer *eb, unsigned long p,
1120
		      int item_size, struct btrfs_key *key,
1121
		      int max, int *slot)
1122
{
1123
	int low = 0;
1124
	int high = max;
1125
	int mid;
1126
	int ret;
1127
	unsigned long offset;
1128
	struct btrfs_disk_key *tmp;
1129
1130
	while(low < high) {
1131
		mid = (low + high) / 2;
1132
		offset = p + mid * item_size;
1133
1134
		tmp = (struct btrfs_disk_key *)(eb->data + offset);
1135
		ret = btrfs_comp_keys(tmp, key);
1136
1137
		if (ret < 0)
1138
			low = mid + 1;
1139
		else if (ret > 0)
1140
			high = mid;
1141
		else {
1142
			*slot = mid;
1143
			return 0;
1144
		}
1145
	}
1146
	*slot = low;
1147
	return 1;
1148
}
1149
1150
/* look for a key in a node */
1151
static int node_lookup(struct extent_buffer *eb,
1152
		       struct btrfs_key *key,
1153
		       int *slot)
1154
{
1155
	if (btrfs_header_level(eb) == 0) {
1156
		return bin_search(eb,
1157
				  offsetof(struct btrfs_leaf, items),
1158
				  sizeof(struct btrfs_item),
1159
				  key, btrfs_header_nritems(eb),
1160
				  slot);
1161
	} else {
1162
		return bin_search(eb,
1163
				  offsetof(struct btrfs_node, ptrs),
1164
				  sizeof(struct btrfs_key_ptr),
1165
				  key, btrfs_header_nritems(eb),
1166
				  slot);
1167
	}
1168
	return -1;
1169
}
1170
1171
static inline int check_node(struct extent_buffer *buf, int slot)
1172
{
1173
	return 0;
1174
}
1175
1176
/*
1177
 * Look for an item by key in read-only tree.
1178
 * Return 0, if key was found. Return -1 on io errors.
1179
 *
1180
 * Preconditions: btrfs_mount already executed.
1181
 * Postconditions: if returned value is non-negative,
1182
 * then path[0] represents the found position in the
1183
 * tree. All components of the @path from leaf to root
1184
 * are valid except their data buffers (only path[0]
1185
 * has valid attached data buffer).
1186
 */
1187
1188
int aux_tree_lookup(struct btrfs_root *root,
1189
		    struct btrfs_key *key,
1190
		    struct btrfs_path *path)
1191
{
1192
	int ret;
1193
	int slot = 0;
1194
	int level;
1195
	struct extent_buffer node;
1196
	init_extent_buffer(&node,
1197
			   NULL,
1198
			   0,
1199
			   0,
1200
			   0,
1201
			   path->lpid);
1202
	copy_extent_buffer(&node, &root->node);
1203
	do {
1204
		level = btrfs_header_level(&node);
1205
		ret = check_node(&node, slot);
1206
		if (ret)
1207
			return -1;
1208
		move_extent_buffer(&path->nodes[level],
1209
				   &node);
1210
		ret = node_lookup(&node, key, &slot);
1211
		if (ret < 0)
1212
			return ret;
1213
		if (level) {
1214
		        /*
1215
			 * non-leaf,
1216
			 * jump to the next level
1217
			 */
1218
			if (ret && slot > 0)
1219
			        slot -= 1;
1220
			ret = parent2child(root, &node, slot, path->lpid);
1221
			if (ret == 0)
1222
				return -1;
1223
		}
1224
		path->slots[level] = slot;
1225
	} while (level);
1226
	return ret;
1227
}
1228
1229
static int readup_buffer(struct extent_buffer *buf, lookup_pool_id lpid)
1230
{
1231
	buf->data = grab_lookup_cache(lpid);
1232
	return read_extent_from_disk(buf);
1233
}
1234
1235
/*
1236
 * Find the next leaf in accordance with tree order;
1237
 * walk up the tree as far as required to find it.
1238
 * Returns 0 if something was found, or 1 if there
1239
 * are no greater leaves. Returns < 0 on io errors.
1240
 *
1241
 * Preconditions: all @path components from leaf to
1242
 * root have valid meta-data fields. path[0] has a
1243
 * valid attached data buffer with initial leaf.
1244
 * Postcondition: the same as above, but path[0] has
1245
 * an attached data buffer with the next leaf.
1246
 */
1247
static int btrfs_next_leaf(struct btrfs_root *root,
1248
			   struct btrfs_path *path)
1249
{
1250
	int res;
1251
	int slot;
1252
	int level = 1;
1253
	struct extent_buffer *buf;
1254
1255
	while(level < BTRFS_MAX_LEVEL) {
1256
		buf = &path->nodes[level];
1257
		slot = path->slots[level] + 1;
1258
		/*
1259
		 * lift data on this level
1260
		 */
1261
		res = readup_buffer(buf, path->lpid);
1262
		if (!res)
1263
			break;
1264
		if (slot >= btrfs_header_nritems(buf)) {
1265
			/* alas, go to parent (if any) */
1266
			level++;
1267
			res = 1;
1268
			continue;
1269
		}
1270
		break;
1271
	}
1272
	if (!res)
1273
		return 1;
1274
	/*
1275
	 * At this level slot points to
1276
	 * the subtree we are interested in.
1277
	 */
1278
	path->slots[level] = slot;
1279
	while(level) {
1280
		struct extent_buffer tmp;
1281
		move_extent_buffer(&tmp, &path->nodes[level]);
1282
		res = parent2child(root, &tmp, slot, path->lpid);
1283
		if (res == 0)
1284
			return -1;
1285
		level --;
1286
		slot = 0;
1287
		move_extent_buffer(&path->nodes[level], &tmp);
1288
		path->slots[level] = slot;
1289
	}
1290
	return 0;
1291
}
1292
1293
/* Preconditions: path is valid, data buffer
1294
 * is attached to leaf node.
1295
 * Postcondition: path is updated to point to
1296
 * the next position with respect to the tree
1297
 * order.
1298
 *
1299
 * Return -1 on io errors.
1300
 * Return 0, if next item was found.
1301
 * Return 1, if next item wasn't found (no more items).
1302
 */
1303
static int btrfs_next_item(struct btrfs_root *root,
1304
			   struct btrfs_path *path)
1305
{
1306
	WARN_ON(path->slots[0] >= btrfs_header_nritems(&path->nodes[0]));
1307
1308
	path->slots[0] += 1;
1309
1310
	if (path->slots[0] < btrfs_header_nritems(&path->nodes[0]))
1311
		return 0;
1312
	if (coord_is_root(root, path))
1313
		/* no more items */
1314
		return 1;
1315
	return btrfs_next_leaf(root, path);
1316
}
1317
1318
/*
1319
 * check if we can reuse results of previous
1320
 * search for read operation
1321
 */
1322
static int path_is_valid(struct btrfs_path *path,
1323
			 struct btrfs_key *key, u64 offset)
1324
{
1325
	btrfs_item_key_to_cpu(&path->nodes[0],
1326
			      key,
1327
			      path->slots[0]);
1328
	if (BTRFS_FILE_INFO_KEY->objectid != key->objectid)
1329
		return 0;
1330
	if (btrfs_key_type(key) == BTRFS_INODE_ITEM_KEY)
1331
		return 1;
1332
	if (btrfs_key_type(key) != BTRFS_EXTENT_DATA_KEY)
1333
		return 0;
1334
	return BTRFS_FILE_INFO_KEY->offset <= offset;
1335
}
1336
1337
/* ->read_func() */
1338
int btrfs_read(char *buf, int len)
1339
{
1340
	int ret;
1341
	struct btrfs_root *fs_root;
1342
	struct btrfs_path *path;
1343
	struct btrfs_key  path_key;
1344
	u64 ioff;
1345
	u64 bytes;
1346
	int to_read;
1347
	char *pos = buf;
1348
1349
	fs_root = BTRFS_FS_ROOT;
1350
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
1351
1352
	if (!path_is_valid(path, &path_key, filepos)) {
1353
		ret = aux_tree_lookup(fs_root, BTRFS_FILE_INFO_KEY, path);
1354
		if (ret < 0)
1355
			errnum = ERR_FSYS_CORRUPT;
1356
	}
1357
	while (!errnum) {
1358
		struct btrfs_item *item;
1359
		struct btrfs_file_extent_item *fi;
1360
		u64 from;
1361
1362
		btrfs_item_key_to_cpu(&path->nodes[0],
1363
				      &path_key,
1364
				      path->slots[0]);
1365
		if (BTRFS_FILE_INFO_KEY->objectid != path_key.objectid)
1366
			break;
1367
		if (btrfs_key_type(&path_key) != BTRFS_EXTENT_DATA_KEY)
1368
			goto next;
1369
		/*
1370
		 * current position is extent item
1371
		 */
1372
		item = btrfs_item_nr(&path->nodes[0], path->slots[0]);
1373
		fi = btrfs_item_ptr(&path->nodes[0],
1374
				    path->slots[0],
1375
				    struct btrfs_file_extent_item);
1376
		if (btrfs_file_extent_compression(&path->nodes[0], fi)) {
1377
		       btrfs_msg("Btrfs transparent compression unsupported\n");
1378
		       errnum = ERR_BAD_FILETYPE;
1379
		       goto exit;
1380
		}
1381
		ioff = filepos - path_key.offset;
1382
1383
		switch (btrfs_file_extent_type(&path->nodes[0], fi)) {
1384
		case BTRFS_FILE_EXTENT_INLINE:
1385
			bytes = btrfs_file_extent_inline_item_len(&path->
1386
								  nodes[0],
1387
								  item);
1388
			if (path_key.offset + bytes < filepos)
1389
				goto next;
1390
			to_read = bytes - ioff;
1391
			if (to_read > len)
1392
				to_read = len;
1393
			from = ioff + btrfs_file_extent_inline_start(fi);
1394
			if (disk_read_hook != NULL) {
1395
				disk_read_func = disk_read_hook;
1396
				ret = btrfs_devread(path->nodes[0].dev.drive,
1397
						    path->nodes[0].dev.part,
1398
						    path->nodes[0].dev.length,
1399
						    path->nodes[0].dev_bytenr >>
1400
						    SECTOR_BITS,
1401
						    from,
1402
						    to_read,
1403
						    pos);
1404
				disk_read_func = NULL;
1405
				if (ret)
1406
					goto exit;
1407
			} else
1408
				memcpy(pos,
1409
				       path->nodes[0].data + from,
1410
				       to_read);
1411
			btrfs_msg("BTRFS inline extent: read %d bytes pos %d\n",
1412
				  to_read, filepos);
1413
			break;
1414
		case BTRFS_FILE_EXTENT_REG:
1415
			bytes = btrfs_file_extent_num_bytes(&path->nodes[0],
1416
							    fi);
1417
			if (path_key.offset + bytes < filepos)
1418
				goto next;
1419
			to_read = bytes - ioff;
1420
			if (to_read > len)
1421
				to_read = len;
1422
			from = ioff +
1423
				btrfs_file_extent_disk_bytenr(&path->nodes[0],
1424
							      fi) +
1425
				btrfs_file_extent_offset(&path->nodes[0],
1426
							 fi);
1427
			ret = read_data_extent(from, to_read, pos);
1428
			if (ret)
1429
				goto exit;
1430
			break;
1431
		case BTRFS_FILE_EXTENT_PREALLOC:
1432
			btrfs_msg("Btrfs preallocated extents unsupported\n");
1433
			errnum = ERR_BAD_FILETYPE;
1434
			goto exit;
1435
		default:
1436
			errnum = ERR_FSYS_CORRUPT;
1437
			goto exit;
1438
		}
1439
		len -= to_read;
1440
		pos += to_read;
1441
		filepos += to_read;
1442
		if (len == 0)
1443
			break;
1444
		/* not everything was read */
1445
	next:
1446
		ret = btrfs_next_item(fs_root, path);
1447
		if (ret < 0) {
1448
			errnum = ERR_FSYS_CORRUPT;
1449
			break;
1450
		}
1451
		btrfs_update_file_info(path);
1452
		continue;
1453
	}
1454
exit:
1455
	return errnum ? 0 : pos - buf;
1456
}
1457
1458
static int btrfs_follow_link(struct btrfs_root *root,
1459
			     struct btrfs_path *path,
1460
			     char **dirname, char *linkbuf,
1461
			     int *link_count,
1462
			     struct btrfs_inode_item *sd)
1463
{
1464
	int ret;
1465
	int len;
1466
	char *name = *dirname;
1467
1468
	if (++(*link_count) > MAX_LINK_COUNT) {
1469
		errnum = ERR_SYMLINK_LOOP;
1470
		return 0;
1471
	}
1472
	/* calculate remaining name size */
1473
	filemax = btrfs_inode_size(&path->nodes[0], sd);
1474
	for (len = 0;
1475
	     name[len] && isspace(name[len]);
1476
	     len ++);
1477
1478
	if (filemax + len > PATH_MAX - 1) {
1479
		errnum = ERR_FILELENGTH;
1480
		return 0;
1481
	}
1482
	grub_memmove(linkbuf + filemax, name, len + 1);
1483
	btrfs_update_file_info(path);
1484
	filepos = 0;
1485
	/* extract symlink content */
1486
	while (1) {
1487
		u64 oid = BTRFS_FILE_INFO_KEY->objectid;
1488
		ret = btrfs_next_item(root, path);
1489
		if (ret)
1490
			break;
1491
		btrfs_update_file_info(path);
1492
		if (oid != BTRFS_FILE_INFO_KEY->objectid)
1493
			break;
1494
		if (btrfs_key_type(BTRFS_FILE_INFO_KEY) ==
1495
		    BTRFS_EXTENT_DATA_KEY)
1496
			goto found;
1497
	}
1498
	/* no target was found */
1499
	errnum = ERR_FSYS_CORRUPT;
1500
	return 0;
1501
found:
1502
	/* fill the rest of linkbuf with the content */
1503
	ret = btrfs_read(linkbuf, filemax);
1504
	if (ret != filemax) {
1505
		errnum = ERR_FSYS_CORRUPT;
1506
		return 0;
1507
	}
1508
	return 1;
1509
}
1510
1511
static int update_fs_root(struct btrfs_root *fs_root,
1512
			  struct btrfs_key *location)
1513
{
1514
	int ret;
1515
	struct btrfs_root *tree_root;
1516
1517
	if (location->offset != (u64)-1)
1518
		return 0;
1519
	tree_root = &BTRFS_FS_INFO->tree_root;
1520
	ret = find_setup_root(tree_root,
1521
			      tree_root->nodesize,
1522
			      tree_root->leafsize,
1523
			      tree_root->sectorsize,
1524
			      tree_root->stripesize,
1525
			      location->objectid,
1526
			      fs_root,
1527
			      0,
1528
			      0,
1529
			      0,
1530
			      SECOND_EXTERNAL_LOOKUP_POOL);
1531
	if (ret)
1532
		return ret;
1533
	location->objectid = btrfs_root_dirid(&fs_root->root_item);
1534
	btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY);
1535
	location->offset = 0;
1536
	return 0;
1537
}
1538
1539
#ifndef STAGE1_5
1540
static inline void update_possibilities(void)
1541
{
1542
	if (print_possibilities > 0)
1543
		print_possibilities =
1544
			-print_possibilities;
1545
}
1546
#endif
1547
1548
/*
1549
 * Look for a directory item by name.
1550
 * Print possibilities, if needed.
1551
 * Postconditions: on success @sd_key points
1552
 * to the key contained in the directory entry.
1553
 */
1554
static int btrfs_de_index_by_name(struct btrfs_root *root,
1555
				  struct btrfs_path *path,
1556
				  char **dirname,
1557
				  struct btrfs_key *sd_key)
1558
{
1559
	char ch;
1560
	int ret;
1561
	char *rest;
1562
	struct btrfs_dir_item *di;
1563
#ifndef STAGE1_5
1564
	int do_possibilities = 0;
1565
#endif
1566
	for (; **dirname == '/'; (*dirname)++);
1567
	for (rest = *dirname;
1568
	     (ch = *rest) && !isspace(ch) && ch != '/';
1569
	     rest++);
1570
	*rest = 0; /* for substrung() */
1571
#ifndef STAGE1_5
1572
	if (print_possibilities && ch != '/')
1573
		do_possibilities = 1;
1574
#endif
1575
	/* scan a directory */
1576
	while (1) {
1577
		u32 total;
1578
		u32 cur = 0;
1579
		u32 len;
1580
		struct btrfs_key di_key;
1581
		struct btrfs_disk_key location;
1582
		struct btrfs_item *item;
1583
1584
		/* extract next dir entry */
1585
		ret = btrfs_next_item(root, path);
1586
		if (ret)
1587
			break;
1588
		item = btrfs_item_nr(&path->nodes[0],
1589
				     path->slots[0]);
1590
		btrfs_item_key_to_cpu(&path->nodes[0],
1591
				      &di_key,
1592
				      path->slots[0]);
1593
		if (di_key.objectid != sd_key->objectid)
1594
			/* no more entries */
1595
			break;
1596
		di = btrfs_item_ptr(&path->nodes[0],
1597
				    path->slots[0],
1598
				    struct btrfs_dir_item);
1599
		/*
1600
		 * working around special cases:
1601
		 * btrfs doesn't maintain directory entries
1602
		 * which contain names "." and ".."
1603
		 */
1604
		if (!substring(".", *dirname)) {
1605
#ifndef STAGE1_5
1606
			if (do_possibilities) {
1607
				update_possibilities();
1608
				return 1;
1609
			}
1610
#endif
1611
			goto found;
1612
		}
1613
		if (!substring("..", *dirname)) {
1614
			if (di_key.type != BTRFS_INODE_REF_KEY)
1615
				continue;
1616
			sd_key->objectid = di_key.offset;
1617
			btrfs_set_key_type(sd_key, BTRFS_INODE_ITEM_KEY);
1618
			sd_key->offset = 0;
1619
#ifndef STAGE1_5
1620
			if (do_possibilities) {
1621
				update_possibilities();
1622
				return 1;
1623
			}
1624
#endif
1625
			goto found;
1626
		}
1627
		if (di_key.type != BTRFS_DIR_ITEM_KEY)
1628
			continue;
1629
		total = btrfs_item_size(&path->nodes[0], item);
1630
		/* scan a directory item */
1631
		while (cur < total) {
1632
			char tmp;
1633
			int result;
1634
			char *filename;
1635
			char *end_of_name;
1636
			int name_len;
1637
			int data_len;
1638
1639
			btrfs_dir_item_key(&path->nodes[0], di, &location);
1640
1641
			name_len = btrfs_dir_name_len(&path->nodes[0], di);
1642
			data_len = btrfs_dir_data_len(&path->nodes[0], di);
1643
1644
			WARN_ON(name_len > BTRFS_NAME_LEN);
1645
1646
			filename = (char *)(path->nodes[0].data +
1647
					    (unsigned long)(di + 1));
1648
			end_of_name = filename + name_len;
1649
			/*
1650
			 * working around not null-terminated
1651
			 * directory names in btrfs: just
1652
			 * a short-term overwrite of the
1653
			 * cache with the following rollback
1654
			 * of the change.
1655
			 */
1656
			tmp = *end_of_name;
1657
			*end_of_name = 0;
1658
			result = substring(*dirname, filename);
1659
			*end_of_name = tmp;
1660
#ifndef STAGE1_5
1661
			if (do_possibilities) {
1662
				if (result <= 0) {
1663
					update_possibilities();
1664
					*end_of_name = 0;
1665
					print_a_completion(filename);
1666
					*end_of_name = tmp;
1667
				}
1668
			}
1669
			else
1670
#endif
1671
				if (result == 0) {
1672
				      btrfs_dir_item_key_to_cpu(&path->nodes[0],
1673
								di, sd_key);
1674
				      goto found;
1675
				}
1676
			len = sizeof(*di) + name_len + data_len;
1677
			di = (struct btrfs_dir_item *)((char *)di + len);
1678
			cur += len;
1679
		}
1680
	}
1681
#ifndef STAGE1_5
1682
	if (print_possibilities < 0)
1683
		return 1;
1684
#endif
1685
	errnum = ERR_FILE_NOT_FOUND;
1686
	*rest = ch;
1687
	return 0;
1688
 found:
1689
	*rest = ch;
1690
	*dirname = rest;
1691
	return 1;
1692
}
1693
1694
/*
1695
 * ->dir_func().
1696
 * Postcondition: on a non-zero return BTRFS_FS_INFO
1697
 * contains the latest fs_root of file's subvolume.
1698
 * BTRFS_FS_INFO points to a subvolume of a file we
1699
 * were trying to look up.
1700
 * BTRFS_FILE_INFO contains info of the file we were
1701
 * trying to look up.
1702
 */
1703
1704
int btrfs_dir(char *dirname)
1705
{
1706
	int ret;
1707
	int mode;
1708
	u64 size;
1709
	int linkcount = 0;
1710
	char linkbuf[PATH_MAX];
1711
1712
	struct btrfs_path *path;
1713
	struct btrfs_root *root;
1714
1715
	struct btrfs_key sd_key;
1716
	struct btrfs_inode_item *sd;
1717
	struct btrfs_key parent_sd_key;
1718
1719
	root = BTRFS_FS_ROOT;
1720
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
1721
1722
	btrfs_set_root_dir_key(&sd_key);
1723
	while (1) {
1724
		struct extent_buffer *leaf;
1725
		ret = aux_tree_lookup(root, &sd_key, path);
1726
		if (ret)
1727
			return 0;
1728
		leaf = &path->nodes[0];
1729
		sd = btrfs_item_ptr(leaf,
1730
				    path->slots[0],
1731
				    struct btrfs_inode_item);
1732
		mode = btrfs_inode_mode(leaf, sd);
1733
		size = btrfs_inode_size(leaf, sd);
1734
		switch (btrfs_get_file_type(mode)) {
1735
		case BTRFS_SYMLINK_FILE:
1736
			ret = btrfs_follow_link(root,
1737
						path,
1738
						&dirname,
1739
						linkbuf,
1740
						&linkcount,
1741
						sd);
1742
			if (!ret)
1743
				return 0;
1744
			dirname = linkbuf;
1745
			if (*dirname == '/')
1746
				/* absolute name */
1747
				btrfs_set_root_dir_key(&sd_key);
1748
			else
1749
				memcpy(&sd_key, &parent_sd_key,
1750
				       sizeof(sd_key));
1751
			continue;
1752
		case BTRFS_REGULAR_FILE:
1753
			/*
1754
			 * normally we want to exit here
1755
			 */
1756
			if (*dirname && !isspace (*dirname)) {
1757
				errnum = ERR_BAD_FILETYPE;
1758
				return 0;
1759
			}
1760
			filepos = 0;
1761
			filemax = btrfs_inode_size(leaf, sd);
1762
			btrfs_update_file_info(path);
1763
			return 1;
1764
		case BTRFS_DIRECTORY_FILE:
1765
			memcpy(&parent_sd_key, &sd_key, sizeof(sd_key));
1766
			ret = btrfs_de_index_by_name(root,
1767
						     path,
1768
						     &dirname,
1769
						     &sd_key);
1770
			if (!ret)
1771
				return 0;
1772
#ifndef STAGE1_5
1773
			if (print_possibilities < 0)
1774
				return 1;
1775
#endif
1776
			/*
1777
			 * update fs_tree:
1778
			 * subvolume stuff goes here
1779
			 */
1780
			ret = update_fs_root(root, &sd_key);
1781
			if (ret)
1782
				return 0;
1783
			continue;
1784
		case BTRFS_UNKNOWN_FILE:
1785
		default:
1786
			btrfs_msg("Btrfs: bad file type\n");
1787
			errnum = ERR_BAD_FILETYPE;
1788
			return 0;
1789
		}
1790
	}
1791
}
1792
1793
int btrfs_embed(int *start_sector, int needed_sectors)
1794
{
1795
	int ret;
1796
	init_btrfs_info();
1797
	init_btrfs_volatile_dev_cache();
1798
1799
	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
1800
	if (ret)
1801
		return 0;
1802
	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
1803
	if (ret)
1804
		return 0;
1805
	*start_sector = 1; /* reserve first sector for stage1 */
1806
	return needed_sectors <=
1807
		((BTRFS_SUPER_INFO_OFFSET >> SECTOR_BITS) - 1);
1808
}
1809
#endif /* FSYS_BTRFS */
1810
1811
/*
1812
  Local variables:
1813
  c-indentation-style: "K&R"
1814
  mode-name: "LC"
1815
  c-basic-offset: 8
1816
  tab-width: 8
1817
  fill-column: 80
1818
  scroll-step: 1
1819
  End:
1820
*/
(-)grub-0.97-r9/stage2/Makefile.am (-14 / +28 lines)
Lines 17-29 Link Here
17
noinst_LIBRARIES = libgrub.a
17
noinst_LIBRARIES = libgrub.a
18
libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
18
libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
19
	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
19
	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
20
	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
20
	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_btrfs.c fsys_ufs2.c \
21
	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
21
	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
22
	terminfo.c tparm.c graphics.c
22
	terminfo.c tparm.c graphics.c
23
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
23
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
24
	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
24
	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
25
	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
25
	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
26
	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
26
	-DFSYS_BTRFS=1 -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
27
	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
27
	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
28
28
29
# Stage 2 and Stage 1.5's.
29
# Stage 2 and Stage 1.5's.
Lines 34-57 Link Here
34
if DISKLESS_SUPPORT
34
if DISKLESS_SUPPORT
35
pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
35
pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
36
	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
36
	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
37
	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
37
	reiserfs_stage1_5 btrfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 \
38
	nbgrub pxegrub
38
	xfs_stage1_5 nbgrub pxegrub
39
noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
39
noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
40
noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
40
noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
41
	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
41
	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
42
	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
42
	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
43
	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
43
	reiserfs_stage1_5.exec btrfs_stage1_5.exec ufs2_stage1_5.exec \
44
	xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
44
	vstafs_stage1_5.exec xfs_stage1_5.exec nbloader.exec \
45
	pxeloader.exec diskless.exec
45
else
46
else
46
pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
47
pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
47
	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
48
	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
48
	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
49
	reiserfs_stage1_5 btrfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 \
50
	xfs_stage1_5
49
noinst_DATA = pre_stage2 start start_eltorito
51
noinst_DATA = pre_stage2 start start_eltorito
50
noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
52
noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
51
	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
53
	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
52
	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
54
	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
53
	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
55
	reiserfs_stage1_5.exec btrfs_stage1_5.exec ufs2_stage1_5.exec \
54
	xfs_stage1_5.exec
56
	vstafs_stage1_5.exec xfs_stage1_5.exec
55
endif
57
endif
56
MOSTLYCLEANFILES = $(noinst_PROGRAMS)
58
MOSTLYCLEANFILES = $(noinst_PROGRAMS)
57
59
Lines 95-109 Link Here
95
pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
97
pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
96
	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
98
	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
97
	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
99
	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
98
	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
100
	fsys_reiserfs.c fsys_btrfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c \
99
	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
101
	gunzip.c hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c \
100
	graphics.c
102
	tparm.c graphics.c
101
pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
103
pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
102
pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
104
pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
103
pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
105
pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
104
106
105
if NETBOOT_SUPPORT
107
if NETBOOT_SUPPORT
106
pre_stage2_exec_LDADD = ../netboot/libdrivers.a
108
pre_stage2_exec_LDADD = ../netboot/libdrivers.a -lgcc
109
else
110
pre_stage2_exec_LDADD = -lgcc
107
endif
111
endif
108
112
109
if DISKLESS_SUPPORT
113
if DISKLESS_SUPPORT
Lines 197-202 Link Here
197
	-DNO_BLOCK_FILES=1
201
	-DNO_BLOCK_FILES=1
198
reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
202
reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
199
203
204
# For btrfs_stage1_5 target.
205
btrfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
206
       disk_io.c stage1_5.c fsys_btrfs.c bios.c
207
btrfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_BTRFS=1 \
208
       -DNO_BLOCK_FILES=1
209
btrfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_BTRFS=1 \
210
       -DNO_BLOCK_FILES=1
211
btrfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
212
btrfs_stage1_5_exec_LDADD = -lgcc
213
200
# For vstafs_stage1_5 target.
214
# For vstafs_stage1_5 target.
201
vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
215
vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
202
	disk_io.c stage1_5.c fsys_vstafs.c bios.c
216
	disk_io.c stage1_5.c fsys_vstafs.c bios.c
Lines 240-246 Link Here
240
diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
254
diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
241
	-DSUPPORT_DISKLESS=1
255
	-DSUPPORT_DISKLESS=1
242
diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK)
256
diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK)
243
diskless_exec_LDADD = ../netboot/libdrivers.a
257
diskless_exec_LDADD = ../netboot/libdrivers.a -lgcc
244
258
245
diskless_size.h: diskless
259
diskless_size.h: diskless
246
	-rm -f $@
260
	-rm -f $@
(-)grub-0.97-r9/stage2/shared.h (-5 / +8 lines)
Lines 209-219 Link Here
209
#define STAGE2_ID_FAT_STAGE1_5		3
209
#define STAGE2_ID_FAT_STAGE1_5		3
210
#define STAGE2_ID_MINIX_STAGE1_5	4
210
#define STAGE2_ID_MINIX_STAGE1_5	4
211
#define STAGE2_ID_REISERFS_STAGE1_5	5
211
#define STAGE2_ID_REISERFS_STAGE1_5	5
212
#define STAGE2_ID_VSTAFS_STAGE1_5	6
212
#define STAGE2_ID_BTRFS_STAGE1_5	6
213
#define STAGE2_ID_JFS_STAGE1_5		7
213
#define STAGE2_ID_VSTAFS_STAGE1_5	7
214
#define STAGE2_ID_XFS_STAGE1_5		8
214
#define STAGE2_ID_JFS_STAGE1_5		8
215
#define STAGE2_ID_ISO9660_STAGE1_5	9
215
#define STAGE2_ID_XFS_STAGE1_5		9
216
#define STAGE2_ID_UFS2_STAGE1_5		10
216
#define STAGE2_ID_ISO9660_STAGE1_5	10
217
#define STAGE2_ID_UFS2_STAGE1_5		11
217
218
218
#ifndef STAGE1_5
219
#ifndef STAGE1_5
219
# define STAGE2_ID	STAGE2_ID_STAGE2
220
# define STAGE2_ID	STAGE2_ID_STAGE2
Lines 228-233 Link Here
228
#  define STAGE2_ID	STAGE2_ID_MINIX_STAGE1_5
229
#  define STAGE2_ID	STAGE2_ID_MINIX_STAGE1_5
229
# elif defined(FSYS_REISERFS)
230
# elif defined(FSYS_REISERFS)
230
#  define STAGE2_ID	STAGE2_ID_REISERFS_STAGE1_5
231
#  define STAGE2_ID	STAGE2_ID_REISERFS_STAGE1_5
232
# elif defined(FSYS_BTRFS)
233
#  define STAGE2_ID	STAGE2_ID_BTRFS_STAGE1_5
231
# elif defined(FSYS_VSTAFS)
234
# elif defined(FSYS_VSTAFS)
232
#  define STAGE2_ID	STAGE2_ID_VSTAFS_STAGE1_5
235
#  define STAGE2_ID	STAGE2_ID_VSTAFS_STAGE1_5
233
# elif defined(FSYS_JFS)
236
# elif defined(FSYS_JFS)

Return to bug 283637