UBI: improve internal interfaces

Pass volume description object to the EBA function which makes
more sense, and EBA function do not have to find the volume
description object by volume ID.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Artem Bityutskiy 2007-12-16 20:00:38 +02:00
parent 77c722dde9
commit 89b96b6929
10 changed files with 68 additions and 72 deletions

View file

@ -249,7 +249,7 @@ static void kill_volumes(struct ubi_device *ubi)
for (i = 0; i < ubi->vtbl_slots; i++) for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i]) if (ubi->volumes[i])
ubi_free_volume(ubi, i); ubi_free_volume(ubi, ubi->volumes[i]);
} }
/** /**
@ -300,7 +300,7 @@ static int uif_init(struct ubi_device *ubi)
for (i = 0; i < ubi->vtbl_slots; i++) for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i]) { if (ubi->volumes[i]) {
err = ubi_add_volume(ubi, i); err = ubi_add_volume(ubi, ubi->volumes[i]);
if (err) { if (err) {
ubi_err("cannot add volume %d", i); ubi_err("cannot add volume %d", i);
goto out_volumes; goto out_volumes;

View file

@ -249,7 +249,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
if (off + len >= vol->usable_leb_size) if (off + len >= vol->usable_leb_size)
len = vol->usable_leb_size - off; len = vol->usable_leb_size - off;
err = ubi_eba_read_leb(ubi, vol_id, lnum, tbuf, off, len, 0); err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
if (err) if (err)
break; break;
@ -339,7 +339,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
break; break;
} }
err = ubi_eba_write_leb(ubi, vol_id, lnum, tbuf, off, len, err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len,
UBI_UNKNOWN); UBI_UNKNOWN);
if (err) if (err)
break; break;
@ -484,7 +484,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
} }
dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); dbg_msg("erase LEB %d:%d", vol->vol_id, lnum);
err = ubi_eba_unmap_leb(ubi, vol->vol_id, lnum); err = ubi_eba_unmap_leb(ubi, vol, lnum);
if (err) if (err)
break; break;

View file

@ -289,17 +289,17 @@ static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum)
/** /**
* ubi_eba_unmap_leb - un-map logical eraseblock. * ubi_eba_unmap_leb - un-map logical eraseblock.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* *
* This function un-maps logical eraseblock @lnum and schedules corresponding * This function un-maps logical eraseblock @lnum and schedules corresponding
* physical eraseblock for erasure. Returns zero in case of success and a * physical eraseblock for erasure. Returns zero in case of success and a
* negative error code in case of failure. * negative error code in case of failure.
*/ */
int ubi_eba_unmap_leb(struct ubi_device *ubi, int vol_id, int lnum) int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum)
{ {
int idx = vol_id2idx(ubi, vol_id), err, pnum; int err, pnum, vol_id = vol->vol_id;
struct ubi_volume *vol = ubi->volumes[idx];
if (ubi->ro_mode) if (ubi->ro_mode)
return -EROFS; return -EROFS;
@ -326,7 +326,7 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, int vol_id, int lnum)
/** /**
* ubi_eba_read_leb - read data. * ubi_eba_read_leb - read data.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* @buf: buffer to store the read data * @buf: buffer to store the read data
* @offset: offset from where to read * @offset: offset from where to read
@ -342,12 +342,11 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, int vol_id, int lnum)
* returned for any volume type if an ECC error was detected by the MTD device * returned for any volume type if an ECC error was detected by the MTD device
* driver. Other negative error cored may be returned in case of other errors. * driver. Other negative error cored may be returned in case of other errors.
*/ */
int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int offset, int len, int check) void *buf, int offset, int len, int check)
{ {
int err, pnum, scrub = 0, idx = vol_id2idx(ubi, vol_id); int err, pnum, scrub = 0, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr; struct ubi_vid_hdr *vid_hdr;
struct ubi_volume *vol = ubi->volumes[idx];
uint32_t uninitialized_var(crc); uint32_t uninitialized_var(crc);
err = leb_read_lock(ubi, vol_id, lnum); err = leb_read_lock(ubi, vol_id, lnum);
@ -555,7 +554,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
/** /**
* ubi_eba_write_leb - write data to dynamic volume. * ubi_eba_write_leb - write data to dynamic volume.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* @buf: the data to write * @buf: the data to write
* @offset: offset within the logical eraseblock where to write * @offset: offset within the logical eraseblock where to write
@ -563,15 +562,14 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
* @dtype: data type * @dtype: data type
* *
* This function writes data to logical eraseblock @lnum of a dynamic volume * This function writes data to logical eraseblock @lnum of a dynamic volume
* @vol_id. Returns zero in case of success and a negative error code in case * @vol. Returns zero in case of success and a negative error code in case
* of failure. In case of error, it is possible that something was still * of failure. In case of error, it is possible that something was still
* written to the flash media, but may be some garbage. * written to the flash media, but may be some garbage.
*/ */
int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
const void *buf, int offset, int len, int dtype) const void *buf, int offset, int len, int dtype)
{ {
int idx = vol_id2idx(ubi, vol_id), err, pnum, tries = 0; int err, pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_volume *vol = ubi->volumes[idx];
struct ubi_vid_hdr *vid_hdr; struct ubi_vid_hdr *vid_hdr;
if (ubi->ro_mode) if (ubi->ro_mode)
@ -590,7 +588,8 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
if (err) { if (err) {
ubi_warn("failed to write data to PEB %d", pnum); ubi_warn("failed to write data to PEB %d", pnum);
if (err == -EIO && ubi->bad_allowed) if (err == -EIO && ubi->bad_allowed)
err = recover_peb(ubi, pnum, vol_id, lnum, buf, offset, len); err = recover_peb(ubi, pnum, vol_id, lnum, buf,
offset, len);
if (err) if (err)
ubi_ro_mode(ubi); ubi_ro_mode(ubi);
} }
@ -678,7 +677,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
/** /**
* ubi_eba_write_leb_st - write data to static volume. * ubi_eba_write_leb_st - write data to static volume.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* @buf: data to write * @buf: data to write
* @len: how many bytes to write * @len: how many bytes to write
@ -686,7 +685,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
* @used_ebs: how many logical eraseblocks will this volume contain * @used_ebs: how many logical eraseblocks will this volume contain
* *
* This function writes data to logical eraseblock @lnum of static volume * This function writes data to logical eraseblock @lnum of static volume
* @vol_id. The @used_ebs argument should contain total number of logical * @vol. The @used_ebs argument should contain total number of logical
* eraseblock in this static volume. * eraseblock in this static volume.
* *
* When writing to the last logical eraseblock, the @len argument doesn't have * When writing to the last logical eraseblock, the @len argument doesn't have
@ -698,12 +697,11 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
* volumes. This function returns zero in case of success and a negative error * volumes. This function returns zero in case of success and a negative error
* code in case of failure. * code in case of failure.
*/ */
int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
const void *buf, int len, int dtype, int used_ebs) int lnum, const void *buf, int len, int dtype,
int used_ebs)
{ {
int err, pnum, tries = 0, data_size = len; int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id;
int idx = vol_id2idx(ubi, vol_id);
struct ubi_volume *vol = ubi->volumes[idx];
struct ubi_vid_hdr *vid_hdr; struct ubi_vid_hdr *vid_hdr;
uint32_t crc; uint32_t crc;
@ -799,7 +797,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
/* /*
* ubi_eba_atomic_leb_change - change logical eraseblock atomically. * ubi_eba_atomic_leb_change - change logical eraseblock atomically.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume escription object
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* @buf: data to write * @buf: data to write
* @len: how many bytes to write * @len: how many bytes to write
@ -814,11 +812,10 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
* UBI reserves one LEB for the "atomic LEB change" operation, so only one * UBI reserves one LEB for the "atomic LEB change" operation, so only one
* LEB change may be done at a time. This is ensured by @ubi->alc_mutex. * LEB change may be done at a time. This is ensured by @ubi->alc_mutex.
*/ */
int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
const void *buf, int len, int dtype) int lnum, const void *buf, int len, int dtype)
{ {
int err, pnum, tries = 0, idx = vol_id2idx(ubi, vol_id); int err, pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_volume *vol = ubi->volumes[idx];
struct ubi_vid_hdr *vid_hdr; struct ubi_vid_hdr *vid_hdr;
uint32_t crc; uint32_t crc;

View file

@ -129,8 +129,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
if (to_read > total_read) if (to_read > total_read)
to_read = total_read; to_read = total_read;
err = ubi_eba_read_leb(ubi, vol->vol_id, lnum, buf, offs, err = ubi_eba_read_leb(ubi, vol, lnum, buf, offs, to_read, 0);
to_read, 0);
if (err) if (err)
break; break;
@ -187,8 +186,8 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
if (to_write > total_written) if (to_write > total_written)
to_write = total_written; to_write = total_written;
err = ubi_eba_write_leb(ubi, vol->vol_id, lnum, buf, offs, err = ubi_eba_write_leb(ubi, vol, lnum, buf, offs, to_write,
to_write, UBI_UNKNOWN); UBI_UNKNOWN);
if (err) if (err)
break; break;
@ -237,7 +236,7 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EROFS; return -EROFS;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
err = ubi_eba_unmap_leb(ubi, vol->vol_id, lnum + i); err = ubi_eba_unmap_leb(ubi, vol, lnum + i);
if (err) if (err)
goto out_err; goto out_err;
} }

View file

@ -332,7 +332,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
if (len == 0) if (len == 0)
return 0; return 0;
err = ubi_eba_read_leb(ubi, vol_id, lnum, buf, offset, len, check); err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check);
if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) { if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) {
ubi_warn("mark volume %d as corrupted", vol_id); ubi_warn("mark volume %d as corrupted", vol_id);
vol->corrupted = 1; vol->corrupted = 1;
@ -399,7 +399,7 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
if (len == 0) if (len == 0)
return 0; return 0;
return ubi_eba_write_leb(ubi, vol_id, lnum, buf, offset, len, dtype); return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len, dtype);
} }
EXPORT_SYMBOL_GPL(ubi_leb_write); EXPORT_SYMBOL_GPL(ubi_leb_write);
@ -448,7 +448,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
if (len == 0) if (len == 0)
return 0; return 0;
return ubi_eba_atomic_leb_change(ubi, vol_id, lnum, buf, len, dtype); return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype);
} }
EXPORT_SYMBOL_GPL(ubi_leb_change); EXPORT_SYMBOL_GPL(ubi_leb_change);
@ -481,7 +481,7 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum)
if (vol->upd_marker) if (vol->upd_marker)
return -EBADF; return -EBADF;
err = ubi_eba_unmap_leb(ubi, vol_id, lnum); err = ubi_eba_unmap_leb(ubi, vol, lnum);
if (err) if (err)
return err; return err;
@ -542,7 +542,7 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
if (vol->upd_marker) if (vol->upd_marker)
return -EBADF; return -EBADF;
return ubi_eba_unmap_leb(ubi, vol_id, lnum); return ubi_eba_unmap_leb(ubi, vol, lnum);
} }
EXPORT_SYMBOL_GPL(ubi_leb_unmap); EXPORT_SYMBOL_GPL(ubi_leb_unmap);
@ -587,7 +587,7 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
if (vol->eba_tbl[lnum] >= 0) if (vol->eba_tbl[lnum] >= 0)
return -EBADMSG; return -EBADMSG;
return ubi_eba_write_leb(ubi, vol_id, lnum, NULL, 0, 0, dtype); return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype);
} }
EXPORT_SYMBOL_GPL(ubi_leb_map); EXPORT_SYMBOL_GPL(ubi_leb_map);

