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 | |
| 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
| -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 | ||||
| -rw-r--r-- | fs/ubifs/commit.c | 8 | ||||
| -rw-r--r-- | fs/ubifs/debug.c | 6 | ||||
| -rw-r--r-- | fs/ubifs/journal.c | 7 | ||||
| -rw-r--r-- | fs/ubifs/log.c | 19 |
10 files changed, 79 insertions, 52 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 | ||
