Annotation of /trunk/grub/patches/grub-0.97-ext4-4.patch
Parent Directory | Revision Log
Revision 1053 -
(hide 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 | 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 */ |