* Always support xattrs    (remove the Kconfig option)
    * Always support debugging (remove the Kconfig option)
    * A fix for a memory leak on error path
    * A number of clean-ups
 UBI:
    * Always support debugging (remove the Kconfig option)
    * Remove "data type" hint support
    * Huge amount of renames to prepare for the fastmap wor
    * A lot of clean-ups
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJPuzTxAAoJECmIfjd9wqK0D/AP/iNOnYWnYZmmO18jDM48kKt/
 Jp7VTAE0l7DBUDxtiIthq4c7YxIE1o1bN9gMmvzZibvwIrZcoAOnQpeL96s1Bc9J
 t0aGm8ONvrtuyFeyxPC0aplWgqWQ49qDLGV/lIVJ+BSGmXMeU4giUIXqbsjyCPR4
 YVJJw6rLTC10EhuAUs99keJxxuN5ZMrCB8y47fD+bkalVxgqNh9JNkKabyjevt5C
 AERVWnP20hnEcwnbQWMHueGWiaqFeesTytNOy6heRi0uL3bNy5nrol7AFXKqnDc9
 OpSkApH6SCO3C8X/bIep2bL9kKiW1LpClxgDIF6p7lj2t2ToPn6PZJbP60zSHQPb
 0bgy1SzHccF3ihIMgCdOXYZ5EomBgKZyDyU6Ec+gAttE00ZbIigNmjFmukwMhO89
 I0bGvjQdKFAFSzo+ffm8xNfYjmmNfB+edLkPaVttjMWAbQ4V831ZPDT07Q11W4TQ
 2p2NDKTps3etbtkemZ/Cm1jeEWI3KuogrFhyDhpcgXc7pxlJbvMg+tt22FusoQ8T
 VPGGT+WhmXfF0ZG/gurI69k8opj4BUhm4EfGL6pGEoUMe1nGp2pSUNv5Kwby1wau
 1wElJt2qO9xdjJ4QlLc+Ux1vm8rCS1iQst9plUX1BZt2bKja7tZaW7uu4hGKqe5u
 UwrosuYcmS1Ei1Rs7Sqz
 =+6Qi
 -----END PGP SIGNATURE-----

Merge tag 'upstream-3.5-rc1' of git://git.infradead.org/linux-ubifs

Pull UBI and UBIFS updates from Artem Bityutskiy:

UBIFS:
   * Always support xattrs    (remove the Kconfig option)
   * Always support debugging (remove the Kconfig option)
   * A fix for a memory leak on error path
   * A number of clean-ups
UBI:
   * Always support debugging (remove the Kconfig option)
   * Remove "data type" hint support
   * Huge amount of renames to prepare for the fastmap wor
   * A lot of clean-ups

* tag 'upstream-3.5-rc1' of git://git.infradead.org/linux-ubifs: (54 commits)
  UBI: modify ubi_wl_flush function to clear work queue for a lnum
  UBI: introduce UBI_ALL constant
  UBI: add lnum and vol_id to struct ubi_work
  UBI: add volume id struct ubi_ainf_peb
  UBI: add in hex the value for UBI_INTERNAL_VOL_START to comment
  UBI: rename scan.c to attach.c
  UBI: remove scan.h
  UBI: rename UBI_SCAN_UNKNOWN_EC
  UBI: move and rename attach_by_scanning
  UBI: rename _init_scan functions
  UBI: amend comments after all the renamings
  UBI: rename ubi_scan_leb_slab
  UBI: rename ubi_scan_move_to_list
  UBI: rename ubi_scan_destroy_ai
  UBI: rename ubi_scan_get_free_peb
  UBI: rename ubi_scan_rm_volume
  UBI: rename ubi_scan_find_av
  UBI: rename ubi_scan_add_used
  UBI: remove unused function
  UBI: make ubi_scan_erase_peb static and rename
  ...
This commit is contained in:
Linus Torvalds 2012-05-22 19:30:27 -07:00
commit 6133308ad1
46 changed files with 1585 additions and 2095 deletions

View file

@ -52,12 +52,4 @@ config MTD_UBI_GLUEBI
work on top of UBI. Do not enable this unless you use legacy
software.
config MTD_UBI_DEBUG
bool "UBI debugging"
depends on SYSFS
select DEBUG_FS
select KALLSYMS
help
This option enables UBI debugging.
endif # MTD_UBI

View file

@ -1,7 +1,6 @@
obj-$(CONFIG_MTD_UBI) += ubi.o
ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o scan.o
ubi-y += misc.o
ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
ubi-y += misc.o debug.o
ubi-$(CONFIG_MTD_UBI_DEBUG) += debug.o
obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o

File diff suppressed because it is too large Load diff

View file

@ -27,10 +27,6 @@
* module load parameters or the kernel boot parameters. If MTD devices were
* specified, UBI does not attach any MTD device, but it is possible to do
* later using the "UBI control device".
*
* At the moment we only attach UBI devices by scanning, which will become a
* bottleneck when flashes reach certain large size. Then one may improve UBI
* and add other methods, although it does not seem to be easy to do.
*/
#include <linux/err.h>
@ -554,10 +550,10 @@ static void uif_close(struct ubi_device *ubi)
}
/**
* free_internal_volumes - free internal volumes.
* ubi_free_internal_volumes - free internal volumes.
* @ubi: UBI device description object
*/
static void free_internal_volumes(struct ubi_device *ubi)
void ubi_free_internal_volumes(struct ubi_device *ubi)
{
int i;
@ -568,59 +564,6 @@ static void free_internal_volumes(struct ubi_device *ubi)
}
}
/**
* attach_by_scanning - attach an MTD device using scanning method.
* @ubi: UBI device descriptor
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*
* Note, currently this is the only method to attach UBI devices. Hopefully in
* the future we'll have more scalable attaching methods and avoid full media
* scanning. But even in this case scanning will be needed as a fall-back
* attaching method if there are some on-flash table corruptions.
*/
static int attach_by_scanning(struct ubi_device *ubi)
{
int err;
struct ubi_scan_info *si;
si = ubi_scan(ubi);
if (IS_ERR(si))
return PTR_ERR(si);
ubi->bad_peb_count = si->bad_peb_count;
ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
ubi->corr_peb_count = si->corr_peb_count;
ubi->max_ec = si->max_ec;
ubi->mean_ec = si->mean_ec;
ubi_msg("max. sequence number: %llu", si->max_sqnum);
err = ubi_read_volume_table(ubi, si);
if (err)
goto out_si;
err = ubi_wl_init_scan(ubi, si);
if (err)
goto out_vtbl;
err = ubi_eba_init_scan(ubi, si);
if (err)
goto out_wl;
ubi_scan_destroy_si(si);
return 0;
out_wl:
ubi_wl_close(ubi);
out_vtbl:
free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_si:
ubi_scan_destroy_si(si);
return err;
}
/**
* io_init - initialize I/O sub-system for a given UBI device.
* @ubi: UBI device description object
@ -790,11 +733,11 @@ static int io_init(struct ubi_device *ubi)
ubi_msg("data offset: %d", ubi->leb_start);
/*
* Note, ideally, we have to initialize ubi->bad_peb_count here. But
* Note, ideally, we have to initialize @ubi->bad_peb_count here. But
* unfortunately, MTD does not provide this information. We should loop
* over all physical eraseblocks and invoke mtd->block_is_bad() for
* each physical eraseblock. So, we skip ubi->bad_peb_count
* uninitialized and initialize it after scanning.
* each physical eraseblock. So, we leave @ubi->bad_peb_count
* uninitialized so far.
*/
return 0;
@ -805,7 +748,7 @@ static int io_init(struct ubi_device *ubi)
* @ubi: UBI device description object
* @vol_id: ID of the volume to re-size
*
* This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in
* This function re-sizes the volume marked by the %UBI_VTBL_AUTORESIZE_FLG in
* the volume table to the largest possible size. See comments in ubi-header.h
* for more description of the flag. Returns zero in case of success and a
* negative error code in case of failure.
@ -881,7 +824,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
for (i = 0; i < UBI_MAX_DEVICES; i++) {
ubi = ubi_devices[i];
if (ubi && mtd->index == ubi->mtd->index) {
dbg_err("mtd%d is already attached to ubi%d",
ubi_err("mtd%d is already attached to ubi%d",
mtd->index, i);
return -EEXIST;
}
@ -907,7 +850,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (!ubi_devices[ubi_num])
break;
if (ubi_num == UBI_MAX_DEVICES) {
dbg_err("only %d UBI devices may be created",
ubi_err("only %d UBI devices may be created",
UBI_MAX_DEVICES);
return -ENFILE;
}
@ -917,7 +860,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
/* Make sure ubi_num is not busy */
if (ubi_devices[ubi_num]) {
dbg_err("ubi%d already exists", ubi_num);
ubi_err("ubi%d already exists", ubi_num);
return -EEXIST;
}
}
@ -937,7 +880,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
spin_lock_init(&ubi->volumes_lock);
ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
dbg_msg("sizeof(struct ubi_scan_leb) %zu", sizeof(struct ubi_scan_leb));
dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
err = io_init(ubi);
@ -953,9 +896,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (err)
goto out_free;
err = attach_by_scanning(ubi);
err = ubi_attach(ubi);
if (err) {
dbg_err("failed to attach by scanning, error %d", err);
ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
goto out_debugging;
}
@ -1020,7 +963,7 @@ out_uif:
uif_close(ubi);
out_detach:
ubi_wl_close(ubi);
free_internal_volumes(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_debugging:
ubi_debugging_exit_dev(ubi);
@ -1092,7 +1035,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_debugfs_exit_dev(ubi);
uif_close(ubi);
ubi_wl_close(ubi);
free_internal_volumes(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
ubi_debugging_exit_dev(ubi);

View file

@ -63,7 +63,7 @@ static int get_exclusive(struct ubi_volume_desc *desc)
users = vol->readers + vol->writers + vol->exclusive;
ubi_assert(users > 0);
if (users > 1) {
dbg_err("%d users for volume %d", users, vol->vol_id);
ubi_err("%d users for volume %d", users, vol->vol_id);
err = -EBUSY;
} else {
vol->readers = vol->writers = 0;
@ -159,7 +159,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
if (vol->updating) {
/* Update is in progress, seeking is prohibited */
dbg_err("updating");
ubi_err("updating");
return -EBUSY;
}
@ -178,7 +178,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
}
if (new_offset < 0 || new_offset > vol->used_bytes) {
dbg_err("bad seek %lld", new_offset);
ubi_err("bad seek %lld", new_offset);
return -EINVAL;
}
@ -216,11 +216,11 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
count, *offp, vol->vol_id);
if (vol->updating) {
dbg_err("updating");
ubi_err("updating");
return -EBUSY;
}
if (vol->upd_marker) {
dbg_err("damaged volume, update marker is set");
ubi_err("damaged volume, update marker is set");
return -EBADF;
}
if (*offp == vol->used_bytes || count == 0)
@ -300,7 +300,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
if (off & (ubi->min_io_size - 1)) {
dbg_err("unaligned position");
ubi_err("unaligned position");
return -EINVAL;
}
@ -309,7 +309,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
/* We can write only in fractions of the minimum I/O unit */
if (count & (ubi->min_io_size - 1)) {
dbg_err("unaligned write length");
ubi_err("unaligned write length");
return -EINVAL;
}
@ -334,8 +334,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
break;
}
err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len,
UBI_UNKNOWN);
err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len);
if (err)
break;
@ -477,9 +476,6 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
if (req.lnum < 0 || req.lnum >= vol->reserved_pebs ||
req.bytes < 0 || req.lnum >= vol->usable_leb_size)
break;
if (req.dtype != UBI_LONGTERM && req.dtype != UBI_SHORTTERM &&
req.dtype != UBI_UNKNOWN)
break;
err = get_exclusive(desc);
if (err < 0)
@ -518,7 +514,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
if (err)
break;
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
break;
}
@ -532,7 +528,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
err = -EFAULT;
break;
}
err = ubi_leb_map(desc, req.lnum, req.dtype);
err = ubi_leb_map(desc, req.lnum);
break;
}
@ -647,8 +643,8 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
return 0;
bad:
dbg_err("bad volume creation request");
ubi_dbg_dump_mkvol_req(req);
ubi_err("bad volume creation request");
ubi_dump_mkvol_req(req);
return err;
}
@ -713,12 +709,12 @@ static int rename_volumes(struct ubi_device *ubi,
for (i = 0; i < req->count - 1; i++) {
for (n = i + 1; n < req->count; n++) {
if (req->ents[i].vol_id == req->ents[n].vol_id) {
dbg_err("duplicated volume id %d",
ubi_err("duplicated volume id %d",
req->ents[i].vol_id);
return -EINVAL;
}
if (!strcmp(req->ents[i].name, req->ents[n].name)) {
dbg_err("duplicated volume name \"%s\"",
ubi_err("duplicated volume name \"%s\"",
req->ents[i].name);
return -EINVAL;
}
@ -741,7 +737,7 @@ static int rename_volumes(struct ubi_device *ubi,
re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE);
if (IS_ERR(re->desc)) {
err = PTR_ERR(re->desc);
dbg_err("cannot open volume %d, error %d", vol_id, err);
ubi_err("cannot open volume %d, error %d", vol_id, err);
kfree(re);
goto out_free;
}
@ -800,7 +796,7 @@ static int rename_volumes(struct ubi_device *ubi,
continue;
/* The volume exists but busy, or an error occurred */
dbg_err("cannot open volume \"%s\", error %d",
ubi_err("cannot open volume \"%s\", error %d",
re->new_name, err);
goto out_free;
}

View file

@ -18,24 +18,49 @@
* Author: Artem Bityutskiy (Битюцкий Артём)
*/
/*
* Here we keep all the UBI debugging stuff which should normally be disabled
* and compiled-out, but it is extremely helpful when hunting bugs or doing big
* changes.
*/
#ifdef CONFIG_MTD_UBI_DEBUG
#include "ubi.h"
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/module.h>
/**
* ubi_dbg_dump_ec_hdr - dump an erase counter header.
* ubi_dump_flash - dump a region of flash.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to dump
* @offset: the starting offset within the physical eraseblock to dump
* @len: the length of the region to dump
*/
void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
{
int err;
size_t read;
void *buf;
loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
buf = vmalloc(len);
if (!buf)
return;
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && err != -EUCLEAN) {
ubi_err("error %d while reading %d bytes from PEB %d:%d, "
"read %zd bytes", err, len, pnum, offset, read);
goto out;
}
ubi_msg("dumping %d bytes of data from PEB %d, offset %d",
len, pnum, offset);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
out:
vfree(buf);
return;
}
/**
* ubi_dump_ec_hdr - dump an erase counter header.
* @ec_hdr: the erase counter header to dump
*/
void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
printk(KERN_DEBUG "Erase counter header dump:\n");
printk(KERN_DEBUG "\tmagic %#08x\n",
@ -57,10 +82,10 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
}
/**
* ubi_dbg_dump_vid_hdr - dump a volume identifier header.
* ubi_dump_vid_hdr - dump a volume identifier header.
* @vid_hdr: the volume identifier header to dump
*/
void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
printk(KERN_DEBUG "Volume identifier header dump:\n");
printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic));
@ -82,10 +107,10 @@ void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
}
/**
* ubi_dbg_dump_vol_info- dump volume information.
* ubi_dump_vol_info - dump volume information.
* @vol: UBI volume description object
*/
void ubi_dbg_dump_vol_info(const struct ubi_volume *vol)
void ubi_dump_vol_info(const struct ubi_volume *vol)
{
printk(KERN_DEBUG "Volume information dump:\n");
printk(KERN_DEBUG "\tvol_id %d\n", vol->vol_id);
@ -112,11 +137,11 @@ void ubi_dbg_dump_vol_info(const struct ubi_volume *vol)
}
/**
* ubi_dbg_dump_vtbl_record - dump a &struct ubi_vtbl_record object.
* ubi_dump_vtbl_record - dump a &struct ubi_vtbl_record object.
* @r: the object to dump
* @idx: volume table index
*/
void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
int name_len = be16_to_cpu(r->name_len);
@ -146,44 +171,44 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
}
/**
* ubi_dbg_dump_sv - dump a &struct ubi_scan_volume object.
* @sv: the object to dump
* ubi_dump_av - dump a &struct ubi_ainf_volume object.
* @av: the object to dump
*/
void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv)
void ubi_dump_av(const struct ubi_ainf_volume *av)
{
printk(KERN_DEBUG "Volume scanning information dump:\n");
printk(KERN_DEBUG "\tvol_id %d\n", sv->vol_id);
printk(KERN_DEBUG "\thighest_lnum %d\n", sv->highest_lnum);
printk(KERN_DEBUG "\tleb_count %d\n", sv->leb_count);
printk(KERN_DEBUG "\tcompat %d\n", sv->compat);
printk(KERN_DEBUG "\tvol_type %d\n", sv->vol_type);
printk(KERN_DEBUG "\tused_ebs %d\n", sv->used_ebs);
printk(KERN_DEBUG "\tlast_data_size %d\n", sv->last_data_size);
printk(KERN_DEBUG "\tdata_pad %d\n", sv->data_pad);
printk(KERN_DEBUG "Volume attaching information dump:\n");
printk(KERN_DEBUG "\tvol_id %d\n", av->vol_id);
printk(KERN_DEBUG "\thighest_lnum %d\n", av->highest_lnum);
printk(KERN_DEBUG "\tleb_count %d\n", av->leb_count);
printk(KERN_DEBUG "\tcompat %d\n", av->compat);
printk(KERN_DEBUG "\tvol_type %d\n", av->vol_type);
printk(KERN_DEBUG "\tused_ebs %d\n", av->used_ebs);
printk(KERN_DEBUG "\tlast_data_size %d\n", av->last_data_size);
printk(KERN_DEBUG "\tdata_pad %d\n", av->data_pad);
}
/**
* ubi_dbg_dump_seb - dump a &struct ubi_scan_leb object.
* @seb: the object to dump
* ubi_dump_aeb - dump a &struct ubi_ainf_peb object.
* @aeb: the object to dump
* @type: object type: 0 - not corrupted, 1 - corrupted
*/
void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type)
void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type)
{
printk(KERN_DEBUG "eraseblock scanning information dump:\n");
printk(KERN_DEBUG "\tec %d\n", seb->ec);
printk(KERN_DEBUG "\tpnum %d\n", seb->pnum);
printk(KERN_DEBUG "eraseblock attaching information dump:\n");
printk(KERN_DEBUG "\tec %d\n", aeb->ec);
printk(KERN_DEBUG "\tpnum %d\n", aeb->pnum);
if (type == 0) {
printk(KERN_DEBUG "\tlnum %d\n", seb->lnum);
printk(KERN_DEBUG "\tscrub %d\n", seb->scrub);
printk(KERN_DEBUG "\tsqnum %llu\n", seb->sqnum);
printk(KERN_DEBUG "\tlnum %d\n", aeb->lnum);
printk(KERN_DEBUG "\tscrub %d\n", aeb->scrub);
printk(KERN_DEBUG "\tsqnum %llu\n", aeb->sqnum);
}
}
/**
* ubi_dbg_dump_mkvol_req - dump a &struct ubi_mkvol_req object.
* ubi_dump_mkvol_req - dump a &struct ubi_mkvol_req object.
* @req: the object to dump
*/
void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
{
char nm[17];
@ -199,38 +224,6 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
}
/**
* ubi_dbg_dump_flash - dump a region of flash.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to dump
* @offset: the starting offset within the physical eraseblock to dump
* @len: the length of the region to dump
*/
void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
{
int err;
size_t read;
void *buf;
loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
buf = vmalloc(len);
if (!buf)
return;
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && err != -EUCLEAN) {
ubi_err("error %d while reading %d bytes from PEB %d:%d, "
"read %zd bytes", err, len, pnum, offset, read);
goto out;
}
dbg_msg("dumping %d bytes of data from PEB %d, offset %d",
len, pnum, offset);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
out:
vfree(buf);
return;
}
/**
* ubi_debugging_init_dev - initialize debugging for an UBI device.
* @ubi: UBI device description object
@ -479,5 +472,3 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi)
{
debugfs_remove_recursive(ubi->dbg->dfs_dir);
}
#endif /* CONFIG_MTD_UBI_DEBUG */

View file

