Skip to content

Commit

Permalink
Merge tag 'upstream-3.8-rc1' of git://git.infradead.org/linux-ubi
Browse files Browse the repository at this point in the history
Pull UBI update from Artem Bityutskiy:
 "Nothing exciting, just clean-ups and nicification.  Oh, and one small
  optimization which makes UBI to use less RAM."

* tag 'upstream-3.8-rc1' of git://git.infradead.org/linux-ubi:
  UBI: embed ubi_debug_info field in ubi_device struct
  UBI: introduce helpers dbg_chk_{io, gen}
  UBI: replace memcpy with struct assignment
  UBI: remove spurious comment
  UBI: gluebi: rename misleading variables
  UBI: do not allocate the memory unnecessarily
  UBI: use list_move_tail instead of list_del/list_add_tail
  • Loading branch information
Linus Torvalds committed Dec 20, 2012
2 parents 43260ad + eab7377 commit 85d5b70
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 135 deletions.
23 changes: 9 additions & 14 deletions drivers/mtd/ubi/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
int pnum, const struct ubi_vid_hdr *vid_hdr)
{
void *buf;
int len, err, second_is_newer, bitflips = 0, corrupted = 0;
uint32_t data_crc, crc;
struct ubi_vid_hdr *vh = NULL;
Expand Down Expand Up @@ -393,18 +392,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
/* Read the data of the copy and check the CRC */

len = be32_to_cpu(vid_hdr->data_size);
buf = vmalloc(len);
if (!buf) {
err = -ENOMEM;
goto out_free_vidh;
}

err = ubi_io_read_data(ubi, buf, pnum, 0, len);
mutex_lock(&ubi->buf_mutex);
err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len);
if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
goto out_free_buf;
goto out_unlock;

data_crc = be32_to_cpu(vid_hdr->data_crc);
crc = crc32(UBI_CRC32_INIT, buf, len);
crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len);
if (crc != data_crc) {
dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x",
pnum, crc, data_crc);
Expand All @@ -415,8 +410,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
dbg_bld("PEB %d CRC is OK", pnum);
bitflips = !!err;
}
mutex_unlock(&ubi->buf_mutex);

vfree(buf);
ubi_free_vid_hdr(ubi, vh);

if (second_is_newer)
Expand All @@ -426,8 +421,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,

return second_is_newer | (bitflips << 1) | (corrupted << 2);

out_free_buf:
vfree(buf);
out_unlock:
mutex_unlock(&ubi->buf_mutex);
out_free_vidh:
ubi_free_vid_hdr(ubi, vh);
return err;
Expand Down Expand Up @@ -1453,7 +1448,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
goto out_wl;

