diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-03 17:37:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-03 17:37:02 -0400 |
commit | c939f9f9d225972a60181c95df8a9aa50f8b1701 (patch) | |
tree | 06f7621294bab5862ca15fa8c3749edcfc1ead3c /fs/ubifs | |
parent | b8b3e9058f0f1d5c5a81c7d3d46f373d5f59a82c (diff) | |
parent | c18de72fb3c72fdc5ca883910761af3f14d90d76 (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
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/lpt.c | 14 | ||||
-rw-r--r-- | fs/ubifs/lpt_commit.c | 2 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 23 | ||||
-rw-r--r-- | fs/ubifs/super.c | 4 |
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) | |||
1139 | find_free: | 1152 | find_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); |