@ -21,21 +21,20 @@
#ifndef __UBI_DEBUG_H__
#define __UBI_DEBUG_H__
#ifdef CONFIG_MTD_UBI_DEBUG
void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr);
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
#include <linux/random.h>
#define ubi_assert(expr) do { \
if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
ubi_dbg_dump_stack(); \
dump_stack(); \
} \
} while (0)
#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__)
#define ubi_dbg_dump_stack() dump_stack()
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
print_hex_dump(l, ps, pt, r, g, b, len, a)
@ -58,17 +57,13 @@
/* Initialization and build messages */
#define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__)
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);
void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
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);
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);
void ubi_dump_vol_info(const struct ubi_volume *vol);
void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
void ubi_dump_av(const struct ubi_ainf_volume *av);
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);
@ -167,73 +162,4 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
return 0;
}
#else
/* Use "if (0)" to make compiler check arguments even if debugging is off */
#define ubi_assert(expr) do { \
if (0) { \
printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
} \
} while (0)
#define dbg_err(fmt, ...) do { \
if (0) \
ubi_err(fmt, ##__VA_ARGS__); \
} while (0)
#define ubi_dbg_msg(fmt, ...) do { \
if (0) \
printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
} while (0)
#define dbg_msg(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_gen(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_eba(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_wl(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_io(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_bld(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
static inline void ubi_dbg_dump_stack(void) { return; }
static inline void
ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { return; }
static inline void
ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { return; }
static inline void
ubi_dbg_dump_vol_info(const struct ubi_volume *vol) { return; }
static inline void
ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; }
static inline void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) { return; }
static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb,
int type) { return; }
static inline void
ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; }
static inline void ubi_dbg_dump_flash(struct ubi_device *ubi,
int pnum, int offset, int len) { return; }
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_check_all_ff(struct ubi_device *ubi,
int pnum, int offset,
int len) { return 0; }
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(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__ */

View file

@ -341,7 +341,7 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum);
vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
err = ubi_wl_put_peb(ubi, pnum, 0);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0);
out_unlock:
leb_write_unlock(ubi, vol_id, lnum);
@ -507,7 +507,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
return -ENOMEM;
retry:
new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN);
new_pnum = ubi_wl_get_peb(ubi);
if (new_pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr);
return new_pnum;
@ -550,7 +550,7 @@ retry:
ubi_free_vid_hdr(ubi, vid_hdr);
vol->eba_tbl[lnum] = new_pnum;
ubi_wl_put_peb(ubi, pnum, 1);
ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
ubi_msg("data was successfully recovered");
return 0;
@ -558,7 +558,7 @@ retry:
out_unlock:
mutex_unlock(&ubi->buf_mutex);
out_put:
ubi_wl_put_peb(ubi, new_pnum, 1);
ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
@ -568,7 +568,7 @@ write_error:
* get another one.
*/
ubi_warn("failed to write to PEB %d", new_pnum);
ubi_wl_put_peb(ubi, new_pnum, 1);
ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1);
if (++tries > UBI_IO_RETRIES) {
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
@ -585,7 +585,6 @@ write_error:
* @buf: the data to write
* @offset: offset within the logical eraseblock where to write
* @len: how many bytes to write
* @dtype: data type
*
* This function writes data to logical eraseblock @lnum of a dynamic volume
* @vol. Returns zero in case of success and a negative error code in case
@ -593,7 +592,7 @@ write_error:
* written to the flash media, but may be some garbage.
*/
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 err, pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr;
@ -641,7 +640,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
vid_hdr->data_pad = cpu_to_be32(vol->data_pad);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
pnum = ubi_wl_get_peb(ubi);
if (pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum);
@ -687,7 +686,7 @@ write_error:
* eraseblock, so just put it and request a new one. We assume that if
* this physical eraseblock went bad, the erase code will handle that.
*/
err = ubi_wl_put_peb(ubi, pnum, 1);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
if (err || ++tries > UBI_IO_RETRIES) {
ubi_ro_mode(ubi);
leb_write_unlock(ubi, vol_id, lnum);
@ -707,7 +706,6 @@ write_error:
* @lnum: logical eraseblock number
* @buf: data to write
* @len: how many bytes to write
* @dtype: data type
* @used_ebs: how many logical eraseblocks will this volume contain
*
* This function writes data to logical eraseblock @lnum of static volume
@ -724,8 +722,7 @@ write_error:
* code in case of failure.
*/
int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len, int dtype,
int used_ebs)
int lnum, const void *buf, int len, int used_ebs)
{
int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr;
@ -763,7 +760,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
vid_hdr->data_crc = cpu_to_be32(crc);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
pnum = ubi_wl_get_peb(ubi);
if (pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum);
@ -807,7 +804,7 @@ write_error:
return err;
}
err = ubi_wl_put_peb(ubi, pnum, 1);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
if (err || ++tries > UBI_IO_RETRIES) {
ubi_ro_mode(ubi);
leb_write_unlock(ubi, vol_id, lnum);
@ -827,7 +824,6 @@ write_error:
* @lnum: logical eraseblock number
* @buf: data to write
* @len: how many bytes to write
* @dtype: data type
*
* This function changes the contents of a logical eraseblock atomically. @buf
* has to contain new logical eraseblock data, and @len - the length of the
@ -839,7 +835,7 @@ write_error:
* 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, struct ubi_volume *vol,
int lnum, const void *buf, int len, int dtype)
int lnum, const void *buf, int len)
{
int err, pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr;
@ -856,7 +852,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
err = ubi_eba_unmap_leb(ubi, vol, lnum);
if (err)
return err;
return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype);
return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0);
}
vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
@ -881,7 +877,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
vid_hdr->data_crc = cpu_to_be32(crc);
retry:
pnum = ubi_wl_get_peb(ubi, dtype);
pnum = ubi_wl_get_peb(ubi);
if (pnum < 0) {
err = pnum;
goto out_leb_unlock;
@ -905,7 +901,7 @@ retry:
}
if (vol->eba_tbl[lnum] >= 0) {
err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0);
err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0);
if (err)
goto out_leb_unlock;
}
@ -930,7 +926,7 @@ write_error:
goto out_leb_unlock;
}
err = ubi_wl_put_peb(ubi, pnum, 1);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
if (err || ++tries > UBI_IO_RETRIES) {
ubi_ro_mode(ubi);
goto out_leb_unlock;
@ -1171,7 +1167,7 @@ out_unlock_leb:
* print_rsvd_warning - warn about not having enough reserved PEBs.
* @ubi: UBI device description object
*
* This is a helper function for 'ubi_eba_init_scan()' which is called when UBI
* This is a helper function for 'ubi_eba_init()' which is called when UBI
* cannot reserve enough PEBs for bad block handling. This function makes a
* decision whether we have to print a warning or not. The algorithm is as
* follows:
@ -1186,13 +1182,13 @@ out_unlock_leb:
* reported by real users.
*/
static void print_rsvd_warning(struct ubi_device *ubi,
struct ubi_scan_info *si)
struct ubi_attach_info *ai)
{
/*
* The 1 << 18 (256KiB) number is picked randomly, just a reasonably
* large number to distinguish between newly flashed and used images.
*/
if (si->max_sqnum > (1 << 18)) {
if (ai->max_sqnum > (1 << 18)) {
int min = ubi->beb_rsvd_level / 10;
if (!min)
@ -1209,19 +1205,19 @@ static void print_rsvd_warning(struct ubi_device *ubi,
}
/**
* ubi_eba_init_scan - initialize the EBA sub-system using scanning information.
* ubi_eba_init - initialize the EBA sub-system using attaching information.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
{
int i, j, err, num_volumes;
struct ubi_scan_volume *sv;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
struct ubi_scan_leb *seb;
struct ubi_ainf_peb *aeb;
struct rb_node *rb;
dbg_eba("initialize EBA sub-system");
@ -1230,7 +1226,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
mutex_init(&ubi->alc_mutex);
ubi->ltree = RB_ROOT;
ubi->global_sqnum = si->max_sqnum + 1;
ubi->global_sqnum = ai->max_sqnum + 1;
num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;
for (i = 0; i < num_volumes; i++) {
@ -1250,18 +1246,18 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
for (j = 0; j < vol->reserved_pebs; j++)
vol->eba_tbl[j] = UBI_LEB_UNMAPPED;
sv = ubi_scan_find_sv(si, idx2vol_id(ubi, i));
if (!sv)
av = ubi_find_av(ai, idx2vol_id(ubi, i));
if (!av)
continue;
ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) {
if (seb->lnum >= vol->reserved_pebs)
ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) {
if (aeb->lnum >= vol->reserved_pebs)
/*
* This may happen in case of an unclean reboot
* during re-size.
*/
ubi_scan_move_to_list(sv, seb, &si->erase);
vol->eba_tbl[seb->lnum] = seb->pnum;
ubi_move_aeb_to_list(av, aeb, &ai->erase);
vol->eba_tbl[aeb->lnum] = aeb->pnum;
}
}
@ -1283,7 +1279,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
if (ubi->avail_pebs < ubi->beb_rsvd_level) {
/* No enough free physical eraseblocks */
ubi->beb_rsvd_pebs = ubi->avail_pebs;
print_rsvd_warning(ubi, si);
print_rsvd_warning(ubi, ai);
} else
ubi->beb_rsvd_pebs = ubi->beb_rsvd_level;

View file

@ -227,7 +227,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
if (to_write > total_written)
to_write = total_written;
err = ubi_write(gluebi->desc, lnum, buf, offs, to_write);
err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write);
if (err)
break;

View file

@ -91,21 +91,15 @@
#include <linux/slab.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum);
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_ec_hdr *ec_hdr);
static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum);
static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_vid_hdr *vid_hdr);
#else
#define paranoid_check_not_bad(ubi, pnum) 0
#define paranoid_check_peb_ec_hdr(ubi, pnum) 0
#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0
#define paranoid_check_peb_vid_hdr(ubi, pnum) 0
#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0
#endif
static int self_check_not_bad(const struct ubi_device *ubi, int pnum);
static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_ec_hdr *ec_hdr);
static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum);
static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_vid_hdr *vid_hdr);
static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum,
int offset, int len);
/**
* ubi_io_read - read data from a physical eraseblock.
@ -142,7 +136,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
ubi_assert(offset >= 0 && offset + len <= ubi->peb_size);
ubi_assert(len > 0);
err = paranoid_check_not_bad(ubi, pnum);
err = self_check_not_bad(ubi, pnum);
if (err)
return err;
@ -189,16 +183,16 @@ retry:
}
if (retries++ < UBI_IO_RETRIES) {
dbg_io("error %d%s while reading %d bytes from PEB "
"%d:%d, read only %zd bytes, retry",
err, errstr, len, pnum, offset, read);
ubi_warn("error %d%s while reading %d bytes from PEB "
"%d:%d, read only %zd bytes, retry",
err, errstr, len, pnum, offset, read);
yield();
goto retry;
}
ubi_err("error %d%s while reading %d bytes from PEB %d:%d, "
"read %zd bytes", err, errstr, len, pnum, offset, read);
ubi_dbg_dump_stack();
dump_stack();
/*
* The driver should never return -EBADMSG if it failed to read
@ -257,14 +251,12 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
return -EROFS;
}
/* The below has to be compiled out if paranoid checks are disabled */
err = paranoid_check_not_bad(ubi, pnum);
err = self_check_not_bad(ubi, pnum);
if (err)
return err;
/* The area we are writing to has to contain all 0xFF bytes */
err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
err = ubi_self_check_all_ff(ubi, pnum, offset, len);
if (err)
return err;
@ -273,18 +265,18 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
* We write to the data area of the physical eraseblock. Make
* sure it has valid EC and VID headers.
*/
err = paranoid_check_peb_ec_hdr(ubi, pnum);
err = self_check_peb_ec_hdr(ubi, pnum);
if (err)
return err;
err = paranoid_check_peb_vid_hdr(ubi, pnum);
err = self_check_peb_vid_hdr(ubi, pnum);
if (err)
return err;
}
if (ubi_dbg_is_write_failure(ubi)) {
dbg_err("cannot write %d bytes to PEB %d:%d "
ubi_err("cannot write %d bytes to PEB %d:%d "
"(emulated)", len, pnum, offset);
ubi_dbg_dump_stack();
dump_stack();
return -EIO;
}
@ -293,13 +285,13 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
if (err) {
ubi_err("error %d while writing %d bytes to PEB %d:%d, written "
"%zd bytes", err, len, pnum, offset, written);
ubi_dbg_dump_stack();
ubi_dbg_dump_flash(ubi, pnum, offset, len);
dump_stack();
ubi_dump_flash(ubi, pnum, offset, len);
} else
ubi_assert(written == len);
if (!err) {
err = ubi_dbg_check_write(ubi, buf, pnum, offset, len);
err = self_check_write(ubi, buf, pnum, offset, len);
if (err)
return err;
@ -310,7 +302,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
offset += len;
len = ubi->peb_size - offset;
if (len)
err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
err = ubi_self_check_all_ff(ubi, pnum, offset, len);
}
return err;
@ -364,13 +356,13 @@ retry:
err = mtd_erase(ubi->mtd, &ei);
if (err) {
if (retries++ < UBI_IO_RETRIES) {
dbg_io("error %d while erasing PEB %d, retry",
err, pnum);
ubi_warn("error %d while erasing PEB %d, retry",
err, pnum);
yield();
goto retry;
}
ubi_err("cannot erase PEB %d, error %d", pnum, err);
ubi_dbg_dump_stack();
dump_stack();
return err;
}
@ -383,21 +375,21 @@ retry:
if (ei.state == MTD_ERASE_FAILED) {
if (retries++ < UBI_IO_RETRIES) {
dbg_io("error while erasing PEB %d, retry", pnum);
ubi_warn("error while erasing PEB %d, retry", pnum);
yield();
goto retry;
}
ubi_err("cannot erase PEB %d", pnum);
ubi_dbg_dump_stack();
dump_stack();
return -EIO;
}
err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
err = ubi_self_check_all_ff(ubi, pnum, 0, ubi->peb_size);
if (err)
return err;
if (ubi_dbg_is_erase_failure(ubi)) {
dbg_err("cannot erase PEB %d (emulated)", pnum);
ubi_err("cannot erase PEB %d (emulated)", pnum);
return -EIO;
}
@ -521,8 +513,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
* It is important to first invalidate the EC header, and then the VID
* header. Otherwise a power cut may lead to valid EC header and
* invalid VID header, in which case UBI will treat this PEB as
* corrupted and will try to preserve it, and print scary warnings (see
* the header comment in scan.c for more information).
* corrupted and will try to preserve it, and print scary warnings.
*/
addr = (loff_t)pnum * ubi->peb_size;
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
@ -563,7 +554,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
*/
ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
pnum, err, err1);
ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size);
ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
return -EIO;
}
@ -589,7 +580,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
err = paranoid_check_not_bad(ubi, pnum);
err = self_check_not_bad(ubi, pnum);
if (err != 0)
return err;
@ -721,8 +712,8 @@ static int validate_ec_hdr(const struct ubi_device *ubi,
bad:
ubi_err("bad EC header");
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dbg_dump_stack();
ubi_dump_ec_hdr(ec_hdr);
dump_stack();
return 1;
}
@ -803,7 +794,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (verbose) {
ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_EC_HDR_MAGIC);
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dump_ec_hdr(ec_hdr);
}
dbg_bld("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_EC_HDR_MAGIC);
@ -817,7 +808,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (verbose) {
ubi_warn("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc);
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dump_ec_hdr(ec_hdr);
}
dbg_bld("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc);
@ -874,7 +865,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);
ec_hdr->hdr_crc = cpu_to_be32(crc);
err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
err = self_check_ec_hdr(ubi, pnum, ec_hdr);
if (err)
return err;
@ -905,40 +896,40 @@ static int validate_vid_hdr(const struct ubi_device *ubi,
int usable_leb_size = ubi->leb_size - data_pad;
if (copy_flag != 0 && copy_flag != 1) {
dbg_err("bad copy_flag");
ubi_err("bad copy_flag");
goto bad;
}
if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 ||
data_pad < 0) {
dbg_err("negative values");
ubi_err("negative values");
goto bad;
}
if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) {
dbg_err("bad vol_id");
ubi_err("bad vol_id");
goto bad;
}
if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) {
dbg_err("bad compat");
ubi_err("bad compat");
goto bad;
}
if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE &&
compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE &&
compat != UBI_COMPAT_REJECT) {
dbg_err("bad compat");
ubi_err("bad compat");
goto bad;
}
if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) {
dbg_err("bad vol_type");
ubi_err("bad vol_type");
goto bad;
}
if (data_pad >= ubi->leb_size / 2) {
dbg_err("bad data_pad");
ubi_err("bad data_pad");
goto bad;
}
@ -950,45 +941,45 @@ static int validate_vid_hdr(const struct ubi_device *ubi,
* mapped logical eraseblocks.
*/
if (used_ebs == 0) {
dbg_err("zero used_ebs");
ubi_err("zero used_ebs");
goto bad;
}
if (data_size == 0) {
dbg_err("zero data_size");
ubi_err("zero data_size");
goto bad;
}
if (lnum < used_ebs - 1) {
if (data_size != usable_leb_size) {
dbg_err("bad data_size");
ubi_err("bad data_size");
goto bad;
}
} else if (lnum == used_ebs - 1) {
if (data_size == 0) {
dbg_err("bad data_size at last LEB");
ubi_err("bad data_size at last LEB");
goto bad;
}
} else {
dbg_err("too high lnum");
ubi_err("too high lnum");
goto bad;
}
} else {
if (copy_flag == 0) {
if (data_crc != 0) {
dbg_err("non-zero data CRC");
ubi_err("non-zero data CRC");
goto bad;
}
if (data_size != 0) {
dbg_err("non-zero data_size");
ubi_err("non-zero data_size");
goto bad;
}
} else {
if (data_size == 0) {
dbg_err("zero data_size of copy");
ubi_err("zero data_size of copy");
goto bad;
}
}
if (used_ebs != 0) {
dbg_err("bad used_ebs");
ubi_err("bad used_ebs");
goto bad;
}
}
@ -997,8 +988,8 @@ static int validate_vid_hdr(const struct ubi_device *ubi,
bad:
ubi_err("bad VID header");
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dbg_dump_stack();
ubi_dump_vid_hdr(vid_hdr);
dump_stack();
return 1;
}
@ -1054,7 +1045,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (verbose) {
ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dump_vid_hdr(vid_hdr);
}
dbg_bld("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
@ -1068,7 +1059,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (verbose) {
ubi_warn("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dump_vid_hdr(vid_hdr);
}
dbg_bld("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
@ -1112,7 +1103,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
dbg_io("write VID header to PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
err = paranoid_check_peb_ec_hdr(ubi, pnum);
err = self_check_peb_ec_hdr(ubi, pnum);
if (err)
return err;
@ -1121,7 +1112,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);
vid_hdr->hdr_crc = cpu_to_be32(crc);
err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
err = self_check_vid_hdr(ubi, pnum, vid_hdr);
if (err)
return err;
@ -1131,17 +1122,15 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
return err;
}
#ifdef CONFIG_MTD_UBI_DEBUG
/**
* paranoid_check_not_bad - ensure that a physical eraseblock is not bad.
* self_check_not_bad - ensure that a physical eraseblock is not bad.
* @ubi: UBI device description object
* @pnum: physical eraseblock number to check
*
* This function returns zero if the physical eraseblock is good, %-EINVAL if
* it is bad and a negative error code if an error occurred.
*/
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
static int self_check_not_bad(const struct ubi_device *ubi, int pnum)
{
int err;
@ -1152,13 +1141,13 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
if (!err)
return err;
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_stack();
ubi_err("self-check failed for PEB %d", pnum);
dump_stack();
return err > 0 ? -EINVAL : err;
}
/**
* paranoid_check_ec_hdr - check if an erase counter header is all right.
* self_check_ec_hdr - check if an erase counter header is all right.
* @ubi: UBI device description object
* @pnum: physical eraseblock number the erase counter header belongs to
* @ec_hdr: the erase counter header to check
@ -1166,8 +1155,8 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
* This function returns zero if the erase counter header contains valid
* values, and %-EINVAL if not.
*/
static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_ec_hdr *ec_hdr)
static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_ec_hdr *ec_hdr)
{
int err;
uint32_t magic;
@ -1184,27 +1173,27 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
err = validate_ec_hdr(ubi, ec_hdr);
if (err) {
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_err("self-check failed for PEB %d", pnum);
goto fail;
}
return 0;
fail:
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dbg_dump_stack();
ubi_dump_ec_hdr(ec_hdr);
dump_stack();
return -EINVAL;
}
/**
* paranoid_check_peb_ec_hdr - check erase counter header.
* self_check_peb_ec_hdr - check erase counter header.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
*
* This function returns zero if the erase counter header is all right and and
* a negative error code if not or if an error occurred.
*/
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
{
int err;
uint32_t crc, hdr_crc;
@ -1225,14 +1214,14 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
hdr_crc = be32_to_cpu(ec_hdr->hdr_crc);
if (hdr_crc != crc) {
ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc);
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dbg_dump_stack();
ubi_err("self-check failed for PEB %d", pnum);
ubi_dump_ec_hdr(ec_hdr);
dump_stack();
err = -EINVAL;
goto exit;
}
err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
err = self_check_ec_hdr(ubi, pnum, ec_hdr);
exit:
kfree(ec_hdr);
@ -1240,7 +1229,7 @@ exit:
}
/**
* paranoid_check_vid_hdr - check that a volume identifier header is all right.
* self_check_vid_hdr - check that a volume identifier header is all right.
* @ubi: UBI device description object
* @pnum: physical eraseblock number the volume identifier header belongs to
* @vid_hdr: the volume identifier header to check
@ -1248,8 +1237,8 @@ exit:
* This function returns zero if the volume identifier header is all right, and
* %-EINVAL if not.
*/
static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_vid_hdr *vid_hdr)
static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_vid_hdr *vid_hdr)
{
int err;
uint32_t magic;
@ -1266,29 +1255,29 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
err = validate_vid_hdr(ubi, vid_hdr);
if (err) {
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_err("self-check failed for PEB %d", pnum);
goto fail;
}
return err;
fail:
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dbg_dump_stack();
ubi_err("self-check failed for PEB %d", pnum);
ubi_dump_vid_hdr(vid_hdr);
dump_stack();
return -EINVAL;
}
/**
* paranoid_check_peb_vid_hdr - check volume identifier header.
* self_check_peb_vid_hdr - check volume identifier header.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
*
* This function returns zero if the volume identifier header is all right,
* and a negative error code if not or if an error occurred.
*/
static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
{
int err;
uint32_t crc, hdr_crc;
@ -1313,14 +1302,14 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
if (hdr_crc != crc) {
ubi_err("bad VID header CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dbg_dump_stack();
ubi_err("self-check failed for PEB %d", pnum);
ubi_dump_vid_hdr(vid_hdr);
dump_stack();
err = -EINVAL;
goto exit;
}
err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
err = self_check_vid_hdr(ubi, pnum, vid_hdr);
exit:
ubi_free_vid_hdr(ubi, vid_hdr);
@ -1328,7 +1317,7 @@ exit:
}
/**
* ubi_dbg_check_write - make sure write succeeded.
* self_check_write - make sure write succeeded.
* @ubi: UBI device description object
* @buf: buffer with data which were written
* @pnum: physical eraseblock number the data were written to
@ -1339,8 +1328,8 @@ exit:
* the original data buffer - the data have to match. Returns zero if the data
* match and a negative error code if not or in case of failure.
*/
int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
int offset, int len)
static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum,
int offset, int len)
{
int err, i;
size_t read;
@ -1368,7 +1357,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
if (c == c1)
continue;
ubi_err("paranoid check failed for PEB %d:%d, len %d",
ubi_err("self-check failed for PEB %d:%d, len %d",
pnum, offset, len);
ubi_msg("data differ at position %d", i);
dump_len = max_t(int, 128, len - i);
@ -1380,7 +1369,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
i, i + dump_len);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
buf1 + i, dump_len, 1);
ubi_dbg_dump_stack();
dump_stack();
err = -EINVAL;
goto out_free;
}
@ -1394,7 +1383,7 @@ out_free:
}
/**
* ubi_dbg_check_all_ff - check that a region of flash is empty.
* ubi_self_check_all_ff - check that a region of flash is empty.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
* @offset: the starting offset within the physical eraseblock to check
@ -1404,7 +1393,7 @@ out_free:
* @offset of the physical eraseblock @pnum, and a negative error code if not
* or if an error occurred.
*/
int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
{
size_t read;
int err;
@ -1438,14 +1427,12 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
return 0;
fail:
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_err("self-check failed for PEB %d", pnum);
ubi_msg("hex dump of the %d-%d region", offset, offset + len);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
err = -EINVAL;
error:
ubi_dbg_dump_stack();
dump_stack();
vfree(buf);
return err;
}
#endif /* CONFIG_MTD_UBI_DEBUG */

View file

