diff options
Diffstat (limited to 'drivers/mtd/ubi/eba.c')
-rw-r--r-- | drivers/mtd/ubi/eba.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index d8966bae0e0b..048a606cebde 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, | |||
504 | if (!vid_hdr) | 504 | if (!vid_hdr) |
505 | return -ENOMEM; | 505 | return -ENOMEM; |
506 | 506 | ||
507 | mutex_lock(&ubi->buf_mutex); | ||
508 | |||
509 | retry: | 507 | retry: |
510 | new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); | 508 | new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); |
511 | if (new_pnum < 0) { | 509 | if (new_pnum < 0) { |
512 | mutex_unlock(&ubi->buf_mutex); | ||
513 | ubi_free_vid_hdr(ubi, vid_hdr); | 510 | ubi_free_vid_hdr(ubi, vid_hdr); |
514 | return new_pnum; | 511 | return new_pnum; |
515 | } | 512 | } |
@@ -529,20 +526,23 @@ retry: | |||
529 | goto write_error; | 526 | goto write_error; |
530 | 527 | ||
531 | data_size = offset + len; | 528 | data_size = offset + len; |
529 | mutex_lock(&ubi->buf_mutex); | ||
532 | memset(ubi->peb_buf1 + offset, 0xFF, len); | 530 | memset(ubi->peb_buf1 + offset, 0xFF, len); |
533 | 531 | ||
534 | /* Read everything before the area where the write failure happened */ | 532 | /* Read everything before the area where the write failure happened */ |
535 | if (offset > 0) { | 533 | if (offset > 0) { |
536 | err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); | 534 | err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); |
537 | if (err && err != UBI_IO_BITFLIPS) | 535 | if (err && err != UBI_IO_BITFLIPS) |
538 | goto out_put; | 536 | goto out_unlock; |
539 | } | 537 | } |
540 | 538 | ||
541 | memcpy(ubi->peb_buf1 + offset, buf, len); | 539 | memcpy(ubi->peb_buf1 + offset, buf, len); |
542 | 540 | ||
543 | err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); | 541 | err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); |
544 | if (err) | 542 | if (err) { |
543 | mutex_unlock(&ubi->buf_mutex); | ||
545 | goto write_error; | 544 | goto write_error; |
545 | } | ||
546 | 546 | ||
547 | mutex_unlock(&ubi->buf_mutex); | 547 | mutex_unlock(&ubi->buf_mutex); |
548 | ubi_free_vid_hdr(ubi, vid_hdr); | 548 | ubi_free_vid_hdr(ubi, vid_hdr); |
@@ -553,8 +553,9 @@ retry: | |||
553 | ubi_msg("data was successfully recovered"); | 553 | ubi_msg("data was successfully recovered"); |
554 | return 0; | 554 | return 0; |
555 | 555 | ||
556 | out_put: | 556 | out_unlock: |
557 | mutex_unlock(&ubi->buf_mutex); | 557 | mutex_unlock(&ubi->buf_mutex); |
558 | out_put: | ||
558 | ubi_wl_put_peb(ubi, new_pnum, 1); | 559 | ubi_wl_put_peb(ubi, new_pnum, 1); |
559 | ubi_free_vid_hdr(ubi, vid_hdr); | 560 | ubi_free_vid_hdr(ubi, vid_hdr); |
560 | return err; | 561 | return err; |
@@ -567,7 +568,6 @@ write_error: | |||
567 | ubi_warn("failed to write to PEB %d", new_pnum); | 568 | ubi_warn("failed to write to PEB %d", new_pnum); |
568 | ubi_wl_put_peb(ubi, new_pnum, 1); | 569 | ubi_wl_put_peb(ubi, new_pnum, 1); |
569 | if (++tries > UBI_IO_RETRIES) { | 570 | if (++tries > UBI_IO_RETRIES) { |
570 | mutex_unlock(&ubi->buf_mutex); | ||
571 | ubi_free_vid_hdr(ubi, vid_hdr); | 571 | ubi_free_vid_hdr(ubi, vid_hdr); |
572 | return err; | 572 | return err; |
573 | } | 573 | } |
@@ -949,10 +949,14 @@ write_error: | |||
949 | * This function copies logical eraseblock from physical eraseblock @from to | 949 | * This function copies logical eraseblock from physical eraseblock @from to |
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 and should be tried later (e.g., | 953 | * o %1 if the operation was canceled because the volume is being deleted |
954 | * because a bit-flip was detected at the target PEB); | 954 | * or because the PEB was put meanwhile; |
955 | * o %2 if the volume is being deleted and this LEB should not be moved. | 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. | ||
956 | */ | 960 | */ |
957 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 961 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
958 | struct ubi_vid_hdr *vid_hdr) | 962 | struct ubi_vid_hdr *vid_hdr) |
@@ -978,7 +982,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
978 | /* | 982 | /* |
979 | * Note, we may race with volume deletion, which means that the volume | 983 | * Note, we may race with volume deletion, which means that the volume |
980 | * this logical eraseblock belongs to might be being deleted. Since the | 984 | * this logical eraseblock belongs to might be being deleted. Since the |
981 | * volume deletion unmaps all the volume's logical eraseblocks, it will | 985 | * volume deletion un-maps all the volume's logical eraseblocks, it will |
982 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. | 986 | * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. |
983 | */ | 987 | */ |
984 | vol = ubi->volumes[idx]; | 988 | vol = ubi->volumes[idx]; |
@@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
986 | /* No need to do further work, cancel */ | 990 | /* No need to do further work, cancel */ |
987 | dbg_eba("volume %d is being removed, cancel", vol_id); | 991 | dbg_eba("volume %d is being removed, cancel", vol_id); |
988 | spin_unlock(&ubi->volumes_lock); | 992 | spin_unlock(&ubi->volumes_lock); |
989 | return 2; | 993 | return 1; |
990 | } | 994 | } |
991 | spin_unlock(&ubi->volumes_lock); | 995 | spin_unlock(&ubi->volumes_lock); |
992 | 996 | ||
@@ -1023,7 +1027,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1023 | 1027 | ||
1024 | /* | 1028 | /* |
1025 | * OK, now the LEB is locked and we can safely start moving it. Since | 1029 | * OK, now the LEB is locked and we can safely start moving it. Since |
1026 | * this function utilizes thie @ubi->peb1_buf buffer which is shared | 1030 | * this function utilizes the @ubi->peb1_buf buffer which is shared |
1027 | * with some other functions, so lock the buffer by taking the | 1031 | * with some other functions, so lock the buffer by taking the |
1028 | * @ubi->buf_mutex. | 1032 | * @ubi->buf_mutex. |
1029 | */ | 1033 | */ |
@@ -1068,8 +1072,11 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1068 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); | 1072 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
1069 | 1073 | ||
1070 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); | 1074 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); |
1071 | if (err) | 1075 | if (err) { |
1076 | if (err == -EIO) | ||
1077 | err = 2; | ||
1072 | goto out_unlock_buf; | 1078 | goto out_unlock_buf; |
1079 | } | ||
1073 | 1080 | ||
1074 | cond_resched(); | 1081 | cond_resched(); |
1075 | 1082 | ||
@@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1079 | if (err != UBI_IO_BITFLIPS) | 1086 | if (err != UBI_IO_BITFLIPS) |
1080 | ubi_warn("cannot read VID header back from PEB %d", to); | 1087 | ubi_warn("cannot read VID header back from PEB %d", to); |
1081 | else | 1088 | else |
1082 | err = 1; | 1089 | err = -EAGAIN; |
1083 | goto out_unlock_buf; | 1090 | goto out_unlock_buf; |
1084 | } | 1091 | } |
1085 | 1092 | ||
1086 | if (data_size > 0) { | 1093 | if (data_size > 0) { |
1087 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); | 1094 | err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); |
1088 | if (err) | 1095 | if (err) { |
1096 | if (err == -EIO) | ||
1097 | err = 2; | ||
1089 | goto out_unlock_buf; | 1098 | goto out_unlock_buf; |
1099 | } | ||
1090 | 1100 | ||
1091 | cond_resched(); | 1101 | cond_resched(); |
1092 | 1102 | ||
@@ -1101,15 +1111,16 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1101 | ubi_warn("cannot read data back from PEB %d", | 1111 | ubi_warn("cannot read data back from PEB %d", |
1102 | to); | 1112 | to); |
1103 | else | 1113 | else |
1104 | err = 1; | 1114 | err = -EAGAIN; |
1105 | goto out_unlock_buf; | 1115 | goto out_unlock_buf; |
1106 | } | 1116 | } |
1107 | 1117 | ||
1108 | cond_resched(); | 1118 | cond_resched(); |
1109 | 1119 | ||
1110 | if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { | 1120 | if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { |
1111 | ubi_warn("read data back from PEB %d - it is different", | 1121 | ubi_warn("read data back from PEB %d and it is " |
1112 | to); | 1122 | "different", to); |
1123 | err = -EINVAL; | ||
1113 | goto out_unlock_buf; | 1124 | goto out_unlock_buf; |
1114 | } | 1125 | } |
1115 | } | 1126 | } |