From d99383b00eba9c6ac3dea462d718b2849012ee03 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 14:47:34 +0300 Subject: UBI: change the interface of a debugging check function This is a minor preparational patch which changes the 'paranoid_check_in_wl_tree()' function interface by adding the 'ubi' parameter which will be needed there in the next patch. And while on it, add "const" qualifier to the 'ubi' parameter of the 'paranoid_check_in_pq()' function. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index ff2c4956eeff..d5076d2cce39 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1,4 +1,5 @@ /* + * @ubi: UBI device description object * Copyright (c) International Business Machines Corp., 2006 * * This program is free software; you can redistribute it and/or modify @@ -163,12 +164,14 @@ struct ubi_work { #ifdef CONFIG_MTD_UBI_DEBUG static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); -static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, +static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, + struct ubi_wl_entry *e, struct rb_root *root); -static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e); +static int paranoid_check_in_pq(const struct ubi_device *ubi, + struct ubi_wl_entry *e); #else #define paranoid_check_ec(ubi, pnum, ec) 0 -#define paranoid_check_in_wl_tree(e, root) +#define paranoid_check_in_wl_tree(ubi, e, root) #define paranoid_check_in_pq(ubi, e) 0 #endif @@ -449,7 +452,7 @@ retry: BUG(); } - paranoid_check_in_wl_tree(e, &ubi->free); + paranoid_check_in_wl_tree(ubi, e, &ubi->free); /* * Move the physical eraseblock to the protection queue where it will @@ -712,7 +715,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, e1->ec, e2->ec); goto out_cancel; } - paranoid_check_in_wl_tree(e1, &ubi->used); + paranoid_check_in_wl_tree(ubi, e1, &ubi->used); rb_erase(&e1->u.rb, &ubi->used); dbg_wl("move PEB %d EC %d to PEB %d EC %d", e1->pnum, e1->ec, e2->pnum, e2->ec); @@ -721,12 +724,12 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, scrubbing = 1; e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); - paranoid_check_in_wl_tree(e1, &ubi->scrub); + paranoid_check_in_wl_tree(ubi, e1, &ubi->scrub); rb_erase(&e1->u.rb, &ubi->scrub); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); } - paranoid_check_in_wl_tree(e2, &ubi->free); + paranoid_check_in_wl_tree(ubi, e2, &ubi->free); rb_erase(&e2->u.rb, &ubi->free); ubi->move_from = e1; ubi->move_to = e2; @@ -1169,13 +1172,13 @@ retry: return 0; } else { if (in_wl_tree(e, &ubi->used)) { - paranoid_check_in_wl_tree(e, &ubi->used); + paranoid_check_in_wl_tree(ubi, e, &ubi->used); rb_erase(&e->u.rb, &ubi->used); } else if (in_wl_tree(e, &ubi->scrub)) { - paranoid_check_in_wl_tree(e, &ubi->scrub); + paranoid_check_in_wl_tree(ubi, e, &ubi->scrub); rb_erase(&e->u.rb, &ubi->scrub); } else if (in_wl_tree(e, &ubi->erroneous)) { - paranoid_check_in_wl_tree(e, &ubi->erroneous); + paranoid_check_in_wl_tree(ubi, e, &ubi->erroneous); rb_erase(&e->u.rb, &ubi->erroneous); ubi->erroneous_peb_count -= 1; ubi_assert(ubi->erroneous_peb_count >= 0); @@ -1242,7 +1245,7 @@ retry: } if (in_wl_tree(e, &ubi->used)) { - paranoid_check_in_wl_tree(e, &ubi->used); + paranoid_check_in_wl_tree(ubi, e, &ubi->used); rb_erase(&e->u.rb, &ubi->used); } else { int err; @@ -1609,13 +1612,15 @@ out_free: /** * paranoid_check_in_wl_tree - check that wear-leveling entry is in WL RB-tree. + * @ubi: UBI device description object * @e: the wear-leveling entry to check * @root: the root of the tree * * This function returns zero if @e is in the @root RB-tree and %-EINVAL if it * is not. */ -static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, +static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, + struct ubi_wl_entry *e, struct rb_root *root) { if (!(ubi_chk_flags & UBI_CHK_GEN)) @@ -1638,7 +1643,8 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, * * This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not. */ -static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) +static int paranoid_check_in_pq(const struct ubi_device *ubi, + struct ubi_wl_entry *e) { struct ubi_wl_entry *p; int i; -- cgit v1.2.3 From 2a734bb8d502b645c061fa329e87c5d651498e68 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 14:53:05 +0300 Subject: UBI: use debugfs for the extra checks knobs This patch introduces debugfs support to UBI. All the UBI stuff is kept in the "ubi" debugfs directory, which contains per-UBI device "ubi/ubiX" sub-directories, containing debugging files. This file also creates "ubi/ubiX/chk_gen" and "ubi/ubiX/chk_io" knobs for switching general and I/O extra checks on and off. And it removes the 'debug_chks' UBI module parameters. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 26 +++++- drivers/mtd/ubi/debug.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++- drivers/mtd/ubi/debug.h | 59 +++++++++---- drivers/mtd/ubi/io.c | 14 +-- drivers/mtd/ubi/scan.c | 2 +- drivers/mtd/ubi/ubi.h | 4 + drivers/mtd/ubi/vmt.c | 2 +- drivers/mtd/ubi/vtbl.c | 2 +- drivers/mtd/ubi/wl.c | 6 +- 9 files changed, 310 insertions(+), 36 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 65626c1c446d..6d0d48395d8c 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -953,10 +953,14 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (!ubi->peb_buf2) goto out_free; + err = ubi_debugging_init_dev(ubi); + if (err) + goto out_free; + err = attach_by_scanning(ubi); if (err) { dbg_err("failed to attach by scanning, error %d", err); - goto out_free; + goto out_debugging; } if (ubi->autoresize_vol_id != -1) { @@ -969,12 +973,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_detach; + err = ubi_debugfs_init_dev(ubi); + if (err) + goto out_uif; + ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); if (IS_ERR(ubi->bgt_thread)) { err = PTR_ERR(ubi->bgt_thread); ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, err); - goto out_uif; + goto out_debugfs; } ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); @@ -1008,12 +1016,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); return ubi_num; +out_debugfs: + ubi_debugfs_exit_dev(ubi); out_uif: uif_close(ubi); out_detach: ubi_wl_close(ubi); free_internal_volumes(ubi); vfree(ubi->vtbl); +out_debugging: + ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); @@ -1080,11 +1092,13 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) */ get_device(&ubi->dev); + ubi_debugfs_exit_dev(ubi); uif_close(ubi); ubi_wl_close(ubi); free_internal_volumes(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); + ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); @@ -1199,6 +1213,11 @@ static int __init ubi_init(void) if (!ubi_wl_entry_slab) goto out_dev_unreg; + err = ubi_debugfs_init(); + if (err) + goto out_slab; + + /* Attach MTD devices */ for (i = 0; i < mtd_devs; i++) { struct mtd_dev_param *p = &mtd_dev_param[i]; @@ -1247,6 +1266,8 @@ out_detach: ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); mutex_unlock(&ubi_devices_mutex); } + ubi_debugfs_exit(); +out_slab: kmem_cache_destroy(ubi_wl_entry_slab); out_dev_unreg: misc_deregister(&ubi_ctrl_cdev); @@ -1270,6 +1291,7 @@ static void __exit ubi_exit(void) ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1); mutex_unlock(&ubi_devices_mutex); } + ubi_debugfs_exit(); kmem_cache_destroy(ubi_wl_entry_slab); misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 2224cbe41ddf..dce1227929f1 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -27,16 +27,15 @@ #ifdef CONFIG_MTD_UBI_DEBUG #include "ubi.h" +#include +#include #include #include -unsigned int ubi_chk_flags; unsigned int ubi_tst_flags; -module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); -module_param_named(debug_tsts, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); +module_param_named(debug_tsts, ubi_tst_flags, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug_chks, "Debug check flags"); MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); /** @@ -239,4 +238,228 @@ out: return; } +/** + * 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. + */ +static struct dentry *dfs_rootdir; + +/** + * ubi_debugfs_init - create UBI debugfs directory. + * + * Create UBI debugfs directory. Returns zero in case of success and a negative + * error code in case of failure. + */ +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); + + ubi_err("cannot create \"ubi\" debugfs directory, error %d\n", + err); + return err; + } + + return 0; +} + +/** + * ubi_debugfs_exit - remove UBI debugfs directory. + */ +void ubi_debugfs_exit(void) +{ + debugfs_remove(dfs_rootdir); +} + +/* Read an UBI debugfs file */ +static ssize_t dfs_file_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + unsigned long ubi_num = (unsigned long)file->private_data; + struct dentry *dent = file->f_path.dentry; + struct ubi_device *ubi; + struct ubi_debug_info *d; + char buf[3]; + int val; + + ubi = ubi_get_device(ubi_num); + if (!ubi) + return -ENODEV; + d = ubi->dbg; + + if (dent == d->dfs_chk_gen) + val = d->chk_gen; + else if (dent == d->dfs_chk_io) + val = d->chk_io; + else { + count = -EINVAL; + goto out; + } + + if (val) + buf[0] = '1'; + else + buf[0] = '0'; + buf[1] = '\n'; + buf[2] = 0x00; + + count = simple_read_from_buffer(user_buf, count, ppos, buf, 2); + +out: + ubi_put_device(ubi); + return count; +} + +/* Write an UBI debugfs file */ +static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + unsigned long ubi_num = (unsigned long)file->private_data; + struct dentry *dent = file->f_path.dentry; + struct ubi_device *ubi; + struct ubi_debug_info *d; + size_t buf_size; + char buf[8]; + int val; + + ubi = ubi_get_device(ubi_num); + if (!ubi) + return -ENODEV; + d = ubi->dbg; + + buf_size = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) { + count = -EFAULT; + goto out; + } + + if (buf[0] == '1') + val = 1; + else if (buf[0] == '0') + val = 0; + else { + count = -EINVAL; + goto out; + } + + if (dent == d->dfs_chk_gen) + d->chk_gen = val; + else if (dent == d->dfs_chk_io) + d->chk_io = val; + else + count = -EINVAL; + +out: + ubi_put_device(ubi); + return count; +} + +static int default_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + +/* File operations for all UBI debugfs files */ +static const struct file_operations dfs_fops = { + .read = dfs_file_read, + .write = dfs_file_write, + .open = default_open, + .llseek = no_llseek, + .owner = THIS_MODULE, +}; + +/** + * ubi_debugfs_init_dev - initialize debugfs for an UBI device. + * @ubi: UBI device description object + * + * This function creates all debugfs files for UBI device @ubi. Returns zero in + * case of success and a negative error code in case of failure. + */ +int ubi_debugfs_init_dev(struct ubi_device *ubi) +{ + int err, n; + unsigned long ubi_num = ubi->ubi_num; + const char *fname; + struct dentry *dent; + struct ubi_debug_info *d = ubi->dbg; + + n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, + ubi->ubi_num); + if (n == UBI_DFS_DIR_LEN) { + /* The array size is too small */ + fname = UBI_DFS_DIR_NAME; + dent = ERR_PTR(-EINVAL); + goto out; + } + + fname = d->dfs_dir_name; + dent = debugfs_create_dir(fname, dfs_rootdir); + if (IS_ERR_OR_NULL(dent)) + goto out; + d->dfs_dir = dent; + + fname = "chk_gen"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_chk_gen = dent; + + fname = "chk_io"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_chk_io = dent; + + return 0; + +out_remove: + debugfs_remove_recursive(d->dfs_dir); +out: + err = dent ? PTR_ERR(dent) : -ENODEV; + ubi_err("cannot create \"%s\" debugfs file or directory, error %d\n", + fname, err); + return err; +} + +/** + * dbg_debug_exit_dev - free all debugfs files corresponding to device @ubi + * @ubi: UBI device description object + */ +void ubi_debugfs_exit_dev(struct ubi_device *ubi) +{ + debugfs_remove_recursive(ubi->dbg->dfs_dir); +} + #endif /* CONFIG_MTD_UBI_DEBUG */ diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 3f1a09c5c438..cb6c87977be6 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -71,24 +71,42 @@ void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); - -extern unsigned int ubi_chk_flags; +int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); +int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, 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); /* - * Debugging check flags. + * 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. * - * UBI_CHK_GEN: general checks - * UBI_CHK_IO: check writes and erases + * @chk_gen: if UBI general extra checks are enabled + * @chk_io: if UBI I/O extra checks are enabled + * @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 */ -enum { - UBI_CHK_GEN = 0x1, - UBI_CHK_IO = 0x2, +struct ubi_debug_info { + unsigned int chk_gen:1; + unsigned int chk_io:1; + char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; + struct dentry *dfs_dir; + struct dentry *dfs_chk_gen; + struct dentry *dfs_chk_io; }; -int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); -int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, - int offset, int len); - extern unsigned int ubi_tst_flags; /* @@ -201,11 +219,6 @@ static inline void ubi_dbg_dump_flash(struct ubi_device *ubi, static inline void ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, int g, const void *b, size_t len, bool a) { return; } - -static inline int ubi_dbg_is_bgt_disabled(void) { return 0; } -static inline int ubi_dbg_is_bitflip(void) { return 0; } -static inline int ubi_dbg_is_write_failure(void) { return 0; } -static inline int ubi_dbg_is_erase_failure(void) { return 0; } static inline int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) { return 0; } @@ -213,5 +226,17 @@ static inline int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { return 0; } +static inline int ubi_debugging_init_dev(struct ubi_device *ubi) { return 0; } +static inline void ubi_debugging_exit_dev(struct ubi_device *ubi) { return; } +static inline int ubi_debugfs_init(void) { return 0; } +static inline void ubi_debugfs_exit(void) { return; } +static inline int ubi_debugfs_init_dev(struct ubi_device *ubi) { return 0; } +static inline void ubi_debugfs_exit_dev(struct ubi_device *ubi) { return; } + +static inline int ubi_dbg_is_bgt_disabled(void) { return 0; } +static inline int ubi_dbg_is_bitflip(void) { return 0; } +static inline int ubi_dbg_is_write_failure(void) { return 0; } +static inline int ubi_dbg_is_erase_failure(void) { return 0; } + #endif /* !CONFIG_MTD_UBI_DEBUG */ #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 8c1b1c7bc4a7..e23d6118224f 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -1146,7 +1146,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) { int err; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; err = ubi_io_is_bad(ubi, pnum); @@ -1173,7 +1173,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, int err; uint32_t magic; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; magic = be32_to_cpu(ec_hdr->magic); @@ -1211,7 +1211,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) uint32_t crc, hdr_crc; struct ubi_ec_hdr *ec_hdr; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); @@ -1255,7 +1255,7 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, int err; uint32_t magic; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; magic = be32_to_cpu(vid_hdr->magic); @@ -1296,7 +1296,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) struct ubi_vid_hdr *vid_hdr; void *p; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); @@ -1348,7 +1348,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, void *buf1; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); @@ -1412,7 +1412,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - if (!(ubi_chk_flags & UBI_CHK_IO)) + if (!ubi->dbg->chk_io) return 0; buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 2135a53732ff..a3a198f9b98d 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1347,7 +1347,7 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) struct ubi_scan_leb *seb, *last_seb; uint8_t *buf; - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return 0; /* diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index c6c22295898e..d0e321885fd6 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -390,6 +390,8 @@ struct ubi_wl_entry; * @peb_buf2: another buffer of PEB size used for different purposes * @buf_mutex: protects @peb_buf1 and @peb_buf2 * @ckvol_mutex: serializes static volume checking when opening + * + * @dbg: debugging information for this UBI device */ struct ubi_device { struct cdev cdev; @@ -472,6 +474,8 @@ struct ubi_device { void *peb_buf2; struct mutex buf_mutex; struct mutex ckvol_mutex; + + struct ubi_debug_info *dbg; }; extern struct kmem_cache *ubi_wl_entry_slab; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 366eb70219a6..97e093d19672 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -871,7 +871,7 @@ static int paranoid_check_volumes(struct ubi_device *ubi) { int i, err = 0; - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return 0; for (i = 0; i < ubi->vtbl_slots; i++) { diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fd3bf770f518..d704ad275932 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -876,7 +876,7 @@ out_free: */ static void paranoid_vtbl_check(const struct ubi_device *ubi) { - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return; if (vtbl_check(ubi, ubi->vtbl)) { diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index d5076d2cce39..bf13ca275f85 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1582,7 +1582,7 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) long long read_ec; struct ubi_ec_hdr *ec_hdr; - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return 0; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); @@ -1623,7 +1623,7 @@ static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root) { - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return 0; if (in_wl_tree(e, root)) @@ -1649,7 +1649,7 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *p; int i; - if (!(ubi_chk_flags & UBI_CHK_GEN)) + if (!ubi->dbg->chk_gen) return 0; for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) -- cgit v1.2.3 From 27a0f2a37aa46cb0174decddf8830715e5f1645a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 16:03:23 +0300 Subject: UBI: prepare debugging stuff to further debugfs conversion We'll need the 'struct ubi_device *ubi' pointer in every debugging function (to access the ->dbg field), so add this pointer to all the functions implementing UBI debugging test modes like 'ubi_dbg_is_bitflip()' etc. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 23 +++++++++++++++-------- drivers/mtd/ubi/io.c | 6 +++--- drivers/mtd/ubi/wl.c | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index cb6c87977be6..efefc549fee2 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -126,21 +126,23 @@ enum { /** * ubi_dbg_is_bgt_disabled - if the background thread is disabled. + * @ubi: UBI device description object * * Returns non-zero if the UBI background thread is disabled for testing * purposes. */ -static inline int ubi_dbg_is_bgt_disabled(void) +static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) { return ubi_tst_flags & UBI_TST_DISABLE_BGT; } /** * ubi_dbg_is_bitflip - if it is time to emulate a bit-flip. + * @ubi: UBI device description object * * Returns non-zero if a bit-flip should be emulated, otherwise returns zero. */ -static inline int ubi_dbg_is_bitflip(void) +static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) { if (ubi_tst_flags & UBI_TST_EMULATE_BITFLIPS) return !(random32() % 200); @@ -149,11 +151,12 @@ static inline int ubi_dbg_is_bitflip(void) /** * ubi_dbg_is_write_failure - if it is time to emulate a write failure. + * @ubi: UBI device description object * * Returns non-zero if a write failure should be emulated, otherwise returns * zero. */ -static inline int ubi_dbg_is_write_failure(void) +static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) { if (ubi_tst_flags & UBI_TST_EMULATE_WRITE_FAILURES) return !(random32() % 500); @@ -162,11 +165,12 @@ static inline int ubi_dbg_is_write_failure(void) /** * ubi_dbg_is_erase_failure - if its time to emulate an erase failure. + * @ubi: UBI device description object * * Returns non-zero if an erase failure should be emulated, otherwise returns * zero. */ -static inline int ubi_dbg_is_erase_failure(void) +static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) { if (ubi_tst_flags & UBI_TST_EMULATE_ERASE_FAILURES) return !(random32() % 400); @@ -233,10 +237,13 @@ static inline void ubi_debugfs_exit(void) { return; } static inline int ubi_debugfs_init_dev(struct ubi_device *ubi) { return 0; } static inline void ubi_debugfs_exit_dev(struct ubi_device *ubi) { return; } -static inline int ubi_dbg_is_bgt_disabled(void) { return 0; } -static inline int ubi_dbg_is_bitflip(void) { return 0; } -static inline int ubi_dbg_is_write_failure(void) { return 0; } -static inline int ubi_dbg_is_erase_failure(void) { return 0; } +static inline int +ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) { return 0; } +static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) { return 0; } +static inline int +ubi_dbg_is_write_failure(const struct ubi_device *ubi) { return 0; } +static inline int +ubi_dbg_is_erase_failure(const struct ubi_device *ubi) { return 0; } #endif /* !CONFIG_MTD_UBI_DEBUG */ #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index e23d6118224f..6ba55c235873 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -212,7 +212,7 @@ retry: } else { ubi_assert(len == read); - if (ubi_dbg_is_bitflip()) { + if (ubi_dbg_is_bitflip(ubi)) { dbg_gen("bit-flip (emulated)"); err = UBI_IO_BITFLIPS; } @@ -281,7 +281,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, return err; } - if (ubi_dbg_is_write_failure()) { + if (ubi_dbg_is_write_failure(ubi)) { dbg_err("cannot write %d bytes to PEB %d:%d " "(emulated)", len, pnum, offset); ubi_dbg_dump_stack(); @@ -396,7 +396,7 @@ retry: if (err) return err; - if (ubi_dbg_is_erase_failure()) { + if (ubi_dbg_is_erase_failure(ubi)) { dbg_err("cannot erase PEB %d (emulated)", pnum); return -EIO; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index bf13ca275f85..42c684cf3688 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -616,7 +616,7 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) list_add_tail(&wrk->list, &ubi->works); ubi_assert(ubi->works_count >= 0); ubi->works_count += 1; - if (ubi->thread_enabled && !ubi_dbg_is_bgt_disabled()) + if (ubi->thread_enabled && !ubi_dbg_is_bgt_disabled(ubi)) wake_up_process(ubi->bgt_thread); spin_unlock(&ubi->wl_lock); } @@ -1367,7 +1367,7 @@ int ubi_thread(void *u) spin_lock(&ubi->wl_lock); if (list_empty(&ubi->works) || ubi->ro_mode || - !ubi->thread_enabled || ubi_dbg_is_bgt_disabled()) { + !ubi->thread_enabled || ubi_dbg_is_bgt_disabled(ubi)) { set_current_state(TASK_INTERRUPTIBLE); spin_unlock(&ubi->wl_lock); schedule(); -- cgit v1.2.3 From 18073733247dc0c31e07f3a87f3267fe8d7e7022 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 16:38:06 +0300 Subject: UBI: make it possible to use struct ubi_device in debug.h Current layout does not allow us to add inline functions to debug.h which use the 'struct ubi_device' object, because it is undefined there. Move '#include "debug.h"' in "ubi.h" down so to make 'struct ubi_device" be defined. Additionally, this makes it possible to remove a bunch of forward declarations in "debug.h". This is a preparation to the next patch. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 8 -------- drivers/mtd/ubi/ubi.h | 3 ++- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index efefc549fee2..ef97c12fe9b8 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -21,14 +21,6 @@ #ifndef __UBI_DEBUG_H__ #define __UBI_DEBUG_H__ -struct ubi_ec_hdr; -struct ubi_vid_hdr; -struct ubi_volume; -struct ubi_vtbl_record; -struct ubi_scan_volume; -struct ubi_scan_leb; -struct ubi_mkvol_req; - #ifdef CONFIG_MTD_UBI_DEBUG #include diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index d0e321885fd6..fd19f8d3bce8 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -44,7 +44,6 @@ #include "ubi-media.h" #include "scan.h" -#include "debug.h" /* Maximum number of supported UBI devices */ #define UBI_MAX_DEVICES 32 @@ -478,6 +477,8 @@ struct ubi_device { struct ubi_debug_info *dbg; }; +#include "debug.h" + extern struct kmem_cache *ubi_wl_entry_slab; extern const struct file_operations ubi_ctrl_cdev_operations; extern const struct file_operations ubi_cdev_operations; -- cgit v1.2.3 From cd6d8567a42907d4e7add0b08f9a2d846690fc65 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 16:21:43 +0300 Subject: UBI: switch debugging tests knobs to debugfs Kill the UBI 'debug_tsts' module parameter and switch to debugfs. Create per-test mode files there. E.g., to enable bit-flips emulation you may just do: echo 1 > /sys/kernel/debug/ubi/ubi0/tst_emulate_bitflips Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 40 +++++++++++++++++++++++++++++++++------- drivers/mtd/ubi/debug.h | 37 ++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 28 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index dce1227929f1..ab80c0debac8 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -30,13 +30,6 @@ #include #include #include -#include - -unsigned int ubi_tst_flags; - -module_param_named(debug_tsts, ubi_tst_flags, uint, S_IRUGO | S_IWUSR); - -MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); /** * ubi_dbg_dump_ec_hdr - dump an erase counter header. @@ -318,6 +311,12 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, val = d->chk_gen; else if (dent == d->dfs_chk_io) val = d->chk_io; + else if (dent == d->dfs_disable_bgt) + val = d->disable_bgt; + else if (dent == d->dfs_emulate_bitflips) + val = d->emulate_bitflips; + else if (dent == d->dfs_emulate_io_failures) + val = d->emulate_io_failures; else { count = -EINVAL; goto out; @@ -373,6 +372,12 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, d->chk_gen = val; else if (dent == d->dfs_chk_io) d->chk_io = val; + else if (dent == d->dfs_disable_bgt) + d->disable_bgt = val; + else if (dent == d->dfs_emulate_bitflips) + d->emulate_bitflips = val; + else if (dent == d->dfs_emulate_io_failures) + d->emulate_io_failures = val; else count = -EINVAL; @@ -442,6 +447,27 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) goto out_remove; d->dfs_chk_io = dent; + fname = "tst_disable_bgt"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_disable_bgt = dent; + + fname = "tst_emulate_bitflips"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_emulate_bitflips = dent; + + fname = "tst_emulate_io_failures"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_emulate_io_failures = dent; + return 0; out_remove: diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ef97c12fe9b8..65b5b76cc379 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -85,35 +85,30 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi); * * @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; -}; - -extern unsigned int ubi_tst_flags; - -/* - * Special testing flags. - * - * UBIFS_TST_DISABLE_BGT: disable the background thread - * UBI_TST_EMULATE_BITFLIPS: emulate bit-flips - * UBI_TST_EMULATE_WRITE_FAILURES: emulate write failures - * UBI_TST_EMULATE_ERASE_FAILURES: emulate erase failures - */ -enum { - UBI_TST_DISABLE_BGT = 0x1, - UBI_TST_EMULATE_BITFLIPS = 0x2, - UBI_TST_EMULATE_WRITE_FAILURES = 0x4, - UBI_TST_EMULATE_ERASE_FAILURES = 0x8, + struct dentry *dfs_disable_bgt; + struct dentry *dfs_emulate_bitflips; + struct dentry *dfs_emulate_io_failures; }; /** @@ -125,7 +120,7 @@ enum { */ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) { - return ubi_tst_flags & UBI_TST_DISABLE_BGT; + return ubi->dbg->disable_bgt; } /** @@ -136,7 +131,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_tst_flags & UBI_TST_EMULATE_BITFLIPS) + if (ubi->dbg->emulate_bitflips) return !(random32() % 200); return 0; } @@ -150,7 +145,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_tst_flags & UBI_TST_EMULATE_WRITE_FAILURES) + if (ubi->dbg->emulate_io_failures) return !(random32() % 500); return 0; } @@ -164,7 +159,7 @@ 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_tst_flags & UBI_TST_EMULATE_ERASE_FAILURES) + if (ubi->dbg->emulate_io_failures) return !(random32() % 400); return 0; } -- cgit v1.2.3 From 01a4110d2b86b05918debf39c50867cbb9598491 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 18 May 2011 18:08:05 +0300 Subject: UBI: fix oops in error path This patch fixes an oops in the error path of 'ubi_attach_mtd_dev()'. If anything after 'uif_init()' fails, we get an oops in 'cancel_pending()'. The reason is that 'uif_close()' drops the last reference count for 'ubi->dev' and whole 'struct ubi_device' is freed. And then 'ubi_wl_close()'->'cancel_pending()' tries to access the 'ubi' pointer and problems begin. Note, in 'ubi_detach_mtd_dev()' function we get a device reference to work-around this issue. Do the same in the error path of 'ubi_attach_mtd_dev()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6d0d48395d8c..6c3fb5ab20f5 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1019,6 +1019,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) out_debugfs: ubi_debugfs_exit_dev(ubi); out_uif: + get_device(&ubi->dev); + ubi_assert(ref); uif_close(ubi); out_detach: ubi_wl_close(ubi); -- cgit v1.2.3 From 2a826061df67f205636b953f58f8bede2a3f009c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 20 May 2011 17:24:34 +0300 Subject: UBI: dump stack when switching to R/O mode If we have debugging enabled and switching to R/O mode because of an error - dump the stack to improve UBI error reporting and make the further diagnostics easier to do. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index fd19f8d3bce8..dc64c767fd21 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -667,6 +667,7 @@ static inline void ubi_ro_mode(struct ubi_device *ubi) if (!ubi->ro_mode) { ubi->ro_mode = 1; ubi_warn("switch to read-only mode"); + ubi_dbg_dump_stack(); } } -- cgit v1.2.3 From 4788b60a5faf9f9c9aec10fb7f6b36d9e0f9fa4c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jun 2011 19:41:00 +0300 Subject: UBI: remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to new gcc 4.6 for issuing the following warning: drivers/mtd/ubi/vtbl.c: In function ‘create_vtbl’: drivers/mtd/ubi/vtbl.c:311:33: warning: variable ‘old_seb’ set but not used [-Wunused-but-set-variable] This patch removes some dead code and fixes the warning. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/vtbl.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index d704ad275932..4b50a3029b84 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -307,8 +307,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, { int err, tries = 0; static struct ubi_vid_hdr *vid_hdr; - struct ubi_scan_volume *sv; - struct ubi_scan_leb *new_seb, *old_seb = NULL; + struct ubi_scan_leb *new_seb; ubi_msg("create volume table (copy #%d)", copy + 1); @@ -316,15 +315,6 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, if (!vid_hdr) return -ENOMEM; - /* - * Check if there is a logical eraseblock which would have to contain - * this volume table copy was found during scanning. It has to be wiped - * out. - */ - sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID); - if (sv) - old_seb = ubi_scan_find_seb(sv, copy); - retry: new_seb = ubi_scan_get_free_peb(ubi, si); if (IS_ERR(new_seb)) { @@ -351,8 +341,8 @@ retry: goto write_error; /* - * And add it to the scanning information. Don't delete the old - * @old_seb as it will be deleted and freed in 'ubi_scan_add_used()'. + * And add it to the scanning information. Don't delete the old version + * of this LEB as it will be deleted and freed in 'ubi_scan_add_used()'. */ err = ubi_scan_add_used(ubi, si, new_seb->pnum, new_seb->ec, vid_hdr, 0); -- cgit v1.2.3