diff options
Diffstat (limited to 'meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch')
-rw-r--r-- | meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch new file mode 100644 index 0000000000..494e3f9e8d --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch | |||
@@ -0,0 +1,272 @@ | |||
1 | Upstream-Status: inappropriate | ||
2 | |||
3 | From ea6cbe2880e02026667b9007db9a742be7dcd52b Mon Sep 17 00:00:00 2001 | ||
4 | From: Corey Minyard <cminyard@mvista.com> | ||
5 | Date: Sun, 5 Jun 2011 10:26:11 -0500 | ||
6 | Subject: [PATCH 06/19] Improve the efficiency of extend_blk | ||
7 | |||
8 | When doing multiple extensions operations on the same inode, extend_blk() | ||
9 | would search to the end every time. In the current structure, that means | ||
10 | when creating the reserved blocks, it could parse over the block list | ||
11 | many thousands of time on a large filesystem. For an 800MB filesystem, | ||
12 | that took 2/3rds of the time. | ||
13 | |||
14 | So create a structure for holding the inode position and use it to | ||
15 | know where the end is. This neatens things up a bit, too, more | ||
16 | clearly showing when a truncate or extend is occuring. In future | ||
17 | changes, this will also make it efficient for supporting very large | ||
18 | files that cannot be fully allocated in memory. | ||
19 | --- | ||
20 | genext2fs.c | 147 ++++++++++++++++++++++++++++++++++++++++------------------- | ||
21 | 1 files changed, 100 insertions(+), 47 deletions(-) | ||
22 | |||
23 | diff --git a/genext2fs.c b/genext2fs.c | ||
24 | index 46c9605..e45e520 100644 | ||
25 | --- a/genext2fs.c | ||
26 | +++ b/genext2fs.c | ||
27 | @@ -436,6 +436,17 @@ swab32(uint32 val) | ||
28 | ((val<<8)&0xFF0000) | (val<<24)); | ||
29 | } | ||
30 | |||
31 | +static inline int | ||
32 | +is_blk_empty(uint8 *b) | ||
33 | +{ | ||
34 | + uint32 i; | ||
35 | + uint32 *v = (uint32 *) b; | ||
36 | + | ||
37 | + for(i = 0; i < BLOCKSIZE / 4; i++) | ||
38 | + if (*v++) | ||
39 | + return 0; | ||
40 | + return 1; | ||
41 | +} | ||
42 | |||
43 | // on-disk structures | ||
44 | // this trick makes me declare things only once | ||
45 | @@ -1165,7 +1176,6 @@ init_bw(blockwalker *bw) | ||
46 | // used after being freed, so once you start | ||
47 | // freeing blocks don't stop until the end of | ||
48 | // the file. moreover, i_blocks isn't updated. | ||
49 | -// in fact, don't do that, just use extend_blk | ||
50 | // if hole!=0, create a hole in the file | ||
51 | static uint32 | ||
52 | walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
53 | @@ -1422,52 +1432,80 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
54 | return bk; | ||
55 | } | ||
56 | |||
57 | -// add blocks to an inode (file/dir/etc...) | ||
58 | -static void | ||
59 | -extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
60 | +typedef struct | ||
61 | { | ||
62 | - int create = amount; | ||
63 | - blockwalker bw, lbw; | ||
64 | - uint32 bk; | ||
65 | + blockwalker bw; | ||
66 | + uint32 nod; | ||
67 | nod_info *ni; | ||
68 | inode *inod; | ||
69 | +} inode_pos; | ||
70 | +#define INODE_POS_TRUNCATE 0 | ||
71 | +#define INODE_POS_EXTEND 1 | ||
72 | + | ||
73 | +// Call this to set up an ipos structure for future use with | ||
74 | +// extend_inode_blk to append blocks to the given inode. If | ||
75 | +// op is INODE_POS_TRUNCATE, the inode is truncated to zero size. | ||
76 | +// If op is INODE_POS_EXTEND, the position is moved to the end | ||
77 | +// of the inode's data blocks. | ||
78 | +// Call inode_pos_finish when done with the inode_pos structure. | ||
79 | +static void | ||
80 | +inode_pos_init(filesystem *fs, inode_pos *ipos, uint32 nod, int op, | ||
81 | + blockwalker *endbw) | ||
82 | +{ | ||
83 | + blockwalker lbw; | ||
84 | |||
85 | - inod = get_nod(fs, nod, &ni); | ||
86 | - init_bw(&bw); | ||
87 | - if(amount < 0) | ||
88 | - { | ||
89 | - uint32 i; | ||
90 | - for(i = 0; i < inod->i_blocks / INOBLK + amount; i++) | ||
91 | - walk_bw(fs, nod, &bw, 0, 0); | ||
92 | - while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END) | ||
93 | + init_bw(&ipos->bw); | ||
94 | + ipos->nod = nod; | ||
95 | + ipos->inod = get_nod(fs, nod, &ipos->ni); | ||
96 | + if (op == INODE_POS_TRUNCATE) { | ||
97 | + int32 create = -1; | ||
98 | + while(walk_bw(fs, nod, &ipos->bw, &create, 0) != WALK_END) | ||
99 | /*nop*/; | ||
100 | - inod->i_blocks += amount * INOBLK; | ||
101 | + ipos->inod->i_blocks = 0; | ||
102 | } | ||
103 | - else | ||
104 | + | ||
105 | + if (endbw) | ||
106 | + ipos->bw = *endbw; | ||
107 | + else { | ||
108 | + /* Seek to the end */ | ||
109 | + init_bw(&ipos->bw); | ||
110 | + lbw = ipos->bw; | ||
111 | + while(walk_bw(fs, nod, &ipos->bw, 0, 0) != WALK_END) | ||
112 | + lbw = ipos->bw; | ||
113 | + ipos->bw = lbw; | ||
114 | + } | ||
115 | +} | ||
116 | + | ||
117 | +// Clean up the inode_pos structure. | ||
118 | +static void | ||
119 | +inode_pos_finish(filesystem *fs, inode_pos *ipos) | ||
120 | +{ | ||
121 | + put_nod(ipos->ni); | ||
122 | +} | ||
123 | + | ||
124 | +// add blocks to an inode (file/dir/etc...) at the given position. | ||
125 | +// This will only work when appending to the end of an inode. | ||
126 | +static void | ||
127 | +extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount) | ||
128 | +{ | ||
129 | + uint32 bk; | ||
130 | + uint32 pos; | ||
131 | + | ||
132 | + if (amount < 0) | ||
133 | + error_msg_and_die("extend_inode_blk: Got negative amount"); | ||
134 | + | ||
135 | + for (pos = 0; amount; pos += BLOCKSIZE) | ||
136 | { | ||
137 | - lbw = bw; | ||
138 | - while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
139 | - lbw = bw; | ||
140 | - bw = lbw; | ||
141 | - while(create) | ||
142 | - { | ||
143 | - int i, copyb = 0; | ||
144 | - if(!(fs->sb->s_reserved[200] & OP_HOLES)) | ||
145 | - copyb = 1; | ||
146 | - else | ||
147 | - for(i = 0; i < BLOCKSIZE / 4; i++) | ||
148 | - if(((int32*)(b + BLOCKSIZE * (amount - create)))[i]) | ||
149 | - { | ||
150 | - copyb = 1; | ||
151 | - break; | ||
152 | - } | ||
153 | - if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END) | ||
154 | - break; | ||
155 | - if(copyb) { | ||
156 | - blk_info *bi; | ||
157 | - memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE); | ||
158 | - put_blk(bi); | ||
159 | - } | ||
160 | + int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos)); | ||
161 | + | ||
162 | + bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole); | ||
163 | + if (bk == WALK_END) | ||
164 | + error_msg_and_die("extend_inode_blk: extend failed"); | ||
165 | + if (!hole) { | ||
166 | + blk_info *bi; | ||
167 | + uint8 *block = get_blk(fs, bk, &bi); | ||
168 | + memcpy(block, b + pos, BLOCKSIZE); | ||
169 | + put_blk(bi); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | @@ -1484,6 +1522,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
174 | inode *node; | ||
175 | inode *pnode; | ||
176 | nod_info *dni, *ni; | ||
177 | + inode_pos ipos; | ||
178 | |||
179 | pnode = get_nod(fs, dnod, &dni); | ||
180 | if((pnode->i_mode & FM_IFMT) != FM_IFDIR) | ||
181 | @@ -1534,7 +1573,11 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
182 | node->i_links_count++; | ||
183 | put_nod(ni); | ||
184 | next_dir(&dw); // Force the data into the buffer | ||
185 | - extend_blk(fs, dnod, dir_data(&dw), 1); | ||
186 | + | ||
187 | + inode_pos_init(fs, &ipos, dnod, INODE_POS_EXTEND, &lbw); | ||
188 | + extend_inode_blk(fs, &ipos, dir_data(&dw), 1); | ||
189 | + inode_pos_finish(fs, &ipos); | ||
190 | + | ||
191 | put_dir(&dw); | ||
192 | pnode->i_size += BLOCKSIZE; | ||
193 | out: | ||
194 | @@ -1654,8 +1697,9 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
195 | uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime); | ||
196 | nod_info *ni; | ||
197 | inode *node = get_nod(fs, nod, &ni); | ||
198 | + inode_pos ipos; | ||
199 | |||
200 | - extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
201 | + inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
202 | node->i_size = size; | ||
203 | if(size <= 4 * (EXT2_TIND_BLOCK+1)) | ||
204 | { | ||
205 | @@ -1663,7 +1707,8 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
206 | put_nod(ni); | ||
207 | return nod; | ||
208 | } | ||
209 | - extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
210 | + extend_inode_blk(fs, &ipos, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
211 | + inode_pos_finish(fs, &ipos); | ||
212 | put_nod(ni); | ||
213 | return nod; | ||
214 | } | ||
215 | @@ -1676,8 +1721,9 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
216 | uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime); | ||
217 | nod_info *ni; | ||
218 | inode *node = get_nod(fs, nod, &ni); | ||
219 | + inode_pos ipos; | ||
220 | |||
221 | - extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
222 | + inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
223 | node->i_size = size; | ||
224 | if (size) { | ||
225 | if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1))) | ||
226 | @@ -1685,9 +1731,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
227 | if(f) | ||
228 | if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ... | ||
229 | error_msg_and_die("fread failed"); | ||
230 | - extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
231 | + extend_inode_blk(fs, &ipos, b, | ||
232 | + rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
233 | free(b); | ||
234 | } | ||
235 | + inode_pos_finish(fs, &ipos); | ||
236 | put_nod(ni); | ||
237 | return nod; | ||
238 | } | ||
239 | @@ -2210,6 +2258,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
240 | inode *itab0; | ||
241 | blk_info *bi; | ||
242 | nod_info *ni; | ||
243 | + inode_pos ipos; | ||
244 | |||
245 | if(nbresrvd < 0) | ||
246 | error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page."); | ||
247 | @@ -2337,7 +2386,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
248 | new_dir(fs, EXT2_ROOT_INO, ".", 1, &dw); | ||
249 | shrink_dir(&dw, EXT2_ROOT_INO, "..", 2); | ||
250 | next_dir(&dw); // Force the data into the buffer | ||
251 | - extend_blk(fs, EXT2_ROOT_INO, dir_data(&dw), 1); | ||
252 | + inode_pos_init(fs, &ipos, EXT2_ROOT_INO, INODE_POS_EXTEND, NULL); | ||
253 | + extend_inode_blk(fs, &ipos, dir_data(&dw), 1); | ||
254 | + inode_pos_finish(fs, &ipos); | ||
255 | put_dir(&dw); | ||
256 | |||
257 | // make lost+found directory and reserve blocks | ||
258 | @@ -2355,8 +2406,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
259 | */ | ||
260 | if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS ) | ||
261 | fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS; | ||
262 | + inode_pos_init(fs, &ipos, nod, INODE_POS_EXTEND, NULL); | ||
263 | for(i = 1; i < fs->sb->s_r_blocks_count; i++) | ||
264 | - extend_blk(fs, nod, b, 1); | ||
265 | + extend_inode_blk(fs, &ipos, b, 1); | ||
266 | + inode_pos_finish(fs, &ipos); | ||
267 | free_workblk(b); | ||
268 | node = get_nod(fs, nod, &ni); | ||
269 | node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE; | ||
270 | -- | ||
271 | 1.7.4.1 | ||
272 | |||