diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 12:25:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 12:25:31 -0400 |
commit | 7e61b3ff50f59f134054aaf43096c761fafecf0c (patch) | |
tree | f592c876b8c8c3e8b9ba69dd2bd49f57412f6a6e | |
parent | 6e55f8ed814940b0b7420ed633c08e61702bb8d4 (diff) | |
parent | cc831464f839dc2559f896b96d13eaa0366282b0 (diff) |
Merge tag 'upstream-3.4-rc1' of git://git.infradead.org/linux-ubi
Pull UBI changes from Artem Bityutskiy:
- Reduce memory consumption
- Fix picking unknown blocks
- Fix error-path in 'ubi_scan()'
- Minor clean-ups
* tag 'upstream-3.4-rc1' of git://git.infradead.org/linux-ubi:
UBI: rename MOVE_CANCEL_BITFLIPS to MOVE_TARGET_BITFLIPS
UBI: rename peb_buf1 to peb_buf
UBI: reduce memory consumption
UBI: fix eraseblock picking criteria
UBI: fix documentation and improve readability
UBI: fix error handling in ubi_scan()
-rw-r--r-- | drivers/mtd/ubi/build.c | 14 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 30 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 14 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 16 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 12 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 21 |
6 files changed, 49 insertions, 58 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 115749f20f9e..0fde9fc7d2e5 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -945,12 +945,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
945 | goto out_free; | 945 | goto out_free; |
946 | 946 | ||
947 | err = -ENOMEM; | 947 | err = -ENOMEM; |
948 | ubi->peb_buf1 = vmalloc(ubi->peb_size); | 948 | ubi->peb_buf = vmalloc(ubi->peb_size); |
949 | if (!ubi->peb_buf1) | 949 | if (!ubi->peb_buf) |
950 | goto out_free; | ||
951 | |||
952 | ubi->peb_buf2 = vmalloc(ubi->peb_size); | ||
953 | if (!ubi->peb_buf2) | ||
954 | goto out_free; | 950 | goto out_free; |
955 | 951 | ||
956 | err = ubi_debugging_init_dev(ubi); | 952 | err = ubi_debugging_init_dev(ubi); |
@@ -1029,8 +1025,7 @@ out_detach: | |||
1029 | out_debugging: | 1025 | out_debugging: |
1030 | ubi_debugging_exit_dev(ubi); | 1026 | ubi_debugging_exit_dev(ubi); |
1031 | out_free: | 1027 | out_free: |
1032 | vfree(ubi->peb_buf1); | 1028 | vfree(ubi->peb_buf); |
1033 | vfree(ubi->peb_buf2); | ||
1034 | if (ref) | 1029 | if (ref) |
1035 | put_device(&ubi->dev); | 1030 | put_device(&ubi->dev); |
1036 | else | 1031 | else |
@@ -1101,8 +1096,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
1101 | vfree(ubi->vtbl); | 1096 | vfree(ubi->vtbl); |
1102 | put_mtd_device(ubi->mtd); | 1097 | put_mtd_device(ubi->mtd); |
1103 | ubi_debugging_exit_dev(ubi); | 1098 | ubi_debugging_exit_dev(ubi); |
1104 | vfree(ubi->peb_buf1); | 1099 | vfree(ubi->peb_buf); |
1105 | vfree(ubi->peb_buf2); | ||
1106 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 1100 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |
1107 | put_device(&ubi->dev); | 1101 | put_device(&ubi->dev); |
1108 | return 0; | 1102 | return 0; |
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index cd26da8ad225..2455d620d96b 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -529,18 +529,18 @@ retry: | |||
529 | 529 | ||
530 | data_size = offset + len; | 530 | data_size = offset + len; |
531 | mutex_lock(&ubi->buf_mutex); | 531 | mutex_lock(&ubi->buf_mutex); |
532 | memset(ubi->peb_buf1 + offset, 0xFF, len); | 532 | memset(ubi->peb_buf + offset, 0xFF, len); |
533 | 533 | ||
534 | /* Read everything before the area where the write failure happened */ | 534 | /* Read everything before the area where the write failure happened */ |
535 | if (offset > 0) { | 535 | if (offset > 0) { |
536 | err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); | 536 | err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); |
537 | if (err && err != UBI_IO_BITFLIPS) | 537 | if (err && err != UBI_IO_BITFLIPS) |
538 | goto out_unlock; | 538 | goto out_unlock; |
539 | } | 539 | } |
540 | 540 | ||
541 | memcpy(ubi->peb_buf1 + offset, buf, len); | 541 | memcpy(ubi->peb_buf + offset, buf, len); |
542 | 542 | ||
543 | err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); | 543 | err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); |
544 | if (err) { | 544 | if (err) { |
545 | mutex_unlock(&ubi->buf_mutex); | 545 | mutex_unlock(&ubi->buf_mutex); |
546 | goto write_error; | 546 | goto write_error; |
@@ -979,7 +979,7 @@ static int is_error_sane(int err) | |||
979 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this | 979 | * physical eraseblock @to. The @vid_hdr buffer may be changed by this |
980 | * function. Returns: | 980 | * function. Returns: |
981 | * o %0 in case of success; | 981 | * o %0 in case of success; |
982 | * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, %MOVE_CANCEL_BITFLIPS, etc; | 982 | * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, %MOVE_TARGET_BITFLIPS, etc; |
983 | * o a negative error code in case of failure. | 983 | * o a negative error code in case of failure. |
984 | */ | 984 | */ |
985 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 985 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
@@ -1053,13 +1053,13 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1053 | 1053 | ||
1054 | /* | 1054 | /* |
1055 | * OK, now the LEB is locked and we can safely start moving it. Since | 1055 | * OK, now the LEB is locked and we can safely start moving it. Since |
1056 | * this function utilizes the @ubi->peb_buf1 buffer which is shared | 1056 | * this function utilizes the @ubi->peb_buf buffer which is shared |
1057 | * with some other functions - we lock the buffer by taking the | 1057 | * with some other functions - we lock the buffer by taking the |
1058 | * @ubi->buf_mutex. | 1058 | * @ubi->buf_mutex. |
1059 | */ | 1059 | */ |
1060 | mutex_lock(&ubi->buf_mutex); | 1060 | mutex_lock(&ubi->buf_mutex); |
1061 | dbg_wl("read %d bytes of data", aldata_size); | 1061 | dbg_wl("read %d bytes of data", aldata_size); |
1062 | err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); | 1062 | err = ubi_io_read_data(ubi, ubi->peb_buf, from, 0, aldata_size); |
1063 | if (err && err != UBI_IO_BITFLIPS) { | 1063 | if (err && err != UBI_IO_BITFLIPS) { |
1064 | ubi_warn("error %d while reading data from PEB %d", | 1064 | ubi_warn("error %d while reading data from PEB %d", |
1065 | err, from); | 1065 | err, from); |
@@ -1079,10 +1079,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1079 | */ | 1079 | */ |
1080 | if (vid_hdr->vol_type == UBI_VID_DYNAMIC) | 1080 | if (vid_hdr->vol_type == UBI_VID_DYNAMIC) |
1081 | aldata_size = data_size = | 1081 | aldata_size = data_size = |
1082 | ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); | 1082 | ubi_calc_data_len(ubi, ubi->peb_buf, data_size); |
1083 | 1083 | ||
1084 | cond_resched(); | 1084 | cond_resched(); |
1085 | crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); | 1085 | crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size); |
1086 | cond_resched(); | 1086 | cond_resched(); |
1087 | 1087 | ||
1088 | /* | 1088 | /* |
@@ -1116,12 +1116,12 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1116 | if (is_error_sane(err)) | 1116 | if (is_error_sane(err)) |
1117 | err = MOVE_TARGET_RD_ERR; | 1117 | err = MOVE_TARGET_RD_ERR; |
1118 | } else | 1118 | } else |
1119 | err = MOVE_CANCEL_BITFLIPS; | 1119 | err = MOVE_TARGET_BITFLIPS; |
1120 | goto out_unlock_buf; | 1120 | goto out_unlock_buf; |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (data_size > 0) { | 1123 | if (data_size > 0) { |
1124 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); | 1124 | err = ubi_io_write_data(ubi, ubi->peb_buf, to, 0, aldata_size); |
1125 | if (err) { | 1125 | if (err) { |
1126 | if (err == -EIO) | 1126 | if (err == -EIO) |
1127 | err = MOVE_TARGET_WR_ERR; | 1127 | err = MOVE_TARGET_WR_ERR; |
@@ -1134,8 +1134,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1134 | * We've written the data and are going to read it back to make | 1134 | * We've written the data and are going to read it back to make |
1135 | * sure it was written correctly. | 1135 | * sure it was written correctly. |
1136 | */ | 1136 | */ |
1137 | 1137 | memset(ubi->peb_buf, 0xFF, aldata_size); | |
1138 | err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); | 1138 | err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); |
1139 | if (err) { | 1139 | if (err) { |
1140 | if (err != UBI_IO_BITFLIPS) { | 1140 | if (err != UBI_IO_BITFLIPS) { |
1141 | ubi_warn("error %d while reading data back " | 1141 | ubi_warn("error %d while reading data back " |
@@ -1143,13 +1143,13 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1143 | if (is_error_sane(err)) | 1143 | if (is_error_sane(err)) |
1144 | err = MOVE_TARGET_RD_ERR; | 1144 | err = MOVE_TARGET_RD_ERR; |
1145 | } else | 1145 | } else |
1146 | err = MOVE_CANCEL_BITFLIPS; | 1146 | err = MOVE_TARGET_BITFLIPS; |
1147 | goto out_unlock_buf; | 1147 | goto out_unlock_buf; |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | cond_resched(); | 1150 | cond_resched(); |
1151 | 1151 | ||
1152 | if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { | 1152 | if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { |
1153 | ubi_warn("read data back from PEB %d and it is " | 1153 | ubi_warn("read data back from PEB %d and it is " |
1154 | "different", to); | 1154 | "different", to); |
1155 | err = -EINVAL; | 1155 | err = -EINVAL; |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 5cde4e5ca3e5..43f1a0011a55 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -431,11 +431,11 @@ static int torture_peb(struct ubi_device *ubi, int pnum) | |||
431 | goto out; | 431 | goto out; |
432 | 432 | ||
433 | /* Make sure the PEB contains only 0xFF bytes */ | 433 | /* Make sure the PEB contains only 0xFF bytes */ |
434 | err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); | 434 | err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); |
435 | if (err) | 435 | if (err) |
436 | goto out; | 436 | goto out; |
437 | 437 | ||
438 | err = ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); | 438 | err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); |
439 | if (err == 0) { | 439 | if (err == 0) { |
440 | ubi_err("erased PEB %d, but a non-0xFF byte found", | 440 | ubi_err("erased PEB %d, but a non-0xFF byte found", |
441 | pnum); | 441 | pnum); |
@@ -444,17 +444,17 @@ static int torture_peb(struct ubi_device *ubi, int pnum) | |||
444 | } | 444 | } |
445 | 445 | ||
446 | /* Write a pattern and check it */ | 446 | /* Write a pattern and check it */ |
447 | memset(ubi->peb_buf1, patterns[i], ubi->peb_size); | 447 | memset(ubi->peb_buf, patterns[i], ubi->peb_size); |
448 | err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); | 448 | err = ubi_io_write(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); |
449 | if (err) | 449 | if (err) |
450 | goto out; | 450 | goto out; |
451 | 451 | ||
452 | memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); | 452 | memset(ubi->peb_buf, ~patterns[i], ubi->peb_size); |
453 | err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); | 453 | err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); |
454 | if (err) | 454 | if (err) |
455 | goto out; | 455 | goto out; |
456 | 456 | ||
457 | err = ubi_check_pattern(ubi->peb_buf1, patterns[i], | 457 | err = ubi_check_pattern(ubi->peb_buf, patterns[i], |
458 | ubi->peb_size); | 458 | ubi->peb_size); |
459 | if (err == 0) { | 459 | if (err == 0) { |
460 | ubi_err("pattern %x checking failed for PEB %d", | 460 | ubi_err("pattern %x checking failed for PEB %d", |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 0cb17d936b5a..12c43b44f815 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -789,9 +789,9 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, | |||
789 | int err; | 789 | int err; |
790 | 790 | ||
791 | mutex_lock(&ubi->buf_mutex); | 791 | mutex_lock(&ubi->buf_mutex); |
792 | memset(ubi->peb_buf1, 0x00, ubi->leb_size); | 792 | memset(ubi->peb_buf, 0x00, ubi->leb_size); |
793 | 793 | ||
794 | err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start, | 794 | err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start, |
795 | ubi->leb_size); | 795 | ubi->leb_size); |
796 | if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { | 796 | if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { |
797 | /* | 797 | /* |
@@ -808,7 +808,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, | |||
808 | if (err) | 808 | if (err) |
809 | goto out_unlock; | 809 | goto out_unlock; |
810 | 810 | ||
811 | if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) | 811 | if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) |
812 | goto out_unlock; | 812 | goto out_unlock; |
813 | 813 | ||
814 | ubi_err("PEB %d contains corrupted VID header, and the data does not " | 814 | ubi_err("PEB %d contains corrupted VID header, and the data does not " |
@@ -818,7 +818,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, | |||
818 | dbg_msg("hexdump of PEB %d offset %d, length %d", | 818 | dbg_msg("hexdump of PEB %d offset %d, length %d", |
819 | pnum, ubi->leb_start, ubi->leb_size); | 819 | pnum, ubi->leb_start, ubi->leb_size); |
820 | ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | 820 | ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, |
821 | ubi->peb_buf1, ubi->leb_size, 1); | 821 | ubi->peb_buf, ubi->leb_size, 1); |
822 | err = 1; | 822 | err = 1; |
823 | 823 | ||
824 | out_unlock: | 824 | out_unlock: |
@@ -1174,7 +1174,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
1174 | 1174 | ||
1175 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 1175 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); |
1176 | if (!ech) | 1176 | if (!ech) |
1177 | goto out_slab; | 1177 | goto out_si; |
1178 | 1178 | ||
1179 | vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); | 1179 | vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); |
1180 | if (!vidh) | 1180 | if (!vidh) |
@@ -1235,8 +1235,6 @@ out_vidh: | |||
1235 | ubi_free_vid_hdr(ubi, vidh); | 1235 | ubi_free_vid_hdr(ubi, vidh); |
1236 | out_ech: | 1236 | out_ech: |
1237 | kfree(ech); | 1237 | kfree(ech); |
1238 | out_slab: | ||
1239 | kmem_cache_destroy(si->scan_leb_slab); | ||
1240 | out_si: | 1238 | out_si: |
1241 | ubi_scan_destroy_si(si); | 1239 | ubi_scan_destroy_si(si); |
1242 | return ERR_PTR(err); | 1240 | return ERR_PTR(err); |
@@ -1325,7 +1323,9 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) | |||
1325 | } | 1323 | } |
1326 | } | 1324 | } |
1327 | 1325 | ||
1328 | kmem_cache_destroy(si->scan_leb_slab); | 1326 | if (si->scan_leb_slab) |
1327 | kmem_cache_destroy(si->scan_leb_slab); | ||
1328 | |||
1329 | kfree(si); | 1329 | kfree(si); |
1330 | } | 1330 | } |
1331 | 1331 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index d51d75d34446..b162790790a9 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -118,7 +118,7 @@ enum { | |||
118 | * PEB | 118 | * PEB |
119 | * MOVE_TARGET_WR_ERR: canceled because there was a write error to the target | 119 | * MOVE_TARGET_WR_ERR: canceled because there was a write error to the target |
120 | * PEB | 120 | * PEB |
121 | * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the | 121 | * MOVE_TARGET_BITFLIPS: canceled because a bit-flip was detected in the |
122 | * target PEB | 122 | * target PEB |
123 | * MOVE_RETRY: retry scrubbing the PEB | 123 | * MOVE_RETRY: retry scrubbing the PEB |
124 | */ | 124 | */ |
@@ -127,7 +127,7 @@ enum { | |||
127 | MOVE_SOURCE_RD_ERR, | 127 | MOVE_SOURCE_RD_ERR, |
128 | MOVE_TARGET_RD_ERR, | 128 | MOVE_TARGET_RD_ERR, |
129 | MOVE_TARGET_WR_ERR, | 129 | MOVE_TARGET_WR_ERR, |
130 | MOVE_CANCEL_BITFLIPS, | 130 | MOVE_TARGET_BITFLIPS, |
131 | MOVE_RETRY, | 131 | MOVE_RETRY, |
132 | }; | 132 | }; |
133 | 133 | ||
@@ -387,9 +387,8 @@ struct ubi_wl_entry; | |||
387 | * time (MTD write buffer size) | 387 | * time (MTD write buffer size) |
388 | * @mtd: MTD device descriptor | 388 | * @mtd: MTD device descriptor |
389 | * | 389 | * |
390 | * @peb_buf1: a buffer of PEB size used for different purposes | 390 | * @peb_buf: a buffer of PEB size used for different purposes |
391 | * @peb_buf2: another buffer of PEB size used for different purposes | 391 | * @buf_mutex: protects @peb_buf |
392 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 | ||
393 | * @ckvol_mutex: serializes static volume checking when opening | 392 | * @ckvol_mutex: serializes static volume checking when opening |
394 | * | 393 | * |
395 | * @dbg: debugging information for this UBI device | 394 | * @dbg: debugging information for this UBI device |
@@ -471,8 +470,7 @@ struct ubi_device { | |||
471 | int max_write_size; | 470 | int max_write_size; |
472 | struct mtd_info *mtd; | 471 | struct mtd_info *mtd; |
473 | 472 | ||
474 | void *peb_buf1; | 473 | void *peb_buf; |
475 | void *peb_buf2; | ||
476 | struct mutex buf_mutex; | 474 | struct mutex buf_mutex; |
477 | struct mutex ckvol_mutex; | 475 | struct mutex ckvol_mutex; |
478 | 476 | ||
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0696e36b0539..7c1a9bf8ac86 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -350,18 +350,19 @@ static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e) | |||
350 | /** | 350 | /** |
351 | * find_wl_entry - find wear-leveling entry closest to certain erase counter. | 351 | * find_wl_entry - find wear-leveling entry closest to certain erase counter. |
352 | * @root: the RB-tree where to look for | 352 | * @root: the RB-tree where to look for |
353 | * @max: highest possible erase counter | 353 | * @diff: maximum possible difference from the smallest erase counter |
354 | * | 354 | * |
355 | * This function looks for a wear leveling entry with erase counter closest to | 355 | * This function looks for a wear leveling entry with erase counter closest to |
356 | * @max and less than @max. | 356 | * min + @diff, where min is the smallest erase counter. |
357 | */ | 357 | */ |
358 | static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) | 358 | static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) |
359 | { | 359 | { |
360 | struct rb_node *p; | 360 | struct rb_node *p; |
361 | struct ubi_wl_entry *e; | 361 | struct ubi_wl_entry *e; |
362 | int max; | ||
362 | 363 | ||
363 | e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); | 364 | e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); |
364 | max += e->ec; | 365 | max = e->ec + diff; |
365 | 366 | ||
366 | p = root->rb_node; | 367 | p = root->rb_node; |
367 | while (p) { | 368 | while (p) { |
@@ -389,7 +390,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) | |||
389 | */ | 390 | */ |
390 | int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) | 391 | int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) |
391 | { | 392 | { |
392 | int err, medium_ec; | 393 | int err; |
393 | struct ubi_wl_entry *e, *first, *last; | 394 | struct ubi_wl_entry *e, *first, *last; |
394 | 395 | ||
395 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || | 396 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || |
@@ -427,7 +428,7 @@ retry: | |||
427 | * For unknown data we pick a physical eraseblock with medium | 428 | * For unknown data we pick a physical eraseblock with medium |
428 | * erase counter. But we by no means can pick a physical | 429 | * erase counter. But we by no means can pick a physical |
429 | * eraseblock with erase counter greater or equivalent than the | 430 | * eraseblock with erase counter greater or equivalent than the |
430 | * lowest erase counter plus %WL_FREE_MAX_DIFF. | 431 | * lowest erase counter plus %WL_FREE_MAX_DIFF/2. |
431 | */ | 432 | */ |
432 | first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, | 433 | first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, |
433 | u.rb); | 434 | u.rb); |
@@ -436,10 +437,8 @@ retry: | |||
436 | if (last->ec - first->ec < WL_FREE_MAX_DIFF) | 437 | if (last->ec - first->ec < WL_FREE_MAX_DIFF) |
437 | e = rb_entry(ubi->free.rb_node, | 438 | e = rb_entry(ubi->free.rb_node, |
438 | struct ubi_wl_entry, u.rb); | 439 | struct ubi_wl_entry, u.rb); |
439 | else { | 440 | else |
440 | medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; | 441 | e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); |
441 | e = find_wl_entry(&ubi->free, medium_ec); | ||
442 | } | ||
443 | break; | 442 | break; |
444 | case UBI_SHORTTERM: | 443 | case UBI_SHORTTERM: |
445 | /* | 444 | /* |
@@ -799,7 +798,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
799 | scrubbing = 1; | 798 | scrubbing = 1; |
800 | goto out_not_moved; | 799 | goto out_not_moved; |
801 | } | 800 | } |
802 | if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || | 801 | if (err == MOVE_TARGET_BITFLIPS || err == MOVE_TARGET_WR_ERR || |
803 | err == MOVE_TARGET_RD_ERR) { | 802 | err == MOVE_TARGET_RD_ERR) { |
804 | /* | 803 | /* |
805 | * Target PEB had bit-flips or write error - torture it. | 804 | * Target PEB had bit-flips or write error - torture it. |