Contents of /trunk/grub/patches/grub-0.97-ext4-4.patch
Parent Directory | Revision Log
Revision 1053 -
(show annotations)
(download)
Fri Jun 25 10:52:50 2010 UTC (14 years, 3 months ago) by niro
File size: 9101 byte(s)
Fri Jun 25 10:52:50 2010 UTC (14 years, 3 months ago) by niro
File size: 9101 byte(s)
more patches and fixed ext4 patch
1 | 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 */ |