aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-05-23 09:04:17 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-02 06:53:35 -0400
commit90bf0265e5b0d561f215a69bb7a46c4071b2c93b (patch)
tree7b3b1cb2f394687b5e0f841031200e9c37faef92 /drivers
parentddbd3b61708483f73dbcc62a94d16cc7db928cba (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/ubi/eba.c33
-rw-r--r--drivers/mtd/ubi/ubi.h16
-rw-r--r--drivers/mtd/ubi/wl.c13
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 */
961int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, 956int 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 */
113enum {
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;