int err;
        struct rb_node *node;
        struct scanned_file *file;
-       struct rb_root *tree = &FSCK(c)->rebuild->scanned_files;
+       struct rb_root *tree = &FSCK(c)->scanned_files;
 
        for (node = rb_first(tree); node; node = rb_next(node)) {
                file = rb_entry(node, struct scanned_file, rb);
 
        c->dev_name = NULL;
 }
 
+void handle_error(const struct ubifs_info *c, int reason_set)
+{
+       bool handled = false;
+       unsigned int reason = get_failure_reason_callback(c);
+
+       clear_failure_reason_callback(c);
+       if ((reason_set & HAS_DATA_CORRUPTED) && (reason & FR_DATA_CORRUPTED)) {
+               handled = true;
+               reason &= ~FR_DATA_CORRUPTED;
+               if (fix_problem(c, LOG_CORRUPTED, NULL))
+                       FSCK(c)->try_rebuild = true;
+       }
+       if ((reason_set & HAS_TNC_CORRUPTED) && (reason & FR_TNC_CORRUPTED)) {
+               ubifs_assert(c, !handled);
+               handled = true;
+               reason &= ~FR_TNC_CORRUPTED;
+               if (fix_problem(c, TNC_CORRUPTED, NULL))
+                       FSCK(c)->try_rebuild = true;
+       }
+
+       ubifs_assert(c, reason == 0);
+       if (!handled)
+               exit_code |= FSCK_ERROR;
+}
+
 /*
  * do_fsck - Check & repair the filesystem.
  */
 
 enum { SB_CORRUPTED = 0, MST_CORRUPTED, LOG_CORRUPTED, BUD_CORRUPTED,
        TNC_CORRUPTED, TNC_DATA_CORRUPTED, ORPHAN_CORRUPTED };
 
+enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 };
+
 struct scanned_file;
 
 /**
 
 /**
  * ubifs_rebuild_info - UBIFS rebuilding information.
- * @used_lebs: a bitmap used for recording used lebs
  * @lpts: lprops table
- * @scanned_files: tree of all scanned files
  * @write_buf: write buffer for LEB @head_lnum
  * @head_lnum: current writing LEB number
  * @head_offs: current writing position in LEB @head_lnum
  * @need_update_lpt: whether to update lpt while writing index nodes
  */
 struct ubifs_rebuild_info {
-       unsigned long *used_lebs;
        struct ubifs_lprops *lpts;
-       struct rb_root scanned_files;
        void *write_buf;
        int head_lnum;
        int head_offs;
  * @failure_reason: reasons for failed operations
  * @lpt_status: the status of lpt, could be: %0(OK), %FR_LPT_CORRUPTED or
  *             %FR_LPT_INCORRECT
+ * @scanned_files: tree of all scanned files
+ * @used_lebs: a bitmap used for recording used lebs
  * @try_rebuild: %true means that try to rebuild fs when fsck failed
  * @rebuild: rebuilding-related information
  */
        int mode;
        unsigned int failure_reason;
        unsigned int lpt_status;
+       struct rb_root scanned_files;
+       unsigned long *used_lebs;
        bool try_rebuild;
        struct ubifs_rebuild_info *rebuild;
 };
 /* Exit code for fsck program. */
 extern int exit_code;
 
+/* fsck.ubifs.c */
+void handle_error(const struct ubifs_info *c, int reason_set);
+
 /* problem.c */
 bool fix_problem(const struct ubifs_info *c, int problem_type, const void *priv);
 
 
 #include "misc.h"
 #include "fsck.ubifs.h"
 
-enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 };
-
-static void handle_error(const struct ubifs_info *c, int reason_set)
-{
-       bool handled = false;
-       unsigned int reason = get_failure_reason_callback(c);
-
-       clear_failure_reason_callback(c);
-       if ((reason_set & HAS_DATA_CORRUPTED) && (reason & FR_DATA_CORRUPTED)) {
-               handled = true;
-               reason &= ~FR_DATA_CORRUPTED;
-               if (fix_problem(c, LOG_CORRUPTED, NULL))
-                       FSCK(c)->try_rebuild = true;
-       }
-       if ((reason_set & HAS_TNC_CORRUPTED) && (reason & FR_TNC_CORRUPTED)) {
-               ubifs_assert(c, !handled);
-               handled = true;
-               reason &= ~FR_TNC_CORRUPTED;
-               if (fix_problem(c, TNC_CORRUPTED, NULL))
-                       FSCK(c)->try_rebuild = true;
-       }
-
-       ubifs_assert(c, reason == 0);
-       if (!handled)
-               exit_code |= FSCK_ERROR;
-}
-
 int ubifs_load_filesystem(struct ubifs_info *c)
 {
        int err;
 
                log_err(c, errno, "can not allocate rebuild info");
                goto free_sbuf;
        }
