From 7e9a7ceaa9d3851963f92f99ce012f7cd99e742b Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Mon, 11 Nov 2024 17:08:00 +0800 Subject: fsck.ubifs: Move common functions and data structures into fsck.ubifs.c This is a preparation for adding TNC checking support. Following data structures and functions are moved into fsck.ubifs.c: 1. Move 'scanned_files' and 'used_lebs' from rebuild module, make them resuable for non-rebuild_fs modes. 2. Move function 'handle_error' from load_fs.c, it could be reused in other steps. 3. Add new function ubifs_tnc_remove_node in libubifs, which could remove index entry for a node by given position. Signed-off-by: Zhihao Cheng Signed-off-by: David Oberhollenzer --- ubifs-utils/libubifs/tnc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ ubifs-utils/libubifs/ubifs.h | 2 ++ 2 files changed, 66 insertions(+) (limited to 'ubifs-utils/libubifs') diff --git a/ubifs-utils/libubifs/tnc.c b/ubifs-utils/libubifs/tnc.c index cd1013d..9277062 100644 --- a/ubifs-utils/libubifs/tnc.c +++ b/ubifs-utils/libubifs/tnc.c @@ -2456,6 +2456,70 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum) return ubifs_tnc_remove_range(c, &key1, &key2); } +/** + * ubifs_tnc_remove_node - remove an index entry of a node by given position. + * @c: UBIFS file-system description object + * @key: key of node + * @lnum: LEB number of node + * @offs: node offset + * + * Returns %0 on success or negative error code on failure. + */ +int ubifs_tnc_remove_node(struct ubifs_info *c, const union ubifs_key *key, + int lnum, int offs) +{ + int found, n, err = 0; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnck(key, "pos %d:%d, key ", lnum, offs); + found = lookup_level0_dirty(c, key, &znode, &n); + if (found < 0) { + err = found; + goto out_unlock; + } + if (found == 1) { + struct ubifs_zbranch *zbr = &znode->zbranch[n]; + + if (zbr->lnum == lnum && zbr->offs == offs) { + err = tnc_delete(c, znode, n); + } else if (is_hash_key(c, key)) { + found = resolve_collision_directly(c, key, &znode, &n, + lnum, offs); + if (found < 0) { + err = found; + goto out_unlock; + } + + if (found) { + /* Ensure the znode is dirtied */ + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + } + err = tnc_delete(c, znode, n); + } else { + goto not_found; + } + } else { + goto not_found; + } + } else { +not_found: + /* Impossible, the node has been found before being deleted. */ + ubifs_assert(c, 0); + } + if (!err) + err = dbg_check_tnc(c, 0); + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + /** * ubifs_tnc_next_ent - walk directory or extended attribute entries. * @c: UBIFS file-system description object diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h index 8a506a8..03150cd 100644 --- a/ubifs-utils/libubifs/ubifs.h +++ b/ubifs-utils/libubifs/ubifs.h @@ -1661,6 +1661,8 @@ int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, union ubifs_key *to_key); int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum); +int ubifs_tnc_remove_node(struct ubifs_info *c, const union ubifs_key *key, + int lnum, int offs); struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, union ubifs_key *key, const struct fscrypt_name *nm); -- cgit v1.2.3