Magellan Linux

Annotation of /trunk/grub/patches/grub-0.97-ext4-4.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1053 - (hide annotations) (download)
Fri Jun 25 10:52:50 2010 UTC (13 years, 11 months ago) by niro
File size: 9101 byte(s)
more patches and fixed ext4 patch

1 niro 1053 diff -ruNp grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patch/stage2/fsys_ext2fs.c
2     --- grub-0.97/stage2/fsys_ext2fs.c 2004-08-08 20:19:18.000000000 +0200
3     +++ grub-0.97-patch/stage2/fsys_ext2fs.c 2007-12-29 16:25:19.000000000
4     +0100
5     @@ -51,6 +51,9 @@ typedef unsigned int __u32;
6     #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
7     #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
8    
9     +/* Inode flags */
10     +#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
11     +
12     /* include/linux/ext2_fs.h */
13     struct ext2_super_block
14     {
15     @@ -191,6 +194,42 @@ struct ext2_dir_entry
16     #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
17     ~EXT2_DIR_ROUND)
18    
19     +/* linux/ext4_fs_extents.h */
20     +/*
21     + * This is the extent on-disk structure.
22     + * It's used at the bottom of the tree.
23     + */
24     +struct ext4_extent {
25     + __u32 ee_block; /* first logical block extent covers */
26     + __u16 ee_len; /* number of blocks covered by extent */
27     + __u16 ee_start_hi; /* high 16 bits of physical block */
28     + __u32 ee_start; /* low 32 bits of physical block */
29     +};
30     +
31     +/*
32     + * This is index on-disk structure.
33     + * It's used at all the levels except the bottom.
34     + */
35     +struct ext4_extent_idx {
36     + __u32 ei_block; /* index covers logical blocks from 'block' */
37     + __u32 ei_leaf; /* pointer to the physical block of the next *
38     + * level. leaf or next index could be there */
39     + __u16 ei_leaf_hi; /* high 16 bits of physical block */
40     + __u16 ei_unused;
41     +};
42     +
43     +/*
44     + * Each block (leaves and indexes), even inode-stored has header.
45     + */
46     +struct ext4_extent_header {
47     + __u16 eh_magic; /* probably will support different formats */
48     + __u16 eh_entries; /* number of valid entries */
49     + __u16 eh_max; /* capacity of store in entries */
50     + __u16 eh_depth; /* has tree real underlying blocks? */
51     + __u32 eh_generation; /* generation of the tree */
52     +};
53     +
54     +#define EXT4_EXT_MAGIC 0xf30a
55    
56     /* ext2/super.c */
57     #define log2(n) ffz(~(n))
58     @@ -279,6 +318,26 @@ ext2_rdfsb (int fsblock, int buffer)
59     EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
60     }
61    
62     +/* Walk through extents index tree to find the good leaf */
63     +static struct ext4_extent_header *
64     +ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block)
65     +{
66     + int i;
67     + struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1);
68     + if (extent_block->eh_magic != EXT4_EXT_MAGIC)
69     + return NULL;
70     + if (extent_block->eh_depth == 0)
71     + return extent_block;
72     + for (i = 0; i < extent_block->eh_entries; i++)
73     + {
74     + if (logical_block < index[i].ei_block)
75     + break;
76     + }
77     + if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1))
78     + return NULL;
79     + return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block));
80     +}
81     +
82     /* from
83     ext2/inode.c:ext2_bmap()
84     */
85     --- grub-0.97/stage2/fsys_ext2fs.c~ 2008-12-28 20:19:00.000000000 +0100
86     +++ grub-0.97/stage2/fsys_ext2fs.c 2008-12-28 20:19:00.000000000 +0100
87     @@ -366,83 +366,106 @@
88     }
89     printf ("logical block %d\n", logical_block);
90     #endif /* E2DEBUG */
91     -
92     - /* if it is directly pointed to by the inode, return that physical addr */
93     - if (logical_block < EXT2_NDIR_BLOCKS)
94     - {
95     -#ifdef E2DEBUG
96     - printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
97     - printf ("returning %d\n", INODE->i_block[logical_block]);
98     -#endif /* E2DEBUG */
99     - return INODE->i_block[logical_block];
100     - }
101     - /* else */
102     - logical_block -= EXT2_NDIR_BLOCKS;
103     - /* try the indirect block */
104     - if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
105     + /* standard ext2 inode */
106     + if (!(INODE->i_flags & EXT4_EXTENTS_FL))
107     {
108     - if (mapblock1 != 1
109     - && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
110     - {
111     - errnum = ERR_FSYS_CORRUPT;
112     - return -1;
113     - }
114     - mapblock1 = 1;
115     - return ((__u32 *) DATABLOCK1)[logical_block];
116     - }
117     - /* else */
118     - logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
119     - /* now try the double indirect block */
120     - if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
121     - {
122     - int bnum;
123     - if (mapblock1 != 2
124     - && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
125     - {
126     - errnum = ERR_FSYS_CORRUPT;
127     - return -1;
128     - }
129     - mapblock1 = 2;
130     - if ((bnum = (((__u32 *) DATABLOCK1)
131     - [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))
132     - != mapblock2
133     - && !ext2_rdfsb (bnum, DATABLOCK2))
134     - {
135     - errnum = ERR_FSYS_CORRUPT;
136     - return -1;
137     - }
138     - mapblock2 = bnum;
139     + /* if it is directly pointed to by the inode, return that physical addr */
140     + if (logical_block < EXT2_NDIR_BLOCKS)
141     + {
142     +#ifdef E2DEBUG
143     + printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
144     + printf ("returning %d\n", INODE->i_block[logical_block]);
145     +#endif /* E2DEBUG */
146     + return INODE->i_block[logical_block];
147     + }
148     + /* else */
149     + logical_block -= EXT2_NDIR_BLOCKS;
150     + /* try the indirect block */
151     + if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
152     + {
153     + if (mapblock1 != 1
154     + && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
155     + {
156     + errnum = ERR_FSYS_CORRUPT;
157     + return -1;
158     + }
159     + mapblock1 = 1;
160     + return ((__u32 *) DATABLOCK1)[logical_block];
161     + }
162     + /* else */
163     + logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
164     + /* now try the double indirect block */
165     + if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
166     + {
167     + int bnum;
168     + if (mapblock1 != 2
169     + && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
170     + {
171     + errnum = ERR_FSYS_CORRUPT;
172     + return -1;
173     + }
174     + mapblock1 = 2;
175     + if ((bnum = (((__u32 *) DATABLOCK1)
176     + [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))
177     + != mapblock2
178     + && !ext2_rdfsb (bnum, DATABLOCK2))
179     + {
180     + errnum = ERR_FSYS_CORRUPT;
181     + return -1;
182     + }
183     + mapblock2 = bnum;
184     + return ((__u32 *) DATABLOCK2)
185     + [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
186     + }
187     + /* else */
188     + mapblock2 = -1;
189     + logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
190     + if (mapblock1 != 3
191     + && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
192     + {
193     + errnum = ERR_FSYS_CORRUPT;
194     + return -1;
195     + }
196     + mapblock1 = 3;
197     + if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
198     + [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
199     + * 2)],
200     + DATABLOCK2))
201     + {
202     + errnum = ERR_FSYS_CORRUPT;
203     + return -1;
204     + }
205     + if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
206     + [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
207     + & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
208     + DATABLOCK2))
209     + {
210     + errnum = ERR_FSYS_CORRUPT;
211     + return -1;
212     + }
213     return ((__u32 *) DATABLOCK2)
214     - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
215     - }
216     - /* else */
217     - mapblock2 = -1;
218     - logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
219     - if (mapblock1 != 3
220     - && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
221     - {
222     - errnum = ERR_FSYS_CORRUPT;
223     - return -1;
224     + [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
225     }
226     - mapblock1 = 3;
227     - if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
228     - [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
229     - * 2)],
230     - DATABLOCK2))
231     - {
232     - errnum = ERR_FSYS_CORRUPT;
233     - return -1;
234     - }
235     - if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
236     - [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
237     - & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
238     - DATABLOCK2))
239     + /* inode is in extents format */
240     + else
241     {
242     + int i;
243     + struct ext4_extent_header *extent_hdr = ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block);
244     + struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1);
245     + if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC)
246     + {
247     + errnum = ERR_FSYS_CORRUPT;
248     + return -1;
249     + }
250     + for (i = 0; i<extent_hdr->eh_entries; i++)
251     + {
252     + if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15))
253     + return (logical_block - extent[i].ee_block + extent[i].ee_start);
254     + }
255     + /* We should not arrive here */
256     errnum = ERR_FSYS_CORRUPT;
257     return -1;
258     }
259     - return ((__u32 *) DATABLOCK2)
260     - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
261     }
262    
263     /* preconditions: all preconds of ext2fs_block_map */