diff options
Diffstat (limited to 'fs/ubifs/recovery.c')
-rw-r--r-- | fs/ubifs/recovery.c | 23 |
1 files changed, 18 insertions, 5 deletions
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) { |