Commit c939f9f9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6

* 'linux-next' of git://git.infradead.org/ubifs-2.6:
  UBIFS: fix a memory leak on error path.
  UBIFS: fix GC LEB recovery
  UBIFS: use ERR_CAST
  UBIFS: check return code
parents b8b3e905 c18de72f
...@@ -1457,13 +1457,13 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) ...@@ -1457,13 +1457,13 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum)
shft -= UBIFS_LPT_FANOUT_SHIFT; shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip); nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode)) if (IS_ERR(nnode))
return ERR_PTR(PTR_ERR(nnode)); return ERR_CAST(nnode);
} }
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
shft -= UBIFS_LPT_FANOUT_SHIFT; shft -= UBIFS_LPT_FANOUT_SHIFT;
pnode = ubifs_get_pnode(c, nnode, iip); pnode = ubifs_get_pnode(c, nnode, iip);
if (IS_ERR(pnode)) if (IS_ERR(pnode))
return ERR_PTR(PTR_ERR(pnode)); return ERR_CAST(pnode);
iip = (i & (UBIFS_LPT_FANOUT - 1)); iip = (i & (UBIFS_LPT_FANOUT - 1));
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty, pnode->lprops[iip].free, pnode->lprops[iip].dirty,
...@@ -1586,7 +1586,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) ...@@ -1586,7 +1586,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
nnode = c->nroot; nnode = c->nroot;
nnode = dirty_cow_nnode(c, nnode); nnode = dirty_cow_nnode(c, nnode);
if (IS_ERR(nnode)) if (IS_ERR(nnode))
return ERR_PTR(PTR_ERR(nnode)); return ERR_CAST(nnode);
i = lnum - c->main_first; i = lnum - c->main_first;
shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT;
for (h = 1; h < c->lpt_hght; h++) { for (h = 1; h < c->lpt_hght; h++) {
...@@ -1594,19 +1594,19 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) ...@@ -1594,19 +1594,19 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
shft -= UBIFS_LPT_FANOUT_SHIFT; shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip); nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode)) if (IS_ERR(nnode))
return ERR_PTR(PTR_ERR(nnode)); return ERR_CAST(nnode);
nnode = dirty_cow_nnode(c, nnode); nnode = dirty_cow_nnode(c, nnode);
if (IS_ERR(nnode)) if (IS_ERR(nnode))
return ERR_PTR(PTR_ERR(nnode)); return ERR_CAST(nnode);
} }
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
shft -= UBIFS_LPT_FANOUT_SHIFT; shft -= UBIFS_LPT_FANOUT_SHIFT;
pnode = ubifs_get_pnode(c, nnode, iip); pnode = ubifs_get_pnode(c, nnode, iip);
if (IS_ERR(pnode)) if (IS_ERR(pnode))
return ERR_PTR(PTR_ERR(pnode)); return ERR_CAST(pnode);
pnode = dirty_cow_pnode(c, pnode); pnode = dirty_cow_pnode(c, pnode);
if (IS_ERR(pnode)) if (IS_ERR(pnode))
return ERR_PTR(PTR_ERR(pnode)); return ERR_CAST(pnode);
iip = (i & (UBIFS_LPT_FANOUT - 1)); iip = (i & (UBIFS_LPT_FANOUT - 1));
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty, pnode->lprops[iip].free, pnode->lprops[iip].dirty,
......
...@@ -646,7 +646,7 @@ static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i) ...@@ -646,7 +646,7 @@ static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i)
shft -= UBIFS_LPT_FANOUT_SHIFT; shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip); nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode)) if (IS_ERR(nnode))
return ERR_PTR(PTR_ERR(nnode)); return ERR_CAST(nnode);
} }
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
return ubifs_get_pnode(c, nnode, iip); return ubifs_get_pnode(c, nnode, iip);
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* This file implements functions needed to recover from unclean un-mounts. * This file implements functions needed to recover from unclean un-mounts.
* When UBIFS is mounted, it checks a flag on the master node to determine if * When UBIFS is mounted, it checks a flag on the master node to determine if
* an un-mount was completed successfully. If not, the process of mounting * an un-mount was completed successfully. If not, the process of mounting
* incorparates additional checking and fixing of on-flash data structures. * incorporates additional checking and fixing of on-flash data structures.
* UBIFS always cleans away all remnants of an unclean un-mount, so that * UBIFS always cleans away all remnants of an unclean un-mount, so that
* errors do not accumulate. However UBIFS defers recovery if it is mounted * errors do not accumulate. However UBIFS defers recovery if it is mounted
* read-only, and the flash is not modified in that case. * read-only, and the flash is not modified in that case.
...@@ -1063,8 +1063,21 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) ...@@ -1063,8 +1063,21 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
} }
err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2);
if (err) { if (err) {
if (err == -ENOSPC) /*
dbg_err("could not find a dirty LEB"); * There are no dirty or empty LEBs subject to here being
* enough for the index. Try to use
* 'ubifs_find_free_leb_for_idx()', which will return any empty
* LEBs (ignoring index requirements). If the index then
* doesn't have enough LEBs the recovery commit will fail -
* which is the same result anyway i.e. recovery fails. So
* there is no problem ignoring index requirements and just
* grabbing a free LEB since we have already established there
* is not a dirty LEB we could have used instead.
*/
if (err == -ENOSPC) {
dbg_rcvry("could not find a dirty LEB");
goto find_free;
}
return err; return err;
} }
ubifs_assert(!(lp.flags & LPROPS_INDEX)); ubifs_assert(!(lp.flags & LPROPS_INDEX));
...@@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) ...@@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
find_free: find_free:
/* /*
* There is no GC head LEB or the free space in the GC head LEB is too * There is no GC head LEB or the free space in the GC head LEB is too
* small. Allocate gc_lnum by calling 'ubifs_find_free_leb_for_idx()' so * small, or there are not dirty LEBs. Allocate gc_lnum by calling
* GC is not run. * 'ubifs_find_free_leb_for_idx()' so GC is not run.
*/ */
lnum = ubifs_find_free_leb_for_idx(c); lnum = ubifs_find_free_leb_for_idx(c);
if (lnum < 0) { if (lnum < 0) {
......
...@@ -1307,6 +1307,8 @@ static int mount_ubifs(struct ubifs_info *c) ...@@ -1307,6 +1307,8 @@ static int mount_ubifs(struct ubifs_info *c)
if (err) if (err)
goto out_orphans; goto out_orphans;
err = ubifs_rcvry_gc_commit(c); err = ubifs_rcvry_gc_commit(c);
if (err)
goto out_orphans;
} else { } else {
err = take_gc_lnum(c); err = take_gc_lnum(c);
if (err) if (err)
...@@ -1318,7 +1320,7 @@ static int mount_ubifs(struct ubifs_info *c) ...@@ -1318,7 +1320,7 @@ static int mount_ubifs(struct ubifs_info *c)
*/ */
err = ubifs_leb_unmap(c, c->gc_lnum); err = ubifs_leb_unmap(c, c->gc_lnum);
if (err) if (err)
return err; goto out_orphans;
} }
err = dbg_check_lprops(c); err = dbg_check_lprops(c);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment