aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-03 17:37:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-03 17:37:02 -0400
commitc939f9f9d225972a60181c95df8a9aa50f8b1701 (patch)
tree06f7621294bab5862ca15fa8c3749edcfc1ead3c
parentb8b3e9058f0f1d5c5a81c7d3d46f373d5f59a82c (diff)
parentc18de72fb3c72fdc5ca883910761af3f14d90d76 (diff)
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
-rw-r--r--fs/ubifs/lpt.c14
-rw-r--r--fs/ubifs/lpt_commit.c2
-rw-r--r--fs/ubifs/recovery.c23
-rw-r--r--fs/ubifs/super.c4
4 files changed, 29 insertions, 14 deletions
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index ad7f67b827ea..0084a33c4c69 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1457,13 +1457,13 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum)
1457 shft -= UBIFS_LPT_FANOUT_SHIFT; 1457 shft -= UBIFS_LPT_FANOUT_SHIFT;
1458 nnode = ubifs_get_nnode(c, nnode, iip); 1458 nnode = ubifs_get_nnode(c, nnode, iip);
1459 if (IS_ERR(nnode)) 1459 if (IS_ERR(nnode))
1460 return ERR_PTR(PTR_ERR(nnode)); 1460 return ERR_CAST(nnode);
1461 } 1461 }
1462 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); 1462 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
1463 shft -= UBIFS_LPT_FANOUT_SHIFT; 1463 shft -= UBIFS_LPT_FANOUT_SHIFT;
1464 pnode = ubifs_get_pnode(c, nnode, iip); 1464 pnode = ubifs_get_pnode(c, nnode, iip);
1465 if (IS_ERR(pnode)) 1465 if (IS_ERR(pnode))
1466 return ERR_PTR(PTR_ERR(pnode)); 1466 return ERR_CAST(pnode);
1467 iip = (i & (UBIFS_LPT_FANOUT - 1)); 1467 iip = (i & (UBIFS_LPT_FANOUT - 1));
1468 dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, 1468 dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
1469 pnode->lprops[iip].free, pnode->lprops[iip].dirty, 1469 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 nnode = c->nroot; 1586 nnode = c->nroot;
1587 nnode = dirty_cow_nnode(c, nnode); 1587 nnode = dirty_cow_nnode(c, nnode);
1588 if (IS_ERR(nnode)) 1588 if (IS_ERR(nnode))
1589 return ERR_PTR(PTR_ERR(nnode)); 1589 return ERR_CAST(nnode);
1590 i = lnum - c->main_first; 1590 i = lnum - c->main_first;
1591 shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; 1591 shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT;
1592 for (h = 1; h < c->lpt_hght; h++) { 1592 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 shft -= UBIFS_LPT_FANOUT_SHIFT; 1594 shft -= UBIFS_LPT_FANOUT_SHIFT;
1595 nnode = ubifs_get_nnode(c, nnode, iip); 1595 nnode = ubifs_get_nnode(c, nnode, iip);
1596 if (IS_ERR(nnode)) 1596 if (IS_ERR(nnode))
1597 return ERR_PTR(PTR_ERR(nnode)); 1597 return ERR_CAST(nnode);
1598 nnode = dirty_cow_nnode(c, nnode); 1598 nnode = dirty_cow_nnode(c, nnode);
1599 if (IS_ERR(nnode)) 1599 if (IS_ERR(nnode))
1600 return ERR_PTR(PTR_ERR(nnode)); 1600 return ERR_CAST(nnode);
1601 } 1601 }
1602 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); 1602 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
1603 shft -= UBIFS_LPT_FANOUT_SHIFT; 1603 shft -= UBIFS_LPT_FANOUT_SHIFT;
1604 pnode = ubifs_get_pnode(c, nnode, iip); 1604 pnode = ubifs_get_pnode(c, nnode, iip);
1605 if (IS_ERR(pnode)) 1605 if (IS_ERR(pnode))
1606 return ERR_PTR(PTR_ERR(pnode)); 1606 return ERR_CAST(pnode);
1607 pnode = dirty_cow_pnode(c, pnode); 1607 pnode = dirty_cow_pnode(c, pnode);
1608 if (IS_ERR(pnode)) 1608 if (IS_ERR(pnode))
1609 return ERR_PTR(PTR_ERR(pnode)); 1609 return ERR_CAST(pnode);
1610 iip = (i & (UBIFS_LPT_FANOUT - 1)); 1610 iip = (i & (UBIFS_LPT_FANOUT - 1));
1611 dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, 1611 dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
1612 pnode->lprops[iip].free, pnode->lprops[iip].dirty, 1612 pnode->lprops[iip].free, pnode->lprops[iip].dirty,
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 13cb7a4237bf..d12535b7fc78 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -646,7 +646,7 @@ static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i)
646 shft -= UBIFS_LPT_FANOUT_SHIFT; 646 shft -= UBIFS_LPT_FANOUT_SHIFT;
647 nnode = ubifs_get_nnode(c, nnode, iip); 647 nnode = ubifs_get_nnode(c, nnode, iip);
648 if (IS_ERR(nnode)) 648 if (IS_ERR(nnode))
649 return ERR_PTR(PTR_ERR(nnode)); 649 return ERR_CAST(nnode);
650 } 650 }
651 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); 651 iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
652 return ubifs_get_pnode(c, nnode, iip); 652 return ubifs_get_pnode(c, nnode, iip);
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 109c6ea03bb5..daae9e1f5382 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -24,7 +24,7 @@
24 * This file implements functions needed to recover from unclean un-mounts. 24 * This file implements functions needed to recover from unclean un-mounts.
25 * When UBIFS is mounted, it checks a flag on the master node to determine if 25 * When UBIFS is mounted, it checks a flag on the master node to determine if
26 * an un-mount was completed successfully. If not, the process of mounting 26 * an un-mount was completed successfully. If not, the process of mounting
27 * incorparates additional checking and fixing of on-flash data structures. 27 * incorporates additional checking and fixing of on-flash data structures.
28 * UBIFS always cleans away all remnants of an unclean un-mount, so that 28 * UBIFS always cleans away all remnants of an unclean un-mount, so that
29 * errors do not accumulate. However UBIFS defers recovery if it is mounted 29 * errors do not accumulate. However UBIFS defers recovery if it is mounted
30 * read-only, and the flash is not modified in that case. 30 * 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 } 1063 }
1064 err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); 1064 err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2);
1065 if (err) { 1065 if (err) {
1066 if (err == -ENOSPC) 1066 /*
1067 dbg_err("could not find a dirty LEB"); 1067 * There are no dirty or empty LEBs subject to here being
1068 * enough for the index. Try to use
1069 * 'ubifs_find_free_leb_for_idx()', which will return any empty
1070 * LEBs (ignoring index requirements). If the index then
1071 * doesn't have enough LEBs the recovery commit will fail -
1072 * which is the same result anyway i.e. recovery fails. So
1073 * there is no problem ignoring index requirements and just
1074 * grabbing a free LEB since we have already established there
1075 * is not a dirty LEB we could have used instead.
1076 */
1077 if (err == -ENOSPC) {
1078 dbg_rcvry("could not find a dirty LEB");
1079 goto find_free;
1080 }
1068 return err; 1081 return err;
1069 } 1082 }
1070 ubifs_assert(!(lp.flags & LPROPS_INDEX)); 1083 ubifs_assert(!(lp.flags & LPROPS_INDEX));
@@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
1139find_free: 1152find_free:
1140 /* 1153 /*
1141 * There is no GC head LEB or the free space in the GC head LEB is too 1154 * There is no GC head LEB or the free space in the GC head LEB is too
1142 * small. Allocate gc_lnum by calling 'ubifs_find_free_leb_for_idx()' so 1155 * small, or there are not dirty LEBs. Allocate gc_lnum by calling
1143 * GC is not run. 1156 * 'ubifs_find_free_leb_for_idx()' so GC is not run.
1144 */ 1157 */
1145 lnum = ubifs_find_free_leb_for_idx(c); 1158 lnum = ubifs_find_free_leb_for_idx(c);
1146 if (lnum < 0) { 1159 if (lnum < 0) {
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 4d2f2157dd3f..5fc5a0988970 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1307,6 +1307,8 @@ static int mount_ubifs(struct ubifs_info *c)
1307 if (err) 1307 if (err)
1308 goto out_orphans; 1308 goto out_orphans;
1309 err = ubifs_rcvry_gc_commit(c); 1309 err = ubifs_rcvry_gc_commit(c);
1310 if (err)
1311 goto out_orphans;
1310 } else { 1312 } else {
1311 err = take_gc_lnum(c); 1313 err = take_gc_lnum(c);
1312 if (err) 1314 if (err)
@@ -1318,7 +1320,7 @@ static int mount_ubifs(struct ubifs_info *c)
1318 */ 1320 */
1319 err = ubifs_leb_unmap(c, c->gc_lnum); 1321 err = ubifs_leb_unmap(c, c->gc_lnum);
1320 if (err) 1322 if (err)
1321 return err; 1323 goto out_orphans;
1322 } 1324 }
1323 1325
1324 err = dbg_check_lprops(c); 1326 err = dbg_check_lprops(c);