11e51764aSArtem Bityutskiy /* 21e51764aSArtem Bityutskiy * This file is part of UBIFS. 31e51764aSArtem Bityutskiy * 41e51764aSArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation. 51e51764aSArtem Bityutskiy * 61e51764aSArtem Bityutskiy * This program is free software; you can redistribute it and/or modify it 71e51764aSArtem Bityutskiy * under the terms of the GNU General Public License version 2 as published by 81e51764aSArtem Bityutskiy * the Free Software Foundation. 91e51764aSArtem Bityutskiy * 101e51764aSArtem Bityutskiy * This program is distributed in the hope that it will be useful, but WITHOUT 111e51764aSArtem Bityutskiy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 121e51764aSArtem Bityutskiy * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 131e51764aSArtem Bityutskiy * more details. 141e51764aSArtem Bityutskiy * 151e51764aSArtem Bityutskiy * You should have received a copy of the GNU General Public License along with 161e51764aSArtem Bityutskiy * this program; if not, write to the Free Software Foundation, Inc., 51 171e51764aSArtem Bityutskiy * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 181e51764aSArtem Bityutskiy * 191e51764aSArtem Bityutskiy * Authors: Adrian Hunter 201e51764aSArtem Bityutskiy * Artem Bityutskiy (Битюцкий Артём) 211e51764aSArtem Bityutskiy */ 221e51764aSArtem Bityutskiy 231e51764aSArtem Bityutskiy /* 241e51764aSArtem Bityutskiy * This file contains journal replay code. It runs when the file-system is being 251e51764aSArtem Bityutskiy * mounted and requires no locking. 261e51764aSArtem Bityutskiy * 271e51764aSArtem Bityutskiy * The larger is the journal, the longer it takes to scan it, so the longer it 281e51764aSArtem Bityutskiy * takes to mount UBIFS. This is why the journal has limited size which may be 291e51764aSArtem Bityutskiy * changed depending on the system requirements. But a larger journal gives 301e51764aSArtem Bityutskiy * faster I/O speed because it writes the index less frequently. So this is a 311e51764aSArtem Bityutskiy * trade-off. Also, the journal is indexed by the in-memory index (TNC), so the 321e51764aSArtem Bityutskiy * larger is the journal, the more memory its index may consume. 331e51764aSArtem Bityutskiy */ 341e51764aSArtem Bityutskiy 351e51764aSArtem Bityutskiy #include "ubifs.h" 361e51764aSArtem Bityutskiy 371e51764aSArtem Bityutskiy /* 381e51764aSArtem Bityutskiy * Replay flags. 391e51764aSArtem Bityutskiy * 401e51764aSArtem Bityutskiy * REPLAY_DELETION: node was deleted 411e51764aSArtem Bityutskiy * REPLAY_REF: node is a reference node 421e51764aSArtem Bityutskiy */ 431e51764aSArtem Bityutskiy enum { 441e51764aSArtem Bityutskiy REPLAY_DELETION = 1, 451e51764aSArtem Bityutskiy REPLAY_REF = 2, 461e51764aSArtem Bityutskiy }; 471e51764aSArtem Bityutskiy 481e51764aSArtem Bityutskiy /** 491e51764aSArtem Bityutskiy * struct replay_entry - replay tree entry. 501e51764aSArtem Bityutskiy * @lnum: logical eraseblock number of the node 511e51764aSArtem Bityutskiy * @offs: node offset 521e51764aSArtem Bityutskiy * @len: node length 531e51764aSArtem Bityutskiy * @sqnum: node sequence number 541e51764aSArtem Bityutskiy * @flags: replay flags 551e51764aSArtem Bityutskiy * @rb: links the replay tree 561e51764aSArtem Bityutskiy * @key: node key 571e51764aSArtem Bityutskiy * @nm: directory entry name 581e51764aSArtem Bityutskiy * @old_size: truncation old size 591e51764aSArtem Bityutskiy * @new_size: truncation new size 601e51764aSArtem Bityutskiy * @free: amount of free space in a bud 611e51764aSArtem Bityutskiy * @dirty: amount of dirty space in a bud from padding and deletion nodes 621e51764aSArtem Bityutskiy * 631e51764aSArtem Bityutskiy * UBIFS journal replay must compare node sequence numbers, which means it must 641e51764aSArtem Bityutskiy * build a tree of node information to insert into the TNC. 651e51764aSArtem Bityutskiy */ 661e51764aSArtem Bityutskiy struct replay_entry { 671e51764aSArtem Bityutskiy int lnum; 681e51764aSArtem Bityutskiy int offs; 691e51764aSArtem Bityutskiy int len; 701e51764aSArtem Bityutskiy unsigned long long sqnum; 711e51764aSArtem Bityutskiy int flags; 721e51764aSArtem Bityutskiy struct rb_node rb; 731e51764aSArtem Bityutskiy union ubifs_key key; 741e51764aSArtem Bityutskiy union { 751e51764aSArtem Bityutskiy struct qstr nm; 761e51764aSArtem Bityutskiy struct { 771e51764aSArtem Bityutskiy loff_t old_size; 781e51764aSArtem Bityutskiy loff_t new_size; 791e51764aSArtem Bityutskiy }; 801e51764aSArtem Bityutskiy struct { 811e51764aSArtem Bityutskiy int free; 821e51764aSArtem Bityutskiy int dirty; 831e51764aSArtem Bityutskiy }; 841e51764aSArtem Bityutskiy }; 851e51764aSArtem Bityutskiy }; 861e51764aSArtem Bityutskiy 871e51764aSArtem Bityutskiy /** 881e51764aSArtem Bityutskiy * struct bud_entry - entry in the list of buds to replay. 891e51764aSArtem Bityutskiy * @list: next bud in the list 901e51764aSArtem Bityutskiy * @bud: bud description object 911e51764aSArtem Bityutskiy * @free: free bytes in the bud 921e51764aSArtem Bityutskiy * @sqnum: reference node sequence number 931e51764aSArtem Bityutskiy */ 941e51764aSArtem Bityutskiy struct bud_entry { 951e51764aSArtem Bityutskiy struct list_head list; 961e51764aSArtem Bityutskiy struct ubifs_bud *bud; 971e51764aSArtem Bityutskiy int free; 981e51764aSArtem Bityutskiy unsigned long long sqnum; 991e51764aSArtem Bityutskiy }; 1001e51764aSArtem Bityutskiy 1011e51764aSArtem Bityutskiy /** 1021e51764aSArtem Bityutskiy * set_bud_lprops - set free and dirty space used by a bud. 1031e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1041e51764aSArtem Bityutskiy * @r: replay entry of bud 1051e51764aSArtem Bityutskiy */ 1061e51764aSArtem Bityutskiy static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r) 1071e51764aSArtem Bityutskiy { 1081e51764aSArtem Bityutskiy const struct ubifs_lprops *lp; 1091e51764aSArtem Bityutskiy int err = 0, dirty; 1101e51764aSArtem Bityutskiy 1111e51764aSArtem Bityutskiy ubifs_get_lprops(c); 1121e51764aSArtem Bityutskiy 1131e51764aSArtem Bityutskiy lp = ubifs_lpt_lookup_dirty(c, r->lnum); 1141e51764aSArtem Bityutskiy if (IS_ERR(lp)) { 1151e51764aSArtem Bityutskiy err = PTR_ERR(lp); 1161e51764aSArtem Bityutskiy goto out; 1171e51764aSArtem Bityutskiy } 1181e51764aSArtem Bityutskiy 1191e51764aSArtem Bityutskiy dirty = lp->dirty; 1201e51764aSArtem Bityutskiy if (r->offs == 0 && (lp->free != c->leb_size || lp->dirty != 0)) { 1211e51764aSArtem Bityutskiy /* 1221e51764aSArtem Bityutskiy * The LEB was added to the journal with a starting offset of 1231e51764aSArtem Bityutskiy * zero which means the LEB must have been empty. The LEB 1241e51764aSArtem Bityutskiy * property values should be lp->free == c->leb_size and 1251e51764aSArtem Bityutskiy * lp->dirty == 0, but that is not the case. The reason is that 1261e51764aSArtem Bityutskiy * the LEB was garbage collected. The garbage collector resets 1271e51764aSArtem Bityutskiy * the free and dirty space without recording it anywhere except 1281e51764aSArtem Bityutskiy * lprops, so if there is not a commit then lprops does not have 1291e51764aSArtem Bityutskiy * that information next time the file system is mounted. 1301e51764aSArtem Bityutskiy * 1311e51764aSArtem Bityutskiy * We do not need to adjust free space because the scan has told 1321e51764aSArtem Bityutskiy * us the exact value which is recorded in the replay entry as 1331e51764aSArtem Bityutskiy * r->free. 1341e51764aSArtem Bityutskiy * 1351e51764aSArtem Bityutskiy * However we do need to subtract from the dirty space the 1361e51764aSArtem Bityutskiy * amount of space that the garbage collector reclaimed, which 1371e51764aSArtem Bityutskiy * is the whole LEB minus the amount of space that was free. 1381e51764aSArtem Bityutskiy */ 1391e51764aSArtem Bityutskiy dbg_mnt("bud LEB %d was GC'd (%d free, %d dirty)", r->lnum, 1401e51764aSArtem Bityutskiy lp->free, lp->dirty); 1411e51764aSArtem Bityutskiy dbg_gc("bud LEB %d was GC'd (%d free, %d dirty)", r->lnum, 1421e51764aSArtem Bityutskiy lp->free, lp->dirty); 1431e51764aSArtem Bityutskiy dirty -= c->leb_size - lp->free; 1441e51764aSArtem Bityutskiy /* 1451e51764aSArtem Bityutskiy * If the replay order was perfect the dirty space would now be 1461e51764aSArtem Bityutskiy * zero. The order is not perfect because the the journal heads 1471e51764aSArtem Bityutskiy * race with each other. This is not a problem but is does mean 1481e51764aSArtem Bityutskiy * that the dirty space may temporarily exceed c->leb_size 1491e51764aSArtem Bityutskiy * during the replay. 1501e51764aSArtem Bityutskiy */ 1511e51764aSArtem Bityutskiy if (dirty != 0) 1521e51764aSArtem Bityutskiy dbg_msg("LEB %d lp: %d free %d dirty " 1531e51764aSArtem Bityutskiy "replay: %d free %d dirty", r->lnum, lp->free, 1541e51764aSArtem Bityutskiy lp->dirty, r->free, r->dirty); 1551e51764aSArtem Bityutskiy } 1561e51764aSArtem Bityutskiy lp = ubifs_change_lp(c, lp, r->free, dirty + r->dirty, 1571e51764aSArtem Bityutskiy lp->flags | LPROPS_TAKEN, 0); 1581e51764aSArtem Bityutskiy if (IS_ERR(lp)) { 1591e51764aSArtem Bityutskiy err = PTR_ERR(lp); 1601e51764aSArtem Bityutskiy goto out; 1611e51764aSArtem Bityutskiy } 1621e51764aSArtem Bityutskiy out: 1631e51764aSArtem Bityutskiy ubifs_release_lprops(c); 1641e51764aSArtem Bityutskiy return err; 1651e51764aSArtem Bityutskiy } 1661e51764aSArtem Bityutskiy 1671e51764aSArtem Bityutskiy /** 1681e51764aSArtem Bityutskiy * trun_remove_range - apply a replay entry for a truncation to the TNC. 1691e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1701e51764aSArtem Bityutskiy * @r: replay entry of truncation 1711e51764aSArtem Bityutskiy */ 1721e51764aSArtem Bityutskiy static int trun_remove_range(struct ubifs_info *c, struct replay_entry *r) 1731e51764aSArtem Bityutskiy { 1741e51764aSArtem Bityutskiy unsigned min_blk, max_blk; 1751e51764aSArtem Bityutskiy union ubifs_key min_key, max_key; 1761e51764aSArtem Bityutskiy ino_t ino; 1771e51764aSArtem Bityutskiy 1781e51764aSArtem Bityutskiy min_blk = r->new_size / UBIFS_BLOCK_SIZE; 1791e51764aSArtem Bityutskiy if (r->new_size & (UBIFS_BLOCK_SIZE - 1)) 1801e51764aSArtem Bityutskiy min_blk += 1; 1811e51764aSArtem Bityutskiy 1821e51764aSArtem Bityutskiy max_blk = r->old_size / UBIFS_BLOCK_SIZE; 1831e51764aSArtem Bityutskiy if ((r->old_size & (UBIFS_BLOCK_SIZE - 1)) == 0) 1841e51764aSArtem Bityutskiy max_blk -= 1; 1851e51764aSArtem Bityutskiy 1861e51764aSArtem Bityutskiy ino = key_inum(c, &r->key); 1871e51764aSArtem Bityutskiy 1881e51764aSArtem Bityutskiy data_key_init(c, &min_key, ino, min_blk); 1891e51764aSArtem Bityutskiy data_key_init(c, &max_key, ino, max_blk); 1901e51764aSArtem Bityutskiy 1911e51764aSArtem Bityutskiy return ubifs_tnc_remove_range(c, &min_key, &max_key); 1921e51764aSArtem Bityutskiy } 1931e51764aSArtem Bityutskiy 1941e51764aSArtem Bityutskiy /** 1951e51764aSArtem Bityutskiy * apply_replay_entry - apply a replay entry to the TNC. 1961e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1971e51764aSArtem Bityutskiy * @r: replay entry to apply 1981e51764aSArtem Bityutskiy * 1991e51764aSArtem Bityutskiy * Apply a replay entry to the TNC. 2001e51764aSArtem Bityutskiy */ 2011e51764aSArtem Bityutskiy static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) 2021e51764aSArtem Bityutskiy { 2031e51764aSArtem Bityutskiy int err, deletion = ((r->flags & REPLAY_DELETION) != 0); 2041e51764aSArtem Bityutskiy 2051e51764aSArtem Bityutskiy dbg_mnt("LEB %d:%d len %d flgs %d sqnum %llu %s", r->lnum, 2061e51764aSArtem Bityutskiy r->offs, r->len, r->flags, r->sqnum, DBGKEY(&r->key)); 2071e51764aSArtem Bityutskiy 2081e51764aSArtem Bityutskiy /* Set c->replay_sqnum to help deal with dangling branches. */ 2091e51764aSArtem Bityutskiy c->replay_sqnum = r->sqnum; 2101e51764aSArtem Bityutskiy 2111e51764aSArtem Bityutskiy if (r->flags & REPLAY_REF) 2121e51764aSArtem Bityutskiy err = set_bud_lprops(c, r); 2131e51764aSArtem Bityutskiy else if (is_hash_key(c, &r->key)) { 2141e51764aSArtem Bityutskiy if (deletion) 2151e51764aSArtem Bityutskiy err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); 2161e51764aSArtem Bityutskiy else 2171e51764aSArtem Bityutskiy err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, 2181e51764aSArtem Bityutskiy r->len, &r->nm); 2191e51764aSArtem Bityutskiy } else { 2201e51764aSArtem Bityutskiy if (deletion) 2211e51764aSArtem Bityutskiy switch (key_type(c, &r->key)) { 2221e51764aSArtem Bityutskiy case UBIFS_INO_KEY: 2231e51764aSArtem Bityutskiy { 2241e51764aSArtem Bityutskiy ino_t inum = key_inum(c, &r->key); 2251e51764aSArtem Bityutskiy 2261e51764aSArtem Bityutskiy err = ubifs_tnc_remove_ino(c, inum); 2271e51764aSArtem Bityutskiy break; 2281e51764aSArtem Bityutskiy } 2291e51764aSArtem Bityutskiy case UBIFS_TRUN_KEY: 2301e51764aSArtem Bityutskiy err = trun_remove_range(c, r); 2311e51764aSArtem Bityutskiy break; 2321e51764aSArtem Bityutskiy default: 2331e51764aSArtem Bityutskiy err = ubifs_tnc_remove(c, &r->key); 2341e51764aSArtem Bityutskiy break; 2351e51764aSArtem Bityutskiy } 2361e51764aSArtem Bityutskiy else 2371e51764aSArtem Bityutskiy err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, 2381e51764aSArtem Bityutskiy r->len); 2391e51764aSArtem Bityutskiy if (err) 2401e51764aSArtem Bityutskiy return err; 2411e51764aSArtem Bityutskiy 2421e51764aSArtem Bityutskiy if (c->need_recovery) 2431e51764aSArtem Bityutskiy err = ubifs_recover_size_accum(c, &r->key, deletion, 2441e51764aSArtem Bityutskiy r->new_size); 2451e51764aSArtem Bityutskiy } 2461e51764aSArtem Bityutskiy 2471e51764aSArtem Bityutskiy return err; 2481e51764aSArtem Bityutskiy } 2491e51764aSArtem Bityutskiy 2501e51764aSArtem Bityutskiy /** 2511e51764aSArtem Bityutskiy * destroy_replay_tree - destroy the replay. 2521e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2531e51764aSArtem Bityutskiy * 2541e51764aSArtem Bityutskiy * Destroy the replay tree. 2551e51764aSArtem Bityutskiy */ 2561e51764aSArtem Bityutskiy static void destroy_replay_tree(struct ubifs_info *c) 2571e51764aSArtem Bityutskiy { 2581e51764aSArtem Bityutskiy struct rb_node *this = c->replay_tree.rb_node; 2591e51764aSArtem Bityutskiy struct replay_entry *r; 2601e51764aSArtem Bityutskiy 2611e51764aSArtem Bityutskiy while (this) { 2621e51764aSArtem Bityutskiy if (this->rb_left) { 2631e51764aSArtem Bityutskiy this = this->rb_left; 2641e51764aSArtem Bityutskiy continue; 2651e51764aSArtem Bityutskiy } else if (this->rb_right) { 2661e51764aSArtem Bityutskiy this = this->rb_right; 2671e51764aSArtem Bityutskiy continue; 2681e51764aSArtem Bityutskiy } 2691e51764aSArtem Bityutskiy r = rb_entry(this, struct replay_entry, rb); 2701e51764aSArtem Bityutskiy this = rb_parent(this); 2711e51764aSArtem Bityutskiy if (this) { 2721e51764aSArtem Bityutskiy if (this->rb_left == &r->rb) 2731e51764aSArtem Bityutskiy this->rb_left = NULL; 2741e51764aSArtem Bityutskiy else 2751e51764aSArtem Bityutskiy this->rb_right = NULL; 2761e51764aSArtem Bityutskiy } 2771e51764aSArtem Bityutskiy if (is_hash_key(c, &r->key)) 2781e51764aSArtem Bityutskiy kfree(r->nm.name); 2791e51764aSArtem Bityutskiy kfree(r); 2801e51764aSArtem Bityutskiy } 2811e51764aSArtem Bityutskiy c->replay_tree = RB_ROOT; 2821e51764aSArtem Bityutskiy } 2831e51764aSArtem Bityutskiy 2841e51764aSArtem Bityutskiy /** 2851e51764aSArtem Bityutskiy * apply_replay_tree - apply the replay tree to the TNC. 2861e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2871e51764aSArtem Bityutskiy * 2881e51764aSArtem Bityutskiy * Apply the replay tree. 2891e51764aSArtem Bityutskiy * Returns zero in case of success and a negative error code in case of 2901e51764aSArtem Bityutskiy * failure. 2911e51764aSArtem Bityutskiy */ 2921e51764aSArtem Bityutskiy static int apply_replay_tree(struct ubifs_info *c) 2931e51764aSArtem Bityutskiy { 2941e51764aSArtem Bityutskiy struct rb_node *this = rb_first(&c->replay_tree); 2951e51764aSArtem Bityutskiy 2961e51764aSArtem Bityutskiy while (this) { 2971e51764aSArtem Bityutskiy struct replay_entry *r; 2981e51764aSArtem Bityutskiy int err; 2991e51764aSArtem Bityutskiy 3001e51764aSArtem Bityutskiy cond_resched(); 3011e51764aSArtem Bityutskiy 3021e51764aSArtem Bityutskiy r = rb_entry(this, struct replay_entry, rb); 3031e51764aSArtem Bityutskiy err = apply_replay_entry(c, r); 3041e51764aSArtem Bityutskiy if (err) 3051e51764aSArtem Bityutskiy return err; 3061e51764aSArtem Bityutskiy this = rb_next(this); 3071e51764aSArtem Bityutskiy } 3081e51764aSArtem Bityutskiy return 0; 3091e51764aSArtem Bityutskiy } 3101e51764aSArtem Bityutskiy 3111e51764aSArtem Bityutskiy /** 3121e51764aSArtem Bityutskiy * insert_node - insert a node to the replay tree. 3131e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3141e51764aSArtem Bityutskiy * @lnum: node logical eraseblock number 3151e51764aSArtem Bityutskiy * @offs: node offset 3161e51764aSArtem Bityutskiy * @len: node length 3171e51764aSArtem Bityutskiy * @key: node key 3181e51764aSArtem Bityutskiy * @sqnum: sequence number 3191e51764aSArtem Bityutskiy * @deletion: non-zero if this is a deletion 3201e51764aSArtem Bityutskiy * @used: number of bytes in use in a LEB 3211e51764aSArtem Bityutskiy * @old_size: truncation old size 3221e51764aSArtem Bityutskiy * @new_size: truncation new size 3231e51764aSArtem Bityutskiy * 3241e51764aSArtem Bityutskiy * This function inserts a scanned non-direntry node to the replay tree. The 3251e51764aSArtem Bityutskiy * replay tree is an RB-tree containing @struct replay_entry elements which are 3261e51764aSArtem Bityutskiy * indexed by the sequence number. The replay tree is applied at the very end 3271e51764aSArtem Bityutskiy * of the replay process. Since the tree is sorted in sequence number order, 3281e51764aSArtem Bityutskiy * the older modifications are applied first. This function returns zero in 3291e51764aSArtem Bityutskiy * case of success and a negative error code in case of failure. 3301e51764aSArtem Bityutskiy */ 3311e51764aSArtem Bityutskiy static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, 3321e51764aSArtem Bityutskiy union ubifs_key *key, unsigned long long sqnum, 3331e51764aSArtem Bityutskiy int deletion, int *used, loff_t old_size, 3341e51764aSArtem Bityutskiy loff_t new_size) 3351e51764aSArtem Bityutskiy { 3361e51764aSArtem Bityutskiy struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; 3371e51764aSArtem Bityutskiy struct replay_entry *r; 3381e51764aSArtem Bityutskiy 3391e51764aSArtem Bityutskiy if (key_inum(c, key) >= c->highest_inum) 3401e51764aSArtem Bityutskiy c->highest_inum = key_inum(c, key); 3411e51764aSArtem Bityutskiy 3421e51764aSArtem Bityutskiy dbg_mnt("add LEB %d:%d, key %s", lnum, offs, DBGKEY(key)); 3431e51764aSArtem Bityutskiy while (*p) { 3441e51764aSArtem Bityutskiy parent = *p; 3451e51764aSArtem Bityutskiy r = rb_entry(parent, struct replay_entry, rb); 3461e51764aSArtem Bityutskiy if (sqnum < r->sqnum) { 3471e51764aSArtem Bityutskiy p = &(*p)->rb_left; 3481e51764aSArtem Bityutskiy continue; 3491e51764aSArtem Bityutskiy } else if (sqnum > r->sqnum) { 3501e51764aSArtem Bityutskiy p = &(*p)->rb_right; 3511e51764aSArtem Bityutskiy continue; 3521e51764aSArtem Bityutskiy } 3531e51764aSArtem Bityutskiy ubifs_err("duplicate sqnum in replay"); 3541e51764aSArtem Bityutskiy return -EINVAL; 3551e51764aSArtem Bityutskiy } 3561e51764aSArtem Bityutskiy 3571e51764aSArtem Bityutskiy r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); 3581e51764aSArtem Bityutskiy if (!r) 3591e51764aSArtem Bityutskiy return -ENOMEM; 3601e51764aSArtem Bityutskiy 3611e51764aSArtem Bityutskiy if (!deletion) 3621e51764aSArtem Bityutskiy *used += ALIGN(len, 8); 3631e51764aSArtem Bityutskiy r->lnum = lnum; 3641e51764aSArtem Bityutskiy r->offs = offs; 3651e51764aSArtem Bityutskiy r->len = len; 3661e51764aSArtem Bityutskiy r->sqnum = sqnum; 3671e51764aSArtem Bityutskiy r->flags = (deletion ? REPLAY_DELETION : 0); 3681e51764aSArtem Bityutskiy r->old_size = old_size; 3691e51764aSArtem Bityutskiy r->new_size = new_size; 3701e51764aSArtem Bityutskiy key_copy(c, key, &r->key); 3711e51764aSArtem Bityutskiy 3721e51764aSArtem Bityutskiy rb_link_node(&r->rb, parent, p); 3731e51764aSArtem Bityutskiy rb_insert_color(&r->rb, &c->replay_tree); 3741e51764aSArtem Bityutskiy return 0; 3751e51764aSArtem Bityutskiy } 3761e51764aSArtem Bityutskiy 3771e51764aSArtem Bityutskiy /** 3781e51764aSArtem Bityutskiy * insert_dent - insert a directory entry node into the replay tree. 3791e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3801e51764aSArtem Bityutskiy * @lnum: node logical eraseblock number 3811e51764aSArtem Bityutskiy * @offs: node offset 3821e51764aSArtem Bityutskiy * @len: node length 3831e51764aSArtem Bityutskiy * @key: node key 3841e51764aSArtem Bityutskiy * @name: directory entry name 3851e51764aSArtem Bityutskiy * @nlen: directory entry name length 3861e51764aSArtem Bityutskiy * @sqnum: sequence number 3871e51764aSArtem Bityutskiy * @deletion: non-zero if this is a deletion 3881e51764aSArtem Bityutskiy * @used: number of bytes in use in a LEB 3891e51764aSArtem Bityutskiy * 3901e51764aSArtem Bityutskiy * This function inserts a scanned directory entry node to the replay tree. 3911e51764aSArtem Bityutskiy * Returns zero in case of success and a negative error code in case of 3921e51764aSArtem Bityutskiy * failure. 3931e51764aSArtem Bityutskiy * 3941e51764aSArtem Bityutskiy * This function is also used for extended attribute entries because they are 3951e51764aSArtem Bityutskiy * implemented as directory entry nodes. 3961e51764aSArtem Bityutskiy */ 3971e51764aSArtem Bityutskiy static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, 3981e51764aSArtem Bityutskiy union ubifs_key *key, const char *name, int nlen, 3991e51764aSArtem Bityutskiy unsigned long long sqnum, int deletion, int *used) 4001e51764aSArtem Bityutskiy { 4011e51764aSArtem Bityutskiy struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; 4021e51764aSArtem Bityutskiy struct replay_entry *r; 4031e51764aSArtem Bityutskiy char *nbuf; 4041e51764aSArtem Bityutskiy 4051e51764aSArtem Bityutskiy if (key_inum(c, key) >= c->highest_inum) 4061e51764aSArtem Bityutskiy c->highest_inum = key_inum(c, key); 4071e51764aSArtem Bityutskiy 4081e51764aSArtem Bityutskiy dbg_mnt("add LEB %d:%d, key %s", lnum, offs, DBGKEY(key)); 4091e51764aSArtem Bityutskiy while (*p) { 4101e51764aSArtem Bityutskiy parent = *p; 4111e51764aSArtem Bityutskiy r = rb_entry(parent, struct replay_entry, rb); 4121e51764aSArtem Bityutskiy if (sqnum < r->sqnum) { 4131e51764aSArtem Bityutskiy p = &(*p)->rb_left; 4141e51764aSArtem Bityutskiy continue; 4151e51764aSArtem Bityutskiy } 4161e51764aSArtem Bityutskiy if (sqnum > r->sqnum) { 4171e51764aSArtem Bityutskiy p = &(*p)->rb_right; 4181e51764aSArtem Bityutskiy continue; 4191e51764aSArtem Bityutskiy } 4201e51764aSArtem Bityutskiy ubifs_err("duplicate sqnum in replay"); 4211e51764aSArtem Bityutskiy return -EINVAL; 4221e51764aSArtem Bityutskiy } 4231e51764aSArtem Bityutskiy 4241e51764aSArtem Bityutskiy r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); 4251e51764aSArtem Bityutskiy if (!r) 4261e51764aSArtem Bityutskiy return -ENOMEM; 4271e51764aSArtem Bityutskiy nbuf = kmalloc(nlen + 1, GFP_KERNEL); 4281e51764aSArtem Bityutskiy if (!nbuf) { 4291e51764aSArtem Bityutskiy kfree(r); 4301e51764aSArtem Bityutskiy return -ENOMEM; 4311e51764aSArtem Bityutskiy } 4321e51764aSArtem Bityutskiy 4331e51764aSArtem Bityutskiy if (!deletion) 4341e51764aSArtem Bityutskiy *used += ALIGN(len, 8); 4351e51764aSArtem Bityutskiy r->lnum = lnum; 4361e51764aSArtem Bityutskiy r->offs = offs; 4371e51764aSArtem Bityutskiy r->len = len; 4381e51764aSArtem Bityutskiy r->sqnum = sqnum; 4391e51764aSArtem Bityutskiy r->nm.len = nlen; 4401e51764aSArtem Bityutskiy memcpy(nbuf, name, nlen); 4411e51764aSArtem Bityutskiy nbuf[nlen] = '\0'; 4421e51764aSArtem Bityutskiy r->nm.name = nbuf; 4431e51764aSArtem Bityutskiy r->flags = (deletion ? REPLAY_DELETION : 0); 4441e51764aSArtem Bityutskiy key_copy(c, key, &r->key); 4451e51764aSArtem Bityutskiy 4461e51764aSArtem Bityutskiy ubifs_assert(!*p); 4471e51764aSArtem Bityutskiy rb_link_node(&r->rb, parent, p); 4481e51764aSArtem Bityutskiy rb_insert_color(&r->rb, &c->replay_tree); 4491e51764aSArtem Bityutskiy return 0; 4501e51764aSArtem Bityutskiy } 4511e51764aSArtem Bityutskiy 4521e51764aSArtem Bityutskiy /** 4531e51764aSArtem Bityutskiy * ubifs_validate_entry - validate directory or extended attribute entry node. 4541e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4551e51764aSArtem Bityutskiy * @dent: the node to validate 4561e51764aSArtem Bityutskiy * 4571e51764aSArtem Bityutskiy * This function validates directory or extended attribute entry node @dent. 4581e51764aSArtem Bityutskiy * Returns zero if the node is all right and a %-EINVAL if not. 4591e51764aSArtem Bityutskiy */ 4601e51764aSArtem Bityutskiy int ubifs_validate_entry(struct ubifs_info *c, 4611e51764aSArtem Bityutskiy const struct ubifs_dent_node *dent) 4621e51764aSArtem Bityutskiy { 4631e51764aSArtem Bityutskiy int key_type = key_type_flash(c, dent->key); 4641e51764aSArtem Bityutskiy int nlen = le16_to_cpu(dent->nlen); 4651e51764aSArtem Bityutskiy 4661e51764aSArtem Bityutskiy if (le32_to_cpu(dent->ch.len) != nlen + UBIFS_DENT_NODE_SZ + 1 || 4671e51764aSArtem Bityutskiy dent->type >= UBIFS_ITYPES_CNT || 4681e51764aSArtem Bityutskiy nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 || 4691e51764aSArtem Bityutskiy strnlen(dent->name, nlen) != nlen || 4701e51764aSArtem Bityutskiy le64_to_cpu(dent->inum) > MAX_INUM) { 4711e51764aSArtem Bityutskiy ubifs_err("bad %s node", key_type == UBIFS_DENT_KEY ? 4721e51764aSArtem Bityutskiy "directory entry" : "extended attribute entry"); 4731e51764aSArtem Bityutskiy return -EINVAL; 4741e51764aSArtem Bityutskiy } 4751e51764aSArtem Bityutskiy 4761e51764aSArtem Bityutskiy if (key_type != UBIFS_DENT_KEY && key_type != UBIFS_XENT_KEY) { 4771e51764aSArtem Bityutskiy ubifs_err("bad key type %d", key_type); 4781e51764aSArtem Bityutskiy return -EINVAL; 4791e51764aSArtem Bityutskiy } 4801e51764aSArtem Bityutskiy 4811e51764aSArtem Bityutskiy return 0; 4821e51764aSArtem Bityutskiy } 4831e51764aSArtem Bityutskiy 4841e51764aSArtem Bityutskiy /** 4851e51764aSArtem Bityutskiy * replay_bud - replay a bud logical eraseblock. 4861e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4871e51764aSArtem Bityutskiy * @lnum: bud logical eraseblock number to replay 4881e51764aSArtem Bityutskiy * @offs: bud start offset 4891e51764aSArtem Bityutskiy * @jhead: journal head to which this bud belongs 4901e51764aSArtem Bityutskiy * @free: amount of free space in the bud is returned here 4911e51764aSArtem Bityutskiy * @dirty: amount of dirty space from padding and deletion nodes is returned 4921e51764aSArtem Bityutskiy * here 4931e51764aSArtem Bityutskiy * 4941e51764aSArtem Bityutskiy * This function returns zero in case of success and a negative error code in 4951e51764aSArtem Bityutskiy * case of failure. 4961e51764aSArtem Bityutskiy */ 4971e51764aSArtem Bityutskiy static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, 4981e51764aSArtem Bityutskiy int *free, int *dirty) 4991e51764aSArtem Bityutskiy { 5001e51764aSArtem Bityutskiy int err = 0, used = 0; 5011e51764aSArtem Bityutskiy struct ubifs_scan_leb *sleb; 5021e51764aSArtem Bityutskiy struct ubifs_scan_node *snod; 5031e51764aSArtem Bityutskiy struct ubifs_bud *bud; 5041e51764aSArtem Bityutskiy 5051e51764aSArtem Bityutskiy dbg_mnt("replay bud LEB %d, head %d", lnum, jhead); 5061e51764aSArtem Bityutskiy if (c->need_recovery) 5071e51764aSArtem Bityutskiy sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD); 5081e51764aSArtem Bityutskiy else 5091e51764aSArtem Bityutskiy sleb = ubifs_scan(c, lnum, offs, c->sbuf); 5101e51764aSArtem Bityutskiy if (IS_ERR(sleb)) 5111e51764aSArtem Bityutskiy return PTR_ERR(sleb); 5121e51764aSArtem Bityutskiy 5131e51764aSArtem Bityutskiy /* 5141e51764aSArtem Bityutskiy * The bud does not have to start from offset zero - the beginning of 5151e51764aSArtem Bityutskiy * the 'lnum' LEB may contain previously committed data. One of the 5161e51764aSArtem Bityutskiy * things we have to do in replay is to correctly update lprops with 5171e51764aSArtem Bityutskiy * newer information about this LEB. 5181e51764aSArtem Bityutskiy * 5191e51764aSArtem Bityutskiy * At this point lprops thinks that this LEB has 'c->leb_size - offs' 5201e51764aSArtem Bityutskiy * bytes of free space because it only contain information about 5211e51764aSArtem Bityutskiy * committed data. 5221e51764aSArtem Bityutskiy * 5231e51764aSArtem Bityutskiy * But we know that real amount of free space is 'c->leb_size - 5241e51764aSArtem Bityutskiy * sleb->endpt', and the space in the 'lnum' LEB between 'offs' and 5251e51764aSArtem Bityutskiy * 'sleb->endpt' is used by bud data. We have to correctly calculate 5261e51764aSArtem Bityutskiy * how much of these data are dirty and update lprops with this 5271e51764aSArtem Bityutskiy * information. 5281e51764aSArtem Bityutskiy * 5291e51764aSArtem Bityutskiy * The dirt in that LEB region is comprised of padding nodes, deletion 5301e51764aSArtem Bityutskiy * nodes, truncation nodes and nodes which are obsoleted by subsequent 5311e51764aSArtem Bityutskiy * nodes in this LEB. So instead of calculating clean space, we 5321e51764aSArtem Bityutskiy * calculate used space ('used' variable). 5331e51764aSArtem Bityutskiy */ 5341e51764aSArtem Bityutskiy 5351e51764aSArtem Bityutskiy list_for_each_entry(snod, &sleb->nodes, list) { 5361e51764aSArtem Bityutskiy int deletion = 0; 5371e51764aSArtem Bityutskiy 5381e51764aSArtem Bityutskiy cond_resched(); 5391e51764aSArtem Bityutskiy 5401e51764aSArtem Bityutskiy if (snod->sqnum >= SQNUM_WATERMARK) { 5411e51764aSArtem Bityutskiy ubifs_err("file system's life ended"); 5421e51764aSArtem Bityutskiy goto out_dump; 5431e51764aSArtem Bityutskiy } 5441e51764aSArtem Bityutskiy 5451e51764aSArtem Bityutskiy if (snod->sqnum > c->max_sqnum) 5461e51764aSArtem Bityutskiy c->max_sqnum = snod->sqnum; 5471e51764aSArtem Bityutskiy 5481e51764aSArtem Bityutskiy switch (snod->type) { 5491e51764aSArtem Bityutskiy case UBIFS_INO_NODE: 5501e51764aSArtem Bityutskiy { 5511e51764aSArtem Bityutskiy struct ubifs_ino_node *ino = snod->node; 5521e51764aSArtem Bityutskiy loff_t new_size = le64_to_cpu(ino->size); 5531e51764aSArtem Bityutskiy 5541e51764aSArtem Bityutskiy if (le32_to_cpu(ino->nlink) == 0) 5551e51764aSArtem Bityutskiy deletion = 1; 5561e51764aSArtem Bityutskiy err = insert_node(c, lnum, snod->offs, snod->len, 5571e51764aSArtem Bityutskiy &snod->key, snod->sqnum, deletion, 5581e51764aSArtem Bityutskiy &used, 0, new_size); 5591e51764aSArtem Bityutskiy break; 5601e51764aSArtem Bityutskiy } 5611e51764aSArtem Bityutskiy case UBIFS_DATA_NODE: 5621e51764aSArtem Bityutskiy { 5631e51764aSArtem Bityutskiy struct ubifs_data_node *dn = snod->node; 5641e51764aSArtem Bityutskiy loff_t new_size = le32_to_cpu(dn->size) + 5651e51764aSArtem Bityutskiy key_block(c, &snod->key) * 5661e51764aSArtem Bityutskiy UBIFS_BLOCK_SIZE; 5671e51764aSArtem Bityutskiy 5681e51764aSArtem Bityutskiy err = insert_node(c, lnum, snod->offs, snod->len, 5691e51764aSArtem Bityutskiy &snod->key, snod->sqnum, deletion, 5701e51764aSArtem Bityutskiy &used, 0, new_size); 5711e51764aSArtem Bityutskiy break; 5721e51764aSArtem Bityutskiy } 5731e51764aSArtem Bityutskiy case UBIFS_DENT_NODE: 5741e51764aSArtem Bityutskiy case UBIFS_XENT_NODE: 5751e51764aSArtem Bityutskiy { 5761e51764aSArtem Bityutskiy struct ubifs_dent_node *dent = snod->node; 5771e51764aSArtem Bityutskiy 5781e51764aSArtem Bityutskiy err = ubifs_validate_entry(c, dent); 5791e51764aSArtem Bityutskiy if (err) 5801e51764aSArtem Bityutskiy goto out_dump; 5811e51764aSArtem Bityutskiy 5821e51764aSArtem Bityutskiy err = insert_dent(c, lnum, snod->offs, snod->len, 5831e51764aSArtem Bityutskiy &snod->key, dent->name, 5841e51764aSArtem Bityutskiy le16_to_cpu(dent->nlen), snod->sqnum, 5851e51764aSArtem Bityutskiy !le64_to_cpu(dent->inum), &used); 5861e51764aSArtem Bityutskiy break; 5871e51764aSArtem Bityutskiy } 5881e51764aSArtem Bityutskiy case UBIFS_TRUN_NODE: 5891e51764aSArtem Bityutskiy { 5901e51764aSArtem Bityutskiy struct ubifs_trun_node *trun = snod->node; 5911e51764aSArtem Bityutskiy loff_t old_size = le64_to_cpu(trun->old_size); 5921e51764aSArtem Bityutskiy loff_t new_size = le64_to_cpu(trun->new_size); 5931e51764aSArtem Bityutskiy union ubifs_key key; 5941e51764aSArtem Bityutskiy 5951e51764aSArtem Bityutskiy /* Validate truncation node */ 5961e51764aSArtem Bityutskiy if (old_size < 0 || old_size > c->max_inode_sz || 5971e51764aSArtem Bityutskiy new_size < 0 || new_size > c->max_inode_sz || 5981e51764aSArtem Bityutskiy old_size <= new_size) { 5991e51764aSArtem Bityutskiy ubifs_err("bad truncation node"); 6001e51764aSArtem Bityutskiy goto out_dump; 6011e51764aSArtem Bityutskiy } 6021e51764aSArtem Bityutskiy 6031e51764aSArtem Bityutskiy /* 6041e51764aSArtem Bityutskiy * Create a fake truncation key just to use the same 6051e51764aSArtem Bityutskiy * functions which expect nodes to have keys. 6061e51764aSArtem Bityutskiy */ 6071e51764aSArtem Bityutskiy trun_key_init(c, &key, le32_to_cpu(trun->inum)); 6081e51764aSArtem Bityutskiy err = insert_node(c, lnum, snod->offs, snod->len, 6091e51764aSArtem Bityutskiy &key, snod->sqnum, 1, &used, 6101e51764aSArtem Bityutskiy old_size, new_size); 6111e51764aSArtem Bityutskiy break; 6121e51764aSArtem Bityutskiy } 6131e51764aSArtem Bityutskiy default: 6141e51764aSArtem Bityutskiy ubifs_err("unexpected node type %d in bud LEB %d:%d", 6151e51764aSArtem Bityutskiy snod->type, lnum, snod->offs); 6161e51764aSArtem Bityutskiy err = -EINVAL; 6171e51764aSArtem Bityutskiy goto out_dump; 6181e51764aSArtem Bityutskiy } 6191e51764aSArtem Bityutskiy if (err) 6201e51764aSArtem Bityutskiy goto out; 6211e51764aSArtem Bityutskiy } 6221e51764aSArtem Bityutskiy 6231e51764aSArtem Bityutskiy bud = ubifs_search_bud(c, lnum); 6241e51764aSArtem Bityutskiy if (!bud) 6251e51764aSArtem Bityutskiy BUG(); 6261e51764aSArtem Bityutskiy 6271e51764aSArtem Bityutskiy ubifs_assert(sleb->endpt - offs >= used); 6281e51764aSArtem Bityutskiy ubifs_assert(sleb->endpt % c->min_io_size == 0); 6291e51764aSArtem Bityutskiy 6301e51764aSArtem Bityutskiy if (sleb->endpt + c->min_io_size <= c->leb_size && 6311e51764aSArtem Bityutskiy !(c->vfs_sb->s_flags & MS_RDONLY)) 6321e51764aSArtem Bityutskiy err = ubifs_wbuf_seek_nolock(&c->jheads[jhead].wbuf, lnum, 6331e51764aSArtem Bityutskiy sleb->endpt, UBI_SHORTTERM); 6341e51764aSArtem Bityutskiy 6351e51764aSArtem Bityutskiy *dirty = sleb->endpt - offs - used; 6361e51764aSArtem Bityutskiy *free = c->leb_size - sleb->endpt; 6371e51764aSArtem Bityutskiy 6381e51764aSArtem Bityutskiy out: 6391e51764aSArtem Bityutskiy ubifs_scan_destroy(sleb); 6401e51764aSArtem Bityutskiy return err; 6411e51764aSArtem Bityutskiy 6421e51764aSArtem Bityutskiy out_dump: 6431e51764aSArtem Bityutskiy ubifs_err("bad node is at LEB %d:%d", lnum, snod->offs); 6441e51764aSArtem Bityutskiy dbg_dump_node(c, snod->node); 6451e51764aSArtem Bityutskiy ubifs_scan_destroy(sleb); 6461e51764aSArtem Bityutskiy return -EINVAL; 6471e51764aSArtem Bityutskiy } 6481e51764aSArtem Bityutskiy 6491e51764aSArtem Bityutskiy /** 6501e51764aSArtem Bityutskiy * insert_ref_node - insert a reference node to the replay tree. 6511e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 6521e51764aSArtem Bityutskiy * @lnum: node logical eraseblock number 6531e51764aSArtem Bityutskiy * @offs: node offset 6541e51764aSArtem Bityutskiy * @sqnum: sequence number 6551e51764aSArtem Bityutskiy * @free: amount of free space in bud 6561e51764aSArtem Bityutskiy * @dirty: amount of dirty space from padding and deletion nodes 6571e51764aSArtem Bityutskiy * 6581e51764aSArtem Bityutskiy * This function inserts a reference node to the replay tree and returns zero 659*6edbfafdSArtem Bityutskiy * in case of success or a negative error code in case of failure. 6601e51764aSArtem Bityutskiy */ 6611e51764aSArtem Bityutskiy static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, 6621e51764aSArtem Bityutskiy unsigned long long sqnum, int free, int dirty) 6631e51764aSArtem Bityutskiy { 6641e51764aSArtem Bityutskiy struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; 6651e51764aSArtem Bityutskiy struct replay_entry *r; 6661e51764aSArtem Bityutskiy 6671e51764aSArtem Bityutskiy dbg_mnt("add ref LEB %d:%d", lnum, offs); 6681e51764aSArtem Bityutskiy while (*p) { 6691e51764aSArtem Bityutskiy parent = *p; 6701e51764aSArtem Bityutskiy r = rb_entry(parent, struct replay_entry, rb); 6711e51764aSArtem Bityutskiy if (sqnum < r->sqnum) { 6721e51764aSArtem Bityutskiy p = &(*p)->rb_left; 6731e51764aSArtem Bityutskiy continue; 6741e51764aSArtem Bityutskiy } else if (sqnum > r->sqnum) { 6751e51764aSArtem Bityutskiy p = &(*p)->rb_right; 6761e51764aSArtem Bityutskiy continue; 6771e51764aSArtem Bityutskiy } 6781e51764aSArtem Bityutskiy ubifs_err("duplicate sqnum in replay tree"); 6791e51764aSArtem Bityutskiy return -EINVAL; 6801e51764aSArtem Bityutskiy } 6811e51764aSArtem Bityutskiy 6821e51764aSArtem Bityutskiy r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); 6831e51764aSArtem Bityutskiy if (!r) 6841e51764aSArtem Bityutskiy return -ENOMEM; 6851e51764aSArtem Bityutskiy 6861e51764aSArtem Bityutskiy r->lnum = lnum; 6871e51764aSArtem Bityutskiy r->offs = offs; 6881e51764aSArtem Bityutskiy r->sqnum = sqnum; 6891e51764aSArtem Bityutskiy r->flags = REPLAY_REF; 6901e51764aSArtem Bityutskiy r->free = free; 6911e51764aSArtem Bityutskiy r->dirty = dirty; 6921e51764aSArtem Bityutskiy 6931e51764aSArtem Bityutskiy rb_link_node(&r->rb, parent, p); 6941e51764aSArtem Bityutskiy rb_insert_color(&r->rb, &c->replay_tree); 6951e51764aSArtem Bityutskiy return 0; 6961e51764aSArtem Bityutskiy } 6971e51764aSArtem Bityutskiy 6981e51764aSArtem Bityutskiy /** 6991e51764aSArtem Bityutskiy * replay_buds - replay all buds. 7001e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 7011e51764aSArtem Bityutskiy * 7021e51764aSArtem Bityutskiy * This function returns zero in case of success and a negative error code in 7031e51764aSArtem Bityutskiy * case of failure. 7041e51764aSArtem Bityutskiy */ 7051e51764aSArtem Bityutskiy static int replay_buds(struct ubifs_info *c) 7061e51764aSArtem Bityutskiy { 7071e51764aSArtem Bityutskiy struct bud_entry *b; 7081e51764aSArtem Bityutskiy int err, uninitialized_var(free), uninitialized_var(dirty); 7091e51764aSArtem Bityutskiy 7101e51764aSArtem Bityutskiy list_for_each_entry(b, &c->replay_buds, list) { 7111e51764aSArtem Bityutskiy err = replay_bud(c, b->bud->lnum, b->bud->start, b->bud->jhead, 7121e51764aSArtem Bityutskiy &free, &dirty); 7131e51764aSArtem Bityutskiy if (err) 7141e51764aSArtem Bityutskiy return err; 7151e51764aSArtem Bityutskiy err = insert_ref_node(c, b->bud->lnum, b->bud->start, b->sqnum, 7161e51764aSArtem Bityutskiy free, dirty); 7171e51764aSArtem Bityutskiy if (err) 7181e51764aSArtem Bityutskiy return err; 7191e51764aSArtem Bityutskiy } 7201e51764aSArtem Bityutskiy 7211e51764aSArtem Bityutskiy return 0; 7221e51764aSArtem Bityutskiy } 7231e51764aSArtem Bityutskiy 7241e51764aSArtem Bityutskiy /** 7251e51764aSArtem Bityutskiy * destroy_bud_list - destroy the list of buds to replay. 7261e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 7271e51764aSArtem Bityutskiy */ 7281e51764aSArtem Bityutskiy static void destroy_bud_list(struct ubifs_info *c) 7291e51764aSArtem Bityutskiy { 7301e51764aSArtem Bityutskiy struct bud_entry *b; 7311e51764aSArtem Bityutskiy 7321e51764aSArtem Bityutskiy while (!list_empty(&c->replay_buds)) { 7331e51764aSArtem Bityutskiy b = list_entry(c->replay_buds.next, struct bud_entry, list); 7341e51764aSArtem Bityutskiy list_del(&b->list); 7351e51764aSArtem Bityutskiy kfree(b); 7361e51764aSArtem Bityutskiy } 7371e51764aSArtem Bityutskiy } 7381e51764aSArtem Bityutskiy 7391e51764aSArtem Bityutskiy /** 7401e51764aSArtem Bityutskiy * add_replay_bud - add a bud to the list of buds to replay. 7411e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 7421e51764aSArtem Bityutskiy * @lnum: bud logical eraseblock number to replay 7431e51764aSArtem Bityutskiy * @offs: bud start offset 7441e51764aSArtem Bityutskiy * @jhead: journal head to which this bud belongs 7451e51764aSArtem Bityutskiy * @sqnum: reference node sequence number 7461e51764aSArtem Bityutskiy * 7471e51764aSArtem Bityutskiy * This function returns zero in case of success and a negative error code in 7481e51764aSArtem Bityutskiy * case of failure. 7491e51764aSArtem Bityutskiy */ 7501e51764aSArtem Bityutskiy static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, 7511e51764aSArtem Bityutskiy unsigned long long sqnum) 7521e51764aSArtem Bityutskiy { 7531e51764aSArtem Bityutskiy struct ubifs_bud *bud; 7541e51764aSArtem Bityutskiy struct bud_entry *b; 7551e51764aSArtem Bityutskiy 7561e51764aSArtem Bityutskiy dbg_mnt("add replay bud LEB %d:%d, head %d", lnum, offs, jhead); 7571e51764aSArtem Bityutskiy 7581e51764aSArtem Bityutskiy bud = kmalloc(sizeof(struct ubifs_bud), GFP_KERNEL); 7591e51764aSArtem Bityutskiy if (!bud) 7601e51764aSArtem Bityutskiy return -ENOMEM; 7611e51764aSArtem Bityutskiy 7621e51764aSArtem Bityutskiy b = kmalloc(sizeof(struct bud_entry), GFP_KERNEL); 7631e51764aSArtem Bityutskiy if (!b) { 7641e51764aSArtem Bityutskiy kfree(bud); 7651e51764aSArtem Bityutskiy return -ENOMEM; 7661e51764aSArtem Bityutskiy } 7671e51764aSArtem Bityutskiy 7681e51764aSArtem Bityutskiy bud->lnum = lnum; 7691e51764aSArtem Bityutskiy bud->start = offs; 7701e51764aSArtem Bityutskiy bud->jhead = jhead; 7711e51764aSArtem Bityutskiy ubifs_add_bud(c, bud); 7721e51764aSArtem Bityutskiy 7731e51764aSArtem Bityutskiy b->bud = bud; 7741e51764aSArtem Bityutskiy b->sqnum = sqnum; 7751e51764aSArtem Bityutskiy list_add_tail(&b->list, &c->replay_buds); 7761e51764aSArtem Bityutskiy 7771e51764aSArtem Bityutskiy return 0; 7781e51764aSArtem Bityutskiy } 7791e51764aSArtem Bityutskiy 7801e51764aSArtem Bityutskiy /** 7811e51764aSArtem Bityutskiy * validate_ref - validate a reference node. 7821e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 7831e51764aSArtem Bityutskiy * @ref: the reference node to validate 7841e51764aSArtem Bityutskiy * @ref_lnum: LEB number of the reference node 7851e51764aSArtem Bityutskiy * @ref_offs: reference node offset 7861e51764aSArtem Bityutskiy * 7871e51764aSArtem Bityutskiy * This function returns %1 if a bud reference already exists for the LEB. %0 is 7881e51764aSArtem Bityutskiy * returned if the reference node is new, otherwise %-EINVAL is returned if 7891e51764aSArtem Bityutskiy * validation failed. 7901e51764aSArtem Bityutskiy */ 7911e51764aSArtem Bityutskiy static int validate_ref(struct ubifs_info *c, const struct ubifs_ref_node *ref) 7921e51764aSArtem Bityutskiy { 7931e51764aSArtem Bityutskiy struct ubifs_bud *bud; 7941e51764aSArtem Bityutskiy int lnum = le32_to_cpu(ref->lnum); 7951e51764aSArtem Bityutskiy unsigned int offs = le32_to_cpu(ref->offs); 7961e51764aSArtem Bityutskiy unsigned int jhead = le32_to_cpu(ref->jhead); 7971e51764aSArtem Bityutskiy 7981e51764aSArtem Bityutskiy /* 7991e51764aSArtem Bityutskiy * ref->offs may point to the end of LEB when the journal head points 8001e51764aSArtem Bityutskiy * to the end of LEB and we write reference node for it during commit. 8011e51764aSArtem Bityutskiy * So this is why we require 'offs > c->leb_size'. 8021e51764aSArtem Bityutskiy */ 8031e51764aSArtem Bityutskiy if (jhead >= c->jhead_cnt || lnum >= c->leb_cnt || 8041e51764aSArtem Bityutskiy lnum < c->main_first || offs > c->leb_size || 8051e51764aSArtem Bityutskiy offs & (c->min_io_size - 1)) 8061e51764aSArtem Bityutskiy return -EINVAL; 8071e51764aSArtem Bityutskiy 8081e51764aSArtem Bityutskiy /* Make sure we have not already looked at this bud */ 8091e51764aSArtem Bityutskiy bud = ubifs_search_bud(c, lnum); 8101e51764aSArtem Bityutskiy if (bud) { 8111e51764aSArtem Bityutskiy if (bud->jhead == jhead && bud->start <= offs) 8121e51764aSArtem Bityutskiy return 1; 8131e51764aSArtem Bityutskiy ubifs_err("bud at LEB %d:%d was already referred", lnum, offs); 8141e51764aSArtem Bityutskiy return -EINVAL; 8151e51764aSArtem Bityutskiy } 8161e51764aSArtem Bityutskiy 8171e51764aSArtem Bityutskiy return 0; 8181e51764aSArtem Bityutskiy } 8191e51764aSArtem Bityutskiy 8201e51764aSArtem Bityutskiy /** 8211e51764aSArtem Bityutskiy * replay_log_leb - replay a log logical eraseblock. 8221e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 8231e51764aSArtem Bityutskiy * @lnum: log logical eraseblock to replay 8241e51764aSArtem Bityutskiy * @offs: offset to start replaying from 8251e51764aSArtem Bityutskiy * @sbuf: scan buffer 8261e51764aSArtem Bityutskiy * 8271e51764aSArtem Bityutskiy * This function replays a log LEB and returns zero in case of success, %1 if 8281e51764aSArtem Bityutskiy * this is the last LEB in the log, and a negative error code in case of 8291e51764aSArtem Bityutskiy * failure. 8301e51764aSArtem Bityutskiy */ 8311e51764aSArtem Bityutskiy static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) 8321e51764aSArtem Bityutskiy { 8331e51764aSArtem Bityutskiy int err; 8341e51764aSArtem Bityutskiy struct ubifs_scan_leb *sleb; 8351e51764aSArtem Bityutskiy struct ubifs_scan_node *snod; 8361e51764aSArtem Bityutskiy const struct ubifs_cs_node *node; 8371e51764aSArtem Bityutskiy 8381e51764aSArtem Bityutskiy dbg_mnt("replay log LEB %d:%d", lnum, offs); 8391e51764aSArtem Bityutskiy sleb = ubifs_scan(c, lnum, offs, sbuf); 8401e51764aSArtem Bityutskiy if (IS_ERR(sleb)) { 8411e51764aSArtem Bityutskiy if (c->need_recovery) 8421e51764aSArtem Bityutskiy sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); 8431e51764aSArtem Bityutskiy if (IS_ERR(sleb)) 8441e51764aSArtem Bityutskiy return PTR_ERR(sleb); 8451e51764aSArtem Bityutskiy } 8461e51764aSArtem Bityutskiy 8471e51764aSArtem Bityutskiy if (sleb->nodes_cnt == 0) { 8481e51764aSArtem Bityutskiy err = 1; 8491e51764aSArtem Bityutskiy goto out; 8501e51764aSArtem Bityutskiy } 8511e51764aSArtem Bityutskiy 8521e51764aSArtem Bityutskiy node = sleb->buf; 8531e51764aSArtem Bityutskiy 8541e51764aSArtem Bityutskiy snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); 8551e51764aSArtem Bityutskiy if (c->cs_sqnum == 0) { 8561e51764aSArtem Bityutskiy /* 8571e51764aSArtem Bityutskiy * This is the first log LEB we are looking at, make sure that 8581e51764aSArtem Bityutskiy * the first node is a commit start node. Also record its 8591e51764aSArtem Bityutskiy * sequence number so that UBIFS can determine where the log 8601e51764aSArtem Bityutskiy * ends, because all nodes which were have higher sequence 8611e51764aSArtem Bityutskiy * numbers. 8621e51764aSArtem Bityutskiy */ 8631e51764aSArtem Bityutskiy if (snod->type != UBIFS_CS_NODE) { 8641e51764aSArtem Bityutskiy dbg_err("first log node at LEB %d:%d is not CS node", 8651e51764aSArtem Bityutskiy lnum, offs); 8661e51764aSArtem Bityutskiy goto out_dump; 8671e51764aSArtem Bityutskiy } 8681e51764aSArtem Bityutskiy if (le64_to_cpu(node->cmt_no) != c->cmt_no) { 8691e51764aSArtem Bityutskiy dbg_err("first CS node at LEB %d:%d has wrong " 8701e51764aSArtem Bityutskiy "commit number %llu expected %llu", 8711e51764aSArtem Bityutskiy lnum, offs, 8721e51764aSArtem Bityutskiy (unsigned long long)le64_to_cpu(node->cmt_no), 8731e51764aSArtem Bityutskiy c->cmt_no); 8741e51764aSArtem Bityutskiy goto out_dump; 8751e51764aSArtem Bityutskiy } 8761e51764aSArtem Bityutskiy 8771e51764aSArtem Bityutskiy c->cs_sqnum = le64_to_cpu(node->ch.sqnum); 8781e51764aSArtem Bityutskiy dbg_mnt("commit start sqnum %llu", c->cs_sqnum); 8791e51764aSArtem Bityutskiy } 8801e51764aSArtem Bityutskiy 8811e51764aSArtem Bityutskiy if (snod->sqnum < c->cs_sqnum) { 8821e51764aSArtem Bityutskiy /* 8831e51764aSArtem Bityutskiy * This means that we reached end of log and now 8841e51764aSArtem Bityutskiy * look to the older log data, which was already 8851e51764aSArtem Bityutskiy * committed but the eraseblock was not erased (UBIFS 886*6edbfafdSArtem Bityutskiy * only un-maps it). So this basically means we have to 8871e51764aSArtem Bityutskiy * exit with "end of log" code. 8881e51764aSArtem Bityutskiy */ 8891e51764aSArtem Bityutskiy err = 1; 8901e51764aSArtem Bityutskiy goto out; 8911e51764aSArtem Bityutskiy } 8921e51764aSArtem Bityutskiy 8931e51764aSArtem Bityutskiy /* Make sure the first node sits at offset zero of the LEB */ 8941e51764aSArtem Bityutskiy if (snod->offs != 0) { 8951e51764aSArtem Bityutskiy dbg_err("first node is not at zero offset"); 8961e51764aSArtem Bityutskiy goto out_dump; 8971e51764aSArtem Bityutskiy } 8981e51764aSArtem Bityutskiy 8991e51764aSArtem Bityutskiy list_for_each_entry(snod, &sleb->nodes, list) { 9001e51764aSArtem Bityutskiy 9011e51764aSArtem Bityutskiy cond_resched(); 9021e51764aSArtem Bityutskiy 9031e51764aSArtem Bityutskiy if (snod->sqnum >= SQNUM_WATERMARK) { 9041e51764aSArtem Bityutskiy ubifs_err("file system's life ended"); 9051e51764aSArtem Bityutskiy goto out_dump; 9061e51764aSArtem Bityutskiy } 9071e51764aSArtem Bityutskiy 9081e51764aSArtem Bityutskiy if (snod->sqnum < c->cs_sqnum) { 9091e51764aSArtem Bityutskiy dbg_err("bad sqnum %llu, commit sqnum %llu", 9101e51764aSArtem Bityutskiy snod->sqnum, c->cs_sqnum); 9111e51764aSArtem Bityutskiy goto out_dump; 9121e51764aSArtem Bityutskiy } 9131e51764aSArtem Bityutskiy 9141e51764aSArtem Bityutskiy if (snod->sqnum > c->max_sqnum) 9151e51764aSArtem Bityutskiy c->max_sqnum = snod->sqnum; 9161e51764aSArtem Bityutskiy 9171e51764aSArtem Bityutskiy switch (snod->type) { 9181e51764aSArtem Bityutskiy case UBIFS_REF_NODE: { 9191e51764aSArtem Bityutskiy const struct ubifs_ref_node *ref = snod->node; 9201e51764aSArtem Bityutskiy 9211e51764aSArtem Bityutskiy err = validate_ref(c, ref); 9221e51764aSArtem Bityutskiy if (err == 1) 9231e51764aSArtem Bityutskiy break; /* Already have this bud */ 9241e51764aSArtem Bityutskiy if (err) 9251e51764aSArtem Bityutskiy goto out_dump; 9261e51764aSArtem Bityutskiy 9271e51764aSArtem Bityutskiy err = add_replay_bud(c, le32_to_cpu(ref->lnum), 9281e51764aSArtem Bityutskiy le32_to_cpu(ref->offs), 9291e51764aSArtem Bityutskiy le32_to_cpu(ref->jhead), 9301e51764aSArtem Bityutskiy snod->sqnum); 9311e51764aSArtem Bityutskiy if (err) 9321e51764aSArtem Bityutskiy goto out; 9331e51764aSArtem Bityutskiy 9341e51764aSArtem Bityutskiy break; 9351e51764aSArtem Bityutskiy } 9361e51764aSArtem Bityutskiy case UBIFS_CS_NODE: 9371e51764aSArtem Bityutskiy /* Make sure it sits at the beginning of LEB */ 9381e51764aSArtem Bityutskiy if (snod->offs != 0) { 9391e51764aSArtem Bityutskiy ubifs_err("unexpected node in log"); 9401e51764aSArtem Bityutskiy goto out_dump; 9411e51764aSArtem Bityutskiy } 9421e51764aSArtem Bityutskiy break; 9431e51764aSArtem Bityutskiy default: 9441e51764aSArtem Bityutskiy ubifs_err("unexpected node in log"); 9451e51764aSArtem Bityutskiy goto out_dump; 9461e51764aSArtem Bityutskiy } 9471e51764aSArtem Bityutskiy } 9481e51764aSArtem Bityutskiy 9491e51764aSArtem Bityutskiy if (sleb->endpt || c->lhead_offs >= c->leb_size) { 9501e51764aSArtem Bityutskiy c->lhead_lnum = lnum; 9511e51764aSArtem Bityutskiy c->lhead_offs = sleb->endpt; 9521e51764aSArtem Bityutskiy } 9531e51764aSArtem Bityutskiy 9541e51764aSArtem Bityutskiy err = !sleb->endpt; 9551e51764aSArtem Bityutskiy out: 9561e51764aSArtem Bityutskiy ubifs_scan_destroy(sleb); 9571e51764aSArtem Bityutskiy return err; 9581e51764aSArtem Bityutskiy 9591e51764aSArtem Bityutskiy out_dump: 9601e51764aSArtem Bityutskiy ubifs_err("log error detected while replying the log at LEB %d:%d", 9611e51764aSArtem Bityutskiy lnum, offs + snod->offs); 9621e51764aSArtem Bityutskiy dbg_dump_node(c, snod->node); 9631e51764aSArtem Bityutskiy ubifs_scan_destroy(sleb); 9641e51764aSArtem Bityutskiy return -EINVAL; 9651e51764aSArtem Bityutskiy } 9661e51764aSArtem Bityutskiy 9671e51764aSArtem Bityutskiy /** 9681e51764aSArtem Bityutskiy * take_ihead - update the status of the index head in lprops to 'taken'. 9691e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 9701e51764aSArtem Bityutskiy * 9711e51764aSArtem Bityutskiy * This function returns the amount of free space in the index head LEB or a 9721e51764aSArtem Bityutskiy * negative error code. 9731e51764aSArtem Bityutskiy */ 9741e51764aSArtem Bityutskiy static int take_ihead(struct ubifs_info *c) 9751e51764aSArtem Bityutskiy { 9761e51764aSArtem Bityutskiy const struct ubifs_lprops *lp; 9771e51764aSArtem Bityutskiy int err, free; 9781e51764aSArtem Bityutskiy 9791e51764aSArtem Bityutskiy ubifs_get_lprops(c); 9801e51764aSArtem Bityutskiy 9811e51764aSArtem Bityutskiy lp = ubifs_lpt_lookup_dirty(c, c->ihead_lnum); 9821e51764aSArtem Bityutskiy if (IS_ERR(lp)) { 9831e51764aSArtem Bityutskiy err = PTR_ERR(lp); 9841e51764aSArtem Bityutskiy goto out; 9851e51764aSArtem Bityutskiy } 9861e51764aSArtem Bityutskiy 9871e51764aSArtem Bityutskiy free = lp->free; 9881e51764aSArtem Bityutskiy 9891e51764aSArtem Bityutskiy lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC, 9901e51764aSArtem Bityutskiy lp->flags | LPROPS_TAKEN, 0); 9911e51764aSArtem Bityutskiy if (IS_ERR(lp)) { 9921e51764aSArtem Bityutskiy err = PTR_ERR(lp); 9931e51764aSArtem Bityutskiy goto out; 9941e51764aSArtem Bityutskiy } 9951e51764aSArtem Bityutskiy 9961e51764aSArtem Bityutskiy err = free; 9971e51764aSArtem Bityutskiy out: 9981e51764aSArtem Bityutskiy ubifs_release_lprops(c); 9991e51764aSArtem Bityutskiy return err; 10001e51764aSArtem Bityutskiy } 10011e51764aSArtem Bityutskiy 10021e51764aSArtem Bityutskiy /** 10031e51764aSArtem Bityutskiy * ubifs_replay_journal - replay journal. 10041e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 10051e51764aSArtem Bityutskiy * 10061e51764aSArtem Bityutskiy * This function scans the journal, replays and cleans it up. It makes sure all 10071e51764aSArtem Bityutskiy * memory data structures related to uncommitted journal are built (dirty TNC 10081e51764aSArtem Bityutskiy * tree, tree of buds, modified lprops, etc). 10091e51764aSArtem Bityutskiy */ 10101e51764aSArtem Bityutskiy int ubifs_replay_journal(struct ubifs_info *c) 10111e51764aSArtem Bityutskiy { 10121e51764aSArtem Bityutskiy int err, i, lnum, offs, free; 10131e51764aSArtem Bityutskiy void *sbuf = NULL; 10141e51764aSArtem Bityutskiy 10151e51764aSArtem Bityutskiy BUILD_BUG_ON(UBIFS_TRUN_KEY > 5); 10161e51764aSArtem Bityutskiy 10171e51764aSArtem Bityutskiy /* Update the status of the index head in lprops to 'taken' */ 10181e51764aSArtem Bityutskiy free = take_ihead(c); 10191e51764aSArtem Bityutskiy if (free < 0) 10201e51764aSArtem Bityutskiy return free; /* Error code */ 10211e51764aSArtem Bityutskiy 10221e51764aSArtem Bityutskiy if (c->ihead_offs != c->leb_size - free) { 10231e51764aSArtem Bityutskiy ubifs_err("bad index head LEB %d:%d", c->ihead_lnum, 10241e51764aSArtem Bityutskiy c->ihead_offs); 10251e51764aSArtem Bityutskiy return -EINVAL; 10261e51764aSArtem Bityutskiy } 10271e51764aSArtem Bityutskiy 10281e51764aSArtem Bityutskiy sbuf = vmalloc(c->leb_size); 10291e51764aSArtem Bityutskiy if (!sbuf) 10301e51764aSArtem Bityutskiy return -ENOMEM; 10311e51764aSArtem Bityutskiy 10321e51764aSArtem Bityutskiy dbg_mnt("start replaying the journal"); 10331e51764aSArtem Bityutskiy 10341e51764aSArtem Bityutskiy c->replaying = 1; 10351e51764aSArtem Bityutskiy 10361e51764aSArtem Bityutskiy lnum = c->ltail_lnum = c->lhead_lnum; 10371e51764aSArtem Bityutskiy offs = c->lhead_offs; 10381e51764aSArtem Bityutskiy 10391e51764aSArtem Bityutskiy for (i = 0; i < c->log_lebs; i++, lnum++) { 10401e51764aSArtem Bityutskiy if (lnum >= UBIFS_LOG_LNUM + c->log_lebs) { 10411e51764aSArtem Bityutskiy /* 10421e51764aSArtem Bityutskiy * The log is logically circular, we reached the last 10431e51764aSArtem Bityutskiy * LEB, switch to the first one. 10441e51764aSArtem Bityutskiy */ 10451e51764aSArtem Bityutskiy lnum = UBIFS_LOG_LNUM; 10461e51764aSArtem Bityutskiy offs = 0; 10471e51764aSArtem Bityutskiy } 10481e51764aSArtem Bityutskiy err = replay_log_leb(c, lnum, offs, sbuf); 10491e51764aSArtem Bityutskiy if (err == 1) 10501e51764aSArtem Bityutskiy /* We hit the end of the log */ 10511e51764aSArtem Bityutskiy break; 10521e51764aSArtem Bityutskiy if (err) 10531e51764aSArtem Bityutskiy goto out; 10541e51764aSArtem Bityutskiy offs = 0; 10551e51764aSArtem Bityutskiy } 10561e51764aSArtem Bityutskiy 10571e51764aSArtem Bityutskiy err = replay_buds(c); 10581e51764aSArtem Bityutskiy if (err) 10591e51764aSArtem Bityutskiy goto out; 10601e51764aSArtem Bityutskiy 10611e51764aSArtem Bityutskiy err = apply_replay_tree(c); 10621e51764aSArtem Bityutskiy if (err) 10631e51764aSArtem Bityutskiy goto out; 10641e51764aSArtem Bityutskiy 1065*6edbfafdSArtem Bityutskiy /* 1066*6edbfafdSArtem Bityutskiy * UBIFS budgeting calculations use @c->budg_uncommitted_idx variable 1067*6edbfafdSArtem Bityutskiy * to roughly estimate index growth. Things like @c->min_idx_lebs 1068*6edbfafdSArtem Bityutskiy * depend on it. This means we have to initialize it to make sure 1069*6edbfafdSArtem Bityutskiy * budgeting works properly. 1070*6edbfafdSArtem Bityutskiy */ 1071*6edbfafdSArtem Bityutskiy c->budg_uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt); 1072*6edbfafdSArtem Bityutskiy c->budg_uncommitted_idx *= c->max_idx_node_sz; 1073*6edbfafdSArtem Bityutskiy 10741e51764aSArtem Bityutskiy ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); 10751e51764aSArtem Bityutskiy dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " 10761e51764aSArtem Bityutskiy "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, 1077e84461adSArtem Bityutskiy (unsigned long)c->highest_inum); 10781e51764aSArtem Bityutskiy out: 10791e51764aSArtem Bityutskiy destroy_replay_tree(c); 10801e51764aSArtem Bityutskiy destroy_bud_list(c); 10811e51764aSArtem Bityutskiy vfree(sbuf); 10821e51764aSArtem Bityutskiy c->replaying = 0; 10831e51764aSArtem Bityutskiy return err; 10841e51764aSArtem Bityutskiy } 1085