Skip to content

Commit 3bef22e

Browse files
committed
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
2 parents e2b0a16 + 6b238de commit 3bef22e

File tree

3 files changed

+31
-26
lines changed

3 files changed

+31
-26
lines changed

drivers/mtd/ubi/debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ int ubi_debugfs_init(void)
236236

237237
dfs_rootdir = debugfs_create_dir("ubi", NULL);
238238
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;
240240

241241
pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
242242
err);

drivers/mtd/ubi/io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
12991299
if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
13001300
goto exit;
13011301

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);
13031303
hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
13041304
if (hdr_crc != crc) {
13051305
ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x",

drivers/mtd/ubi/wl.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
603603
return 0;
604604
}
605605

606+
static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk);
606607
/**
607608
* do_sync_erase - run the erase worker synchronously.
608609
* @ubi: UBI device description object
@@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
615616
static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
616617
int vol_id, int lnum, int torture)
617618
{
618-
struct ubi_work *wl_wrk;
619+
struct ubi_work wl_wrk;
619620

620621
dbg_wl("sync erase of PEB %i", e->pnum);
621622

622-
wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
623-
if (!wl_wrk)
624-
return -ENOMEM;
625-
626-
wl_wrk->e = e;
627-
wl_wrk->vol_id = vol_id;
628-
wl_wrk->lnum = lnum;
629-
wl_wrk->torture = torture;
623+
wl_wrk.e = e;
624+
wl_wrk.vol_id = vol_id;
625+
wl_wrk.lnum = lnum;
626+
wl_wrk.torture = torture;
630627

631-
return erase_worker(ubi, wl_wrk, 0);
628+
return __erase_worker(ubi, &wl_wrk);
632629
}
633630

634631
/**
@@ -1014,7 +1011,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
10141011
}
10151012

10161013
/**
1017-
* erase_worker - physical eraseblock erase worker function.
1014+
* __erase_worker - physical eraseblock erase worker function.
10181015
* @ubi: UBI device description object
10191016
* @wl_wrk: the work object
10201017
* @shutdown: non-zero if the worker has to free memory and exit
@@ -1025,30 +1022,19 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
10251022
* needed. Returns zero in case of success and a negative error code in case of
10261023
* failure.
10271024
*/
1028-
static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1029-
int shutdown)
1025+
static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
10301026
{
10311027
struct ubi_wl_entry *e = wl_wrk->e;
10321028
int pnum = e->pnum;
10331029
int vol_id = wl_wrk->vol_id;
10341030
int lnum = wl_wrk->lnum;
10351031
int err, available_consumed = 0;
10361032

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-
10441033
dbg_wl("erase PEB %d EC %d LEB %d:%d",
10451034
pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
10461035

10471036
err = sync_erase(ubi, e, wl_wrk->torture);
10481037
if (!err) {
1049-
/* Fine, we've erased it successfully */
1050-
kfree(wl_wrk);
1051-
10521038
spin_lock(&ubi->wl_lock);
10531039
wl_tree_add(e, &ubi->free);
10541040
ubi->free_count++;
@@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
10661052
}
10671053

10681054
ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err);
1069-
kfree(wl_wrk);
10701055

10711056
if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
10721057
err == -EBUSY) {
@@ -1075,6 +1060,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
10751060
/* Re-schedule the LEB for erasure */
10761061
err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
10771062
if (err1) {
1063+
wl_entry_destroy(ubi, e);
10781064
err = err1;
10791065
goto out_ro;
10801066
}
@@ -1150,6 +1136,25 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
11501136
return err;
11511137
}
11521138

1139+
static 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+
11531158
/**
11541159
* ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
11551160
* @ubi: UBI device description object

0 commit comments

Comments
 (0)