aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-12-26 22:55:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-26 22:55:16 -0500
commit3bef22eed98b53cfb3962884f14068251a5dd3f0 (patch)
tree7602b9239d5aa301cf8fcb37affafe86cb2bb832
parente2b0a1613200a044b0e5e3a78d157ab746a7a4fa (diff)
parent6b238de189f69dc77d660d4cce62eed15547f4c3 (diff)
Merge tag 'upstream-4.4-rc7' of git://git.infradead.org/linux-ubifs
Pull UBI bug fixes from Richard Weinberger: "This contains four bug fixes for UBI" * tag 'upstream-4.4-rc7' of git://git.infradead.org/linux-ubifs: mtd: ubi: don't leak e if schedule_erase() fails mtd: ubi: fixup error correction in do_sync_erase() UBI: fix use of "VID" vs. "EC" in header self-check UBI: fix return error code
-rw-r--r--drivers/mtd/ubi/debug.c2
-rw-r--r--drivers/mtd/ubi/io.c2
-rw-r--r--drivers/mtd/ubi/wl.c53
3 files changed, 31 insertions, 26 deletions
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index b077e43b5ba9..c4cb15a3098c 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -236,7 +236,7 @@ int ubi_debugfs_init(void)
236 236
237 dfs_rootdir = debugfs_create_dir("ubi", NULL); 237 dfs_rootdir = debugfs_create_dir("ubi", NULL);
238 if (IS_ERR_OR_NULL(dfs_rootdir)) { 238 if (IS_ERR_OR_NULL(dfs_rootdir)) {
239 int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); 239 int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
240 240
241 pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n", 241 pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
242 err); 242 err);
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 1fc23e48fe8e..10cf3b549959 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -1299,7 +1299,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
1299 if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 1299 if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
1300 goto exit; 1300 goto exit;
1301 1301
1302 crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); 1302 crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
1303 hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); 1303 hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
1304 if (hdr_crc != crc) { 1304 if (hdr_crc != crc) {
1305 ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x", 1305 ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x",
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index eb4489f9082f..56065632a5b8 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
603 return 0; 603 return 0;
604} 604}
605 605
606static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk);
606/** 607/**
607 * do_sync_erase - run the erase worker synchronously. 608 * do_sync_erase - run the erase worker synchronously.
608 * @ubi: UBI device description object 609 * @ubi: UBI device description object
@@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
615static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, 616static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
616 int vol_id, int lnum, int torture) 617 int vol_id, int lnum, int torture)
617{ 618{
618 struct ubi_work *wl_wrk; 619 struct ubi_work wl_wrk;
619 620
620 dbg_wl("sync erase of PEB %i", e->pnum); 621 dbg_wl("sync erase of PEB %i", e->pnum);
621 622
622 wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); 623 wl_wrk.e = e;
623 if (!wl_wrk) 624 wl_wrk.vol_id = vol_id;
624 return -ENOMEM; 625 wl_wrk.lnum = lnum;
625 626 wl_wrk.torture = torture;
626 wl_wrk->e = e;
627 wl_wrk->vol_id = vol_id;
628 wl_wrk->lnum = lnum;
629 wl_wrk->torture = torture;
630 627
631 return erase_worker(ubi, wl_wrk, 0); 628 return __erase_worker(ubi, &wl_wrk);
632} 629}
633 630
634/** 631/**
@@ -1014,7 +1011,7 @@ out_unlock:
1014} 1011}
1015 1012
1016/** 1013/**
1017 * erase_worker - physical eraseblock erase worker function. 1014 * __erase_worker - physical eraseblock erase worker function.
1018 * @ubi: UBI device description object 1015 * @ubi: UBI device description object
1019 * @wl_wrk: the work object 1016 * @wl_wrk: the work object
1020 * @shutdown: non-zero if the worker has to free memory and exit 1017 * @shutdown: non-zero if the worker has to free memory and exit
@@ -1025,8 +1022,7 @@ out_unlock:
1025 * needed. Returns zero in case of success and a negative error code in case of 1022 * needed. Returns zero in case of success and a negative error code in case of
1026 * failure. 1023 * failure.
1027 */ 1024 */
1028static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, 1025static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
1029 int shutdown)
1030{ 1026{
1031 struct ubi_wl_entry *e = wl_wrk->e; 1027 struct ubi_wl_entry *e = wl_wrk->e;
1032 int pnum = e->pnum; 1028 int pnum = e->pnum;
@@ -1034,21 +1030,11 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1034 int lnum = wl_wrk->lnum; 1030 int lnum = wl_wrk->lnum;
1035 int err, available_consumed = 0; 1031 int err, available_consumed = 0;
1036 1032
1037 if (shutdown) {
1038 dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
1039 kfree(wl_wrk);
1040 wl_entry_destroy(ubi, e);
1041 return 0;
1042 }
1043
1044 dbg_wl("erase PEB %d EC %d LEB %d:%d", 1033 dbg_wl("erase PEB %d EC %d LEB %d:%d",
1045 pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); 1034 pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
1046 1035
1047 err = sync_erase(ubi, e, wl_wrk->torture); 1036 err = sync_erase(ubi, e, wl_wrk->torture);
1048 if (!err) { 1037 if (!err) {
1049 /* Fine, we've erased it successfully */
1050 kfree(wl_wrk);
1051
1052 spin_lock(&ubi->wl_lock); 1038 spin_lock(&ubi->wl_lock);
1053 wl_tree_add(e, &ubi->free); 1039 wl_tree_add(e, &ubi->free);
1054 ubi->free_count++; 1040 ubi->free_count++;
@@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1066 } 1052 }
1067 1053
1068 ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err); 1054 ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err);
1069 kfree(wl_wrk);
1070 1055
1071 if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || 1056 if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
1072 err == -EBUSY) { 1057 err == -EBUSY) {
@@ -1075,6 +1060,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1075 /* Re-schedule the LEB for erasure */ 1060 /* Re-schedule the LEB for erasure */
1076 err1 = schedule_erase(ubi, e, vol_id, lnum, 0); 1061 err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
1077 if (err1) { 1062 if (err1) {
1063 wl_entry_destroy(ubi, e);
1078 err = err1; 1064 err = err1;
1079 goto out_ro; 1065 goto out_ro;
1080 } 1066 }
@@ -1150,6 +1136,25 @@ out_ro:
1150 return err; 1136 return err;
1151} 1137}
1152 1138
1139static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1140 int shutdown)
1141{
1142 int ret;
1143
1144 if (shutdown) {
1145 struct ubi_wl_entry *e = wl_wrk->e;
1146
1147 dbg_wl("cancel erasure of PEB %d EC %d", e->pnum, e->ec);
1148 kfree(wl_wrk);
1149 wl_entry_destroy(ubi, e);
1150 return 0;
1151 }
1152
1153 ret = __erase_worker(ubi, wl_wrk);
1154 kfree(wl_wrk);
1155 return ret;
1156}
1157
1153/** 1158/**
1154 * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system. 1159 * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
1155 * @ubi: UBI device description object 1160 * @ubi: UBI device description object