Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1053 - (show annotations) (download)
Fri Jun 25 10:52:50 2010 UTC (13 years, 10 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 */