diff options
| author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-05-23 09:04:17 -0400 |
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-06-02 06:53:35 -0400 |
| commit | 90bf0265e5b0d561f215a69bb7a46c4071b2c93b (patch) | |
| tree | 7b3b1cb2f394687b5e0f841031200e9c37faef92 | |
| parent | ddbd3b61708483f73dbcc62a94d16cc7db928cba (diff) | |
UBI: introduce new constants
This patch is a clean-up and a preparation for the following
patches. It introduece constants for the return values of the
'ubi_eba_copy_leb()' function.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
| -rw-r--r-- | drivers/mtd/ubi/eba.c | 33 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 16 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 13 |
3 files changed, 36 insertions, 26 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 25def348e5ba..7ab79e247245 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -950,12 +950,7 @@ write_error: | |||
| 950 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this | 950 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this |
| 951 | * function. Returns: | 951 | * function. Returns: |
| 952 | * o %0 in case of success; | 952 | * o %0 in case of success; |
| 953 | * o %1 if the operation was canceled because the volume is being deleted | 953 | * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, or %MOVE_CANCEL_BITFLIPS; |
| 954 | * or because the PEB was put meanwhile; | ||
| 955 | * o %2 if the operation was canceled because there was a write error to the | ||
| 956 | * target PEB; | ||
| 957 | * o %-EAGAIN if the operation was canceled because a bit-flip was detected | ||
| 958 | * in the target PEB; | ||
| 959 | * o a negative error code in case of failure. | 954 | * o a negative error code in case of failure. |
| 960 | */ | 955 | */ |
| 961 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 956 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
| @@ -986,13 +981,12 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 986 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. | 981 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. |
| 987 | */ | 982 | */ |
| 988 | vol = ubi->volumes[idx]; | 983 | vol = ubi->volumes[idx]; |
| 984 | spin_unlock(&ubi->volumes_lock); | ||
| 989 | if (!vol) { | 985 | if (!vol) { |
| 990 | /* No need to do further work, cancel */ | 986 | /* No need to do further work, cancel */ |
| 991 | dbg_eba("volume %d is being removed, cancel", vol_id); | 987 | dbg_eba("volume %d is being removed, cancel", vol_id); |
| 992 | spin_unlock(&ubi->volumes_lock); | 988 | return MOVE_CANCEL_RACE; |
| 993 | return 1; | ||
| 994 | } | 989 | } |
| 995 | spin_unlock(&ubi->volumes_lock); | ||
| 996 | 990 | ||
| 997 | /* | 991 | /* |
| 998 | * We do not want anybody to write to this logical eraseblock while we | 992 | * We do not want anybody to write to this logical eraseblock while we |
| @@ -1004,12 +998,13 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1004 | * (@from). This task locks the LEB and goes sleep in the | 998 | * (@from). This task locks the LEB and goes sleep in the |
| 1005 | * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are | 999 | * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are |
| 1006 | * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the | 1000 | * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the |
| 1007 | * LEB is already locked, we just do not move it and return %1. | 1001 | * LEB is already locked, we just do not move it and return |
| 1002 | * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later. | ||
| 1008 | */ | 1003 | */ |
| 1009 | err = leb_write_trylock(ubi, vol_id, lnum); | 1004 | err = leb_write_trylock(ubi, vol_id, lnum); |
| 1010 | if (err) { | 1005 | if (err) { |
| 1011 | dbg_eba("contention on LEB %d:%d, cancel", vol_id, lnum); | 1006 | dbg_eba("contention on LEB %d:%d, cancel", vol_id, lnum); |
| 1012 | return err; | 1007 | return MOVE_CANCEL_RACE; |
| 1013 | } | 1008 | } |
| 1014 | 1009 | ||
| 1015 | /* | 1010 | /* |
| @@ -1021,14 +1016,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1021 | dbg_eba("LEB %d:%d is no longer mapped to PEB %d, mapped to " | 1016 | dbg_eba("LEB %d:%d is no longer mapped to PEB %d, mapped to " |
| 1022 | "PEB %d, cancel", vol_id, lnum, from, | 1017 | "PEB %d, cancel", vol_id, lnum, from, |
| 1023 | vol->eba_tbl[lnum]); | 1018 | vol->eba_tbl[lnum]); |
| 1024 | err = 1; | 1019 | err = MOVE_CANCEL_RACE; |
| 1025 | goto out_unlock_leb; | 1020 | goto out_unlock_leb; |
| 1026 | } | 1021 | } |
| 1027 | 1022 | ||
| 1028 | /* | 1023 | /* |
| 1029 | * OK, now the LEB is locked and we can safely start moving it. Since | 1024 | * OK, now the LEB is locked and we can safely start moving it. Since |
| 1030 | * this function utilizes the @ubi->peb1_buf buffer which is shared | 1025 | * this function utilizes the @ubi->peb_buf1 buffer which is shared |
| 1031 | * with some other functions, so lock the buffer by taking the | 1026 | * with some other functions - we lock the buffer by taking the |
| 1032 | * @ubi->buf_mutex. | 1027 | * @ubi->buf_mutex. |
| 1033 | */ | 1028 | */ |
| 1034 | mutex_lock(&ubi->buf_mutex); | 1029 | mutex_lock(&ubi->buf_mutex); |
| @@ -1059,7 +1054,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1059 | cond_resched(); | 1054 | cond_resched(); |
| 1060 | 1055 | ||
| 1061 | /* | 1056 | /* |
| 1062 | * It may turn out to me that the whole @from physical eraseblock | 1057 | * It may turn out to be that the whole @from physical eraseblock |
| 1063 | * contains only 0xFF bytes. Then we have to only write the VID header | 1058 | * contains only 0xFF bytes. Then we have to only write the VID header |
| 1064 | * and do not write any data. This also means we should not set | 1059 | * and do not write any data. This also means we should not set |
| 1065 | * @vid_hdr->copy_flag, @vid_hdr->data_size, and @vid_hdr->data_crc. | 1060 | * @vid_hdr->copy_flag, @vid_hdr->data_size, and @vid_hdr->data_crc. |
| @@ -1074,7 +1069,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1074 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); | 1069 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); |
| 1075 | if (err) { | 1070 | if (err) { |
| 1076 | if (err == -EIO) | 1071 | if (err == -EIO) |
| 1077 | err = 2; | 1072 | err = MOVE_TARGET_WR_ERR; |
| 1078 | goto out_unlock_buf; | 1073 | goto out_unlock_buf; |
| 1079 | } | 1074 | } |
| 1080 | 1075 | ||
| @@ -1086,7 +1081,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1086 | if (err != UBI_IO_BITFLIPS) | 1081 | if (err != UBI_IO_BITFLIPS) |
| 1087 | ubi_warn("cannot read VID header back from PEB %d", to); | 1082 | ubi_warn("cannot read VID header back from PEB %d", to); |
| 1088 | else | 1083 | else |
| 1089 | err = -EAGAIN; | 1084 | err = MOVE_CANCEL_BITFLIPS; |
| 1090 | goto out_unlock_buf; | 1085 | goto out_unlock_buf; |
| 1091 | } | 1086 | } |
| 1092 | 1087 | ||
| @@ -1094,7 +1089,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1094 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); | 1089 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); |
| 1095 | if (err) { | 1090 | if (err) { |
| 1096 | if (err == -EIO) | 1091 | if (err == -EIO) |
| 1097 | err = 2; | 1092 | err = MOVE_TARGET_WR_ERR; |
| 1098 | goto out_unlock_buf; | 1093 | goto out_unlock_buf; |
| 1099 | } | 1094 | } |
| 1100 | 1095 | ||
| @@ -1111,7 +1106,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1111 | ubi_warn("cannot read data back from PEB %d", | 1106 | ubi_warn("cannot read data back from PEB %d", |
| 1112 | to); | 1107 | to); |
| 1113 | else | 1108 | else |
| 1114 | err = -EAGAIN; | 1109 | err = MOVE_CANCEL_BITFLIPS; |
| 1115 | goto out_unlock_buf; | 1110 | goto out_unlock_buf; |
| 1116 | } | 1111 | } |
| 1117 | 1112 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 749007e9f1aa..fd9b20da5b6b 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -100,6 +100,22 @@ enum { | |||
| 100 | UBI_IO_BITFLIPS | 100 | UBI_IO_BITFLIPS |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | /* | ||
| 104 | * Return codes of the 'ubi_eba_copy_leb()' function. | ||
| 105 | * | ||
| 106 | * MOVE_CANCEL_RACE: canceled because the volume is being deleted, the source | ||
| 107 | * PEB was put meanwhile, or there is I/O on the source PEB | ||
| 108 | * MOVE_TARGET_WR_ERR: canceled because there was a write error to the target | ||
| 109 | * PEB | ||
| 110 | * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the | ||
| 111 | * target PEB | ||
| 112 | */ | ||
| 113 | enum { | ||
| 114 | MOVE_CANCEL_RACE = 1, | ||
| 115 | MOVE_TARGET_WR_ERR, | ||
| 116 | MOVE_CANCEL_BITFLIPS, | ||
| 117 | }; | ||
| 118 | |||
| 103 | /** | 119 | /** |
| 104 | * struct ubi_wl_entry - wear-leveling entry. | 120 | * struct ubi_wl_entry - wear-leveling entry. |
| 105 | * @u.rb: link in the corresponding (free/used) RB-tree | 121 | * @u.rb: link in the corresponding (free/used) RB-tree |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 891534f8210d..ec915c02301c 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -756,15 +756,14 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 756 | 756 | ||
| 757 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); | 757 | err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); |
| 758 | if (err) { | 758 | if (err) { |
| 759 | if (err == -EAGAIN) | 759 | if (err == MOVE_CANCEL_BITFLIPS || |
| 760 | goto out_not_moved; | 760 | err == MOVE_TARGET_WR_ERR) { |
| 761 | if (err < 0) | 761 | /* Target PEB bit-flips or write error, torture it */ |
| 762 | goto out_error; | ||
| 763 | if (err == 2) { | ||
| 764 | /* Target PEB write error, torture it */ | ||
| 765 | torture = 1; | 762 | torture = 1; |
| 766 | goto out_not_moved; | 763 | goto out_not_moved; |
| 767 | } | 764 | } |
| 765 | if (err < 0) | ||
| 766 | goto out_error; | ||
| 768 | 767 | ||
| 769 | /* | 768 | /* |
| 770 | * The LEB has not been moved because the volume is being | 769 | * The LEB has not been moved because the volume is being |
| @@ -774,7 +773,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 774 | */ | 773 | */ |
| 775 | 774 | ||
| 776 | dbg_wl("canceled moving PEB %d", e1->pnum); | 775 | dbg_wl("canceled moving PEB %d", e1->pnum); |
| 777 | ubi_assert(err == 1); | 776 | ubi_assert(err == MOVE_CANCEL_RACE); |
| 778 | 777 | ||
| 779 | ubi_free_vid_hdr(ubi, vid_hdr); | 778 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 780 | vid_hdr = NULL; | 779 | vid_hdr = NULL; |
