提交 4a29d200 编写于 作者: A Adrian Hunter 提交者: Artem Bityutskiy

UBIFS: fix LPT out-of-space bug (again)

The function to traverse and dirty the LPT was still not
dirtying all nodes, with the result that the LPT could
run out of space.
Signed-off-by: NAdrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: NArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
上级 6f7ab6d4
...@@ -556,23 +556,23 @@ static int write_cnodes(struct ubifs_info *c) ...@@ -556,23 +556,23 @@ static int write_cnodes(struct ubifs_info *c)
} }
/** /**
* 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, static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
struct ubifs_pnode *pnode) 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; for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
if (iip < UBIFS_LPT_FANOUT) {
/* We assume here that LEB zero is never an LPT LEB */
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, ...@@ -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 */ for (; iip < UBIFS_LPT_FANOUT; iip++) {
} while (iip >= UBIFS_LPT_FANOUT || !nnode->nbranch[iip].lnum); 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, ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册