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 109c6ea03bb..daae9e1f538 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -24,7 +24,7 @@   * 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   * 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   * errors do not accumulate. However UBIFS defers recovery if it is mounted   * 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);  	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;  	}  	ubifs_assert(!(lp.flags & LPROPS_INDEX)); @@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)  find_free:  	/*  	 * 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);  	if (lnum < 0) {  |