@ -221,7 +221,7 @@ out_free:
kfree(desc);
out_put_ubi:
ubi_put_device(ubi);
dbg_err("cannot open device %d, volume %d, error %d",
ubi_err("cannot open device %d, volume %d, error %d",
ubi_num, vol_id, err);
return ERR_PTR(err);
}
@ -426,11 +426,9 @@ EXPORT_SYMBOL_GPL(ubi_leb_read);
* @buf: data to write
* @offset: offset within the logical eraseblock where to write
* @len: how many bytes to write
* @dtype: expected data type
*
* This function writes @len bytes of data from @buf to offset @offset of
* logical eraseblock @lnum. The @dtype argument describes expected lifetime of
* the data.
* logical eraseblock @lnum.
*
* This function takes care of physical eraseblock write failures. If write to
* the physical eraseblock write operation fails, the logical eraseblock is
@ -447,7 +445,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_read);
* returns immediately with %-EBADF code.
*/
int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
int offset, int len, int dtype)
int offset, int len)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
@ -466,17 +464,13 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1))
return -EINVAL;
if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
dtype != UBI_UNKNOWN)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (len == 0)
return 0;
return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len, dtype);
return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len);
}
EXPORT_SYMBOL_GPL(ubi_leb_write);
@ -486,7 +480,6 @@ EXPORT_SYMBOL_GPL(ubi_leb_write);
* @lnum: logical eraseblock number to change
* @buf: data to write
* @len: how many bytes to write
* @dtype: expected data type
*
* This function changes the contents of a logical eraseblock atomically. @buf
* has to contain new logical eraseblock data, and @len - the length of the
@ -497,7 +490,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_write);
* code in case of failure.
*/
int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len, int dtype)
int len)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
@ -515,17 +508,13 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
len > vol->usable_leb_size || len & (ubi->min_io_size - 1))
return -EINVAL;
if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
dtype != UBI_UNKNOWN)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (len == 0)
return 0;
return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype);
return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len);
}
EXPORT_SYMBOL_GPL(ubi_leb_change);
@ -562,7 +551,7 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum)
if (err)
return err;
return ubi_wl_flush(ubi);
return ubi_wl_flush(ubi, vol->vol_id, lnum);
}
EXPORT_SYMBOL_GPL(ubi_leb_erase);
@ -626,7 +615,6 @@ EXPORT_SYMBOL_GPL(ubi_leb_unmap);
* ubi_leb_map - map logical eraseblock to a physical eraseblock.
* @desc: volume descriptor
* @lnum: logical eraseblock number
* @dtype: expected data type
*
* This function maps an un-mapped logical eraseblock @lnum to a physical
* eraseblock. This means, that after a successful invocation of this
@ -639,7 +627,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_unmap);
* eraseblock is already mapped, and other negative error codes in case of
* other failures.
*/
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
@ -652,17 +640,13 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;
if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
dtype != UBI_UNKNOWN)
return -EINVAL;
if (vol->upd_marker)
return -EBADF;
if (vol->eba_tbl[lnum] >= 0)
return -EBADMSG;
return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype);
return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0);
}
EXPORT_SYMBOL_GPL(ubi_leb_map);
@ -720,6 +704,33 @@ int ubi_sync(int ubi_num)
}
EXPORT_SYMBOL_GPL(ubi_sync);
/**
* ubi_flush - flush UBI work queue.
* @ubi_num: UBI device to flush work queue
* @vol_id: volume id to flush for
* @lnum: logical eraseblock number to flush for
*
* This function executes all pending works for a particular volume id / logical
* eraseblock number pair. If either value is set to %UBI_ALL, then it acts as
* a wildcard for all of the corresponding volume numbers or logical
* eraseblock numbers. It returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_flush(int ubi_num, int vol_id, int lnum)
{
struct ubi_device *ubi;
int err = 0;
ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
err = ubi_wl_flush(ubi, vol_id, lnum);
ubi_put_device(ubi);
return err;
}
EXPORT_SYMBOL_GPL(ubi_flush);
BLOCKING_NOTIFIER_HEAD(ubi_notifiers);
/**

View file

@ -1,174 +0,0 @@
/*
* Copyright (c) International Business Machines Corp., 2006
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Artem Bityutskiy (Битюцкий Артём)
*/
#ifndef __UBI_SCAN_H__
#define __UBI_SCAN_H__
/* The erase counter value for this physical eraseblock is unknown */
#define UBI_SCAN_UNKNOWN_EC (-1)
/**
* struct ubi_scan_leb - scanning information about a physical eraseblock.
* @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown)
* @pnum: physical eraseblock number
* @lnum: logical eraseblock number
* @scrub: if this physical eraseblock needs scrubbing
* @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
* @sqnum: sequence number
* @u: unions RB-tree or @list links
* @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
* @u.list: link in one of the eraseblock lists
*
* One object of this type is allocated for each physical eraseblock during
* scanning.
*/
struct ubi_scan_leb {
int ec;
int pnum;
int lnum;
unsigned int scrub:1;
unsigned int copy_flag:1;
unsigned long long sqnum;
union {
struct rb_node rb;
struct list_head list;
} u;
};
/**
* struct ubi_scan_volume - scanning information about a volume.
* @vol_id: volume ID
* @highest_lnum: highest logical eraseblock number in this volume
* @leb_count: number of logical eraseblocks in this volume
* @vol_type: volume type
* @used_ebs: number of used logical eraseblocks in this volume (only for
* static volumes)
* @last_data_size: amount of data in the last logical eraseblock of this
* volume (always equivalent to the usable logical eraseblock
* size in case of dynamic volumes)
* @data_pad: how many bytes at the end of logical eraseblocks of this volume
* are not used (due to volume alignment)
* @compat: compatibility flags of this volume
* @rb: link in the volume RB-tree
* @root: root of the RB-tree containing all the eraseblock belonging to this
* volume (&struct ubi_scan_leb objects)
*
* One object of this type is allocated for each volume during scanning.
*/
struct ubi_scan_volume {
int vol_id;
int highest_lnum;
int leb_count;
int vol_type;
int used_ebs;
int last_data_size;
int data_pad;
int compat;
struct rb_node rb;
struct rb_root root;
};
/**
* struct ubi_scan_info - UBI scanning information.
* @volumes: root of the volume RB-tree
* @corr: list of corrupted physical eraseblocks
* @free: list of free physical eraseblocks
* @erase: list of physical eraseblocks which have to be erased
* @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
* those belonging to "preserve"-compatible internal volumes)
* @corr_peb_count: count of PEBs in the @corr list
* @empty_peb_count: count of PEBs which are presumably empty (contain only
* 0xFF bytes)
* @alien_peb_count: count of PEBs in the @alien list
* @bad_peb_count: count of bad physical eraseblocks
* @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked
* as bad yet, but which look like bad
* @vols_found: number of volumes found during scanning
* @highest_vol_id: highest volume ID
* @is_empty: flag indicating whether the MTD device is empty or not
* @min_ec: lowest erase counter value
* @max_ec: highest erase counter value
* @max_sqnum: highest sequence number value
* @mean_ec: mean erase counter value
* @ec_sum: a temporary variable used when calculating @mean_ec
* @ec_count: a temporary variable used when calculating @mean_ec
* @scan_leb_slab: slab cache for &struct ubi_scan_leb objects
*
* This data structure contains the result of scanning and may be used by other
* UBI sub-systems to build final UBI data structures, further error-recovery
* and so on.
*/
struct ubi_scan_info {
struct rb_root volumes;
struct list_head corr;
struct list_head free;
struct list_head erase;
struct list_head alien;
int corr_peb_count;
int empty_peb_count;
int alien_peb_count;
int bad_peb_count;
int maybe_bad_peb_count;
int vols_found;
int highest_vol_id;
int is_empty;
int min_ec;
int max_ec;
unsigned long long max_sqnum;
int mean_ec;
uint64_t ec_sum;
int ec_count;
struct kmem_cache *scan_leb_slab;
};
struct ubi_device;
struct ubi_vid_hdr;
/*
* ubi_scan_move_to_list - move a PEB from the volume tree to a list.
*
* @sv: volume scanning information
* @seb: scanning eraseblock information
* @list: the list to move to
*/
static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv,
struct ubi_scan_leb *seb,
struct list_head *list)
{
rb_erase(&seb->u.rb, &sv->root);
list_add_tail(&seb->u.list, list);
}
int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
int pnum, int ec, const struct ubi_vid_hdr *vid_hdr,
int bitflips);
struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si,
int vol_id);
struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv,
int lnum);
void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv);
struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi,
struct ubi_scan_info *si);
int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si,
int pnum, int ec);
struct ubi_scan_info *ubi_scan(struct ubi_device *ubi);
void ubi_scan_destroy_si(struct ubi_scan_info *si);
#endif /* !__UBI_SCAN_H__ */

View file

@ -149,10 +149,10 @@ enum {
* The @image_seq field is used to validate a UBI image that has been prepared
* for a UBI device. The @image_seq value can be any value, but it must be the
* same on all eraseblocks. UBI will ensure that all new erase counter headers
* also contain this value, and will check the value when scanning at start-up.
* also contain this value, and will check the value when attaching the flash.
* One way to make use of @image_seq is to increase its value by one every time
* an image is flashed over an existing image, then, if the flashing does not
* complete, UBI will detect the error when scanning.
* complete, UBI will detect the error when attaching the media.
*/
struct ubi_ec_hdr {
__be32 magic;
@ -298,8 +298,8 @@ struct ubi_vid_hdr {
#define UBI_INT_VOL_COUNT 1
/*
* Starting ID of internal volumes. There is reserved room for 4096 internal
* volumes.
* Starting ID of internal volumes: 0x7fffefff.
* There is reserved room for 4096 internal volumes.
*/
#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096)

View file

@ -43,7 +43,6 @@
#include <asm/pgtable.h>
#include "ubi-media.h"
#include "scan.h"
/* Maximum number of supported UBI devices */
#define UBI_MAX_DEVICES 32
@ -66,7 +65,10 @@
/* Background thread name pattern */
#define UBI_BGT_NAME_PATTERN "ubi_bgt%dd"
/* This marker in the EBA table means that the LEB is um-mapped */
/*
* This marker in the EBA table means that the LEB is um-mapped.
* NOTE! It has to have the same value as %UBI_ALL.
*/
#define UBI_LEB_UNMAPPED -1
/*
@ -82,6 +84,9 @@
*/
#define UBI_PROT_QUEUE_LEN 10
/* The volume ID/LEB number/erase counter is unknown */
#define UBI_UNKNOWN -1
/*
* Error codes returned by the I/O sub-system.
*
@ -222,8 +227,6 @@ struct ubi_volume_desc;
* @upd_ebs: how many eraseblocks are expected to be updated
* @ch_lnum: LEB number which is being changing by the atomic LEB change
* operation
* @ch_dtype: data persistency type which is being changing by the atomic LEB
* change operation
* @upd_bytes: how many bytes are expected to be received for volume update or
* atomic LEB change
* @upd_received: how many bytes were already received for volume update or
@ -270,7 +273,6 @@ struct ubi_volume {
int upd_ebs;
int ch_lnum;
int ch_dtype;
long long upd_bytes;
long long upd_received;
void *upd_buf;
@ -477,6 +479,124 @@ struct ubi_device {
struct ubi_debug_info *dbg;
};
/**
* struct ubi_ainf_peb - attach information about a physical eraseblock.
* @ec: erase counter (%UBI_UNKNOWN if it is unknown)
* @pnum: physical eraseblock number
* @vol_id: ID of the volume this LEB belongs to
* @lnum: logical eraseblock number
* @scrub: if this physical eraseblock needs scrubbing
* @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
* @sqnum: sequence number
* @u: unions RB-tree or @list links
* @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects
* @u.list: link in one of the eraseblock lists
*
* One object of this type is allocated for each physical eraseblock when
* attaching an MTD device. Note, if this PEB does not belong to any LEB /
* volume, the @vol_id and @lnum fields are initialized to %UBI_UNKNOWN.
*/
struct ubi_ainf_peb {
int ec;
int pnum;
int vol_id;
int lnum;
unsigned int scrub:1;
unsigned int copy_flag:1;
unsigned long long sqnum;
union {
struct rb_node rb;
struct list_head list;
} u;
};
/**
* struct ubi_ainf_volume - attaching information about a volume.
* @vol_id: volume ID
* @highest_lnum: highest logical eraseblock number in this volume
* @leb_count: number of logical eraseblocks in this volume
* @vol_type: volume type
* @used_ebs: number of used logical eraseblocks in this volume (only for
* static volumes)
* @last_data_size: amount of data in the last logical eraseblock of this
* volume (always equivalent to the usable logical eraseblock
* size in case of dynamic volumes)
* @data_pad: how many bytes at the end of logical eraseblocks of this volume
* are not used (due to volume alignment)
* @compat: compatibility flags of this volume
* @rb: link in the volume RB-tree
* @root: root of the RB-tree containing all the eraseblock belonging to this
* volume (&struct ubi_ainf_peb objects)
*
* One object of this type is allocated for each volume when attaching an MTD
* device.
*/
struct ubi_ainf_volume {
int vol_id;
int highest_lnum;
int leb_count;
int vol_type;
int used_ebs;
int last_data_size;
int data_pad;
int compat;
struct rb_node rb;
struct rb_root root;
};
/**
* struct ubi_attach_info - MTD device attaching information.
* @volumes: root of the volume RB-tree
* @corr: list of corrupted physical eraseblocks
* @free: list of free physical eraseblocks
* @erase: list of physical eraseblocks which have to be erased
* @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
* those belonging to "preserve"-compatible internal volumes)
* @corr_peb_count: count of PEBs in the @corr list
* @empty_peb_count: count of PEBs which are presumably empty (contain only
* 0xFF bytes)
* @alien_peb_count: count of PEBs in the @alien list
* @bad_peb_count: count of bad physical eraseblocks
* @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked
* as bad yet, but which look like bad
* @vols_found: number of volumes found
* @highest_vol_id: highest volume ID
* @is_empty: flag indicating whether the MTD device is empty or not
* @min_ec: lowest erase counter value
* @max_ec: highest erase counter value
* @max_sqnum: highest sequence number value
* @mean_ec: mean erase counter value
* @ec_sum: a temporary variable used when calculating @mean_ec
* @ec_count: a temporary variable used when calculating @mean_ec
* @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects
*
* This data structure contains the result of attaching an MTD device and may
* be used by other UBI sub-systems to build final UBI data structures, further
* error-recovery and so on.
*/
struct ubi_attach_info {
struct rb_root volumes;
struct list_head corr;
struct list_head free;
struct list_head erase;
struct list_head alien;
int corr_peb_count;
int empty_peb_count;
int alien_peb_count;
int bad_peb_count;
int maybe_bad_peb_count;
int vols_found;
int highest_vol_id;
int is_empty;
int min_ec;
int max_ec;
unsigned long long max_sqnum;
int mean_ec;
uint64_t ec_sum;
int ec_count;
struct kmem_cache *aeb_slab_cache;
};
#include "debug.h"
extern struct kmem_cache *ubi_wl_entry_slab;
@ -487,12 +607,23 @@ extern struct class *ubi_class;
extern struct mutex ubi_devices_mutex;
extern struct blocking_notifier_head ubi_notifiers;
/* scan.c */
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
int vol_id);
void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
struct ubi_attach_info *ai);
int ubi_attach(struct ubi_device *ubi);
void ubi_destroy_ai(struct ubi_attach_info *ai);
/* vtbl.c */
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
struct ubi_vtbl_record *vtbl_rec);
int ubi_vtbl_rename_volumes(struct ubi_device *ubi,
struct list_head *rename_list);
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si);
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai);
/* vmt.c */
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req);
@ -525,22 +656,22 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, 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 ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len, int dtype,
int used_ebs);
int lnum, const void *buf, int len, int used_ebs);
int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len, int dtype);
int lnum, const void *buf, int len);
int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
struct ubi_vid_hdr *vid_hdr);
int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si);
int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
/* wl.c */
int ubi_wl_get_peb(struct ubi_device *ubi, int dtype);
int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture);
int ubi_wl_flush(struct ubi_device *ubi);
int ubi_wl_get_peb(struct ubi_device *ubi);
int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum,
int pnum, int torture);
int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum);
int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum);
int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si);
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
void ubi_wl_close(struct ubi_device *ubi);
int ubi_thread(void *u);
@ -573,6 +704,7 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol,
int ubi_notify_all(struct ubi_device *ubi, int ntype,
struct notifier_block *nb);
int ubi_enumerate_volumes(struct notifier_block *nb);
void ubi_free_internal_volumes(struct ubi_device *ubi);
/* kapi.c */
void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
@ -593,6 +725,21 @@ void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
rb = rb_next(rb), \
pos = (rb ? container_of(rb, typeof(*pos), member) : NULL))
/*
* ubi_move_aeb_to_list - move a PEB from the volume tree to a list.
*
* @av: volume attaching information
* @aeb: attaching eraseblock information
* @list: the list to move to
*/
static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av,
struct ubi_ainf_peb *aeb,
struct list_head *list)
{
rb_erase(&aeb->u.rb, &av->root);
list_add_tail(&aeb->u.list, list);
}
/**
* ubi_zalloc_vid_hdr - allocate a volume identifier header object.
* @ubi: UBI device description object
@ -667,7 +814,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();
dump_stack();
}
}

View file

@ -147,7 +147,7 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
}
if (bytes == 0) {
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;
@ -186,14 +186,12 @@ int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
dbg_gen("start changing LEB %d:%d, %u bytes",
vol->vol_id, req->lnum, req->bytes);
if (req->bytes == 0)
return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0,
req->dtype);
return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0);
vol->upd_bytes = req->bytes;
vol->upd_received = 0;
vol->changing_leb = 1;
vol->ch_lnum = req->lnum;
vol->ch_dtype = req->dtype;
vol->upd_buf = vmalloc(req->bytes);
if (!vol->upd_buf)
@ -246,8 +244,7 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
return 0;
}
err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len,
UBI_UNKNOWN);
err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len);
} else {
/*
* When writing static volume, and this is the last logical
@ -259,8 +256,7 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
* contain zeros, not random trash.
*/
memset(buf + len, 0, vol->usable_leb_size - len);
err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len,
UBI_UNKNOWN, used_ebs);
err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs);
}
return err;
@ -365,7 +361,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
ubi_assert(vol->upd_received <= vol->upd_bytes);
if (vol->upd_received == vol->upd_bytes) {
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;
/* The update is finished, clear the update marker */
@ -421,7 +417,7 @@ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol,
len - vol->upd_bytes);
len = ubi_calc_data_len(ubi, vol->upd_buf, len);
err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum,
vol->upd_buf, len, UBI_UNKNOWN);
vol->upd_buf, len);
if (err)
return err;
}

View file

@ -29,11 +29,7 @@
#include <linux/export.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG
static int paranoid_check_volumes(struct ubi_device *ubi);
#else
#define paranoid_check_volumes(ubi) 0
#endif
static int self_check_volumes(struct ubi_device *ubi);
static ssize_t vol_attribute_show(struct device *dev,
struct device_attribute *attr, char *buf);
@ -227,7 +223,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
}
if (vol_id == UBI_VOL_NUM_AUTO) {
dbg_err("out of volume IDs");
ubi_err("out of volume IDs");
err = -ENFILE;
goto out_unlock;
}
@ -241,7 +237,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
/* Ensure that this volume does not exist */
err = -EEXIST;
if (ubi->volumes[vol_id]) {
dbg_err("volume %d already exists", vol_id);
ubi_err("volume %d already exists", vol_id);
goto out_unlock;
}
@ -250,7 +246,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
if (ubi->volumes[i] &&
ubi->volumes[i]->name_len == req->name_len &&
!strcmp(ubi->volumes[i]->name, req->name)) {
dbg_err("volume \"%s\" exists (ID %d)", req->name, i);
ubi_err("volume \"%s\" exists (ID %d)", req->name, i);
goto out_unlock;
}
@ -261,9 +257,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
/* Reserve physical eraseblocks */
if (vol->reserved_pebs > ubi->avail_pebs) {
dbg_err("not enough PEBs, only %d available", ubi->avail_pebs);
ubi_err("not enough PEBs, only %d available", ubi->avail_pebs);
if (ubi->corr_peb_count)
dbg_err("%d PEBs are corrupted and not used",
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
err = -ENOSPC;
goto out_unlock;
@ -284,7 +280,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
* Finish all pending erases because there may be some LEBs belonging
* to the same volume ID.
*/
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
if (err)
goto out_acc;
@ -360,8 +356,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
spin_unlock(&ubi->volumes_lock);
ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED);
if (paranoid_check_volumes(ubi))
dbg_err("check failed while creating volume %d", vol_id);
self_check_volumes(ubi);
return err;
out_sysfs:
@ -461,8 +456,8 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
spin_unlock(&ubi->volumes_lock);
ubi_volume_notify(ubi, vol, UBI_VOLUME_REMOVED);
if (!no_vtbl && paranoid_check_volumes(ubi))
dbg_err("check failed while removing volume %d", vol_id);
if (!no_vtbl)
self_check_volumes(ubi);
return err;
@ -500,7 +495,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
if (vol->vol_type == UBI_STATIC_VOLUME &&
reserved_pebs < vol->used_ebs) {
dbg_err("too small size %d, %d LEBs contain data",
ubi_err("too small size %d, %d LEBs contain data",
reserved_pebs, vol->used_ebs);
return -EINVAL;
}
@ -529,10 +524,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
if (pebs > 0) {
spin_lock(&ubi->volumes_lock);
if (pebs > ubi->avail_pebs) {
dbg_err("not enough PEBs: requested %d, available %d",
ubi_err("not enough PEBs: requested %d, available %d",
pebs, ubi->avail_pebs);
if (ubi->corr_peb_count)
dbg_err("%d PEBs are corrupted and not used",
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
spin_unlock(&ubi->volumes_lock);
err = -ENOSPC;
@ -588,8 +583,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
}
ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED);
if (paranoid_check_volumes(ubi))
dbg_err("check failed while re-sizing volume %d", vol_id);
self_check_volumes(ubi);
return err;
out_acc:
@ -638,8 +632,8 @@ int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list)
}
}
if (!err && paranoid_check_volumes(ubi))
;
if (!err)
self_check_volumes(ubi);
return err;
}
@ -686,8 +680,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
return err;
}
if (paranoid_check_volumes(ubi))
dbg_err("check failed while adding volume %d", vol_id);
self_check_volumes(ubi);
return err;
out_cdev:
@ -712,16 +705,14 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)
volume_sysfs_close(vol);
}
#ifdef CONFIG_MTD_UBI_DEBUG
/**
* paranoid_check_volume - check volume information.
* self_check_volume - check volume information.
* @ubi: UBI device description object
* @vol_id: volume ID
*
* Returns zero if volume is all right and a a negative error code if not.
*/
static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
static int self_check_volume(struct ubi_device *ubi, int vol_id)
{
int idx = vol_id2idx(ubi, vol_id);
int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker;
@ -771,7 +762,7 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
}
if (vol->upd_marker && vol->corrupted) {
dbg_err("update marker and corrupted simultaneously");
ubi_err("update marker and corrupted simultaneously");
goto fail;
}
@ -853,22 +844,22 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
return 0;
fail:
ubi_err("paranoid check failed for volume %d", vol_id);
ubi_err("self-check failed for volume %d", vol_id);
if (vol)
ubi_dbg_dump_vol_info(vol);
ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
ubi_dump_vol_info(vol);
ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
dump_stack();
spin_unlock(&ubi->volumes_lock);
return -EINVAL;
}
/**
* paranoid_check_volumes - check information about all volumes.
* self_check_volumes - check information about all volumes.
* @ubi: UBI device description object
*
* Returns zero if volumes are all right and a a negative error code if not.
*/
static int paranoid_check_volumes(struct ubi_device *ubi)
static int self_check_volumes(struct ubi_device *ubi)
{
int i, err = 0;
@ -876,11 +867,10 @@ static int paranoid_check_volumes(struct ubi_device *ubi)
return 0;
for (i = 0; i < ubi->vtbl_slots; i++) {
err = paranoid_check_volume(ubi, i);
err = self_check_volume(ubi, i);
if (err)
break;
}
return err;
}
#endif

View file

