// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of UBIFS. * * Copyright (C) 2006-2008 Nokia Corporation. * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter
*/
/* This file implements reading and writing the master node */
#include"ubifs.h"
/** * ubifs_compare_master_node - compare two UBIFS master nodes * @c: UBIFS file-system description object * @m1: the first node * @m2: the second node * * This function compares two UBIFS master nodes. Returns 0 if they are equal * and nonzero if not.
*/ int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2)
{ int ret; int behind; int hmac_offs = offsetof(struct ubifs_mst_node, hmac);
/* * Do not compare the common node header since the sequence number and * hence the CRC are different.
*/
ret = memcmp(m1 + UBIFS_CH_SZ, m2 + UBIFS_CH_SZ,
hmac_offs - UBIFS_CH_SZ); if (ret) return ret;
/* * Do not compare the embedded HMAC as well which also must be different * due to the different common node header.
*/
behind = hmac_offs + UBIFS_MAX_HMAC_LEN;
/* mst_node_check_hash - Check hash of a master node * @c: UBIFS file-system description object * @mst: The master node * @expected: The expected hash of the master node * * This checks the hash of a master node against a given expected hash. * Note that we have two master nodes on a UBIFS image which have different * sequence numbers and consequently different CRCs. To be able to match * both master nodes we exclude the common node header containing the sequence * number and CRC from the hash. * * Returns 0 if the hashes are equal, a negative error code otherwise.
*/ staticint mst_node_check_hash(conststruct ubifs_info *c, conststruct ubifs_mst_node *mst, const u8 *expected)
{
u8 calc[UBIFS_MAX_HASH_LEN]; constvoid *node = mst; int ret;
ret = crypto_shash_tfm_digest(c->hash_tfm, node + sizeof(struct ubifs_ch),
UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch),
calc); if (ret) return ret;
if (ubifs_check_hash(c, expected, calc)) return -EPERM;
return 0;
}
/** * scan_for_master - search the valid master node. * @c: UBIFS file-system description object * * This function scans the master node LEBs and search for the latest master * node. Returns zero in case of success, %-EUCLEAN if there master area is * corrupted and requires recovery, and a negative error code in case of * failure.
*/ staticint scan_for_master(struct ubifs_info *c)
{ struct ubifs_scan_leb *sleb; struct ubifs_scan_node *snod; int lnum, offs = 0, nodes_cnt, err;
/** * validate_master - validate master node. * @c: UBIFS file-system description object * * This function validates data which was read from master node. Returns zero * if the data is all right and %-EINVAL if not.
*/ staticint validate_master(conststruct ubifs_info *c)
{ longlong main_sz; int err;
/** * ubifs_read_master - read master node. * @c: UBIFS file-system description object * * This function finds and reads the master node during file-system mount. If * the flash is empty, it creates default master node as well. Returns zero in * case of success and a negative error code in case of failure.
*/ int ubifs_read_master(struct ubifs_info *c)
{ int err, old_leb_cnt;
c->mst_node = kzalloc(c->mst_node_alsz, GFP_KERNEL); if (!c->mst_node) return -ENOMEM;
err = scan_for_master(c); if (err) { if (err == -EUCLEAN)
err = ubifs_recover_master_node(c); if (err) /* * Note, we do not free 'c->mst_node' here because the * unmount routine will take care of this.
*/ return err;
}
/* Make sure that the recovery flag is clear */
c->mst_node->flags &= cpu_to_le32(~UBIFS_MST_RCVRY);
/* * Reflect changes back onto the master node. N.B. the master * node gets written immediately whenever mounting (or * remounting) in read-write mode, so we do not need to write it * here.
*/
c->mst_node->leb_cnt = cpu_to_le32(c->leb_cnt);
c->mst_node->empty_lebs = cpu_to_le32(c->lst.empty_lebs);
c->mst_node->total_free = cpu_to_le64(c->lst.total_free);
c->mst_node->total_dark = cpu_to_le64(c->lst.total_dark);
}
err = validate_master(c); if (err) return err;
err = dbg_old_index_check_init(c, &c->zroot);
return err;
}
/** * ubifs_write_master - write master node. * @c: UBIFS file-system description object * * This function writes the master node. Returns zero in case of success and a * negative error code in case of failure. The master node is written twice to * enable recovery.
*/ int ubifs_write_master(struct ubifs_info *c)
{ int err, lnum, offs, len;
ubifs_assert(c, !c->ro_media && !c->ro_mount); if (c->ro_error) return -EROFS;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.