View file

@ -79,7 +79,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
else else
size = vol->usable_leb_size; size = vol->usable_leb_size;
err = ubi_eba_read_leb(ubi, vol_id, i, buf, 0, size, 1); err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
if (err) { if (err) {
if (err == -EBADMSG) if (err == -EBADMSG)
err = 1; err = 1;

View file

@ -410,8 +410,8 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si);
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req); int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req);
int ubi_remove_volume(struct ubi_volume_desc *desc); int ubi_remove_volume(struct ubi_volume_desc *desc);
int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs); int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs);
int ubi_add_volume(struct ubi_device *ubi, int vol_id); int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol);
void ubi_free_volume(struct ubi_device *ubi, int vol_id); void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol);
/* upd.c */ /* upd.c */
int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes); int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes);
@ -435,16 +435,17 @@ void ubi_gluebi_updated(struct ubi_volume *vol);
#endif #endif
/* eba.c */ /* eba.c */
int ubi_eba_unmap_leb(struct ubi_device *ubi, int vol_id, int lnum); int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, int lnum);
int offset, int len, int check); int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, int offset, int len, int check);
int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
const void *buf, int offset, int len, int dtype); const void *buf, int offset, int len, int dtype);
int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
const void *buf, int len, int dtype, int lnum, const void *buf, int len, int dtype,
int used_ebs); int used_ebs);
int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
const void *buf, int len, int dtype); int lnum, const void *buf, int len, int dtype);
int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
struct ubi_vid_hdr *vid_hdr); struct ubi_vid_hdr *vid_hdr);
int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si);

View file

@ -136,7 +136,7 @@ int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes)
/* Before updating - wipe out the volume */ /* Before updating - wipe out the volume */
for (i = 0; i < vol->reserved_pebs; i++) { for (i = 0; i < vol->reserved_pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol_id, i); err = ubi_eba_unmap_leb(ubi, vol, i);
if (err) if (err)
return err; return err;
} }
@ -209,8 +209,7 @@ static int write_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf,
if (len != l) if (len != l)
dbg_msg("skip last %d bytes (0xFF)", len - l); dbg_msg("skip last %d bytes (0xFF)", len - l);
err = ubi_eba_write_leb(ubi, vol_id, lnum, buf, 0, l, err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, l, UBI_UNKNOWN);
UBI_UNKNOWN);
} else { } else {
/* /*
* When writing static volume, and this is the last logical * When writing static volume, and this is the last logical
@ -222,7 +221,7 @@ static int write_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf,
* contain zeros, not random trash. * contain zeros, not random trash.
*/ */
memset(buf + len, 0, vol->usable_leb_size - len); memset(buf + len, 0, vol->usable_leb_size - len);
err = ubi_eba_write_leb_st(ubi, vol_id, lnum, buf, len, err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len,
UBI_UNKNOWN, used_ebs); UBI_UNKNOWN, used_ebs);
} }