@ -37,16 +37,15 @@
* LEB 1. This scheme guarantees recoverability from unclean reboots.
*
* In this UBI implementation the on-flash volume table does not contain any
* information about how many data static volumes contain. This information may
* be found from the scanning data.
* information about how much data static volumes contain.
*
* But it would still be beneficial to store this information in the volume
* table. For example, suppose we have a static volume X, and all its physical
* eraseblocks became bad for some reasons. Suppose we are attaching the
* corresponding MTD device, the scanning has found no logical eraseblocks
* corresponding MTD device, for some reason we find no logical eraseblocks
* corresponding to the volume X. According to the volume table volume X does
* exist. So we don't know whether it is just empty or all its physical
* eraseblocks went bad. So we cannot alarm the user about this corruption.
* eraseblocks went bad. So we cannot alarm the user properly.
*
* The volume table also stores so-called "update marker", which is used for
* volume updates. Before updating the volume, the update marker is set, and
@ -62,11 +61,7 @@
#include <asm/div64.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG
static void paranoid_vtbl_check(const struct ubi_device *ubi);
#else
#define paranoid_vtbl_check(ubi)
#endif
static void self_vtbl_check(const struct ubi_device *ubi);
/* Empty volume table record */
static struct ubi_vtbl_record empty_vtbl_record;
@ -106,12 +101,12 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
return err;
err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
ubi->vtbl_size, UBI_LONGTERM);
ubi->vtbl_size);
if (err)
return err;
}
paranoid_vtbl_check(ubi);
self_vtbl_check(ubi);
return 0;
}
@ -158,7 +153,7 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi,
return err;
err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
ubi->vtbl_size, UBI_LONGTERM);
ubi->vtbl_size);
if (err)
return err;
}
@ -197,7 +192,7 @@ static int vtbl_check(const struct ubi_device *ubi,
if (be32_to_cpu(vtbl[i].crc) != crc) {
ubi_err("bad CRC at record %u: %#08x, not %#08x",
i, crc, be32_to_cpu(vtbl[i].crc));
ubi_dbg_dump_vtbl_record(&vtbl[i], i);
ubi_dump_vtbl_record(&vtbl[i], i);
return 1;
}
@ -229,7 +224,7 @@ static int vtbl_check(const struct ubi_device *ubi,
n = ubi->leb_size % alignment;
if (data_pad != n) {
dbg_err("bad data_pad, has to be %d", n);
ubi_err("bad data_pad, has to be %d", n);
err = 6;
goto bad;
}
@ -245,7 +240,7 @@ static int vtbl_check(const struct ubi_device *ubi,
}
if (reserved_pebs > ubi->good_peb_count) {
dbg_err("too large reserved_pebs %d, good PEBs %d",
ubi_err("too large reserved_pebs %d, good PEBs %d",
reserved_pebs, ubi->good_peb_count);
err = 9;
goto bad;
@ -277,8 +272,8 @@ static int vtbl_check(const struct ubi_device *ubi,
!strncmp(vtbl[i].name, vtbl[n].name, len1)) {
ubi_err("volumes %d and %d have the same name"
" \"%s\"", i, n, vtbl[i].name);
ubi_dbg_dump_vtbl_record(&vtbl[i], i);
ubi_dbg_dump_vtbl_record(&vtbl[n], n);
ubi_dump_vtbl_record(&vtbl[i], i);
ubi_dump_vtbl_record(&vtbl[n], n);
return -EINVAL;
}
}
@ -288,26 +283,26 @@ static int vtbl_check(const struct ubi_device *ubi,
bad:
ubi_err("volume table check failed: record %d, error %d", i, err);
ubi_dbg_dump_vtbl_record(&vtbl[i], i);
ubi_dump_vtbl_record(&vtbl[i], i);
return -EINVAL;
}
/**
* create_vtbl - create a copy of volume table.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
* @copy: number of the volume table copy
* @vtbl: contents of the volume table
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si,
static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai,
int copy, void *vtbl)
{
int err, tries = 0;
struct ubi_vid_hdr *vid_hdr;
struct ubi_scan_leb *new_seb;
struct ubi_ainf_peb *new_aeb;
ubi_msg("create volume table (copy #%d)", copy + 1);
@ -316,9 +311,9 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si,
return -ENOMEM;
retry:
new_seb = ubi_scan_get_free_peb(ubi, si);
if (IS_ERR(new_seb)) {
err = PTR_ERR(new_seb);
new_aeb = ubi_early_get_peb(ubi, ai);
if (IS_ERR(new_aeb)) {
err = PTR_ERR(new_aeb);
goto out_free;
}
@ -328,25 +323,24 @@ retry:
vid_hdr->data_size = vid_hdr->used_ebs =
vid_hdr->data_pad = cpu_to_be32(0);
vid_hdr->lnum = cpu_to_be32(copy);
vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum);
vid_hdr->sqnum = cpu_to_be64(++ai->max_sqnum);
/* The EC header is already there, write the VID header */
err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr);
err = ubi_io_write_vid_hdr(ubi, new_aeb->pnum, vid_hdr);
if (err)
goto write_error;
/* Write the layout volume contents */
err = ubi_io_write_data(ubi, vtbl, new_seb->pnum, 0, ubi->vtbl_size);
err = ubi_io_write_data(ubi, vtbl, new_aeb->pnum, 0, ubi->vtbl_size);
if (err)
goto write_error;
/*
* 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()'.
* And add it to the attaching information. Don't delete the old version
* of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.
*/
err = ubi_scan_add_used(ubi, si, new_seb->pnum, new_seb->ec,
vid_hdr, 0);
kfree(new_seb);
err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0);
kfree(new_aeb);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
@ -356,10 +350,10 @@ write_error:
* Probably this physical eraseblock went bad, try to pick
* another one.
*/
list_add(&new_seb->u.list, &si->erase);
list_add(&new_aeb->u.list, &ai->erase);
goto retry;
}
kfree(new_seb);
kfree(new_aeb);
out_free:
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
@ -369,20 +363,20 @@ out_free:
/**
* process_lvol - process the layout volume.
* @ubi: UBI device description object
* @si: scanning information
* @sv: layout volume scanning information
* @ai: attaching information
* @av: layout volume attaching information
*
* This function is responsible for reading the layout volume, ensuring it is
* not corrupted, and recovering from corruptions if needed. Returns volume
* table in case of success and a negative error code in case of failure.
*/
static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
struct ubi_scan_info *si,
struct ubi_scan_volume *sv)
struct ubi_attach_info *ai,
struct ubi_ainf_volume *av)
{
int err;
struct rb_node *rb;
struct ubi_scan_leb *seb;
struct ubi_ainf_peb *aeb;
struct ubi_vtbl_record *leb[UBI_LAYOUT_VOLUME_EBS] = { NULL, NULL };
int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1};
@ -414,14 +408,14 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
dbg_gen("check layout volume");
/* Read both LEB 0 and LEB 1 into memory */
ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) {
leb[seb->lnum] = vzalloc(ubi->vtbl_size);
if (!leb[seb->lnum]) {
ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) {
leb[aeb->lnum] = vzalloc(ubi->vtbl_size);
if (!leb[aeb->lnum]) {
err = -ENOMEM;
goto out_free;
}
err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
err = ubi_io_read_data(ubi, leb[aeb->lnum], aeb->pnum, 0,
ubi->vtbl_size);
if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err))
/*
@ -429,12 +423,12 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
* uncorrectable ECC error, but we have our own CRC and
* the data will be checked later. If the data is OK,
* the PEB will be scrubbed (because we set
* seb->scrub). If the data is not OK, the contents of
* aeb->scrub). If the data is not OK, the contents of
* the PEB will be recovered from the second copy, and
* seb->scrub will be cleared in
* 'ubi_scan_add_used()'.
* aeb->scrub will be cleared in
* 'ubi_add_to_av()'.
*/
seb->scrub = 1;
aeb->scrub = 1;
else if (err)
goto out_free;
}
@ -453,7 +447,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
ubi->vtbl_size);
if (leb_corrupted[1]) {
ubi_warn("volume table copy #2 is corrupted");
err = create_vtbl(ubi, si, 1, leb[0]);
err = create_vtbl(ubi, ai, 1, leb[0]);
if (err)
goto out_free;
ubi_msg("volume table was restored");
@ -476,7 +470,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
}
ubi_warn("volume table copy #1 is corrupted");
err = create_vtbl(ubi, si, 0, leb[1]);
err = create_vtbl(ubi, ai, 0, leb[1]);
if (err)
goto out_free;
ubi_msg("volume table was restored");
@ -494,13 +488,13 @@ out_free:
/**
* create_empty_lvol - create empty layout volume.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
*
* This function returns volume table contents in case of success and a
* negative error code in case of failure.
*/
static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
struct ubi_scan_info *si)
struct ubi_attach_info *ai)
{
int i;
struct ubi_vtbl_record *vtbl;
@ -515,7 +509,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
int err;
err = create_vtbl(ubi, si, i, vtbl);
err = create_vtbl(ubi, ai, i, vtbl);
if (err) {
vfree(vtbl);
return ERR_PTR(err);
@ -528,18 +522,19 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
/**
* init_volumes - initialize volume information for existing volumes.
* @ubi: UBI device description object
* @si: scanning information
* @ai: scanning information
* @vtbl: volume table
*
* This function allocates volume description objects for existing volumes.
* Returns zero in case of success and a negative error code in case of
* failure.
*/
static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
static int init_volumes(struct ubi_device *ubi,
const struct ubi_attach_info *ai,
const struct ubi_vtbl_record *vtbl)
{
int i, reserved_pebs = 0;
struct ubi_scan_volume *sv;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
for (i = 0; i < ubi->vtbl_slots; i++) {
@ -595,8 +590,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
}
/* Static volumes only */
sv = ubi_scan_find_sv(si, i);
if (!sv) {
av = ubi_find_av(ai, i);
if (!av) {
/*
* No eraseblocks belonging to this volume found. We
* don't actually know whether this static volume is
@ -608,22 +603,22 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
continue;
}
if (sv->leb_count != sv->used_ebs) {
if (av->leb_count != av->used_ebs) {
/*
* We found a static volume which misses several
* eraseblocks. Treat it as corrupted.
*/
ubi_warn("static volume %d misses %d LEBs - corrupted",
sv->vol_id, sv->used_ebs - sv->leb_count);
av->vol_id, av->used_ebs - av->leb_count);
vol->corrupted = 1;
continue;
}
vol->used_ebs = sv->used_ebs;
vol->used_ebs = av->used_ebs;
vol->used_bytes =
(long long)(vol->used_ebs - 1) * vol->usable_leb_size;
vol->used_bytes += sv->last_data_size;
vol->last_eb_bytes = sv->last_data_size;
vol->used_bytes += av->last_data_size;
vol->last_eb_bytes = av->last_data_size;
}
/* And add the layout volume */
@ -664,105 +659,104 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
}
/**
* check_sv - check volume scanning information.
* check_av - check volume attaching information.
* @vol: UBI volume description object
* @sv: volume scanning information
* @av: volume attaching information
*
* This function returns zero if the volume scanning information is consistent
* This function returns zero if the volume attaching information is consistent
* to the data read from the volume tabla, and %-EINVAL if not.
*/
static int check_sv(const struct ubi_volume *vol,
const struct ubi_scan_volume *sv)
static int check_av(const struct ubi_volume *vol,
const struct ubi_ainf_volume *av)
{
int err;
if (sv->highest_lnum >= vol->reserved_pebs) {
if (av->highest_lnum >= vol->reserved_pebs) {
err = 1;
goto bad;
}
if (sv->leb_count > vol->reserved_pebs) {
if (av->leb_count > vol->reserved_pebs) {
err = 2;
goto bad;
}
if (sv->vol_type != vol->vol_type) {
if (av->vol_type != vol->vol_type) {
err = 3;
goto bad;
}
if (sv->used_ebs > vol->reserved_pebs) {
if (av->used_ebs > vol->reserved_pebs) {
err = 4;
goto bad;
}
if (sv->data_pad != vol->data_pad) {
if (av->data_pad != vol->data_pad) {
err = 5;
goto bad;
}
return 0;
bad:
ubi_err("bad scanning information, error %d", err);
ubi_dbg_dump_sv(sv);
ubi_dbg_dump_vol_info(vol);
ubi_err("bad attaching information, error %d", err);
ubi_dump_av(av);
ubi_dump_vol_info(vol);
return -EINVAL;
}
/**
* check_scanning_info - check that scanning information.
* check_attaching_info - check that attaching information.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
*
* Even though we protect on-flash data by CRC checksums, we still don't trust
* the media. This function ensures that scanning information is consistent to
* the information read from the volume table. Returns zero if the scanning
* the media. This function ensures that attaching information is consistent to
* the information read from the volume table. Returns zero if the attaching
* information is OK and %-EINVAL if it is not.
*/
static int check_scanning_info(const struct ubi_device *ubi,
struct ubi_scan_info *si)
static int check_attaching_info(const struct ubi_device *ubi,
struct ubi_attach_info *ai)
{
int err, i;
struct ubi_scan_volume *sv;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
if (si->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) {
ubi_err("scanning found %d volumes, maximum is %d + %d",
si->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots);
if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) {
ubi_err("found %d volumes while attaching, maximum is %d + %d",
ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots);
return -EINVAL;
}
if (si->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT &&
si->highest_vol_id < UBI_INTERNAL_VOL_START) {
ubi_err("too large volume ID %d found by scanning",
si->highest_vol_id);
if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT &&
ai->highest_vol_id < UBI_INTERNAL_VOL_START) {
ubi_err("too large volume ID %d found", ai->highest_vol_id);
return -EINVAL;
}
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
cond_resched();
sv = ubi_scan_find_sv(si, i);
av = ubi_find_av(ai, i);
vol = ubi->volumes[i];
if (!vol) {
if (sv)
ubi_scan_rm_volume(si, sv);
if (av)
ubi_remove_av(ai, av);
continue;
}
if (vol->reserved_pebs == 0) {
ubi_assert(i < ubi->vtbl_slots);
if (!sv)
if (!av)
continue;
/*
* During scanning we found a volume which does not
* During attaching we found a volume which does not
* exist according to the information in the volume
* table. This must have happened due to an unclean
* reboot while the volume was being removed. Discard
* these eraseblocks.
*/
ubi_msg("finish volume %d removal", sv->vol_id);
ubi_scan_rm_volume(si, sv);
} else if (sv) {
err = check_sv(vol, sv);
ubi_msg("finish volume %d removal", av->vol_id);
ubi_remove_av(ai, av);
} else if (av) {
err = check_av(vol, av);
if (err)
return err;
}
@ -774,16 +768,16 @@ static int check_scanning_info(const struct ubi_device *ubi,
/**
* ubi_read_volume_table - read the volume table.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
*
* This function reads volume table, checks it, recover from errors if needed,
* or creates it if needed. Returns zero in case of success and a negative
* error code in case of failure.
*/
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
{
int i, err;
struct ubi_scan_volume *sv;
struct ubi_ainf_volume *av;
empty_vtbl_record.crc = cpu_to_be32(0xf116c36b);
@ -798,8 +792,8 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE;
ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size);
sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID);
if (!sv) {
av = ubi_find_av(ai, UBI_LAYOUT_VOLUME_ID);
if (!av) {
/*
* No logical eraseblocks belonging to the layout volume were
* found. This could mean that the flash is just empty. In
@ -808,8 +802,8 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
* But if flash is not empty this must be a corruption or the
* MTD device just contains garbage.
*/
if (si->is_empty) {
ubi->vtbl = create_empty_lvol(ubi, si);
if (ai->is_empty) {
ubi->vtbl = create_empty_lvol(ubi, ai);
if (IS_ERR(ubi->vtbl))
return PTR_ERR(ubi->vtbl);
} else {
@ -817,14 +811,14 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
return -EINVAL;
}
} else {
if (sv->leb_count > UBI_LAYOUT_VOLUME_EBS) {
if (av->leb_count > UBI_LAYOUT_VOLUME_EBS) {
/* This must not happen with proper UBI images */
dbg_err("too many LEBs (%d) in layout volume",
sv->leb_count);
ubi_err("too many LEBs (%d) in layout volume",
av->leb_count);
return -EINVAL;
}
ubi->vtbl = process_lvol(ubi, si, sv);
ubi->vtbl = process_lvol(ubi, ai, av);
if (IS_ERR(ubi->vtbl))
return PTR_ERR(ubi->vtbl);
}
@ -835,15 +829,15 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
* The layout volume is OK, initialize the corresponding in-RAM data
* structures.
*/
err = init_volumes(ubi, si, ubi->vtbl);
err = init_volumes(ubi, ai, ubi->vtbl);
if (err)
goto out_free;
/*
* Make sure that the scanning information is consistent to the
* Make sure that the attaching information is consistent to the
* information stored in the volume table.
*/
err = check_scanning_info(ubi, si);
err = check_attaching_info(ubi, ai);
if (err)
goto out_free;
@ -858,21 +852,17 @@ out_free:
return err;
}
#ifdef CONFIG_MTD_UBI_DEBUG
/**
* paranoid_vtbl_check - check volume table.
* self_vtbl_check - check volume table.
* @ubi: UBI device description object
*/
static void paranoid_vtbl_check(const struct ubi_device *ubi)
static void self_vtbl_check(const struct ubi_device *ubi)
{
if (!ubi->dbg->chk_gen)
return;
if (vtbl_check(ubi, ubi->vtbl)) {
ubi_err("paranoid check failed");
ubi_err("self-check failed");
BUG();
}
}
#endif /* CONFIG_MTD_UBI_DEBUG */

View file

@ -41,12 +41,6 @@
* physical eraseblocks with low erase counter to free physical eraseblocks
* with high erase counter.
*
* The 'ubi_wl_get_peb()' function accepts data type hints which help to pick
* an "optimal" physical eraseblock. For example, when it is known that the
* physical eraseblock will be "put" soon because it contains short-term data,
* the WL sub-system may pick a free physical eraseblock with low erase
* counter, and so forth.
*
* If the WL sub-system fails to erase a physical eraseblock, it marks it as
* bad.
*
@ -70,8 +64,7 @@
* to the user; instead, we first want to let users fill them up with data;
*
* o there is a chance that the user will put the physical eraseblock very
* soon, so it makes sense not to move it for some time, but wait; this is
* especially important in case of "short term" physical eraseblocks.
* soon, so it makes sense not to move it for some time, but wait.
*
* Physical eraseblocks stay protected only for limited time. But the "time" is
* measured in erase cycles in this case. This is implemented with help of the
@ -147,6 +140,8 @@
* @list: a link in the list of pending works
* @func: worker function
* @e: physical eraseblock to erase
* @vol_id: the volume ID on which this erasure is being performed
* @lnum: the logical eraseblock number
* @torture: if the physical eraseblock has to be tortured
*
* The @func pointer points to the worker function. If the @cancel argument is
@ -159,21 +154,16 @@ struct ubi_work {
int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
/* The below fields are only relevant to erasure works */
struct ubi_wl_entry *e;
int vol_id;
int lnum;
int torture;
};
#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(const struct ubi_device *ubi,
struct ubi_wl_entry *e,
struct rb_root *root);
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(ubi, e, root)
#define paranoid_check_in_pq(ubi, e) 0
#endif
static int self_check_ec(struct ubi_device *ubi, int pnum, int ec);
static int self_check_in_wl_tree(const struct ubi_device *ubi,
struct ubi_wl_entry *e, struct rb_root *root);
static int self_check_in_pq(const struct ubi_device *ubi,
struct ubi_wl_entry *e);
/**
* wl_tree_add - add a wear-leveling entry to a WL RB-tree.
@ -383,19 +373,15 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
/**
* ubi_wl_get_peb - get a physical eraseblock.
* @ubi: UBI device description object
* @dtype: type of data which will be stored in this physical eraseblock
*
* This function returns a physical eraseblock in case of success and a
* negative error code in case of failure. Might sleep.
*/
int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
int ubi_wl_get_peb(struct ubi_device *ubi)
{
int err;
struct ubi_wl_entry *e, *first, *last;
ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM ||
dtype == UBI_UNKNOWN);
retry:
spin_lock(&ubi->wl_lock);
if (!ubi->free.rb_node) {
@ -413,45 +399,15 @@ retry:
goto retry;
}
switch (dtype) {
case UBI_LONGTERM:
/*
* For long term data we pick a physical eraseblock with high
* erase counter. But the highest erase counter we can pick is
* bounded by the the lowest erase counter plus
* %WL_FREE_MAX_DIFF.
*/
e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
break;
case UBI_UNKNOWN:
/*
* For unknown data we pick a physical eraseblock with medium
* erase counter. But we by no means can pick a physical
* eraseblock with erase counter greater or equivalent than the
* lowest erase counter plus %WL_FREE_MAX_DIFF/2.
*/
first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry,
u.rb);
last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb);
first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb);
last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb);
if (last->ec - first->ec < WL_FREE_MAX_DIFF)
e = rb_entry(ubi->free.rb_node,
struct ubi_wl_entry, u.rb);
else
e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
break;
case UBI_SHORTTERM:
/*
* For short term data we pick a physical eraseblock with the
* lowest erase counter as we expect it will be erased soon.
*/
e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb);
break;
default:
BUG();
}
if (last->ec - first->ec < WL_FREE_MAX_DIFF)
e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb);
else
e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
paranoid_check_in_wl_tree(ubi, e, &ubi->free);
self_check_in_wl_tree(ubi, e, &ubi->free);
/*
* Move the physical eraseblock to the protection queue where it will
@ -462,8 +418,8 @@ retry:
prot_queue_add(ubi, e);
spin_unlock(&ubi->wl_lock);
err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
ubi->peb_size - ubi->vid_hdr_aloffset);
err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
ubi->peb_size - ubi->vid_hdr_aloffset);
if (err) {
ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
return err;
@ -488,7 +444,7 @@ static int prot_queue_del(struct ubi_device *ubi, int pnum)
if (!e)
return -ENODEV;
if (paranoid_check_in_pq(ubi, e))
if (self_check_in_pq(ubi, e))
return -ENODEV;
list_del(&e->u.list);
@ -514,7 +470,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec);
err = paranoid_check_ec(ubi, e->pnum, e->ec);
err = self_check_ec(ubi, e->pnum, e->ec);
if (err)
return -EINVAL;
@ -627,13 +583,15 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
* schedule_erase - schedule an erase work.
* @ubi: UBI device description object
* @e: the WL entry of the physical eraseblock to erase
* @vol_id: the volume ID that last used this PEB
* @lnum: the last used logical eraseblock number for the PEB
* @torture: if the physical eraseblock has to be tortured
*
* This function returns zero in case of success and a %-ENOMEM in case of
* failure.
*/
static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
int torture)
int vol_id, int lnum, int torture)
{
struct ubi_work *wl_wrk;
@ -646,6 +604,8 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
wl_wrk->func = &erase_worker;
wl_wrk->e = e;
wl_wrk->vol_id = vol_id;
wl_wrk->lnum = lnum;
wl_wrk->torture = torture;
schedule_ubi_work(ubi, wl_wrk);
@ -714,7 +674,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(ubi, e1, &ubi->used);
self_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);
@ -723,12 +683,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(ubi, e1, &ubi->scrub);
self_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(ubi, e2, &ubi->free);
self_check_in_wl_tree(ubi, e2, &ubi->free);
rb_erase(&e2->u.rb, &ubi->free);
ubi->move_from = e1;
ubi->move_to = e2;
@ -846,7 +806,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
ubi->move_to_put = ubi->wl_scheduled = 0;
spin_unlock(&ubi->wl_lock);
err = schedule_erase(ubi, e1, 0);
err = schedule_erase(ubi, e1, vol_id, lnum, 0);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e1);
if (e2)
@ -861,7 +821,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
*/
dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase",
e2->pnum, vol_id, lnum);
err = schedule_erase(ubi, e2, 0);
err = schedule_erase(ubi, e2, vol_id, lnum, 0);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e2);
goto out_ro;
@ -900,7 +860,7 @@ out_not_moved:
spin_unlock(&ubi->wl_lock);
ubi_free_vid_hdr(ubi, vid_hdr);
err = schedule_erase(ubi, e2, torture);
err = schedule_erase(ubi, e2, vol_id, lnum, torture);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e2);
goto out_ro;
@ -1019,6 +979,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
{
struct ubi_wl_entry *e = wl_wrk->e;
int pnum = e->pnum, err, need;
int vol_id = wl_wrk->vol_id;
int lnum = wl_wrk->lnum;
if (cancel) {
dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
@ -1027,7 +989,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
return 0;
}
dbg_wl("erase PEB %d EC %d", pnum, e->ec);
dbg_wl("erase PEB %d EC %d LEB %d:%d",
pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
err = sync_erase(ubi, e, wl_wrk->torture);
if (!err) {
@ -1057,7 +1020,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
int err1;
/* Re-schedule the LEB for erasure */
err1 = schedule_erase(ubi, e, 0);
err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
if (err1) {
err = err1;
goto out_ro;
@ -1125,6 +1088,8 @@ out_ro:
/**
* ubi_wl_put_peb - return a PEB to the wear-leveling sub-system.
* @ubi: UBI device description object
* @vol_id: the volume ID that last used this PEB
* @lnum: the last used logical eraseblock number for the PEB
* @pnum: physical eraseblock to return
* @torture: if this physical eraseblock has to be tortured
*
@ -1133,7 +1098,8 @@ out_ro:
* occurred to this @pnum and it has to be tested. This function returns zero
* in case of success, and a negative error code in case of failure.
*/
int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture)
int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum,
int pnum, int torture)
{
int err;
struct ubi_wl_entry *e;
@ -1175,13 +1141,13 @@ retry:
return 0;
} else {
if (in_wl_tree(e, &ubi->used)) {
paranoid_check_in_wl_tree(ubi, e, &ubi->used);
self_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(ubi, e, &ubi->scrub);
self_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(ubi, e, &ubi->erroneous);
self_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);
@ -1199,7 +1165,7 @@ retry:
}
spin_unlock(&ubi->wl_lock);
err = schedule_erase(ubi, e, torture);
err = schedule_erase(ubi, e, vol_id, lnum, torture);
if (err) {
spin_lock(&ubi->wl_lock);
wl_tree_add(e, &ubi->used);
@ -1248,7 +1214,7 @@ retry:
}
if (in_wl_tree(e, &ubi->used)) {
paranoid_check_in_wl_tree(ubi, e, &ubi->used);
self_check_in_wl_tree(ubi, e, &ubi->used);
rb_erase(&e->u.rb, &ubi->used);
} else {
int err;
@ -1275,44 +1241,55 @@ retry:
/**
* ubi_wl_flush - flush all pending works.
* @ubi: UBI device description object
* @vol_id: the volume id to flush for
* @lnum: the logical eraseblock number to flush for
*
* This function returns zero in case of success and a negative error code in
* case of failure.
* This function executes all pending works for a particular volume id /
* logical eraseblock number pair. If either value is set to %UBI_ALL, then it
* acts as a wildcard for all of the corresponding volume numbers or logical
* eraseblock numbers. It returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_wl_flush(struct ubi_device *ubi)
int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum)
{
int err;
int err = 0;
int found = 1;
/*
* Erase while the pending works queue is not empty, but not more than
* the number of currently pending works.
*/
dbg_wl("flush (%d pending works)", ubi->works_count);
while (ubi->works_count) {
err = do_work(ubi);
if (err)
return err;
}
dbg_wl("flush pending work for LEB %d:%d (%d pending works)",
vol_id, lnum, ubi->works_count);
/*
* Make sure all the works which have been done in parallel are
* finished.
*/
down_write(&ubi->work_sem);
up_write(&ubi->work_sem);
while (found) {
struct ubi_work *wrk;
found = 0;
/*
* And in case last was the WL worker and it canceled the LEB
* movement, flush again.
*/
while (ubi->works_count) {
dbg_wl("flush more (%d pending works)", ubi->works_count);
err = do_work(ubi);
if (err)
return err;
spin_lock(&ubi->wl_lock);
list_for_each_entry(wrk, &ubi->works, list) {
if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) &&
(lnum == UBI_ALL || wrk->lnum == lnum)) {
list_del(&wrk->list);
ubi->works_count -= 1;
ubi_assert(ubi->works_count >= 0);
spin_unlock(&ubi->wl_lock);
err = wrk->func(ubi, wrk, 0);
if (err)
goto out;
spin_lock(&ubi->wl_lock);
found = 1;
break;
}
}
spin_unlock(&ubi->wl_lock);
}
return 0;
out:
up_write(&ubi->work_sem);
return err;
}
/**
@ -1421,26 +1398,26 @@ static void cancel_pending(struct ubi_device *ubi)
}
/**
* ubi_wl_init_scan - initialize the WL sub-system using scanning information.
* ubi_wl_init - initialize the WL sub-system using attaching information.
* @ubi: UBI device description object
* @si: scanning information
* @ai: attaching information
*
* This function returns zero in case of success, and a negative error code in
* case of failure.
*/
int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
{
int err, i;
struct rb_node *rb1, *rb2;
struct ubi_scan_volume *sv;
struct ubi_scan_leb *seb, *tmp;
struct ubi_ainf_volume *av;
struct ubi_ainf_peb *aeb, *tmp;
struct ubi_wl_entry *e;
ubi->used = ubi->erroneous = ubi->free = ubi->scrub = RB_ROOT;
spin_lock_init(&ubi->wl_lock);
mutex_init(&ubi->move_mutex);
init_rwsem(&ubi->work_sem);
ubi->max_ec = si->max_ec;
ubi->max_ec = ai->max_ec;
INIT_LIST_HEAD(&ubi->works);
sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num);
@ -1454,48 +1431,48 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
INIT_LIST_HEAD(&ubi->pq[i]);
ubi->pq_head = 0;
list_for_each_entry_safe(seb, tmp, &si->erase, u.list) {
list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
cond_resched();
e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
if (!e)
goto out_free;
e->pnum = seb->pnum;
e->ec = seb->ec;
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi->lookuptbl[e->pnum] = e;
if (schedule_erase(ubi, e, 0)) {
if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
kmem_cache_free(ubi_wl_entry_slab, e);
goto out_free;
}
}
list_for_each_entry(seb, &si->free, u.list) {
list_for_each_entry(aeb, &ai->free, u.list) {
cond_resched();
e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
if (!e)
goto out_free;
e->pnum = seb->pnum;
e->ec = seb->ec;
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi_assert(e->ec >= 0);
wl_tree_add(e, &ubi->free);
ubi->lookuptbl[e->pnum] = e;
}
ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) {
ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) {
ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) {
cond_resched();
e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
if (!e)
goto out_free;
e->pnum = seb->pnum;
e->ec = seb->ec;
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi->lookuptbl[e->pnum] = e;
if (!seb->scrub) {
if (!aeb->scrub) {
dbg_wl("add PEB %d EC %d to the used tree",
e->pnum, e->ec);
wl_tree_add(e, &ubi->used);
@ -1567,10 +1544,8 @@ void ubi_wl_close(struct ubi_device *ubi)
kfree(ubi->lookuptbl);
}
#ifdef CONFIG_MTD_UBI_DEBUG
/**
* paranoid_check_ec - make sure that the erase counter of a PEB is correct.
* self_check_ec - make sure that the erase counter of a PEB is correct.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
* @ec: the erase counter to check
@ -1579,7 +1554,7 @@ void ubi_wl_close(struct ubi_device *ubi)
* is equivalent to @ec, and a negative error code if not or if an error
* occurred.
*/
static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec)
static int self_check_ec(struct ubi_device *ubi, int pnum, int ec)
{
int err;
long long read_ec;
@ -1601,9 +1576,9 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec)
read_ec = be64_to_cpu(ec_hdr->ec);
if (ec != read_ec) {
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_err("self-check failed for PEB %d", pnum);
ubi_err("read EC is %lld, should be %d", read_ec, ec);
ubi_dbg_dump_stack();
dump_stack();
err = 1;
} else
err = 0;
@ -1614,7 +1589,7 @@ out_free:
}
/**
* paranoid_check_in_wl_tree - check that wear-leveling entry is in WL RB-tree.
* self_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
@ -1622,9 +1597,8 @@ out_free:
* 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(const struct ubi_device *ubi,
struct ubi_wl_entry *e,
struct rb_root *root)
static int self_check_in_wl_tree(const struct ubi_device *ubi,
struct ubi_wl_entry *e, struct rb_root *root)
{
if (!ubi->dbg->chk_gen)
return 0;
@ -1632,22 +1606,22 @@ static int paranoid_check_in_wl_tree(const struct ubi_device *ubi,
if (in_wl_tree(e, root))
return 0;
ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ",
ubi_err("self-check failed for PEB %d, EC %d, RB-tree %p ",
e->pnum, e->ec, root);
ubi_dbg_dump_stack();
dump_stack();
return -EINVAL;
}
/**
* paranoid_check_in_pq - check if wear-leveling entry is in the protection
* self_check_in_pq - check if wear-leveling entry is in the protection
* queue.
* @ubi: UBI device description object
* @e: the wear-leveling entry to check
*
* This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not.
*/
static int paranoid_check_in_pq(const struct ubi_device *ubi,
struct ubi_wl_entry *e)
static int self_check_in_pq(const struct ubi_device *ubi,
struct ubi_wl_entry *e)
{
struct ubi_wl_entry *p;
int i;
@ -1660,10 +1634,8 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi,
if (p == e)
return 0;
ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue",
ubi_err("self-check failed for PEB %d, EC %d, Protect queue",
e->pnum, e->ec);
ubi_dbg_dump_stack();
dump_stack();
return -EINVAL;
}
#endif /* CONFIG_MTD_UBI_DEBUG */

View file

@ -11,12 +11,6 @@ config UBIFS_FS
help
UBIFS is a file system for flash devices which works on top of UBI.
config UBIFS_FS_XATTR
bool "Extended attributes support"
depends on UBIFS_FS
help
This option enables support of extended attributes.
config UBIFS_FS_ADVANCED_COMPR
bool "Advanced compression options"
depends on UBIFS_FS
@ -41,20 +35,3 @@ config UBIFS_FS_ZLIB
default y
help
Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.
# Debugging-related stuff
config UBIFS_FS_DEBUG
bool "Enable debugging support"
depends on UBIFS_FS
select DEBUG_FS
select KALLSYMS
help
This option enables UBIFS debugging support. It makes sure various
assertions, self-checks, debugging messages and test modes are compiled
in (this all is compiled out otherwise). Assertions are light-weight
and this option also enables them. Self-checks, debugging messages and
test modes are switched off by default. Thus, it is safe and actually
recommended to have debugging support enabled, and it should not slow
down UBIFS. You can then further enable / disable individual debugging
features using UBIFS module parameters and the corresponding sysfs
interfaces.

View file

@ -3,7 +3,4 @@ obj-$(CONFIG_UBIFS_FS) += ubifs.o
ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o
ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o
ubifs-$(CONFIG_UBIFS_FS_DEBUG) += debug.o
ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o

View file

@ -496,7 +496,9 @@ int ubifs_gc_should_commit(struct ubifs_info *c)
return ret;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/*
* Everything below is related to debugging.
*/
/**
* struct idx_node - hold index nodes during index tree traversal.
@ -714,14 +716,14 @@ out:
return 0;
out_dump:
dbg_err("dumping index node (iip=%d)", i->iip);
dbg_dump_node(c, idx);
ubifs_err("dumping index node (iip=%d)", i->iip);
ubifs_dump_node(c, idx);
list_del(&i->list);
kfree(i);
if (!list_empty(&list)) {
i = list_entry(list.prev, struct idx_node, list);
dbg_err("dumping parent index node");
dbg_dump_node(c, &i->idx);
ubifs_err("dumping parent index node");
ubifs_dump_node(c, &i->idx);
}
out_free:
while (!list_empty(&list)) {
@ -734,5 +736,3 @@ out_free:
err = -EINVAL;
return err;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -34,8 +34,6 @@
#include <linux/random.h>
#include "ubifs.h"
#ifdef CONFIG_UBIFS_FS_DEBUG
static DEFINE_SPINLOCK(dbg_lock);
static const char *get_key_fmt(int fmt)
@ -232,7 +230,7 @@ static void dump_ch(const struct ubifs_ch *ch)
printk(KERN_ERR "\tlen %u\n", le32_to_cpu(ch->len));
}
void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
{
const struct ubifs_inode *ui = ubifs_inode(inode);
struct qstr nm = { .name = NULL };
@ -300,7 +298,7 @@ void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
kfree(pdent);
}
void dbg_dump_node(const struct ubifs_info *c, const void *node)
void ubifs_dump_node(const struct ubifs_info *c, const void *node)
{
int i, n;
union ubifs_key key;
@ -603,7 +601,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
spin_unlock(&dbg_lock);
}
void dbg_dump_budget_req(const struct ubifs_budget_req *req)
void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
{
spin_lock(&dbg_lock);
printk(KERN_ERR "Budgeting request: new_ino %d, dirtied_ino %d\n",
@ -620,7 +618,7 @@ void dbg_dump_budget_req(const struct ubifs_budget_req *req)
spin_unlock(&dbg_lock);
}
void dbg_dump_lstats(const struct ubifs_lp_stats *lst)
void ubifs_dump_lstats(const struct ubifs_lp_stats *lst)
{
spin_lock(&dbg_lock);
printk(KERN_ERR "(pid %d) Lprops statistics: empty_lebs %d, "
@ -634,7 +632,7 @@ void dbg_dump_lstats(const struct ubifs_lp_stats *lst)
spin_unlock(&dbg_lock);
}
void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
{
int i;
struct rb_node *rb;
@ -707,7 +705,7 @@ out_unlock:
spin_unlock(&c->space_lock);
}
void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
{
int i, spc, dark = 0, dead = 0;
struct rb_node *rb;
@ -801,7 +799,7 @@ void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
printk(KERN_CONT ")\n");
}
void dbg_dump_lprops(struct ubifs_info *c)
void ubifs_dump_lprops(struct ubifs_info *c)
{
int lnum, err;
struct ubifs_lprops lp;
@ -810,20 +808,20 @@ void dbg_dump_lprops(struct ubifs_info *c)
printk(KERN_ERR "(pid %d) start dumping LEB properties\n",
current->pid);
ubifs_get_lp_stats(c, &lst);
dbg_dump_lstats(&lst);
ubifs_dump_lstats(&lst);
for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) {
err = ubifs_read_one_lp(c, lnum, &lp);
if (err)
ubifs_err("cannot read lprops for LEB %d", lnum);
dbg_dump_lprop(c, &lp);
ubifs_dump_lprop(c, &lp);
}
printk(KERN_ERR "(pid %d) finish dumping LEB properties\n",
current->pid);
}
void dbg_dump_lpt_info(struct ubifs_info *c)
void ubifs_dump_lpt_info(struct ubifs_info *c)
{
int i;
@ -862,8 +860,8 @@ void dbg_dump_lpt_info(struct ubifs_info *c)
spin_unlock(&dbg_lock);
}
void dbg_dump_sleb(const struct ubifs_info *c,
const struct ubifs_scan_leb *sleb, int offs)
void ubifs_dump_sleb(const struct ubifs_info *c,
const struct ubifs_scan_leb *sleb, int offs)
{
struct ubifs_scan_node *snod;
@ -874,11 +872,11 @@ void dbg_dump_sleb(const struct ubifs_info *c,
cond_resched();
printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", sleb->lnum,
snod->offs, snod->len);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
}
}
void dbg_dump_leb(const struct ubifs_info *c, int lnum)
void ubifs_dump_leb(const struct ubifs_info *c, int lnum)
{
struct ubifs_scan_leb *sleb;
struct ubifs_scan_node *snod;
@ -909,7 +907,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
cond_resched();
printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", lnum,
snod->offs, snod->len);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
}
printk(KERN_ERR "(pid %d) finish dumping LEB %d\n",
@ -921,8 +919,8 @@ out:
return;
}
void dbg_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode)
void ubifs_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode)
{
int n;
const struct ubifs_zbranch *zbr;
@ -965,7 +963,7 @@ void dbg_dump_znode(const struct ubifs_info *c,
spin_unlock(&dbg_lock);
}
void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
{
int i;
@ -981,8 +979,8 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
printk(KERN_ERR "(pid %d) finish dumping heap\n", current->pid);
}
void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip)
void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip)
{
int i;
@ -999,7 +997,7 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
}
}
void dbg_dump_tnc(struct ubifs_info *c)
void ubifs_dump_tnc(struct ubifs_info *c)
{
struct ubifs_znode *znode;
int level;
@ -1014,7 +1012,7 @@ void dbg_dump_tnc(struct ubifs_info *c)
level = znode->level;
printk(KERN_ERR "== Level %d ==\n", level);
}
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
}
printk(KERN_ERR "(pid %d) finish dumping TNC tree\n", current->pid);
@ -1023,18 +1021,18 @@ void dbg_dump_tnc(struct ubifs_info *c)
static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode,
void *priv)
{
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
return 0;
}
/**
* dbg_dump_index - dump the on-flash index.
* ubifs_dump_index - dump the on-flash index.
* @c: UBIFS file-system description object
*
* This function dumps whole UBIFS indexing B-tree, unlike 'dbg_dump_tnc()'
* This function dumps whole UBIFS indexing B-tree, unlike 'ubifs_dump_tnc()'
* which dumps only in-memory znodes and does not read znodes which from flash.
*/
void dbg_dump_index(struct ubifs_info *c)
void ubifs_dump_index(struct ubifs_info *c)
{
dbg_walk_index(c, NULL, dump_znode, NULL);
}
@ -1120,15 +1118,15 @@ int dbg_check_space_info(struct ubifs_info *c)
out:
ubifs_msg("saved lprops statistics dump");
dbg_dump_lstats(&d->saved_lst);
ubifs_dump_lstats(&d->saved_lst);
ubifs_msg("saved budgeting info dump");
dbg_dump_budg(c, &d->saved_bi);
ubifs_dump_budg(c, &d->saved_bi);
ubifs_msg("saved idx_gc_cnt %d", d->saved_idx_gc_cnt);
ubifs_msg("current lprops statistics dump");
ubifs_get_lp_stats(c, &lst);
dbg_dump_lstats(&lst);
ubifs_dump_lstats(&lst);
ubifs_msg("current budgeting info dump");
dbg_dump_budg(c, &c->bi);
ubifs_dump_budg(c, &c->bi);
dump_stack();
return -EINVAL;
}
@ -1160,7 +1158,7 @@ int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
"is clean", ui->ui_size, ui->synced_i_size);
ubifs_err("i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino,
inode->i_mode, i_size_read(inode));
dbg_dump_stack();
dump_stack();
err = -EINVAL;
}
spin_unlock(&ui->ui_lock);
@ -1223,14 +1221,14 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
"but calculated size is %llu", dir->i_ino,
(unsigned long long)i_size_read(dir),
(unsigned long long)size);
dbg_dump_inode(c, dir);
ubifs_dump_inode(c, dir);
dump_stack();
return -EINVAL;
}
if (dir->i_nlink != nlink) {
ubifs_err("directory inode %lu has nlink %u, but calculated "
"nlink is %u", dir->i_ino, dir->i_nlink, nlink);
dbg_dump_inode(c, dir);
ubifs_dump_inode(c, dir);
dump_stack();
return -EINVAL;
}
@ -1287,25 +1285,25 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
err = 1;
key_read(c, &dent1->key, &key);
if (keys_cmp(c, &zbr1->key, &key)) {
dbg_err("1st entry at %d:%d has key %s", zbr1->lnum,
zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
DBG_KEY_BUF_LEN));
dbg_err("but it should have key %s according to tnc",
dbg_snprintf_key(c, &zbr1->key, key_buf,
DBG_KEY_BUF_LEN));
dbg_dump_node(c, dent1);
ubifs_err("1st entry at %d:%d has key %s", zbr1->lnum,
zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
DBG_KEY_BUF_LEN));
ubifs_err("but it should have key %s according to tnc",
dbg_snprintf_key(c, &zbr1->key, key_buf,
DBG_KEY_BUF_LEN));
ubifs_dump_node(c, dent1);
goto out_free;
}
key_read(c, &dent2->key, &key);
if (keys_cmp(c, &zbr2->key, &key)) {
dbg_err("2nd entry at %d:%d has key %s", zbr1->lnum,
zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
DBG_KEY_BUF_LEN));
dbg_err("but it should have key %s according to tnc",
dbg_snprintf_key(c, &zbr2->key, key_buf,
DBG_KEY_BUF_LEN));
dbg_dump_node(c, dent2);
ubifs_err("2nd entry at %d:%d has key %s", zbr1->lnum,
zbr1->offs, dbg_snprintf_key(c, &key, key_buf,
DBG_KEY_BUF_LEN));
ubifs_err("but it should have key %s according to tnc",
dbg_snprintf_key(c, &zbr2->key, key_buf,
DBG_KEY_BUF_LEN));
ubifs_dump_node(c, dent2);
goto out_free;
}
@ -1318,15 +1316,15 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
goto out_free;
}
if (cmp == 0 && nlen1 == nlen2)
dbg_err("2 xent/dent nodes with the same name");
ubifs_err("2 xent/dent nodes with the same name");
else
dbg_err("bad order of colliding key %s",
dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
ubifs_err("bad order of colliding key %s",
dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
ubifs_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs);
dbg_dump_node(c, dent1);
ubifs_dump_node(c, dent1);
ubifs_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs);
dbg_dump_node(c, dent2);
ubifs_dump_node(c, dent2);
out_free:
kfree(dent2);
@ -1529,10 +1527,10 @@ static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr)
out:
ubifs_err("failed, error %d", err);
ubifs_msg("dump of the znode");
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
if (zp) {
ubifs_msg("dump of the parent znode");
dbg_dump_znode(c, zp);
ubifs_dump_znode(c, zp);
}
dump_stack();
return -EINVAL;
@ -1599,9 +1597,9 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
return err;
if (err) {
ubifs_msg("first znode");
dbg_dump_znode(c, prev);
ubifs_dump_znode(c, prev);
ubifs_msg("second znode");
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
return -EINVAL;
}
}
@ -1690,7 +1688,7 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
if (err) {
ubifs_err("znode checking function returned "
"error %d", err);
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
goto out_dump;
}
}
@ -1758,7 +1756,7 @@ out_dump:
else
zbr = &c->zroot;
ubifs_msg("dump of znode at LEB %d:%d", zbr->lnum, zbr->offs);
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
out_unlock:
mutex_unlock(&c->tnc_mutex);
return err;
@ -2194,7 +2192,7 @@ out:
out_dump:
ubifs_msg("dump of node at LEB %d:%d", zbr->lnum, zbr->offs);
dbg_dump_node(c, node);
ubifs_dump_node(c, node);
out_free:
kfree(node);
return err;
@ -2352,7 +2350,7 @@ out_dump:
ubifs_msg("dump of the inode %lu sitting in LEB %d:%d",
(unsigned long)fscki->inum, zbr->lnum, zbr->offs);
dbg_dump_node(c, ino);
ubifs_dump_node(c, ino);
kfree(ino);
return -EINVAL;
}
@ -2423,12 +2421,12 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head)
if (sa->type != UBIFS_DATA_NODE) {
ubifs_err("bad node type %d", sa->type);
dbg_dump_node(c, sa->node);
ubifs_dump_node(c, sa->node);
return -EINVAL;
}
if (sb->type != UBIFS_DATA_NODE) {
ubifs_err("bad node type %d", sb->type);
dbg_dump_node(c, sb->node);
ubifs_dump_node(c, sb->node);
return -EINVAL;
}
@ -2459,8 +2457,8 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head)
return 0;
error_dump:
dbg_dump_node(c, sa->node);
dbg_dump_node(c, sb->node);
ubifs_dump_node(c, sa->node);
ubifs_dump_node(c, sb->node);
return -EINVAL;
}
@ -2491,13 +2489,13 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE &&
sa->type != UBIFS_XENT_NODE) {
ubifs_err("bad node type %d", sa->type);
dbg_dump_node(c, sa->node);
ubifs_dump_node(c, sa->node);
return -EINVAL;
}
if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE &&
sa->type != UBIFS_XENT_NODE) {
ubifs_err("bad node type %d", sb->type);
dbg_dump_node(c, sb->node);
ubifs_dump_node(c, sb->node);
return -EINVAL;
}
@ -2547,9 +2545,9 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
error_dump:
ubifs_msg("dumping first node");
dbg_dump_node(c, sa->node);
ubifs_dump_node(c, sa->node);
ubifs_msg("dumping second node");
dbg_dump_node(c, sb->node);
ubifs_dump_node(c, sb->node);
return -EINVAL;
return 0;
}
@ -2678,7 +2676,7 @@ static void cut_data(const void *buf, unsigned int len)
}
int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
int offs, int len, int dtype)
int offs, int len)
{
int err, failing;
@ -2688,7 +2686,7 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
failing = power_cut_emulated(c, lnum, 1);
if (failing)
cut_data(buf, len);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
if (err)
return err;
if (failing)
@ -2697,7 +2695,7 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
}
int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
int len, int dtype)
int len)
{
int err;
@ -2705,7 +2703,7 @@ int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
return -EROFS;
if (power_cut_emulated(c, lnum, 1))
return -EROFS;
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
err = ubi_leb_change(c->ubi, lnum, buf, len);
if (err)
return err;
if (power_cut_emulated(c, lnum, 1))
@ -2729,7 +2727,7 @@ int dbg_leb_unmap(struct ubifs_info *c, int lnum)
return 0;
}
int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
int dbg_leb_map(struct ubifs_info *c, int lnum)
{
int err;
@ -2737,7 +2735,7 @@ int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
return -EROFS;
if (power_cut_emulated(c, lnum, 0))
return -EROFS;
err = ubi_leb_map(c->ubi, lnum, dtype);
err = ubi_leb_map(c->ubi, lnum);
if (err)
return err;
if (power_cut_emulated(c, lnum, 0))
@ -2857,16 +2855,16 @@ static ssize_t dfs_file_write(struct file *file, const char __user *u,
* 'ubifs-debug' file-system instead.
*/
if (file->f_path.dentry == d->dfs_dump_lprops) {
dbg_dump_lprops(c);
ubifs_dump_lprops(c);
return count;
}
if (file->f_path.dentry == d->dfs_dump_budg) {
dbg_dump_budg(c, &c->bi);
ubifs_dump_budg(c, &c->bi);
return count;
}
if (file->f_path.dentry == d->dfs_dump_tnc) {
mutex_lock(&c->tnc_mutex);
dbg_dump_tnc(c);
ubifs_dump_tnc(c);
mutex_unlock(&c->tnc_mutex);
return count;
}
@ -3189,5 +3187,3 @@ void ubifs_debugging_exit(struct ubifs_info *c)
{
kfree(c->dbg);
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -29,8 +29,6 @@ typedef int (*dbg_leaf_callback)(struct ubifs_info *c,
typedef int (*dbg_znode_callback)(struct ubifs_info *c,
struct ubifs_znode *znode, void *priv);
#ifdef CONFIG_UBIFS_FS_DEBUG
/*
* The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi"
* + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
@ -149,7 +147,7 @@ struct ubifs_global_debug_info {
if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
dbg_dump_stack(); \
dump_stack(); \
} \
} while (0)
@ -161,12 +159,6 @@ struct ubifs_global_debug_info {
} \
} while (0)
#define dbg_dump_stack() dump_stack()
#define dbg_err(fmt, ...) do { \
ubifs_err(fmt, ##__VA_ARGS__); \
} while (0)
#define ubifs_dbg_msg(type, fmt, ...) \
pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__)
@ -257,27 +249,27 @@ const char *dbg_get_key_dump(const struct ubifs_info *c,
const union ubifs_key *key);
const char *dbg_snprintf_key(const struct ubifs_info *c,
const union ubifs_key *key, char *buffer, int len);
void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode);
void dbg_dump_node(const struct ubifs_info *c, const void *node);
void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
int offs);
void dbg_dump_budget_req(const struct ubifs_budget_req *req);
void dbg_dump_lstats(const struct ubifs_lp_stats *lst);
void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi);
void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp);
void dbg_dump_lprops(struct ubifs_info *c);
void dbg_dump_lpt_info(struct ubifs_info *c);
void dbg_dump_leb(const struct ubifs_info *c, int lnum);
void dbg_dump_sleb(const struct ubifs_info *c,
const struct ubifs_scan_leb *sleb, int offs);
void dbg_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode);
void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat);
void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip);
void dbg_dump_tnc(struct ubifs_info *c);
void dbg_dump_index(struct ubifs_info *c);
void dbg_dump_lpt_lebs(const struct ubifs_info *c);
void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode);
void ubifs_dump_node(const struct ubifs_info *c, const void *node);
void ubifs_dump_budget_req(const struct ubifs_budget_req *req);
void ubifs_dump_lstats(const struct ubifs_lp_stats *lst);
void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi);
void ubifs_dump_lprop(const struct ubifs_info *c,
const struct ubifs_lprops *lp);
void ubifs_dump_lprops(struct ubifs_info *c);
void ubifs_dump_lpt_info(struct ubifs_info *c);
void ubifs_dump_leb(const struct ubifs_info *c, int lnum);
void ubifs_dump_sleb(const struct ubifs_info *c,
const struct ubifs_scan_leb *sleb, int offs);
void ubifs_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode);
void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap,
int cat);
void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip);
void ubifs_dump_tnc(struct ubifs_info *c);
void ubifs_dump_index(struct ubifs_info *c);
void ubifs_dump_lpt_lebs(const struct ubifs_info *c);
int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
dbg_znode_callback znode_cb, void *priv);
@ -307,11 +299,10 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
int len, int dtype);
int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
int dtype);
int len);
int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len);
int dbg_leb_unmap(struct ubifs_info *c, int lnum);
int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype);
int dbg_leb_map(struct ubifs_info *c, int lnum);
/* Debugfs-related stuff */
int dbg_debugfs_init(void);
@ -319,162 +310,4 @@ void dbg_debugfs_exit(void);
int dbg_debugfs_init_fs(struct ubifs_info *c);
void dbg_debugfs_exit_fs(struct ubifs_info *c);
#else /* !CONFIG_UBIFS_FS_DEBUG */
/* Use "if (0)" to make compiler check arguments even if debugging is off */
#define ubifs_assert(expr) do { \
if (0) \
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
} while (0)
#define dbg_err(fmt, ...) do { \
if (0) \
ubifs_err(fmt, ##__VA_ARGS__); \
} while (0)
#define DBGKEY(key) ((char *)(key))
#define DBGKEY1(key) ((char *)(key))
#define ubifs_dbg_msg(fmt, ...) do { \
if (0) \
printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
} while (0)
#define dbg_dump_stack()
#define ubifs_assert_cmt_locked(c)
#define dbg_msg(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_gen(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_jnl(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_jnlk(key, fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_tnc(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_tnck(key, fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_lp(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_find(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_mnt(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_mntk(key, fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_io(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_cmt(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_budg(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_log(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_gc(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; }
static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; }
static inline const char *dbg_ntype(int type) { return ""; }
static inline const char *dbg_cstate(int cmt_state) { return ""; }
static inline const char *dbg_jhead(int jhead) { return ""; }
static inline const char *
dbg_get_key_dump(const struct ubifs_info *c,
const union ubifs_key *key) { return ""; }
static inline const char *
dbg_snprintf_key(const struct ubifs_info *c,
const union ubifs_key *key, char *buffer,
int len) { return ""; }
static inline void dbg_dump_inode(struct ubifs_info *c,
const struct inode *inode) { return; }
static inline void dbg_dump_node(const struct ubifs_info *c,
const void *node) { return; }
static inline void dbg_dump_lpt_node(const struct ubifs_info *c,
void *node, int lnum,
int offs) { return; }
static inline void
dbg_dump_budget_req(const struct ubifs_budget_req *req) { return; }
static inline void
dbg_dump_lstats(const struct ubifs_lp_stats *lst) { return; }
static inline void
dbg_dump_budg(struct ubifs_info *c,
const struct ubifs_budg_info *bi) { return; }
static inline void dbg_dump_lprop(const struct ubifs_info *c,
const struct ubifs_lprops *lp) { return; }
static inline void dbg_dump_lprops(struct ubifs_info *c) { return; }
static inline void dbg_dump_lpt_info(struct ubifs_info *c) { return; }
static inline void dbg_dump_leb(const struct ubifs_info *c,
int lnum) { return; }
static inline void
dbg_dump_sleb(const struct ubifs_info *c,
const struct ubifs_scan_leb *sleb, int offs) { return; }
static inline void
dbg_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode) { return; }
static inline void dbg_dump_heap(struct ubifs_info *c,
struct ubifs_lpt_heap *heap,
int cat) { return; }
static inline void dbg_dump_pnode(struct ubifs_info *c,
struct ubifs_pnode *pnode,
struct ubifs_nnode *parent,
int iip) { return; }
static inline void dbg_dump_tnc(struct ubifs_info *c) { return; }
static inline void dbg_dump_index(struct ubifs_info *c) { return; }
static inline void dbg_dump_lpt_lebs(const struct ubifs_info *c) { return; }
static inline int dbg_walk_index(struct ubifs_info *c,
dbg_leaf_callback leaf_cb,
dbg_znode_callback znode_cb,
void *priv) { return 0; }
static inline void dbg_save_space_info(struct ubifs_info *c) { return; }
static inline int dbg_check_space_info(struct ubifs_info *c) { return 0; }
static inline int dbg_check_lprops(struct ubifs_info *c) { return 0; }
static inline int
dbg_old_index_check_init(struct ubifs_info *c,
struct ubifs_zbranch *zroot) { return 0; }
static inline int
dbg_check_old_index(struct ubifs_info *c,
struct ubifs_zbranch *zroot) { return 0; }
static inline int dbg_check_cats(struct ubifs_info *c) { return 0; }
static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; }
static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
int action, int len) { return 0; }
static inline int
dbg_check_synced_i_size(const struct ubifs_info *c,
struct inode *inode) { return 0; }
static inline int dbg_check_dir(struct ubifs_info *c,
const struct inode *dir) { return 0; }
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
static inline int dbg_check_idx_size(struct ubifs_info *c,
long long idx_size) { return 0; }
static inline int dbg_check_filesystem(struct ubifs_info *c) { return 0; }
static inline void dbg_check_heap(struct ubifs_info *c,
struct ubifs_lpt_heap *heap,
int cat, int add_pos) { return; }
static inline int dbg_check_lpt_nodes(struct ubifs_info *c,
struct ubifs_cnode *cnode, int row, int col) { return 0; }
static inline int dbg_check_inode_size(struct ubifs_info *c,
const struct inode *inode,
loff_t size) { return 0; }
static inline int
dbg_check_data_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
static inline int
dbg_check_nondata_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
static inline int dbg_leb_write(struct ubifs_info *c, int lnum,
const void *buf, int offset,
int len, int dtype) { return 0; }
static inline int dbg_leb_change(struct ubifs_info *c, int lnum,
const void *buf, int len,
int dtype) { return 0; }
static inline int dbg_leb_unmap(struct ubifs_info *c, int lnum) { return 0; }
static inline int dbg_leb_map(struct ubifs_info *c, int lnum,
int dtype) { return 0; }
static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; }
static inline int dbg_debugfs_init(void) { return 0; }
static inline void dbg_debugfs_exit(void) { return; }
static inline int dbg_debugfs_init_fs(struct ubifs_info *c) { return 0; }
static inline int dbg_debugfs_exit_fs(struct ubifs_info *c) { return 0; }
#endif /* !CONFIG_UBIFS_FS_DEBUG */
#endif /* !__UBIFS_DEBUG_H__ */

