diff options
| -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) { | 
