|
@@ -556,23 +556,23 @@ no_space:
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * next_pnode - find next pnode.
|
|
|
|
|
|
+ * next_pnode_to_dirty - find next pnode to dirty.
|
|
* @c: UBIFS file-system description object
|
|
* @c: UBIFS file-system description object
|
|
* @pnode: pnode
|
|
* @pnode: pnode
|
|
*
|
|
*
|
|
- * This function returns the next pnode or %NULL if there are no more pnodes.
|
|
|
|
|
|
+ * 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.
|
|
*/
|
|
*/
|
|
-static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
|
|
|
|
- struct ubifs_pnode *pnode)
|
|
|
|
|
|
+static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
|
|
|
|
+ struct ubifs_pnode *pnode)
|
|
{
|
|
{
|
|
struct ubifs_nnode *nnode;
|
|
struct ubifs_nnode *nnode;
|
|
int iip;
|
|
int iip;
|
|
|
|
|
|
/* Try to go right */
|
|
/* Try to go right */
|
|
nnode = pnode->parent;
|
|
nnode = pnode->parent;
|
|
- iip = pnode->iip + 1;
|
|
|
|
- if (iip < UBIFS_LPT_FANOUT) {
|
|
|
|
- /* We assume here that LEB zero is never an LPT LEB */
|
|
|
|
|
|
+ for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
|
|
if (nnode->nbranch[iip].lnum)
|
|
if (nnode->nbranch[iip].lnum)
|
|
return ubifs_get_pnode(c, nnode, iip);
|
|
return ubifs_get_pnode(c, nnode, iip);
|
|
}
|
|
}
|
|
@@ -583,8 +583,11 @@ static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
|
|
nnode = nnode->parent;
|
|
nnode = nnode->parent;
|
|
if (!nnode)
|
|
if (!nnode)
|
|
return NULL;
|
|
return NULL;
|
|
- /* We assume here that LEB zero is never an LPT LEB */
|
|
|
|
- } while (iip >= UBIFS_LPT_FANOUT || !nnode->nbranch[iip].lnum);
|
|
|
|
|
|
+ for (; iip < UBIFS_LPT_FANOUT; iip++) {
|
|
|
|
+ if (nnode->nbranch[iip].lnum)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } while (iip >= UBIFS_LPT_FANOUT);
|
|
|
|
|
|
/* Go right */
|
|
/* Go right */
|
|
nnode = ubifs_get_nnode(c, nnode, iip);
|
|
nnode = ubifs_get_nnode(c, nnode, iip);
|
|
@@ -593,12 +596,29 @@ static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
|
|
|
|
|
|
/* Go down to level 1 */
|
|
/* Go down to level 1 */
|
|
while (nnode->level > 1) {
|
|
while (nnode->level > 1) {
|
|
- nnode = ubifs_get_nnode(c, nnode, 0);
|
|
|
|
|
|
+ for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) {
|
|
|
|
+ if (nnode->nbranch[iip].lnum)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (iip >= UBIFS_LPT_FANOUT) {
|
|
|
|
+ /*
|
|
|
|
+ * Should not happen, but we need to keep going
|
|
|
|
+ * if it does.
|
|
|
|
+ */
|
|
|
|
+ iip = 0;
|
|
|
|
+ }
|
|
|
|
+ nnode = ubifs_get_nnode(c, nnode, iip);
|
|
if (IS_ERR(nnode))
|
|
if (IS_ERR(nnode))
|
|
return (void *)nnode;
|
|
return (void *)nnode;
|
|
}
|
|
}
|
|
|
|
|
|
- return ubifs_get_pnode(c, nnode, 0);
|
|
|
|
|
|
+ for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++)
|
|
|
|
+ if (nnode->nbranch[iip].lnum)
|
|
|
|
+ break;
|
|
|
|
+ if (iip >= UBIFS_LPT_FANOUT)
|
|
|
|
+ /* Should not happen, but we need to keep going if it does */
|
|
|
|
+ iip = 0;
|
|
|
|
+ return ubifs_get_pnode(c, nnode, iip);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -688,7 +708,7 @@ static int make_tree_dirty(struct ubifs_info *c)
|
|
pnode = pnode_lookup(c, 0);
|
|
pnode = pnode_lookup(c, 0);
|
|
while (pnode) {
|
|
while (pnode) {
|
|
do_make_pnode_dirty(c, pnode);
|
|
do_make_pnode_dirty(c, pnode);
|
|
- pnode = next_pnode(c, pnode);
|
|
|
|
|
|
+ pnode = next_pnode_to_dirty(c, pnode);
|
|
if (IS_ERR(pnode))
|
|
if (IS_ERR(pnode))
|
|
return PTR_ERR(pnode);
|
|
return PTR_ERR(pnode);
|
|
}
|
|
}
|