View file

@ -170,8 +170,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
return inode;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
static int dbg_check_name(const struct ubifs_info *c,
const struct ubifs_dent_node *dent,
const struct qstr *nm)
@ -185,12 +183,6 @@ static int dbg_check_name(const struct ubifs_info *c,
return 0;
}
#else
#define dbg_check_name(c, dent, nm) 0
#endif
static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
@ -1187,12 +1179,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
.rename = ubifs_rename,
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,
#ifdef CONFIG_UBIFS_FS_XATTR
.setxattr = ubifs_setxattr,
.getxattr = ubifs_getxattr,
.listxattr = ubifs_listxattr,
.removexattr = ubifs_removexattr,
#endif
};
const struct file_operations ubifs_dir_operations = {

View file

@ -97,7 +97,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
dump:
ubifs_err("bad data node (block %u, inode %lu)",
block, inode->i_ino);
dbg_dump_node(c, dn);
ubifs_dump_node(c, dn);
return -EINVAL;
}
@ -1562,12 +1562,10 @@ const struct address_space_operations ubifs_file_address_operations = {
const struct inode_operations ubifs_file_inode_operations = {
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,
#ifdef CONFIG_UBIFS_FS_XATTR
.setxattr = ubifs_setxattr,
.getxattr = ubifs_getxattr,
.listxattr = ubifs_listxattr,
.removexattr = ubifs_removexattr,
#endif
};
const struct inode_operations ubifs_symlink_inode_operations = {

View file

@ -109,7 +109,7 @@ static int switch_gc_head(struct ubifs_info *c)
return err;
c->gc_lnum = -1;
err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0, UBI_LONGTERM);
err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0);
return err;
}

