diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-07-14 12:08:37 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-07-15 10:35:15 -0400 |
commit | 1e51764a3c2ac05a23a22b2a95ddee4d9bffb16d (patch) | |
tree | 919debdd48aef9eee9ff0e8f465ef2649325b993 /fs/ubifs/log.c | |
parent | e56a99d5a42dcb91e622ae7a0289d8fb2ddabffb (diff) |
UBIFS: add new flash file system
This is a new flash file system. See
http://www.linux-mtd.infradead.org/doc/ubifs.html
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Diffstat (limited to 'fs/ubifs/log.c')
-rw-r--r-- | fs/ubifs/log.c | 805 |
1 files changed, 805 insertions, 0 deletions
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c new file mode 100644 index 000000000000..36857b9ed59e --- /dev/null +++ b/fs/ubifs/log.c | |||
@@ -0,0 +1,805 @@ | |||
1 | /* | ||
2 | * This file is part of UBIFS. | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., 51 | ||
17 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | * | ||
19 | * Authors: Artem Bityutskiy (Битюцкий Артём) | ||
20 | * Adrian Hunter | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * This file is a part of UBIFS journal implementation and contains various | ||
25 | * functions which manipulate the log. The log is a fixed area on the flash | ||
26 | * which does not contain any data but refers to buds. The log is a part of the | ||
27 | * journal. | ||
28 | */ | ||
29 | |||
30 | #include "ubifs.h" | ||
31 | |||
32 | #ifdef CONFIG_UBIFS_FS_DEBUG | ||
33 | static int dbg_check_bud_bytes(struct ubifs_info *c); | ||
34 | #else | ||
35 | #define dbg_check_bud_bytes(c) 0 | ||
36 | #endif | ||
37 | |||
38 | /** | ||
39 | * ubifs_search_bud - search bud LEB. | ||
40 | * @c: UBIFS file-system description object | ||
41 | * @lnum: logical eraseblock number to search | ||
42 | * | ||
43 | * This function searches bud LEB @lnum. Returns bud description object in case | ||
44 | * of success and %NULL if there is no bud with this LEB number. | ||
45 | */ | ||
46 | struct ubifs_bud *ubifs_search_bud(struct ubifs_info *c, int lnum) | ||
47 | { | ||
48 | struct rb_node *p; | ||
49 | struct ubifs_bud *bud; | ||
50 | |||
51 | spin_lock(&c->buds_lock); | ||
52 | p = c->buds.rb_node; | ||
53 | while (p) { | ||
54 | bud = rb_entry(p, struct ubifs_bud, rb); | ||
55 | if (lnum < bud->lnum) | ||
56 | p = p->rb_left; | ||
57 | else if (lnum > bud->lnum) | ||
58 | p = p->rb_right; | ||
59 | else { | ||
60 | spin_unlock(&c->buds_lock); | ||
61 | return bud; | ||
62 | } | ||
63 | } | ||
64 | spin_unlock(&c->buds_lock); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * ubifs_get_wbuf - get the wbuf associated with a LEB, if there is one. | ||
70 | * @c: UBIFS file-system description object | ||
71 | * @lnum: logical eraseblock number to search | ||
72 | * | ||
73 | * This functions returns the wbuf for @lnum or %NULL if there is not one. | ||
74 | */ | ||
75 | struct ubifs_wbuf *ubifs_get_wbuf(struct ubifs_info *c, int lnum) | ||
76 | { | ||
77 | struct rb_node *p; | ||
78 | struct ubifs_bud *bud; | ||
79 | int jhead; | ||
80 | |||
81 | if (!c->jheads) | ||
82 | return NULL; | ||
83 | |||
84 | spin_lock(&c->buds_lock); | ||
85 | p = c->buds.rb_node; | ||
86 | while (p) { | ||
87 | bud = rb_entry(p, struct ubifs_bud, rb); | ||
88 | if (lnum < bud->lnum) | ||
89 | p = p->rb_left; | ||
90 | else if (lnum > bud->lnum) | ||
91 | p = p->rb_right; | ||
92 | else { | ||
93 | jhead = bud->jhead; | ||
94 | spin_unlock(&c->buds_lock); | ||
95 | return &c->jheads[jhead].wbuf; | ||
96 | } | ||
97 | } | ||
98 | spin_unlock(&c->buds_lock); | ||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * next_log_lnum - switch to the next log LEB. | ||
104 | * @c: UBIFS file-system description object | ||
105 | * @lnum: current log LEB | ||
106 | */ | ||
107 | static inline int next_log_lnum(const struct ubifs_info *c, int lnum) | ||
108 | { | ||
109 | lnum += 1; | ||
110 | if (lnum > c->log_last) | ||
111 | lnum = UBIFS_LOG_LNUM; | ||
112 | |||
113 | return lnum; | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * empty_log_bytes - calculate amount of empty space in the log. | ||
118 | * @c: UBIFS file-system description object | ||
119 | */ | ||
120 | static inline long long empty_log_bytes(const struct ubifs_info *c) | ||
121 | { | ||
122 | long long h, t; | ||
123 | |||
124 | h = (long long)c->lhead_lnum * c->leb_size + c->lhead_offs; | ||
125 | t = (long long)c->ltail_lnum * c->leb_size; | ||
126 | |||
127 | if (h >= t) | ||
128 | return c->log_bytes - h + t; | ||
129 | else | ||
130 | return t - h; | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * ubifs_add_bud - add bud LEB to the tree of buds and its journal head list. | ||
135 | * @c: UBIFS file-system description object | ||
136 | * @bud: the bud to add | ||
137 | */ | ||
138 | void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud) | ||
139 | { | ||
140 | struct rb_node **p, *parent = NULL; | ||
141 | struct ubifs_bud *b; | ||
142 | struct ubifs_jhead *jhead; | ||
143 | |||
144 | spin_lock(&c->buds_lock); | ||
145 | p = &c->buds.rb_node; | ||
146 | while (*p) { | ||
147 | parent = *p; | ||
148 | b = rb_entry(parent, struct ubifs_bud, rb); | ||
149 | ubifs_assert(bud->lnum != b->lnum); | ||
150 | if (bud->lnum < b->lnum) | ||
151 | p = &(*p)->rb_left; | ||
152 | else | ||
153 | p = &(*p)->rb_right; | ||
154 | } | ||
155 | |||
156 | rb_link_node(&bud->rb, parent, p); | ||
157 | rb_insert_color(&bud->rb, &c->buds); | ||
158 | if (c->jheads) { | ||
159 | jhead = &c->jheads[bud->jhead]; | ||
160 | list_add_tail(&bud->list, &jhead->buds_list); | ||
161 | } else | ||
162 | ubifs_assert(c->replaying && (c->vfs_sb->s_flags & MS_RDONLY)); | ||
163 | |||
164 | /* | ||
165 | * Note, although this is a new bud, we anyway account this space now, | ||
166 | * before any data has been written to it, because this is about to | ||
167 | * guarantee fixed mount time, and this bud will anyway be read and | ||
168 | * scanned. | ||
169 | */ | ||
170 | c->bud_bytes += c->leb_size - bud->start; | ||
171 | |||
172 | dbg_log("LEB %d:%d, jhead %d, bud_bytes %lld", bud->lnum, | ||
173 | bud->start, bud->jhead, c->bud_bytes); | ||
174 | spin_unlock(&c->buds_lock); | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * ubifs_create_buds_lists - create journal head buds lists for remount rw. | ||
179 | * @c: UBIFS file-system description object | ||
180 | */ | ||
181 | void ubifs_create_buds_lists(struct ubifs_info *c) | ||
182 | { | ||
183 | struct rb_node *p; | ||
184 | |||
185 | spin_lock(&c->buds_lock); | ||
186 | p = rb_first(&c->buds); | ||
187 | while (p) { | ||
188 | struct ubifs_bud *bud = rb_entry(p, struct ubifs_bud, rb); | ||
189 | struct ubifs_jhead *jhead = &c->jheads[bud->jhead]; | ||
190 | |||
191 | list_add_tail(&bud->list, &jhead->buds_list); | ||
192 | p = rb_next(p); | ||
193 | } | ||
194 | spin_unlock(&c->buds_lock); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * ubifs_add_bud_to_log - add a new bud to the log. | ||
199 | * @c: UBIFS file-system description object | ||
200 | * @jhead: journal head the bud belongs to | ||
201 | * @lnum: LEB number of the bud | ||
202 | * @offs: starting offset of the bud | ||
203 | * | ||
204 | * This function writes reference node for the new bud LEB @lnum it to the log, | ||
205 | * and adds it to the buds tress. It also makes sure that log size does not | ||
206 | * exceed the 'c->max_bud_bytes' limit. Returns zero in case of success, | ||
207 | * %-EAGAIN if commit is required, and a negative error codes in case of | ||
208 | * failure. | ||
209 | */ | ||
210 | int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) | ||
211 | { | ||
212 | int err; | ||
213 | struct ubifs_bud *bud; | ||
214 | struct ubifs_ref_node *ref; | ||
215 | |||
216 | bud = kmalloc(sizeof(struct ubifs_bud), GFP_NOFS); | ||
217 | if (!bud) | ||
218 | return -ENOMEM; | ||
219 | ref = kzalloc(c->ref_node_alsz, GFP_NOFS); | ||
220 | if (!ref) { | ||
221 | kfree(bud); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | |||
225 | mutex_lock(&c->log_mutex); | ||
226 | |||
227 | if (c->ro_media) { | ||
228 | err = -EROFS; | ||
229 | goto out_unlock; | ||
230 | } | ||
231 | |||
232 | /* Make sure we have enough space in the log */ | ||
233 | if (empty_log_bytes(c) - c->ref_node_alsz < c->min_log_bytes) { | ||
234 | dbg_log("not enough log space - %lld, required %d", | ||
235 | empty_log_bytes(c), c->min_log_bytes); | ||
236 | ubifs_commit_required(c); | ||
237 | err = -EAGAIN; | ||
238 | goto out_unlock; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Make sure the the amount of space in buds will not exceed | ||
243 | * 'c->max_bud_bytes' limit, because we want to guarantee mount time | ||
244 | * limits. | ||
245 | * | ||
246 | * It is not necessary to hold @c->buds_lock when reading @c->bud_bytes | ||
247 | * because we are holding @c->log_mutex. All @c->bud_bytes take place | ||
248 | * when both @c->log_mutex and @c->bud_bytes are locked. | ||
249 | */ | ||
250 | if (c->bud_bytes + c->leb_size - offs > c->max_bud_bytes) { | ||
251 | dbg_log("bud bytes %lld (%lld max), require commit", | ||
252 | c->bud_bytes, c->max_bud_bytes); | ||
253 | ubifs_commit_required(c); | ||
254 | err = -EAGAIN; | ||
255 | goto out_unlock; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * If the journal is full enough - start background commit. Note, it is | ||
260 | * OK to read 'c->cmt_state' without spinlock because integer reads | ||
261 | * are atomic in the kernel. | ||
262 | */ | ||
263 | if (c->bud_bytes >= c->bg_bud_bytes && | ||
264 | c->cmt_state == COMMIT_RESTING) { | ||
265 | dbg_log("bud bytes %lld (%lld max), initiate BG commit", | ||
266 | c->bud_bytes, c->max_bud_bytes); | ||
267 | ubifs_request_bg_commit(c); | ||
268 | } | ||
269 | |||
270 | bud->lnum = lnum; | ||
271 | bud->start = offs; | ||
272 | bud->jhead = jhead; | ||
273 | |||
274 | ref->ch.node_type = UBIFS_REF_NODE; | ||
275 | ref->lnum = cpu_to_le32(bud->lnum); | ||
276 | ref->offs = cpu_to_le32(bud->start); | ||
277 | ref->jhead = cpu_to_le32(jhead); | ||
278 | |||
279 | if (c->lhead_offs > c->leb_size - c->ref_node_alsz) { | ||
280 | c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); | ||
281 | c->lhead_offs = 0; | ||
282 | } | ||
283 | |||
284 | if (c->lhead_offs == 0) { | ||
285 | /* Must ensure next log LEB has been unmapped */ | ||
286 | err = ubifs_leb_unmap(c, c->lhead_lnum); | ||
287 | if (err) | ||
288 | goto out_unlock; | ||
289 | } | ||
290 | |||
291 | if (bud->start == 0) { | ||
292 | /* | ||
293 | * Before writing the LEB reference which refers an empty LEB | ||
294 | * to the log, we have to make sure it is mapped, because | ||
295 | * otherwise we'd risk to refer an LEB with garbage in case of | ||
296 | * an unclean reboot, because the target LEB might have been | ||
297 | * unmapped, but not yet physically erased. | ||
298 | */ | ||
299 | err = ubi_leb_map(c->ubi, bud->lnum, UBI_SHORTTERM); | ||
300 | if (err) | ||
301 | goto out_unlock; | ||
302 | } | ||
303 | |||
304 | dbg_log("write ref LEB %d:%d", | ||
305 | c->lhead_lnum, c->lhead_offs); | ||
306 | err = ubifs_write_node(c, ref, UBIFS_REF_NODE_SZ, c->lhead_lnum, | ||
307 | c->lhead_offs, UBI_SHORTTERM); | ||
308 | if (err) | ||
309 | goto out_unlock; | ||
310 | |||
311 | c->lhead_offs += c->ref_node_alsz; | ||
312 | |||
313 | ubifs_add_bud(c, bud); | ||
314 | |||
315 | mutex_unlock(&c->log_mutex); | ||
316 | kfree(ref); | ||
317 | return 0; | ||
318 | |||
319 | out_unlock: | ||
320 | mutex_unlock(&c->log_mutex); | ||
321 | kfree(ref); | ||
322 | kfree(bud); | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * remove_buds - remove used buds. | ||
328 | * @c: UBIFS file-system description object | ||
329 | * | ||
330 | * This function removes use buds from the buds tree. It does not remove the | ||
331 | * buds which are pointed to by journal heads. | ||
332 | */ | ||
333 | static void remove_buds(struct ubifs_info *c) | ||
334 | { | ||
335 | struct rb_node *p; | ||
336 | |||
337 | ubifs_assert(list_empty(&c->old_buds)); | ||
338 | c->cmt_bud_bytes = 0; | ||
339 | spin_lock(&c->buds_lock); | ||
340 | p = rb_first(&c->buds); | ||
341 | while (p) { | ||
342 | struct rb_node *p1 = p; | ||
343 | struct ubifs_bud *bud; | ||
344 | struct ubifs_wbuf *wbuf; | ||
345 | |||
346 | p = rb_next(p); | ||
347 | bud = rb_entry(p1, struct ubifs_bud, rb); | ||
348 | wbuf = &c->jheads[bud->jhead].wbuf; | ||
349 | |||
350 | if (wbuf->lnum == bud->lnum) { | ||
351 | /* | ||
352 | * Do not remove buds which are pointed to by journal | ||
353 | * heads (non-closed buds). | ||
354 | */ | ||
355 | c->cmt_bud_bytes += wbuf->offs - bud->start; | ||
356 | dbg_log("preserve %d:%d, jhead %d, bud bytes %d, " | ||
357 | "cmt_bud_bytes %lld", bud->lnum, bud->start, | ||
358 | bud->jhead, wbuf->offs - bud->start, | ||
359 | c->cmt_bud_bytes); | ||
360 | bud->start = wbuf->offs; | ||
361 | } else { | ||
362 | c->cmt_bud_bytes += c->leb_size - bud->start; | ||
363 | dbg_log("remove %d:%d, jhead %d, bud bytes %d, " | ||
364 | "cmt_bud_bytes %lld", bud->lnum, bud->start, | ||
365 | bud->jhead, c->leb_size - bud->start, | ||
366 | c->cmt_bud_bytes); | ||
367 | rb_erase(p1, &c->buds); | ||
368 | list_del(&bud->list); | ||
369 | /* | ||
370 | * If the commit does not finish, the recovery will need | ||
371 | * to replay the journal, in which case the old buds | ||
372 | * must be unchanged. Do not release them until post | ||
373 | * commit i.e. do not allow them to be garbage | ||
374 | * collected. | ||
375 | */ | ||
376 | list_add(&bud->list, &c->old_buds); | ||
377 | } | ||
378 | } | ||
379 | spin_unlock(&c->buds_lock); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * ubifs_log_start_commit - start commit. | ||
384 | * @c: UBIFS file-system description object | ||
385 | * @ltail_lnum: return new log tail LEB number | ||
386 | * | ||
387 | * The commit operation starts with writing "commit start" node to the log and | ||
388 | * reference nodes for all journal heads which will define new journal after | ||
389 | * the commit has been finished. The commit start and reference nodes are | ||
390 | * written in one go to the nearest empty log LEB (hence, when commit is | ||
391 | * finished UBIFS may safely unmap all the previous log LEBs). This function | ||
392 | * returns zero in case of success and a negative error code in case of | ||
393 | * failure. | ||
394 | */ | ||
395 | int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) | ||
396 | { | ||
397 | void *buf; | ||
398 | struct ubifs_cs_node *cs; | ||
399 | struct ubifs_ref_node *ref; | ||
400 | int err, i, max_len, len; | ||
401 | |||
402 | err = dbg_check_bud_bytes(c); | ||
403 | if (err) | ||
404 | return err; | ||
405 | |||
406 | max_len = UBIFS_CS_NODE_SZ + c->jhead_cnt * UBIFS_REF_NODE_SZ; | ||
407 | max_len = ALIGN(max_len, c->min_io_size); | ||
408 | buf = cs = kmalloc(max_len, GFP_NOFS); | ||
409 | if (!buf) | ||
410 | return -ENOMEM; | ||
411 | |||
412 | cs->ch.node_type = UBIFS_CS_NODE; | ||
413 | cs->cmt_no = cpu_to_le64(c->cmt_no + 1); | ||
414 | ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); | ||
415 | |||
416 | /* | ||
417 | * Note, we do not lock 'c->log_mutex' because this is the commit start | ||
418 | * phase and we are exclusively using the log. And we do not lock | ||
419 | * write-buffer because nobody can write to the file-system at this | ||
420 | * phase. | ||
421 | */ | ||
422 | |||
423 | len = UBIFS_CS_NODE_SZ; | ||
424 | for (i = 0; i < c->jhead_cnt; i++) { | ||
425 | int lnum = c->jheads[i].wbuf.lnum; | ||
426 | int offs = c->jheads[i].wbuf.offs; | ||
427 | |||
428 | if (lnum == -1 || offs == c->leb_size) | ||
429 | continue; | ||
430 | |||
431 | dbg_log("add ref to LEB %d:%d for jhead %d", lnum, offs, i); | ||
432 | ref = buf + len; | ||
433 | ref->ch.node_type = UBIFS_REF_NODE; | ||
434 | ref->lnum = cpu_to_le32(lnum); | ||
435 | ref->offs = cpu_to_le32(offs); | ||
436 | ref->jhead = cpu_to_le32(i); | ||
437 | |||
438 | ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); | ||
439 | len += UBIFS_REF_NODE_SZ; | ||
440 | } | ||
441 | |||
442 | ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); | ||
443 | |||
444 | /* Switch to the next log LEB */ | ||
445 | if (c->lhead_offs) { | ||
446 | c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); | ||
447 | c->lhead_offs = 0; | ||
448 | } | ||
449 | |||
450 | if (c->lhead_offs == 0) { | ||
451 | /* Must ensure next LEB has been unmapped */ | ||
452 | err = ubifs_leb_unmap(c, c->lhead_lnum); | ||
453 | if (err) | ||
454 | goto out; | ||
455 | } | ||
456 | |||
457 | len = ALIGN(len, c->min_io_size); | ||
458 | dbg_log("writing commit start at LEB %d:0, len %d", c->lhead_lnum, len); | ||
459 | err = ubifs_leb_write(c, c->lhead_lnum, cs, 0, len, UBI_SHORTTERM); | ||
460 | if (err) | ||
461 | goto out; | ||
462 | |||
463 | *ltail_lnum = c->lhead_lnum; | ||
464 | |||
465 | c->lhead_offs += len; | ||
466 | if (c->lhead_offs == c->leb_size) { | ||
467 | c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); | ||
468 | c->lhead_offs = 0; | ||
469 | } | ||
470 | |||
471 | remove_buds(c); | ||
472 | |||
473 | /* | ||
474 | * We have started the commit and now users may use the rest of the log | ||
475 | * for new writes. | ||
476 | */ | ||
477 | c->min_log_bytes = 0; | ||
478 | |||
479 | out: | ||
480 | kfree(buf); | ||
481 | return err; | ||
482 | } | ||
483 | |||
484 | /** | ||
485 | * ubifs_log_end_commit - end commit. | ||
486 | * @c: UBIFS file-system description object | ||
487 | * @ltail_lnum: new log tail LEB number | ||
488 | * | ||
489 | * This function is called on when the commit operation was finished. It | ||
490 | * moves log tail to new position and unmaps LEBs which contain obsolete data. | ||
491 | * Returns zero in case of success and a negative error code in case of | ||
492 | * failure. | ||
493 | */ | ||
494 | int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum) | ||
495 | { | ||
496 | int err; | ||
497 | |||
498 | /* | ||
499 | * At this phase we have to lock 'c->log_mutex' because UBIFS allows FS | ||
500 | * writes during commit. Its only short "commit" start phase when | ||
501 | * writers are blocked. | ||
502 | */ | ||
503 | mutex_lock(&c->log_mutex); | ||
504 | |||
505 | dbg_log("old tail was LEB %d:0, new tail is LEB %d:0", | ||
506 | c->ltail_lnum, ltail_lnum); | ||
507 | |||
508 | c->ltail_lnum = ltail_lnum; | ||
509 | /* | ||
510 | * The commit is finished and from now on it must be guaranteed that | ||
511 | * there is always enough space for the next commit. | ||
512 | */ | ||
513 | c->min_log_bytes = c->leb_size; | ||
514 | |||
515 | spin_lock(&c->buds_lock); | ||
516 | c->bud_bytes -= c->cmt_bud_bytes; | ||
517 | spin_unlock(&c->buds_lock); | ||
518 | |||
519 | err = dbg_check_bud_bytes(c); | ||
520 | |||
521 | mutex_unlock(&c->log_mutex); | ||
522 | return err; | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * ubifs_log_post_commit - things to do after commit is completed. | ||
527 | * @c: UBIFS file-system description object | ||
528 | * @old_ltail_lnum: old log tail LEB number | ||
529 | * | ||
530 | * Release buds only after commit is completed, because they must be unchanged | ||
531 | * if recovery is needed. | ||
532 | * | ||
533 | * Unmap log LEBs only after commit is completed, because they may be needed for | ||
534 | * recovery. | ||
535 | * | ||
536 | * This function returns %0 on success and a negative error code on failure. | ||
537 | */ | ||
538 | int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum) | ||
539 | { | ||
540 | int lnum, err = 0; | ||
541 | |||
542 | while (!list_empty(&c->old_buds)) { | ||
543 | struct ubifs_bud *bud; | ||
544 | |||
545 | bud = list_entry(c->old_buds.next, struct ubifs_bud, list); | ||
546 | err = ubifs_return_leb(c, bud->lnum); | ||
547 | if (err) | ||
548 | return err; | ||
549 | list_del(&bud->list); | ||
550 | kfree(bud); | ||
551 | } | ||
552 | mutex_lock(&c->log_mutex); | ||
553 | for (lnum = old_ltail_lnum; lnum != c->ltail_lnum; | ||
554 | lnum = next_log_lnum(c, lnum)) { | ||
555 | dbg_log("unmap log LEB %d", lnum); | ||
556 | err = ubifs_leb_unmap(c, lnum); | ||
557 | if (err) | ||
558 | goto out; | ||
559 | } | ||
560 | out: | ||
561 | mutex_unlock(&c->log_mutex); | ||
562 | return err; | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * struct done_ref - references that have been done. | ||
567 | * @rb: rb-tree node | ||
568 | * @lnum: LEB number | ||
569 | */ | ||
570 | struct done_ref { | ||
571 | struct rb_node rb; | ||
572 | int lnum; | ||
573 | }; | ||
574 | |||
575 | /** | ||
576 | * done_already - determine if a reference has been done already. | ||
577 | * @done_tree: rb-tree to store references that have been done | ||
578 | * @lnum: LEB number of reference | ||
579 | * | ||
580 | * This function returns %1 if the reference has been done, %0 if not, otherwise | ||
581 | * a negative error code is returned. | ||
582 | */ | ||
583 | static int done_already(struct rb_root *done_tree, int lnum) | ||
584 | { | ||
585 | struct rb_node **p = &done_tree->rb_node, *parent = NULL; | ||
586 | struct done_ref *dr; | ||
587 | |||
588 | while (*p) { | ||
589 | parent = *p; | ||
590 | dr = rb_entry(parent, struct done_ref, rb); | ||
591 | if (lnum < dr->lnum) | ||
592 | p = &(*p)->rb_left; | ||
593 | else if (lnum > dr->lnum) | ||
594 | p = &(*p)->rb_right; | ||
595 | else | ||
596 | return 1; | ||
597 | } | ||
598 | |||
599 | dr = kzalloc(sizeof(struct done_ref), GFP_NOFS); | ||
600 | if (!dr) | ||
601 | return -ENOMEM; | ||
602 | |||
603 | dr->lnum = lnum; | ||
604 | |||
605 | rb_link_node(&dr->rb, parent, p); | ||
606 | rb_insert_color(&dr->rb, done_tree); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | /** | ||
612 | * destroy_done_tree - destroy the done tree. | ||
613 | * @done_tree: done tree to destroy | ||
614 | */ | ||
615 | static void destroy_done_tree(struct rb_root *done_tree) | ||
616 | { | ||
617 | struct rb_node *this = done_tree->rb_node; | ||
618 | struct done_ref *dr; | ||
619 | |||
620 | while (this) { | ||
621 | if (this->rb_left) { | ||
622 | this = this->rb_left; | ||
623 | continue; | ||
624 | } else if (this->rb_right) { | ||
625 | this = this->rb_right; | ||
626 | continue; | ||
627 | } | ||
628 | dr = rb_entry(this, struct done_ref, rb); | ||
629 | this = rb_parent(this); | ||
630 | if (this) { | ||
631 | if (this->rb_left == &dr->rb) | ||
632 | this->rb_left = NULL; | ||
633 | else | ||
634 | this->rb_right = NULL; | ||
635 | } | ||
636 | kfree(dr); | ||
637 | } | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * add_node - add a node to the consolidated log. | ||
642 | * @c: UBIFS file-system description object | ||
643 | * @buf: buffer to which to add | ||
644 | * @lnum: LEB number to which to write is passed and returned here | ||
645 | * @offs: offset to where to write is passed and returned here | ||
646 | * @node: node to add | ||
647 | * | ||
648 | * This function returns %0 on success and a negative error code on failure. | ||
649 | */ | ||
650 | static int add_node(struct ubifs_info *c, void *buf, int *lnum, int *offs, | ||
651 | void *node) | ||
652 | { | ||
653 | struct ubifs_ch *ch = node; | ||
654 | int len = le32_to_cpu(ch->len), remains = c->leb_size - *offs; | ||
655 | |||
656 | if (len > remains) { | ||
657 | int sz = ALIGN(*offs, c->min_io_size), err; | ||
658 | |||
659 | ubifs_pad(c, buf + *offs, sz - *offs); | ||
660 | err = ubifs_leb_change(c, *lnum, buf, sz, UBI_SHORTTERM); | ||
661 | if (err) | ||
662 | return err; | ||
663 | *lnum = next_log_lnum(c, *lnum); | ||
664 | *offs = 0; | ||
665 | } | ||
666 | memcpy(buf + *offs, node, len); | ||
667 | *offs += ALIGN(len, 8); | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | /** | ||
672 | * ubifs_consolidate_log - consolidate the log. | ||
673 | * @c: UBIFS file-system description object | ||
674 | * | ||
675 | * Repeated failed commits could cause the log to be full, but at least 1 LEB is | ||
676 | * needed for commit. This function rewrites the reference nodes in the log | ||
677 | * omitting duplicates, and failed CS nodes, and leaving no gaps. | ||
678 | * | ||
679 | * This function returns %0 on success and a negative error code on failure. | ||
680 | */ | ||
681 | int ubifs_consolidate_log(struct ubifs_info *c) | ||
682 | { | ||
683 | struct ubifs_scan_leb *sleb; | ||
684 | struct ubifs_scan_node *snod; | ||
685 | struct rb_root done_tree = RB_ROOT; | ||
686 | int lnum, err, first = 1, write_lnum, offs = 0; | ||
687 | void *buf; | ||
688 | |||
689 | dbg_rcvry("log tail LEB %d, log head LEB %d", c->ltail_lnum, | ||
690 | c->lhead_lnum); | ||
691 | buf = vmalloc(c->leb_size); | ||
692 | if (!buf) | ||
693 | return -ENOMEM; | ||
694 | lnum = c->ltail_lnum; | ||
695 | write_lnum = lnum; | ||
696 | while (1) { | ||
697 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | ||
698 | if (IS_ERR(sleb)) { | ||
699 | err = PTR_ERR(sleb); | ||
700 | goto out_free; | ||
701 | } | ||
702 | list_for_each_entry(snod, &sleb->nodes, list) { | ||
703 | switch (snod->type) { | ||
704 | case UBIFS_REF_NODE: { | ||
705 | struct ubifs_ref_node *ref = snod->node; | ||
706 | int ref_lnum = le32_to_cpu(ref->lnum); | ||
707 | |||
708 | err = done_already(&done_tree, ref_lnum); | ||
709 | if (err < 0) | ||
710 | goto out_scan; | ||
711 | if (err != 1) { | ||
712 | err = add_node(c, buf, &write_lnum, | ||
713 | &offs, snod->node); | ||
714 | if (err) | ||
715 | goto out_scan; | ||
716 | } | ||
717 | break; | ||
718 | } | ||
719 | case UBIFS_CS_NODE: | ||
720 | if (!first) | ||
721 | break; | ||
722 | err = add_node(c, buf, &write_lnum, &offs, | ||
723 | snod->node); | ||
724 | if (err) | ||
725 | goto out_scan; | ||
726 | first = 0; | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | ubifs_scan_destroy(sleb); | ||
731 | if (lnum == c->lhead_lnum) | ||
732 | break; | ||
733 | lnum = next_log_lnum(c, lnum); | ||
734 | } | ||
735 | if (offs) { | ||
736 | int sz = ALIGN(offs, c->min_io_size); | ||
737 | |||
738 | ubifs_pad(c, buf + offs, sz - offs); | ||
739 | err = ubifs_leb_change(c, write_lnum, buf, sz, UBI_SHORTTERM); | ||
740 | if (err) | ||
741 | goto out_free; | ||
742 | offs = ALIGN(offs, c->min_io_size); | ||
743 | } | ||
744 | destroy_done_tree(&done_tree); | ||
745 | vfree(buf); | ||
746 | if (write_lnum == c->lhead_lnum) { | ||
747 | ubifs_err("log is too full"); | ||
748 | return -EINVAL; | ||
749 | } | ||
750 | /* Unmap remaining LEBs */ | ||
751 | lnum = write_lnum; | ||
752 | do { | ||
753 | lnum = next_log_lnum(c, lnum); | ||
754 | err = ubifs_leb_unmap(c, lnum); | ||
755 | if (err) | ||
756 | return err; | ||
757 | } while (lnum != c->lhead_lnum); | ||
758 | c->lhead_lnum = write_lnum; | ||
759 | c->lhead_offs = offs; | ||
760 | dbg_rcvry("new log head at %d:%d", c->lhead_lnum, c->lhead_offs); | ||
761 | return 0; | ||
762 | |||
763 | out_scan: | ||
764 | ubifs_scan_destroy(sleb); | ||
765 | out_free: | ||
766 | destroy_done_tree(&done_tree); | ||
767 | vfree(buf); | ||
768 | return err; | ||
769 | } | ||
770 | |||
771 | #ifdef CONFIG_UBIFS_FS_DEBUG | ||
772 | |||
773 | /** | ||
774 | * dbg_check_bud_bytes - make sure bud bytes calculation are all right. | ||
775 | * @c: UBIFS file-system description object | ||
776 | * | ||
777 | * This function makes sure the amount of flash space used by closed buds | ||
778 | * ('c->bud_bytes' is correct). Returns zero in case of success and %-EINVAL in | ||
779 | * case of failure. | ||
780 | */ | ||
781 | static int dbg_check_bud_bytes(struct ubifs_info *c) | ||
782 | { | ||
783 | int i, err = 0; | ||
784 | struct ubifs_bud *bud; | ||
785 | long long bud_bytes = 0; | ||
786 | |||
787 | if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) | ||
788 | return 0; | ||
789 | |||
790 | spin_lock(&c->buds_lock); | ||
791 | for (i = 0; i < c->jhead_cnt; i++) | ||
792 | list_for_each_entry(bud, &c->jheads[i].buds_list, list) | ||
793 | bud_bytes += c->leb_size - bud->start; | ||
794 | |||
795 | if (c->bud_bytes != bud_bytes) { | ||
796 | ubifs_err("bad bud_bytes %lld, calculated %lld", | ||
797 | c->bud_bytes, bud_bytes); | ||
798 | err = -EINVAL; | ||
799 | } | ||
800 | spin_unlock(&c->buds_lock); | ||
801 | |||
802 | return err; | ||
803 | } | ||
804 | |||
805 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | ||