summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch
diff options
context:
space:
mode:
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.patch272
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 @@
1Upstream-Status: inappropriate
2
3From ea6cbe2880e02026667b9007db9a742be7dcd52b Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 10:26:11 -0500
6Subject: [PATCH 06/19] Improve the efficiency of extend_blk
7
8When doing multiple extensions operations on the same inode, extend_blk()
9would search to the end every time. In the current structure, that means
10when creating the reserved blocks, it could parse over the block list
11many thousands of time on a large filesystem. For an 800MB filesystem,
12that took 2/3rds of the time.
13
14So create a structure for holding the inode position and use it to
15know where the end is. This neatens things up a bit, too, more
16clearly showing when a truncate or extend is occuring. In future
17changes, this will also make it efficient for supporting very large
18files that cannot be fully allocated in memory.
19---
20 genext2fs.c | 147 ++++++++++++++++++++++++++++++++++++++++-------------------
21 1 files changed, 100 insertions(+), 47 deletions(-)
22
23diff --git a/genext2fs.c b/genext2fs.c
24index 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--
2711.7.4.1
272