diff options
| -rw-r--r-- | drivers/mtd/ubi/eba.c | 16 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 3 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 32 |
3 files changed, 33 insertions, 18 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 5fa726f9c1fc..b703ac7729cf 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -341,7 +341,7 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, | |||
| 341 | dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); | 341 | dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); |
| 342 | 342 | ||
| 343 | vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; | 343 | vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; |
| 344 | err = ubi_wl_put_peb(ubi, pnum, 0); | 344 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); |
| 345 | 345 | ||
| 346 | out_unlock: | 346 | out_unlock: |
| 347 | leb_write_unlock(ubi, vol_id, lnum); | 347 | leb_write_unlock(ubi, vol_id, lnum); |
| @@ -550,7 +550,7 @@ retry: | |||
| 550 | ubi_free_vid_hdr(ubi, vid_hdr); | 550 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 551 | 551 | ||
| 552 | vol->eba_tbl[lnum] = new_pnum; | 552 | vol->eba_tbl[lnum] = new_pnum; |
| 553 | ubi_wl_put_peb(ubi, pnum, 1); | 553 | ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); |
| 554 | 554 | ||
| 555 | ubi_msg("data was successfully recovered"); | 555 | ubi_msg("data was successfully recovered"); |
| 556 | return 0; | 556 | return 0; |
| @@ -558,7 +558,7 @@ retry: | |||
| 558 | out_unlock: | 558 | out_unlock: |
| 559 | mutex_unlock(&ubi->buf_mutex); | 559 | mutex_unlock(&ubi->buf_mutex); |
| 560 | out_put: | 560 | out_put: |
| 561 | ubi_wl_put_peb(ubi, new_pnum, 1); | 561 | ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); |
| 562 | ubi_free_vid_hdr(ubi, vid_hdr); | 562 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 563 | return err; | 563 | return err; |
| 564 | 564 | ||
| @@ -568,7 +568,7 @@ write_error: | |||
| 568 | * get another one. | 568 | * get another one. |
| 569 | */ | 569 | */ |
| 570 | ubi_warn("failed to write to PEB %d", new_pnum); | 570 | ubi_warn("failed to write to PEB %d", new_pnum); |
| 571 | ubi_wl_put_peb(ubi, new_pnum, 1); | 571 | ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); |
| 572 | if (++tries > UBI_IO_RETRIES) { | 572 | if (++tries > UBI_IO_RETRIES) { |
| 573 | ubi_free_vid_hdr(ubi, vid_hdr); | 573 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 574 | return err; | 574 | return err; |
| @@ -686,7 +686,7 @@ write_error: | |||
| 686 | * eraseblock, so just put it and request a new one. We assume that if | 686 | * eraseblock, so just put it and request a new one. We assume that if |
| 687 | * this physical eraseblock went bad, the erase code will handle that. | 687 | * this physical eraseblock went bad, the erase code will handle that. |
| 688 | */ | 688 | */ |
| 689 | err = ubi_wl_put_peb(ubi, pnum, 1); | 689 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); |
| 690 | if (err || ++tries > UBI_IO_RETRIES) { | 690 | if (err || ++tries > UBI_IO_RETRIES) { |
| 691 | ubi_ro_mode(ubi); | 691 | ubi_ro_mode(ubi); |
| 692 | leb_write_unlock(ubi, vol_id, lnum); | 692 | leb_write_unlock(ubi, vol_id, lnum); |
| @@ -804,7 +804,7 @@ write_error: | |||
| 804 | return err; | 804 | return err; |
| 805 | } | 805 | } |
| 806 | 806 | ||
| 807 | err = ubi_wl_put_peb(ubi, pnum, 1); | 807 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); |
| 808 | if (err || ++tries > UBI_IO_RETRIES) { | 808 | if (err || ++tries > UBI_IO_RETRIES) { |
| 809 | ubi_ro_mode(ubi); | 809 | ubi_ro_mode(ubi); |
| 810 | leb_write_unlock(ubi, vol_id, lnum); | 810 | leb_write_unlock(ubi, vol_id, lnum); |
| @@ -901,7 +901,7 @@ retry: | |||
| 901 | } | 901 | } |
| 902 | 902 | ||
| 903 | if (vol->eba_tbl[lnum] >= 0) { | 903 | if (vol->eba_tbl[lnum] >= 0) { |
| 904 | err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0); | 904 | err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0); |
| 905 | if (err) | 905 | if (err) |
| 906 | goto out_leb_unlock; | 906 | goto out_leb_unlock; |
| 907 | } | 907 | } |
| @@ -926,7 +926,7 @@ write_error: | |||
| 926 | goto out_leb_unlock; | 926 | goto out_leb_unlock; |
| 927 | } | 927 | } |
| 928 | 928 | ||
| 929 | err = ubi_wl_put_peb(ubi, pnum, 1); | 929 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); |
| 930 | if (err || ++tries > UBI_IO_RETRIES) { | 930 | if (err || ++tries > UBI_IO_RETRIES) { |
| 931 | ubi_ro_mode(ubi); | 931 | ubi_ro_mode(ubi); |
| 932 | goto out_leb_unlock; | 932 | goto out_leb_unlock; |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index b4b3913f1df4..5e1182ca289b 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -667,7 +667,8 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | |||
| 667 | 667 | ||
| 668 | /* wl.c */ | 668 | /* wl.c */ |
| 669 | int ubi_wl_get_peb(struct ubi_device *ubi); | 669 | int ubi_wl_get_peb(struct ubi_device *ubi); |
| 670 | int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); | 670 | int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, |
| 671 | int pnum, int torture); | ||
| 671 | int ubi_wl_flush(struct ubi_device *ubi); | 672 | int ubi_wl_flush(struct ubi_device *ubi); |
| 672 | int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); | 673 | int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); |
| 673 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | 674 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index c143e6112357..70ebfa7bc384 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -140,6 +140,8 @@ | |||
| 140 | * @list: a link in the list of pending works | 140 | * @list: a link in the list of pending works |
| 141 | * @func: worker function | 141 | * @func: worker function |
| 142 | * @e: physical eraseblock to erase | 142 | * @e: physical eraseblock to erase |
| 143 | * @vol_id: the volume ID on which this erasure is being performed | ||
| 144 | * @lnum: the logical eraseblock number | ||
| 143 | * @torture: if the physical eraseblock has to be tortured | 145 | * @torture: if the physical eraseblock has to be tortured |
| 144 | * | 146 | * |
| 145 | * The @func pointer points to the worker function. If the @cancel argument is | 147 | * The @func pointer points to the worker function. If the @cancel argument is |
| @@ -152,6 +154,8 @@ struct ubi_work { | |||
| 152 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | 154 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); |
| 153 | /* The below fields are only relevant to erasure works */ | 155 | /* The below fields are only relevant to erasure works */ |
| 154 | struct ubi_wl_entry *e; | 156 | struct ubi_wl_entry *e; |
| 157 | int vol_id; | ||
| 158 | int lnum; | ||
| 155 | int torture; | 159 | int torture; |
| 156 | }; | 160 | }; |
| 157 | 161 | ||
| @@ -579,13 +583,15 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 579 | * schedule_erase - schedule an erase work. | 583 | * schedule_erase - schedule an erase work. |
| 580 | * @ubi: UBI device description object | 584 | * @ubi: UBI device description object |
| 581 | * @e: the WL entry of the physical eraseblock to erase | 585 | * @e: the WL entry of the physical eraseblock to erase |
| 586 | * @vol_id: the volume ID that last used this PEB | ||
| 587 | * @lnum: the last used logical eraseblock number for the PEB | ||
| 582 | * @torture: if the physical eraseblock has to be tortured | 588 | * @torture: if the physical eraseblock has to be tortured |
| 583 | * | 589 | * |
| 584 | * This function returns zero in case of success and a %-ENOMEM in case of | 590 | * This function returns zero in case of success and a %-ENOMEM in case of |
| 585 | * failure. | 591 | * failure. |
| 586 | */ | 592 | */ |
| 587 | static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | 593 | static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, |
| 588 | int torture) | 594 | int vol_id, int lnum, int torture) |
| 589 | { | 595 | { |
| 590 | struct ubi_work *wl_wrk; | 596 | struct ubi_work *wl_wrk; |
| 591 | 597 | ||
| @@ -598,6 +604,8 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
| 598 | 604 | ||
| 599 | wl_wrk->func = &erase_worker; | 605 | wl_wrk->func = &erase_worker; |
| 600 | wl_wrk->e = e; | 606 | wl_wrk->e = e; |
| 607 | wl_wrk->vol_id = vol_id; | ||
| 608 | wl_wrk->lnum = lnum; | ||
| 601 | wl_wrk->torture = torture; | 609 | wl_wrk->torture = torture; |
| 602 | 610 | ||
| 603 | schedule_ubi_work(ubi, wl_wrk); | 611 | schedule_ubi_work(ubi, wl_wrk); |
| @@ -798,7 +806,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 798 | ubi->move_to_put = ubi->wl_scheduled = 0; | 806 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 799 | spin_unlock(&ubi->wl_lock); | 807 | spin_unlock(&ubi->wl_lock); |
| 800 | 808 | ||
| 801 | err = schedule_erase(ubi, e1, 0); | 809 | err = schedule_erase(ubi, e1, vol_id, lnum, 0); |
| 802 | if (err) { | 810 | if (err) { |
| 803 | kmem_cache_free(ubi_wl_entry_slab, e1); | 811 | kmem_cache_free(ubi_wl_entry_slab, e1); |
| 804 | if (e2) | 812 | if (e2) |
| @@ -813,7 +821,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 813 | */ | 821 | */ |
| 814 | dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", | 822 | dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", |
| 815 | e2->pnum, vol_id, lnum); | 823 | e2->pnum, vol_id, lnum); |
| 816 | err = schedule_erase(ubi, e2, 0); | 824 | err = schedule_erase(ubi, e2, vol_id, lnum, 0); |
| 817 | if (err) { | 825 | if (err) { |
| 818 | kmem_cache_free(ubi_wl_entry_slab, e2); | 826 | kmem_cache_free(ubi_wl_entry_slab, e2); |
| 819 | goto out_ro; | 827 | goto out_ro; |
| @@ -852,7 +860,7 @@ out_not_moved: | |||
| 852 | spin_unlock(&ubi->wl_lock); | 860 | spin_unlock(&ubi->wl_lock); |
| 853 | 861 | ||
| 854 | ubi_free_vid_hdr(ubi, vid_hdr); | 862 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 855 | err = schedule_erase(ubi, e2, torture); | 863 | err = schedule_erase(ubi, e2, vol_id, lnum, torture); |
| 856 | if (err) { | 864 | if (err) { |
| 857 | kmem_cache_free(ubi_wl_entry_slab, e2); | 865 | kmem_cache_free(ubi_wl_entry_slab, e2); |
| 858 | goto out_ro; | 866 | goto out_ro; |
| @@ -971,6 +979,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 971 | { | 979 | { |
| 972 | struct ubi_wl_entry *e = wl_wrk->e; | 980 | struct ubi_wl_entry *e = wl_wrk->e; |
| 973 | int pnum = e->pnum, err, need; | 981 | int pnum = e->pnum, err, need; |
| 982 | int vol_id = wl_wrk->vol_id; | ||
| 983 | int lnum = wl_wrk->lnum; | ||
| 974 | 984 | ||
| 975 | if (cancel) { | 985 | if (cancel) { |
| 976 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); | 986 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); |
| @@ -979,7 +989,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 979 | return 0; | 989 | return 0; |
| 980 | } | 990 | } |
| 981 | 991 | ||
| 982 | dbg_wl("erase PEB %d EC %d", pnum, e->ec); | 992 | dbg_wl("erase PEB %d EC %d LEB %d:%d", |
| 993 | pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); | ||
| 983 | 994 | ||
| 984 | err = sync_erase(ubi, e, wl_wrk->torture); | 995 | err = sync_erase(ubi, e, wl_wrk->torture); |
| 985 | if (!err) { | 996 | if (!err) { |
| @@ -1009,7 +1020,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
| 1009 | int err1; | 1020 | int err1; |
| 1010 | 1021 | ||
| 1011 | /* Re-schedule the LEB for erasure */ | 1022 | /* Re-schedule the LEB for erasure */ |
| 1012 | err1 = schedule_erase(ubi, e, 0); | 1023 | err1 = schedule_erase(ubi, e, vol_id, lnum, 0); |
| 1013 | if (err1) { | 1024 | if (err1) { |
| 1014 | err = err1; | 1025 | err = err1; |
| 1015 | goto out_ro; | 1026 | goto out_ro; |
| @@ -1077,6 +1088,8 @@ out_ro: | |||
| 1077 | /** | 1088 | /** |
| 1078 | * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system. | 1089 | * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system. |
| 1079 | * @ubi: UBI device description object | 1090 | * @ubi: UBI device description object |
| 1091 | * @vol_id: the volume ID that last used this PEB | ||
| 1092 | * @lnum: the last used logical eraseblock number for the PEB | ||
| 1080 | * @pnum: physical eraseblock to return | 1093 | * @pnum: physical eraseblock to return |
| 1081 | * @torture: if this physical eraseblock has to be tortured | 1094 | * @torture: if this physical eraseblock has to be tortured |
| 1082 | * | 1095 | * |
| @@ -1085,7 +1098,8 @@ out_ro: | |||
| 1085 | * occurred to this @pnum and it has to be tested. This function returns zero | 1098 | * occurred to this @pnum and it has to be tested. This function returns zero |
| 1086 | * in case of success, and a negative error code in case of failure. | 1099 | * in case of success, and a negative error code in case of failure. |
| 1087 | */ | 1100 | */ |
| 1088 | int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) | 1101 | int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, |
| 1102 | int pnum, int torture) | ||
| 1089 | { | 1103 | { |
| 1090 | int err; | 1104 | int err; |
| 1091 | struct ubi_wl_entry *e; | 1105 | struct ubi_wl_entry *e; |
| @@ -1151,7 +1165,7 @@ retry: | |||
| 1151 | } | 1165 | } |
| 1152 | spin_unlock(&ubi->wl_lock); | 1166 | spin_unlock(&ubi->wl_lock); |
| 1153 | 1167 | ||
| 1154 | err = schedule_erase(ubi, e, torture); | 1168 | err = schedule_erase(ubi, e, vol_id, lnum, torture); |
| 1155 | if (err) { | 1169 | if (err) { |
| 1156 | spin_lock(&ubi->wl_lock); | 1170 | spin_lock(&ubi->wl_lock); |
| 1157 | wl_tree_add(e, &ubi->used); | 1171 | wl_tree_add(e, &ubi->used); |
| @@ -1416,7 +1430,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) | |||
| 1416 | e->pnum = aeb->pnum; | 1430 | e->pnum = aeb->pnum; |
| 1417 | e->ec = aeb->ec; | 1431 | e->ec = aeb->ec; |
| 1418 | ubi->lookuptbl[e->pnum] = e; | 1432 | ubi->lookuptbl[e->pnum] = e; |
| 1419 | if (schedule_erase(ubi, e, 0)) { | 1433 | if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) { |
| 1420 | kmem_cache_free(ubi_wl_entry_slab, e); | 1434 | kmem_cache_free(ubi_wl_entry_slab, e); |
| 1421 | goto out_free; | 1435 | goto out_free; |
| 1422 | } | 1436 | } |
