Skip to content

Commit

Permalink
UBI: fix missing scrub when there is a bit-flip
Browse files Browse the repository at this point in the history
Under some cases, when scrubbing the PEB if we did not get the lock on
the PEB it fails to scrub. Add that PEB again to the scrub list

Artem: minor amendments.

Cc: stable@kernel.org [2.6.31+]
Signed-off-by: Bhavesh Parekh <bparekh@nvidia.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
  • Loading branch information
Bhavesh Parekh authored and Artem Bityutskiy committed Nov 30, 2011
1 parent eaecf43 commit e801e12
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
6 changes: 4 additions & 2 deletions drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -1028,12 +1028,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
* 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are
* holding @ubi->move_mutex and go sleep on the LEB lock. So, if the
* LEB is already locked, we just do not move it and return
* %MOVE_CANCEL_RACE, which means that UBI will re-try, but later.
* %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because
* we do not know the reasons of the contention - it may be just a
* normal I/O on this LEB, so we want to re-try.
*/
err = leb_write_trylock(ubi, vol_id, lnum);
if (err) {
dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum);
return MOVE_CANCEL_RACE;
return MOVE_RETRY;
}

/*
Expand Down
2 changes: 2 additions & 0 deletions drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,15 @@ enum {
* PEB
* MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the
* target PEB
* MOVE_RETRY: retry scrubbing the PEB
*/
enum {
MOVE_CANCEL_RACE = 1,
MOVE_SOURCE_RD_ERR,
MOVE_TARGET_RD_ERR,
MOVE_TARGET_WR_ERR,
MOVE_CANCEL_BITFLIPS,
MOVE_RETRY,
};

/**
Expand Down
5 changes: 4 additions & 1 deletion drivers/mtd/ubi/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
protect = 1;
goto out_not_moved;
}

if (err == MOVE_RETRY) {
scrubbing = 1;
goto out_not_moved;
}
if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR ||
err == MOVE_TARGET_RD_ERR) {
/*
Expand Down

0 comments on commit e801e12

Please sign in to comment.