diff options
author | Zhihao Cheng <chengzhihao1@huawei.com> | 2024-11-11 17:01:00 +0800 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2024-11-11 10:32:45 +0100 |
commit | 665c44e7c9135a58847ab0773fc7977929d1497c (patch) | |
tree | b66859f364d9bafc2d9bd0d19c5d4a42cf72e8c4 /ubifs-utils/mkfs.ubifs | |
parent | 2ac2e90cca9528147969d21378f8a736db710e35 (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/mkfs.ubifs')
-rw-r--r-- | ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 236 |
1 files changed, 74 insertions, 162 deletions
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c index fb99222..2817b6c 100644 --- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c +++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c @@ -46,15 +46,15 @@ #include <zstd.h> #endif -#include "linux_types.h" -#include "defs.h" +#include "bitops.h" #include "crypto.h" #include "fscrypt.h" #include "ubifs.h" -#include "lpt.h" -#include "compr.h" +#include "defs.h" +#include "debug.h" #include "key.h" -#include "sign.h" +#include "compr.h" +#include "misc.h" #include "devtable.h" /* Size (prime number) of hash table for link counting */ @@ -291,11 +291,6 @@ static const char *helptext = "mkfs.ubifs supports building signed images. For this the \"--hash-algo\",\n" "\"--auth-key\" and \"--auth-cert\" options have to be specified.\n"; -static inline uint8_t *ubifs_branch_hash(struct ubifs_branch *br) -{ - return (void *)br + sizeof(*br) + c->key_len; -} - /** * make_path - make a path name from a directory and a name. * @dir: directory path name @@ -914,97 +909,13 @@ static int get_options(int argc, char**argv) } /** - * prepare_node - fill in the common header. - * @node: node - * @len: node length - */ -static void prepare_node(void *node, int len) -{ - uint32_t crc; - struct ubifs_ch *ch = node; - - ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); - ch->len = cpu_to_le32(len); - ch->group_type = UBIFS_NO_NODE_GROUP; - ch->sqnum = cpu_to_le64(++c->max_sqnum); - ch->padding[0] = ch->padding[1] = 0; - crc = mtd_crc32(UBIFS_CRC32_INIT, node + 8, len - 8); - ch->crc = cpu_to_le32(crc); -} - -/** - * write_leb - copy the image of a LEB to the output target. - * @c: the UBIFS file-system description object - * @lnum: LEB number - * @len: length of data in the buffer - * @buf: buffer (must be at least c->leb_size bytes) - */ -int write_leb(struct ubifs_info *c, int lnum, int len, void *buf) -{ - off_t pos = (off_t)lnum * c->leb_size; - - pr_debug("LEB %d len %d\n", lnum, len); - memset(buf + len, 0xff, c->leb_size - len); - if (c->libubi) - if (ubi_leb_change_start(c->libubi, c->dev_fd, lnum, c->leb_size)) - return sys_errmsg("ubi_leb_change_start failed"); - - if (lseek(c->dev_fd, pos, SEEK_SET) != pos) - return sys_errmsg("lseek failed seeking %lld", (long long)pos); - - if (write(c->dev_fd, buf, c->leb_size) != c->leb_size) - return sys_errmsg("write failed writing %d bytes at pos %lld", - c->leb_size, (long long)pos); - - return 0; -} - -/** * write_empty_leb - copy the image of an empty LEB to the output target. * @lnum: LEB number */ static int write_empty_leb(int lnum) { - return write_leb(c, lnum, 0, leb_buf); -} - -/** - * do_pad - pad a buffer to the minimum I/O size. - * @buf: buffer - * @len: buffer length - */ -static int do_pad(void *buf, int len) -{ - int pad_len, alen = ALIGN(len, 8), wlen = ALIGN(alen, c->min_io_size); - uint32_t crc; - - memset(buf + len, 0xff, alen - len); - pad_len = wlen - alen; - pr_debug("len %d pad_len %d\n", len, pad_len); - buf += alen; - if (pad_len >= (int)UBIFS_PAD_NODE_SZ) { - struct ubifs_ch *ch = buf; - struct ubifs_pad_node *pad_node = buf; - - ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); - ch->node_type = UBIFS_PAD_NODE; - ch->group_type = UBIFS_NO_NODE_GROUP; - ch->padding[0] = ch->padding[1] = 0; - ch->sqnum = cpu_to_le64(0); - ch->len = cpu_to_le32(UBIFS_PAD_NODE_SZ); - - pad_len -= UBIFS_PAD_NODE_SZ; - pad_node->pad_len = cpu_to_le32(pad_len); - - crc = mtd_crc32(UBIFS_CRC32_INIT, buf + 8, - UBIFS_PAD_NODE_SZ - 8); - ch->crc = cpu_to_le32(crc); - - memset(buf + UBIFS_PAD_NODE_SZ, 0, pad_len); - } else if (pad_len > 0) - memset(buf, UBIFS_PADDING_BYTE, pad_len); - - return wlen; + memset(leb_buf, 0xff, c->leb_size); + return ubifs_leb_change(c, lnum, leb_buf, c->leb_size); } /** @@ -1015,13 +926,16 @@ static int do_pad(void *buf, int len) */ static int write_node(void *node, int len, int lnum) { - prepare_node(node, len); + int alen = ALIGN(len, 8), wlen = ALIGN(len, c->min_io_size); + ubifs_prepare_node(c, node, len, 0); memcpy(leb_buf, node, len); + memset(leb_buf + len, 0xff, alen - len); + ubifs_pad(c, leb_buf + alen, wlen - alen); - len = do_pad(leb_buf, len); + memset(leb_buf + wlen, 0xff, c->leb_size - wlen); - return write_leb(c, lnum, len, leb_buf); + return ubifs_leb_change(c, lnum, leb_buf, c->leb_size); } /** @@ -1133,8 +1047,10 @@ static int flush_nodes(void) if (!head_offs) return 0; - len = do_pad(leb_buf, head_offs); - err = write_leb(c, head_lnum, len, leb_buf); + len = ALIGN(head_offs, c->min_io_size); + ubifs_pad(c, leb_buf + head_offs, len - head_offs); + memset(leb_buf + len, 0xff, c->leb_size - len); + err = ubifs_leb_change(c, head_lnum, leb_buf, c->leb_size); if (err) return err; set_lprops(head_lnum, head_offs, head_flags); @@ -1172,7 +1088,7 @@ static int reserve_space(int len, int *lnum, int *offs) */ static int add_node(union ubifs_key *key, char *name, int name_len, void *node, int len) { - int err, lnum, offs, type = key_type(key); + int err, lnum, offs, type = key_type(c, key); uint8_t hash[UBIFS_MAX_HASH_LEN]; if (type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY) { @@ -1184,7 +1100,7 @@ static int add_node(union ubifs_key *key, char *name, int name_len, void *node, return errmsg("Name given for non dir/xattr node!"); } - prepare_node(node, len); + ubifs_prepare_node(c, node, len, 0); err = reserve_space(len, &lnum, &offs); if (err) @@ -1193,7 +1109,7 @@ static int add_node(union ubifs_key *key, char *name, int name_len, void *node, memcpy(leb_buf + offs, node, len); memset(leb_buf + offs + len, 0xff, ALIGN(len, 8) - len); - ubifs_node_calc_hash(node, hash); + ubifs_node_calc_hash(c, node, hash); add_to_index(key, name, name_len, lnum, offs, len, hash); @@ -1206,43 +1122,43 @@ static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, { struct ubifs_ino_node *ino; struct ubifs_dent_node *xent; - struct qstr nm; + struct fscrypt_name nm; char *tmp_name; union ubifs_key xkey, nkey; int len, ret; - nm.len = strlen(name); - tmp_name = xmalloc(nm.len + 1); - memcpy(tmp_name, name, nm.len + 1); - nm.name = tmp_name; + fname_len(&nm) = strlen(name); + tmp_name = xmalloc(fname_len(&nm) + 1); + memcpy(tmp_name, name, fname_len(&nm) + 1); + fname_name(&nm) = tmp_name; host_ino->xattr_cnt++; - host_ino->xattr_size += CALC_DENT_SIZE(nm.len); + host_ino->xattr_size += CALC_DENT_SIZE(fname_len(&nm)); host_ino->xattr_size += CALC_XATTR_BYTES(data_len); - host_ino->xattr_names += nm.len; + host_ino->xattr_names += fname_len(&nm); - xent = xzalloc(sizeof(*xent) + nm.len + 1); + xent = xzalloc(sizeof(*xent) + fname_len(&nm) + 1); ino = xzalloc(sizeof(*ino) + data_len); xent_key_init(c, &xkey, inum, &nm); xent->ch.node_type = UBIFS_XENT_NODE; - key_write(&xkey, &xent->key); + key_write(c, &xkey, &xent->key); - len = UBIFS_XENT_NODE_SZ + nm.len + 1; + len = UBIFS_XENT_NODE_SZ + fname_len(&nm) + 1; xent->ch.len = len; xent->padding1 = 0; xent->type = UBIFS_ITYPE_REG; - xent->nlen = cpu_to_le16(nm.len); + xent->nlen = cpu_to_le16(fname_len(&nm)); - memcpy(xent->name, nm.name, nm.len + 1); + memcpy(xent->name, fname_name(&nm), fname_len(&nm) + 1); inum = ++c->highest_inum; creat_sqnum = ++c->max_sqnum; xent->inum = cpu_to_le64(inum); - ret = add_node(&xkey, tmp_name, nm.len, xent, len); + ret = add_node(&xkey, tmp_name, fname_len(&nm), xent, len); if (ret) goto out; @@ -1263,8 +1179,8 @@ static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino->compr_type = cpu_to_le16(c->default_compr); ino->ch.node_type = UBIFS_INO_NODE; - ino_key_init(&nkey, inum); - key_write(&nkey, &ino->key); + ino_key_init(c, &nkey, inum); + key_write(c, &nkey, &ino->key); ino->size = cpu_to_le64(data_len); ino->mode = cpu_to_le32(S_IFREG); @@ -1557,9 +1473,9 @@ static int add_inode(struct stat *st, ino_t inum, void *data, use_flags |= UBIFS_CRYPT_FL; memset(ino, 0, UBIFS_INO_NODE_SZ); - ino_key_init(&key, inum); + ino_key_init(c, &key, inum); ino->ch.node_type = UBIFS_INO_NODE; - key_write(&key, &ino->key); + key_write(c, &key, &ino->key); ino->creat_sqnum = cpu_to_le64(creat_sqnum); ino->size = cpu_to_le64(st->st_size); ino->nlink = cpu_to_le32(st->st_nlink); @@ -1710,6 +1626,7 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum, struct ubifs_dent_node *dent = node_buf; union ubifs_key key; struct qstr dname; + struct fscrypt_name nm; char *kname; int len; @@ -1747,13 +1664,15 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum, *kname_len = ret; } - dent_key_init(c, &key, dir_inum, kname, *kname_len); + fname_name(&nm) = kname; + fname_len(&nm) = *kname_len; + dent_key_init(c, &key, dir_inum, &nm); dent->nlen = cpu_to_le16(*kname_len); memcpy(dent->name, kname, *kname_len); dent->name[*kname_len] = '\0'; len = UBIFS_DENT_NODE_SZ + *kname_len + 1; - key_write(&key, dent->key); + key_write(c, &key, dent->key); return add_node(&key, kname, *kname_len, dent, len); } @@ -1849,9 +1768,9 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum, } /* Make data node */ memset(dn, 0, UBIFS_DATA_NODE_SZ); - data_key_init(&key, inum, block_no); + data_key_init(c, &key, inum, block_no); dn->ch.node_type = UBIFS_DATA_NODE; - key_write(&key, &dn->key); + key_write(c, &key, &dn->key); out_len = NODE_BUFFER_SIZE - UBIFS_DATA_NODE_SZ; if (c->default_compr == UBIFS_COMPR_NONE && !c->encrypted && (flags & FS_COMPR_FL)) @@ -2313,7 +2232,7 @@ static int cmp_idx(const void *a, const void *b) const struct idx_entry *e2 = *(const struct idx_entry **)b; int cmp; - cmp = keys_cmp(&e1->key, &e2->key); + cmp = keys_cmp(c, &e1->key, &e2->key); if (cmp) return cmp; return namecmp(e1, e2); @@ -2330,7 +2249,7 @@ static int add_idx_node(void *node, int child_cnt) len = ubifs_idx_node_sz(c, child_cnt); - prepare_node(node, len); + ubifs_prepare_node(c, node, len, 0); err = reserve_space(len, &lnum, &offs); if (err) @@ -2339,10 +2258,10 @@ static int add_idx_node(void *node, int child_cnt) memcpy(leb_buf + offs, node, len); memset(leb_buf + offs + len, 0xff, ALIGN(len, 8) - len); - c->old_idx_sz += ALIGN(len, 8); + c->bi.old_idx_sz += ALIGN(len, 8); pr_debug("at %d:%d len %d index size %llu\n", lnum, offs, len, - c->old_idx_sz); + c->bi.old_idx_sz); /* The last index node written will be the root */ c->zroot.lnum = lnum; @@ -2409,15 +2328,15 @@ static int write_index(void) idx->level = cpu_to_le16(0); for (j = 0; j < child_cnt; j++, p++) { br = ubifs_idx_branch(c, idx, j); - key_write_idx(&(*p)->key, &br->key); + key_write_idx(c, &(*p)->key, &br->key); br->lnum = cpu_to_le32((*p)->lnum); br->offs = cpu_to_le32((*p)->offs); br->len = cpu_to_le32((*p)->len); - memcpy(ubifs_branch_hash(br), (*p)->hash, c->hash_len); + memcpy(ubifs_branch_hash(c, br), (*p)->hash, c->hash_len); } add_idx_node(idx, child_cnt); - ubifs_node_calc_hash(idx, hashes + i * c->hash_len); + ubifs_node_calc_hash(c, idx, hashes + i * c->hash_len); } /* Write level 1 index nodes and above */ level = 0; @@ -2484,7 +2403,7 @@ static int write_index(void) * of the index node from the level below. */ br = ubifs_idx_branch(c, idx, j); - key_write_idx(&(*p)->key, &br->key); + key_write_idx(c, &(*p)->key, &br->key); br->lnum = cpu_to_le32(blnum); br->offs = cpu_to_le32(boffs); br->len = cpu_to_le32(blen); @@ -2495,12 +2414,12 @@ static int write_index(void) boffs += ALIGN(blen, 8); p += pstep; - memcpy(ubifs_branch_hash(br), + memcpy(ubifs_branch_hash(c, br), hashes + bn * c->hash_len, c->hash_len); } add_idx_node(idx, child_cnt); - ubifs_node_calc_hash(idx, hashes + i * c->hash_len); + ubifs_node_calc_hash(c, idx, hashes + i * c->hash_len); } } @@ -2571,7 +2490,7 @@ static int finalize_leb_cnt(void) pr_debug("total_used: %llu\n", c->lst.total_used); pr_debug("total_dead: %llu\n", c->lst.total_dead); pr_debug("total_dark: %llu\n", c->lst.total_dark); - pr_debug("index size: %llu\n", c->old_idx_sz); + pr_debug("index size: %llu\n", c->bi.old_idx_sz); pr_debug("empty_lebs: %d\n", c->lst.empty_lebs); return 0; } @@ -2598,7 +2517,6 @@ static int write_super(void) buf = xzalloc(c->leb_size); sup = buf; - sig = buf + UBIFS_SB_NODE_SZ; sup->ch.node_type = UBIFS_SB_NODE; sup->key_hash = c->key_hash_type; @@ -2634,27 +2552,27 @@ static int write_super(void) sup->flags |= cpu_to_le32(UBIFS_FLG_DOUBLE_HASH); if (c->encrypted) sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION); - if (authenticated()) { + if (ubifs_authenticated(c)) { sup->flags |= cpu_to_le32(UBIFS_FLG_AUTHENTICATION); memcpy(sup->hash_mst, c->mst_hash, c->hash_len); } - prepare_node(sup, UBIFS_SB_NODE_SZ); + ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 0); - err = sign_superblock_node(sup); + err = ubifs_sign_superblock_node(c, sup); if (err) goto out; sig = (void *)(sup + 1); - prepare_node(sig, UBIFS_SIG_NODE_SZ + le32_to_cpu(sig->len)); + ubifs_prepare_node(c, sig, UBIFS_SIG_NODE_SZ + le32_to_cpu(sig->len), 1); - len = do_pad(sig, UBIFS_SIG_NODE_SZ + le32_to_cpu(sig->len)); + len = ALIGN(ALIGN(UBIFS_SIG_NODE_SZ + le32_to_cpu(sig->len), 8), c->min_io_size); + memset(buf + UBIFS_SB_NODE_SZ + len, 0xff, c->leb_size - (UBIFS_SB_NODE_SZ + len)); - err = write_leb(c, UBIFS_SB_LNUM, UBIFS_SB_NODE_SZ + len, sup); + err = ubifs_leb_change(c, UBIFS_SB_LNUM, buf, c->leb_size); if (err) goto out; - err = 0; out: free(buf); @@ -2682,7 +2600,7 @@ static int write_master(void) mst.gc_lnum = cpu_to_le32(c->gc_lnum); mst.ihead_lnum = cpu_to_le32(c->ihead_lnum); mst.ihead_offs = cpu_to_le32(c->ihead_offs); - mst.index_size = cpu_to_le64(c->old_idx_sz); + mst.index_size = cpu_to_le64(c->bi.old_idx_sz); mst.lpt_lnum = cpu_to_le32(c->lpt_lnum); mst.lpt_offs = cpu_to_le32(c->lpt_offs); mst.nhead_lnum = cpu_to_le32(c->nhead_lnum); @@ -2701,7 +2619,7 @@ static int write_master(void) mst.total_dark = cpu_to_le64(c->lst.total_dark); mst.leb_cnt = cpu_to_le32(c->leb_cnt); - if (authenticated()) { + if (ubifs_authenticated(c)) { memcpy(mst.hash_root_idx, c->root_idx_hash, c->hash_len); memcpy(mst.hash_lpt, c->lpt_hash, c->hash_len); } @@ -2714,7 +2632,9 @@ static int write_master(void) if (err) return err; - mst_node_calc_hash(&mst, c->mst_hash); + err = ubifs_master_node_calc_hash(c, &mst, c->mst_hash); + if (err) + return err; return 0; } @@ -2754,7 +2674,8 @@ static int write_lpt(void) { int err, lnum; - err = create_lpt(c); + c->lscan_lnum = c->main_first; + err = ubifs_create_lpt(c, c->lpt, c->main_lebs, c->lpt_hash); if (err) return err; @@ -2789,7 +2710,7 @@ static int write_orphan_area(void) */ static int init(void) { - int err, i, main_lebs, big_lpt = 0, sz; + int err, main_lebs, big_lpt = 0, sz; c->highest_inum = UBIFS_FIRST_INO; @@ -2798,7 +2719,7 @@ static int init(void) main_lebs = c->max_leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS; main_lebs -= c->log_lebs + c->orph_lebs; - err = calc_dflt_lpt_geom(c, &main_lebs, &big_lpt); + err = ubifs_calc_dflt_lpt_geom(c, &main_lebs, &big_lpt); if (err) return err; @@ -2811,13 +2732,6 @@ static int init(void) c->lpt_last = c->lpt_first + c->lpt_lebs - 1; c->lpt = xmalloc(c->main_lebs * sizeof(struct ubifs_lprops)); - c->ltab = xmalloc(c->lpt_lebs * sizeof(struct ubifs_lprops)); - - /* Initialize LPT's own lprops */ - for (i = 0; i < c->lpt_lebs; i++) { - c->ltab[i].free = c->leb_size; - c->ltab[i].dirty = 0; - } c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size); c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size); @@ -2877,7 +2791,6 @@ static void deinit(void) #endif free(c->lpt); - free(c->ltab); free(leb_buf); free(node_buf); free(block_buf); @@ -2885,6 +2798,7 @@ static void deinit(void) free(hash_table); destroy_compression(); free_devtable_info(); + ubifs_exit_authentication(c); } /** @@ -2904,7 +2818,7 @@ static int mkfs(void) if (err) goto out; - err = init_authentication(); + err = ubifs_init_authentication(c); if (err) goto out; @@ -2951,9 +2865,7 @@ int main(int argc, char *argv[]) { int err; - info_.program_name = MKFS_PROGRAM_NAME; - info_.program_type = MKFS_PROGRAM_TYPE; - info_.debug_level = WARN_LEVEL; + init_ubifs_info(c, MKFS_PROGRAM_TYPE); if (crypto_init()) return -1; |