#ifdef CONFIG_MTD_UBI_FASTMAP
if (ubi->fm && ubi->dbg->chk_gen) {
if (ubi->fm && ubi_dbg_chk_gen(ubi)) {
struct ubi_attach_info *scan_ai;

scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
Expand Down Expand Up @@ -1503,7 +1498,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai)
struct ubi_ainf_peb *aeb, *last_aeb;
uint8_t *buf;

if (!ubi->dbg->chk_gen)
if (!ubi_dbg_chk_gen(ubi))
return 0;

/*
Expand Down
12 changes: 2 additions & 10 deletions drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
* No available PEBs to re-size the volume, clear the flag on
* flash and exit.
*/
memcpy(&vtbl_rec, &ubi->vtbl[vol_id],
sizeof(struct ubi_vtbl_record));
vtbl_rec = ubi->vtbl[vol_id];
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
ubi_err("cannot clean auto-resize flag for volume %d",
Expand Down Expand Up @@ -986,14 +985,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
if (!ubi->fm_buf)
goto out_free;
#endif
err = ubi_debugging_init_dev(ubi);
if (err)
goto out_free;

err = ubi_attach(ubi, 0);
if (err) {
ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
goto out_debugging;
goto out_free;
}

if (ubi->autoresize_vol_id != -1) {
Expand Down Expand Up @@ -1060,8 +1055,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_debugging:
ubi_debugging_exit_dev(ubi);
out_free:
vfree(ubi->peb_buf);
vfree(ubi->fm_buf);
Expand Down Expand Up @@ -1139,7 +1132,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
ubi_debugging_exit_dev(ubi);
vfree(ubi->peb_buf);
vfree(ubi->fm_buf);
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
Expand Down
34 changes: 4 additions & 30 deletions drivers/mtd/ubi/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,32 +217,6 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
pr_err("\t1st 16 characters of name: %s\n", nm);
}

/**
* ubi_debugging_init_dev - initialize debugging for an UBI device.
* @ubi: UBI device description object
*
* This function initializes debugging-related data for UBI device @ubi.
* Returns zero in case of success and a negative error code in case of
* failure.
*/
int ubi_debugging_init_dev(struct ubi_device *ubi)
{
ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL);
if (!ubi->dbg)
return -ENOMEM;

return 0;
}

/**
* ubi_debugging_exit_dev - free debugging data for an UBI device.
* @ubi: UBI device description object
*/
void ubi_debugging_exit_dev(struct ubi_device *ubi)
{
kfree(ubi->dbg);
}

/*
* Root directory for UBI stuff in debugfs. Contains sub-directories which
* contain the stuff specific to particular UBI devices.
Expand Down Expand Up @@ -295,7 +269,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
d = ubi->dbg;
d = &ubi->dbg;

if (dent == d->dfs_chk_gen)
val = d->chk_gen;
Expand Down Expand Up @@ -341,7 +315,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
d = ubi->dbg;
d = &ubi->dbg;

buf_size = min_t(size_t, count, (sizeof(buf) - 1));
if (copy_from_user(buf, user_buf, buf_size)) {
Expand Down Expand Up @@ -398,7 +372,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
unsigned long ubi_num = ubi->ubi_num;
const char *fname;
struct dentry *dent;
struct ubi_debug_info *d = ubi->dbg;
struct ubi_debug_info *d = &ubi->dbg;

if (!IS_ENABLED(CONFIG_DEBUG_FS))
return 0;
Expand Down Expand Up @@ -471,5 +445,5 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
void ubi_debugfs_exit_dev(struct ubi_device *ubi)
{
if (IS_ENABLED(CONFIG_DEBUG_FS))
debugfs_remove_recursive(ubi->dbg->dfs_dir);
debugfs_remove_recursive(ubi->dbg.dfs_dir);
}
57 changes: 13 additions & 44 deletions drivers/mtd/ubi/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,51 +60,11 @@ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type);
void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req);
int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
int len);
int ubi_debugging_init_dev(struct ubi_device *ubi);
void ubi_debugging_exit_dev(struct ubi_device *ubi);
int ubi_debugfs_init(void);
void ubi_debugfs_exit(void);
int ubi_debugfs_init_dev(struct ubi_device *ubi);
void ubi_debugfs_exit_dev(struct ubi_device *ubi);

/*
* The UBI debugfs directory name pattern and maximum name length (3 for "ubi"
* + 2 for the number plus 1 for the trailing zero byte.
*/
#define UBI_DFS_DIR_NAME "ubi%d"
#define UBI_DFS_DIR_LEN (3 + 2 + 1)

/**
* struct ubi_debug_info - debugging information for an UBI device.
*
* @chk_gen: if UBI general extra checks are enabled
* @chk_io: if UBI I/O extra checks are enabled
* @disable_bgt: disable the background task for testing purposes
* @emulate_bitflips: emulate bit-flips for testing purposes
* @emulate_io_failures: emulate write/erase failures for testing purposes
* @dfs_dir_name: name of debugfs directory containing files of this UBI device
* @dfs_dir: direntry object of the UBI device debugfs directory
* @dfs_chk_gen: debugfs knob to enable UBI general extra checks
* @dfs_chk_io: debugfs knob to enable UBI I/O extra checks
* @dfs_disable_bgt: debugfs knob to disable the background task
* @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
* @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
*/
struct ubi_debug_info {
unsigned int chk_gen:1;
unsigned int chk_io:1;
unsigned int disable_bgt:1;
unsigned int emulate_bitflips:1;
unsigned int emulate_io_failures:1;
char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_chk_gen;
struct dentry *dfs_chk_io;
struct dentry *dfs_disable_bgt;
struct dentry *dfs_emulate_bitflips;
struct dentry *dfs_emulate_io_failures;
};

/**
* ubi_dbg_is_bgt_disabled - if the background thread is disabled.
* @ubi: UBI device description object
Expand All @@ -114,7 +74,7 @@ struct ubi_debug_info {
*/
static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
{
return ubi->dbg->disable_bgt;
return ubi->dbg.disable_bgt;
}

/**
Expand All @@ -125,7 +85,7 @@ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
*/
static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
{
if (ubi->dbg->emulate_bitflips)
if (ubi->dbg.emulate_bitflips)
return !(random32() % 200);
return 0;
}
Expand All @@ -139,7 +99,7 @@ static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
*/
static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
{
if (ubi->dbg->emulate_io_failures)
if (ubi->dbg.emulate_io_failures)
return !(random32() % 500);
return 0;
}
Expand All @@ -153,9 +113,18 @@ static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
*/
static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
{
if (ubi->dbg->emulate_io_failures)
if (ubi->dbg.emulate_io_failures)
return !(random32() % 400);
return 0;
}

static inline int ubi_dbg_chk_io(const struct ubi_device *ubi)
{
return ubi->dbg.chk_io;
}

static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi)
{
return ubi->dbg.chk_gen;
}
#endif /* !__UBI_DEBUG_H__ */
6 changes: 2 additions & 4 deletions drivers/mtd/ubi/fastmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,10 +814,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
if (max_sqnum > ai->max_sqnum)
ai->max_sqnum = max_sqnum;

