^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This file is part of UBIFS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006-2008 Nokia Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors: Adrian Hunter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Artem Bityutskiy (Битюцкий Артём)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This file implements commit-related functionality of the LEB properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/crc16.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ubifs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int dbg_populate_lsave(struct ubifs_info *c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * first_dirty_cnode - find first dirty cnode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * @nnode: nnode at which to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * This function returns the first dirty cnode or %NULL if there is not one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct ubifs_cnode *first_dirty_cnode(const struct ubifs_info *c, struct ubifs_nnode *nnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ubifs_assert(c, nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int i, cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct ubifs_cnode *cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) cnode = nnode->nbranch[i].cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (cnode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) test_bit(DIRTY_CNODE, &cnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (cnode->level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) nnode = (struct ubifs_nnode *)cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) cont = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (!cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return (struct ubifs_cnode *)nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * next_dirty_cnode - find next dirty cnode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @cnode: cnode from which to begin searching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * This function returns the next dirty cnode or %NULL if there is not one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct ubifs_cnode *next_dirty_cnode(const struct ubifs_info *c, struct ubifs_cnode *cnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ubifs_assert(c, cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) nnode = cnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!nnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) for (i = cnode->iip + 1; i < UBIFS_LPT_FANOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cnode = nnode->nbranch[i].cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (cnode && test_bit(DIRTY_CNODE, &cnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (cnode->level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return cnode; /* cnode is a pnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* cnode is a nnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return first_dirty_cnode(c, (struct ubifs_nnode *)cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return (struct ubifs_cnode *)nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * get_cnodes_to_commit - create list of dirty cnodes to commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * This function returns the number of cnodes to commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int get_cnodes_to_commit(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct ubifs_cnode *cnode, *cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!c->nroot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!test_bit(DIRTY_CNODE, &c->nroot->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) c->lpt_cnext = first_dirty_cnode(c, c->nroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) cnode = c->lpt_cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!cnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ubifs_assert(c, !test_bit(COW_CNODE, &cnode->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) __set_bit(COW_CNODE, &cnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) cnext = next_dirty_cnode(c, cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!cnext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) cnode->cnext = c->lpt_cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) cnode->cnext = cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) cnode = cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) dbg_cmt("committing %d cnodes", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dbg_lp("committing %d cnodes", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ubifs_assert(c, cnt == c->dirty_nn_cnt + c->dirty_pn_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * upd_ltab - update LPT LEB properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @lnum: LEB number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @free: amount of free space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @dirty: amount of dirty space to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void upd_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dbg_lp("LEB %d free %d dirty %d to %d +%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) lnum, c->ltab[lnum - c->lpt_first].free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) c->ltab[lnum - c->lpt_first].dirty, free, dirty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) c->ltab[lnum - c->lpt_first].free = free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) c->ltab[lnum - c->lpt_first].dirty += dirty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * alloc_lpt_leb - allocate an LPT LEB that is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @lnum: LEB number is passed and returned here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * This function finds the next empty LEB in the ltab starting from @lnum. If a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * an empty LEB is found it is returned in @lnum and the function returns %0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Otherwise the function returns -ENOSPC. Note however, that LPT is designed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * never to run out of space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int alloc_lpt_leb(struct ubifs_info *c, int *lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) n = *lnum - c->lpt_first + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for (i = n; i < c->lpt_lebs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (c->ltab[i].tgc || c->ltab[i].cmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (c->ltab[i].free == c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) c->ltab[i].cmt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *lnum = i + c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (c->ltab[i].tgc || c->ltab[i].cmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (c->ltab[i].free == c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) c->ltab[i].cmt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *lnum = i + c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * layout_cnodes - layout cnodes for commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int layout_cnodes(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int lnum, offs, len, alen, done_lsave, done_ltab, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct ubifs_cnode *cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) err = dbg_chk_lpt_sz(c, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) cnode = c->lpt_cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!cnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) lnum = c->nhead_lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) offs = c->nhead_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Try to place lsave and ltab nicely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) done_lsave = !c->big_lpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) done_ltab = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (!done_lsave && offs + c->lsave_sz <= c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) c->lsave_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) c->lsave_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (offs + c->ltab_sz <= c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) done_ltab = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) c->ltab_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) c->ltab_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (cnode->level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) len = c->nnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) c->dirty_nn_cnt -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) len = c->pnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) c->dirty_pn_cnt -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) while (offs + len > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) alen = ALIGN(offs, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err = alloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Try to place lsave and ltab nicely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!done_lsave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) c->lsave_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) c->lsave_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!done_ltab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) done_ltab = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) c->ltab_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) c->ltab_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (cnode->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cnode->parent->nbranch[cnode->iip].lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cnode->parent->nbranch[cnode->iip].offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) c->lpt_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) c->lpt_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) offs += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dbg_chk_lpt_sz(c, 1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) cnode = cnode->cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) } while (cnode && cnode != c->lpt_cnext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Make sure to place LPT's save table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!done_lsave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (offs + c->lsave_sz > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) alen = ALIGN(offs, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) err = alloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) c->lsave_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) c->lsave_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Make sure to place LPT's own lprops table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (!done_ltab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (offs + c->ltab_sz > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) alen = ALIGN(offs, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) err = alloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) c->ltab_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) c->ltab_offs = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) alen = ALIGN(offs, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dbg_chk_lpt_sz(c, 4, alen - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) err = dbg_chk_lpt_sz(c, 3, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) no_space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ubifs_err(c, "LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) lnum, offs, len, done_ltab, done_lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ubifs_dump_lpt_info(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ubifs_dump_lpt_lebs(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * realloc_lpt_leb - allocate an LPT LEB that is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * @lnum: LEB number is passed and returned here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * This function duplicates exactly the results of the function alloc_lpt_leb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * It is used during end commit to reallocate the same LEB numbers that were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * allocated by alloc_lpt_leb during start commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * This function finds the next LEB that was allocated by the alloc_lpt_leb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * function starting from @lnum. If a LEB is found it is returned in @lnum and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * the function returns %0. Otherwise the function returns -ENOSPC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * Note however, that LPT is designed never to run out of space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int realloc_lpt_leb(struct ubifs_info *c, int *lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) n = *lnum - c->lpt_first + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) for (i = n; i < c->lpt_lebs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (c->ltab[i].cmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) c->ltab[i].cmt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) *lnum = i + c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (c->ltab[i].cmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) c->ltab[i].cmt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *lnum = i + c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * write_cnodes - write cnodes for commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int write_cnodes(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int lnum, offs, len, from, err, wlen, alen, done_ltab, done_lsave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct ubifs_cnode *cnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) void *buf = c->lpt_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cnode = c->lpt_cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!cnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) lnum = c->nhead_lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) offs = c->nhead_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) from = offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Ensure empty LEB is unmapped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (offs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err = ubifs_leb_unmap(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Try to place lsave and ltab nicely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) done_lsave = !c->big_lpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) done_ltab = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!done_lsave && offs + c->lsave_sz <= c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ubifs_pack_lsave(c, buf + offs, c->lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (offs + c->ltab_sz <= c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) done_ltab = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Loop for each cnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (cnode->level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) len = c->nnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) len = c->pnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) while (offs + len > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) wlen = offs - from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (wlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) alen = ALIGN(wlen, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) memset(buf + offs, 0xff, alen - wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) err = ubifs_leb_write(c, lnum, buf + from, from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) err = realloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) offs = from = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err = ubifs_leb_unmap(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Try to place lsave and ltab nicely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!done_lsave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ubifs_pack_lsave(c, buf + offs, c->lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!done_ltab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) done_ltab = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (cnode->level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ubifs_pack_nnode(c, buf + offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (struct ubifs_nnode *)cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ubifs_pack_pnode(c, buf + offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) (struct ubifs_pnode *)cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * The reason for the barriers is the same as in case of TNC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * See comment in 'write_index()'. 'dirty_cow_nnode()' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * 'dirty_cow_pnode()' are the functions for which this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * important.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) clear_bit(DIRTY_CNODE, &cnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) clear_bit(COW_CNODE, &cnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) smp_mb__after_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) offs += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dbg_chk_lpt_sz(c, 1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) cnode = cnode->cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) } while (cnode && cnode != c->lpt_cnext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Make sure to place LPT's save table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!done_lsave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (offs + c->lsave_sz > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) wlen = offs - from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) alen = ALIGN(wlen, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) memset(buf + offs, 0xff, alen - wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) err = ubifs_leb_write(c, lnum, buf + from, from, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) err = realloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) offs = from = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) err = ubifs_leb_unmap(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) done_lsave = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ubifs_pack_lsave(c, buf + offs, c->lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) offs += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dbg_chk_lpt_sz(c, 1, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Make sure to place LPT's own lprops table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (!done_ltab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (offs + c->ltab_sz > c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) wlen = offs - from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) alen = ALIGN(wlen, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) memset(buf + offs, 0xff, alen - wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) err = ubifs_leb_write(c, lnum, buf + from, from, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) err = realloc_lpt_leb(c, &lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) goto no_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) offs = from = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ubifs_assert(c, lnum >= c->lpt_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) lnum <= c->lpt_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) err = ubifs_leb_unmap(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) offs += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) dbg_chk_lpt_sz(c, 1, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* Write remaining data in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) wlen = offs - from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) alen = ALIGN(wlen, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) memset(buf + offs, 0xff, alen - wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) err = ubifs_leb_write(c, lnum, buf + from, from, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dbg_chk_lpt_sz(c, 4, alen - wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) err = dbg_chk_lpt_sz(c, 3, ALIGN(offs, c->min_io_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) c->nhead_lnum = lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) c->nhead_offs = ALIGN(offs, c->min_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dbg_lp("LPT root is at %d:%d", c->lpt_lnum, c->lpt_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) dbg_lp("LPT head is at %d:%d", c->nhead_lnum, c->nhead_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dbg_lp("LPT ltab is at %d:%d", c->ltab_lnum, c->ltab_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) no_space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ubifs_err(c, "LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) lnum, offs, len, done_ltab, done_lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ubifs_dump_lpt_info(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ubifs_dump_lpt_lebs(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * next_pnode_to_dirty - find next pnode to dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * @pnode: pnode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * This function returns the next pnode to dirty or %NULL if there are no more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * pnodes. Note that pnodes that have never been written (lnum == 0) are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * skipped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct ubifs_pnode *pnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int iip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Try to go right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) nnode = pnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (nnode->nbranch[iip].lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ubifs_get_pnode(c, nnode, iip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Go up while can't go right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) iip = nnode->iip + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) nnode = nnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!nnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) for (; iip < UBIFS_LPT_FANOUT; iip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (nnode->nbranch[iip].lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) } while (iip >= UBIFS_LPT_FANOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Go right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) nnode = ubifs_get_nnode(c, nnode, iip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (IS_ERR(nnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return (void *)nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* Go down to level 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) while (nnode->level > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (nnode->nbranch[iip].lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (iip >= UBIFS_LPT_FANOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Should not happen, but we need to keep going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * if it does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) iip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) nnode = ubifs_get_nnode(c, nnode, iip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (IS_ERR(nnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return (void *)nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (nnode->nbranch[iip].lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (iip >= UBIFS_LPT_FANOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Should not happen, but we need to keep going if it does */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) iip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ubifs_get_pnode(c, nnode, iip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * add_pnode_dirt - add dirty space to LPT LEB properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * @pnode: pnode for which to add dirt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ubifs_add_lpt_dirt(c, pnode->parent->nbranch[pnode->iip].lnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) c->pnode_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * do_make_pnode_dirty - mark a pnode dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * @pnode: pnode to mark dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static void do_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* Assumes cnext list is empty i.e. not called during commit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (!test_and_set_bit(DIRTY_CNODE, &pnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) c->dirty_pn_cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) add_pnode_dirt(c, pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* Mark parent and ancestors dirty too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) nnode = pnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) while (nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) c->dirty_nn_cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ubifs_add_nnode_dirt(c, nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) nnode = nnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * make_tree_dirty - mark the entire LEB properties tree dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * This function is used by the "small" LPT model to cause the entire LEB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * properties tree to be written. The "small" LPT model does not use LPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * garbage collection because it is more efficient to write the entire tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * (because it is small).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int make_tree_dirty(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct ubifs_pnode *pnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) pnode = ubifs_pnode_lookup(c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (IS_ERR(pnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return PTR_ERR(pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) while (pnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) do_make_pnode_dirty(c, pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) pnode = next_pnode_to_dirty(c, pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (IS_ERR(pnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return PTR_ERR(pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * need_write_all - determine if the LPT area is running out of free space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * This function returns %1 if the LPT area is running out of free space and %0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * if it is not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int need_write_all(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) long long free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) for (i = 0; i < c->lpt_lebs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (i + c->lpt_first == c->nhead_lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) free += c->leb_size - c->nhead_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) else if (c->ltab[i].free == c->leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) free += c->leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) else if (c->ltab[i].free + c->ltab[i].dirty == c->leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) free += c->leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* Less than twice the size left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (free <= c->lpt_sz * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * lpt_tgc_start - start trivial garbage collection of LPT LEBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * LPT trivial garbage collection is where a LPT LEB contains only dirty and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * free space and so may be reused as soon as the next commit is completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * This function is called during start commit to mark LPT LEBs for trivial GC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static void lpt_tgc_start(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) for (i = 0; i < c->lpt_lebs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (i + c->lpt_first == c->nhead_lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (c->ltab[i].dirty > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) c->ltab[i].free + c->ltab[i].dirty == c->leb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) c->ltab[i].tgc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) c->ltab[i].free = c->leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) c->ltab[i].dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dbg_lp("LEB %d", i + c->lpt_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * lpt_tgc_end - end trivial garbage collection of LPT LEBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * LPT trivial garbage collection is where a LPT LEB contains only dirty and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * free space and so may be reused as soon as the next commit is completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * This function is called after the commit is completed (master node has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * written) and un-maps LPT LEBs that were marked for trivial GC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int lpt_tgc_end(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) for (i = 0; i < c->lpt_lebs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (c->ltab[i].tgc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) err = ubifs_leb_unmap(c, i + c->lpt_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) c->ltab[i].tgc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dbg_lp("LEB %d", i + c->lpt_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * populate_lsave - fill the lsave array with important LEB numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * This function is only called for the "big" model. It records a small number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * of LEB numbers of important LEBs. Important LEBs are ones that are (from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * most important to least important): empty, freeable, freeable index, dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * index, dirty or free. Upon mount, we read this list of LEB numbers and bring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * their pnodes into memory. That will stop us from having to scan the LPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * straight away. For the "small" model we assume that scanning the LPT is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * big deal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static void populate_lsave(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct ubifs_lprops *lprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct ubifs_lpt_heap *heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) int i, cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ubifs_assert(c, c->big_lpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) c->lpt_drty_flgs |= LSAVE_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (dbg_populate_lsave(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) list_for_each_entry(lprops, &c->empty_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) c->lsave[cnt++] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) list_for_each_entry(lprops, &c->freeable_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) c->lsave[cnt++] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) list_for_each_entry(lprops, &c->frdi_idx_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) c->lsave[cnt++] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) for (i = 0; i < heap->cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) c->lsave[cnt++] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) heap = &c->lpt_heap[LPROPS_DIRTY - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) for (i = 0; i < heap->cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) c->lsave[cnt++] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) heap = &c->lpt_heap[LPROPS_FREE - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) for (i = 0; i < heap->cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) c->lsave[cnt++] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (cnt >= c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* Fill it up completely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) while (cnt < c->lsave_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) c->lsave[cnt++] = c->main_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * nnode_lookup - lookup a nnode in the LPT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * @i: nnode number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * This function returns a pointer to the nnode on success or a negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static struct ubifs_nnode *nnode_lookup(struct ubifs_info *c, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int err, iip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!c->nroot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) err = ubifs_read_nnode(c, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) nnode = c->nroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) iip = i & (UBIFS_LPT_FANOUT - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) i >>= UBIFS_LPT_FANOUT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) nnode = ubifs_get_nnode(c, nnode, iip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (IS_ERR(nnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * make_nnode_dirty - find a nnode and, if found, make it dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * @node_num: nnode number of nnode to make dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * @lnum: LEB number where nnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * @offs: offset where nnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * This function is used by LPT garbage collection. LPT garbage collection is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * simply involves marking all the nodes in the LEB being garbage-collected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * dirty. The dirty nodes are written next commit, after which the LEB is free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int make_nnode_dirty(struct ubifs_info *c, int node_num, int lnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) nnode = nnode_lookup(c, node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (IS_ERR(nnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return PTR_ERR(nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (nnode->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct ubifs_nbranch *branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) branch = &nnode->parent->nbranch[nnode->iip];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (branch->lnum != lnum || branch->offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return 0; /* nnode is obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) } else if (c->lpt_lnum != lnum || c->lpt_offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0; /* nnode is obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* Assumes cnext list is empty i.e. not called during commit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) c->dirty_nn_cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ubifs_add_nnode_dirt(c, nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* Mark parent and ancestors dirty too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) nnode = nnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) while (nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) c->dirty_nn_cnt += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ubifs_add_nnode_dirt(c, nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) nnode = nnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * make_pnode_dirty - find a pnode and, if found, make it dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * @node_num: pnode number of pnode to make dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * @lnum: LEB number where pnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * @offs: offset where pnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * This function is used by LPT garbage collection. LPT garbage collection is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * simply involves marking all the nodes in the LEB being garbage-collected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * dirty. The dirty nodes are written next commit, after which the LEB is free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int make_pnode_dirty(struct ubifs_info *c, int node_num, int lnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct ubifs_pnode *pnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct ubifs_nbranch *branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) pnode = ubifs_pnode_lookup(c, node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (IS_ERR(pnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return PTR_ERR(pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) branch = &pnode->parent->nbranch[pnode->iip];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (branch->lnum != lnum || branch->offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) do_make_pnode_dirty(c, pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * make_ltab_dirty - make ltab node dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * @lnum: LEB number where ltab was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * @offs: offset where ltab was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * This function is used by LPT garbage collection. LPT garbage collection is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * simply involves marking all the nodes in the LEB being garbage-collected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * dirty. The dirty nodes are written next commit, after which the LEB is free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int make_ltab_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (lnum != c->ltab_lnum || offs != c->ltab_offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return 0; /* This ltab node is obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (!(c->lpt_drty_flgs & LTAB_DIRTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) c->lpt_drty_flgs |= LTAB_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ubifs_add_lpt_dirt(c, c->ltab_lnum, c->ltab_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * make_lsave_dirty - make lsave node dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * @lnum: LEB number where lsave was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * @offs: offset where lsave was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * This function is used by LPT garbage collection. LPT garbage collection is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * simply involves marking all the nodes in the LEB being garbage-collected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * dirty. The dirty nodes are written next commit, after which the LEB is free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static int make_lsave_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (lnum != c->lsave_lnum || offs != c->lsave_offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0; /* This lsave node is obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) c->lpt_drty_flgs |= LSAVE_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * make_node_dirty - make node dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * @node_type: LPT node type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * @node_num: node number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * @lnum: LEB number where node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * @offs: offset where node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * This function is used by LPT garbage collection. LPT garbage collection is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * simply involves marking all the nodes in the LEB being garbage-collected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * dirty. The dirty nodes are written next commit, after which the LEB is free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static int make_node_dirty(struct ubifs_info *c, int node_type, int node_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) switch (node_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) case UBIFS_LPT_NNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return make_nnode_dirty(c, node_num, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) case UBIFS_LPT_PNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return make_pnode_dirty(c, node_num, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) case UBIFS_LPT_LTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return make_ltab_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) case UBIFS_LPT_LSAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return make_lsave_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * get_lpt_node_len - return the length of a node based on its type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * @node_type: LPT node type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static int get_lpt_node_len(const struct ubifs_info *c, int node_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) switch (node_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) case UBIFS_LPT_NNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return c->nnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) case UBIFS_LPT_PNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return c->pnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) case UBIFS_LPT_LTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) case UBIFS_LPT_LSAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * get_pad_len - return the length of padding in a buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * @buf: buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * @len: length of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static int get_pad_len(const struct ubifs_info *c, uint8_t *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int offs, pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (c->min_io_size == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) offs = c->leb_size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) pad_len = ALIGN(offs, c->min_io_size) - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * get_lpt_node_type - return type (and node number) of a node in a buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * @buf: buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * @node_num: node number is returned here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) int *node_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int pos = 0, node_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) *node_num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return node_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * is_a_node - determine if a buffer contains a node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * @buf: buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * @len: length of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * This function returns %1 if the buffer contains a node or %0 if it does not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int pos = 0, node_type, node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) uint16_t crc, calc_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (len < UBIFS_LPT_CRC_BYTES + (UBIFS_LPT_TYPE_BITS + 7) / 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (node_type == UBIFS_LPT_NOT_A_NODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) node_len = get_lpt_node_len(c, node_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!node_len || node_len > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) addr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) node_len - UBIFS_LPT_CRC_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (crc != calc_crc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * lpt_gc_lnum - garbage collect a LPT LEB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * @lnum: LEB number to garbage collect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * LPT garbage collection is used only for the "big" LPT model
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * (c->big_lpt == 1). Garbage collection simply involves marking all the nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * in the LEB being garbage-collected as dirty. The dirty nodes are written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * next commit, after which the LEB is free to be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) int err, len = c->leb_size, node_type, node_num, node_len, offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) void *buf = c->lpt_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) dbg_lp("LEB %d", lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (!is_a_node(c, buf, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) int pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) pad_len = get_pad_len(c, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (pad_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) buf += pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) len -= pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) node_type = get_lpt_node_type(c, buf, &node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) node_len = get_lpt_node_len(c, node_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) offs = c->leb_size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ubifs_assert(c, node_len != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) err = make_node_dirty(c, node_type, node_num, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) buf += node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) len -= node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * lpt_gc - LPT garbage collection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) * Select a LPT LEB for LPT garbage collection and call 'lpt_gc_lnum()'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * Returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static int lpt_gc(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) int i, lnum = -1, dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) for (i = 0; i < c->lpt_lebs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ubifs_assert(c, !c->ltab[i].tgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (i + c->lpt_first == c->nhead_lnum ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) c->ltab[i].free + c->ltab[i].dirty == c->leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (c->ltab[i].dirty > dirty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) dirty = c->ltab[i].dirty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) lnum = i + c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (lnum == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return lpt_gc_lnum(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * ubifs_lpt_start_commit - UBIFS commit starts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * This function has to be called when UBIFS starts the commit operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * This function "freezes" all currently dirty LEB properties and does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * change them anymore. Further changes are saved and tracked separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * because they are not part of this commit. This function returns zero in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * of success and a negative error code in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) int ubifs_lpt_start_commit(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) int err, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) dbg_lp("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) err = dbg_chk_lpt_free_spc(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) err = dbg_check_ltab(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (c->check_lpt_free) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * We ensure there is enough free space in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * ubifs_lpt_post_commit() by marking nodes dirty. That
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * information is lost when we unmount, so we also need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * to check free space once after mounting also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) c->check_lpt_free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) while (need_write_all(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) err = lpt_gc(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) lpt_tgc_start(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (!c->dirty_pn_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dbg_cmt("no cnodes to commit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (!c->big_lpt && need_write_all(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /* If needed, write everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) err = make_tree_dirty(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) lpt_tgc_start(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) populate_lsave(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) cnt = get_cnodes_to_commit(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ubifs_assert(c, cnt != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) err = layout_cnodes(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) err = ubifs_lpt_calc_hash(c, c->mst_node->hash_lpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /* Copy the LPT's own lprops for end commit to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) memcpy(c->ltab_cmt, c->ltab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) c->lpt_drty_flgs &= ~(LTAB_DIRTY | LSAVE_DIRTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * free_obsolete_cnodes - free obsolete cnodes for commit end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static void free_obsolete_cnodes(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct ubifs_cnode *cnode, *cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) cnext = c->lpt_cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (!cnext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) cnode = cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) cnext = cnode->cnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (test_bit(OBSOLETE_CNODE, &cnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) kfree(cnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) cnode->cnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } while (cnext != c->lpt_cnext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) c->lpt_cnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * ubifs_lpt_end_commit - finish the commit operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * This function has to be called when the commit operation finishes. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) * flushes the changes which were "frozen" by 'ubifs_lprops_start_commit()' to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * the media. Returns zero in case of success and a negative error code in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) int ubifs_lpt_end_commit(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) dbg_lp("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!c->lpt_cnext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) err = write_cnodes(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) free_obsolete_cnodes(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * ubifs_lpt_post_commit - post commit LPT trivial GC and LPT GC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * LPT trivial GC is completed after a commit. Also LPT GC is done after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * commit for the "big" LPT model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) int ubifs_lpt_post_commit(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) err = lpt_tgc_end(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) while (need_write_all(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) err = lpt_gc(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) mutex_lock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) mutex_unlock(&c->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * first_nnode - find the first nnode in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * @hght: height of tree where nnode found is returned here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) * This function returns a pointer to the nnode found or %NULL if no nnode is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) * found. This function is a helper to 'ubifs_lpt_free()'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static struct ubifs_nnode *first_nnode(struct ubifs_info *c, int *hght)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int h, i, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) nnode = c->nroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) *hght = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!nnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) for (h = 1; h < c->lpt_hght; h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (nnode->nbranch[i].nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) nnode = nnode->nbranch[i].nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) *hght = h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * next_nnode - find the next nnode in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * @nnode: nnode from which to start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * @hght: height of tree where nnode is, is passed and returned here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * This function returns a pointer to the nnode found or %NULL if no nnode is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * found. This function is a helper to 'ubifs_lpt_free()'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static struct ubifs_nnode *next_nnode(struct ubifs_info *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct ubifs_nnode *nnode, int *hght)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct ubifs_nnode *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) int iip, h, i, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) parent = nnode->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (nnode->iip == UBIFS_LPT_FANOUT - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) *hght -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) for (iip = nnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) nnode = parent->nbranch[iip].nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (nnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (!nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) *hght -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) for (h = *hght + 1; h < c->lpt_hght; h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (nnode->nbranch[i].nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) nnode = nnode->nbranch[i].nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) *hght = h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) * ubifs_lpt_free - free resources owned by the LPT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) * @wr_only: free only resources used for writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) int i, hght;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* Free write-only things first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) free_obsolete_cnodes(c); /* Leftover from a failed commit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) vfree(c->ltab_cmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) c->ltab_cmt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) vfree(c->lpt_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) c->lpt_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) kfree(c->lsave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) c->lsave = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (wr_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /* Now free the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) nnode = first_nnode(c, &hght);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) while (nnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) for (i = 0; i < UBIFS_LPT_FANOUT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) kfree(nnode->nbranch[i].nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) nnode = next_nnode(c, nnode, &hght);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) for (i = 0; i < LPROPS_HEAP_CNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) kfree(c->lpt_heap[i].arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) kfree(c->dirty_idx.arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) kfree(c->nroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) vfree(c->ltab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) kfree(c->lpt_nod_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * Everything below is related to debugging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * dbg_is_all_ff - determine if a buffer contains only 0xFF bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * @buf: buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * @len: buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static int dbg_is_all_ff(uint8_t *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (buf[i] != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * dbg_is_nnode_dirty - determine if a nnode is dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * @lnum: LEB number where nnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * @offs: offset where nnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int dbg_is_nnode_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct ubifs_nnode *nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) int hght;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /* Entire tree is in memory so first_nnode / next_nnode are OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) nnode = first_nnode(c, &hght);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) for (; nnode; nnode = next_nnode(c, nnode, &hght)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct ubifs_nbranch *branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (nnode->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) branch = &nnode->parent->nbranch[nnode->iip];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (branch->lnum != lnum || branch->offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (test_bit(DIRTY_CNODE, &nnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (c->lpt_lnum != lnum || c->lpt_offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (test_bit(DIRTY_CNODE, &nnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * dbg_is_pnode_dirty - determine if a pnode is dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * @lnum: LEB number where pnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * @offs: offset where pnode was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static int dbg_is_pnode_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) int i, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) cnt = DIV_ROUND_UP(c->main_lebs, UBIFS_LPT_FANOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) struct ubifs_pnode *pnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) struct ubifs_nbranch *branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) pnode = ubifs_pnode_lookup(c, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (IS_ERR(pnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return PTR_ERR(pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) branch = &pnode->parent->nbranch[pnode->iip];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (branch->lnum != lnum || branch->offs != offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (test_bit(DIRTY_CNODE, &pnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * dbg_is_ltab_dirty - determine if a ltab node is dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * @lnum: LEB number where ltab node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * @offs: offset where ltab node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static int dbg_is_ltab_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (lnum != c->ltab_lnum || offs != c->ltab_offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return (c->lpt_drty_flgs & LTAB_DIRTY) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * dbg_is_lsave_dirty - determine if a lsave node is dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * @lnum: LEB number where lsave node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * @offs: offset where lsave node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) static int dbg_is_lsave_dirty(struct ubifs_info *c, int lnum, int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (lnum != c->lsave_lnum || offs != c->lsave_offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) return (c->lpt_drty_flgs & LSAVE_DIRTY) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * dbg_is_node_dirty - determine if a node is dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * @node_type: node type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * @lnum: LEB number where node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * @offs: offset where node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) static int dbg_is_node_dirty(struct ubifs_info *c, int node_type, int lnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) int offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) switch (node_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) case UBIFS_LPT_NNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return dbg_is_nnode_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case UBIFS_LPT_PNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return dbg_is_pnode_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case UBIFS_LPT_LTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) return dbg_is_ltab_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) case UBIFS_LPT_LSAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) return dbg_is_lsave_dirty(c, lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * dbg_check_ltab_lnum - check the ltab for a LPT LEB number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * @lnum: LEB number where node was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) int err, len = c->leb_size, dirty = 0, node_type, node_num, node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) void *buf, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (!dbg_is_chk_lprops(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) buf = p = __vmalloc(c->leb_size, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) ubifs_err(c, "cannot allocate memory for ltab checking");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) dbg_lp("LEB %d", lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) if (!is_a_node(c, p, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) int i, pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) pad_len = get_pad_len(c, p, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (pad_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) p += pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) len -= pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) dirty += pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (!dbg_is_all_ff(p, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) ubifs_err(c, "invalid empty space in LEB %d at %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) lnum, c->leb_size - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) i = lnum - c->lpt_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if (len != c->ltab[i].free) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) ubifs_err(c, "invalid free space in LEB %d (free %d, expected %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) lnum, len, c->ltab[i].free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (dirty != c->ltab[i].dirty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) ubifs_err(c, "invalid dirty space in LEB %d (dirty %d, expected %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) lnum, dirty, c->ltab[i].dirty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) node_type = get_lpt_node_type(c, p, &node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) node_len = get_lpt_node_len(c, node_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ret = dbg_is_node_dirty(c, node_type, lnum, c->leb_size - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) dirty += node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) p += node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) len -= node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) vfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * dbg_check_ltab - check the free and dirty space in the ltab.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) int dbg_check_ltab(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) int lnum, err, i, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (!dbg_is_chk_lprops(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* Bring the entire tree into memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) cnt = DIV_ROUND_UP(c->main_lebs, UBIFS_LPT_FANOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct ubifs_pnode *pnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) pnode = ubifs_pnode_lookup(c, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (IS_ERR(pnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return PTR_ERR(pnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /* Check nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) err = dbg_check_lpt_nodes(c, (struct ubifs_cnode *)c->nroot, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) /* Check each LEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) err = dbg_check_ltab_lnum(c, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) ubifs_err(c, "failed at LEB %d", lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) dbg_lp("succeeded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * dbg_chk_lpt_free_spc - check LPT free space is enough to write entire LPT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) int dbg_chk_lpt_free_spc(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) long long free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (!dbg_is_chk_lprops(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) for (i = 0; i < c->lpt_lebs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (c->ltab[i].tgc || c->ltab[i].cmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (i + c->lpt_first == c->nhead_lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) free += c->leb_size - c->nhead_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) else if (c->ltab[i].free == c->leb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) free += c->leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (free < c->lpt_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) ubifs_err(c, "LPT space error: free %lld lpt_sz %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) free, c->lpt_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) ubifs_dump_lpt_info(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) ubifs_dump_lpt_lebs(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * dbg_chk_lpt_sz - check LPT does not write more than LPT size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * @c: the UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) * @action: what to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) * @len: length written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) * This function returns %0 on success and a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * The @action argument may be one of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) * o %0 - LPT debugging checking starts, initialize debugging variables;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * o %1 - wrote an LPT node, increase LPT size by @len bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) * o %2 - switched to a different LEB and wasted @len bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) * o %3 - check that we've written the right number of bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) * o %4 - wasted @len bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct ubifs_debug_info *d = c->dbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) long long chk_lpt_sz, lpt_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (!dbg_is_chk_lprops(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) d->chk_lpt_sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) d->chk_lpt_sz2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) d->chk_lpt_lebs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) d->chk_lpt_wastage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (c->dirty_pn_cnt > c->pnode_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ubifs_err(c, "dirty pnodes %d exceed max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) c->dirty_pn_cnt, c->pnode_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (c->dirty_nn_cnt > c->nnode_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) ubifs_err(c, "dirty nnodes %d exceed max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) c->dirty_nn_cnt, c->nnode_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) d->chk_lpt_sz += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) d->chk_lpt_sz += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) d->chk_lpt_wastage += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) d->chk_lpt_lebs += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) chk_lpt_sz = c->leb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) chk_lpt_sz *= d->chk_lpt_lebs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) chk_lpt_sz += len - c->nhead_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (d->chk_lpt_sz != chk_lpt_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) ubifs_err(c, "LPT wrote %lld but space used was %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) d->chk_lpt_sz, chk_lpt_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (d->chk_lpt_sz > c->lpt_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) ubifs_err(c, "LPT wrote %lld but lpt_sz is %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) d->chk_lpt_sz, c->lpt_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ubifs_err(c, "LPT layout size %lld but wrote %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) d->chk_lpt_sz, d->chk_lpt_sz2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (d->chk_lpt_sz2 && d->new_nhead_offs != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) ubifs_err(c, "LPT new nhead offs: expected %d was %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) d->new_nhead_offs, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) lpt_sz += c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) lpt_sz += c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) ubifs_err(c, "LPT chk_lpt_sz %lld + waste %lld exceeds %lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) ubifs_dump_lpt_info(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) ubifs_dump_lpt_lebs(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) d->chk_lpt_sz2 = d->chk_lpt_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) d->chk_lpt_sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) d->chk_lpt_wastage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) d->chk_lpt_lebs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) d->new_nhead_offs = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) d->chk_lpt_sz += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) d->chk_lpt_wastage += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * dump_lpt_leb - dump an LPT LEB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * @lnum: LEB number to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) * This function dumps an LEB from LPT area. Nodes in this area are very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * different to nodes in the main area (e.g., they do not have common headers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * they do not have 8-byte alignments, etc), so we have a separate function to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * dump LPT area LEBs. Note, LPT has to be locked by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) int err, len = c->leb_size, node_type, node_num, node_len, offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) void *buf, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) buf = p = __vmalloc(c->leb_size, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) ubifs_err(c, "cannot allocate memory to dump LPT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) offs = c->leb_size - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (!is_a_node(c, p, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) int pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) pad_len = get_pad_len(c, p, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) if (pad_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) pr_err("LEB %d:%d, pad %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) lnum, offs, pad_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) p += pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) len -= pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) pr_err("LEB %d:%d, free %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) lnum, offs, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) node_type = get_lpt_node_type(c, p, &node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) switch (node_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) case UBIFS_LPT_PNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) node_len = c->pnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) pr_err("LEB %d:%d, pnode num %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) lnum, offs, node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) pr_err("LEB %d:%d, pnode\n", lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) case UBIFS_LPT_NNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) struct ubifs_nnode nnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) node_len = c->nnode_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (c->big_lpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) pr_err("LEB %d:%d, nnode num %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) lnum, offs, node_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) pr_err("LEB %d:%d, nnode, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) err = ubifs_unpack_nnode(c, p, &nnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) pr_err("failed to unpack_node, error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) pr_cont("%d:%d", nnode.nbranch[i].lnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) nnode.nbranch[i].offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (i != UBIFS_LPT_FANOUT - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) pr_cont(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) case UBIFS_LPT_LTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) node_len = c->ltab_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) pr_err("LEB %d:%d, ltab\n", lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) case UBIFS_LPT_LSAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) node_len = c->lsave_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) pr_err("LEB %d:%d, lsave len\n", lnum, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) ubifs_err(c, "LPT node type %d not recognized", node_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) p += node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) len -= node_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) vfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) * ubifs_dump_lpt_lebs - dump LPT lebs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) * This function dumps all LPT LEBs. The caller has to make sure the LPT is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) * locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) void ubifs_dump_lpt_lebs(const struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) pr_err("(pid %d) start dumping all LPT LEBs\n", current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) for (i = 0; i < c->lpt_lebs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) dump_lpt_leb(c, i + c->lpt_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) pr_err("(pid %d) finish dumping all LPT LEBs\n", current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) * dbg_populate_lsave - debugging version of 'populate_lsave()'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) * @c: UBIFS file-system description object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) * This is a debugging version for 'populate_lsave()' which populates lsave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * with random LEBs instead of useful LEBs, which is good for test coverage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) * Returns zero if lsave has not been populated (this debugging feature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * disabled) an non-zero if lsave has been populated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) static int dbg_populate_lsave(struct ubifs_info *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) struct ubifs_lprops *lprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) struct ubifs_lpt_heap *heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (!dbg_is_chk_gen(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) if (prandom_u32() & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) for (i = 0; i < c->lsave_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) c->lsave[i] = c->main_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) list_for_each_entry(lprops, &c->empty_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) c->lsave[prandom_u32() % c->lsave_cnt] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) list_for_each_entry(lprops, &c->freeable_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) c->lsave[prandom_u32() % c->lsave_cnt] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) list_for_each_entry(lprops, &c->frdi_idx_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) c->lsave[prandom_u32() % c->lsave_cnt] = lprops->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) for (i = 0; i < heap->cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) c->lsave[prandom_u32() % c->lsave_cnt] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) heap = &c->lpt_heap[LPROPS_DIRTY - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) for (i = 0; i < heap->cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) c->lsave[prandom_u32() % c->lsave_cnt] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) heap = &c->lpt_heap[LPROPS_FREE - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) for (i = 0; i < heap->cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) c->lsave[prandom_u32() % c->lsave_cnt] = heap->arr[i]->lnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }