Lines Matching +full:negative +full:- +full:phase
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2006-2008 Nokia Corporation.
23 * ubifs_search_bud - search bud LEB.
24 * @c: UBIFS file-system description object
35 spin_lock(&c->buds_lock); in ubifs_search_bud()
36 p = c->buds.rb_node; in ubifs_search_bud()
39 if (lnum < bud->lnum) in ubifs_search_bud()
40 p = p->rb_left; in ubifs_search_bud()
41 else if (lnum > bud->lnum) in ubifs_search_bud()
42 p = p->rb_right; in ubifs_search_bud()
44 spin_unlock(&c->buds_lock); in ubifs_search_bud()
48 spin_unlock(&c->buds_lock); in ubifs_search_bud()
53 * ubifs_get_wbuf - get the wbuf associated with a LEB, if there is one.
54 * @c: UBIFS file-system description object
65 if (!c->jheads) in ubifs_get_wbuf()
68 spin_lock(&c->buds_lock); in ubifs_get_wbuf()
69 p = c->buds.rb_node; in ubifs_get_wbuf()
72 if (lnum < bud->lnum) in ubifs_get_wbuf()
73 p = p->rb_left; in ubifs_get_wbuf()
74 else if (lnum > bud->lnum) in ubifs_get_wbuf()
75 p = p->rb_right; in ubifs_get_wbuf()
77 jhead = bud->jhead; in ubifs_get_wbuf()
78 spin_unlock(&c->buds_lock); in ubifs_get_wbuf()
79 return &c->jheads[jhead].wbuf; in ubifs_get_wbuf()
82 spin_unlock(&c->buds_lock); in ubifs_get_wbuf()
87 * empty_log_bytes - calculate amount of empty space in the log.
88 * @c: UBIFS file-system description object
94 h = (long long)c->lhead_lnum * c->leb_size + c->lhead_offs; in empty_log_bytes()
95 t = (long long)c->ltail_lnum * c->leb_size; in empty_log_bytes()
98 return c->log_bytes - h + t; in empty_log_bytes()
100 return t - h; in empty_log_bytes()
101 else if (c->lhead_lnum != c->ltail_lnum) in empty_log_bytes()
104 return c->log_bytes; in empty_log_bytes()
108 * ubifs_add_bud - add bud LEB to the tree of buds and its journal head list.
109 * @c: UBIFS file-system description object
118 spin_lock(&c->buds_lock); in ubifs_add_bud()
119 p = &c->buds.rb_node; in ubifs_add_bud()
123 ubifs_assert(c, bud->lnum != b->lnum); in ubifs_add_bud()
124 if (bud->lnum < b->lnum) in ubifs_add_bud()
125 p = &(*p)->rb_left; in ubifs_add_bud()
127 p = &(*p)->rb_right; in ubifs_add_bud()
130 rb_link_node(&bud->rb, parent, p); in ubifs_add_bud()
131 rb_insert_color(&bud->rb, &c->buds); in ubifs_add_bud()
132 if (c->jheads) { in ubifs_add_bud()
133 jhead = &c->jheads[bud->jhead]; in ubifs_add_bud()
134 list_add_tail(&bud->list, &jhead->buds_list); in ubifs_add_bud()
136 ubifs_assert(c, c->replaying && c->ro_mount); in ubifs_add_bud()
144 c->bud_bytes += c->leb_size - bud->start; in ubifs_add_bud()
146 dbg_log("LEB %d:%d, jhead %s, bud_bytes %lld", bud->lnum, in ubifs_add_bud()
147 bud->start, dbg_jhead(bud->jhead), c->bud_bytes); in ubifs_add_bud()
148 spin_unlock(&c->buds_lock); in ubifs_add_bud()
152 * ubifs_add_bud_to_log - add a new bud to the log.
153 * @c: UBIFS file-system description object
160 * exceed the 'c->max_bud_bytes' limit. Returns zero in case of success,
161 * %-EAGAIN if commit is required, and a negative error code in case of
172 return -ENOMEM; in ubifs_add_bud_to_log()
173 ref = kzalloc(c->ref_node_alsz, GFP_NOFS); in ubifs_add_bud_to_log()
176 return -ENOMEM; in ubifs_add_bud_to_log()
179 mutex_lock(&c->log_mutex); in ubifs_add_bud_to_log()
180 ubifs_assert(c, !c->ro_media && !c->ro_mount); in ubifs_add_bud_to_log()
181 if (c->ro_error) { in ubifs_add_bud_to_log()
182 err = -EROFS; in ubifs_add_bud_to_log()
187 if (empty_log_bytes(c) - c->ref_node_alsz < c->min_log_bytes) { in ubifs_add_bud_to_log()
188 dbg_log("not enough log space - %lld, required %d", in ubifs_add_bud_to_log()
189 empty_log_bytes(c), c->min_log_bytes); in ubifs_add_bud_to_log()
191 err = -EAGAIN; in ubifs_add_bud_to_log()
197 * 'c->max_bud_bytes' limit, because we want to guarantee mount time in ubifs_add_bud_to_log()
200 * It is not necessary to hold @c->buds_lock when reading @c->bud_bytes in ubifs_add_bud_to_log()
201 * because we are holding @c->log_mutex. All @c->bud_bytes take place in ubifs_add_bud_to_log()
202 * when both @c->log_mutex and @c->bud_bytes are locked. in ubifs_add_bud_to_log()
204 if (c->bud_bytes + c->leb_size - offs > c->max_bud_bytes) { in ubifs_add_bud_to_log()
206 c->bud_bytes, c->max_bud_bytes); in ubifs_add_bud_to_log()
208 err = -EAGAIN; in ubifs_add_bud_to_log()
213 * If the journal is full enough - start background commit. Note, it is in ubifs_add_bud_to_log()
214 * OK to read 'c->cmt_state' without spinlock because integer reads in ubifs_add_bud_to_log()
217 if (c->bud_bytes >= c->bg_bud_bytes && in ubifs_add_bud_to_log()
218 c->cmt_state == COMMIT_RESTING) { in ubifs_add_bud_to_log()
220 c->bud_bytes, c->max_bud_bytes); in ubifs_add_bud_to_log()
224 bud->lnum = lnum; in ubifs_add_bud_to_log()
225 bud->start = offs; in ubifs_add_bud_to_log()
226 bud->jhead = jhead; in ubifs_add_bud_to_log()
227 bud->log_hash = NULL; in ubifs_add_bud_to_log()
229 ref->ch.node_type = UBIFS_REF_NODE; in ubifs_add_bud_to_log()
230 ref->lnum = cpu_to_le32(bud->lnum); in ubifs_add_bud_to_log()
231 ref->offs = cpu_to_le32(bud->start); in ubifs_add_bud_to_log()
232 ref->jhead = cpu_to_le32(jhead); in ubifs_add_bud_to_log()
234 if (c->lhead_offs > c->leb_size - c->ref_node_alsz) { in ubifs_add_bud_to_log()
235 c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); in ubifs_add_bud_to_log()
236 ubifs_assert(c, c->lhead_lnum != c->ltail_lnum); in ubifs_add_bud_to_log()
237 c->lhead_offs = 0; in ubifs_add_bud_to_log()
240 if (c->lhead_offs == 0) { in ubifs_add_bud_to_log()
242 err = ubifs_leb_unmap(c, c->lhead_lnum); in ubifs_add_bud_to_log()
247 if (bud->start == 0) { in ubifs_add_bud_to_log()
255 err = ubifs_leb_map(c, bud->lnum); in ubifs_add_bud_to_log()
261 c->lhead_lnum, c->lhead_offs); in ubifs_add_bud_to_log()
262 err = ubifs_write_node(c, ref, UBIFS_REF_NODE_SZ, c->lhead_lnum, in ubifs_add_bud_to_log()
263 c->lhead_offs); in ubifs_add_bud_to_log()
267 err = ubifs_shash_update(c, c->log_hash, ref, UBIFS_REF_NODE_SZ); in ubifs_add_bud_to_log()
271 err = ubifs_shash_copy_state(c, c->log_hash, c->jheads[jhead].log_hash); in ubifs_add_bud_to_log()
275 c->lhead_offs += c->ref_node_alsz; in ubifs_add_bud_to_log()
279 mutex_unlock(&c->log_mutex); in ubifs_add_bud_to_log()
284 mutex_unlock(&c->log_mutex); in ubifs_add_bud_to_log()
291 * remove_buds - remove used buds.
292 * @c: UBIFS file-system description object
301 ubifs_assert(c, list_empty(&c->old_buds)); in remove_buds()
302 c->cmt_bud_bytes = 0; in remove_buds()
303 spin_lock(&c->buds_lock); in remove_buds()
304 p = rb_first(&c->buds); in remove_buds()
312 wbuf = &c->jheads[bud->jhead].wbuf; in remove_buds()
314 if (wbuf->lnum == bud->lnum) { in remove_buds()
317 * heads (non-closed buds). in remove_buds()
319 c->cmt_bud_bytes += wbuf->offs - bud->start; in remove_buds()
321 bud->lnum, bud->start, dbg_jhead(bud->jhead), in remove_buds()
322 wbuf->offs - bud->start, c->cmt_bud_bytes); in remove_buds()
323 bud->start = wbuf->offs; in remove_buds()
325 c->cmt_bud_bytes += c->leb_size - bud->start; in remove_buds()
327 bud->lnum, bud->start, dbg_jhead(bud->jhead), in remove_buds()
328 c->leb_size - bud->start, c->cmt_bud_bytes); in remove_buds()
329 rb_erase(p1, &c->buds); in remove_buds()
337 list_move(&bud->list, &c->old_buds); in remove_buds()
340 spin_unlock(&c->buds_lock); in remove_buds()
344 * ubifs_log_start_commit - start commit.
345 * @c: UBIFS file-system description object
353 * returns zero in case of success and a negative error code in case of
367 max_len = UBIFS_CS_NODE_SZ + c->jhead_cnt * UBIFS_REF_NODE_SZ; in ubifs_log_start_commit()
368 max_len = ALIGN(max_len, c->min_io_size); in ubifs_log_start_commit()
371 return -ENOMEM; in ubifs_log_start_commit()
373 cs->ch.node_type = UBIFS_CS_NODE; in ubifs_log_start_commit()
374 cs->cmt_no = cpu_to_le64(c->cmt_no); in ubifs_log_start_commit()
377 err = ubifs_shash_init(c, c->log_hash); in ubifs_log_start_commit()
381 err = ubifs_shash_update(c, c->log_hash, cs, UBIFS_CS_NODE_SZ); in ubifs_log_start_commit()
386 * Note, we do not lock 'c->log_mutex' because this is the commit start in ubifs_log_start_commit()
387 * phase and we are exclusively using the log. And we do not lock in ubifs_log_start_commit()
388 * write-buffer because nobody can write to the file-system at this in ubifs_log_start_commit()
389 * phase. in ubifs_log_start_commit()
393 for (i = 0; i < c->jhead_cnt; i++) { in ubifs_log_start_commit()
394 int lnum = c->jheads[i].wbuf.lnum; in ubifs_log_start_commit()
395 int offs = c->jheads[i].wbuf.offs; in ubifs_log_start_commit()
397 if (lnum == -1 || offs == c->leb_size) in ubifs_log_start_commit()
403 ref->ch.node_type = UBIFS_REF_NODE; in ubifs_log_start_commit()
404 ref->lnum = cpu_to_le32(lnum); in ubifs_log_start_commit()
405 ref->offs = cpu_to_le32(offs); in ubifs_log_start_commit()
406 ref->jhead = cpu_to_le32(i); in ubifs_log_start_commit()
411 err = ubifs_shash_update(c, c->log_hash, ref, in ubifs_log_start_commit()
415 ubifs_shash_copy_state(c, c->log_hash, c->jheads[i].log_hash); in ubifs_log_start_commit()
418 ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); in ubifs_log_start_commit()
421 if (c->lhead_offs) { in ubifs_log_start_commit()
422 c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); in ubifs_log_start_commit()
423 ubifs_assert(c, c->lhead_lnum != c->ltail_lnum); in ubifs_log_start_commit()
424 c->lhead_offs = 0; in ubifs_log_start_commit()
428 err = ubifs_leb_unmap(c, c->lhead_lnum); in ubifs_log_start_commit()
432 len = ALIGN(len, c->min_io_size); in ubifs_log_start_commit()
433 dbg_log("writing commit start at LEB %d:0, len %d", c->lhead_lnum, len); in ubifs_log_start_commit()
434 err = ubifs_leb_write(c, c->lhead_lnum, cs, 0, len); in ubifs_log_start_commit()
438 *ltail_lnum = c->lhead_lnum; in ubifs_log_start_commit()
440 c->lhead_offs += len; in ubifs_log_start_commit()
441 ubifs_assert(c, c->lhead_offs < c->leb_size); in ubifs_log_start_commit()
449 c->min_log_bytes = 0; in ubifs_log_start_commit()
457 * ubifs_log_end_commit - end commit.
458 * @c: UBIFS file-system description object
463 * the new log tail LEB number. Returns zero in case of success and a negative
471 * At this phase we have to lock 'c->log_mutex' because UBIFS allows FS in ubifs_log_end_commit()
472 * writes during commit. Its only short "commit" start phase when in ubifs_log_end_commit()
475 mutex_lock(&c->log_mutex); in ubifs_log_end_commit()
478 c->ltail_lnum, ltail_lnum); in ubifs_log_end_commit()
480 c->ltail_lnum = ltail_lnum; in ubifs_log_end_commit()
485 c->min_log_bytes = c->leb_size; in ubifs_log_end_commit()
487 spin_lock(&c->buds_lock); in ubifs_log_end_commit()
488 c->bud_bytes -= c->cmt_bud_bytes; in ubifs_log_end_commit()
489 spin_unlock(&c->buds_lock); in ubifs_log_end_commit()
498 mutex_unlock(&c->log_mutex); in ubifs_log_end_commit()
503 * ubifs_log_post_commit - things to do after commit is completed.
504 * @c: UBIFS file-system description object
513 * This function returns %0 on success and a negative error code on failure.
519 while (!list_empty(&c->old_buds)) { in ubifs_log_post_commit()
522 bud = list_entry(c->old_buds.next, struct ubifs_bud, list); in ubifs_log_post_commit()
523 err = ubifs_return_leb(c, bud->lnum); in ubifs_log_post_commit()
526 list_del(&bud->list); in ubifs_log_post_commit()
527 kfree(bud->log_hash); in ubifs_log_post_commit()
530 mutex_lock(&c->log_mutex); in ubifs_log_post_commit()
531 for (lnum = old_ltail_lnum; lnum != c->ltail_lnum; in ubifs_log_post_commit()
539 mutex_unlock(&c->log_mutex); in ubifs_log_post_commit()
544 * struct done_ref - references that have been done.
545 * @rb: rb-tree node
554 * done_already - determine if a reference has been done already.
555 * @done_tree: rb-tree to store references that have been done
559 * a negative error code is returned.
563 struct rb_node **p = &done_tree->rb_node, *parent = NULL; in done_already()
569 if (lnum < dr->lnum) in done_already()
570 p = &(*p)->rb_left; in done_already()
571 else if (lnum > dr->lnum) in done_already()
572 p = &(*p)->rb_right; in done_already()
579 return -ENOMEM; in done_already()
581 dr->lnum = lnum; in done_already()
583 rb_link_node(&dr->rb, parent, p); in done_already()
584 rb_insert_color(&dr->rb, done_tree); in done_already()
590 * destroy_done_tree - destroy the done tree.
602 * add_node - add a node to the consolidated log.
603 * @c: UBIFS file-system description object
609 * This function returns %0 on success and a negative error code on failure.
615 int len = le32_to_cpu(ch->len), remains = c->leb_size - *offs; in add_node()
618 int sz = ALIGN(*offs, c->min_io_size), err; in add_node()
620 ubifs_pad(c, buf + *offs, sz - *offs); in add_node()
633 * ubifs_consolidate_log - consolidate the log.
634 * @c: UBIFS file-system description object
640 * This function returns %0 on success and a negative error code on failure.
650 dbg_rcvry("log tail LEB %d, log head LEB %d", c->ltail_lnum, in ubifs_consolidate_log()
651 c->lhead_lnum); in ubifs_consolidate_log()
652 buf = vmalloc(c->leb_size); in ubifs_consolidate_log()
654 return -ENOMEM; in ubifs_consolidate_log()
655 lnum = c->ltail_lnum; in ubifs_consolidate_log()
658 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0); in ubifs_consolidate_log()
663 list_for_each_entry(snod, &sleb->nodes, list) { in ubifs_consolidate_log()
664 switch (snod->type) { in ubifs_consolidate_log()
666 struct ubifs_ref_node *ref = snod->node; in ubifs_consolidate_log()
667 int ref_lnum = le32_to_cpu(ref->lnum); in ubifs_consolidate_log()
674 &offs, snod->node); in ubifs_consolidate_log()
684 snod->node); in ubifs_consolidate_log()
692 if (lnum == c->lhead_lnum) in ubifs_consolidate_log()
697 int sz = ALIGN(offs, c->min_io_size); in ubifs_consolidate_log()
699 ubifs_pad(c, buf + offs, sz - offs); in ubifs_consolidate_log()
703 offs = ALIGN(offs, c->min_io_size); in ubifs_consolidate_log()
707 if (write_lnum == c->lhead_lnum) { in ubifs_consolidate_log()
709 return -EINVAL; in ubifs_consolidate_log()
718 } while (lnum != c->lhead_lnum); in ubifs_consolidate_log()
719 c->lhead_lnum = write_lnum; in ubifs_consolidate_log()
720 c->lhead_offs = offs; in ubifs_consolidate_log()
721 dbg_rcvry("new log head at %d:%d", c->lhead_lnum, c->lhead_offs); in ubifs_consolidate_log()
733 * dbg_check_bud_bytes - make sure bud bytes calculation are all right.
734 * @c: UBIFS file-system description object
737 * ('c->bud_bytes' is correct). Returns zero in case of success and %-EINVAL in
749 spin_lock(&c->buds_lock); in dbg_check_bud_bytes()
750 for (i = 0; i < c->jhead_cnt; i++) in dbg_check_bud_bytes()
751 list_for_each_entry(bud, &c->jheads[i].buds_list, list) in dbg_check_bud_bytes()
752 bud_bytes += c->leb_size - bud->start; in dbg_check_bud_bytes()
754 if (c->bud_bytes != bud_bytes) { in dbg_check_bud_bytes()
756 c->bud_bytes, bud_bytes); in dbg_check_bud_bytes()
757 err = -EINVAL; in dbg_check_bud_bytes()
759 spin_unlock(&c->buds_lock); in dbg_check_bud_bytes()