Commit cdf4a648 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'upstream' of git://git.infradead.org/~dedekind/ubi-2.6

* 'upstream' of git://git.infradead.org/~dedekind/ubi-2.6: (28 commits)
  UBI: fix compile warning
  UBI: fix error handling in erase worker
  UBI: fix comments
  UBI: remove unneeded error checks
  UBI: cleanup usage of try_module_get
  UBI: fix overflow bug
  UBI: bugfix in max_sqnum calculation
  UBI: bugfix in sqnum calculation
  UBI: fix signed-unsigned multiplication
  UBI: fix bug in atomic_leb_change()
  UBI: fix message
  UBI: fix debugging stuff
  UBI: bugfix in error path
  UBI: use is_power_of_2()
  UBI: fix freeing ubi->vtbl while unloading
  UBI: fix MAINTAINERS
  UBI: bugfix in ubi_leb_change()
  UBI: kill homegrown endian macros
  UBI: cleanup ioctl handling
  UBI: error path bugfix
  ...
parents 485cf925 add0b43c
......@@ -2393,7 +2393,7 @@ P: Artem Bityutskiy
M: dedekind@infradead.org
W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubi-2.6.git
T: git git://git.infradead.org/~dedekind/ubi-2.6.git
S: Maintained
MICROTEK X6 SCANNER
......
......@@ -33,6 +33,7 @@
#include <linux/moduleparam.h>
#include <linux/stringify.h>
#include <linux/stat.h>
#include <linux/log2.h>
#include "ubi.h"
/* Maximum length of the 'mtd=' parameter */
......@@ -369,7 +370,7 @@ static int attach_by_scanning(struct ubi_device *ubi)
out_wl:
ubi_wl_close(ubi);
out_vtbl:
kfree(ubi->vtbl);
vfree(ubi->vtbl);
out_si:
ubi_scan_destroy_si(si);
return err;
......@@ -422,8 +423,7 @@ static int io_init(struct ubi_device *ubi)
ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
/* Make sure minimal I/O unit is power of 2 */
if (ubi->min_io_size == 0 ||
(ubi->min_io_size & (ubi->min_io_size - 1))) {
if (!is_power_of_2(ubi->min_io_size)) {
ubi_err("bad min. I/O unit");
return -EINVAL;
}
......@@ -593,8 +593,6 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
if (err)
goto out_detach;
ubi_devices_cnt += 1;
ubi_msg("attached mtd%d to ubi%d", ubi->mtd->index, ubi_devices_cnt);
ubi_msg("MTD device name: \"%s\"", ubi->mtd->name);
ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20);
......@@ -624,12 +622,13 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
wake_up_process(ubi->bgt_thread);
}
ubi_devices_cnt += 1;
return 0;
out_detach:
ubi_eba_close(ubi);
ubi_wl_close(ubi);
kfree(ubi->vtbl);
vfree(ubi->vtbl);
out_free:
kfree(ubi);
out_mtd:
......@@ -650,7 +649,7 @@ static void detach_mtd_dev(struct ubi_device *ubi)
uif_close(ubi);
ubi_eba_close(ubi);
ubi_wl_close(ubi);
kfree(ubi->vtbl);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
kfree(ubi_devices[ubi_num]);
ubi_devices[ubi_num] = NULL;
......@@ -686,13 +685,6 @@ static int __init ubi_init(void)
struct mtd_dev_param *p = &mtd_dev_param[i];
cond_resched();
if (!p->name) {
dbg_err("empty name");
err = -EINVAL;
goto out_detach;
}
err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs);
if (err)
goto out_detach;
......@@ -799,7 +791,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
/* Get rid of the final newline */
if (buf[len - 1] == '\n')
buf[len - 1] = 0;
buf[len - 1] = '\0';
for (i = 0; i < 3; i++)
tokens[i] = strsep(&pbuf, ",");
......@@ -809,9 +801,6 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
return -EINVAL;
}
if (tokens[0] == '\0')
return -EINVAL;
p = &mtd_dev_param[mtd_devs];
strcpy(&p->name[0], tokens[0]);
......
......@@ -64,6 +64,7 @@ static struct ubi_device *major_to_device(int major)
if (ubi_devices[i] && ubi_devices[i]->major == major)
return ubi_devices[i];
BUG();
return NULL;
}
/**
......@@ -153,7 +154,7 @@ static int vol_cdev_release(struct inode *inode, struct file *file)
ubi_warn("update of volume %d not finished, volume is damaged",
vol->vol_id);
vol->updating = 0;
kfree(vol->upd_buf);
vfree(vol->upd_buf);
}
ubi_close_volume(desc);
......@@ -232,7 +233,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
tbuf_size = vol->usable_leb_size;
if (count < tbuf_size)
tbuf_size = ALIGN(count, ubi->min_io_size);
tbuf = kmalloc(tbuf_size, GFP_KERNEL);
tbuf = vmalloc(tbuf_size);
if (!tbuf)
return -ENOMEM;
......@@ -271,7 +272,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
len = count > tbuf_size ? tbuf_size : count;
} while (count);
kfree(tbuf);
vfree(tbuf);
return err ? err : count_save - count;
}
......@@ -320,7 +321,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
tbuf_size = vol->usable_leb_size;
if (count < tbuf_size)
tbuf_size = ALIGN(count, ubi->min_io_size);
tbuf = kmalloc(tbuf_size, GFP_KERNEL);
tbuf = vmalloc(tbuf_size);
if (!tbuf)
return -ENOMEM;
......@@ -355,7 +356,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
len = count > tbuf_size ? tbuf_size : count;
}
kfree(tbuf);
vfree(tbuf);
return err ? err : count_save - count;
}
......@@ -397,6 +398,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
vol->corrupted = 1;
}
vol->checked = 1;
ubi_gluebi_updated(vol);
revoke_exclusive(desc, UBI_READWRITE);
}
......@@ -413,19 +415,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
struct ubi_device *ubi = vol->ubi;
void __user *argp = (void __user *)arg;
if (_IOC_NR(cmd) > VOL_CDEV_IOC_MAX_SEQ ||
_IOC_TYPE(cmd) != UBI_VOL_IOC_MAGIC)
return -ENOTTY;
if (_IOC_DIR(cmd) && _IOC_READ)
err = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) && _IOC_WRITE)
err = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
if (err)
return -EFAULT;
switch (cmd) {
/* Volume update command */
case UBI_IOCVOLUP:
{
......@@ -471,7 +461,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
{
int32_t lnum;
err = __get_user(lnum, (__user int32_t *)argp);
err = get_user(lnum, (__user int32_t *)argp);
if (err) {
err = -EFAULT;
break;
......@@ -587,17 +577,6 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
struct ubi_volume_desc *desc;
void __user *argp = (void __user *)arg;
if (_IOC_NR(cmd) > UBI_CDEV_IOC_MAX_SEQ ||
_IOC_TYPE(cmd) != UBI_IOC_MAGIC)
return -ENOTTY;
if (_IOC_DIR(cmd) && _IOC_READ)
err = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) && _IOC_WRITE)
err = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
if (err)
return -EFAULT;
if (!capable(CAP_SYS_RESOURCE))
return -EPERM;
......@@ -612,7 +591,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
struct ubi_mkvol_req req;
dbg_msg("create volume");
err = __copy_from_user(&req, argp,
err = copy_from_user(&req, argp,
sizeof(struct ubi_mkvol_req));
if (err) {
err = -EFAULT;
......@@ -629,7 +608,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
if (err)
break;
err = __put_user(req.vol_id, (__user int32_t *)argp);
err = put_user(req.vol_id, (__user int32_t *)argp);
if (err)
err = -EFAULT;
......@@ -642,7 +621,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
int vol_id;
dbg_msg("remove volume");
err = __get_user(vol_id, (__user int32_t *)argp);
err = get_user(vol_id, (__user int32_t *)argp);
if (err) {
err = -EFAULT;
break;
......@@ -669,7 +648,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
struct ubi_rsvol_req req;
dbg_msg("re-size volume");
err = __copy_from_user(&req, argp,
err = copy_from_user(&req, argp,
sizeof(struct ubi_rsvol_req));
if (err) {
err = -EFAULT;
......@@ -707,7 +686,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
struct file_operations ubi_cdev_operations = {
.owner = THIS_MODULE,
.ioctl = ubi_cdev_ioctl,
.llseek = no_llseek
.llseek = no_llseek,
};
/* UBI volume character device operations */
......@@ -718,5 +697,5 @@ struct file_operations ubi_vol_cdev_operations = {
.llseek = vol_cdev_llseek,
.read = vol_cdev_read,
.write = vol_cdev_write,
.ioctl = vol_cdev_ioctl
.ioctl = vol_cdev_ioctl,
};
......@@ -35,12 +35,12 @@
void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
dbg_msg("erase counter header dump:");
dbg_msg("magic %#08x", ubi32_to_cpu(ec_hdr->magic));
dbg_msg("magic %#08x", be32_to_cpu(ec_hdr->magic));
dbg_msg("version %d", (int)ec_hdr->version);
dbg_msg("ec %llu", (long long)ubi64_to_cpu(ec_hdr->ec));
dbg_msg("vid_hdr_offset %d", ubi32_to_cpu(ec_hdr->vid_hdr_offset));
dbg_msg("data_offset %d", ubi32_to_cpu(ec_hdr->data_offset));
dbg_msg("hdr_crc %#08x", ubi32_to_cpu(ec_hdr->hdr_crc));
dbg_msg("ec %llu", (long long)be64_to_cpu(ec_hdr->ec));
dbg_msg("vid_hdr_offset %d", be32_to_cpu(ec_hdr->vid_hdr_offset));
dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset));
dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc));
dbg_msg("erase counter header hexdump:");
ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE);
}
......@@ -52,20 +52,20 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
dbg_msg("volume identifier header dump:");
dbg_msg("magic %08x", ubi32_to_cpu(vid_hdr->magic));
dbg_msg("magic %08x", be32_to_cpu(vid_hdr->magic));
dbg_msg("version %d", (int)vid_hdr->version);
dbg_msg("vol_type %d", (int)vid_hdr->vol_type);
dbg_msg("copy_flag %d", (int)vid_hdr->copy_flag);
dbg_msg("compat %d", (int)vid_hdr->compat);
dbg_msg("vol_id %d", ubi32_to_cpu(vid_hdr->vol_id));
dbg_msg("lnum %d", ubi32_to_cpu(vid_hdr->lnum));
dbg_msg("leb_ver %u", ubi32_to_cpu(vid_hdr->leb_ver));
dbg_msg("data_size %d", ubi32_to_cpu(vid_hdr->data_size));
dbg_msg("used_ebs %d", ubi32_to_cpu(vid_hdr->used_ebs));
dbg_msg("data_pad %d", ubi32_to_cpu(vid_hdr->data_pad));
dbg_msg("vol_id %d", be32_to_cpu(vid_hdr->vol_id));
dbg_msg("lnum %d", be32_to_cpu(vid_hdr->lnum));
dbg_msg("leb_ver %u", be32_to_cpu(vid_hdr->leb_ver));
dbg_msg("data_size %d", be32_to_cpu(vid_hdr->data_size));
dbg_msg("used_ebs %d", be32_to_cpu(vid_hdr->used_ebs));
dbg_msg("data_pad %d", be32_to_cpu(vid_hdr->data_pad));
dbg_msg("sqnum %llu",
(unsigned long long)ubi64_to_cpu(vid_hdr->sqnum));
dbg_msg("hdr_crc %08x", ubi32_to_cpu(vid_hdr->hdr_crc));
(unsigned long long)be64_to_cpu(vid_hdr->sqnum));
dbg_msg("hdr_crc %08x", be32_to_cpu(vid_hdr->hdr_crc));
dbg_msg("volume identifier header hexdump:");
}
......@@ -91,7 +91,7 @@ void ubi_dbg_dump_vol_info(const struct ubi_volume *vol)
if (vol->name_len <= UBI_VOL_NAME_MAX &&
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
dbg_msg("name %s", vol->name);
dbg_msg("name %s", vol->name);
} else {
dbg_msg("the 1st 5 characters of the name: %c%c%c%c%c",
vol->name[0], vol->name[1], vol->name[2],
......@@ -106,30 +106,30 @@ void ubi_dbg_dump_vol_info(const struct ubi_volume *vol)
*/
void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
int name_len = ubi16_to_cpu(r->name_len);
int name_len = be16_to_cpu(r->name_len);
dbg_msg("volume table record %d dump:", idx);
dbg_msg("reserved_pebs %d", ubi32_to_cpu(r->reserved_pebs));
dbg_msg("alignment %d", ubi32_to_cpu(r->alignment));
dbg_msg("data_pad %d", ubi32_to_cpu(r->data_pad));
dbg_msg("reserved_pebs %d", be32_to_cpu(r->reserved_pebs));
dbg_msg("alignment %d", be32_to_cpu(r->alignment));
dbg_msg("data_pad %d", be32_to_cpu(r->data_pad));
dbg_msg("vol_type %d", (int)r->vol_type);
dbg_msg("upd_marker %d", (int)r->upd_marker);
dbg_msg("name_len %d", name_len);
if (r->name[0] == '\0') {
dbg_msg("name NULL");
dbg_msg("name NULL");
return;
}
if (name_len <= UBI_VOL_NAME_MAX &&
strnlen(&r->name[0], name_len + 1) == name_len) {
dbg_msg("name %s", &r->name[0]);
dbg_msg("name %s", &r->name[0]);
} else {
dbg_msg("1st 5 characters of the name: %c%c%c%c%c",
r->name[0], r->name[1], r->name[2], r->name[3],
r->name[4]);
}
dbg_msg("crc %#08x", ubi32_to_cpu(r->crc));
dbg_msg("crc %#08x", be32_to_cpu(r->crc));
}
/**
......
......@@ -52,7 +52,6 @@ struct ubi_scan_volume;
struct ubi_scan_leb;
struct ubi_mkvol_req;
void ubi_dbg_print(int type, const char *func, const char *fmt, ...);
void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr);
void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
void ubi_dbg_dump_vol_info(const struct ubi_volume *vol);
......@@ -66,7 +65,6 @@ void ubi_dbg_hexdump(const void *buf, int size);
#define dbg_msg(fmt, ...) ({})
#define ubi_dbg_dump_stack() ({})
#define ubi_dbg_print(func, fmt, ...) ({})
#define ubi_dbg_dump_ec_hdr(ec_hdr) ({})
#define ubi_dbg_dump_vid_hdr(vid_hdr) ({})
#define ubi_dbg_dump_vol_info(vol) ({})
......
......@@ -425,10 +425,10 @@ retry:
} else if (err == UBI_IO_BITFLIPS)
scrub = 1;
ubi_assert(lnum < ubi32_to_cpu(vid_hdr->used_ebs));
ubi_assert(len == ubi32_to_cpu(vid_hdr->data_size));
ubi_assert(lnum < be32_to_cpu(vid_hdr->used_ebs));
ubi_assert(len == be32_to_cpu(vid_hdr->data_size));
crc = ubi32_to_cpu(vid_hdr->data_crc);
crc = be32_to_cpu(vid_hdr->data_crc);
ubi_free_vid_hdr(ubi, vid_hdr);
}
......@@ -518,13 +518,13 @@ retry:
goto out_put;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
if (err)
goto write_error;
data_size = offset + len;
new_buf = kmalloc(data_size, GFP_KERNEL);
new_buf = vmalloc(data_size);
if (!new_buf) {
err = -ENOMEM;
goto out_put;
......@@ -535,7 +535,7 @@ retry:
if (offset > 0) {
err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset);
if (err && err != UBI_IO_BITFLIPS) {
kfree(new_buf);
vfree(new_buf);
goto out_put;
}
}
......@@ -544,11 +544,11 @@ retry:
err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size);
if (err) {
kfree(new_buf);
vfree(new_buf);
goto write_error;
}
kfree(new_buf);
vfree(new_buf);
ubi_free_vid_hdr(ubi, vid_hdr);
vol->eba_tbl[lnum] = new_pnum;
......@@ -634,11 +634,11 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
}
vid_hdr->vol_type = UBI_VID_DYNAMIC;
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_ubi32(vol_id);
vid_hdr->lnum = cpu_to_ubi32(lnum);
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
vid_hdr->data_pad = cpu_to_be32(vol->data_pad);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
......@@ -692,7 +692,7 @@ write_error:
return err;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
......@@ -748,17 +748,17 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
return err;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_ubi32(vol_id);
vid_hdr->lnum = cpu_to_ubi32(lnum);
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
vid_hdr->data_pad = cpu_to_be32(vol->data_pad);
crc = crc32(UBI_CRC32_INIT, buf, data_size);
vid_hdr->vol_type = UBI_VID_STATIC;
vid_hdr->data_size = cpu_to_ubi32(data_size);
vid_hdr->used_ebs = cpu_to_ubi32(used_ebs);
vid_hdr->data_crc = cpu_to_ubi32(crc);
vid_hdr->data_size = cpu_to_be32(data_size);
vid_hdr->used_ebs = cpu_to_be32(used_ebs);
vid_hdr->data_crc = cpu_to_be32(crc);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
......@@ -813,7 +813,7 @@ write_error:
return err;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
......@@ -854,17 +854,17 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
return err;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_ubi32(vol_id);
vid_hdr->lnum = cpu_to_ubi32(lnum);
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad);
vid_hdr->data_pad = cpu_to_be32(vol->data_pad);
crc = crc32(UBI_CRC32_INIT, buf, len);
vid_hdr->vol_type = UBI_VID_STATIC;
vid_hdr->data_size = cpu_to_ubi32(len);
vid_hdr->vol_type = UBI_VID_DYNAMIC;
vid_hdr->data_size = cpu_to_be32(len);
vid_hdr->copy_flag = 1;
vid_hdr->data_crc = cpu_to_ubi32(crc);
vid_hdr->data_crc = cpu_to_be32(crc);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
......@@ -891,11 +891,13 @@ retry:
goto write_error;
}
err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1);
if (err) {
ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum);
return err;
if (vol->eba_tbl[lnum] >= 0) {
err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1);
if (err) {
ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum);
return err;
}
}
vol->eba_tbl[lnum] = pnum;
......@@ -924,7 +926,7 @@ write_error:
return err;
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
......@@ -965,19 +967,19 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
uint32_t crc;
void *buf, *buf1 = NULL;
vol_id = ubi32_to_cpu(vid_hdr->vol_id);
lnum = ubi32_to_cpu(vid_hdr->lnum);
vol_id = be32_to_cpu(vid_hdr->vol_id);
lnum = be32_to_cpu(vid_hdr->lnum);
dbg_eba("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to);
if (vid_hdr->vol_type == UBI_VID_STATIC) {
data_size = ubi32_to_cpu(vid_hdr->data_size);
data_size = be32_to_cpu(vid_hdr->data_size);
aldata_size = ALIGN(data_size, ubi->min_io_size);
} else
data_size = aldata_size =
ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad);
ubi->leb_size - be32_to_cpu(vid_hdr->data_pad);
buf = kmalloc(aldata_size, GFP_KERNEL);
buf = vmalloc(aldata_size);
if (!buf)
return -ENOMEM;
......@@ -987,7 +989,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
*/
err = leb_write_lock(ubi, vol_id, lnum);
if (err) {
kfree(buf);
vfree(buf);
return err;
}
......@@ -1054,10 +1056,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
*/
if (data_size > 0) {
vid_hdr->copy_flag = 1;
vid_hdr->data_size = cpu_to_ubi32(data_size);
vid_hdr->data_crc = cpu_to_ubi32(crc);
vid_hdr->data_size = cpu_to_be32(data_size);
vid_hdr->data_crc = cpu_to_be32(crc);
}
vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi));
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
if (err)
......@@ -1082,7 +1084,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
* We've written the data and are going to read it back to make
* sure it was written correctly.
*/
buf1 = kmalloc(aldata_size, GFP_KERNEL);
buf1 = vmalloc(aldata_size);
if (!buf1) {
err = -ENOMEM;
goto out_unlock;
......@@ -1111,15 +1113,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
vol->eba_tbl[lnum] = to;
leb_write_unlock(ubi, vol_id, lnum);
kfree(buf);
kfree(buf1);
vfree(buf);
vfree(buf1);
return 0;
out_unlock:
leb_write_unlock(ubi, vol_id, lnum);
kfree(buf);
kfree(buf1);
vfree(buf);
vfree(buf1);
return err;
}
......
......@@ -282,7 +282,6 @@ int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol)
mtd->flags = MTD_WRITEABLE;
mtd->writesize = ubi->min_io_size;
mtd->owner = THIS_MODULE;
mtd->size = vol->usable_leb_size * vol->reserved_pebs;
mtd->erasesize = vol->usable_leb_size;
mtd->read = gluebi_read;
mtd->write = gluebi_write;
......@@ -290,6 +289,15 @@ int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol)
mtd->get_device = gluebi_get_device;
mtd->put_device = gluebi_put_device;
/*
* In case of dynamic volume, MTD device size is just volume size. In
* case of a static volume the size is equivalent to the amount of data
* bytes, which is zero at this moment and will be changed after volume
* update.
*/
if (vol->vol_type == UBI_DYNAMIC_VOLUME)
mtd->size = vol->usable_leb_size * vol->reserved_pebs;