list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
list_del(&tmp_aeb->u.list);
list_add_tail(&tmp_aeb->u.list, &ai->free);
}
list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list)
list_move_tail(&tmp_aeb->u.list, &ai->free);

/*
* If fastmap is leaking PEBs (must not happen), raise a
Expand Down
28 changes: 14 additions & 14 deletions drivers/mtd/ubi/gluebi.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,29 +171,29 @@ static void gluebi_put_device(struct mtd_info *mtd)
static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, unsigned char *buf)
{
int err = 0, lnum, offs, total_read;
int err = 0, lnum, offs, bytes_left;
struct gluebi_device *gluebi;

gluebi = container_of(mtd, struct gluebi_device, mtd);
lnum = div_u64_rem(from, mtd->erasesize, &offs);
total_read = len;
while (total_read) {
bytes_left = len;
while (bytes_left) {
size_t to_read = mtd->erasesize - offs;

if (to_read > total_read)
to_read = total_read;
if (to_read > bytes_left)
to_read = bytes_left;

err = ubi_read(gluebi->desc, lnum, buf, offs, to_read);
if (err)
break;

lnum += 1;
offs = 0;
total_read -= to_read;
bytes_left -= to_read;
buf += to_read;
}

*retlen = len - total_read;
*retlen = len - bytes_left;
return err;
}

Expand All @@ -211,7 +211,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
int err = 0, lnum, offs, total_written;
int err = 0, lnum, offs, bytes_left;
struct gluebi_device *gluebi;

gluebi = container_of(mtd, struct gluebi_device, mtd);
Expand All @@ -220,24 +220,24 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
if (len % mtd->writesize || offs % mtd->writesize)
return -EINVAL;

total_written = len;
while (total_written) {
bytes_left = len;
while (bytes_left) {
size_t to_write = mtd->erasesize - offs;

if (to_write > total_written)
to_write = total_written;
if (to_write > bytes_left)
to_write = bytes_left;

err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write);
if (err)
break;

lnum += 1;
offs = 0;
total_written -= to_write;
bytes_left -= to_write;
buf += to_write;
}

*retlen = len - total_written;
*retlen = len - bytes_left;
return err;
}

Expand Down
Loading

0 comments on commit 85d5b70

Please sign in to comment.