-       FSCK(c)->rebuild->scanned_files = RB_ROOT;
-       FSCK(c)->rebuild->used_lebs = kcalloc(BITS_TO_LONGS(c->main_lebs),
-                                             sizeof(unsigned long), GFP_KERNEL);
-       if (!FSCK(c)->rebuild->used_lebs) {
+       FSCK(c)->scanned_files = RB_ROOT;
+       FSCK(c)->used_lebs = kcalloc(BITS_TO_LONGS(c->main_lebs),
+                                    sizeof(unsigned long), GFP_KERNEL);
+       if (!FSCK(c)->used_lebs) {
                err = -ENOMEM;
                log_err(c, errno, "can not allocate bitmap of used lebs");
                goto free_rebuild;
 free_lpts:
        kfree(FSCK(c)->rebuild->lpts);
 free_used_lebs:
-       kfree(FSCK(c)->rebuild->used_lebs);
+       kfree(FSCK(c)->used_lebs);
 free_rebuild:
        kfree(FSCK(c)->rebuild);
 free_sbuf:
 {
        vfree(FSCK(c)->rebuild->write_buf);
        kfree(FSCK(c)->rebuild->lpts);
-       kfree(FSCK(c)->rebuild->used_lebs);
+       kfree(FSCK(c)->used_lebs);
        kfree(FSCK(c)->rebuild);
        vfree(c->sbuf);
 }
                return 1;
        }
 
-       tree = &FSCK(c)->rebuild->scanned_files;
+       tree = &FSCK(c)->scanned_files;
        return insert_or_update_file(c, tree, sn, key_type(c, key), inum);
 }
 
        struct scanned_dent_node *dent_node;
        struct rb_node *this;
 
-       destroy_file_tree(c, &FSCK(c)->rebuild->scanned_files);
+       destroy_file_tree(c, &FSCK(c)->scanned_files);
 
        this = rb_first(&si->valid_inos);
        while (this) {
  *
  * This function scans nodes from flash, all ino/dent nodes are split
  * into valid tree and deleted tree, all trun/data nodes are collected
- * into file, the file is inserted into @FSCK(c)->rebuild->scanned_files.
+ * into file, the file is inserted into @FSCK(c)->scanned_files.
  */
 static int scan_nodes(struct ubifs_info *c, struct scanned_info *si)
 {
        int index = sn->lnum - c->main_first;
        int pos = sn->offs + ALIGN(sn->len, 8);
 
-       set_bit(index, FSCK(c)->rebuild->used_lebs);
+       set_bit(index, FSCK(c)->used_lebs);
        FSCK(c)->rebuild->lpts[index].end = max_t(int,
                                        FSCK(c)->rebuild->lpts[index].end, pos);
 
        struct scanned_ino_node *ino_node;
        struct scanned_dent_node *dent_node;
        struct rb_node *this;
-       struct rb_root *tree = &FSCK(c)->rebuild->scanned_files;
+       struct rb_root *tree = &FSCK(c)->scanned_files;
 
        this = rb_first(&si->valid_inos);
        while (this) {
 {
        struct rb_node *node;
        struct scanned_file *file;
-       struct rb_root *tree = &FSCK(c)->rebuild->scanned_files;
+       struct rb_root *tree = &FSCK(c)->scanned_files;
        LIST_HEAD(tmp_list);
 
        /* Add all xattr files into a list. */
 {
        struct rb_node *node;
        struct scanned_file *file;
-       struct rb_root *tree = &FSCK(c)->rebuild->scanned_files;
+       struct rb_root *tree = &FSCK(c)->scanned_files;
        LIST_HEAD(unreachable);
 
        for (node = rb_first(tree); node; node = rb_next(node)) {
 }
 
 /**
- * get_free_leb - get a free LEB according to @FSCK(c)->rebuild->used_lebs.
+ * get_free_leb - get a free LEB according to @FSCK(c)->used_lebs.
  * @c: UBIFS file-system description object
  *
  * This function tries to find a free LEB, lnum is returned if found, otherwise
 {
        int lnum;
 
-       lnum = find_next_zero_bit(FSCK(c)->rebuild->used_lebs, c->main_lebs, 0);
+       lnum = find_next_zero_bit(FSCK(c)->used_lebs, c->main_lebs, 0);
        if (lnum >= c->main_lebs) {
                ubifs_err(c, "No space left.");
                return -ENOSPC;
        }
-       set_bit(lnum, FSCK(c)->rebuild->used_lebs);
+       set_bit(lnum, FSCK(c)->used_lebs);
        lnum += c->main_first;
 
        return lnum;
        file->calc_xnms = file->ino.xnms = le32_to_cpu(ino->xattr_names);
        file->calc_size = file->ino.size = le64_to_cpu(ino->size);
 
-       rb_link_node(&file->rb, NULL, &FSCK(c)->rebuild->scanned_files.rb_node);
-       rb_insert_color(&file->rb, &FSCK(c)->rebuild->scanned_files);
+       rb_link_node(&file->rb, NULL, &FSCK(c)->scanned_files.rb_node);
+       rb_insert_color(&file->rb, &FSCK(c)->scanned_files);
 
 out:
        kfree(ino);
        int i, err = 0, idx_cnt = 0;
        struct rb_node *node;
        struct scanned_file *file;
-       struct rb_root *tree = &FSCK(c)->rebuild->scanned_files;
+       struct rb_root *tree = &FSCK(c)->scanned_files;
        struct idx_entry *ie, *tmp_ie;
        LIST_HEAD(idx_list);
 
        for (i = 0; i < c->main_lebs; ++i) {
                int lnum, len, end;
 
-               if (!test_bit(i, FSCK(c)->rebuild->used_lebs))
+               if (!test_bit(i, FSCK(c)->used_lebs))
                        continue;
 
                lnum = i + c->main_first;
 
        /* Update LPT. */
        for (i = 0; i < c->main_lebs; i++) {
-               if (!test_bit(i, FSCK(c)->rebuild->used_lebs) ||
+               if (!test_bit(i, FSCK(c)->used_lebs) ||
                    c->gc_lnum == i + c->main_first) {
                        free = c->leb_size;
                        dirty = 0;
 
        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
 
 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);