View file

@ -109,13 +109,13 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
if (err && (err != -EBADMSG || even_ebadmsg)) {
ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
len, lnum, offs, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
int len, int dtype)
int len)
{
int err;
@ -123,20 +123,19 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
if (c->ro_error)
return -EROFS;
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
else
err = dbg_leb_write(c, lnum, buf, offs, len, dtype);
err = dbg_leb_write(c, lnum, buf, offs, len);
if (err) {
ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
len, lnum, offs, err);
ubifs_ro_mode(c, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
int dtype)
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len)
{
int err;
@ -144,14 +143,14 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
if (c->ro_error)
return -EROFS;
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
err = ubi_leb_change(c->ubi, lnum, buf, len);
else
err = dbg_leb_change(c, lnum, buf, len, dtype);
err = dbg_leb_change(c, lnum, buf, len);
if (err) {
ubifs_err("changing %d bytes in LEB %d failed, error %d",
len, lnum, err);
ubifs_ro_mode(c, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
@ -170,12 +169,12 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
if (err) {
ubifs_err("unmap LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
int ubifs_leb_map(struct ubifs_info *c, int lnum)
{
int err;
@ -183,13 +182,13 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
if (c->ro_error)
return -EROFS;
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_map(c->ubi, lnum, dtype);
err = ubi_leb_map(c->ubi, lnum);
else
err = dbg_leb_map(c, lnum, dtype);
err = dbg_leb_map(c, lnum);
if (err) {
ubifs_err("mapping LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
@ -202,7 +201,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
if (err < 0) {
ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
lnum, err);
dbg_dump_stack();
dump_stack();
}
return err;
}
@ -294,8 +293,8 @@ out_len:
out:
if (!quiet) {
ubifs_err("bad node at LEB %d:%d", lnum, offs);
dbg_dump_node(c, buf);
dbg_dump_stack();
ubifs_dump_node(c, buf);
dump_stack();
}
return err;
}
@ -523,8 +522,7 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
dirt = sync_len - wbuf->used;
if (dirt)
ubifs_pad(c, wbuf->buf + wbuf->used, dirt);
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, sync_len,
wbuf->dtype);
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, sync_len);
if (err)
return err;
@ -562,14 +560,12 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
* @wbuf: write-buffer
* @lnum: logical eraseblock number to seek to
* @offs: logical eraseblock offset to seek to
* @dtype: data type
*
* This function targets the write-buffer to logical eraseblock @lnum:@offs.
* The write-buffer has to be empty. Returns zero in case of success and a
* negative error code in case of failure.
*/
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
int dtype)
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs)
{
const struct ubifs_info *c = wbuf->c;
@ -592,7 +588,6 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
wbuf->avail = wbuf->size;
wbuf->used = 0;
spin_unlock(&wbuf->lock);
wbuf->dtype = dtype;
return 0;
}
@ -719,8 +714,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_io("flush jhead %s wbuf to LEB %d:%d",
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf,
wbuf->offs, wbuf->size,
wbuf->dtype);
wbuf->offs, wbuf->size);
if (err)
goto out;
@ -756,7 +750,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs,
wbuf->size, wbuf->dtype);
wbuf->size);
if (err)
goto out;
@ -775,7 +769,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_io("write %d bytes to LEB %d:%d",
wbuf->size, wbuf->lnum, wbuf->offs);
err = ubifs_leb_write(c, wbuf->lnum, buf, wbuf->offs,
wbuf->size, wbuf->dtype);
wbuf->size);
if (err)
goto out;
@ -797,7 +791,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
wbuf->offs);
err = ubifs_leb_write(c, wbuf->lnum, buf + written,
wbuf->offs, n, wbuf->dtype);
wbuf->offs, n);
if (err)
goto out;
wbuf->offs += n;
@ -841,9 +835,9 @@ exit:
out:
ubifs_err("cannot write %d bytes to LEB %d:%d, error %d",
len, wbuf->lnum, wbuf->offs, err);
dbg_dump_node(c, buf);
dbg_dump_stack();
dbg_dump_leb(c, wbuf->lnum);
ubifs_dump_node(c, buf);
dump_stack();
ubifs_dump_leb(c, wbuf->lnum);
return err;
}
@ -854,7 +848,6 @@ out:
* @len: node length
* @lnum: logical eraseblock number
* @offs: offset within the logical eraseblock
* @dtype: node life-time hint (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
*
* This function automatically fills node magic number, assigns sequence
* number, and calculates node CRC checksum. The length of the @buf buffer has
@ -863,7 +856,7 @@ out:
* success and a negative error code in case of failure.
*/
int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
int offs, int dtype)
int offs)
{
int err, buf_len = ALIGN(len, c->min_io_size);
@ -879,9 +872,9 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
return -EROFS;
ubifs_prepare_node(c, buf, len, 1);
err = ubifs_leb_write(c, lnum, buf, offs, buf_len, dtype);
err = ubifs_leb_write(c, lnum, buf, offs, buf_len);
if (err)
dbg_dump_node(c, buf);
ubifs_dump_node(c, buf);
return err;
}
@ -960,8 +953,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
out:
ubifs_err("bad node at LEB %d:%d", lnum, offs);
dbg_dump_node(c, buf);
dbg_dump_stack();
ubifs_dump_node(c, buf);
dump_stack();
return -EINVAL;
}
@ -1017,8 +1010,8 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
out:
ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs,
ubi_is_mapped(c->ubi, lnum));
dbg_dump_node(c, buf);
dbg_dump_stack();
ubifs_dump_node(c, buf);
dump_stack();
return -EINVAL;
}
@ -1056,7 +1049,6 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf)
*/
size = c->max_write_size - (c->leb_start % c->max_write_size);
wbuf->avail = wbuf->size = size;
wbuf->dtype = UBI_UNKNOWN;
wbuf->sync_callback = NULL;
mutex_init(&wbuf->io_mutex);
spin_lock_init(&wbuf->lock);

View file

@ -214,7 +214,7 @@ out:
err = ubifs_add_bud_to_log(c, jhead, lnum, offs);
if (err)
goto out_return;
err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype);
err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs);
if (err)
goto out_unlock;
@ -385,9 +385,9 @@ out:
if (err == -ENOSPC) {
/* This are some budgeting problems, print useful information */
down_write(&c->commit_sem);
dbg_dump_stack();
dbg_dump_budg(c, &c->bi);
dbg_dump_lprops(c);
dump_stack();
ubifs_dump_budg(c, &c->bi);
ubifs_dump_lprops(c);
cmt_retries = dbg_check_lprops(c);
up_write(&c->commit_sem);
}
@ -1267,7 +1267,6 @@ out_free:
return err;
}
#ifdef CONFIG_UBIFS_FS_XATTR
/**
* ubifs_jnl_delete_xattr - delete an extended attribute.
@ -1462,4 +1461,3 @@ out_free:
return err;
}
#endif /* CONFIG_UBIFS_FS_XATTR */

View file

