diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-14 02:38:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-14 02:38:54 -0400 |
commit | b11445f830df0ec9271f39bff19ecc6f8db58eb8 (patch) | |
tree | 31b972607d563c099406235f9abcac687d1b583e /drivers | |
parent | 0ef3a56b1c466629cd0bf482b09c7b0e5a085bb5 (diff) | |
parent | 91401a34038e614076dbfb5c4969a052e72fb296 (diff) |
Merge tag 'upstream-3.18-rc1-v2' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS fixes from Artem Bityutskiy:
- fix for a theoretical race condition which could lead to a situation
when UBIFS is unable to mount a file-system (Hujianyang)
- a few fixes for the ubiblock sybsystem, error path fixes
- the ubiblock subsystem has had the volume size change handling
improved
- a few fixes and nicifications in the fastmap subsystem
* tag 'upstream-3.18-rc1-v2' of git://git.infradead.org/linux-ubifs:
UBI: Fastmap: Calc fastmap size correctly
UBIFS: Fix trivial typo in power_cut_emulated()
UBI: Fix trivial typo in __schedule_ubi_work
UBI: wl: Rename cancel flag to shutdown
UBI: ubi_eba_read_leb: Remove in vain variable assignment
UBIFS: Align the dump messages of SB_NODE
UBI: Fix livelock in produce_free_peb()
UBI: return on error in rename_volumes()
UBI: Improve comment on work_sem
UBIFS: Remove bogus assert
UBI: Dispatch update notification if the volume is updated
UBI: block: Add support for the UBI_VOLUME_UPDATED notification
UBI: block: Fix block device size setting
UBI: block: fix dereference on uninitialized dev
UBI: add missing kmem_cache_free() in process_pool_aeb error path
UBIFS: fix free log space calculation
UBIFS: fix a race condition
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/block.c | 36 | ||||
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 5 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 4 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 12 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 28 |
6 files changed, 56 insertions, 35 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 33c64955d4d7..8876c7d3d712 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c | |||
@@ -188,8 +188,9 @@ static int ubiblock_read_to_buf(struct ubiblock *dev, char *buffer, | |||
188 | 188 | ||
189 | ret = ubi_read(dev->desc, leb, buffer, offset, len); | 189 | ret = ubi_read(dev->desc, leb, buffer, offset, len); |
190 | if (ret) { | 190 | if (ret) { |
191 | ubi_err("%s ubi_read error %d", | 191 | ubi_err("%s: error %d while reading from LEB %d (offset %d, " |
192 | dev->gd->disk_name, ret); | 192 | "length %d)", dev->gd->disk_name, ret, leb, offset, |
193 | len); | ||
193 | return ret; | 194 | return ret; |
194 | } | 195 | } |
195 | return 0; | 196 | return 0; |
@@ -378,7 +379,7 @@ int ubiblock_create(struct ubi_volume_info *vi) | |||
378 | { | 379 | { |
379 | struct ubiblock *dev; | 380 | struct ubiblock *dev; |
380 | struct gendisk *gd; | 381 | struct gendisk *gd; |
381 | u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; | 382 | u64 disk_capacity = vi->used_bytes >> 9; |
382 | int ret; | 383 | int ret; |
383 | 384 | ||
384 | if ((sector_t)disk_capacity != disk_capacity) | 385 | if ((sector_t)disk_capacity != disk_capacity) |
@@ -502,13 +503,8 @@ int ubiblock_remove(struct ubi_volume_info *vi) | |||
502 | static int ubiblock_resize(struct ubi_volume_info *vi) | 503 | static int ubiblock_resize(struct ubi_volume_info *vi) |
503 | { | 504 | { |
504 | struct ubiblock *dev; | 505 | struct ubiblock *dev; |
505 | u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; | 506 | u64 disk_capacity = vi->used_bytes >> 9; |
506 | 507 | ||
507 | if ((sector_t)disk_capacity != disk_capacity) { | ||
508 | ubi_warn("%s: the volume is too big, cannot resize (%d LEBs)", | ||
509 | dev->gd->disk_name, vi->size); | ||
510 | return -EFBIG; | ||
511 | } | ||
512 | /* | 508 | /* |
513 | * Need to lock the device list until we stop using the device, | 509 | * Need to lock the device list until we stop using the device, |
514 | * otherwise the device struct might get released in | 510 | * otherwise the device struct might get released in |
@@ -520,10 +516,20 @@ static int ubiblock_resize(struct ubi_volume_info *vi) | |||
520 | mutex_unlock(&devices_mutex); | 516 | mutex_unlock(&devices_mutex); |
521 | return -ENODEV; | 517 | return -ENODEV; |
522 | } | 518 | } |
519 | if ((sector_t)disk_capacity != disk_capacity) { | ||
520 | mutex_unlock(&devices_mutex); | ||
521 | ubi_warn("%s: the volume is too big (%d LEBs), cannot resize", | ||
522 | dev->gd->disk_name, vi->size); | ||
523 | return -EFBIG; | ||
524 | } | ||
523 | 525 | ||
524 | mutex_lock(&dev->dev_mutex); | 526 | mutex_lock(&dev->dev_mutex); |
525 | set_capacity(dev->gd, disk_capacity); | 527 | |
526 | ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size); | 528 | if (get_capacity(dev->gd) != disk_capacity) { |
529 | set_capacity(dev->gd, disk_capacity); | ||
530 | ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, | ||
531 | vi->used_bytes); | ||
532 | } | ||
527 | mutex_unlock(&dev->dev_mutex); | 533 | mutex_unlock(&dev->dev_mutex); |
528 | mutex_unlock(&devices_mutex); | 534 | mutex_unlock(&devices_mutex); |
529 | return 0; | 535 | return 0; |
@@ -547,6 +553,14 @@ static int ubiblock_notify(struct notifier_block *nb, | |||
547 | case UBI_VOLUME_RESIZED: | 553 | case UBI_VOLUME_RESIZED: |
548 | ubiblock_resize(&nt->vi); | 554 | ubiblock_resize(&nt->vi); |
549 | break; | 555 | break; |
556 | case UBI_VOLUME_UPDATED: | ||
557 | /* | ||
558 | * If the volume is static, a content update might mean the | ||
559 | * size (i.e. used_bytes) was also changed. | ||
560 | */ | ||
561 | if (nt->vi.vol_type == UBI_STATIC_VOLUME) | ||
562 | ubiblock_resize(&nt->vi); | ||
563 | break; | ||
550 | default: | 564 | default: |
551 | break; | 565 | break; |
552 | } | 566 | } |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 7646220ca6e2..59de69a24e40 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -425,8 +425,10 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, | |||
425 | break; | 425 | break; |
426 | 426 | ||
427 | err = ubi_start_update(ubi, vol, bytes); | 427 | err = ubi_start_update(ubi, vol, bytes); |
428 | if (bytes == 0) | 428 | if (bytes == 0) { |
429 | ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED); | ||
429 | revoke_exclusive(desc, UBI_READWRITE); | 430 | revoke_exclusive(desc, UBI_READWRITE); |
431 | } | ||
430 | break; | 432 | break; |
431 | } | 433 | } |
432 | 434 | ||
@@ -699,7 +701,7 @@ static int rename_volumes(struct ubi_device *ubi, | |||
699 | req->ents[i].name[req->ents[i].name_len] = '\0'; | 701 | req->ents[i].name[req->ents[i].name_len] = '\0'; |
700 | n = strlen(req->ents[i].name); | 702 | n = strlen(req->ents[i].name); |
701 | if (n != req->ents[i].name_len) | 703 | if (n != req->ents[i].name_len) |
702 | err = -EINVAL; | 704 | return -EINVAL; |
703 | } | 705 | } |
704 | 706 | ||
705 | /* Make sure volume IDs and names are unique */ | 707 | /* Make sure volume IDs and names are unique */ |
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 0e11671dadc4..2402d3b50171 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -441,10 +441,9 @@ retry: | |||
441 | 441 | ||
442 | err = ubi_io_read_data(ubi, buf, pnum, offset, len); | 442 | err = ubi_io_read_data(ubi, buf, pnum, offset, len); |
443 | if (err) { | 443 | if (err) { |
444 | if (err == UBI_IO_BITFLIPS) { | 444 | if (err == UBI_IO_BITFLIPS) |
445 | scrub = 1; | 445 | scrub = 1; |
446 | err = 0; | 446 | else if (mtd_is_eccerr(err)) { |
447 | } else if (mtd_is_eccerr(err)) { | ||
448 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) | 447 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) |
449 | goto out_unlock; | 448 | goto out_unlock; |
450 | scrub = 1; | 449 | scrub = 1; |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 0431b46d9fd9..cfd5b5e90156 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -24,7 +24,8 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi) | |||
24 | { | 24 | { |
25 | size_t size; | 25 | size_t size; |
26 | 26 | ||
27 | size = sizeof(struct ubi_fm_hdr) + \ | 27 | size = sizeof(struct ubi_fm_sb) + \ |
28 | sizeof(struct ubi_fm_hdr) + \ | ||
28 | sizeof(struct ubi_fm_scan_pool) + \ | 29 | sizeof(struct ubi_fm_scan_pool) + \ |
29 | sizeof(struct ubi_fm_scan_pool) + \ | 30 | sizeof(struct ubi_fm_scan_pool) + \ |
30 | (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \ | 31 | (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \ |
@@ -330,6 +331,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
330 | av = tmp_av; | 331 | av = tmp_av; |
331 | else { | 332 | else { |
332 | ubi_err("orphaned volume in fastmap pool!"); | 333 | ubi_err("orphaned volume in fastmap pool!"); |
334 | kmem_cache_free(ai->aeb_slab_cache, new_aeb); | ||
333 | return UBI_BAD_FASTMAP; | 335 | return UBI_BAD_FASTMAP; |
334 | } | 336 | } |
335 | 337 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 7bf416329c19..320fc38fa2a1 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -439,7 +439,8 @@ struct ubi_debug_info { | |||
439 | * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, | 439 | * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, |
440 | * @erroneous, and @erroneous_peb_count fields | 440 | * @erroneous, and @erroneous_peb_count fields |
441 | * @move_mutex: serializes eraseblock moves | 441 | * @move_mutex: serializes eraseblock moves |
442 | * @work_sem: synchronizes the WL worker with use tasks | 442 | * @work_sem: used to wait for all the scheduled works to finish and prevent |
443 | * new works from being submitted | ||
443 | * @wl_scheduled: non-zero if the wear-leveling was scheduled | 444 | * @wl_scheduled: non-zero if the wear-leveling was scheduled |
444 | * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any | 445 | * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any |
445 | * physical eraseblock | 446 | * physical eraseblock |
@@ -713,14 +714,15 @@ struct ubi_attach_info { | |||
713 | * @torture: if the physical eraseblock has to be tortured | 714 | * @torture: if the physical eraseblock has to be tortured |
714 | * @anchor: produce a anchor PEB to by used by fastmap | 715 | * @anchor: produce a anchor PEB to by used by fastmap |
715 | * | 716 | * |
716 | * The @func pointer points to the worker function. If the @cancel argument is | 717 | * The @func pointer points to the worker function. If the @shutdown argument is |
717 | * not zero, the worker has to free the resources and exit immediately. The | 718 | * not zero, the worker has to free the resources and exit immediately as the |
718 | * worker has to return zero in case of success and a negative error code in | 719 | * WL sub-system is shutting down. |
720 | * The worker has to return zero in case of success and a negative error code in | ||
719 | * case of failure. | 721 | * case of failure. |
720 | */ | 722 | */ |
721 | struct ubi_work { | 723 | struct ubi_work { |
722 | struct list_head list; | 724 | struct list_head list; |
723 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | 725 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int shutdown); |
724 | /* The below fields are only relevant to erasure works */ | 726 | /* The below fields are only relevant to erasure works */ |
725 | struct ubi_wl_entry *e; | 727 | struct ubi_wl_entry *e; |
726 | int vol_id; | 728 | int vol_id; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 20f491713145..6654f191868e 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -272,7 +272,7 @@ static int produce_free_peb(struct ubi_device *ubi) | |||
272 | { | 272 | { |
273 | int err; | 273 | int err; |
274 | 274 | ||
275 | while (!ubi->free.rb_node) { | 275 | while (!ubi->free.rb_node && ubi->works_count) { |
276 | spin_unlock(&ubi->wl_lock); | 276 | spin_unlock(&ubi->wl_lock); |
277 | 277 | ||
278 | dbg_wl("do one work synchronously"); | 278 | dbg_wl("do one work synchronously"); |
@@ -835,7 +835,7 @@ repeat: | |||
835 | * @wrk: the work to schedule | 835 | * @wrk: the work to schedule |
836 | * | 836 | * |
837 | * This function adds a work defined by @wrk to the tail of the pending works | 837 | * This function adds a work defined by @wrk to the tail of the pending works |
838 | * list. Can only be used of ubi->work_sem is already held in read mode! | 838 | * list. Can only be used if ubi->work_sem is already held in read mode! |
839 | */ | 839 | */ |
840 | static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) | 840 | static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) |
841 | { | 841 | { |
@@ -864,7 +864,7 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) | |||
864 | } | 864 | } |
865 | 865 | ||
866 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | 866 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, |
867 | int cancel); | 867 | int shutdown); |
868 | 868 | ||
869 | #ifdef CONFIG_MTD_UBI_FASTMAP | 869 | #ifdef CONFIG_MTD_UBI_FASTMAP |
870 | /** | 870 | /** |
@@ -990,14 +990,15 @@ int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e, | |||
990 | * wear_leveling_worker - wear-leveling worker function. | 990 | * wear_leveling_worker - wear-leveling worker function. |
991 | * @ubi: UBI device description object | 991 | * @ubi: UBI device description object |
992 | * @wrk: the work object | 992 | * @wrk: the work object |
993 | * @cancel: non-zero if the worker has to free memory and exit | 993 | * @shutdown: non-zero if the worker has to free memory and exit |
994 | * because the WL-subsystem is shutting down | ||
994 | * | 995 | * |
995 | * This function copies a more worn out physical eraseblock to a less worn out | 996 | * This function copies a more worn out physical eraseblock to a less worn out |
996 | * one. Returns zero in case of success and a negative error code in case of | 997 | * one. Returns zero in case of success and a negative error code in case of |
997 | * failure. | 998 | * failure. |
998 | */ | 999 | */ |
999 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | 1000 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, |
1000 | int cancel) | 1001 | int shutdown) |
1001 | { | 1002 | { |
1002 | int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; | 1003 | int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; |
1003 | int vol_id = -1, uninitialized_var(lnum); | 1004 | int vol_id = -1, uninitialized_var(lnum); |
@@ -1008,7 +1009,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
1008 | struct ubi_vid_hdr *vid_hdr; | 1009 | struct ubi_vid_hdr *vid_hdr; |
1009 | 1010 | ||
1010 | kfree(wrk); | 1011 | kfree(wrk); |
1011 | if (cancel) | 1012 | if (shutdown) |
1012 | return 0; | 1013 | return 0; |
1013 | 1014 | ||
1014 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); | 1015 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
@@ -1407,7 +1408,8 @@ int ubi_ensure_anchor_pebs(struct ubi_device *ubi) | |||
1407 | * erase_worker - physical eraseblock erase worker function. | 1408 | * erase_worker - physical eraseblock erase worker function. |
1408 | * @ubi: UBI device description object | 1409 | * @ubi: UBI device description object |
1409 | * @wl_wrk: the work object | 1410 | * @wl_wrk: the work object |
1410 | * @cancel: non-zero if the worker has to free memory and exit | 1411 | * @shutdown: non-zero if the worker has to free memory and exit |
1412 | * because the WL sub-system is shutting down | ||
1411 | * | 1413 | * |
1412 | * This function erases a physical eraseblock and perform torture testing if | 1414 | * This function erases a physical eraseblock and perform torture testing if |
1413 | * needed. It also takes care about marking the physical eraseblock bad if | 1415 | * needed. It also takes care about marking the physical eraseblock bad if |
@@ -1415,7 +1417,7 @@ int ubi_ensure_anchor_pebs(struct ubi_device *ubi) | |||
1415 | * failure. | 1417 | * failure. |
1416 | */ | 1418 | */ |
1417 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | 1419 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, |
1418 | int cancel) | 1420 | int shutdown) |
1419 | { | 1421 | { |
1420 | struct ubi_wl_entry *e = wl_wrk->e; | 1422 | struct ubi_wl_entry *e = wl_wrk->e; |
1421 | int pnum = e->pnum; | 1423 | int pnum = e->pnum; |
@@ -1423,7 +1425,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1423 | int lnum = wl_wrk->lnum; | 1425 | int lnum = wl_wrk->lnum; |
1424 | int err, available_consumed = 0; | 1426 | int err, available_consumed = 0; |
1425 | 1427 | ||
1426 | if (cancel) { | 1428 | if (shutdown) { |
1427 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); | 1429 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); |
1428 | kfree(wl_wrk); | 1430 | kfree(wl_wrk); |
1429 | kmem_cache_free(ubi_wl_entry_slab, e); | 1431 | kmem_cache_free(ubi_wl_entry_slab, e); |
@@ -1845,10 +1847,10 @@ int ubi_thread(void *u) | |||
1845 | } | 1847 | } |
1846 | 1848 | ||
1847 | /** | 1849 | /** |
1848 | * cancel_pending - cancel all pending works. | 1850 | * shutdown_work - shutdown all pending works. |
1849 | * @ubi: UBI device description object | 1851 | * @ubi: UBI device description object |
1850 | */ | 1852 | */ |
1851 | static void cancel_pending(struct ubi_device *ubi) | 1853 | static void shutdown_work(struct ubi_device *ubi) |
1852 | { | 1854 | { |
1853 | while (!list_empty(&ubi->works)) { | 1855 | while (!list_empty(&ubi->works)) { |
1854 | struct ubi_work *wrk; | 1856 | struct ubi_work *wrk; |
@@ -1997,7 +1999,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) | |||
1997 | return 0; | 1999 | return 0; |
1998 | 2000 | ||
1999 | out_free: | 2001 | out_free: |
2000 | cancel_pending(ubi); | 2002 | shutdown_work(ubi); |
2001 | tree_destroy(&ubi->used); | 2003 | tree_destroy(&ubi->used); |
2002 | tree_destroy(&ubi->free); | 2004 | tree_destroy(&ubi->free); |
2003 | tree_destroy(&ubi->scrub); | 2005 | tree_destroy(&ubi->scrub); |
@@ -2029,7 +2031,7 @@ static void protection_queue_destroy(struct ubi_device *ubi) | |||
2029 | void ubi_wl_close(struct ubi_device *ubi) | 2031 | void ubi_wl_close(struct ubi_device *ubi) |
2030 | { | 2032 | { |
2031 | dbg_wl("close the WL sub-system"); | 2033 | dbg_wl("close the WL sub-system"); |
2032 | cancel_pending(ubi); | 2034 | shutdown_work(ubi); |
2033 | protection_queue_destroy(ubi); | 2035 | protection_queue_destroy(ubi); |
2034 | tree_destroy(&ubi->used); | 2036 | tree_destroy(&ubi->used); |
2035 | tree_destroy(&ubi->erroneous); | 2037 | tree_destroy(&ubi->erroneous); |