This pull request contains four bug fixes for UBI.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJWenfTAAoJEEtJtSqsAOnWmYwQAMd4R4/OwBvNgKKYyBW4D/yv wku0ToGnmdcJ6d85eHuMVSwx/5ATAdom4W12LVxyifA4UxF2OkwMnU/hQEYFsAXJ gWv4O9Hj6d+hv4EVMRvH5/Q9Oqp8cMDyM9GcbR6vJ6jDWn9KM6VXnaydvpWmGgLN Zi+0YJIgHENuieQ66VNVUT+WdQ2DgkUEdZBNc5YaRGbzBrCzGF4tATWw1rZ8P0v2 tRtcY0NykoCkxRnnsa/RQfuojkzAB2vVFRl2iFg2//5rkFjo/zFyGal/VPl8hSyk frZgZUiJRo0AEr4eZGSPc3IRliKqtdFdVrNaxIqwzG5R7YCDHjmuNq4FlLGvXpkt xf6WgIxNrtfXMVLBizHHy5QivcsHLxW0TKq+oFQymO0L8D3IoU/9zBXLS1TcvCxL cLn3SqxG/b7MWsq6PfVl2jI338O0uJhKAvnWhj9HsH4tgnP7Bfkn6RF8Dwy6HtJ9 SIerXqjnkw9R1KydOrVFRm4bJ4M6VxI8G/+CiUpQuSgihWvrjgqQ6HXc/nAPRGUt 6nasEuDWa4lIujACNQjgT+TgsLhiuERllI5aA0zp8LlP2jwxGFtDsAD7eaubQ7TM xazdglGJoIDh7C+CdZBmG070uWgQlNNb5CEWrc3cF4OAmTHvXgpYv04EWpiAVec7 2j7u2+zqHGhjQ29KEJac =84oS -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
3bef22eed9
|
@ -236,7 +236,7 @@ int ubi_debugfs_init(void)
|
|||
|
||||
dfs_rootdir = debugfs_create_dir("ubi", NULL);
|
||||
if (IS_ERR_OR_NULL(dfs_rootdir)) {
|
||||
int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir);
|
||||
int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
|
||||
|
||||
pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
|
||||
err);
|
||||
|
|
|
@ -1299,7 +1299,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
|
|||
if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
|
||||
goto exit;
|
||||
|
||||
crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
|
||||
crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
|
||||
hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
|
||||
if (hdr_crc != crc) {
|
||||
ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x",
|
||||
|
|
|
@ -603,6 +603,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk);
|
||||
/**
|
||||
* do_sync_erase - run the erase worker synchronously.
|
||||
* @ubi: UBI device description object
|
||||
|
@ -615,20 +616,16 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
|
|||
static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
|
||||
int vol_id, int lnum, int torture)
|
||||
{
|
||||
struct ubi_work *wl_wrk;
|
||||
struct ubi_work wl_wrk;
|
||||
|
||||
dbg_wl("sync erase of PEB %i", e->pnum);
|
||||
|
||||
wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
|
||||
if (!wl_wrk)
|
||||
return -ENOMEM;
|
||||
wl_wrk.e = e;
|
||||
wl_wrk.vol_id = vol_id;
|
||||
wl_wrk.lnum = lnum;
|
||||
wl_wrk.torture = torture;
|
||||
|
||||
wl_wrk->e = e;
|
||||
wl_wrk->vol_id = vol_id;
|
||||
wl_wrk->lnum = lnum;
|
||||
wl_wrk->torture = torture;
|
||||
|
||||
return erase_worker(ubi, wl_wrk, 0);
|
||||
return __erase_worker(ubi, &wl_wrk);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1014,7 +1011,7 @@ out_unlock:
|
|||
}
|
||||
|
||||
/**
|
||||
* erase_worker - physical eraseblock erase worker function.
|
||||
* __erase_worker - physical eraseblock erase worker function.
|
||||
* @ubi: UBI device description object
|
||||
* @wl_wrk: the work object
|
||||
* @shutdown: non-zero if the worker has to free memory and exit
|
||||
|
@ -1025,8 +1022,7 @@ out_unlock:
|
|||
* needed. Returns zero in case of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
||||
int shutdown)
|
||||
static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
|
||||
{
|
||||
struct ubi_wl_entry *e = wl_wrk->e;
|
||||
int pnum = e->pnum;
|
||||
|
@ -1034,21 +1030,11 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
|||
int lnum = wl_wrk->lnum;
|
||||
int err, available_consumed = 0;
|
||||
|
||||
if (shutdown) {
|
||||
dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
|
||||
kfree(wl_wrk);
|
||||
wl_entry_destroy(ubi, e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbg_wl("erase PEB %d EC %d LEB %d:%d",
|
||||
pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
|
||||
|
||||
err = sync_erase(ubi, e, wl_wrk->torture);
|
||||
if (!err) {
|
||||
/* Fine, we've erased it successfully */
|
||||
kfree(wl_wrk);
|
||||
|
||||
spin_lock(&ubi->wl_lock);
|
||||
wl_tree_add(e, &ubi->free);
|
||||
ubi->free_count++;
|
||||
|
@ -1066,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
|||
}
|
||||
|
||||
ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err);
|
||||
kfree(wl_wrk);
|
||||
|
||||
if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
|
||||
err == -EBUSY) {
|
||||
|
@ -1075,6 +1060,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
|||
/* Re-schedule the LEB for erasure */
|
||||
err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
|
||||
if (err1) {
|
||||
wl_entry_destroy(ubi, e);
|
||||
err = err1;
|
||||
goto out_ro;
|
||||
}
|
||||
|
@ -1150,6 +1136,25 @@ out_ro:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
||||
int shutdown)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (shutdown) {
|
||||
struct ubi_wl_entry *e = wl_wrk->e;
|
||||
|
||||
dbg_wl("cancel erasure of PEB %d EC %d", e->pnum, e->ec);
|
||||
kfree(wl_wrk);
|
||||
wl_entry_destroy(ubi, e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = __erase_worker(ubi, wl_wrk);
|
||||
kfree(wl_wrk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
|
||||
* @ubi: UBI device description object
|
||||
|
|
Загрузка…
Ссылка в новой задаче