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-gentoo/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-gentoo/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-gentoo/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-gentoo/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-gentoo/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-gentoo/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-gentoo/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-gentoo/stage2/disk_io.c (+3 lines)
Lines 64-69 Link Here
64
# ifdef FSYS_REISERFS
64
# ifdef FSYS_REISERFS
65
  {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
65
  {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
66
# endif
66
# endif
67
# ifdef FSYS_BTRFS
68
  {"btrfs", btrfs_mount, btrfs_read, btrfs_dir, 0, btrfs_embed},
69
# endif
67
# ifdef FSYS_VSTAFS
70
# ifdef FSYS_VSTAFS
68
  {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
71
  {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
69
# endif
72
# endif
(-)grub-0.97-gentoo/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-gentoo/stage2/fsys_btrfs.c (+1818 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
	errnum = ERR_NONE;
445
	if (cdrom_drive != GRUB_INVALID_DRIVE &&
446
	    !get_diskinfo(cdrom_drive, &geom)) {
447
		dev->drive = cdrom_drive;
448
		dev->part = 0;
449
		dev->length = geom.total_sectors;
450
		if (discerner(&dev, lookup)) {
451
			count++;
452
			if (lookup)
453
				goto exit;
454
		}
455
	}
456
#ifdef SUPPORT_NETBOOT
457
	errnum = ERR_NONE;
458
	if (network_ready &&
459
	    !get_diskinfo(NETWORK_DRIVE, &geom)) {
460
		dev->drive = NETWORK_DRIVE;
461
		dev->part = 0;
462
		dev->length = geom.total_sectors;
463
		if (discerner(&dev, lookup)) {
464
			count++;
465
			if (lookup)
466
				goto exit;
467
		}
468
	}
469
#endif /* SUPPORT_NETBOOT */
470
 exit:
471
	return count;
472
}
473
474
#if 0
475
static int btrfs_next_item(struct btrfs_root *root,
476
			   struct btrfs_path *path);
477
478
/*
479
 * Scan the chunk tree for dev items
480
 * and call a seeker for all of them.
481
 * Preconditions: chunk root is installed
482
 * to the global btrfs_fs_info.
483
 */
484
static int scan_dev_tree(struct btrfs_device* (*seeker)(u64))
485
{
486
	int ret;
487
	u64 num_devices = 0;
488
	struct btrfs_key key;
489
	struct btrfs_key found_key;
490
	struct btrfs_path *path;
491
	struct btrfs_root *root;
492
493
	root = BTRFS_CHUNK_ROOT;
494
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
495
	key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
496
	key.type = 0;
497
	key.offset = 0;
498
499
	ret = aux_tree_lookup(root, &key, path);
500
	if (ret == -1)
501
		goto corrupted;
502
	while (1) {
503
		struct btrfs_device *result;
504
		struct btrfs_dev_item *dev_item;
505
506
		btrfs_item_key_to_cpu(&path->nodes[0],
507
				      &found_key,
508
				      path->slots[0]);
509
		if (found_key.objectid != BTRFS_DEV_ITEMS_OBJECTID)
510
			break;
511
		dev_item = btrfs_item_ptr(&path->nodes[0],
512
					  path->slots[0],
513
					  struct btrfs_dev_item);
514
		result = seeker(btrfs_device_id(&path->nodes[0], dev_item));
515
		if (result == NULL) {
516
			btrfs_msg("Btrfs device %llu is not available\n",
517
				  btrfs_device_id(&path->nodes[0], dev_item));
518
			goto missed_dev;
519
		}
520
		num_devices++;
521
		ret = btrfs_next_item(root, path);
522
		if (ret)
523
			break;
524
	}
525
	if (num_devices == btrfs_super_num_devices(BTRFS_SUPER))
526
		return 0;
527
 corrupted:
528
	errnum = ERR_FSYS_CORRUPT;
529
	return 1;
530
 missed_dev:
531
	errnum = ERR_FSYS_MOUNT;
532
	return 1;
533
}
534
#endif /* 0 */
535
536
/*
537
 * Find a grub btrfs device by devid.
538
 * Preconditions: global btrfs_fs_info
539
 * contains a copy of btrfs super block.
540
 *
541
 * Return pointer to the cached device on success.
542
 * Otherwise return NULL.
543
 */
544
static struct btrfs_device *btrfs_lookup_device(u64 devid)
545
{
546
	int i, result;
547
	struct btrfs_device *cdev;
548
549
	for (i = 0; i < BTRFS_NUM_CACHED_DEVICES; i++) {
550
		cdev = &BTRFS_DEVICES[i];
551
		if (cdev->devid == devid)
552
			goto found_in_cache;
553
		if (cdev->devid == 0)
554
			goto not_found_in_cache;
555
	}
556
not_found_in_cache:
557
	cdev = BTRFS_VOLATILE_DEV_CACHE;
558
	cdev->devid = devid;
559
	result = scan_grub_devices(cdev,
560
				   btrfs_discerner,
561
				   1);
562
	if (result == 0)
563
		/*
564
		 * At mount time we have figured out that
565
		 * number of available devices is not less
566
		 * then number of devices recorded in the
567
		 * super block. Hence we treat this case as
568
		 * file system corruption.
569
		 */
570
		goto corrupt;
571
	result = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
572
	if (result)
573
		goto corrupt;
574
found_in_cache:
575
	return cdev;
576
corrupt:
577
	errnum = ERR_FSYS_CORRUPT;
578
	return NULL;
579
}
580
581
static int btrfs_find_device(struct btrfs_device *dev)
582
{
583
	struct btrfs_device *cdev;
584
585
	if (btrfs_super_num_devices(BTRFS_SUPER) == 1) {
586
		dev->drive = current_drive;
587
		dev->part = part_start;
588
		dev->length = part_length;
589
		return 0;
590
	}
591
	cdev = btrfs_lookup_device(dev->devid);
592
	if (cdev == NULL)
593
		return 1;
594
	dev->drive  = cdev->drive;
595
	dev->part   = cdev->part;
596
	dev->length = cdev->length;
597
	return 0;
598
}
599
600
static inline void init_btrfs_volatile_dev_cache(void)
601
{
602
	BTRFS_VOLATILE_DEV_CACHE->devid = 0;
603
	BTRFS_VOLATILE_DEV_CACHE->drive = current_drive;
604
	BTRFS_VOLATILE_DEV_CACHE->part = part_start;
605
	BTRFS_VOLATILE_DEV_CACHE->length = part_length;
606
}
607
608
/*
609
 * check availability of btrfs devices
610
 * and populate the persistent device cache
611
 */
612
static int btrfs_check_devices(void)
613
{
614
	u64 num_dev;
615
616
	if (btrfs_super_num_devices(BTRFS_SUPER) == 1)
617
		return 0;
618
	num_dev = scan_grub_devices(BTRFS_DEVICES,
619
				    btrfs_discerner, 0);
620
	if (btrfs_uptodate_super_copy(BTRFS_FS_INFO))
621
		return 1;
622
	if (num_dev < btrfs_super_num_devices(BTRFS_SUPER)) {
623
		btrfs_msg("Some (%llu) Btrfs devices is not available\n",
624
			  btrfs_super_num_devices(BTRFS_SUPER) - num_dev);
625
	        return 1;
626
	}
627
	return 0;
628
}
629
630
int btrfs_mount(void)
631
{
632
	int ret;
633
634
	check_btrfs_cache_size();
635
	init_btrfs_info();
636
	init_btrfs_volatile_dev_cache();
637
638
	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
639
	if (ret) {
640
		btrfs_msg("Drive %lu, partition %lu: no Btrfs metadata\n",
641
			  current_drive, part_start);
642
		goto error;
643
	}
644
	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
645
	if (ret)
646
		goto error;
647
	BTRFS_FS_INFO->sb_transid =
648
		btrfs_super_generation(BTRFS_SUPER);
649
	memcpy(BTRFS_FS_INFO->fsid,
650
	       BTRFS_SUPER->fsid,
651
	       BTRFS_FSID_SIZE);
652
	ret = btrfs_check_devices();
653
	if (ret)
654
		goto error;
655
	/* setup chunk root */
656
	ret = find_setup_root(NULL,
657
			      btrfs_super_nodesize(BTRFS_SUPER),
658
			      btrfs_super_leafsize(BTRFS_SUPER),
659
			      btrfs_super_sectorsize(BTRFS_SUPER),
660
			      btrfs_super_stripesize(BTRFS_SUPER),
661
			      BTRFS_CHUNK_TREE_OBJECTID,
662
			      BTRFS_CHUNK_ROOT,
663
			      btrfs_super_chunk_root(BTRFS_SUPER),
664
			      btrfs_chunk_root_level_size(BTRFS_SUPER),
665
			      btrfs_super_chunk_root_generation(BTRFS_SUPER),
666
			      FIRST_EXTERNAL_LOOKUP_POOL);
667
	if (ret)
668
		return 0;
669
	/* setup tree root */
670
	ret = find_setup_root(NULL,
671
			      btrfs_super_nodesize(BTRFS_SUPER),
672
			      btrfs_super_leafsize(BTRFS_SUPER),
673
			      btrfs_super_sectorsize(BTRFS_SUPER),
674
			      btrfs_super_stripesize(BTRFS_SUPER),
675
			      BTRFS_ROOT_TREE_OBJECTID,
676
			      BTRFS_TREE_ROOT,
677
			      btrfs_super_root(BTRFS_SUPER),
678
			      btrfs_root_level_size(BTRFS_SUPER),
679
			      btrfs_super_generation(BTRFS_SUPER),
680
			      FIRST_EXTERNAL_LOOKUP_POOL);
681
	if (ret)
682
		return 0;
683
	/* setup fs_root */
684
	ret = find_setup_root(BTRFS_TREE_ROOT,
685
			      btrfs_super_nodesize(BTRFS_SUPER),
686
			      btrfs_super_leafsize(BTRFS_SUPER),
687
			      btrfs_super_sectorsize(BTRFS_SUPER),
688
			      btrfs_super_stripesize(BTRFS_SUPER),
689
			      BTRFS_FS_TREE_OBJECTID,
690
			      BTRFS_FS_ROOT,
691
			      0,
692
			      0,
693
			      0,
694
			      FIRST_EXTERNAL_LOOKUP_POOL);
695
	return !ret;
696
697
error:
698
	errnum = ERR_FSYS_MOUNT;
699
	return 0;
700
}
701
702
/*
703
 * Check, whether @chunk is the map for a
704
 * block with @logical block number.
705
 * If yes, then fill the @map.
706
 * Return 1 on affirmative result,
707
 * otherwise return 0.
708
 */
709
int check_read_chunk(struct btrfs_key *key,
710
			    struct extent_buffer *leaf,
711
			    struct btrfs_chunk *chunk,
712
			    struct map_lookup *map,
713
			    u64 logical)
714
{
715
	int i, ret;
716
	u64 chunk_start;
717
	u64 chunk_size;
718
	int num_stripes;
719
720
	chunk_start = key->offset;
721
	chunk_size = btrfs_chunk_length(leaf, chunk);
722
723
	if (logical + 1 > chunk_start + chunk_size ||
724
	    logical < chunk_start)
725
		/* not a fit */
726
		return 0;
727
	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
728
	map->ce.start = chunk_start;
729
	map->ce.size = chunk_size;
730
	map->num_stripes = num_stripes;
731
	map->io_width = btrfs_chunk_io_width(leaf, chunk);
732
	map->io_align = btrfs_chunk_io_align(leaf, chunk);
733
	map->sector_size = btrfs_chunk_sector_size(leaf, chunk);
734
	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
735
	map->type = btrfs_chunk_type(leaf, chunk);
736
	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
737
738
	for (i = 0; i < num_stripes; i++) {
739
		map->stripes[i].physical =
740
			btrfs_stripe_offset_nr(leaf, chunk, i);
741
		map->stripes[i].dev.devid =
742
			btrfs_stripe_devid_nr(leaf, chunk, i);
743
		ret = btrfs_find_device(&map->stripes[i].dev);
744
		if (ret)
745
			return 0;
746
	}
747
	return 1;
748
}
749
750
static void init_extent_buffer(struct extent_buffer *eb,
751
			       struct btrfs_device *dev,
752
			       u64 logical,
753
			       u32 blocksize,
754
			       u64 physical,
755
			       lookup_pool_id lpid)
756
{
757
	if (dev)
758
		memcpy(&eb->dev, dev, sizeof(*dev));
759
	eb->start = logical;
760
	eb->len = blocksize;
761
	eb->dev_bytenr = physical;
762
	eb->data = grab_lookup_cache(lpid);
763
}
764
765
/*
766
 * Search for a map by logical offset in sys array.
767
 * Return -1 on errors;
768
 * Return 1 if the map is found,
769
 * Return 0 if the map is not found.
770
 */
771
int sys_array_lookup(struct map_lookup *map, u64 logical)
772
{
773
	struct extent_buffer sb;
774
	struct btrfs_disk_key *disk_key;
775
	struct btrfs_chunk *chunk;
776
	struct btrfs_key key;
777
	u32 num_stripes;
778
	u32 array_size;
779
	u32 len = 0;
780
	u8 *ptr;
781
	unsigned long sb_ptr;
782
	u32 cur;
783
	int ret;
784
	int i = 0;
785
786
	sb.data = (char *)BTRFS_SUPER;
787
	array_size = btrfs_super_sys_array_size(BTRFS_SUPER);
788
789
	ptr = BTRFS_SUPER->sys_chunk_array;
790
	sb_ptr = offsetof(struct btrfs_super_block, sys_chunk_array);
791
	cur = 0;
792
793
	while (cur < array_size) {
794
		disk_key = (struct btrfs_disk_key *)ptr;
795
		btrfs_disk_key_to_cpu(&key, disk_key);
796
797
		len = sizeof(*disk_key);
798
		ptr += len;
799
		sb_ptr += len;
800
		cur += len;
801
802
		if (key.type == BTRFS_CHUNK_ITEM_KEY) {
803
			chunk = (struct btrfs_chunk *)sb_ptr;
804
			ret = check_read_chunk(&key, &sb,
805
					       chunk, map, logical);
806
			if (ret)
807
				/* map is found */
808
				return ret;
809
			num_stripes = btrfs_chunk_num_stripes(&sb, chunk);
810
			len = btrfs_chunk_item_size(num_stripes);
811
		} else {
812
			errnum = ERR_FSYS_CORRUPT;
813
			return -1;
814
		}
815
		ptr += len;
816
		sb_ptr += len;
817
		cur += len;
818
		i++;
819
	}
820
	return 0;
821
}
822
823
/*
824
 * Search for a map by logical offset in the chunk tree.
825
 * Return 1 if map is found, otherwise return 0.
826
 */
827
static int chunk_tree_lookup(struct map_lookup *map,
828
			     u64 logical)
829
{
830
	int ret;
831
	int slot;
832
	struct extent_buffer *leaf;
833
	struct btrfs_key key;
834
	struct btrfs_key found_key;
835
	struct btrfs_chunk *chunk;
836
	struct btrfs_path *path;
837
838
	path = btrfs_grab_path(INTERNAL_LOOKUP_POOL);
839
840
	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
841
	key.offset = logical;
842
	key.type = BTRFS_CHUNK_ITEM_KEY;
843
844
	ret = aux_tree_lookup(BTRFS_CHUNK_ROOT, &key, path);
845
	if (ret < 0)
846
		return 0;
847
	leaf = &path->nodes[0];
848
	slot = path->slots[0];
849
	if (ret == 1) {
850
		WARN_ON(slot == 0);
851
		slot -= 1;
852
	}
853
	btrfs_item_key_to_cpu(leaf, &found_key, slot);
854
	if (found_key.type != BTRFS_CHUNK_ITEM_KEY)
855
		return 0;
856
	chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
857
	return check_read_chunk(&found_key, leaf,
858
				chunk, map, logical);
859
}
860
861
/*
862
 * Btrfs logical/physical block mapper.
863
 * Look for an appropriate map-extent and
864
 * perform a translation. Return 1 on errors.
865
 */
866
static int btrfs_map_block(u64 logical, u64 *length,
867
			   struct btrfs_multi_bio *multi,
868
			   int mirror_num)
869
{
870
	struct map_lookup map;
871
	u64 offset;
872
	u64 stripe_offset;
873
	u64 stripe_nr;
874
	struct cache_extent *ce;
875
	int stripe_index;
876
	int i;
877
	int ret;
878
879
	memset(&map, 0, sizeof(map));
880
	ret = sys_array_lookup(&map, logical);
881
	if (ret == -1) {
882
		errnum = ERR_FSYS_CORRUPT;
883
		return 1;
884
	}
885
	if (ret == 0) {
886
		ret = chunk_tree_lookup(&map, logical);
887
		if (!ret) {
888
			/* something should be found! */
889
			errnum = ERR_FSYS_CORRUPT;
890
			return 1;
891
		}
892
	}
893
	/* do translation */
894
	ce = &map.ce;
895
896
	offset = logical - ce->start;
897
	stripe_nr = offset / map.stripe_len;
898
	stripe_offset = stripe_nr * map.stripe_len;
899
	WARN_ON(offset < stripe_offset);
900
901
	stripe_offset = offset - stripe_offset;
902
903
	if (map.type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
904
			 BTRFS_BLOCK_GROUP_RAID10 |
905
			 BTRFS_BLOCK_GROUP_DUP)) {
906
		*length = min_t(u64, ce->size - offset,
907
			      map.stripe_len - stripe_offset);
908
	} else {
909
		*length = ce->size - offset;
910
	}
911
	multi->num_stripes = 1;
912
	stripe_index = 0;
913
	if (map.type & BTRFS_BLOCK_GROUP_RAID1) {
914
		if (mirror_num)
915
			stripe_index = mirror_num - 1;
916
		else
917
			stripe_index = stripe_nr % map.num_stripes;
918
	} else if (map.type & BTRFS_BLOCK_GROUP_RAID10) {
919
		int factor = map.num_stripes / map.sub_stripes;
920
921
		stripe_index = stripe_nr % factor;
922
		stripe_index *= map.sub_stripes;
923
924
		if (mirror_num)
925
			stripe_index += mirror_num - 1;
926
		else
927
			stripe_index = stripe_nr % map.sub_stripes;
928
929
		stripe_nr = stripe_nr / factor;
930
	} else if (map.type & BTRFS_BLOCK_GROUP_DUP) {
931
		if (mirror_num)
932
			stripe_index = mirror_num - 1;
933
	} else {
934
		stripe_index = stripe_nr % map.num_stripes;
935
		stripe_nr = stripe_nr / map.num_stripes;
936
	}
937
	WARN_ON(stripe_index >= map.num_stripes);
938
939
	for (i = 0; i < multi->num_stripes; i++) {
940
		asm("" : "+r"(multi));
941
		multi->stripes[i].physical =
942
			map.stripes[stripe_index].physical + stripe_offset +
943
			stripe_nr * map.stripe_len;
944
		memcpy(&multi->stripes[i].dev,
945
		       &map.stripes[stripe_index].dev,
946
		       sizeof(struct btrfs_device));
947
		stripe_index++;
948
	}
949
	return 0;
950
}
951
952
static u64 read_data_extent(u64 logical_start, u64 to_read, char *pos)
953
{
954
	int ret;
955
	u64 length;
956
	struct btrfs_multi_bio multi;
957
958
	while (to_read) {
959
		ret = btrfs_map_block(logical_start, &length, &multi, 0);
960
		if (ret) {
961
			errnum = ERR_FSYS_CORRUPT;
962
			return ret;
963
		}
964
		if (length > to_read)
965
			length = to_read;
966
		disk_read_func = disk_read_hook;
967
		ret = btrfs_devread(multi.stripes[0].dev.drive,
968
				    multi.stripes[0].dev.part,
969
				    multi.stripes[0].dev.length,
970
				    multi.stripes[0].physical >> SECTOR_BITS,
971
				    logical_start & ((u64)SECTOR_SIZE - 1),
972
				    length,
973
				    pos);
974
		disk_read_func = NULL;
975
		if (!ret)
976
			return 1;
977
		btrfs_msg("BTRFS data extent: read %llu bytes\n", length);
978
		to_read -= length;
979
		pos += length;
980
		logical_start += length;
981
	}
982
	return 0;
983
}
984
985
static int read_extent_from_disk(struct extent_buffer *eb)
986
{
987
	WARN_ON(eb->dev_bytenr % SECTOR_BITS);
988
	return btrfs_devread(eb->dev.drive,
989
			     eb->dev.part,
990
			     eb->dev.length,
991
			     eb->dev_bytenr >> SECTOR_BITS,
992
			     0,
993
			     eb->len,
994
			     eb->data);
995
}
996
997
static int verify_parent_transid(struct extent_buffer *eb, u64 parent_transid)
998
{
999
	return parent_transid && (btrfs_header_generation(eb) != parent_transid);
1000
}
1001
1002
static int btrfs_num_copies(u64 logical, u64 len)
1003
{
1004
	return 1;
1005
}
1006
1007
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
1008
{
1009
	return 0;
1010
}
1011
1012
static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
1013
		    int verify)
1014
{
1015
	return 0;
1016
}
1017
1018
/*
1019
 * Read a block of logical number @bytenr
1020
 * from disk to buffer @eb.
1021
 * Return 1 on success.
1022
 */
1023
int read_tree_block(struct btrfs_root *root,
1024
		    struct extent_buffer *eb,
1025
		    u64 bytenr, /* logical */
1026
		    u32 blocksize,
1027
		    u64 parent_transid,
1028
		    lookup_pool_id lpid)
1029
{
1030
	int ret;
1031
	int dev_nr;
1032
	u64 length;
1033
	struct btrfs_multi_bio multi;
1034
	int mirror_num = 0;
1035
	int num_copies;
1036
1037
	dev_nr = 0;
1038
	length = blocksize;
1039
	while (1) {
1040
		ret = btrfs_map_block(bytenr,
1041
				      &length, &multi, mirror_num);
1042
		if (ret) {
1043
			errnum = ERR_FSYS_CORRUPT;
1044
			return 0;
1045
		}
1046
		init_extent_buffer(eb,
1047
				   &multi.stripes[0].dev,
1048
				   bytenr,
1049
				   blocksize,
1050
				   multi.stripes[0].physical,
1051
				   lpid);
1052
1053
		ret = read_extent_from_disk(eb);
1054
		if (ret &&
1055
		    check_tree_block(root, eb) == 0 &&
1056
		    csum_tree_block(root, eb, 1) == 0 &&
1057
		    verify_parent_transid(eb, parent_transid) == 0)
1058
			return 1;
1059
1060
		num_copies = btrfs_num_copies(eb->start, eb->len);
1061
		if (num_copies == 1)
1062
			break;
1063
		mirror_num++;
1064
		if (mirror_num > num_copies)
1065
			break;
1066
	}
1067
	return 0;
1068
}
1069
1070
/*
1071
 * Read a child pointed by @slot node pointer
1072
 * of @parent. Put the result to @parent.
1073
 * Return 1 on success.
1074
 */
1075
static int parent2child(struct btrfs_root *root,
1076
			struct extent_buffer *parent,
1077
			int slot,
1078
			lookup_pool_id lpid)
1079
{
1080
	int level;
1081
1082
	WARN_ON(slot < 0);
1083
	WARN_ON(slot >= btrfs_header_nritems(parent));
1084
1085
	level = btrfs_header_level(parent);
1086
	WARN_ON(level <= 0);
1087
1088
	return read_tree_block(root,
1089
			       parent,
1090
			       btrfs_node_blockptr(parent, slot),
1091
			       btrfs_level_size(root, level - 1),
1092
			       btrfs_node_ptr_generation(parent, slot),
1093
			       lpid);
1094
}
1095
1096
static int btrfs_comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
1097
{
1098
	struct btrfs_key k1;
1099
1100
	btrfs_disk_key_to_cpu(&k1, disk);
1101
1102
	if (k1.objectid > k2->objectid)
1103
		return 1;
1104
	if (k1.objectid < k2->objectid)
1105
		return -1;
1106
	if (k1.type > k2->type)
1107
		return 1;
1108
	if (k1.type < k2->type)
1109
		return -1;
1110
	if (k1.offset > k2->offset)
1111
		return 1;
1112
	if (k1.offset < k2->offset)
1113
		return -1;
1114
	return 0;
1115
}
1116
1117
static int bin_search(struct extent_buffer *eb, unsigned long p,
1118
		      int item_size, struct btrfs_key *key,
1119
		      int max, int *slot)
1120
{
1121
	int low = 0;
1122
	int high = max;
1123
	int mid;
1124
	int ret;
1125
	unsigned long offset;
1126
	struct btrfs_disk_key *tmp;
1127
1128
	while(low < high) {
1129
		mid = (low + high) / 2;
1130
		offset = p + mid * item_size;
1131
1132
		tmp = (struct btrfs_disk_key *)(eb->data + offset);
1133
		ret = btrfs_comp_keys(tmp, key);
1134
1135
		if (ret < 0)
1136
			low = mid + 1;
1137
		else if (ret > 0)
1138
			high = mid;
1139
		else {
1140
			*slot = mid;
1141
			return 0;
1142
		}
1143
	}
1144
	*slot = low;
1145
	return 1;
1146
}
1147
1148
/* look for a key in a node */
1149
static int node_lookup(struct extent_buffer *eb,
1150
		       struct btrfs_key *key,
1151
		       int *slot)
1152
{
1153
	if (btrfs_header_level(eb) == 0) {
1154
		return bin_search(eb,
1155
				  offsetof(struct btrfs_leaf, items),
1156
				  sizeof(struct btrfs_item),
1157
				  key, btrfs_header_nritems(eb),
1158
				  slot);
1159
	} else {
1160
		return bin_search(eb,
1161
				  offsetof(struct btrfs_node, ptrs),
1162
				  sizeof(struct btrfs_key_ptr),
1163
				  key, btrfs_header_nritems(eb),
1164
				  slot);
1165
	}
1166
	return -1;
1167
}
1168
1169
static inline int check_node(struct extent_buffer *buf, int slot)
1170
{
1171
	return 0;
1172
}
1173
1174
/*
1175
 * Look for an item by key in read-only tree.
1176
 * Return 0, if key was found. Return -1 on io errors.
1177
 *
1178
 * Preconditions: btrfs_mount already executed.
1179
 * Postconditions: if returned value is non-negative,
1180
 * then path[0] represents the found position in the
1181
 * tree. All components of the @path from leaf to root
1182
 * are valid except their data buffers (only path[0]
1183
 * has valid attached data buffer).
1184
 */
1185
1186
int aux_tree_lookup(struct btrfs_root *root,
1187
		    struct btrfs_key *key,
1188
		    struct btrfs_path *path)
1189
{
1190
	int ret;
1191
	int slot = 0;
1192
	int level;
1193
	struct extent_buffer node;
1194
	init_extent_buffer(&node,
1195
			   NULL,
1196
			   0,
1197
			   0,
1198
			   0,
1199
			   path->lpid);
1200
	copy_extent_buffer(&node, &root->node);
1201
	do {
1202
		level = btrfs_header_level(&node);
1203
		ret = check_node(&node, slot);
1204
		if (ret)
1205
			return -1;
1206
		move_extent_buffer(&path->nodes[level],
1207
				   &node);
1208
		ret = node_lookup(&node, key, &slot);
1209
		if (ret < 0)
1210
			return ret;
1211
		if (level) {
1212
		        /*
1213
			 * non-leaf,
1214
			 * jump to the next level
1215
			 */
1216
			if (ret && slot > 0)
1217
			        slot -= 1;
1218
			ret = parent2child(root, &node, slot, path->lpid);
1219
			if (ret == 0)
1220
				return -1;
1221
		}
1222
		path->slots[level] = slot;
1223
	} while (level);
1224
	return ret;
1225
}
1226
1227
static int readup_buffer(struct extent_buffer *buf, lookup_pool_id lpid)
1228
{
1229
	buf->data = grab_lookup_cache(lpid);
1230
	return read_extent_from_disk(buf);
1231
}
1232
1233
/*
1234
 * Find the next leaf in accordance with tree order;
1235
 * walk up the tree as far as required to find it.
1236
 * Returns 0 if something was found, or 1 if there
1237
 * are no greater leaves. Returns < 0 on io errors.
1238
 *
1239
 * Preconditions: all @path components from leaf to
1240
 * root have valid meta-data fields. path[0] has a
1241
 * valid attached data buffer with initial leaf.
1242
 * Postcondition: the same as above, but path[0] has
1243
 * an attached data buffer with the next leaf.
1244
 */
1245
static int btrfs_next_leaf(struct btrfs_root *root,
1246
			   struct btrfs_path *path)
1247
{
1248
	int res;
1249
	int slot;
1250
	int level = 1;
1251
	struct extent_buffer *buf;
1252
1253
	while(level < BTRFS_MAX_LEVEL) {
1254
		buf = &path->nodes[level];
1255
		slot = path->slots[level] + 1;
1256
		/*
1257
		 * lift data on this level
1258
		 */
1259
		res = readup_buffer(buf, path->lpid);
1260
		if (!res)
1261
			break;
1262
		if (slot >= btrfs_header_nritems(buf)) {
1263
			/* alas, go to parent (if any) */
1264
			level++;
1265
			res = 1;
1266
			continue;
1267
		}
1268
		break;
1269
	}
1270
	if (!res)
1271
		return 1;
1272
	/*
1273
	 * At this level slot points to
1274
	 * the subtree we are interested in.
1275
	 */
1276
	path->slots[level] = slot;
1277
	while(level) {
1278
		struct extent_buffer tmp;
1279
		move_extent_buffer(&tmp, &path->nodes[level]);
1280
		res = parent2child(root, &tmp, slot, path->lpid);
1281
		if (res == 0)
1282
			return -1;
1283
		level --;
1284
		slot = 0;
1285
		move_extent_buffer(&path->nodes[level], &tmp);
1286
		path->slots[level] = slot;
1287
	}
1288
	return 0;
1289
}
1290
1291
/* Preconditions: path is valid, data buffer
1292
 * is attached to leaf node.
1293
 * Postcondition: path is updated to point to
1294
 * the next position with respect to the tree
1295
 * order.
1296
 *
1297
 * Return -1 on io errors.
1298
 * Return 0, if next item was found.
1299
 * Return 1, if next item wasn't found (no more items).
1300
 */
1301
static int btrfs_next_item(struct btrfs_root *root,
1302
			   struct btrfs_path *path)
1303
{
1304
	WARN_ON(path->slots[0] >= btrfs_header_nritems(&path->nodes[0]));
1305
1306
	path->slots[0] += 1;
1307
1308
	if (path->slots[0] < btrfs_header_nritems(&path->nodes[0]))
1309
		return 0;
1310
	if (coord_is_root(root, path))
1311
		/* no more items */
1312
		return 1;
1313
	return btrfs_next_leaf(root, path);
1314
}
1315
1316
/*
1317
 * check if we can reuse results of previous
1318
 * search for read operation
1319
 */
1320
static int path_is_valid(struct btrfs_path *path,
1321
			 struct btrfs_key *key, u64 offset)
1322
{
1323
	btrfs_item_key_to_cpu(&path->nodes[0],
1324
			      key,
1325
			      path->slots[0]);
1326
	if (BTRFS_FILE_INFO_KEY->objectid != key->objectid)
1327
		return 0;
1328
	if (btrfs_key_type(key) == BTRFS_INODE_ITEM_KEY)
1329
		return 1;
1330
	if (btrfs_key_type(key) != BTRFS_EXTENT_DATA_KEY)
1331
		return 0;
1332
	return BTRFS_FILE_INFO_KEY->offset <= offset;
1333
}
1334
1335
/* ->read_func() */
1336
int btrfs_read(char *buf, int len)
1337
{
1338
	int ret;
1339
	struct btrfs_root *fs_root;
1340
	struct btrfs_path *path;
1341
	struct btrfs_key  path_key;
1342
	u64 ioff;
1343
	u64 bytes;
1344
	int to_read;
1345
	char *pos = buf;
1346
1347
	fs_root = BTRFS_FS_ROOT;
1348
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
1349
1350
	if (!path_is_valid(path, &path_key, filepos)) {
1351
		ret = aux_tree_lookup(fs_root, BTRFS_FILE_INFO_KEY, path);
1352
		if (ret < 0)
1353
			errnum = ERR_FSYS_CORRUPT;
1354
	}
1355
	while (!errnum) {
1356
		struct btrfs_item *item;
1357
		struct btrfs_file_extent_item *fi;
1358
		u64 from;
1359
1360
		btrfs_item_key_to_cpu(&path->nodes[0],
1361
				      &path_key,
1362
				      path->slots[0]);
1363
		if (BTRFS_FILE_INFO_KEY->objectid != path_key.objectid)
1364
			break;
1365
		if (btrfs_key_type(&path_key) != BTRFS_EXTENT_DATA_KEY)
1366
			goto next;
1367
		/*
1368
		 * current position is extent item
1369
		 */
1370
		item = btrfs_item_nr(&path->nodes[0], path->slots[0]);
1371
		fi = btrfs_item_ptr(&path->nodes[0],
1372
				    path->slots[0],
1373
				    struct btrfs_file_extent_item);
1374
		if (btrfs_file_extent_compression(&path->nodes[0], fi)) {
1375
		       btrfs_msg("Btrfs transparent compression unsupported\n");
1376
		       errnum = ERR_BAD_FILETYPE;
1377
		       goto exit;
1378
		}
1379
		ioff = filepos - path_key.offset;
1380
1381
		switch (btrfs_file_extent_type(&path->nodes[0], fi)) {
1382
		case BTRFS_FILE_EXTENT_INLINE:
1383
			bytes = btrfs_file_extent_inline_item_len(&path->
1384
								  nodes[0],
1385
								  item);
1386
			if (path_key.offset + bytes < filepos)
1387
				goto next;
1388
			to_read = bytes - ioff;
1389
			if (to_read > len)
1390
				to_read = len;
1391
			from = ioff + btrfs_file_extent_inline_start(fi);
1392
			if (disk_read_hook != NULL) {
1393
				disk_read_func = disk_read_hook;
1394
				ret = btrfs_devread(path->nodes[0].dev.drive,
1395
						    path->nodes[0].dev.part,
1396
						    path->nodes[0].dev.length,
1397
						    path->nodes[0].dev_bytenr >>
1398
						    SECTOR_BITS,
1399
						    from,
1400
						    to_read,
1401
						    pos);
1402
				disk_read_func = NULL;
1403
				if (ret)
1404
					goto exit;
1405
			} else
1406
				memcpy(pos,
1407
				       path->nodes[0].data + from,
1408
				       to_read);
1409
			btrfs_msg("BTRFS inline extent: read %d bytes pos %d\n",
1410
				  to_read, filepos);
1411
			break;
1412
		case BTRFS_FILE_EXTENT_REG:
1413
			bytes = btrfs_file_extent_num_bytes(&path->nodes[0],
1414
							    fi);
1415
			if (path_key.offset + bytes < filepos)
1416
				goto next;
1417
			to_read = bytes - ioff;
1418
			if (to_read > len)
1419
				to_read = len;
1420
			from = ioff +
1421
				btrfs_file_extent_disk_bytenr(&path->nodes[0],
1422
							      fi) +
1423
				btrfs_file_extent_offset(&path->nodes[0],
1424
							 fi);
1425
			ret = read_data_extent(from, to_read, pos);
1426
			if (ret)
1427
				goto exit;
1428
			break;
1429
		case BTRFS_FILE_EXTENT_PREALLOC:
1430
			btrfs_msg("Btrfs preallocated extents unsupported\n");
1431
			errnum = ERR_BAD_FILETYPE;
1432
			goto exit;
1433
		default:
1434
			errnum = ERR_FSYS_CORRUPT;
1435
			goto exit;
1436
		}
1437
		len -= to_read;
1438
		pos += to_read;
1439
		filepos += to_read;
1440
		if (len == 0)
1441
			break;
1442
		/* not everything was read */
1443
	next:
1444
		ret = btrfs_next_item(fs_root, path);
1445
		if (ret < 0) {
1446
			errnum = ERR_FSYS_CORRUPT;
1447
			break;
1448
		}
1449
		btrfs_update_file_info(path);
1450
		continue;
1451
	}
1452
exit:
1453
	return errnum ? 0 : pos - buf;
1454
}
1455
1456
static int btrfs_follow_link(struct btrfs_root *root,
1457
			     struct btrfs_path *path,
1458
			     char **dirname, char *linkbuf,
1459
			     int *link_count,
1460
			     struct btrfs_inode_item *sd)
1461
{
1462
	int ret;
1463
	int len;
1464
	char *name = *dirname;
1465
1466
	if (++(*link_count) > MAX_LINK_COUNT) {
1467
		errnum = ERR_SYMLINK_LOOP;
1468
		return 0;
1469
	}
1470
	/* calculate remaining name size */
1471
	filemax = btrfs_inode_size(&path->nodes[0], sd);
1472
	for (len = 0;
1473
	     name[len] && isspace(name[len]);
1474
	     len ++);
1475
1476
	if (filemax + len > PATH_MAX - 1) {
1477
		errnum = ERR_FILELENGTH;
1478
		return 0;
1479
	}
1480
	grub_memmove(linkbuf + filemax, name, len + 1);
1481
	btrfs_update_file_info(path);
1482
	filepos = 0;
1483
	/* extract symlink content */
1484
	while (1) {
1485
		u64 oid = BTRFS_FILE_INFO_KEY->objectid;
1486
		ret = btrfs_next_item(root, path);
1487
		if (ret)
1488
			break;
1489
		btrfs_update_file_info(path);
1490
		if (oid != BTRFS_FILE_INFO_KEY->objectid)
1491
			break;
1492
		if (btrfs_key_type(BTRFS_FILE_INFO_KEY) ==
1493
		    BTRFS_EXTENT_DATA_KEY)
1494
			goto found;
1495
	}
1496
	/* no target was found */
1497
	errnum = ERR_FSYS_CORRUPT;
1498
	return 0;
1499
found:
1500
	/* fill the rest of linkbuf with the content */
1501
	ret = btrfs_read(linkbuf, filemax);
1502
	if (ret != filemax) {
1503
		errnum = ERR_FSYS_CORRUPT;
1504
		return 0;
1505
	}
1506
	return 1;
1507
}
1508
1509
static int update_fs_root(struct btrfs_root *fs_root,
1510
			  struct btrfs_key *location)
1511
{
1512
	int ret;
1513
	struct btrfs_root *tree_root;
1514
1515
	if (location->offset != (u64)-1)
1516
		return 0;
1517
	tree_root = &BTRFS_FS_INFO->tree_root;
1518
	ret = find_setup_root(tree_root,
1519
			      tree_root->nodesize,
1520
			      tree_root->leafsize,
1521
			      tree_root->sectorsize,
1522
			      tree_root->stripesize,
1523
			      location->objectid,
1524
			      fs_root,
1525
			      0,
1526
			      0,
1527
			      0,
1528
			      SECOND_EXTERNAL_LOOKUP_POOL);
1529
	if (ret)
1530
		return ret;
1531
	location->objectid = btrfs_root_dirid(&fs_root->root_item);
1532
	btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY);
1533
	location->offset = 0;
1534
	return 0;
1535
}
1536
1537
#ifndef STAGE1_5
1538
static inline void update_possibilities(void)
1539
{
1540
	if (print_possibilities > 0)
1541
		print_possibilities =
1542
			-print_possibilities;
1543
}
1544
#endif
1545
1546
/*
1547
 * Look for a directory item by name.
1548
 * Print possibilities, if needed.
1549
 * Postconditions: on success @sd_key points
1550
 * to the key contained in the directory entry.
1551
 */
1552
static int btrfs_de_index_by_name(struct btrfs_root *root,
1553
				  struct btrfs_path *path,
1554
				  char **dirname,
1555
				  struct btrfs_key *sd_key)
1556
{
1557
	char ch;
1558
	int ret;
1559
	char *rest;
1560
	struct btrfs_dir_item *di;
1561
#ifndef STAGE1_5
1562
	int do_possibilities = 0;
1563
#endif
1564
	for (; **dirname == '/'; (*dirname)++);
1565
	for (rest = *dirname;
1566
	     (ch = *rest) && !isspace(ch) && ch != '/';
1567
	     rest++);
1568
	*rest = 0; /* for substrung() */
1569
#ifndef STAGE1_5
1570
	if (print_possibilities && ch != '/')
1571
		do_possibilities = 1;
1572
#endif
1573
	/* scan a directory */
1574
	while (1) {
1575
		u32 total;
1576
		u32 cur = 0;
1577
		u32 len;
1578
		struct btrfs_key di_key;
1579
		struct btrfs_disk_key location;
1580
		struct btrfs_item *item;
1581
1582
		/* extract next dir entry */
1583
		ret = btrfs_next_item(root, path);
1584
		if (ret)
1585
			break;
1586
		item = btrfs_item_nr(&path->nodes[0],
1587
				     path->slots[0]);
1588
		btrfs_item_key_to_cpu(&path->nodes[0],
1589
				      &di_key,
1590
				      path->slots[0]);
1591
		if (di_key.objectid != sd_key->objectid)
1592
			/* no more entries */
1593
			break;
1594
		di = btrfs_item_ptr(&path->nodes[0],
1595
				    path->slots[0],
1596
				    struct btrfs_dir_item);
1597
		/*
1598
		 * working around special cases:
1599
		 * btrfs doesn't maintain directory entries
1600
		 * which contain names "." and ".."
1601
		 */
1602
		if (!substring(".", *dirname)) {
1603
#ifndef STAGE1_5
1604
			if (do_possibilities) {
1605
				update_possibilities();
1606
				return 1;
1607
			}
1608
#endif
1609
			goto found;
1610
		}
1611
		if (!substring("..", *dirname)) {
1612
			if (di_key.type != BTRFS_INODE_REF_KEY)
1613
				continue;
1614
			sd_key->objectid = di_key.offset;
1615
			btrfs_set_key_type(sd_key, BTRFS_INODE_ITEM_KEY);
1616
			sd_key->offset = 0;
1617
#ifndef STAGE1_5
1618
			if (do_possibilities) {
1619
				update_possibilities();
1620
				return 1;
1621
			}
1622
#endif
1623
			goto found;
1624
		}
1625
		if (di_key.type != BTRFS_DIR_ITEM_KEY)
1626
			continue;
1627
		total = btrfs_item_size(&path->nodes[0], item);
1628
		/* scan a directory item */
1629
		while (cur < total) {
1630
			char tmp;
1631
			int result;
1632
			char *filename;
1633
			char *end_of_name;
1634
			int name_len;
1635
			int data_len;
1636
1637
			btrfs_dir_item_key(&path->nodes[0], di, &location);
1638
1639
			name_len = btrfs_dir_name_len(&path->nodes[0], di);
1640
			data_len = btrfs_dir_data_len(&path->nodes[0], di);
1641
1642
			WARN_ON(name_len > BTRFS_NAME_LEN);
1643
1644
			filename = (char *)(path->nodes[0].data +
1645
					    (unsigned long)(di + 1));
1646
			end_of_name = filename + name_len;
1647
			/*
1648
			 * working around not null-terminated
1649
			 * directory names in btrfs: just
1650
			 * a short-term overwrite of the
1651
			 * cache with the following rollback
1652
			 * of the change.
1653
			 */
1654
			tmp = *end_of_name;
1655
			*end_of_name = 0;
1656
			result = substring(*dirname, filename);
1657
			*end_of_name = tmp;
1658
#ifndef STAGE1_5
1659
			if (do_possibilities) {
1660
				if (result <= 0) {
1661
					update_possibilities();
1662
					*end_of_name = 0;
1663
					print_a_completion(filename);
1664
					*end_of_name = tmp;
1665
				}
1666
			}
1667
			else
1668
#endif
1669
				if (result == 0) {
1670
				      btrfs_dir_item_key_to_cpu(&path->nodes[0],
1671
								di, sd_key);
1672
				      goto found;
1673
				}
1674
			len = sizeof(*di) + name_len + data_len;
1675
			di = (struct btrfs_dir_item *)((char *)di + len);
1676
			cur += len;
1677
		}
1678
	}
1679
#ifndef STAGE1_5
1680
	if (print_possibilities < 0)
1681
		return 1;
1682
#endif
1683
	errnum = ERR_FILE_NOT_FOUND;
1684
	*rest = ch;
1685
	return 0;
1686
 found:
1687
	*rest = ch;
1688
	*dirname = rest;
1689
	return 1;
1690
}
1691
1692
/*
1693
 * ->dir_func().
1694
 * Postcondition: on a non-zero return BTRFS_FS_INFO
1695
 * contains the latest fs_root of file's subvolume.
1696
 * BTRFS_FS_INFO points to a subvolume of a file we
1697
 * were trying to look up.
1698
 * BTRFS_FILE_INFO contains info of the file we were
1699
 * trying to look up.
1700
 */
1701
1702
int btrfs_dir(char *dirname)
1703
{
1704
	int ret;
1705
	int mode;
1706
	u64 size;
1707
	int linkcount = 0;
1708
	char linkbuf[PATH_MAX];
1709
1710
	struct btrfs_path *path;
1711
	struct btrfs_root *root;
1712
1713
	struct btrfs_key sd_key;
1714
	struct btrfs_inode_item *sd;
1715
	struct btrfs_key parent_sd_key;
1716
1717
	root = BTRFS_FS_ROOT;
1718
	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
1719
1720
	btrfs_set_root_dir_key(&sd_key);
1721
	while (1) {
1722
		struct extent_buffer *leaf;
1723
		ret = aux_tree_lookup(root, &sd_key, path);
1724
		if (ret)
1725
			return 0;
1726
		leaf = &path->nodes[0];
1727
		sd = btrfs_item_ptr(leaf,
1728
				    path->slots[0],
1729
				    struct btrfs_inode_item);
1730
		mode = btrfs_inode_mode(leaf, sd);
1731
		size = btrfs_inode_size(leaf, sd);
1732
		switch (btrfs_get_file_type(mode)) {
1733
		case BTRFS_SYMLINK_FILE:
1734
			ret = btrfs_follow_link(root,
1735
						path,
1736
						&dirname,
1737
						linkbuf,
1738
						&linkcount,
1739
						sd);
1740
			if (!ret)
1741
				return 0;
1742
			dirname = linkbuf;
1743
			if (*dirname == '/')
1744
				/* absolute name */
1745
				btrfs_set_root_dir_key(&sd_key);
1746
			else
1747
				memcpy(&sd_key, &parent_sd_key,
1748
				       sizeof(sd_key));
1749
			continue;
1750
		case BTRFS_REGULAR_FILE:
1751
			/*
1752
			 * normally we want to exit here
1753
			 */
1754
			if (*dirname && !isspace (*dirname)) {
1755
				errnum = ERR_BAD_FILETYPE;
1756
				return 0;
1757
			}
1758
			filepos = 0;
1759
			filemax = btrfs_inode_size(leaf, sd);
1760
			btrfs_update_file_info(path);
1761
			return 1;
1762
		case BTRFS_DIRECTORY_FILE:
1763
			memcpy(&parent_sd_key, &sd_key, sizeof(sd_key));
1764
			ret = btrfs_de_index_by_name(root,
1765
						     path,
1766
						     &dirname,
1767
						     &sd_key);
1768
			if (!ret)
1769
				return 0;
1770
#ifndef STAGE1_5
1771
			if (print_possibilities < 0)
1772
				return 1;
1773
#endif
1774
			/*
1775
			 * update fs_tree:
1776
			 * subvolume stuff goes here
1777
			 */
1778
			ret = update_fs_root(root, &sd_key);
1779
			if (ret)
1780
				return 0;
1781
			continue;
1782
		case BTRFS_UNKNOWN_FILE:
1783
		default:
1784
			btrfs_msg("Btrfs: bad file type\n");
1785
			errnum = ERR_BAD_FILETYPE;
1786
			return 0;
1787
		}
1788
	}
1789
}
1790
1791
int btrfs_embed(int *start_sector, int needed_sectors)
1792
{
1793
	int ret;
1794
	init_btrfs_info();
1795
	init_btrfs_volatile_dev_cache();
1796
1797
	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
1798
	if (ret)
1799
		return 0;
1800
	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
1801
	if (ret)
1802
		return 0;
1803
	*start_sector = 1; /* reserve first sector for stage1 */
1804
	return needed_sectors <=
1805
		((BTRFS_SUPER_INFO_OFFSET >> SECTOR_BITS) - 1);
1806
}
1807
#endif /* FSYS_BTRFS */
1808
1809
/*
1810
  Local variables:
1811
  c-indentation-style: "K&R"
1812
  mode-name: "LC"
1813
  c-basic-offset: 8
1814
  tab-width: 8
1815
  fill-column: 80
1816
  scroll-step: 1
1817
  End:
1818
*/
(-)grub-0.97-gentoo/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-gentoo/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