Lines Matching refs:c
97 static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf, in get_master_node() argument
100 const int sz = c->mst_node_alsz; in get_master_node()
104 sbuf = vmalloc(c->leb_size); in get_master_node()
108 err = ubifs_leb_read(c, lnum, sbuf, 0, c->leb_size, 0); in get_master_node()
115 len = c->leb_size; in get_master_node()
116 while (offs + UBIFS_MST_NODE_SZ <= c->leb_size) { in get_master_node()
132 ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); in get_master_node()
138 ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); in get_master_node()
160 if (offs < c->leb_size) { in get_master_node()
170 if (offs < c->leb_size) in get_master_node()
192 static int write_rcvrd_mst_node(struct ubifs_info *c, in write_rcvrd_mst_node() argument
195 int err = 0, lnum = UBIFS_MST_LNUM, sz = c->mst_node_alsz; in write_rcvrd_mst_node()
203 err = ubifs_prepare_node_hmac(c, mst, UBIFS_MST_NODE_SZ, in write_rcvrd_mst_node()
207 err = ubifs_leb_change(c, lnum, mst, sz); in write_rcvrd_mst_node()
210 err = ubifs_leb_change(c, lnum + 1, mst, sz); in write_rcvrd_mst_node()
227 int ubifs_recover_master_node(struct ubifs_info *c) in ubifs_recover_master_node() argument
231 const int sz = c->mst_node_alsz; in ubifs_recover_master_node()
236 err = get_master_node(c, UBIFS_MST_LNUM, &buf1, &mst1, &cor1); in ubifs_recover_master_node()
240 err = get_master_node(c, UBIFS_MST_LNUM + 1, &buf2, &mst2, &cor2); in ubifs_recover_master_node()
258 if (ubifs_compare_master_node(c, mst1, mst2)) in ubifs_recover_master_node()
267 c->leb_size - offs2 - sz < sz) { in ubifs_recover_master_node()
292 if (offs2 + sz + sz <= c->leb_size) in ubifs_recover_master_node()
297 ubifs_msg(c, "recovered master node from LEB %d", in ubifs_recover_master_node()
300 memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); in ubifs_recover_master_node()
302 if (c->ro_mount) { in ubifs_recover_master_node()
304 c->rcvrd_mst_node = kmalloc(sz, GFP_KERNEL); in ubifs_recover_master_node()
305 if (!c->rcvrd_mst_node) { in ubifs_recover_master_node()
309 memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); in ubifs_recover_master_node()
335 c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); in ubifs_recover_master_node()
338 c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1; in ubifs_recover_master_node()
339 err = write_rcvrd_mst_node(c, c->mst_node); in ubifs_recover_master_node()
352 ubifs_err(c, "failed to recover master node"); in ubifs_recover_master_node()
354 ubifs_err(c, "dumping first master node"); in ubifs_recover_master_node()
355 ubifs_dump_node(c, mst1); in ubifs_recover_master_node()
358 ubifs_err(c, "dumping second master node"); in ubifs_recover_master_node()
359 ubifs_dump_node(c, mst2); in ubifs_recover_master_node()
375 int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) in ubifs_write_rcvrd_mst_node() argument
379 if (!c->rcvrd_mst_node) in ubifs_write_rcvrd_mst_node()
381 c->rcvrd_mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); in ubifs_write_rcvrd_mst_node()
382 c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); in ubifs_write_rcvrd_mst_node()
383 err = write_rcvrd_mst_node(c, c->rcvrd_mst_node); in ubifs_write_rcvrd_mst_node()
386 kfree(c->rcvrd_mst_node); in ubifs_write_rcvrd_mst_node()
387 c->rcvrd_mst_node = NULL; in ubifs_write_rcvrd_mst_node()
402 static int is_last_write(const struct ubifs_info *c, void *buf, int offs) in is_last_write() argument
411 empty_offs = ALIGN(offs + 1, c->max_write_size); in is_last_write()
412 check_len = c->leb_size - empty_offs; in is_last_write()
429 static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, in clean_buf() argument
436 ubifs_assert(c, !(*offs & 7)); in clean_buf()
437 empty_offs = ALIGN(*offs, c->min_io_size); in clean_buf()
439 ubifs_pad(c, *buf, pad_len); in clean_buf()
443 memset(*buf, 0xff, c->leb_size - empty_offs); in clean_buf()
458 static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, in no_more_nodes() argument
465 skip = ALIGN(offs + UBIFS_CH_SZ, c->max_write_size) - offs; in no_more_nodes()
472 if (ubifs_check_node(c, buf, lnum, offs, 1, 0) != -EUCLEAN) { in no_more_nodes()
477 skip = ALIGN(offs + dlen, c->max_write_size) - offs; in no_more_nodes()
491 static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, in fix_unclean_leb() argument
505 if (c->ro_mount && !c->remounting_rw) { in fix_unclean_leb()
516 list_add_tail(&ucleb->list, &c->unclean_leb_list); in fix_unclean_leb()
524 err = ubifs_leb_unmap(c, lnum); in fix_unclean_leb()
528 int len = ALIGN(endpt, c->min_io_size); in fix_unclean_leb()
531 err = ubifs_leb_read(c, lnum, sleb->buf, 0, in fix_unclean_leb()
543 ubifs_pad(c, buf, pad_len); in fix_unclean_leb()
546 err = ubifs_leb_change(c, lnum, sleb->buf, len); in fix_unclean_leb()
622 struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, in ubifs_recover_leb() argument
625 int ret = 0, err, len = c->leb_size - offs, start = offs, min_io_unit; in ubifs_recover_leb()
626 int grouped = jhead == -1 ? 0 : c->jheads[jhead].grouped; in ubifs_recover_leb()
632 sleb = ubifs_start_scan(c, lnum, offs, sbuf); in ubifs_recover_leb()
636 ubifs_assert(c, len >= 8); in ubifs_recover_leb()
647 ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); in ubifs_recover_leb()
653 err = ubifs_add_snod(c, sleb, buf, offs); in ubifs_recover_leb()
673 ubifs_err(c, "unexpected return value %d", ret); in ubifs_recover_leb()
680 if (!is_last_write(c, buf, offs)) in ubifs_recover_leb()
683 if (!no_more_nodes(c, buf, len, lnum, offs)) in ubifs_recover_leb()
686 if (!is_last_write(c, buf, offs)) { in ubifs_recover_leb()
693 ubifs_err(c, "corrupt empty space LEB %d:%d, corruption starts at %d", in ubifs_recover_leb()
702 min_io_unit = round_down(offs, c->min_io_size); in ubifs_recover_leb()
766 len = c->leb_size - offs; in ubifs_recover_leb()
768 clean_buf(c, &buf, lnum, &offs, &len); in ubifs_recover_leb()
769 ubifs_end_scan(c, sleb, lnum, offs); in ubifs_recover_leb()
771 err = fix_unclean_leb(c, sleb, start); in ubifs_recover_leb()
779 ubifs_err(c, "corruption %d", ret); in ubifs_recover_leb()
780 ubifs_scan_a_node(c, buf, len, lnum, offs, 0); in ubifs_recover_leb()
782 ubifs_scanned_corruption(c, lnum, offs, buf); in ubifs_recover_leb()
785 ubifs_err(c, "LEB %d scanning failed", lnum); in ubifs_recover_leb()
799 static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, in get_cs_sqnum() argument
809 if (c->leb_size - offs < UBIFS_CS_NODE_SZ) in get_cs_sqnum()
811 err = ubifs_leb_read(c, lnum, (void *)cs_node, offs, in get_cs_sqnum()
815 ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0); in get_cs_sqnum()
817 ubifs_err(c, "Not a valid node"); in get_cs_sqnum()
821 ubifs_err(c, "Not a CS node, type is %d", cs_node->ch.node_type); in get_cs_sqnum()
824 if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) { in get_cs_sqnum()
825 ubifs_err(c, "CS node cmt_no %llu != current cmt_no %llu", in get_cs_sqnum()
827 c->cmt_no); in get_cs_sqnum()
838 ubifs_err(c, "failed to get CS sqnum"); in get_cs_sqnum()
856 struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, in ubifs_recover_log_leb() argument
864 if (next_lnum >= UBIFS_LOG_LNUM + c->log_lebs) in ubifs_recover_log_leb()
866 if (next_lnum != c->ltail_lnum) { in ubifs_recover_log_leb()
871 sleb = ubifs_scan(c, next_lnum, 0, sbuf, 0); in ubifs_recover_log_leb()
876 unsigned long long cs_sqnum = c->cs_sqnum; in ubifs_recover_log_leb()
883 err = get_cs_sqnum(c, lnum, offs, &cs_sqnum); in ubifs_recover_log_leb()
890 ubifs_err(c, "unrecoverable log corruption in LEB %d", in ubifs_recover_log_leb()
898 return ubifs_recover_leb(c, lnum, offs, sbuf, -1); in ubifs_recover_log_leb()
912 static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf) in recover_head() argument
914 int len = c->max_write_size, err; in recover_head()
916 if (offs + len > c->leb_size) in recover_head()
917 len = c->leb_size - offs; in recover_head()
923 err = ubifs_leb_read(c, lnum, sbuf, offs, len, 1); in recover_head()
927 return ubifs_leb_unmap(c, lnum); in recover_head()
928 err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1); in recover_head()
931 return ubifs_leb_change(c, lnum, sbuf, offs); in recover_head()
954 int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf) in ubifs_recover_inl_heads() argument
958 ubifs_assert(c, !c->ro_mount || c->remounting_rw); in ubifs_recover_inl_heads()
960 dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs); in ubifs_recover_inl_heads()
961 err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf); in ubifs_recover_inl_heads()
965 dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs); in ubifs_recover_inl_heads()
967 return recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf); in ubifs_recover_inl_heads()
982 static int clean_an_unclean_leb(struct ubifs_info *c, in clean_an_unclean_leb() argument
992 return ubifs_leb_unmap(c, lnum); in clean_an_unclean_leb()
995 err = ubifs_leb_read(c, lnum, buf, offs, len, 0); in clean_an_unclean_leb()
1005 ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet); in clean_an_unclean_leb()
1028 ubifs_err(c, "unexpected empty space at %d:%d", in clean_an_unclean_leb()
1039 ubifs_scanned_corruption(c, lnum, offs, buf); in clean_an_unclean_leb()
1044 len = ALIGN(ucleb->endpt, c->min_io_size); in clean_an_unclean_leb()
1049 buf = c->sbuf + len - pad_len; in clean_an_unclean_leb()
1050 ubifs_pad(c, buf, pad_len); in clean_an_unclean_leb()
1055 err = ubifs_leb_change(c, lnum, sbuf, len); in clean_an_unclean_leb()
1075 int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf) in ubifs_clean_lebs() argument
1078 while (!list_empty(&c->unclean_leb_list)) { in ubifs_clean_lebs()
1082 ucleb = list_entry(c->unclean_leb_list.next, in ubifs_clean_lebs()
1084 err = clean_an_unclean_leb(c, ucleb, sbuf); in ubifs_clean_lebs()
1101 static int grab_empty_leb(struct ubifs_info *c) in grab_empty_leb() argument
1120 lnum = ubifs_find_free_leb_for_idx(c); in grab_empty_leb()
1122 ubifs_err(c, "could not find an empty LEB"); in grab_empty_leb()
1123 ubifs_dump_lprops(c); in grab_empty_leb()
1124 ubifs_dump_budg(c, &c->bi); in grab_empty_leb()
1129 err = ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0, in grab_empty_leb()
1134 c->gc_lnum = lnum; in grab_empty_leb()
1137 return ubifs_run_commit(c); in grab_empty_leb()
1158 int ubifs_rcvry_gc_commit(struct ubifs_info *c) in ubifs_rcvry_gc_commit() argument
1160 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; in ubifs_rcvry_gc_commit()
1166 c->gc_lnum = -1; in ubifs_rcvry_gc_commit()
1167 if (wbuf->lnum == -1 || wbuf->offs == c->leb_size) in ubifs_rcvry_gc_commit()
1168 return grab_empty_leb(c); in ubifs_rcvry_gc_commit()
1170 err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); in ubifs_rcvry_gc_commit()
1176 return grab_empty_leb(c); in ubifs_rcvry_gc_commit()
1179 ubifs_assert(c, !(lp.flags & LPROPS_INDEX)); in ubifs_rcvry_gc_commit()
1180 ubifs_assert(c, lp.free + lp.dirty >= wbuf->offs); in ubifs_rcvry_gc_commit()
1187 err = ubifs_run_commit(c); in ubifs_rcvry_gc_commit()
1193 err = ubifs_garbage_collect_leb(c, &lp); in ubifs_rcvry_gc_commit()
1202 ubifs_err(c, "GC failed, error %d", err); in ubifs_rcvry_gc_commit()
1208 ubifs_assert(c, err == LEB_RETAINED); in ubifs_rcvry_gc_commit()
1212 err = ubifs_leb_unmap(c, c->gc_lnum); in ubifs_rcvry_gc_commit()
1246 static int add_ino(struct ubifs_info *c, ino_t inum, loff_t i_size, in add_ino() argument
1249 struct rb_node **p = &c->size_tree.rb_node, *parent = NULL; in add_ino()
1271 rb_insert_color(&e->rb, &c->size_tree); in add_ino()
1281 static struct size_entry *find_ino(struct ubifs_info *c, ino_t inum) in find_ino() argument
1283 struct rb_node *p = c->size_tree.rb_node; in find_ino()
1303 static void remove_ino(struct ubifs_info *c, ino_t inum) in remove_ino() argument
1305 struct size_entry *e = find_ino(c, inum); in remove_ino()
1309 rb_erase(&e->rb, &c->size_tree); in remove_ino()
1317 void ubifs_destroy_size_tree(struct ubifs_info *c) in ubifs_destroy_size_tree() argument
1321 rbtree_postorder_for_each_entry_safe(e, n, &c->size_tree, rb) { in ubifs_destroy_size_tree()
1326 c->size_tree = RB_ROOT; in ubifs_destroy_size_tree()
1354 int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, in ubifs_recover_size_accum() argument
1357 ino_t inum = key_inum(c, key); in ubifs_recover_size_accum()
1361 switch (key_type(c, key)) { in ubifs_recover_size_accum()
1364 remove_ino(c, inum); in ubifs_recover_size_accum()
1366 e = find_ino(c, inum); in ubifs_recover_size_accum()
1371 err = add_ino(c, inum, new_size, 0, 1); in ubifs_recover_size_accum()
1378 e = find_ino(c, inum); in ubifs_recover_size_accum()
1383 err = add_ino(c, inum, 0, new_size, 0); in ubifs_recover_size_accum()
1389 e = find_ino(c, inum); in ubifs_recover_size_accum()
1402 static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) in fix_size_in_place() argument
1404 struct ubifs_ino_node *ino = c->sbuf; in fix_size_in_place()
1412 ino_key_init(c, &key, e->inum); in fix_size_in_place()
1413 err = ubifs_tnc_locate(c, &key, ino, &lnum, &offs); in fix_size_in_place()
1424 err = ubifs_leb_read(c, lnum, c->sbuf, 0, c->leb_size, 1); in fix_size_in_place()
1428 ino = c->sbuf + offs; in fix_size_in_place()
1434 p = c->sbuf; in fix_size_in_place()
1435 len = c->leb_size - 1; in fix_size_in_place()
1438 len = ALIGN(len + 1, c->min_io_size); in fix_size_in_place()
1440 err = ubifs_leb_change(c, lnum, c->sbuf, len); in fix_size_in_place()
1448 ubifs_warn(c, "inode %lu failed to fix size %lld -> %lld error %d", in fix_size_in_place()
1458 static int inode_fix_size(struct ubifs_info *c, struct size_entry *e) in inode_fix_size() argument
1464 if (c->ro_mount) in inode_fix_size()
1465 ubifs_assert(c, !e->inode); in inode_fix_size()
1471 inode = ubifs_iget(c->vfs_sb, e->inum); in inode_fix_size()
1502 if (c->ro_mount) in inode_fix_size()
1505 err = ubifs_jnl_write_inode(c, inode); in inode_fix_size()
1512 rb_erase(&e->rb, &c->size_tree); in inode_fix_size()
1528 int ubifs_recover_size(struct ubifs_info *c, bool in_place) in ubifs_recover_size() argument
1530 struct rb_node *this = rb_first(&c->size_tree); in ubifs_recover_size()
1543 ino_key_init(c, &key, e->inum); in ubifs_recover_size()
1544 err = ubifs_tnc_lookup(c, &key, c->sbuf); in ubifs_recover_size()
1551 err = ubifs_tnc_remove_ino(c, e->inum); in ubifs_recover_size()
1555 struct ubifs_ino_node *ino = c->sbuf; in ubifs_recover_size()
1563 ubifs_assert(c, !(c->ro_mount && in_place)); in ubifs_recover_size()
1571 err = fix_size_in_place(c, e); in ubifs_recover_size()
1576 err = inode_fix_size(c, e); in ubifs_recover_size()
1583 rb_erase(&e->rb, &c->size_tree); in ubifs_recover_size()