summaryrefslogtreecommitdiff
path: root/fs/ubifs/lpt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 01:58:04 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 01:58:04 +0300
commit6f7948f566bf423ddf5ff58dc0198afcf37c0b64 (patch)
treef6a361d71d971626a27487d32c1379371f2e369b /fs/ubifs/lpt.c
parentb39d7efc11b93d9150d99a731db26fd36e2facd2 (diff)
parent99a24e02ccf6604e3020cf9e2c7a042b6ebb655f (diff)
downloadlinux-6f7948f566bf423ddf5ff58dc0198afcf37c0b64.tar.xz
Merge tag 'upstream-4.19-rc1' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS updates from Richard Weinberger: - Year 2038 preparations - New UBI feature to skip CRC checks of static volumes - A new Kconfig option to disable xattrs in UBIFS - Lots of fixes in UBIFS, found by our new test framework * tag 'upstream-4.19-rc1' of git://git.infradead.org/linux-ubifs: (21 commits) ubifs: Set default assert action to read-only ubifs: Allow setting assert action as mount parameter ubifs: Rework ubifs_assert() ubifs: Pass struct ubifs_info to ubifs_assert() ubifs: Turn two ubifs_assert() into a WARN_ON() ubi: expose the volume CRC check skip flag ubi: provide a way to skip CRC checks ubifs: Use kmalloc_array() ubifs: Check data node size before truncate Revert "UBIFS: Fix potential integer overflow in allocation" ubifs: Add comment on c->commit_sem ubifs: introduce Kconfig symbol for xattr support ubifs: use swap macro in swap_dirty_idx ubifs: tnc: use monotonic znode timestamp ubifs: use timespec64 for inode timestamps ubifs: xattr: Don't operate on deleted inodes ubifs: gc: Fix typo ubifs: Fix memory leak in lprobs self-check ubi: Initialize Fastmap checkmapping correctly ubifs: Fix synced_i_size calculation for xattr inodes ...
Diffstat (limited to 'fs/ubifs/lpt.c')
-rw-r--r--fs/ubifs/lpt.c112
1 files changed, 57 insertions, 55 deletions
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 8e99dad18880..31393370e334 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -225,21 +225,22 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
/**
* pack_bits - pack bit fields end-to-end.
+ * @c: UBIFS file-system description object
* @addr: address at which to pack (passed and next address returned)
* @pos: bit position at which to pack (passed and next position returned)
* @val: value to pack
* @nrbits: number of bits of value to pack (1-32)
*/
-static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
+static void pack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, uint32_t val, int nrbits)
{
uint8_t *p = *addr;
int b = *pos;
- ubifs_assert(nrbits > 0);
- ubifs_assert(nrbits <= 32);
- ubifs_assert(*pos >= 0);
- ubifs_assert(*pos < 8);
- ubifs_assert((val >> nrbits) == 0 || nrbits == 32);
+ ubifs_assert(c, nrbits > 0);
+ ubifs_assert(c, nrbits <= 32);
+ ubifs_assert(c, *pos >= 0);
+ ubifs_assert(c, *pos < 8);
+ ubifs_assert(c, (val >> nrbits) == 0 || nrbits == 32);
if (b) {
*p |= ((uint8_t)val) << b;
nrbits += b;
@@ -274,13 +275,14 @@ static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
/**
* ubifs_unpack_bits - unpack bit fields.
+ * @c: UBIFS file-system description object
* @addr: address at which to unpack (passed and next address returned)
* @pos: bit position at which to unpack (passed and next position returned)
* @nrbits: number of bits of value to unpack (1-32)
*
* This functions returns the value unpacked.
*/
-uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
+uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits)
{
const int k = 32 - nrbits;
uint8_t *p = *addr;
@@ -288,10 +290,10 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
uint32_t uninitialized_var(val);
const int bytes = (nrbits + b + 7) >> 3;
- ubifs_assert(nrbits > 0);
- ubifs_assert(nrbits <= 32);
- ubifs_assert(*pos >= 0);
- ubifs_assert(*pos < 8);
+ ubifs_assert(c, nrbits > 0);
+ ubifs_assert(c, nrbits <= 32);
+ ubifs_assert(c, *pos >= 0);
+ ubifs_assert(c, *pos < 8);
if (b) {
switch (bytes) {
case 2:
@@ -337,7 +339,7 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
p += nrbits >> 3;
*addr = p;
*pos = b;
- ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);
+ ubifs_assert(c, (val >> nrbits) == 0 || nrbits - b == 32);
return val;
}
@@ -354,24 +356,24 @@ void ubifs_pack_pnode(struct ubifs_info *c, void *buf,
int i, pos = 0;
uint16_t crc;
- pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
+ pack_bits(c, &addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
if (c->big_lpt)
- pack_bits(&addr, &pos, pnode->num, c->pcnt_bits);
+ pack_bits(c, &addr, &pos, pnode->num, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
- pack_bits(&addr, &pos, pnode->lprops[i].free >> 3,
+ pack_bits(c, &addr, &pos, pnode->lprops[i].free >> 3,
c->space_bits);
- pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3,
+ pack_bits(c, &addr, &pos, pnode->lprops[i].dirty >> 3,
c->space_bits);
if (pnode->lprops[i].flags & LPROPS_INDEX)
- pack_bits(&addr, &pos, 1, 1);
+ pack_bits(c, &addr, &pos, 1, 1);
else
- pack_bits(&addr, &pos, 0, 1);
+ pack_bits(c, &addr, &pos, 0, 1);
}
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->pnode_sz - UBIFS_LPT_CRC_BYTES);
addr = buf;
pos = 0;
- pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+ pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
}
/**
@@ -387,23 +389,23 @@ void ubifs_pack_nnode(struct ubifs_info *c, void *buf,
int i, pos = 0;
uint16_t crc;
- pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
+ pack_bits(c, &addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
if (c->big_lpt)
- pack_bits(&addr, &pos, nnode->num, c->pcnt_bits);
+ pack_bits(c, &addr, &pos, nnode->num, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
int lnum = nnode->nbranch[i].lnum;
if (lnum == 0)
lnum = c->lpt_last + 1;
- pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
- pack_bits(&addr, &pos, nnode->nbranch[i].offs,
+ pack_bits(c, &addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
+ pack_bits(c, &addr, &pos, nnode->nbranch[i].offs,
c->lpt_offs_bits);
}
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->nnode_sz - UBIFS_LPT_CRC_BYTES);
addr = buf;
pos = 0;
- pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+ pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
}
/**
@@ -419,16 +421,16 @@ void ubifs_pack_ltab(struct ubifs_info *c, void *buf,
int i, pos = 0;
uint16_t crc;
- pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
+ pack_bits(c, &addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
for (i = 0; i < c->lpt_lebs; i++) {
- pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits);
- pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
+ pack_bits(c, &addr, &pos, ltab[i].free, c->lpt_spc_bits);
+ pack_bits(c, &addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
}
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->ltab_sz - UBIFS_LPT_CRC_BYTES);
addr = buf;
pos = 0;
- pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+ pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
}
/**
@@ -443,14 +445,14 @@ void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
int i, pos = 0;
uint16_t crc;
- pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
+ pack_bits(c, &addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
for (i = 0; i < c->lsave_cnt; i++)
- pack_bits(&addr, &pos, lsave[i], c->lnum_bits);
+ pack_bits(c, &addr, &pos, lsave[i], c->lnum_bits);
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->lsave_sz - UBIFS_LPT_CRC_BYTES);
addr = buf;
pos = 0;
- pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+ pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
}
/**
@@ -465,7 +467,7 @@ void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty)
return;
dbg_lp("LEB %d add %d to %d",
lnum, dirty, c->ltab[lnum - c->lpt_first].dirty);
- ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last);
+ ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
c->ltab[lnum - c->lpt_first].dirty += dirty;
}
@@ -481,7 +483,7 @@ static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
dbg_lp("LEB %d free %d dirty %d to %d %d",
lnum, c->ltab[lnum - c->lpt_first].free,
c->ltab[lnum - c->lpt_first].dirty, free, dirty);
- ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last);
+ ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
c->ltab[lnum - c->lpt_first].free = free;
c->ltab[lnum - c->lpt_first].dirty = dirty;
}
@@ -639,7 +641,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
goto out;
}
- ubifs_assert(!c->ltab);
+ ubifs_assert(c, !c->ltab);
c->ltab = ltab; /* Needed by set_ltab */
/* Initialize LPT's own lprops */
@@ -918,7 +920,7 @@ static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len)
uint8_t *addr = buf;
uint16_t crc, calc_crc;
- crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS);
+ crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
len - UBIFS_LPT_CRC_BYTES);
if (crc != calc_crc) {
@@ -944,7 +946,7 @@ static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr,
{
int node_type;
- node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS);
+ node_type = ubifs_unpack_bits(c, addr, pos, UBIFS_LPT_TYPE_BITS);
if (node_type != type) {
ubifs_err(c, "invalid type (%d) in LPT node type %d",
node_type, type);
@@ -972,16 +974,16 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf,
if (err)
return err;
if (c->big_lpt)
- pnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+ pnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
struct ubifs_lprops * const lprops = &pnode->lprops[i];
- lprops->free = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+ lprops->free = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
lprops->free <<= 3;
- lprops->dirty = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+ lprops->dirty = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
lprops->dirty <<= 3;
- if (ubifs_unpack_bits(&addr, &pos, 1))
+ if (ubifs_unpack_bits(c, &addr, &pos, 1))
lprops->flags = LPROPS_INDEX;
else
lprops->flags = 0;
@@ -1009,16 +1011,16 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
if (err)
return err;
if (c->big_lpt)
- nnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+ nnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
int lnum;
- lnum = ubifs_unpack_bits(&addr, &pos, c->lpt_lnum_bits) +
+ lnum = ubifs_unpack_bits(c, &addr, &pos, c->lpt_lnum_bits) +
c->lpt_first;
if (lnum == c->lpt_last + 1)
lnum = 0;
nnode->nbranch[i].lnum = lnum;
- nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos,
+ nnode->nbranch[i].offs = ubifs_unpack_bits(c, &addr, &pos,
c->lpt_offs_bits);
}
err = check_lpt_crc(c, buf, c->nnode_sz);
@@ -1041,8 +1043,8 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)
if (err)
return err;
for (i = 0; i < c->lpt_lebs; i++) {
- int free = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
- int dirty = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
+ int free = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
+ int dirty = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
if (free < 0 || free > c->leb_size || dirty < 0 ||
dirty > c->leb_size || free + dirty > c->leb_size)
@@ -1073,7 +1075,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)
if (err)
return err;
for (i = 0; i < c->lsave_cnt; i++) {
- int lnum = ubifs_unpack_bits(&addr, &pos, c->lnum_bits);
+ int lnum = ubifs_unpack_bits(c, &addr, &pos, c->lnum_bits);
if (lnum < c->main_first || lnum >= c->leb_cnt)
return -EINVAL;
@@ -1515,7 +1517,7 @@ static struct ubifs_nnode *dirty_cow_nnode(struct ubifs_info *c,
branch->cnode->parent = n;
}
- ubifs_assert(!test_bit(OBSOLETE_CNODE, &nnode->flags));
+ ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &nnode->flags));
__set_bit(OBSOLETE_CNODE, &nnode->flags);
c->dirty_nn_cnt += 1;
@@ -1558,7 +1560,7 @@ static struct ubifs_pnode *dirty_cow_pnode(struct ubifs_info *c,
__clear_bit(COW_CNODE, &p->flags);
replace_cats(c, pnode, p);
- ubifs_assert(!test_bit(OBSOLETE_CNODE, &pnode->flags));
+ ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &pnode->flags));
__set_bit(OBSOLETE_CNODE, &pnode->flags);
c->dirty_pn_cnt += 1;
@@ -1613,7 +1615,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty,
pnode->lprops[iip].flags);
- ubifs_assert(test_bit(DIRTY_CNODE, &pnode->flags));
+ ubifs_assert(c, test_bit(DIRTY_CNODE, &pnode->flags));
return &pnode->lprops[iip];
}
@@ -1889,9 +1891,9 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
lprops->flags = ubifs_categorize_lprops(c, lprops);
}
} else {
- ubifs_assert(branch->lnum >= c->lpt_first &&
+ ubifs_assert(c, branch->lnum >= c->lpt_first &&
branch->lnum <= c->lpt_last);
- ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size);
+ ubifs_assert(c, branch->offs >= 0 && branch->offs < c->leb_size);
err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
c->pnode_sz, 1);
if (err)
@@ -1935,8 +1937,8 @@ int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,
start_lnum = c->main_first;
}
- ubifs_assert(start_lnum >= c->main_first && start_lnum < c->leb_cnt);
- ubifs_assert(end_lnum >= c->main_first && end_lnum < c->leb_cnt);
+ ubifs_assert(c, start_lnum >= c->main_first && start_lnum < c->leb_cnt);
+ ubifs_assert(c, end_lnum >= c->main_first && end_lnum < c->leb_cnt);
if (!c->nroot) {
err = ubifs_read_nnode(c, NULL, 0);
@@ -2055,7 +2057,7 @@ again:
iip = pnode->iip;
while (1) {
h -= 1;
- ubifs_assert(h >= 0);
+ ubifs_assert(c, h >= 0);
nnode = path[h].ptr.nnode;
if (iip + 1 < UBIFS_LPT_FANOUT)
break;
@@ -2234,7 +2236,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
return 0;
while (cnode) {
- ubifs_assert(row >= 0);
+ ubifs_assert(c, row >= 0);
nnode = cnode->parent;
if (cnode->level) {
/* cnode is a nnode */