aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/common
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:01:00 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:45 +0100
commit665c44e7c9135a58847ab0773fc7977929d1497c (patch)
treeb66859f364d9bafc2d9bd0d19c5d4a42cf72e8c4 /ubifs-utils/common
parent2ac2e90cca9528147969d21378f8a736db710e35 (diff)
ubifs-utils: Replace ubifs related source code with linux kernel implementation
Replace ubifs related source code with the implementation of linux kernel. It makes userspace implementation be same with linux kernel, then fsck.ubifs can resuse the code. Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/common')
-rw-r--r--ubifs-utils/common/README3
-rw-r--r--ubifs-utils/common/defs.h9
-rw-r--r--ubifs-utils/common/key.h222
-rw-r--r--ubifs-utils/common/lpt.c595
-rw-r--r--ubifs-utils/common/lpt.h30
-rw-r--r--ubifs-utils/common/sign.c148
-rw-r--r--ubifs-utils/common/sign.h65
-rw-r--r--ubifs-utils/common/super.c123
-rw-r--r--ubifs-utils/common/ubifs.h498
9 files changed, 77 insertions, 1616 deletions
diff --git a/ubifs-utils/common/README b/ubifs-utils/common/README
index 32d04e3..a93ebd0 100644
--- a/ubifs-utils/common/README
+++ b/ubifs-utils/common/README
@@ -2,10 +2,7 @@ Common Library
* crc16.h and crc16.c were copied from the linux kernel.
* crc32.h and crc32.c were copied from mtd-utils and amended.
-* ubifs.h is a selection of definitions from fs/ubifs/ubifs.h from the linux kernel.
-* key.h is copied from fs/ubifs/key.h from the linux kernel.
* defs.h is a bunch of definitions to smooth things over.
-* lpt.c is a selection of functions copied from fs/ubifs/lpt.c from the linux kernel, and amended.
* hashtable/* was downloaded from http://www.cl.cam.ac.uk/~cwc22/hashtable/
* atomic.h was downloaded from https://the-linux-channel.the-toffee-project.org/index.php?page=6-tutorials-linux-user-space-atomic-operations
* bitops.h and bitops.c were copied from the linux kernel.
diff --git a/ubifs-utils/common/defs.h b/ubifs-utils/common/defs.h
index ac46d83..db32ea4 100644
--- a/ubifs-utils/common/defs.h
+++ b/ubifs-utils/common/defs.h
@@ -15,7 +15,6 @@
#include <assert.h>
#include <execinfo.h>
-#include "linux_types.h"
#include "ubifs.h"
/* common.h requires the PROGRAM_NAME macro */
@@ -27,8 +26,6 @@ extern struct ubifs_info info_;
enum { MKFS_PROGRAM_TYPE = 0 };
-enum { ERR_LEVEL = 1, WARN_LEVEL, INFO_LEVEL, DEBUG_LEVEL };
-
enum {
DUMP_PREFIX_NONE,
DUMP_PREFIX_ADDRESS,
@@ -114,12 +111,6 @@ static inline u64 div_u64(u64 dividend, u32 divisor)
return dividend / divisor;
}
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
#if INT_MAX != 0x7fffffff
#error : sizeof(int) must be 4 for this program
#endif
diff --git a/ubifs-utils/common/key.h b/ubifs-utils/common/key.h
deleted file mode 100644
index 2de530b..0000000
--- a/ubifs-utils/common/key.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2006-2008 Nokia Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy (Битюцкий Артём)
- * Adrian Hunter
- */
-
-/*
- * This header contains various key-related definitions and helper function.
- * UBIFS allows several key schemes, so we access key fields only via these
- * helpers. At the moment only one key scheme is supported.
- *
- * Simple key scheme
- * ~~~~~~~~~~~~~~~~~
- *
- * Keys are 64-bits long. First 32-bits are inode number (parent inode number
- * in case of direntry key). Next 3 bits are node type. The last 29 bits are
- * 4KiB offset in case of inode node, and direntry hash in case of a direntry
- * node. We use "r5" hash borrowed from reiserfs.
- */
-
-#ifndef __UBIFS_KEY_H__
-#define __UBIFS_KEY_H__
-
-#include <assert.h>
-
-/**
- * key_mask_hash - mask a valid hash value.
- * @val: value to be masked
- *
- * We use hash values as offset in directories, so values %0 and %1 are
- * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
- * function makes sure the reserved values are not used.
- */
-static inline uint32_t key_mask_hash(uint32_t hash)
-{
- hash &= UBIFS_S_KEY_HASH_MASK;
- if (unlikely(hash <= 2))
- hash += 3;
- return hash;
-}
-
-/**
- * key_r5_hash - R5 hash function (borrowed from reiserfs).
- * @s: direntry name
- * @len: name length
- */
-static inline uint32_t key_r5_hash(const char *s, int len)
-{
- uint32_t a = 0;
- const signed char *str = (const signed char *)s;
-
- while (len--) {
- a += *str << 4;
- a += *str >> 4;
- a *= 11;
- str++;
- }
-
- return key_mask_hash(a);
-}
-
-/**
- * key_test_hash - testing hash function.
- * @str: direntry name
- * @len: name length
- */
-static inline uint32_t key_test_hash(const char *str, int len)
-{
- uint32_t a = 0;
-
- len = min_t(uint32_t, len, 4);
- memcpy(&a, str, len);
- return key_mask_hash(a);
-}
-
-/**
- * ino_key_init - initialize inode key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: inode number
- */
-static inline void ino_key_init(union ubifs_key *key, ino_t inum)
-{
- key->u32[0] = inum;
- key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
-}
-
-/**
- * dent_key_init - initialize directory entry key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: parent inode number
- * @nm: direntry name and length
- */
-static inline void dent_key_init(const struct ubifs_info *c,
- union ubifs_key *key, ino_t inum,
- const void *name, int name_len)
-{
- uint32_t hash = c->key_hash(name, name_len);
-
- assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
- key->u32[0] = inum;
- key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
-}
-
-/**
- * xent_key_init - initialize extended attribute entry key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: host inode number
- * @nm: extended attribute entry name and length
- */
-static inline void xent_key_init(const struct ubifs_info *c,
- union ubifs_key *key, ino_t inum,
- const struct qstr *nm)
-{
- uint32_t hash = c->key_hash(nm->name, nm->len);
-
- assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
- key->u32[0] = inum;
- key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
-}
-
-/**
- * data_key_init - initialize data key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: inode number
- * @block: block number
- */
-static inline void data_key_init(union ubifs_key *key, ino_t inum,
- unsigned int block)
-{
- assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
- key->u32[0] = inum;
- key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
-}
-
-/**
- * key_write - transform a key from in-memory format.
- * @c: UBIFS file-system description object
- * @from: the key to transform
- * @to: the key to store the result
- */
-static inline void key_write(const union ubifs_key *from, void *to)
-{
- __le32 x[2];
-
- x[0] = cpu_to_le32(from->u32[0]);
- x[1] = cpu_to_le32(from->u32[1]);
-
- memcpy(to, &x, 8);
- memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
-}
-
-/**
- * key_write_idx - transform a key from in-memory format for the index.
- * @c: UBIFS file-system description object
- * @from: the key to transform
- * @to: the key to store the result
- */
-static inline void key_write_idx(const union ubifs_key *from, void *to)
-{
- __le32 x[2];
-
- x[0] = cpu_to_le32(from->u32[0]);
- x[1] = cpu_to_le32(from->u32[1]);
-
- memcpy(to, &x, 8);
-}
-
-/**
- * keys_cmp - compare keys.
- * @c: UBIFS file-system description object
- * @key1: the first key to compare
- * @key2: the second key to compare
- *
- * This function compares 2 keys and returns %-1 if @key1 is less than
- * @key2, 0 if the keys are equivalent and %1 if @key1 is greater than @key2.
- */
-static inline int keys_cmp(const union ubifs_key *key1,
- const union ubifs_key *key2)
-{
- if (key1->u32[0] < key2->u32[0])
- return -1;
- if (key1->u32[0] > key2->u32[0])
- return 1;
- if (key1->u32[1] < key2->u32[1])
- return -1;
- if (key1->u32[1] > key2->u32[1])
- return 1;
-
- return 0;
-}
-
-/**
- * key_type - get key type.
- * @c: UBIFS file-system description object
- * @key: key to get type of
- */
-static inline int key_type(const union ubifs_key *key)
-{
- return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
-}
-
-#endif /* !__UBIFS_KEY_H__ */
diff --git a/ubifs-utils/common/lpt.c b/ubifs-utils/common/lpt.c
deleted file mode 100644
index 0723698..0000000
--- a/ubifs-utils/common/lpt.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2006, 2007 Nokia Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Adrian Hunter
- * Artem Bityutskiy
- */
-
-#ifdef WITH_CRYPTO
-#include <openssl/evp.h>
-#endif
-
-#include "lpt.h"
-#include "bitops.h"
-#include "defs.h"
-#include "ubifs.h"
-#include "crc16.h"
-#include "sign.h"
-
-/**
- * do_calc_lpt_geom - calculate sizes for the LPT area.
- * @c: the UBIFS file-system description object
- *
- * Calculate the sizes of LPT bit fields, nodes, and tree, based on the
- * properties of the flash and whether LPT is "big" (c->big_lpt).
- */
-static void do_calc_lpt_geom(struct ubifs_info *c)
-{
- int n, bits, per_leb_wastage;
- long long sz, tot_wastage;
-
- c->pnode_cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-
- n = (c->pnode_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
- c->nnode_cnt = n;
- while (n > 1) {
- n = (n + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
- c->nnode_cnt += n;
- }
-
- c->lpt_hght = 1;
- n = UBIFS_LPT_FANOUT;
- while (n < c->pnode_cnt) {
- c->lpt_hght += 1;
- n <<= UBIFS_LPT_FANOUT_SHIFT;
- }
-
- c->space_bits = fls(c->leb_size) - 3;
- c->lpt_lnum_bits = fls(c->lpt_lebs);
- c->lpt_offs_bits = fls(c->leb_size - 1);
- c->lpt_spc_bits = fls(c->leb_size);
-
- n = (c->max_leb_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
- c->pcnt_bits = fls(n - 1);
-
- c->lnum_bits = fls(c->max_leb_cnt - 1);
-
- bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
- (c->big_lpt ? c->pcnt_bits : 0) +
- (c->space_bits * 2 + 1) * UBIFS_LPT_FANOUT;
- c->pnode_sz = (bits + 7) / 8;
-
- bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
- (c->big_lpt ? c->pcnt_bits : 0) +
- (c->lpt_lnum_bits + c->lpt_offs_bits) * UBIFS_LPT_FANOUT;
- c->nnode_sz = (bits + 7) / 8;
-
- bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
- c->lpt_lebs * c->lpt_spc_bits * 2;
- c->ltab_sz = (bits + 7) / 8;
-
- bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
- c->lnum_bits * c->lsave_cnt;
- c->lsave_sz = (bits + 7) / 8;
-
- /* Calculate the minimum LPT size */
- c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
- c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
- c->lpt_sz += c->ltab_sz;
- c->lpt_sz += c->lsave_sz;
-
- /* Add wastage */
- sz = c->lpt_sz;
- per_leb_wastage = max_t(int, c->pnode_sz, c->nnode_sz);
- sz += per_leb_wastage;
- tot_wastage = per_leb_wastage;
- while (sz > c->leb_size) {
- sz += per_leb_wastage;
- sz -= c->leb_size;
- tot_wastage += per_leb_wastage;
- }
- tot_wastage += ALIGN(sz, c->min_io_size) - sz;
- c->lpt_sz += tot_wastage;
-}
-
-/**
- * calc_dflt_lpt_geom - calculate default LPT geometry.
- * @c: the UBIFS file-system description object
- * @main_lebs: number of main area LEBs is passed and returned here
- * @big_lpt: whether the LPT area is "big" is returned here
- *
- * The size of the LPT area depends on parameters that themselves are dependent
- * on the size of the LPT area. This function, successively recalculates the LPT
- * area geometry until the parameters and resultant geometry are consistent.
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt)
-{
- int i, lebs_needed;
- long long sz;
-
- /* Start by assuming the minimum number of LPT LEBs */
- c->lpt_lebs = UBIFS_MIN_LPT_LEBS;
- c->main_lebs = *main_lebs - c->lpt_lebs;
- if (c->main_lebs <= 0)
- return -EINVAL;
-
- /* And assume we will use the small LPT model */
- c->big_lpt = 0;
-
- /*
- * Calculate the geometry based on assumptions above and then see if it
- * makes sense
- */
- do_calc_lpt_geom(c);
-
- /* Small LPT model must have lpt_sz < leb_size */
- if (c->lpt_sz > c->leb_size) {
- /* Nope, so try again using big LPT model */
- c->big_lpt = 1;
- do_calc_lpt_geom(c);
- }
-
- /* Now check there are enough LPT LEBs */
- for (i = 0; i < 64 ; i++) {
- sz = c->lpt_sz * 4; /* Allow 4 times the size */
- sz += c->leb_size - 1;
- do_div(sz, c->leb_size);
- lebs_needed = sz;
- if (lebs_needed > c->lpt_lebs) {
- /* Not enough LPT LEBs so try again with more */
- c->lpt_lebs = lebs_needed;
- c->main_lebs = *main_lebs - c->lpt_lebs;
- if (c->main_lebs <= 0)
- return -EINVAL;
- do_calc_lpt_geom(c);
- continue;
- }
- if (c->ltab_sz > c->leb_size) {
- errmsg("LPT ltab too big");
- return -EINVAL;
- }
- *main_lebs = c->main_lebs;
- *big_lpt = c->big_lpt;
- return 0;
- }
- return -EINVAL;
-}
-
-/**
- * pack_bits - pack bit fields end-to-end.
- * @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)
-{
- uint8_t *p = *addr;
- int b = *pos;
-
- if (b) {
- *p |= ((uint8_t)val) << b;
- nrbits += b;
- if (nrbits > 8) {
- *++p = (uint8_t)(val >>= (8 - b));
- if (nrbits > 16) {
- *++p = (uint8_t)(val >>= 8);
- if (nrbits > 24) {
- *++p = (uint8_t)(val >>= 8);
- if (nrbits > 32)
- *++p = (uint8_t)(val >>= 8);
- }
- }
- }
- } else {
- *p = (uint8_t)val;
- if (nrbits > 8) {
- *++p = (uint8_t)(val >>= 8);
- if (nrbits > 16) {
- *++p = (uint8_t)(val >>= 8);
- if (nrbits > 24)
- *++p = (uint8_t)(val >>= 8);
- }
- }
- }
- b = nrbits & 7;
- if (b == 0)
- p++;
- *addr = p;
- *pos = b;
-}
-
-/**
- * pack_pnode - pack all the bit fields of a pnode.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @pnode: pnode to pack
- */
-static void pack_pnode(struct ubifs_info *c, void *buf,
- struct ubifs_pnode *pnode)
-{
- uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
- int i, pos = 0;
- uint16_t crc;
-
- pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
- if (c->big_lpt)
- pack_bits(&addr, &pos, pnode->num, c->pcnt_bits);
- for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
- pack_bits(&addr, &pos, pnode->lprops[i].free >> 3,
- c->space_bits);
- pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3,
- c->space_bits);
- if (pnode->lprops[i].flags & LPROPS_INDEX)
- pack_bits(&addr, &pos, 1, 1);
- else
- pack_bits(&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_nnode - pack all the bit fields of a nnode.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @nnode: nnode to pack
- */
-static void pack_nnode(struct ubifs_info *c, void *buf,
- struct ubifs_nnode *nnode)
-{
- uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
- int i, pos = 0;
- uint16_t crc;
-
- pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
- if (c->big_lpt)
- pack_bits(&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,
- 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_ltab - pack the LPT's own lprops table.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @ltab: LPT's own lprops table to pack
- */
-static void pack_ltab(struct ubifs_info *c, void *buf,
- struct ubifs_lpt_lprops *ltab)
-{
- uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
- int i, pos = 0;
- uint16_t crc;
-
- pack_bits(&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);
- }
- 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_lsave - pack the LPT's save table.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @lsave: LPT's save table to pack
- */
-static void pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
-{
- uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
- int i, pos = 0;
- uint16_t crc;
-
- pack_bits(&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);
- 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);
-}
-
-/**
- * set_ltab - set LPT LEB properties.
- * @c: UBIFS file-system description object
- * @lnum: LEB number
- * @free: amount of free space
- * @dirty: amount of dirty space
- */
-static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
-{
- pr_debug("LEB %d free %d dirty %d to %d %d\n",
- lnum, c->ltab[lnum - c->lpt_first].free,
- c->ltab[lnum - c->lpt_first].dirty, free, dirty);
- c->ltab[lnum - c->lpt_first].free = free;
- c->ltab[lnum - c->lpt_first].dirty = dirty;
-}
-
-/**
- * calc_nnode_num - calculate nnode number.
- * @row: the row in the tree (root is zero)
- * @col: the column in the row (leftmost is zero)
- *
- * The nnode number is a number that uniquely identifies a nnode and can be used
- * easily to traverse the tree from the root to that nnode.
- *
- * This function calculates and returns the nnode number for the nnode at @row
- * and @col.
- */
-static int calc_nnode_num(int row, int col)
-{
- int num, bits;
-
- num = 1;
- while (row--) {
- bits = (col & (UBIFS_LPT_FANOUT - 1));
- col >>= UBIFS_LPT_FANOUT_SHIFT;
- num <<= UBIFS_LPT_FANOUT_SHIFT;
- num |= bits;
- }
- return num;
-}
-
-/**
- * create_lpt - create LPT.
- * @c: UBIFS file-system description object
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-int create_lpt(struct ubifs_info *c)
-{
- int lnum, err = 0, i, j, cnt, len, alen, row;
- int blnum, boffs, bsz, bcnt;
- struct ubifs_pnode *pnode = NULL;
- struct ubifs_nnode *nnode = NULL;
- void *buf = NULL, *p;
- int *lsave = NULL;
- unsigned int md_len;
-
- pnode = malloc(sizeof(struct ubifs_pnode));
- nnode = malloc(sizeof(struct ubifs_nnode));
- buf = malloc(c->leb_size);
- lsave = malloc(sizeof(int) * c->lsave_cnt);
- if (!pnode || !nnode || !buf || !lsave) {
- err = -ENOMEM;
- goto out;
- }
- memset(pnode, 0 , sizeof(struct ubifs_pnode));
- memset(nnode, 0 , sizeof(struct ubifs_nnode));
-
- hash_digest_init();
-
- c->lscan_lnum = c->main_first;
-
- lnum = c->lpt_first;
- p = buf;
- len = 0;
- /* Number of leaf nodes (pnodes) */
- cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) >> UBIFS_LPT_FANOUT_SHIFT;
- //printf("pnode_cnt=%d\n",cnt);
-
- /*
- * To calculate the internal node branches, we keep information about
- * the level below.
- */
- blnum = lnum; /* LEB number of level below */
- boffs = 0; /* Offset of level below */
- bcnt = cnt; /* Number of nodes in level below */
- bsz = c->pnode_sz; /* Size of nodes in level below */
-
- /* Add pnodes */
- for (i = 0; i < cnt; i++) {
- if (len + c->pnode_sz > c->leb_size) {
- alen = ALIGN(len, c->min_io_size);
- set_ltab(c, lnum, c->leb_size - alen, alen - len);
- memset(p, 0xff, alen - len);
- err = write_leb(c, lnum++, alen, buf);
- if (err)
- goto out;
- p = buf;
- len = 0;
- }
- /* Fill in the pnode */
- for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
- int k = (i << UBIFS_LPT_FANOUT_SHIFT) + j;
-
- if (k < c->main_lebs)
- pnode->lprops[j] = c->lpt[k];
- else {
- pnode->lprops[j].free = c->leb_size;
- pnode->lprops[j].dirty = 0;
- pnode->lprops[j].flags = 0;
- }
- }
- pack_pnode(c, p, pnode);
-
- hash_digest_update(p, c->pnode_sz);
-
- p += c->pnode_sz;
- len += c->pnode_sz;
- /*
- * pnodes are simply numbered left to right starting at zero,
- * which means the pnode number can be used easily to traverse
- * down the tree to the corresponding pnode.
- */
- pnode->num += 1;
- }
-
- hash_digest_final(c->lpt_hash, &md_len);
-
- row = c->lpt_hght - 1;
- /* Add all nnodes, one level at a time */
- while (1) {
- /* Number of internal nodes (nnodes) at next level */
- cnt = (cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
- if (cnt == 0)
- cnt = 1;
- for (i = 0; i < cnt; i++) {
- if (len + c->nnode_sz > c->leb_size) {
- alen = ALIGN(len, c->min_io_size);
- set_ltab(c, lnum, c->leb_size - alen,
- alen - len);
- memset(p, 0xff, alen - len);
- err = write_leb(c, lnum++, alen, buf);
- if (err)
- goto out;
- p = buf;
- len = 0;
- }
- /* The root is on row zero */
- if (row == 0) {
- c->lpt_lnum = lnum;
- c->lpt_offs = len;
- }
- /* Set branches to the level below */
- for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
- if (bcnt) {
- if (boffs + bsz > c->leb_size) {
- blnum += 1;
- boffs = 0;
- }
- nnode->nbranch[j].lnum = blnum;
- nnode->nbranch[j].offs = boffs;
- boffs += bsz;
- bcnt--;
- } else {
- nnode->nbranch[j].lnum = 0;
- nnode->nbranch[j].offs = 0;
- }
- }
- nnode->num = calc_nnode_num(row, i);
- pack_nnode(c, p, nnode);
- p += c->nnode_sz;
- len += c->nnode_sz;
- }
- /* Row zero is the top row */
- if (row == 0)
- break;
- /* Update the information about the level below */
- bcnt = cnt;
- bsz = c->nnode_sz;
- row -= 1;
- }
-
- if (c->big_lpt) {
- /* Need to add LPT's save table */
- if (len + c->lsave_sz > c->leb_size) {
- alen = ALIGN(len, c->min_io_size);
- set_ltab(c, lnum, c->leb_size - alen, alen - len);
- memset(p, 0xff, alen - len);
- err = write_leb(c, lnum++, alen, buf);
- if (err)
- goto out;
- p = buf;
- len = 0;
- }
-
- c->lsave_lnum = lnum;
- c->lsave_offs = len;
-
- for (i = 0; i < c->lsave_cnt; i++)
- lsave[i] = c->main_first + i;
-
- pack_lsave(c, p, lsave);
- p += c->lsave_sz;
- len += c->lsave_sz;
- }
-
- /* Need to add LPT's own LEB properties table */
- if (len + c->ltab_sz > c->leb_size) {
- alen = ALIGN(len, c->min_io_size);
- set_ltab(c, lnum, c->leb_size - alen, alen - len);
- memset(p, 0xff, alen - len);
- err = write_leb(c, lnum++, alen, buf);
- if (err)
- goto out;
- p = buf;
- len = 0;
- }
-
- c->ltab_lnum = lnum;
- c->ltab_offs = len;
-
- /* Update ltab before packing it */
- len += c->ltab_sz;
- alen = ALIGN(len, c->min_io_size);
- set_ltab(c, lnum, c->leb_size - alen, alen - len);
-
- pack_ltab(c, p, c->ltab);
- p += c->ltab_sz;
-
- /* Write remaining buffer */
- memset(p, 0xff, alen - len);
- err = write_leb(c, lnum, alen, buf);
- if (err)
- goto out;
-
- c->nhead_lnum = lnum;
- c->nhead_offs = ALIGN(len, c->min_io_size);
-
- pr_debug("lpt_sz: %lld\n", c->lpt_sz);
- pr_debug("space_bits: %d\n", c->space_bits);
- pr_debug("lpt_lnum_bits: %d\n", c->lpt_lnum_bits);
- pr_debug("lpt_offs_bits: %d\n", c->lpt_offs_bits);
- pr_debug("lpt_spc_bits: %d\n", c->lpt_spc_bits);
- pr_debug("pcnt_bits: %d\n", c->pcnt_bits);
- pr_debug("lnum_bits: %d\n", c->lnum_bits);
- pr_debug("pnode_sz: %d\n", c->pnode_sz);
- pr_debug("nnode_sz: %d\n", c->nnode_sz);
- pr_debug("ltab_sz: %d\n", c->ltab_sz);
- pr_debug("lsave_sz: %d\n", c->lsave_sz);
- pr_debug("lsave_cnt: %d\n", c->lsave_cnt);
- pr_debug("lpt_hght: %d\n", c->lpt_hght);
- pr_debug("big_lpt: %d\n", c->big_lpt);
- pr_debug("LPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
- pr_debug("LPT head is at %d:%d\n", c->nhead_lnum, c->nhead_offs);
- pr_debug("LPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs);
- if (c->big_lpt)
- pr_debug("LPT lsave is at %d:%d\n",
- c->lsave_lnum, c->lsave_offs);
-out:
- free(lsave);
- free(buf);
- free(nnode);
- free(pnode);
- return err;
-}
diff --git a/ubifs-utils/common/lpt.h b/ubifs-utils/common/lpt.h
deleted file mode 100644
index 86148a2..0000000
--- a/ubifs-utils/common/lpt.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- * Adrian Hunter
- */
-
-#ifndef __UBIFS_LPT_H__
-#define __UBIFS_LPT_H__
-
-#include "ubifs.h"
-
-int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt);
-int create_lpt(struct ubifs_info *c);
-
-#endif
diff --git a/ubifs-utils/common/sign.c b/ubifs-utils/common/sign.c
index dfbc96b..032a6ac 100644
--- a/ubifs-utils/common/sign.c
+++ b/ubifs-utils/common/sign.c
@@ -30,8 +30,8 @@
#include "linux_types.h"
#include "sign.h"
-#include "defs.h"
#include "ubifs.h"
+#include "defs.h"
extern struct ubifs_info info_;
static struct ubifs_info *c = &info_;
@@ -39,11 +39,6 @@ static struct ubifs_info *c = &info_;
EVP_MD_CTX *hash_md;
const EVP_MD *md;
-int authenticated(void)
-{
- return c->hash_algo_name != NULL;
-}
-
static int match_string(const char * const *array, size_t n, const char *string)
{
int index;
@@ -242,36 +237,32 @@ out:
return x509;
}
-int sign_superblock_node(void *node)
+int hash_sign_node(const char *auth_key_filename, const char *auth_cert_filename,
+ void *buf, int *len, void *outbuf)
{
EVP_PKEY *private_key;
CMS_ContentInfo *cms = NULL;
X509 *cert = NULL;
BIO *bd, *bm;
void *obuf;
- long len;
int ret;
void *pret;
- struct ubifs_sig_node *sig = node + UBIFS_SB_NODE_SZ;
-
- if (!authenticated())
- return 0;
ERR_load_crypto_strings();
ERR_clear_error();
key_pass = getenv("MKFS_UBIFS_SIGN_PIN");
- bm = BIO_new_mem_buf(node, UBIFS_SB_NODE_SZ);
+ bm = BIO_new_mem_buf(buf, UBIFS_SB_NODE_SZ);
- private_key = read_private_key(c->auth_key_filename, &cert);
+ private_key = read_private_key(auth_key_filename, &cert);
if (!private_key)
return -1;
if (!cert) {
- if (!c->auth_cert_filename)
+ if (!auth_cert_filename)
return errmsg("authentication certificate not provided (--auth-cert)");
- cert = read_x509(c->auth_cert_filename);
+ cert = read_x509(auth_cert_filename);
}
if (!cert)
@@ -302,13 +293,9 @@ int sign_superblock_node(void *node)
if (!ret)
return errmsg("i2d_CMS_bio_stream failed");
- len = BIO_get_mem_data(bd, &obuf);
-
- sig->type = UBIFS_SIGNATURE_TYPE_PKCS7;
- sig->len = cpu_to_le32(len);
- sig->ch.node_type = UBIFS_SIG_NODE;
+ *len = BIO_get_mem_data(bd, &obuf);
- memcpy(sig + 1, obuf, len);
+ memcpy(outbuf, obuf, *len);
BIO_free(bd);
BIO_free(bm);
@@ -316,83 +303,61 @@ int sign_superblock_node(void *node)
return 0;
}
-/**
- * ubifs_node_calc_hash - calculate the hash of a UBIFS node
- * @c: UBIFS file-system description object
- * @node: the node to calculate a hash for
- * @hash: the returned hash
- */
-void ubifs_node_calc_hash(const void *node, uint8_t *hash)
+int hash_digest(const void *buf, unsigned int len, uint8_t *hash)
{
- const struct ubifs_ch *ch = node;
+ int err;
unsigned int md_len;
- if (!authenticated())
- return;
+ err = EVP_DigestInit_ex(hash_md, md, NULL);
+ if (!err)
+ return errmsg("Init hash digest failed");
+ err = EVP_DigestUpdate(hash_md, buf, len);
+ if (!err)
+ return errmsg("Update hash digest failed");
+ err = EVP_DigestFinal_ex(hash_md, hash, &md_len);
+ if (!err)
+ return errmsg("Finalize hash digest failed");
- EVP_DigestInit_ex(hash_md, md, NULL);
- EVP_DigestUpdate(hash_md, node, le32_to_cpu(ch->len));
- EVP_DigestFinal_ex(hash_md, hash, &md_len);
+ return 0;
}
-/**
- * mst_node_calc_hash - calculate the hash of a UBIFS master node
- * @c: UBIFS file-system description object
- * @node: the node to calculate a hash for
- * @hash: the returned hash
- */
-void mst_node_calc_hash(const void *node, uint8_t *hash)
+int hash_digest_init(void)
{
- unsigned int md_len;
+ int err;
- if (!authenticated())
- return;
+ err = EVP_DigestInit_ex(hash_md, md, NULL);
+ if (!err)
+ return errmsg("Init hash digest failed");
- EVP_DigestInit_ex(hash_md, md, NULL);
- EVP_DigestUpdate(hash_md, node + sizeof(struct ubifs_ch),
- UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch));
- EVP_DigestFinal_ex(hash_md, hash, &md_len);
+ return 0;
}
-void hash_digest_init(void)
+int hash_digest_update(const void *buf, int len)
{
- if (!authenticated())
- return;
-
- EVP_DigestInit_ex(hash_md, md, NULL);
-}
+ int err;
-void hash_digest_update(const void *buf, int len)
-{
- if (!authenticated())
- return;
+ err = EVP_DigestUpdate(hash_md, buf, len);
+ if (!err)
+ return errmsg("Update hash digest failed");
- EVP_DigestUpdate(hash_md, buf, len);
+ return 0;
}
-void hash_digest_final(void *hash, unsigned int *len)
+int hash_digest_final(void *hash)
{
- if (!authenticated())
- return;
+ int err;
+ unsigned int md_len;
+
+ err = EVP_DigestFinal_ex(hash_md, hash, &md_len);
+ if (!err)
+ return errmsg("Finalize hash digest failed");
- EVP_DigestFinal_ex(hash_md, hash, len);
+ return 0;
}
-int init_authentication(void)
+int init_authentication(const char *algo_name, int *hash_len, int *hash_algo)
{
- int hash_algo;
-
- if (!c->auth_key_filename && !c->auth_cert_filename && !c->hash_algo_name)
- return 0;
-
- if (!c->auth_key_filename)
- return errmsg("authentication key not given (--auth-key)");
-
- if (!c->hash_algo_name)
- return errmsg("Hash algorithm not given (--hash-algo)");
-
OPENSSL_config(NULL);
-
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
@@ -401,13 +366,30 @@ int init_authentication(void)
return errmsg("Unknown message digest %s", c->hash_algo_name);
hash_md = EVP_MD_CTX_create();
- c->hash_len = EVP_MD_size(md);
-
- hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST, c->hash_algo_name);
- if (hash_algo < 0)
- return errmsg("Unsupported message digest %s", c->hash_algo_name);
+ if (!hash_md)
+ return errmsg("Cannot create md ctx");
+
+ *hash_len = EVP_MD_size(md);
+ if (*hash_len < 0) {
+ EVP_MD_CTX_destroy(hash_md);
+ hash_md = NULL;
+ return errmsg("Cannot init hash len");
+ }
- c->hash_algo = hash_algo;
+ *hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST, algo_name);
+ if (*hash_algo < 0) {
+ EVP_MD_CTX_destroy(hash_md);
+ hash_md = NULL;
+ return errmsg("Unsupported message digest %s", algo_name);
+ }
return 0;
}
+
+void exit_authentication(void)
+{
+ if (hash_md) {
+ EVP_MD_CTX_destroy(hash_md);
+ hash_md = NULL;
+ }
+}
diff --git a/ubifs-utils/common/sign.h b/ubifs-utils/common/sign.h
index fe9fdd8..f49c76a 100644
--- a/ubifs-utils/common/sign.h
+++ b/ubifs-utils/common/sign.h
@@ -20,61 +20,20 @@
#ifndef __UBIFS_SIGN_H__
#define __UBIFS_SIGN_H__
-#ifdef WITH_CRYPTO
#include <openssl/evp.h>
-void ubifs_node_calc_hash(const void *node, uint8_t *hash);
-void mst_node_calc_hash(const void *node, uint8_t *hash);
-void hash_digest_init(void);
-void hash_digest_update(const void *buf, int len);
-void hash_digest_final(void *hash, unsigned int *len);
-int init_authentication(void);
-int sign_superblock_node(void *node);
-int authenticated(void);
-
-extern EVP_MD_CTX *hash_md;
-extern const EVP_MD *md;
-
-#else
-static inline void ubifs_node_calc_hash(__attribute__((unused)) const void *node,
- __attribute__((unused)) uint8_t *hash)
-{
-}
-
-static inline void mst_node_calc_hash(__attribute__((unused)) const void *node,
- __attribute__((unused)) uint8_t *hash)
-{
-}
-
-static inline void hash_digest_init(void)
-{
-}
-
-static inline void hash_digest_update(__attribute__((unused)) const void *buf,
- __attribute__((unused)) int len)
-{
-}
+struct shash_desc {
+ void *ctx;
+};
-static inline void hash_digest_final(__attribute__((unused)) void *hash,
- __attribute__((unused)) unsigned int *len)
-{
-}
-
-static inline int init_authentication(void)
-{
- return 0;
-}
-
-static inline int sign_superblock_node(__attribute__((unused)) void *node)
-{
- return 0;
-}
-
-static inline int authenticated(void)
-{
- return 0;
-}
-
-#endif
+int hash_digest(const void *buf, unsigned int len, uint8_t *hash);
+int hash_digest_init(void);
+int hash_digest_update(const void *buf, int len);
+int hash_digest_final(void *hash);
+int init_authentication(const char *algo_name, int *hash_len, int *hash_algo);
+void exit_authentication(void);
+void mst_node_calc_hash(const void *node, uint8_t *hash);
+int hash_sign_node(const char *auth_key_filename, const char *auth_cert_filename,
+ void *buf, int *len, void *outbuf);
#endif /* __UBIFS_SIGN_H__ */
diff --git a/ubifs-utils/common/super.c b/ubifs-utils/common/super.c
deleted file mode 100644
index eee0197..0000000
--- a/ubifs-utils/common/super.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "defs.h"
-
-/**
- * open_ubi - open the libubi.
- * @c: the UBIFS file-system description object
- * @node: name of the UBI volume character device to fetch information about
- *
- * This function opens libubi, and initialize device & volume information
- * according to @node. Returns %0 in case of success and %-1 in case of failure.
- */
-int open_ubi(struct ubifs_info *c, const char *node)
-{
- struct stat st;
-
- if (stat(node, &st) || !S_ISCHR(st.st_mode))
- return -1;
-
- c->libubi = libubi_open();
- if (!c->libubi)
- return -1;
- if (ubi_get_vol_info(c->libubi, node, &c->vi))
- goto out_err;
- if (ubi_get_dev_info1(c->libubi, c->vi.dev_num, &c->di))
- goto out_err;
-
- return 0;
-
-out_err:
- close_ubi(c);
- return -1;
-}
-
-void close_ubi(struct ubifs_info *c)
-{
- if (c->libubi) {
- libubi_close(c->libubi);
- c->libubi = NULL;
- }
-}
-
-/**
- * open_target - open the output target.
- * @c: the UBIFS file-system description object
- *
- * Open the output target. The target can be an UBI volume
- * or a file.
- *
- * Returns %0 in case of success and %-1 in case of failure.
- */
-int open_target(struct ubifs_info *c)
-{
- if (c->libubi) {
- c->dev_fd = open(c->dev_name, O_RDWR | O_EXCL);
-
- if (c->dev_fd == -1)
- return sys_errmsg("cannot open the UBI volume '%s'",
- c->dev_name);
- if (ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 1)) {
- close(c->dev_fd);
- return sys_errmsg("ubi_set_property(set direct_write) failed");
- }
- } else {
- c->dev_fd = open(c->dev_name, O_CREAT | O_RDWR | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
- if (c->dev_fd == -1)
- return sys_errmsg("cannot create output file '%s'",
- c->dev_name);
- }
- return 0;
-}
-
-
-/**
- * close_target - close the output target.
- * @c: the UBIFS file-system description object
- *
- * Close the output target. If the target was an UBI
- * volume, also close libubi.
- *
- * Returns %0 in case of success and %-1 in case of failure.
- */
-int close_target(struct ubifs_info *c)
-{
- if (c->dev_fd >= 0) {
- if (c->libubi && ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 0))
- return sys_errmsg("ubi_set_property(clear direct_write) failed");
- if (close(c->dev_fd) == -1)
- return sys_errmsg("cannot close the target '%s'", c->dev_name);
- }
- return 0;
-}
-
-/**
- * check_volume_empty - check if the UBI volume is empty.
- * @c: the UBIFS file-system description object
- *
- * This function checks if the UBI volume is empty by looking if its LEBs are
- * mapped or not.
- *
- * Returns %0 in case of success, %1 is the volume is not empty,
- * and a negative error code in case of failure.
- */
-int check_volume_empty(struct ubifs_info *c)
-{
- int lnum, err;
-
- for (lnum = 0; lnum < c->vi.rsvd_lebs; lnum++) {
- err = ubi_is_mapped(c->dev_fd, lnum);
- if (err < 0)
- return err;
- if (err == 1)
- return 1;
- }
- return 0;
-}
diff --git a/ubifs-utils/common/ubifs.h b/ubifs-utils/common/ubifs.h
deleted file mode 100644
index ed297cc..0000000
--- a/ubifs-utils/common/ubifs.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- * Adrian Hunter
- * Zoltan Sogor
- */
-
-#ifndef __UBIFS_H__
-#define __UBIFS_H__
-
-#include "ubifs-media.h"
-#include "libubi.h"
-
-/* Maximum logical eraseblock size in bytes */
-#define UBIFS_MAX_LEB_SZ (2*1024*1024)
-
-/* Minimum amount of data UBIFS writes to the flash */
-#define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8)
-
-/* Largest key size supported in this implementation */
-#define CUR_MAX_KEY_LEN UBIFS_SK_LEN
-
-/*
- * There is no notion of truncation key because truncation nodes do not exist
- * in TNC. However, when replaying, it is handy to introduce fake "truncation"
- * keys for truncation nodes because the code becomes simpler. So we define
- * %UBIFS_TRUN_KEY type.
- */
-#define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT
-
-/*
- * How much a directory entry/extended attribute entry adds to the parent/host
- * inode.
- */
-#define CALC_DENT_SIZE(name_len) ALIGN(UBIFS_DENT_NODE_SZ + (name_len) + 1, 8)
-
-/* How much an extended attribute adds to the host inode */
-#define CALC_XATTR_BYTES(data_len) ALIGN(UBIFS_INO_NODE_SZ + (data_len) + 1, 8)
-
-/* The below union makes it easier to deal with keys */
-union ubifs_key
-{
- uint8_t u8[CUR_MAX_KEY_LEN];
- uint32_t u32[CUR_MAX_KEY_LEN/4];
- uint64_t u64[CUR_MAX_KEY_LEN/8];
- __le32 j32[CUR_MAX_KEY_LEN/4];
-};
-
-/*
- * LEB properties flags.
- *
- * LPROPS_UNCAT: not categorized
- * LPROPS_DIRTY: dirty > 0, not index
- * LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and index
- * LPROPS_FREE: free > 0, not empty, not index
- * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs
- * LPROPS_EMPTY: LEB is empty, not taken
- * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken
- * LPROPS_FRDI_IDX: free + dirty == leb_size and index, may be taken
- * LPROPS_CAT_MASK: mask for the LEB categories above
- * LPROPS_TAKEN: LEB was taken (this flag is not saved on the media)
- * LPROPS_INDEX: LEB contains indexing nodes (this flag also exists on flash)
- */
-enum {
- LPROPS_UNCAT = 0,
- LPROPS_DIRTY = 1,
- LPROPS_DIRTY_IDX = 2,
- LPROPS_FREE = 3,
- LPROPS_HEAP_CNT = 3,
- LPROPS_EMPTY = 4,
- LPROPS_FREEABLE = 5,
- LPROPS_FRDI_IDX = 6,
- LPROPS_CAT_MASK = 15,
- LPROPS_TAKEN = 16,
- LPROPS_INDEX = 32,
-};
-
-/**
- * struct ubifs_lprops - logical eraseblock properties.
- * @free: amount of free space in bytes
- * @dirty: amount of dirty space in bytes
- * @flags: LEB properties flags (see above)
- */
-struct ubifs_lprops
-{
- int free;
- int dirty;
- int flags;
-};
-
-/**
- * struct ubifs_lpt_lprops - LPT logical eraseblock properties.
- * @free: amount of free space in bytes
- * @dirty: amount of dirty space in bytes
- */
-struct ubifs_lpt_lprops
-{
- int free;
- int dirty;
-};
-
-struct ubifs_nnode;
-
-/**
- * struct ubifs_cnode - LEB Properties Tree common node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (zero for pnodes, greater than zero for nnodes)
- * @num: node number
- */
-struct ubifs_cnode
-{
- struct ubifs_nnode *parent;
- struct ubifs_cnode *cnext;
- unsigned long flags;
- int iip;
- int level;
- int num;
-};
-
-/**
- * struct ubifs_pnode - LEB Properties Tree leaf node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (always zero for pnodes)
- * @num: node number
- * @lprops: LEB properties array
- */
-struct ubifs_pnode
-{
- struct ubifs_nnode *parent;
- struct ubifs_cnode *cnext;
- unsigned long flags;
- int iip;
- int level;
- int num;
- struct ubifs_lprops lprops[UBIFS_LPT_FANOUT];
-};
-
-/**
- * struct ubifs_nbranch - LEB Properties Tree internal node branch.
- * @lnum: LEB number of child
- * @offs: offset of child
- * @nnode: nnode child
- * @pnode: pnode child
- * @cnode: cnode child
- */
-struct ubifs_nbranch
-{
- int lnum;
- int offs;
- union
- {
- struct ubifs_nnode *nnode;
- struct ubifs_pnode *pnode;
- struct ubifs_cnode *cnode;
- };
-};
-
-/**
- * struct ubifs_nnode - LEB Properties Tree internal node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (always greater than zero for nnodes)
- * @num: node number
- * @nbranch: branches to child nodes
- */
-struct ubifs_nnode
-{
- struct ubifs_nnode *parent;
- struct ubifs_cnode *cnext;
- unsigned long flags;
- int iip;
- int level;
- int num;
- struct ubifs_nbranch nbranch[UBIFS_LPT_FANOUT];
-};
-
-/**
- * struct ubifs_lp_stats - statistics of eraseblocks in the main area.
- * @empty_lebs: number of empty LEBs
- * @taken_empty_lebs: number of taken LEBs
- * @idx_lebs: number of indexing LEBs
- * @total_free: total free space in bytes
- * @total_dirty: total dirty space in bytes
- * @total_used: total used space in bytes (includes only data LEBs)
- * @total_dead: total dead space in bytes (includes only data LEBs)
- * @total_dark: total dark space in bytes (includes only data LEBs)
- */
-struct ubifs_lp_stats {
- int empty_lebs;
- int taken_empty_lebs;
- int idx_lebs;
- long long total_free;
- long long total_dirty;
- long long total_used;
- long long total_dead;
- long long total_dark;
-};
-
-/**
- * struct ubifs_zbranch - key/coordinate/length branch stored in znodes.
- * @key: key
- * @znode: znode address in memory
- * @lnum: LEB number of the indexing node
- * @offs: offset of the indexing node within @lnum
- * @len: target node length
- */
-struct ubifs_zbranch
-{
- union ubifs_key key;
- struct ubifs_znode *znode;
- int lnum;
- int offs;
- int len;
-};
-
-/**
- * struct ubifs_znode - in-memory representation of an indexing node.
- * @parent: parent znode or NULL if it is the root
- * @cnext: next znode to commit
- * @flags: flags
- * @time: last access time (seconds)
- * @level: level of the entry in the TNC tree
- * @child_cnt: count of child znodes
- * @iip: index in parent's zbranch array
- * @alt: lower bound of key range has altered i.e. child inserted at slot 0
- * @zbranch: array of znode branches (@c->fanout elements)
- */
-struct ubifs_znode
-{
- struct ubifs_znode *parent;
- struct ubifs_znode *cnext;
- unsigned long flags;
- unsigned long time;
- int level;
- int child_cnt;
- int iip;
- int alt;
-#ifdef CONFIG_UBIFS_FS_DEBUG
- int lnum, offs, len;
-#endif
- struct ubifs_zbranch zbranch[];
-};
-
-/**
- * struct ubifs_info - UBIFS file-system description data structure
- * (per-superblock).
- *
- * @highest_inum: highest used inode number
- * @max_sqnum: current global sequence number
- *
- * @debug_level: level of debug messages, 0 - none, 1 - statistics,
- * 2 - files, 3 - more details
- * @program_type: used to identify the type of current program
- * @program_name: program name
- * @dev_name: device name
- * @dev_fd: opening handler for an UBI volume or an image file
- * @libubi: opening handler for libubi
- *
- * @jhead_cnt: count of journal heads
- * @max_bud_bytes: maximum number of bytes allowed in buds
- *
- * @zroot: zbranch which points to the root index node and znode
- * @ihead_lnum: LEB number of index head
- * @ihead_offs: offset of index head
- *
- * @log_lebs: number of logical eraseblocks in the log
- * @lpt_lebs: number of LEBs used for lprops table
- * @lpt_first: first LEB of the lprops table area
- * @lpt_last: last LEB of the lprops table area
- * @main_lebs: count of LEBs in the main area
- * @main_first: first LEB of the main area
- * @default_compr: default compression type
- * @favor_lzo: favor LZO compression method
- * @favor_percent: lzo vs. zlib threshold used in case favor LZO
- *
- * @key_hash_type: type of the key hash
- * @key_hash: direntry key hash function
- * @key_fmt: key format
- * @key_len: key length
- * @fanout: fanout of the index tree (number of links per indexing node)
- *
- * @min_io_size: minimal input/output unit size
- * @leb_size: logical eraseblock size in bytes
- * @leb_cnt: count of logical eraseblocks
- * @max_leb_cnt: maximum count of logical eraseblocks
- *
- * @old_idx_sz: size of index on flash
- * @lst: lprops statistics
- *
- * @dead_wm: LEB dead space watermark
- * @dark_wm: LEB dark space watermark
- *
- * @di: UBI device information
- * @vi: UBI volume information
- *
- * @gc_lnum: LEB number used for garbage collection
- * @rp_size: reserved pool size
- *
- * @space_bits: number of bits needed to record free or dirty space
- * @lpt_lnum_bits: number of bits needed to record a LEB number in the LPT
- * @lpt_offs_bits: number of bits needed to record an offset in the LPT
- * @lpt_spc_bits: number of bits needed to space in the LPT
- * @pcnt_bits: number of bits needed to record pnode or nnode number
- * @lnum_bits: number of bits needed to record LEB number
- * @nnode_sz: size of on-flash nnode
- * @pnode_sz: size of on-flash pnode
- * @ltab_sz: size of on-flash LPT lprops table
- * @lsave_sz: size of on-flash LPT save table
- * @pnode_cnt: number of pnodes
- * @nnode_cnt: number of nnodes
- * @lpt_hght: height of the LPT
- *
- * @lpt_lnum: LEB number of the root nnode of the LPT
- * @lpt_offs: offset of the root nnode of the LPT
- * @nhead_lnum: LEB number of LPT head
- * @nhead_offs: offset of LPT head
- * @big_lpt: flag that LPT is too big to write whole during commit
- * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up
- * @double_hash: flag indicating that we can do lookups by hash
- * @lpt_sz: LPT size
- *
- * @ltab_lnum: LEB number of LPT's own lprops table
- * @ltab_offs: offset of LPT's own lprops table
- * @lpt: lprops table
- * @ltab: LPT's own lprops table
- * @lsave_cnt: number of LEB numbers in LPT's save table
- * @lsave_lnum: LEB number of LPT's save table
- * @lsave_offs: offset of LPT's save table
- * @lsave: LPT's save table
- * @lscan_lnum: LEB number of last LPT scan
- *
- * @hash_algo_name: the name of the hashing algorithm to use
- * @hash_algo: The hash algo number (from include/linux/hash_info.h)
- * @auth_key_filename: authentication key file name
- * @x509_filename: x509 certificate file name for authentication
- * @hash_len: the length of the hash
- * @root_idx_hash: The hash of the root index node
- * @lpt_hash: The hash of the LPT
- * @mst_hash: The hash of the master node
- */
-struct ubifs_info
-{
- ino_t highest_inum;
- unsigned long long max_sqnum;
-
- int debug_level;
- int program_type;
- const char *program_name;
- char *dev_name;
- int dev_fd;
- libubi_t libubi;
-
- int jhead_cnt;
- long long max_bud_bytes;
-
- struct ubifs_zbranch zroot;
- int ihead_lnum;
- int ihead_offs;
-
- int log_lebs;
- int lpt_lebs;
- int lpt_first;
- int lpt_last;
- int orph_lebs;
- int main_lebs;
- int main_first;
- int default_compr;
- int favor_lzo;
- int favor_percent;
-
- uint8_t key_hash_type;
- uint32_t (*key_hash)(const char *str, int len);
- int key_fmt;
- int key_len;
- int fanout;
-
- int min_io_size;
- int leb_size;
- int leb_cnt;
- int max_leb_cnt;
-
- unsigned long long old_idx_sz;
- struct ubifs_lp_stats lst;
-
- int dead_wm;
- int dark_wm;
-
- struct ubi_dev_info di;
- struct ubi_vol_info vi;
-
- int gc_lnum;
- long long rp_size;
-
- int space_bits;
- int lpt_lnum_bits;
- int lpt_offs_bits;
- int lpt_spc_bits;
- int pcnt_bits;
- int lnum_bits;
- int nnode_sz;
- int pnode_sz;
- int ltab_sz;
- int lsave_sz;
- int pnode_cnt;
- int nnode_cnt;
- int lpt_hght;
-
- int lpt_lnum;
- int lpt_offs;
- int nhead_lnum;
- int nhead_offs;
- int big_lpt;
- int space_fixup;
- int double_hash;
- int encrypted;
- long long lpt_sz;
-
- int ltab_lnum;
- int ltab_offs;
- struct ubifs_lprops *lpt;
- struct ubifs_lpt_lprops *ltab;
- int lsave_cnt;
- int lsave_lnum;
- int lsave_offs;
- int *lsave;
- int lscan_lnum;
-
- char *hash_algo_name;
- int hash_algo;
- char *auth_key_filename;
- char *auth_cert_filename;
- int hash_len;
- uint8_t root_idx_hash[UBIFS_MAX_HASH_LEN];
- uint8_t lpt_hash[UBIFS_MAX_HASH_LEN];
- uint8_t mst_hash[UBIFS_MAX_HASH_LEN];
-};
-
-/**
- * ubifs_idx_node_sz - return index node size.
- * @c: the UBIFS file-system description object
- * @child_cnt: number of children of this index node
- */
-static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt)
-{
- return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len + c->hash_len)
- * child_cnt;
-}
-
-/**
- * ubifs_idx_branch - return pointer to an index branch.
- * @c: the UBIFS file-system description object
- * @idx: index node
- * @bnum: branch number
- */
-static inline
-struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c,
- const struct ubifs_idx_node *idx,
- int bnum)
-{
- return (struct ubifs_branch *)((void *)idx->branches +
- (UBIFS_BRANCH_SZ + c->key_len + c->hash_len) * bnum);
-}
-
-int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
-
-/* super.c */
-int open_ubi(struct ubifs_info *c, const char *node);
-void close_ubi(struct ubifs_info *c);
-int open_target(struct ubifs_info *c);
-int close_target(struct ubifs_info *c);
-int check_volume_empty(struct ubifs_info *c);
-
-#endif /* __UBIFS_H__ */