@ -29,11 +29,7 @@
#include "ubifs.h"
#ifdef CONFIG_UBIFS_FS_DEBUG
static int dbg_check_bud_bytes(struct ubifs_info *c);
#else
#define dbg_check_bud_bytes(c) 0
#endif
/**
* ubifs_search_bud - search bud LEB.
@ -262,7 +258,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
* an unclean reboot, because the target LEB might have been
* unmapped, but not yet physically erased.
*/
err = ubifs_leb_map(c, bud->lnum, UBI_SHORTTERM);
err = ubifs_leb_map(c, bud->lnum);
if (err)
goto out_unlock;
}
@ -270,7 +266,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
dbg_log("write ref LEB %d:%d",
c->lhead_lnum, c->lhead_offs);
err = ubifs_write_node(c, ref, UBIFS_REF_NODE_SZ, c->lhead_lnum,
c->lhead_offs, UBI_SHORTTERM);
c->lhead_offs);
if (err)
goto out_unlock;
@ -422,7 +418,7 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
len = ALIGN(len, c->min_io_size);
dbg_log("writing commit start at LEB %d:0, len %d", c->lhead_lnum, len);
err = ubifs_leb_write(c, c->lhead_lnum, cs, 0, len, UBI_SHORTTERM);
err = ubifs_leb_write(c, c->lhead_lnum, cs, 0, len);
if (err)
goto out;
@ -623,7 +619,7 @@ static int add_node(struct ubifs_info *c, void *buf, int *lnum, int *offs,
int sz = ALIGN(*offs, c->min_io_size), err;
ubifs_pad(c, buf + *offs, sz - *offs);
err = ubifs_leb_change(c, *lnum, buf, sz, UBI_SHORTTERM);
err = ubifs_leb_change(c, *lnum, buf, sz);
if (err)
return err;
*lnum = ubifs_next_log_lnum(c, *lnum);
@ -702,7 +698,7 @@ int ubifs_consolidate_log(struct ubifs_info *c)
int sz = ALIGN(offs, c->min_io_size);
ubifs_pad(c, buf + offs, sz - offs);
err = ubifs_leb_change(c, write_lnum, buf, sz, UBI_SHORTTERM);
err = ubifs_leb_change(c, write_lnum, buf, sz);
if (err)
goto out_free;
offs = ALIGN(offs, c->min_io_size);
@ -734,8 +730,6 @@ out_free:
return err;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/**
* dbg_check_bud_bytes - make sure bud bytes calculation are all right.
* @c: UBIFS file-system description object
@ -767,5 +761,3 @@ static int dbg_check_bud_bytes(struct ubifs_info *c)
return err;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -447,7 +447,7 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
int new_cat = ubifs_categorize_lprops(c, lprops);
if (old_cat == new_cat) {
struct ubifs_lpt_heap *heap = &c->lpt_heap[new_cat - 1];
struct ubifs_lpt_heap *heap;
/* lprops on a heap now must be moved up or down */
if (new_cat < 1 || new_cat > LPROPS_HEAP_CNT)
@ -846,7 +846,9 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c)
return lprops;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/*
* Everything below is related to debugging.
*/
/**
* dbg_check_cats - check category heaps and lists.
@ -1001,8 +1003,8 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
out:
if (err) {
dbg_msg("failed cat %d hpos %d err %d", cat, i, err);
dbg_dump_stack();
dbg_dump_heap(c, heap, cat);
dump_stack();
ubifs_dump_heap(c, heap, cat);
}
}
@ -1109,8 +1111,8 @@ static int scan_check_cb(struct ubifs_info *c,
if (IS_ERR(sleb)) {
ret = PTR_ERR(sleb);
if (ret == -EUCLEAN) {
dbg_dump_lprops(c);
dbg_dump_budg(c, &c->bi);
ubifs_dump_lprops(c);
ubifs_dump_budg(c, &c->bi);
}
goto out;
}
@ -1237,7 +1239,7 @@ out_print:
ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, "
"should be free %d, dirty %d",
lnum, lp->free, lp->dirty, lp->flags, free, dirty);
dbg_dump_leb(c, lnum);
ubifs_dump_leb(c, lnum);
out_destroy:
ubifs_scan_destroy(sleb);
ret = -EINVAL;
@ -1315,5 +1317,3 @@ int dbg_check_lprops(struct ubifs_info *c)
out:
return err;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -701,8 +701,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
err = ubifs_leb_change(c, lnum++, buf, alen,
UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum++, buf, alen);
if (err)
goto out;
p = buf;
@ -732,8 +731,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
set_ltab(c, lnum, c->leb_size - alen,
alen - len);
memset(p, 0xff, alen - len);
err = ubifs_leb_change(c, lnum++, buf, alen,
UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum++, buf, alen);
if (err)
goto out;
p = buf;
@ -780,8 +778,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
err = ubifs_leb_change(c, lnum++, buf, alen,
UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum++, buf, alen);
if (err)
goto out;
p = buf;
@ -806,7 +803,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum++, buf, alen);
if (err)
goto out;
p = buf;
@ -826,7 +823,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
/* Write remaining buffer */
memset(p, 0xff, alen - len);
err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum, buf, alen);
if (err)
goto out;
@ -926,7 +923,7 @@ static int check_lpt_crc(void *buf, int len)
if (crc != calc_crc) {
ubifs_err("invalid crc in LPT node: crc %hx calc %hx", crc,
calc_crc);
dbg_dump_stack();
dump_stack();
return -EINVAL;
}
return 0;
@ -949,7 +946,7 @@ static int check_lpt_type(uint8_t **addr, int *pos, int type)
if (node_type != type) {
ubifs_err("invalid type (%d) in LPT node type %d", node_type,
type);
dbg_dump_stack();
dump_stack();
return -EINVAL;
}
return 0;
@ -1247,7 +1244,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
out:
ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs);
dbg_dump_stack();
dump_stack();
kfree(nnode);
return err;
}
@ -1312,8 +1309,8 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
out:
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
dbg_dump_pnode(c, pnode, parent, iip);
dbg_dump_stack();
ubifs_dump_pnode(c, pnode, parent, iip);
dump_stack();
dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
kfree(pnode);
return err;
@ -1740,16 +1737,20 @@ int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr)
if (rd) {
err = lpt_init_rd(c);
if (err)
return err;
goto out_err;
}
if (wr) {
err = lpt_init_wr(c);
if (err)
return err;
goto out_err;
}
return 0;
out_err:
ubifs_lpt_free(c, 0);
return err;
}
/**
@ -2080,8 +2081,6 @@ out:
return err;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/**
* dbg_chk_pnode - check a pnode.
* @c: the UBIFS file-system description object
@ -2096,8 +2095,8 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
int i;
if (pnode->num != col) {
dbg_err("pnode num %d expected %d parent num %d iip %d",
pnode->num, col, pnode->parent->num, pnode->iip);
ubifs_err("pnode num %d expected %d parent num %d iip %d",
pnode->num, col, pnode->parent->num, pnode->iip);
return -EINVAL;
}
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
@ -2111,14 +2110,14 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
if (lnum >= c->leb_cnt)
continue;
if (lprops->lnum != lnum) {
dbg_err("bad LEB number %d expected %d",
lprops->lnum, lnum);
ubifs_err("bad LEB number %d expected %d",
lprops->lnum, lnum);
return -EINVAL;
}
if (lprops->flags & LPROPS_TAKEN) {
if (cat != LPROPS_UNCAT) {
dbg_err("LEB %d taken but not uncat %d",
lprops->lnum, cat);
ubifs_err("LEB %d taken but not uncat %d",
lprops->lnum, cat);
return -EINVAL;
}
continue;
@ -2130,8 +2129,8 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
case LPROPS_FRDI_IDX:
break;
default:
dbg_err("LEB %d index but cat %d",
lprops->lnum, cat);
ubifs_err("LEB %d index but cat %d",
lprops->lnum, cat);
return -EINVAL;
}
} else {
@ -2143,8 +2142,8 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
case LPROPS_FREEABLE:
break;
default:
dbg_err("LEB %d not index but cat %d",
lprops->lnum, cat);
ubifs_err("LEB %d not index but cat %d",
lprops->lnum, cat);
return -EINVAL;
}
}
@ -2184,24 +2183,24 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
break;
}
if (!found) {
dbg_err("LEB %d cat %d not found in cat heap/list",
lprops->lnum, cat);
ubifs_err("LEB %d cat %d not found in cat heap/list",
lprops->lnum, cat);
return -EINVAL;
}
switch (cat) {
case LPROPS_EMPTY:
if (lprops->free != c->leb_size) {
dbg_err("LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free,
lprops->dirty);
ubifs_err("LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free,
lprops->dirty);
return -EINVAL;
}
case LPROPS_FREEABLE:
case LPROPS_FRDI_IDX:
if (lprops->free + lprops->dirty != c->leb_size) {
dbg_err("LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free,
lprops->dirty);
ubifs_err("LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free,
lprops->dirty);
return -EINVAL;
}
}
@ -2235,9 +2234,10 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
/* cnode is a nnode */
num = calc_nnode_num(row, col);
if (cnode->num != num) {
dbg_err("nnode num %d expected %d "
"parent num %d iip %d", cnode->num, num,
(nnode ? nnode->num : 0), cnode->iip);
ubifs_err("nnode num %d expected %d "
"parent num %d iip %d",
cnode->num, num,
(nnode ? nnode->num : 0), cnode->iip);
return -EINVAL;
}
nn = (struct ubifs_nnode *)cnode;
@ -2274,5 +2274,3 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
}
return 0;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -30,11 +30,7 @@
#include <linux/random.h>
#include "ubifs.h"
#ifdef CONFIG_UBIFS_FS_DEBUG
static int dbg_populate_lsave(struct ubifs_info *c);
#else
#define dbg_populate_lsave(c) 0
#endif
/**
* first_dirty_cnode - find first dirty cnode.
@ -324,11 +320,10 @@ static int layout_cnodes(struct ubifs_info *c)
return 0;
no_space:
ubifs_err("LPT out of space");
dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, "
"done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
dbg_dump_lpt_info(c);
dbg_dump_lpt_lebs(c);
ubifs_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, "
"done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
return err;
}
@ -421,7 +416,7 @@ static int write_cnodes(struct ubifs_info *c)
alen = ALIGN(wlen, c->min_io_size);
memset(buf + offs, 0xff, alen - wlen);
err = ubifs_leb_write(c, lnum, buf + from, from,
alen, UBI_SHORTTERM);
alen);
if (err)
return err;
}
@ -479,8 +474,7 @@ static int write_cnodes(struct ubifs_info *c)
wlen = offs - from;
alen = ALIGN(wlen, c->min_io_size);
memset(buf + offs, 0xff, alen - wlen);
err = ubifs_leb_write(c, lnum, buf + from, from, alen,
UBI_SHORTTERM);
err = ubifs_leb_write(c, lnum, buf + from, from, alen);
if (err)
return err;
dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
@ -506,8 +500,7 @@ static int write_cnodes(struct ubifs_info *c)
wlen = offs - from;
alen = ALIGN(wlen, c->min_io_size);
memset(buf + offs, 0xff, alen - wlen);
err = ubifs_leb_write(c, lnum, buf + from, from, alen,
UBI_SHORTTERM);
err = ubifs_leb_write(c, lnum, buf + from, from, alen);
if (err)
return err;
dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
@ -531,7 +524,7 @@ static int write_cnodes(struct ubifs_info *c)
wlen = offs - from;
alen = ALIGN(wlen, c->min_io_size);
memset(buf + offs, 0xff, alen - wlen);
err = ubifs_leb_write(c, lnum, buf + from, from, alen, UBI_SHORTTERM);
err = ubifs_leb_write(c, lnum, buf + from, from, alen);
if (err)
return err;
@ -552,11 +545,10 @@ static int write_cnodes(struct ubifs_info *c)
return 0;
no_space:
ubifs_err("LPT out of space mismatch");
dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab "
"%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
dbg_dump_lpt_info(c);
dbg_dump_lpt_lebs(c);
ubifs_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab "
"%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
return err;
}
@ -1497,7 +1489,9 @@ void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
kfree(c->lpt_nod_buf);
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/*
* Everything below is related to debugging.
*/
/**
* dbg_is_all_ff - determine if a buffer contains only 0xFF bytes.
@ -1735,7 +1729,7 @@ int dbg_check_ltab(struct ubifs_info *c)
for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) {
err = dbg_check_ltab_lnum(c, lnum);
if (err) {
dbg_err("failed at LEB %d", lnum);
ubifs_err("failed at LEB %d", lnum);
return err;
}
}
@ -1767,10 +1761,10 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
free += c->leb_size;
}
if (free < c->lpt_sz) {
dbg_err("LPT space error: free %lld lpt_sz %lld",
free, c->lpt_sz);
dbg_dump_lpt_info(c);
dbg_dump_lpt_lebs(c);
ubifs_err("LPT space error: free %lld lpt_sz %lld",
free, c->lpt_sz);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
return -EINVAL;
}
@ -1807,13 +1801,13 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
d->chk_lpt_lebs = 0;
d->chk_lpt_wastage = 0;
if (c->dirty_pn_cnt > c->pnode_cnt) {
dbg_err("dirty pnodes %d exceed max %d",
c->dirty_pn_cnt, c->pnode_cnt);
ubifs_err("dirty pnodes %d exceed max %d",
c->dirty_pn_cnt, c->pnode_cnt);
err = -EINVAL;
}
if (c->dirty_nn_cnt > c->nnode_cnt) {
dbg_err("dirty nnodes %d exceed max %d",
c->dirty_nn_cnt, c->nnode_cnt);
ubifs_err("dirty nnodes %d exceed max %d",
c->dirty_nn_cnt, c->nnode_cnt);
err = -EINVAL;
}
return err;
@ -1830,23 +1824,23 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
chk_lpt_sz *= d->chk_lpt_lebs;
chk_lpt_sz += len - c->nhead_offs;
if (d->chk_lpt_sz != chk_lpt_sz) {
dbg_err("LPT wrote %lld but space used was %lld",
d->chk_lpt_sz, chk_lpt_sz);
ubifs_err("LPT wrote %lld but space used was %lld",
d->chk_lpt_sz, chk_lpt_sz);
err = -EINVAL;
}
if (d->chk_lpt_sz > c->lpt_sz) {
dbg_err("LPT wrote %lld but lpt_sz is %lld",
d->chk_lpt_sz, c->lpt_sz);
ubifs_err("LPT wrote %lld but lpt_sz is %lld",
d->chk_lpt_sz, c->lpt_sz);
err = -EINVAL;
}
if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) {
dbg_err("LPT layout size %lld but wrote %lld",
d->chk_lpt_sz, d->chk_lpt_sz2);
ubifs_err("LPT layout size %lld but wrote %lld",
d->chk_lpt_sz, d->chk_lpt_sz2);
err = -EINVAL;
}
if (d->chk_lpt_sz2 && d->new_nhead_offs != len) {
dbg_err("LPT new nhead offs: expected %d was %d",
d->new_nhead_offs, len);
ubifs_err("LPT new nhead offs: expected %d was %d",
d->new_nhead_offs, len);
err = -EINVAL;
}
lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
@ -1855,13 +1849,13 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
if (c->big_lpt)
lpt_sz += c->lsave_sz;
if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) {
dbg_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld",
d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz);
ubifs_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld",
d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz);
err = -EINVAL;
}
if (err) {
dbg_dump_lpt_info(c);
dbg_dump_lpt_lebs(c);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
}
d->chk_lpt_sz2 = d->chk_lpt_sz;
@ -1880,7 +1874,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
}
/**
* dbg_dump_lpt_leb - dump an LPT LEB.
* ubifs_dump_lpt_leb - dump an LPT LEB.
* @c: UBIFS file-system description object
* @lnum: LEB number to dump
*
@ -1986,13 +1980,13 @@ out:
}
/**
* dbg_dump_lpt_lebs - dump LPT lebs.
* ubifs_dump_lpt_lebs - dump LPT lebs.
* @c: UBIFS file-system description object
*
* This function dumps all LPT LEBs. The caller has to make sure the LPT is
* locked.
*/
void dbg_dump_lpt_lebs(const struct ubifs_info *c)
void ubifs_dump_lpt_lebs(const struct ubifs_info *c)
{
int i;
@ -2046,5 +2040,3 @@ static int dbg_populate_lsave(struct ubifs_info *c)
return 1;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -241,7 +241,7 @@ static int validate_master(const struct ubifs_info *c)
out:
ubifs_err("bad master node at offset %d error %d", c->mst_offs, err);
dbg_dump_node(c, c->mst_node);
ubifs_dump_node(c, c->mst_node);
return -EINVAL;
}
@ -317,7 +317,7 @@ int ubifs_read_master(struct ubifs_info *c)
if (c->leb_cnt < old_leb_cnt ||
c->leb_cnt < UBIFS_MIN_LEB_CNT) {
ubifs_err("bad leb_cnt on master node");
dbg_dump_node(c, c->mst_node);
ubifs_dump_node(c, c->mst_node);
return -EINVAL;
}
@ -379,7 +379,7 @@ int ubifs_write_master(struct ubifs_info *c)
c->mst_offs = offs;
c->mst_node->highest_inum = cpu_to_le64(c->highest_inum);
err = ubifs_write_node(c, c->mst_node, len, lnum, offs, UBI_SHORTTERM);
err = ubifs_write_node(c, c->mst_node, len, lnum, offs);
if (err)
return err;
@ -390,7 +390,7 @@ int ubifs_write_master(struct ubifs_info *c)
if (err)
return err;
}
err = ubifs_write_node(c, c->mst_node, len, lnum, offs, UBI_SHORTTERM);
err = ubifs_write_node(c, c->mst_node, len, lnum, offs);
return err;
}

View file

@ -52,11 +52,7 @@
* than the maximum number of orphans allowed.
*/
#ifdef CONFIG_UBIFS_FS_DEBUG
static int dbg_check_orphans(struct ubifs_info *c);
#else
#define dbg_check_orphans(c) 0
#endif
/**
* ubifs_add_orphan - add an orphan.
@ -92,7 +88,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
else if (inum > o->inum)
p = &(*p)->rb_right;
else {
dbg_err("orphaned twice");
ubifs_err("orphaned twice");
spin_unlock(&c->orphan_lock);
kfree(orphan);
return 0;
@ -158,8 +154,8 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
}
}
spin_unlock(&c->orphan_lock);
dbg_err("missing orphan ino %lu", (unsigned long)inum);
dbg_dump_stack();
ubifs_err("missing orphan ino %lu", (unsigned long)inum);
dump_stack();
}
/**
@ -248,8 +244,7 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
ubifs_assert(c->ohead_offs == 0);
ubifs_prepare_node(c, c->orph_buf, len, 1);
len = ALIGN(len, c->min_io_size);
err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len,
UBI_SHORTTERM);
err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len);
} else {
if (c->ohead_offs == 0) {
/* Ensure LEB has been unmapped */
@ -258,7 +253,7 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
return err;
}
err = ubifs_write_node(c, c->orph_buf, len, c->ohead_lnum,
c->ohead_offs, UBI_SHORTTERM);
c->ohead_offs);
}
return err;
}
@ -569,7 +564,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
if (snod->type != UBIFS_ORPH_NODE) {
ubifs_err("invalid node type %d in orphan area at "
"%d:%d", snod->type, sleb->lnum, snod->offs);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
return -EINVAL;
}
@ -597,7 +592,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
ubifs_err("out of order commit number %llu in "
"orphan node at %d:%d",
cmt_no, sleb->lnum, snod->offs);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
return -EINVAL;
}
dbg_rcvry("out of date LEB %d", sleb->lnum);
@ -725,7 +720,9 @@ int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only)
return err;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/*
* Everything below is related to debugging.
*/
struct check_orphan {
struct rb_node rb;
@ -968,5 +965,3 @@ out:
kfree(ci.node);
return err;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -213,10 +213,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum, mst, sz);
if (err)
goto out;
err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum + 1, mst, sz);
if (err)
goto out;
out:
@ -362,12 +362,12 @@ out_err:
out_free:
ubifs_err("failed to recover master node");
if (mst1) {
dbg_err("dumping first master node");
dbg_dump_node(c, mst1);
ubifs_err("dumping first master node");
ubifs_dump_node(c, mst1);
}
if (mst2) {
dbg_err("dumping second master node");
dbg_dump_node(c, mst2);
ubifs_err("dumping second master node");
ubifs_dump_node(c, mst2);
}
vfree(buf2);
vfree(buf1);
@ -555,8 +555,7 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
ubifs_pad(c, buf, pad_len);
}
}
err = ubifs_leb_change(c, lnum, sleb->buf, len,
UBI_UNKNOWN);
err = ubifs_leb_change(c, lnum, sleb->buf, len);
if (err)
return err;
}
@ -683,7 +682,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
ret, lnum, offs);
break;
} else {
dbg_err("unexpected return value %d", ret);
ubifs_err("unexpected return value %d", ret);
err = -EINVAL;
goto error;
}
@ -789,7 +788,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
corrupted_rescan:
/* Re-scan the corrupted data with verbose messages */
dbg_err("corruptio %d", ret);
ubifs_err("corruptio %d", ret);
ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
corrupted:
ubifs_scanned_corruption(c, lnum, offs, buf);
@ -827,17 +826,17 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
goto out_free;
ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
if (ret != SCANNED_A_NODE) {
dbg_err("Not a valid node");
ubifs_err("Not a valid node");
goto out_err;
}
if (cs_node->ch.node_type != UBIFS_CS_NODE) {
dbg_err("Node a CS node, type is %d", cs_node->ch.node_type);
ubifs_err("Node a CS node, type is %d", cs_node->ch.node_type);
goto out_err;
}
if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) {
dbg_err("CS node cmt_no %llu != current cmt_no %llu",
(unsigned long long)le64_to_cpu(cs_node->cmt_no),
c->cmt_no);
ubifs_err("CS node cmt_no %llu != current cmt_no %llu",
(unsigned long long)le64_to_cpu(cs_node->cmt_no),
c->cmt_no);
goto out_err;
}
*cs_sqnum = le64_to_cpu(cs_node->ch.sqnum);
@ -941,7 +940,7 @@ static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
if (err)
return err;
return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN);
return ubifs_leb_change(c, lnum, sbuf, offs);
}
return 0;
@ -1071,7 +1070,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c,
}
/* Write back the LEB atomically */
err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN);
err = ubifs_leb_change(c, lnum, sbuf, len);
if (err)
return err;
@ -1138,9 +1137,9 @@ static int grab_empty_leb(struct ubifs_info *c)
*/
lnum = ubifs_find_free_leb_for_idx(c);
if (lnum < 0) {
dbg_err("could not find an empty LEB");
dbg_dump_lprops(c);
dbg_dump_budg(c, &c->bi);
ubifs_err("could not find an empty LEB");
ubifs_dump_lprops(c);
ubifs_dump_budg(c, &c->bi);
return lnum;
}
@ -1218,7 +1217,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
}
mutex_unlock(&wbuf->io_mutex);
if (err < 0) {
dbg_err("GC failed, error %d", err);
ubifs_err("GC failed, error %d", err);
if (err == -EAGAIN)
err = -EINVAL;
return err;
@ -1472,7 +1471,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
len -= 1;
len = ALIGN(len + 1, c->min_io_size);
/* Atomically write the fixed LEB back again */
err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
err = ubifs_leb_change(c, lnum, c->sbuf, len);
if (err)
goto out;
dbg_rcvry("inode %lu at %d:%d size %lld -> %lld",

View file

@ -154,8 +154,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b)
/* Make sure the journal head points to the latest bud */
err = ubifs_wbuf_seek_nolock(&c->jheads[b->bud->jhead].wbuf,
b->bud->lnum, c->leb_size - b->free,
UBI_SHORTTERM);
b->bud->lnum, c->leb_size - b->free);
out:
ubifs_release_lprops(c);
@ -686,7 +685,7 @@ out:
out_dump:
ubifs_err("bad node is at LEB %d:%d", lnum, snod->offs);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
ubifs_scan_destroy(sleb);
return -EINVAL;
}
@ -861,16 +860,16 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
* numbers.
*/
if (snod->type != UBIFS_CS_NODE) {
dbg_err("first log node at LEB %d:%d is not CS node",
lnum, offs);
ubifs_err("first log node at LEB %d:%d is not CS node",
lnum, offs);
goto out_dump;
}
if (le64_to_cpu(node->cmt_no) != c->cmt_no) {
dbg_err("first CS node at LEB %d:%d has wrong "
"commit number %llu expected %llu",
lnum, offs,
(unsigned long long)le64_to_cpu(node->cmt_no),
c->cmt_no);
ubifs_err("first CS node at LEB %d:%d has wrong "
"commit number %llu expected %llu",
lnum, offs,
(unsigned long long)le64_to_cpu(node->cmt_no),
c->cmt_no);
goto out_dump;
}
@ -892,7 +891,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
/* Make sure the first node sits at offset zero of the LEB */
if (snod->offs != 0) {
dbg_err("first node is not at zero offset");
ubifs_err("first node is not at zero offset");
goto out_dump;
}
@ -905,8 +904,8 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
}
if (snod->sqnum < c->cs_sqnum) {
dbg_err("bad sqnum %llu, commit sqnum %llu",
snod->sqnum, c->cs_sqnum);
ubifs_err("bad sqnum %llu, commit sqnum %llu",
snod->sqnum, c->cs_sqnum);
goto out_dump;
}
@ -958,7 +957,7 @@ out:
out_dump:
ubifs_err("log error detected while replaying the log at LEB %d:%d",
lnum, offs + snod->offs);
dbg_dump_node(c, snod->node);
ubifs_dump_node(c, snod->node);
ubifs_scan_destroy(sleb);
return -EINVAL;
}

