diff options
author | Richard Weinberger <richard@nod.at> | 2014-11-10 10:28:08 -0500 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-03-26 17:46:02 -0400 |
commit | 111ab0b26fc1bfad575d1e376e146d194d261e22 (patch) | |
tree | 451a0a31b6f28d85986569010fa8c3381eb1d622 /drivers/mtd | |
parent | 42dd3cdcd6b5671ebedc3df76ca8dcc3473bcc67 (diff) |
UBI: Fastmap: Locking updates
a) Rename ubi->fm_sem to ubi->fm_eba_sem as this semaphore
protects EBA changes.
b) Turn ubi->fm_mutex into a rw semaphore. It will still serialize
fastmap writes but also ensures that ubi_wl_put_peb() is not
interrupted by a fastmap write. We use a rw semaphore to allow
ubi_wl_put_peb() still to be executed in parallel if no fastmap
write is happening.
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/ubi/build.c | 4 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 44 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 18 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 9 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 19 |
5 files changed, 50 insertions, 44 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 59af91b41f9a..a7571508fdab 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -969,8 +969,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, | |||
969 | mutex_init(&ubi->ckvol_mutex); | 969 | mutex_init(&ubi->ckvol_mutex); |
970 | mutex_init(&ubi->device_mutex); | 970 | mutex_init(&ubi->device_mutex); |
971 | spin_lock_init(&ubi->volumes_lock); | 971 | spin_lock_init(&ubi->volumes_lock); |
972 | mutex_init(&ubi->fm_mutex); | 972 | init_rwsem(&ubi->fm_protect); |
973 | init_rwsem(&ubi->fm_sem); | 973 | init_rwsem(&ubi->fm_eba_sem); |
974 | 974 | ||
975 | ubi_msg(ubi, "attaching mtd%d", mtd->index); | 975 | ubi_msg(ubi, "attaching mtd%d", mtd->index); |
976 | 976 | ||
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 4757cef756f7..51bca035cd83 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -340,9 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, | |||
340 | 340 | ||
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 | down_read(&ubi->fm_sem); | 343 | down_read(&ubi->fm_eba_sem); |
344 | vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; | 344 | vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; |
345 | up_read(&ubi->fm_sem); | 345 | up_read(&ubi->fm_eba_sem); |
346 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); | 346 | err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); |
347 | 347 | ||
348 | out_unlock: | 348 | out_unlock: |
@@ -567,7 +567,7 @@ retry: | |||
567 | new_pnum = ubi_wl_get_peb(ubi); | 567 | new_pnum = ubi_wl_get_peb(ubi); |
568 | if (new_pnum < 0) { | 568 | if (new_pnum < 0) { |
569 | ubi_free_vid_hdr(ubi, vid_hdr); | 569 | ubi_free_vid_hdr(ubi, vid_hdr); |
570 | up_read(&ubi->fm_sem); | 570 | up_read(&ubi->fm_eba_sem); |
571 | return new_pnum; | 571 | return new_pnum; |
572 | } | 572 | } |
573 | 573 | ||
@@ -578,14 +578,14 @@ retry: | |||
578 | if (err && err != UBI_IO_BITFLIPS) { | 578 | if (err && err != UBI_IO_BITFLIPS) { |
579 | if (err > 0) | 579 | if (err > 0) |
580 | err = -EIO; | 580 | err = -EIO; |
581 | up_read(&ubi->fm_sem); | 581 | up_read(&ubi->fm_eba_sem); |
582 | goto out_put; | 582 | goto out_put; |
583 | } | 583 | } |
584 | 584 | ||
585 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); | 585 | vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); |
586 | err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); | 586 | err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); |
587 | if (err) { | 587 | if (err) { |
588 | up_read(&ubi->fm_sem); | 588 | up_read(&ubi->fm_eba_sem); |
589 | goto write_error; | 589 | goto write_error; |
590 | } | 590 | } |
591 | 591 | ||
@@ -597,7 +597,7 @@ retry: | |||
597 | if (offset > 0) { | 597 | if (offset > 0) { |
598 | err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); | 598 | err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); |
599 | if (err && err != UBI_IO_BITFLIPS) { | 599 | if (err && err != UBI_IO_BITFLIPS) { |
600 | up_read(&ubi->fm_sem); | 600 | up_read(&ubi->fm_eba_sem); |
601 | goto out_unlock; | 601 | goto out_unlock; |
602 | } | 602 | } |
603 | } | 603 | } |
@@ -607,7 +607,7 @@ retry: | |||
607 | err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); | 607 | err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); |
608 | if (err) { | 608 | if (err) { |
609 | mutex_unlock(&ubi->buf_mutex); | 609 | mutex_unlock(&ubi->buf_mutex); |
610 | up_read(&ubi->fm_sem); | 610 | up_read(&ubi->fm_eba_sem); |
611 | goto write_error; | 611 | goto write_error; |
612 | } | 612 | } |
613 | 613 | ||
@@ -615,7 +615,7 @@ retry: | |||
615 | ubi_free_vid_hdr(ubi, vid_hdr); | 615 | ubi_free_vid_hdr(ubi, vid_hdr); |
616 | 616 | ||
617 | vol->eba_tbl[lnum] = new_pnum; | 617 | vol->eba_tbl[lnum] = new_pnum; |
618 | up_read(&ubi->fm_sem); | 618 | up_read(&ubi->fm_eba_sem); |
619 | ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); | 619 | ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); |
620 | 620 | ||
621 | ubi_msg(ubi, "data was successfully recovered"); | 621 | ubi_msg(ubi, "data was successfully recovered"); |
@@ -710,7 +710,7 @@ retry: | |||
710 | if (pnum < 0) { | 710 | if (pnum < 0) { |
711 | ubi_free_vid_hdr(ubi, vid_hdr); | 711 | ubi_free_vid_hdr(ubi, vid_hdr); |
712 | leb_write_unlock(ubi, vol_id, lnum); | 712 | leb_write_unlock(ubi, vol_id, lnum); |
713 | up_read(&ubi->fm_sem); | 713 | up_read(&ubi->fm_eba_sem); |
714 | return pnum; | 714 | return pnum; |
715 | } | 715 | } |
716 | 716 | ||
@@ -721,7 +721,7 @@ retry: | |||
721 | if (err) { | 721 | if (err) { |
722 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | 722 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", |
723 | vol_id, lnum, pnum); | 723 | vol_id, lnum, pnum); |
724 | up_read(&ubi->fm_sem); | 724 | up_read(&ubi->fm_eba_sem); |
725 | goto write_error; | 725 | goto write_error; |
726 | } | 726 | } |
727 | 727 | ||
@@ -730,13 +730,13 @@ retry: | |||
730 | if (err) { | 730 | if (err) { |
731 | ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", | 731 | ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", |
732 | len, offset, vol_id, lnum, pnum); | 732 | len, offset, vol_id, lnum, pnum); |
733 | up_read(&ubi->fm_sem); | 733 | up_read(&ubi->fm_eba_sem); |
734 | goto write_error; | 734 | goto write_error; |
735 | } | 735 | } |
736 | } | 736 | } |
737 | 737 | ||
738 | vol->eba_tbl[lnum] = pnum; | 738 | vol->eba_tbl[lnum] = pnum; |
739 | up_read(&ubi->fm_sem); | 739 | up_read(&ubi->fm_eba_sem); |
740 | 740 | ||
741 | leb_write_unlock(ubi, vol_id, lnum); | 741 | leb_write_unlock(ubi, vol_id, lnum); |
742 | ubi_free_vid_hdr(ubi, vid_hdr); | 742 | ubi_free_vid_hdr(ubi, vid_hdr); |
@@ -833,7 +833,7 @@ retry: | |||
833 | if (pnum < 0) { | 833 | if (pnum < 0) { |
834 | ubi_free_vid_hdr(ubi, vid_hdr); | 834 | ubi_free_vid_hdr(ubi, vid_hdr); |
835 | leb_write_unlock(ubi, vol_id, lnum); | 835 | leb_write_unlock(ubi, vol_id, lnum); |
836 | up_read(&ubi->fm_sem); | 836 | up_read(&ubi->fm_eba_sem); |
837 | return pnum; | 837 | return pnum; |
838 | } | 838 | } |
839 | 839 | ||
@@ -844,7 +844,7 @@ retry: | |||
844 | if (err) { | 844 | if (err) { |
845 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | 845 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", |
846 | vol_id, lnum, pnum); | 846 | vol_id, lnum, pnum); |
847 | up_read(&ubi->fm_sem); | 847 | up_read(&ubi->fm_eba_sem); |
848 | goto write_error; | 848 | goto write_error; |
849 | } | 849 | } |
850 | 850 | ||
@@ -852,13 +852,13 @@ retry: | |||
852 | if (err) { | 852 | if (err) { |
853 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", | 853 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", |
854 | len, pnum); | 854 | len, pnum); |
855 | up_read(&ubi->fm_sem); | 855 | up_read(&ubi->fm_eba_sem); |
856 | goto write_error; | 856 | goto write_error; |
857 | } | 857 | } |
858 | 858 | ||
859 | ubi_assert(vol->eba_tbl[lnum] < 0); | 859 | ubi_assert(vol->eba_tbl[lnum] < 0); |
860 | vol->eba_tbl[lnum] = pnum; | 860 | vol->eba_tbl[lnum] = pnum; |
861 | up_read(&ubi->fm_sem); | 861 | up_read(&ubi->fm_eba_sem); |
862 | 862 | ||
863 | leb_write_unlock(ubi, vol_id, lnum); | 863 | leb_write_unlock(ubi, vol_id, lnum); |
864 | ubi_free_vid_hdr(ubi, vid_hdr); | 864 | ubi_free_vid_hdr(ubi, vid_hdr); |
@@ -953,7 +953,7 @@ retry: | |||
953 | pnum = ubi_wl_get_peb(ubi); | 953 | pnum = ubi_wl_get_peb(ubi); |
954 | if (pnum < 0) { | 954 | if (pnum < 0) { |
955 | err = pnum; | 955 | err = pnum; |
956 | up_read(&ubi->fm_sem); | 956 | up_read(&ubi->fm_eba_sem); |
957 | goto out_leb_unlock; | 957 | goto out_leb_unlock; |
958 | } | 958 | } |
959 | 959 | ||
@@ -964,7 +964,7 @@ retry: | |||
964 | if (err) { | 964 | if (err) { |
965 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", | 965 | ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", |
966 | vol_id, lnum, pnum); | 966 | vol_id, lnum, pnum); |
967 | up_read(&ubi->fm_sem); | 967 | up_read(&ubi->fm_eba_sem); |
968 | goto write_error; | 968 | goto write_error; |
969 | } | 969 | } |
970 | 970 | ||
@@ -972,13 +972,13 @@ retry: | |||
972 | if (err) { | 972 | if (err) { |
973 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", | 973 | ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", |
974 | len, pnum); | 974 | len, pnum); |
975 | up_read(&ubi->fm_sem); | 975 | up_read(&ubi->fm_eba_sem); |
976 | goto write_error; | 976 | goto write_error; |
977 | } | 977 | } |
978 | 978 | ||
979 | old_pnum = vol->eba_tbl[lnum]; | 979 | old_pnum = vol->eba_tbl[lnum]; |
980 | vol->eba_tbl[lnum] = pnum; | 980 | vol->eba_tbl[lnum] = pnum; |
981 | up_read(&ubi->fm_sem); | 981 | up_read(&ubi->fm_eba_sem); |
982 | 982 | ||
983 | if (old_pnum >= 0) { | 983 | if (old_pnum >= 0) { |
984 | err = ubi_wl_put_peb(ubi, vol_id, lnum, old_pnum, 0); | 984 | err = ubi_wl_put_peb(ubi, vol_id, lnum, old_pnum, 0); |
@@ -1231,9 +1231,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | ubi_assert(vol->eba_tbl[lnum] == from); | 1233 | ubi_assert(vol->eba_tbl[lnum] == from); |
1234 | down_read(&ubi->fm_sem); | 1234 | down_read(&ubi->fm_eba_sem); |
1235 | vol->eba_tbl[lnum] = to; | 1235 | vol->eba_tbl[lnum] = to; |
1236 | up_read(&ubi->fm_sem); | 1236 | up_read(&ubi->fm_eba_sem); |
1237 | 1237 | ||
1238 | out_unlock_buf: | 1238 | out_unlock_buf: |
1239 | mutex_unlock(&ubi->buf_mutex); | 1239 | mutex_unlock(&ubi->buf_mutex); |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 749e2e4738fc..2cf2506b8f44 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -800,7 +800,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
800 | __be32 crc, tmp_crc; | 800 | __be32 crc, tmp_crc; |
801 | unsigned long long sqnum = 0; | 801 | unsigned long long sqnum = 0; |
802 | 802 | ||
803 | mutex_lock(&ubi->fm_mutex); | 803 | down_write(&ubi->fm_protect); |
804 | memset(ubi->fm_buf, 0, ubi->fm_size); | 804 | memset(ubi->fm_buf, 0, ubi->fm_size); |
805 | 805 | ||
806 | fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); | 806 | fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); |
@@ -991,7 +991,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
991 | ubi_free_vid_hdr(ubi, vh); | 991 | ubi_free_vid_hdr(ubi, vh); |
992 | kfree(ech); | 992 | kfree(ech); |
993 | out: | 993 | out: |
994 | mutex_unlock(&ubi->fm_mutex); | 994 | up_write(&ubi->fm_protect); |
995 | if (ret == UBI_BAD_FASTMAP) | 995 | if (ret == UBI_BAD_FASTMAP) |
996 | ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); | 996 | ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); |
997 | return ret; | 997 | return ret; |
@@ -1340,24 +1340,24 @@ int ubi_update_fastmap(struct ubi_device *ubi) | |||
1340 | struct ubi_fastmap_layout *new_fm, *old_fm; | 1340 | struct ubi_fastmap_layout *new_fm, *old_fm; |
1341 | struct ubi_wl_entry *tmp_e; | 1341 | struct ubi_wl_entry *tmp_e; |
1342 | 1342 | ||
1343 | mutex_lock(&ubi->fm_mutex); | 1343 | down_write(&ubi->fm_protect); |
1344 | 1344 | ||
1345 | ubi_refill_pools(ubi); | 1345 | ubi_refill_pools(ubi); |
1346 | 1346 | ||
1347 | if (ubi->ro_mode || ubi->fm_disabled) { | 1347 | if (ubi->ro_mode || ubi->fm_disabled) { |
1348 | mutex_unlock(&ubi->fm_mutex); | 1348 | up_write(&ubi->fm_protect); |
1349 | return 0; | 1349 | return 0; |
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | ret = ubi_ensure_anchor_pebs(ubi); | 1352 | ret = ubi_ensure_anchor_pebs(ubi); |
1353 | if (ret) { | 1353 | if (ret) { |
1354 | mutex_unlock(&ubi->fm_mutex); | 1354 | up_write(&ubi->fm_protect); |
1355 | return ret; | 1355 | return ret; |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); | 1358 | new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); |
1359 | if (!new_fm) { | 1359 | if (!new_fm) { |
1360 | mutex_unlock(&ubi->fm_mutex); | 1360 | up_write(&ubi->fm_protect); |
1361 | return -ENOMEM; | 1361 | return -ENOMEM; |
1362 | } | 1362 | } |
1363 | 1363 | ||
@@ -1447,16 +1447,16 @@ int ubi_update_fastmap(struct ubi_device *ubi) | |||
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | down_write(&ubi->work_sem); | 1449 | down_write(&ubi->work_sem); |
1450 | down_write(&ubi->fm_sem); | 1450 | down_write(&ubi->fm_eba_sem); |
1451 | ret = ubi_write_fastmap(ubi, new_fm); | 1451 | ret = ubi_write_fastmap(ubi, new_fm); |
1452 | up_write(&ubi->fm_sem); | 1452 | up_write(&ubi->fm_eba_sem); |
1453 | up_write(&ubi->work_sem); | 1453 | up_write(&ubi->work_sem); |
1454 | 1454 | ||
1455 | if (ret) | 1455 | if (ret) |
1456 | goto err; | 1456 | goto err; |
1457 | 1457 | ||
1458 | out_unlock: | 1458 | out_unlock: |
1459 | mutex_unlock(&ubi->fm_mutex); | 1459 | up_write(&ubi->fm_protect); |
1460 | kfree(old_fm); | 1460 | kfree(old_fm); |
1461 | return ret; | 1461 | return ret; |
1462 | 1462 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 3ea9480bd055..058c84cac8dc 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -426,10 +426,11 @@ struct ubi_debug_info { | |||
426 | * @fm_pool: in-memory data structure of the fastmap pool | 426 | * @fm_pool: in-memory data structure of the fastmap pool |
427 | * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL | 427 | * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL |
428 | * sub-system | 428 | * sub-system |
429 | * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf | 429 | * @fm_protect: serializes ubi_update_fastmap(), protects @fm_buf and makes sure |
430 | * that critical sections cannot be interrupted by ubi_update_fastmap() | ||
430 | * @fm_buf: vmalloc()'d buffer which holds the raw fastmap | 431 | * @fm_buf: vmalloc()'d buffer which holds the raw fastmap |
431 | * @fm_size: fastmap size in bytes | 432 | * @fm_size: fastmap size in bytes |
432 | * @fm_sem: allows ubi_update_fastmap() to block EBA table changes | 433 | * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes |
433 | * @fm_work: fastmap work queue | 434 | * @fm_work: fastmap work queue |
434 | * @fm_work_scheduled: non-zero if fastmap work was scheduled | 435 | * @fm_work_scheduled: non-zero if fastmap work was scheduled |
435 | * | 436 | * |
@@ -534,8 +535,8 @@ struct ubi_device { | |||
534 | struct ubi_fastmap_layout *fm; | 535 | struct ubi_fastmap_layout *fm; |
535 | struct ubi_fm_pool fm_pool; | 536 | struct ubi_fm_pool fm_pool; |
536 | struct ubi_fm_pool fm_wl_pool; | 537 | struct ubi_fm_pool fm_wl_pool; |
537 | struct rw_semaphore fm_sem; | 538 | struct rw_semaphore fm_eba_sem; |
538 | struct mutex fm_mutex; | 539 | struct rw_semaphore fm_protect; |
539 | void *fm_buf; | 540 | void *fm_buf; |
540 | size_t fm_size; | 541 | size_t fm_size; |
541 | struct work_struct fm_work; | 542 | struct work_struct fm_work; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b8ad5e005cdc..609b16d45406 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -641,7 +641,7 @@ void ubi_refill_pools(struct ubi_device *ubi) | |||
641 | 641 | ||
642 | /* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of | 642 | /* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of |
643 | * the fastmap pool. | 643 | * the fastmap pool. |
644 | * Returns with ubi->fm_sem held in read mode! | 644 | * Returns with ubi->fm_eba_sem held in read mode! |
645 | */ | 645 | */ |
646 | int ubi_wl_get_peb(struct ubi_device *ubi) | 646 | int ubi_wl_get_peb(struct ubi_device *ubi) |
647 | { | 647 | { |
@@ -650,20 +650,20 @@ int ubi_wl_get_peb(struct ubi_device *ubi) | |||
650 | struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; | 650 | struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; |
651 | 651 | ||
652 | again: | 652 | again: |
653 | down_read(&ubi->fm_sem); | 653 | down_read(&ubi->fm_eba_sem); |
654 | spin_lock(&ubi->wl_lock); | 654 | spin_lock(&ubi->wl_lock); |
655 | /* We check here also for the WL pool because at this point we can | 655 | /* We check here also for the WL pool because at this point we can |
656 | * refill the WL pool synchronous. */ | 656 | * refill the WL pool synchronous. */ |
657 | if (pool->used == pool->size || wl_pool->used == wl_pool->size) { | 657 | if (pool->used == pool->size || wl_pool->used == wl_pool->size) { |
658 | spin_unlock(&ubi->wl_lock); | 658 | spin_unlock(&ubi->wl_lock); |
659 | up_read(&ubi->fm_sem); | 659 | up_read(&ubi->fm_eba_sem); |
660 | ret = ubi_update_fastmap(ubi); | 660 | ret = ubi_update_fastmap(ubi); |
661 | if (ret) { | 661 | if (ret) { |
662 | ubi_msg(ubi, "Unable to write a new fastmap: %i", ret); | 662 | ubi_msg(ubi, "Unable to write a new fastmap: %i", ret); |
663 | down_read(&ubi->fm_sem); | 663 | down_read(&ubi->fm_eba_sem); |
664 | return -ENOSPC; | 664 | return -ENOSPC; |
665 | } | 665 | } |
666 | down_read(&ubi->fm_sem); | 666 | down_read(&ubi->fm_eba_sem); |
667 | spin_lock(&ubi->wl_lock); | 667 | spin_lock(&ubi->wl_lock); |
668 | } | 668 | } |
669 | 669 | ||
@@ -675,7 +675,7 @@ again: | |||
675 | goto out; | 675 | goto out; |
676 | } | 676 | } |
677 | retried = 1; | 677 | retried = 1; |
678 | up_read(&ubi->fm_sem); | 678 | up_read(&ubi->fm_eba_sem); |
679 | goto again; | 679 | goto again; |
680 | } | 680 | } |
681 | 681 | ||
@@ -731,7 +731,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi) | |||
731 | spin_lock(&ubi->wl_lock); | 731 | spin_lock(&ubi->wl_lock); |
732 | peb = wl_get_peb(ubi); | 732 | peb = wl_get_peb(ubi); |
733 | spin_unlock(&ubi->wl_lock); | 733 | spin_unlock(&ubi->wl_lock); |
734 | down_read(&ubi->fm_sem); | 734 | down_read(&ubi->fm_eba_sem); |
735 | 735 | ||
736 | if (peb < 0) | 736 | if (peb < 0) |
737 | return peb; | 737 | return peb; |
@@ -1607,6 +1607,8 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, | |||
1607 | ubi_assert(pnum >= 0); | 1607 | ubi_assert(pnum >= 0); |
1608 | ubi_assert(pnum < ubi->peb_count); | 1608 | ubi_assert(pnum < ubi->peb_count); |
1609 | 1609 | ||
1610 | down_read(&ubi->fm_protect); | ||
1611 | |||
1610 | retry: | 1612 | retry: |
1611 | spin_lock(&ubi->wl_lock); | 1613 | spin_lock(&ubi->wl_lock); |
1612 | e = ubi->lookuptbl[pnum]; | 1614 | e = ubi->lookuptbl[pnum]; |
@@ -1637,6 +1639,7 @@ retry: | |||
1637 | ubi_assert(!ubi->move_to_put); | 1639 | ubi_assert(!ubi->move_to_put); |
1638 | ubi->move_to_put = 1; | 1640 | ubi->move_to_put = 1; |
1639 | spin_unlock(&ubi->wl_lock); | 1641 | spin_unlock(&ubi->wl_lock); |
1642 | up_read(&ubi->fm_protect); | ||
1640 | return 0; | 1643 | return 0; |
1641 | } else { | 1644 | } else { |
1642 | if (in_wl_tree(e, &ubi->used)) { | 1645 | if (in_wl_tree(e, &ubi->used)) { |
@@ -1658,6 +1661,7 @@ retry: | |||
1658 | ubi_err(ubi, "PEB %d not found", pnum); | 1661 | ubi_err(ubi, "PEB %d not found", pnum); |
1659 | ubi_ro_mode(ubi); | 1662 | ubi_ro_mode(ubi); |
1660 | spin_unlock(&ubi->wl_lock); | 1663 | spin_unlock(&ubi->wl_lock); |
1664 | up_read(&ubi->fm_protect); | ||
1661 | return err; | 1665 | return err; |
1662 | } | 1666 | } |
1663 | } | 1667 | } |
@@ -1671,6 +1675,7 @@ retry: | |||
1671 | spin_unlock(&ubi->wl_lock); | 1675 | spin_unlock(&ubi->wl_lock); |
1672 | } | 1676 | } |
1673 | 1677 | ||
1678 | up_read(&ubi->fm_protect); | ||
1674 | return err; | 1679 | return err; |
1675 | } | 1680 | } |
1676 | 1681 | ||