aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-10 04:32:05 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-10 09:13:28 -0400
commit6b5c94c6b4e1630a8e1ee7d30383d9396603749f (patch)
tree28e1ab5143f317d561197b3bebfe2994c12ddec8 /drivers/mtd
parent815bc5f8fe516f55291aef90f2142073821e7a9c (diff)
UBI: handle more error codes
The UBIFS WL worker may encounter read errors and there is logic which makes a decision whether we should do one of: 1. cancel the operation and move the PEB with the read errors to the 'erroneous' list; 2. switch to R/O mode. ATM, only -EIO errors trigger 1., other errors trigger 2. The idea is that if we know we encountered an I/O error, do 1. Otherwise, we do not know how to react, and do 2., just in case. E.g., if the underlying driver became crazy because of a bug, we do not want to harm any data, and switch to R/O mode. This patch does 2 things: 1. Makes sure reads from the source PEB always cause 1. This is more consistent with other reads which come from the upper layers and never cause R/O. 2. Teaches UBI to do 1. also on -EBADMSG, UBI_IO_BAD_VID_HDR, -ENOMEM, and -ETIMEOUT. But this is only when reading the target PEB. This preblems were hunted by Adrian Hunter. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/eba.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index b6565561218e..0f2034c3ed2f 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -941,6 +941,33 @@ write_error:
941} 941}
942 942
943/** 943/**
944 * is_error_sane - check whether a read error is sane.
945 * @err: code of the error happened during reading
946 *
947 * This is a helper function for 'ubi_eba_copy_leb()' which is called when we
948 * cannot read data from the target PEB (an error @err happened). If the error
949 * code is sane, then we treat this error as non-fatal. Otherwise the error is
950 * fatal and UBI will be switched to R/O mode later.
951 *
952 * The idea is that we try not to switch to R/O mode if the read error is
953 * something which suggests there was a real read problem. E.g., %-EIO. Or a
954 * memory allocation failed (-%ENOMEM). Otherwise, it is safer to switch to R/O
955 * mode, simply because we do not know what happened at the MTD level, and we
956 * cannot handle this. E.g., the underlying driver may have become crazy, and
957 * it is safer to switch to R/O mode to preserve the data.
958 *
959 * And bear in mind, this is about reading from the target PEB, i.e. the PEB
960 * which we have just written.
961 */
962static int is_error_sane(int err)
963{
964 if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_VID_HDR ||
965 err == -ETIMEDOUT)
966 return 0;
967 return 1;
968}
969
970/**
944 * ubi_eba_copy_leb - copy logical eraseblock. 971 * ubi_eba_copy_leb - copy logical eraseblock.
945 * @ubi: UBI device description object 972 * @ubi: UBI device description object
946 * @from: physical eraseblock number from where to copy 973 * @from: physical eraseblock number from where to copy
@@ -1033,8 +1060,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1033 if (err && err != UBI_IO_BITFLIPS) { 1060 if (err && err != UBI_IO_BITFLIPS) {
1034 ubi_warn("error %d while reading data from PEB %d", 1061 ubi_warn("error %d while reading data from PEB %d",
1035 err, from); 1062 err, from);
1036 if (err == -EIO) 1063 err = MOVE_SOURCE_RD_ERR;
1037 err = MOVE_SOURCE_RD_ERR;
1038 goto out_unlock_buf; 1064 goto out_unlock_buf;
1039 } 1065 }
1040 1066
@@ -1082,8 +1108,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1082 err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); 1108 err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1);
1083 if (err) { 1109 if (err) {
1084 if (err != UBI_IO_BITFLIPS) { 1110 if (err != UBI_IO_BITFLIPS) {
1085 ubi_warn("cannot read VID header back from PEB %d", to); 1111 ubi_warn("error %d while reading VID header back from "
1086 if (err == -EIO) 1112 "PEB %d", err, to);
1113 if (is_error_sane(err))
1087 err = MOVE_TARGET_RD_ERR; 1114 err = MOVE_TARGET_RD_ERR;
1088 } else 1115 } else
1089 err = MOVE_CANCEL_BITFLIPS; 1116 err = MOVE_CANCEL_BITFLIPS;
@@ -1108,9 +1135,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1108 err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); 1135 err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size);
1109 if (err) { 1136 if (err) {
1110 if (err != UBI_IO_BITFLIPS) { 1137 if (err != UBI_IO_BITFLIPS) {
1111 ubi_warn("cannot read data back from PEB %d", 1138 ubi_warn("error %d while reading data back "
1112 to); 1139 "from PEB %d", err, to);
1113 if (err == -EIO) 1140 if (is_error_sane(err))
1114 err = MOVE_TARGET_RD_ERR; 1141 err = MOVE_TARGET_RD_ERR;
1115 } else 1142 } else
1116 err = MOVE_CANCEL_BITFLIPS; 1143 err = MOVE_CANCEL_BITFLIPS;