diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-24 01:58:04 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-24 01:58:04 +0300 |
commit | 6f7948f566bf423ddf5ff58dc0198afcf37c0b64 (patch) | |
tree | f6a361d71d971626a27487d32c1379371f2e369b /fs/ubifs/lpt.c | |
parent | b39d7efc11b93d9150d99a731db26fd36e2facd2 (diff) | |
parent | 99a24e02ccf6604e3020cf9e2c7a042b6ebb655f (diff) | |
download | linux-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.c | 112 |
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 */ |