diff options
-rw-r--r-- | drivers/mtd/ubi/eba.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 5 |
3 files changed, 10 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index fb7f19b62d91..cd26da8ad225 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -1028,12 +1028,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1028 | * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are | 1028 | * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are |
1029 | * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the | 1029 | * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the |
1030 | * LEB is already locked, we just do not move it and return | 1030 | * LEB is already locked, we just do not move it and return |
1031 | * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later. | 1031 | * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because |
1032 | * we do not know the reasons of the contention - it may be just a | ||
1033 | * normal I/O on this LEB, so we want to re-try. | ||
1032 | */ | 1034 | */ |
1033 | err = leb_write_trylock(ubi, vol_id, lnum); | 1035 | err = leb_write_trylock(ubi, vol_id, lnum); |
1034 | if (err) { | 1036 | if (err) { |
1035 | dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum); | 1037 | dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum); |
1036 | return MOVE_CANCEL_RACE; | 1038 | return MOVE_RETRY; |
1037 | } | 1039 | } |
1038 | 1040 | ||
1039 | /* | 1041 | /* |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index dc64c767fd21..d51d75d34446 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -120,6 +120,7 @@ enum { | |||
120 | * PEB | 120 | * PEB |
121 | * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the | 121 | * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the |
122 | * target PEB | 122 | * target PEB |
123 | * MOVE_RETRY: retry scrubbing the PEB | ||
123 | */ | 124 | */ |
124 | enum { | 125 | enum { |
125 | MOVE_CANCEL_RACE = 1, | 126 | MOVE_CANCEL_RACE = 1, |
@@ -127,6 +128,7 @@ enum { | |||
127 | MOVE_TARGET_RD_ERR, | 128 | MOVE_TARGET_RD_ERR, |
128 | MOVE_TARGET_WR_ERR, | 129 | MOVE_TARGET_WR_ERR, |
129 | MOVE_CANCEL_BITFLIPS, | 130 | MOVE_CANCEL_BITFLIPS, |
131 | MOVE_RETRY, | ||
130 | }; | 132 | }; |
131 | 133 | ||
132 | /** | 134 | /** |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 42c684cf3688..277c429a138f 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -795,7 +795,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
795 | protect = 1; | 795 | protect = 1; |
796 | goto out_not_moved; | 796 | goto out_not_moved; |
797 | } | 797 | } |
798 | 798 | if (err == MOVE_RETRY) { | |
799 | scrubbing = 1; | ||
800 | goto out_not_moved; | ||
801 | } | ||
799 | if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || | 802 | if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || |
800 | err == MOVE_TARGET_RD_ERR) { | 803 | err == MOVE_TARGET_RD_ERR) { |
801 | /* | 804 | /* |