aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/libubifs
diff options
context:
space:
mode:
Diffstat (limited to 'ubifs-utils/libubifs')
-rw-r--r--ubifs-utils/libubifs/lpt.c6
-rw-r--r--ubifs-utils/libubifs/lpt_commit.c97
-rw-r--r--ubifs-utils/libubifs/super.c9
-rw-r--r--ubifs-utils/libubifs/ubifs.h7
4 files changed, 69 insertions, 50 deletions
diff --git a/ubifs-utils/libubifs/lpt.c b/ubifs-utils/libubifs/lpt.c
index b07f1f7..fc70cad 100644
--- a/ubifs-utils/libubifs/lpt.c
+++ b/ubifs-utils/libubifs/lpt.c
@@ -523,7 +523,7 @@ static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode)
}
/**
- * calc_nnode_num - calculate nnode number.
+ * ubifs_calc_nnode_num - calculate nnode number.
* @row: the row in the tree (root is zero)
* @col: the column in the row (leftmost is zero)
*
@@ -533,7 +533,7 @@ static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode)
* 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 ubifs_calc_nnode_num(int row, int col)
{
int num, bits;
@@ -779,7 +779,7 @@ int ubifs_create_lpt(struct ubifs_info *c, struct ubifs_lprops *lps, int lp_cnt,
nnode->nbranch[j].offs = 0;
}
}
- nnode->num = calc_nnode_num(row, i);
+ nnode->num = ubifs_calc_nnode_num(row, i);
ubifs_pack_nnode(c, p, nnode);
p += c->nnode_sz;
len += c->nnode_sz;
diff --git a/ubifs-utils/libubifs/lpt_commit.c b/ubifs-utils/libubifs/lpt_commit.c
index 43eb7a6..8a44546 100644
--- a/ubifs-utils/libubifs/lpt_commit.c
+++ b/ubifs-utils/libubifs/lpt_commit.c
@@ -545,16 +545,15 @@ no_space:
}
/**
- * next_pnode_to_dirty - find next pnode to dirty.
+ * ubifs_find_next_pnode - find next pnode.
* @c: UBIFS file-system description object
* @pnode: pnode
*
- * This function returns the next pnode to dirty or %NULL if there are no more
- * pnodes. Note that pnodes that have never been written (lnum == 0) are
- * skipped.
+ * This function returns the next pnode or %NULL if there are no more pnodes.
+ * Note that pnodes that have never been written (lnum == 0) are skipped.
*/
-static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
- struct ubifs_pnode *pnode)
+struct ubifs_pnode *ubifs_find_next_pnode(struct ubifs_info *c,
+ struct ubifs_pnode *pnode)
{
struct ubifs_nnode *nnode;
int iip;
@@ -622,28 +621,35 @@ static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode)
}
/**
- * do_make_pnode_dirty - mark a pnode dirty.
+ * ubifs_make_nnode_dirty - mark a nnode dirty.
+ * @c: UBIFS file-system description object
+ * @nnode: nnode to mark dirty
+ */
+void ubifs_make_nnode_dirty(struct ubifs_info *c, struct ubifs_nnode *nnode)
+{
+ while (nnode) {
+ if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
+ c->dirty_nn_cnt += 1;
+ ubifs_add_nnode_dirt(c, nnode);
+ nnode = nnode->parent;
+ } else
+ break;
+ }
+}
+
+/**
+ * ubifs_make_pnode_dirty - mark a pnode dirty.
* @c: UBIFS file-system description object
* @pnode: pnode to mark dirty
*/
-static void do_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode)
+void ubifs_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode)
{
/* Assumes cnext list is empty i.e. not called during commit */
if (!test_and_set_bit(DIRTY_CNODE, &pnode->flags)) {
- struct ubifs_nnode *nnode;
-
c->dirty_pn_cnt += 1;
add_pnode_dirt(c, pnode);
/* Mark parent and ancestors dirty too */
- nnode = pnode->parent;
- while (nnode) {
- if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
- c->dirty_nn_cnt += 1;
- ubifs_add_nnode_dirt(c, nnode);
- nnode = nnode->parent;
- } else
- break;
- }
+ ubifs_make_nnode_dirty(c, pnode->parent);
}
}
@@ -667,8 +673,8 @@ static int make_tree_dirty(struct ubifs_info *c)
return PTR_ERR(pnode);
while (pnode) {
- do_make_pnode_dirty(c, pnode);
- pnode = next_pnode_to_dirty(c, pnode);
+ ubifs_make_pnode_dirty(c, pnode);
+ pnode = ubifs_find_next_pnode(c, pnode);
if (IS_ERR(pnode))
return PTR_ERR(pnode);
}
@@ -878,20 +884,7 @@ static int make_nnode_dirty(struct ubifs_info *c, int node_num, int lnum,
} else if (c->lpt_lnum != lnum || c->lpt_offs != offs)
return 0; /* nnode is obsolete */
/* Assumes cnext list is empty i.e. not called during commit */
- if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
- c->dirty_nn_cnt += 1;
- ubifs_add_nnode_dirt(c, nnode);
- /* Mark parent and ancestors dirty too */
- nnode = nnode->parent;
- while (nnode) {
- if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) {
- c->dirty_nn_cnt += 1;
- ubifs_add_nnode_dirt(c, nnode);
- nnode = nnode->parent;
- } else
- break;
- }
- }
+ ubifs_make_nnode_dirty(c, nnode);
return 0;
}
@@ -922,7 +915,7 @@ static int make_pnode_dirty(struct ubifs_info *c, int node_num, int lnum,
branch = &pnode->parent->nbranch[pnode->iip];
if (branch->lnum != lnum || branch->offs != offs)
return 0;
- do_make_pnode_dirty(c, pnode);
+ ubifs_make_pnode_dirty(c, pnode);
return 0;
}
@@ -1414,14 +1407,33 @@ static struct ubifs_nnode *next_nnode(struct ubifs_info *c,
}
/**
+ * ubifs_free_lpt_nodes - free pnodes/nnodes in LPT.
+ * @c: UBIFS file-system description object
+ */
+void ubifs_free_lpt_nodes(struct ubifs_info *c)
+{
+ int i, hght;
+ struct ubifs_nnode *nnode;
+
+ nnode = first_nnode(c, &hght);
+ while (nnode) {
+ for (i = 0; i < UBIFS_LPT_FANOUT; i++)
+ kfree(nnode->nbranch[i].nnode);
+ nnode = next_nnode(c, nnode, &hght);
+ }
+
+ kfree(c->nroot);
+ c->nroot = NULL;
+}
+
+/**
* ubifs_lpt_free - free resources owned by the LPT.
* @c: UBIFS file-system description object
* @wr_only: free only resources used for writing
*/
void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
{
- struct ubifs_nnode *nnode;
- int i, hght;
+ int i;
/* Free write-only things first */
@@ -1439,17 +1451,12 @@ void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
/* Now free the rest */
- nnode = first_nnode(c, &hght);
- while (nnode) {
- for (i = 0; i < UBIFS_LPT_FANOUT; i++)
- kfree(nnode->nbranch[i].nnode);
- nnode = next_nnode(c, nnode, &hght);
- }
+ ubifs_free_lpt_nodes(c);
for (i = 0; i < LPROPS_HEAP_CNT; i++)
kfree(c->lpt_heap[i].arr);
kfree(c->dirty_idx.arr);
- kfree(c->nroot);
vfree(c->ltab);
+ c->ltab = NULL;
kfree(c->lpt_nod_buf);
}
diff --git a/ubifs-utils/libubifs/super.c b/ubifs-utils/libubifs/super.c
index 155489d..559623f 100644
--- a/ubifs-utils/libubifs/super.c
+++ b/ubifs-utils/libubifs/super.c
@@ -654,15 +654,20 @@ void free_orphans(struct ubifs_info *c)
/**
* free_buds - free per-bud objects.
* @c: UBIFS file-system description object
+ * @delete_from_list: whether to delete the bud from list
*/
-static void free_buds(struct ubifs_info *c)
+void free_buds(struct ubifs_info *c, bool delete_from_list)
{
struct ubifs_bud *bud, *n;
rbtree_postorder_for_each_entry_safe(bud, n, &c->buds, rb) {
+ if (delete_from_list)
+ list_del(&bud->list);
kfree(bud->log_hash);
kfree(bud);
}
+
+ c->buds = RB_ROOT;
}
/**
@@ -693,5 +698,5 @@ void destroy_journal(struct ubifs_info *c)
ubifs_destroy_idx_gc(c);
ubifs_destroy_size_tree(c);
ubifs_tnc_close(c);
- free_buds(c);
+ free_buds(c, false);
}
diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h
index 72497cd..45c4105 100644
--- a/ubifs-utils/libubifs/ubifs.h
+++ b/ubifs-utils/libubifs/ubifs.h
@@ -1778,6 +1778,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip);
void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty);
void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode);
uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits);
+int ubifs_calc_nnode_num(int row, int col);
struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght);
/* Needed only in debugging code in lpt_commit.c */
int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
@@ -1785,9 +1786,14 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash);
/* lpt_commit.c */
+struct ubifs_pnode *ubifs_find_next_pnode(struct ubifs_info *c,
+ struct ubifs_pnode *pnode);
+void ubifs_make_nnode_dirty(struct ubifs_info *c, struct ubifs_nnode *nnode);
+void ubifs_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode);
int ubifs_lpt_start_commit(struct ubifs_info *c);
int ubifs_lpt_end_commit(struct ubifs_info *c);
int ubifs_lpt_post_commit(struct ubifs_info *c);
+void ubifs_free_lpt_nodes(struct ubifs_info *c);
void ubifs_lpt_free(struct ubifs_info *c, int wr_only);
/* lprops.c */
@@ -1830,6 +1836,7 @@ int take_gc_lnum(struct ubifs_info *c);
int alloc_wbufs(struct ubifs_info *c);
void free_wbufs(struct ubifs_info *c);
void free_orphans(struct ubifs_info *c);
+void free_buds(struct ubifs_info *c, bool delete_from_list);
void destroy_journal(struct ubifs_info *c);
/* recovery.c */