View file

@ -130,7 +130,6 @@ static int create_default_filesystem(struct ubifs_info *c)
* orphan node.
*/
orph_lebs = UBIFS_MIN_ORPH_LEBS;
#ifdef CONFIG_UBIFS_FS_DEBUG
if (c->leb_cnt - min_leb_cnt > 1)
/*
* For debugging purposes it is better to have at least 2
@ -138,7 +137,6 @@ static int create_default_filesystem(struct ubifs_info *c)
* consolidations and would be stressed more.
*/
orph_lebs += 1;
#endif
main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS - log_lebs;
main_lebs -= orph_lebs;
@ -196,7 +194,7 @@ static int create_default_filesystem(struct ubifs_info *c)
sup->rp_size = cpu_to_le64(tmp64);
sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION);
err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM);
err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0);
kfree(sup);
if (err)
return err;
@ -252,14 +250,13 @@ static int create_default_filesystem(struct ubifs_info *c)
mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ);
err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0,
UBI_UNKNOWN);
err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0);
if (err) {
kfree(mst);
return err;
}
err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, 0,
UBI_UNKNOWN);
err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1,
0);
kfree(mst);
if (err)
return err;
@ -282,8 +279,7 @@ static int create_default_filesystem(struct ubifs_info *c)
key_write_idx(c, &key, &br->key);
br->lnum = cpu_to_le32(main_first + DEFAULT_DATA_LEB);
br->len = cpu_to_le32(UBIFS_INO_NODE_SZ);
err = ubifs_write_node(c, idx, tmp, main_first + DEFAULT_IDX_LEB, 0,
UBI_UNKNOWN);
err = ubifs_write_node(c, idx, tmp, main_first + DEFAULT_IDX_LEB, 0);
kfree(idx);
if (err)
return err;
@ -315,8 +311,7 @@ static int create_default_filesystem(struct ubifs_info *c)
ino->flags = cpu_to_le32(UBIFS_COMPR_FL);
err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ,
main_first + DEFAULT_DATA_LEB, 0,
UBI_UNKNOWN);
main_first + DEFAULT_DATA_LEB, 0);
kfree(ino);
if (err)
return err;
@ -335,8 +330,7 @@ static int create_default_filesystem(struct ubifs_info *c)
return -ENOMEM;
cs->ch.node_type = UBIFS_CS_NODE;
err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM,
0, UBI_UNKNOWN);
err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0);
kfree(cs);
ubifs_msg("default file-system created");
@ -475,7 +469,7 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
failed:
ubifs_err("bad superblock, error %d", err);
dbg_dump_node(c, sup);
ubifs_dump_node(c, sup);
return -EINVAL;
}
@ -518,7 +512,7 @@ int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup)
int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size);
ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1);
return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len, UBI_LONGTERM);
return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len);
}
/**
@ -691,7 +685,7 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
if (err)
return err;
return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
return ubifs_leb_change(c, lnum, c->sbuf, len);
}
/**

View file

@ -101,7 +101,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
if (!quiet) {
ubifs_err("bad pad node at LEB %d:%d",
lnum, offs);
dbg_dump_node(c, pad);
ubifs_dump_node(c, pad);
}
return SCANNED_A_BAD_PAD_NODE;
}
@ -109,8 +109,8 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
/* Make the node pads to 8-byte boundary */
if ((node_len + pad_len) & 7) {
if (!quiet)
dbg_err("bad padding length %d - %d",
offs, offs + node_len + pad_len);
ubifs_err("bad padding length %d - %d",
offs, offs + node_len + pad_len);
return SCANNED_A_BAD_PAD_NODE;
}
@ -245,7 +245,7 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
len = c->leb_size - offs;
if (len > 8192)
len = 8192;
dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs);
ubifs_err("first %d bytes from LEB %d:%d", len, lnum, offs);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1);
}
@ -300,16 +300,16 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
switch (ret) {
case SCANNED_GARBAGE:
dbg_err("garbage");
ubifs_err("garbage");
goto corrupted;
case SCANNED_A_NODE:
break;
case SCANNED_A_CORRUPT_NODE:
case SCANNED_A_BAD_PAD_NODE:
dbg_err("bad node");
ubifs_err("bad node");
goto corrupted;
default:
dbg_err("unknown");
ubifs_err("unknown");
err = -EINVAL;
goto error;
}

View file

@ -246,8 +246,8 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
out_invalid:
ubifs_err("inode %lu validation failed, error %d", inode->i_ino, err);
dbg_dump_node(c, ino);
dbg_dump_inode(c, inode);
ubifs_dump_node(c, ino);
ubifs_dump_inode(c, inode);
err = -EINVAL;
out_ino:
kfree(ino);
@ -668,8 +668,8 @@ static int init_constants_sb(struct ubifs_info *c)
tmp = UBIFS_CS_NODE_SZ + UBIFS_REF_NODE_SZ * c->jhead_cnt;
tmp = ALIGN(tmp, c->min_io_size);
if (tmp > c->leb_size) {
dbg_err("too small LEB size %d, at least %d needed",
c->leb_size, tmp);
ubifs_err("too small LEB size %d, at least %d needed",
c->leb_size, tmp);
return -EINVAL;
}
@ -683,8 +683,8 @@ static int init_constants_sb(struct ubifs_info *c)
tmp /= c->leb_size;
tmp += 1;
if (c->log_lebs < tmp) {
dbg_err("too small log %d LEBs, required min. %d LEBs",
c->log_lebs, tmp);
ubifs_err("too small log %d LEBs, required min. %d LEBs",
c->log_lebs, tmp);
return -EINVAL;
}
@ -813,13 +813,10 @@ static int alloc_wbufs(struct ubifs_info *c)
c->jheads[i].grouped = 1;
}
c->jheads[BASEHD].wbuf.dtype = UBI_SHORTTERM;
/*
* Garbage Collector head likely contains long-term data and
* does not need to be synchronized by timer. Also GC head nodes are
* not grouped.
* Garbage Collector head does not need to be synchronized by timer.
* Also GC head nodes are not grouped.
*/
c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM;
c->jheads[GCHD].wbuf.no_timer = 1;
c->jheads[GCHD].grouped = 0;
@ -863,7 +860,7 @@ static void free_orphans(struct ubifs_info *c)
orph = list_entry(c->orph_list.next, struct ubifs_orphan, list);
list_del(&orph->list);
kfree(orph);
dbg_err("orphan list not empty at unmount");
ubifs_err("orphan list not empty at unmount");
}
vfree(c->orph_buf);
@ -1147,8 +1144,8 @@ static int check_free_space(struct ubifs_info *c)
ubifs_assert(c->dark_wm > 0);
if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) {
ubifs_err("insufficient free space to mount in R/W mode");
dbg_dump_budg(c, &c->bi);
dbg_dump_lprops(c);
ubifs_dump_budg(c, &c->bi);
ubifs_dump_lprops(c);
return -ENOSPC;
}
return 0;
@ -1301,7 +1298,7 @@ static int mount_ubifs(struct ubifs_info *c)
if (!c->ro_mount && c->space_fixup) {
err = ubifs_fixup_free_space(c);
if (err)
goto out_master;
goto out_lpt;
}
if (!c->ro_mount) {
@ -2126,8 +2123,8 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags,
*/
ubi = open_ubi(name, UBI_READONLY);
if (IS_ERR(ubi)) {
dbg_err("cannot open \"%s\", error %d",
name, (int)PTR_ERR(ubi));
ubifs_err("cannot open \"%s\", error %d",
name, (int)PTR_ERR(ubi));
return ERR_CAST(ubi);
}

View file

@ -339,8 +339,8 @@ static int lnc_add(struct ubifs_info *c, struct ubifs_zbranch *zbr,
err = ubifs_validate_entry(c, dent);
if (err) {
dbg_dump_stack();
dbg_dump_node(c, dent);
dump_stack();
ubifs_dump_node(c, dent);
return err;
}
@ -372,8 +372,8 @@ static int lnc_add_directly(struct ubifs_info *c, struct ubifs_zbranch *zbr,
err = ubifs_validate_entry(c, node);
if (err) {
dbg_dump_stack();
dbg_dump_node(c, node);
dump_stack();
ubifs_dump_node(c, node);
return err;
}
@ -1733,8 +1733,8 @@ out_err:
err = -EINVAL;
out:
ubifs_err("bad node at LEB %d:%d", zbr->lnum, zbr->offs);
dbg_dump_node(c, buf);
dbg_dump_stack();
ubifs_dump_node(c, buf);
dump_stack();
return err;
}
@ -1775,7 +1775,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
if (err && err != -EBADMSG) {
ubifs_err("failed to read from LEB %d:%d, error %d",
lnum, offs, err);
dbg_dump_stack();
dump_stack();
dbg_tnck(&bu->key, "key ");
return err;
}
@ -2403,7 +2403,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
err = ubifs_add_dirt(c, zbr->lnum, zbr->len);
if (err) {
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
return err;
}
@ -2649,7 +2649,7 @@ int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key,
err = ubifs_add_dirt(c, znode->zbranch[i].lnum,
znode->zbranch[i].len);
if (err) {
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
goto out_unlock;
}
dbg_tnck(key, "removing key ");
@ -3275,8 +3275,6 @@ out_unlock:
return err;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/**
* dbg_check_inode_size - check if inode size is correct.
* @c: UBIFS file-system description object
@ -3335,13 +3333,11 @@ out_dump:
(unsigned long)inode->i_ino, size,
((loff_t)block) << UBIFS_BLOCK_SHIFT);
mutex_unlock(&c->tnc_mutex);
dbg_dump_inode(c, inode);
dbg_dump_stack();
ubifs_dump_inode(c, inode);
dump_stack();
return -EINVAL;
out_unlock:
mutex_unlock(&c->tnc_mutex);
return err;
}
#endif /* CONFIG_UBIFS_FS_DEBUG */

View file

@ -54,18 +54,16 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
br->len = cpu_to_le32(zbr->len);
if (!zbr->lnum || !zbr->len) {
ubifs_err("bad ref in znode");
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
if (zbr->znode)
dbg_dump_znode(c, zbr->znode);
ubifs_dump_znode(c, zbr->znode);
}
}
ubifs_prepare_node(c, idx, len, 0);
#ifdef CONFIG_UBIFS_FS_DEBUG
znode->lnum = lnum;
znode->offs = offs;
znode->len = len;
#endif
err = insert_old_idx_znode(c, znode);
@ -322,8 +320,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p)
0, 0, 0);
if (err)
return err;
err = ubifs_leb_change(c, lnum, c->ileb_buf, c->ileb_len,
UBI_SHORTTERM);
err = ubifs_leb_change(c, lnum, c->ileb_buf, c->ileb_len);
if (err)
return err;
dbg_gc("LEB %d wrote %d index nodes", lnum, tot_written);
@ -388,8 +385,8 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
* option which forces in-the-gaps is enabled.
*/
ubifs_warn("out of space");
dbg_dump_budg(c, &c->bi);
dbg_dump_lprops(c);
ubifs_dump_budg(c, &c->bi);
ubifs_dump_lprops(c);
}
/* Try to commit anyway */
err = 0;
@ -456,11 +453,9 @@ static int layout_in_empty_space(struct ubifs_info *c)
offs = buf_offs + used;
#ifdef CONFIG_UBIFS_FS_DEBUG
znode->lnum = lnum;
znode->offs = offs;
znode->len = len;
#endif
/* Update the parent */
zp = znode->parent;
@ -536,10 +531,8 @@ static int layout_in_empty_space(struct ubifs_info *c)
break;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
c->dbg->new_ihead_lnum = lnum;
c->dbg->new_ihead_offs = buf_offs;
#endif
return 0;
}
@ -864,9 +857,9 @@ static int write_index(struct ubifs_info *c)
br->len = cpu_to_le32(zbr->len);
if (!zbr->lnum || !zbr->len) {
ubifs_err("bad ref in znode");
dbg_dump_znode(c, znode);
ubifs_dump_znode(c, znode);
if (zbr->znode)
dbg_dump_znode(c, zbr->znode);
ubifs_dump_znode(c, zbr->znode);
}
}
len = ubifs_idx_node_sz(c, znode->child_cnt);
@ -881,13 +874,11 @@ static int write_index(struct ubifs_info *c)
}
offs = buf_offs + used;
#ifdef CONFIG_UBIFS_FS_DEBUG
if (lnum != znode->lnum || offs != znode->offs ||
len != znode->len) {
ubifs_err("inconsistent znode posn");
return -EINVAL;
}
#endif
/* Grab some stuff from znode while we still can */
cnext = znode->cnext;
@ -959,8 +950,7 @@ static int write_index(struct ubifs_info *c)
}
/* The buffer is full or there are no more znodes to do */
err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, blen,
UBI_SHORTTERM);
err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, blen);
if (err)
return err;
buf_offs += blen;
@ -982,13 +972,11 @@ static int write_index(struct ubifs_info *c)
break;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
if (lnum != c->dbg->new_ihead_lnum ||
buf_offs != c->dbg->new_ihead_offs) {
ubifs_err("inconsistent ihead");
return -EINVAL;
}
#endif
c->ihead_lnum = lnum;
c->ihead_offs = buf_offs;

View file

@ -293,10 +293,10 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
lnum, offs, znode->level, znode->child_cnt);
if (znode->child_cnt > c->fanout || znode->level > UBIFS_MAX_LEVELS) {
dbg_err("current fanout %d, branch count %d",
c->fanout, znode->child_cnt);
dbg_err("max levels %d, znode level %d",
UBIFS_MAX_LEVELS, znode->level);
ubifs_err("current fanout %d, branch count %d",
c->fanout, znode->child_cnt);
ubifs_err("max levels %d, znode level %d",
UBIFS_MAX_LEVELS, znode->level);
err = 1;
goto out_dump;
}
@ -316,7 +316,7 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
if (zbr->lnum < c->main_first ||
zbr->lnum >= c->leb_cnt || zbr->offs < 0 ||
zbr->offs + zbr->len > c->leb_size || zbr->offs & 7) {
dbg_err("bad branch %d", i);
ubifs_err("bad branch %d", i);
err = 2;
goto out_dump;
}
@ -340,19 +340,19 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
type = key_type(c, &zbr->key);
if (c->ranges[type].max_len == 0) {
if (zbr->len != c->ranges[type].len) {
dbg_err("bad target node (type %d) length (%d)",
type, zbr->len);
dbg_err("have to be %d", c->ranges[type].len);
ubifs_err("bad target node (type %d) length (%d)",
type, zbr->len);
ubifs_err("have to be %d", c->ranges[type].len);
err = 4;
goto out_dump;
}
} else if (zbr->len < c->ranges[type].min_len ||
zbr->len > c->ranges[type].max_len) {
dbg_err("bad target node (type %d) length (%d)",
type, zbr->len);
dbg_err("have to be in range of %d-%d",
c->ranges[type].min_len,
c->ranges[type].max_len);
ubifs_err("bad target node (type %d) length (%d)",
type, zbr->len);
ubifs_err("have to be in range of %d-%d",
c->ranges[type].min_len,
c->ranges[type].max_len);
err = 5;
goto out_dump;
}
@ -370,13 +370,13 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
cmp = keys_cmp(c, key1, key2);
if (cmp > 0) {
dbg_err("bad key order (keys %d and %d)", i, i + 1);
ubifs_err("bad key order (keys %d and %d)", i, i + 1);
err = 6;
goto out_dump;
} else if (cmp == 0 && !is_hash_key(c, key1)) {
/* These can only be keys with colliding hash */
dbg_err("keys %d and %d are not hashed but equivalent",
i, i + 1);
ubifs_err("keys %d and %d are not hashed but equivalent",
i, i + 1);
err = 7;
goto out_dump;
}
@ -387,7 +387,7 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
out_dump:
ubifs_err("bad indexing node at LEB %d:%d, error %d", lnum, offs, err);
dbg_dump_node(c, idx);
ubifs_dump_node(c, idx);
kfree(idx);
return -EINVAL;
}
@ -486,7 +486,7 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
zbr->lnum, zbr->offs);
dbg_tnck(key, "looked for key ");
dbg_tnck(&key1, "but found node's key ");
dbg_dump_node(c, node);
ubifs_dump_node(c, node);
return -EINVAL;
}

View file

@ -650,8 +650,6 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c,
* @avail: number of bytes available in the write-buffer
* @used: number of used bytes in the write-buffer
* @size: write-buffer size (in [@c->min_io_size, @c->max_write_size] range)
* @dtype: type of data stored in this LEB (%UBI_LONGTERM, %UBI_SHORTTERM,
* %UBI_UNKNOWN)
* @jhead: journal head the mutex belongs to (note, needed only to shut lockdep
* up by 'mutex_lock_nested()).
* @sync_callback: write-buffer synchronization callback
@ -685,7 +683,6 @@ struct ubifs_wbuf {
int avail;
int used;
int size;
int dtype;
int jhead;
int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad);
struct mutex io_mutex;
@ -762,6 +759,9 @@ struct ubifs_zbranch {
* @offs: offset of the corresponding indexing node
* @len: length of the corresponding indexing node
* @zbranch: array of znode branches (@c->fanout elements)
*
* Note! The @lnum, @offs, and @len fields are not really needed - we have them
* only for internal consistency check. They could be removed to save some RAM.
*/
struct ubifs_znode {
struct ubifs_znode *parent;
@ -772,9 +772,9 @@ struct ubifs_znode {
int child_cnt;
int iip;
int alt;
#ifdef CONFIG_UBIFS_FS_DEBUG
int lnum, offs, len;
#endif
int lnum;
int offs;
int len;
struct ubifs_zbranch zbranch[];
};
@ -1444,9 +1444,7 @@ struct ubifs_info {
struct rb_root size_tree;
struct ubifs_mount_opts mount_opts;
#ifdef CONFIG_UBIFS_FS_DEBUG
struct ubifs_debug_info *dbg;
#endif
};
extern struct list_head ubifs_infos;
@ -1468,22 +1466,20 @@ void ubifs_ro_mode(struct ubifs_info *c, int err);
int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
int len, int even_ebadmsg);
int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
int len, int dtype);
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
int dtype);
int len);
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len);
int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
int ubifs_leb_map(struct ubifs_info *c, int lnum);
int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
int dtype);
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs);
int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf);
int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
int lnum, int offs);
int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
int lnum, int offs);
int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum,
int offs, int dtype);
int offs);
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
int offs, int quiet, int must_chk_crc);
void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);

View file

@ -399,8 +399,8 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
if (buf) {
/* If @buf is %NULL we are supposed to return the length */
if (ui->data_len > size) {
dbg_err("buffer size %zd, xattr len %d",
size, ui->data_len);
ubifs_err("buffer size %zd, xattr len %d",
size, ui->data_len);
err = -ERANGE;
goto out_iput;
}

View file

@ -25,6 +25,9 @@
#include <linux/types.h>
#include <mtd/ubi-user.h>
/* All voumes/LEBs */
#define UBI_ALL -1
/*
* enum ubi_open_mode - UBI volume open mode constants.
*
@ -208,14 +211,15 @@ void ubi_close_volume(struct ubi_volume_desc *desc);
int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
int len, int check);
int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
int offset, int len, int dtype);
int offset, int len);
int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len, int dtype);
int len);
int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum);
int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum);
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype);
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum);
int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
int ubi_sync(int ubi_num);
int ubi_flush(int ubi_num, int vol_id, int lnum);
/*
* This function is the same as the 'ubi_leb_read()' function, but it does not
@ -226,25 +230,4 @@ static inline int ubi_read(struct ubi_volume_desc *desc, int lnum, char *buf,
{
return ubi_leb_read(desc, lnum, buf, offset, len, 0);
}
/*
* This function is the same as the 'ubi_leb_write()' functions, but it does
* not have the data type argument.
*/
static inline int ubi_write(struct ubi_volume_desc *desc, int lnum,
const void *buf, int offset, int len)
{
return ubi_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN);
}
/*
* This function is the same as the 'ubi_leb_change()' functions, but it does
* not have the data type argument.
*/
static inline int ubi_change(struct ubi_volume_desc *desc, int lnum,
const void *buf, int len)
{
return ubi_leb_change(desc, lnum, buf, len, UBI_UNKNOWN);
}
#endif /* !__LINUX_UBI_H__ */

View file

@ -195,23 +195,6 @@
/* Maximum amount of UBI volumes that can be re-named at one go */
#define UBI_MAX_RNVOL 32
/*
* UBI data type hint constants.
*
* UBI_LONGTERM: long-term data
* UBI_SHORTTERM: short-term data
* UBI_UNKNOWN: data persistence is unknown
*
* These constants are used when data is written to UBI volumes in order to
* help the UBI wear-leveling unit to find more appropriate physical
* eraseblocks.
*/
enum {
UBI_LONGTERM = 1,
UBI_SHORTTERM = 2,
UBI_UNKNOWN = 3,
};
/*
* UBI volume type constants.
*
@ -375,25 +358,34 @@ struct ubi_rnvol_req {
* requests.
* @lnum: logical eraseblock number to change
* @bytes: how many bytes will be written to the logical eraseblock
* @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
* @dtype: pass "3" for better compatibility with old kernels
* @padding: reserved for future, not used, has to be zeroed
*
* The @dtype field used to inform UBI about what kind of data will be written
* to the LEB: long term (value 1), short term (value 2), unknown (value 3).
* UBI tried to pick a PEB with lower erase counter for short term data and a
* PEB with higher erase counter for long term data. But this was not really
* used because users usually do not know this and could easily mislead UBI. We
* removed this feature in May 2012. UBI currently just ignores the @dtype
* field. But for better compatibility with older kernels it is recommended to
* set @dtype to 3 (unknown).
*/
struct ubi_leb_change_req {
__s32 lnum;
__s32 bytes;
__s8 dtype;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[7];
} __packed;
/**
* struct ubi_map_req - a data structure used in map LEB requests.
* @dtype: pass "3" for better compatibility with old kernels
* @lnum: logical eraseblock number to unmap
* @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
* @padding: reserved for future, not used, has to be zeroed
*/
struct ubi_map_req {
__s32 lnum;
__s8 dtype;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[3];
} __packed;