|
@@ -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)
|
|
}
|
|
}
|
|
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)
|
|
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
|
|
|
|
- * GC is not run.
|
|
|
|
|
|
+ * small, or there are not dirty LEBs. Allocate gc_lnum by calling
|
|
|
|
+ * '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) {
|