View file

@ -417,7 +417,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
return err; return err;
for (i = 0; i < vol->reserved_pebs; i++) { for (i = 0; i < vol->reserved_pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol_id, i); err = ubi_eba_unmap_leb(ubi, vol, i);
if (err) if (err)
return err; return err;
} }
@ -524,7 +524,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
if (pebs < 0) { if (pebs < 0) {
for (i = 0; i < -pebs; i++) { for (i = 0; i < -pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol_id, reserved_pebs + i); err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
if (err) if (err)
goto out_acc; goto out_acc;
} }
@ -573,17 +573,16 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
/** /**
* ubi_add_volume - add volume. * ubi_add_volume - add volume.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* *
* This function adds an existin volume and initializes all its data * This function adds an existin volume and initializes all its data
* structures. Returnes zero in case of success and a negative error code in * structures. Returnes zero in case of success and a negative error code in
* case of failure. * case of failure.
*/ */
int ubi_add_volume(struct ubi_device *ubi, int vol_id) int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
{ {
int err; int err, vol_id = vol->vol_id;
dev_t dev; dev_t dev;
struct ubi_volume *vol = ubi->volumes[vol_id];
dbg_msg("add volume %d", vol_id); dbg_msg("add volume %d", vol_id);
ubi_dbg_dump_vol_info(vol); ubi_dbg_dump_vol_info(vol);
@ -634,22 +633,21 @@ int ubi_add_volume(struct ubi_device *ubi, int vol_id)
/** /**
* ubi_free_volume - free volume. * ubi_free_volume - free volume.
* @ubi: UBI device description object * @ubi: UBI device description object
* @vol_id: volume ID * @vol: volume description object
* *
* This function frees all resources for volume @vol_id but does not remove it. * This function frees all resources for volume @vol but does not remove it.
* Used only when the UBI device is detached. * Used only when the UBI device is detached.
*/ */
void ubi_free_volume(struct ubi_device *ubi, int vol_id) void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)
{ {
int err; int err;
struct ubi_volume *vol = ubi->volumes[vol_id];
dbg_msg("free volume %d", vol_id); dbg_msg("free volume %d", vol->vol_id);
ubi_assert(vol); ubi_assert(vol);
vol->removed = 1; vol->removed = 1;
err = ubi_destroy_gluebi(vol); err = ubi_destroy_gluebi(vol);
ubi->volumes[vol_id] = NULL; ubi->volumes[vol->vol_id] = NULL;
cdev_del(&vol->cdev); cdev_del(&vol->cdev);
volume_sysfs_close(vol); volume_sysfs_close(vol);
} }

View file

@ -86,8 +86,10 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
{ {
int i, err; int i, err;
uint32_t crc; uint32_t crc;
struct ubi_volume *layout_vol;
ubi_assert(idx >= 0 && idx < ubi->vtbl_slots); ubi_assert(idx >= 0 && idx < ubi->vtbl_slots);
layout_vol = ubi->volumes[vol_id2idx(UBI_LAYOUT_VOL_ID)];
if (!vtbl_rec) if (!vtbl_rec)
vtbl_rec = &empty_vtbl_record; vtbl_rec = &empty_vtbl_record;
@ -99,12 +101,12 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
mutex_lock(&ubi->vtbl_mutex); mutex_lock(&ubi->vtbl_mutex);
memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
err = ubi_eba_unmap_leb(ubi, UBI_LAYOUT_VOL_ID, i); err = ubi_eba_unmap_leb(ubi, layout_vol, i);
if (err) { if (err) {
mutex_unlock(&ubi->vtbl_mutex); mutex_unlock(&ubi->vtbl_mutex);
return err; return err;
} }
err = ubi_eba_write_leb(ubi, UBI_LAYOUT_VOL_ID, i, ubi->vtbl, 0, err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
ubi->vtbl_size, UBI_LONGTERM); ubi->vtbl_size, UBI_LONGTERM);
if (err) { if (err) {
mutex_unlock(&ubi->vtbl_mutex); mutex_unlock(&ubi->vtbl_mutex);