Commit 23a3e178 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull UBI/UBIFS updates from Richard Weinberger:
 "This contains mostly cleanups and minor improvements of UBI and UBIFS"

* tag 'upstream-4.7-rc1' of git://git.infradead.org/linux-ubifs:
  ubifs: ubifs_dump_inode: Fix dumping field bulk_read
  UBI: Fix static volume checks when Fastmap is used
  UBI: Set free_count to zero before walking through erase list
  UBI: Silence an unintialized variable warning
  UBI: Clean up return in ubi_remove_volume()
  UBI: Modify wrong comment in ubi_leb_map function.
  UBI: Don't read back all data in ubi_eba_copy_leb()
  UBI: Add ro-mode sysfs attribute
parents e0714ec4 1112018c
...@@ -107,6 +107,15 @@ Contact: Artem Bityutskiy <dedekind@infradead.org> ...@@ -107,6 +107,15 @@ Contact: Artem Bityutskiy <dedekind@infradead.org>
Description: Description:
Number of physical eraseblocks reserved for bad block handling. Number of physical eraseblocks reserved for bad block handling.
What: /sys/class/ubi/ubiX/ro_mode
Date: April 2016
KernelVersion: 4.7
Contact: linux-mtd@lists.infradead.org
Description:
Contains ASCII "1\n" if the read-only flag is set on this
device, and "0\n" if it is cleared. UBI devices mark themselves
as read-only when they detect an unrecoverable error.
What: /sys/class/ubi/ubiX/total_eraseblocks What: /sys/class/ubi/ubiX/total_eraseblocks
Date: July 2006 Date: July 2006
KernelVersion: 2.6.22 KernelVersion: 2.6.22
......
...@@ -149,6 +149,8 @@ static struct device_attribute dev_bgt_enabled = ...@@ -149,6 +149,8 @@ static struct device_attribute dev_bgt_enabled =
__ATTR(bgt_enabled, S_IRUGO, dev_attribute_show, NULL); __ATTR(bgt_enabled, S_IRUGO, dev_attribute_show, NULL);
static struct device_attribute dev_mtd_num = static struct device_attribute dev_mtd_num =
__ATTR(mtd_num, S_IRUGO, dev_attribute_show, NULL); __ATTR(mtd_num, S_IRUGO, dev_attribute_show, NULL);
static struct device_attribute dev_ro_mode =
__ATTR(ro_mode, S_IRUGO, dev_attribute_show, NULL);
/** /**
* ubi_volume_notify - send a volume change notification. * ubi_volume_notify - send a volume change notification.
...@@ -385,6 +387,8 @@ static ssize_t dev_attribute_show(struct device *dev, ...@@ -385,6 +387,8 @@ static ssize_t dev_attribute_show(struct device *dev,
ret = sprintf(buf, "%d\n", ubi->thread_enabled); ret = sprintf(buf, "%d\n", ubi->thread_enabled);
else if (attr == &dev_mtd_num) else if (attr == &dev_mtd_num)
ret = sprintf(buf, "%d\n", ubi->mtd->index); ret = sprintf(buf, "%d\n", ubi->mtd->index);
else if (attr == &dev_ro_mode)
ret = sprintf(buf, "%d\n", ubi->ro_mode);
else else
ret = -EINVAL; ret = -EINVAL;
...@@ -404,6 +408,7 @@ static struct attribute *ubi_dev_attrs[] = { ...@@ -404,6 +408,7 @@ static struct attribute *ubi_dev_attrs[] = {
&dev_min_io_size.attr, &dev_min_io_size.attr,
&dev_bgt_enabled.attr, &dev_bgt_enabled.attr,
&dev_mtd_num.attr, &dev_mtd_num.attr,
&dev_ro_mode.attr,
NULL NULL
}; };
ATTRIBUTE_GROUPS(ubi_dev); ATTRIBUTE_GROUPS(ubi_dev);
......
...@@ -352,7 +352,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ...@@ -352,7 +352,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
} else if (dent == d->dfs_emulate_power_cut) { } else if (dent == d->dfs_emulate_power_cut) {
if (kstrtoint(buf, 0, &val) != 0) if (kstrtoint(buf, 0, &val) != 0)
count = -EINVAL; count = -EINVAL;
d->emulate_power_cut = val; else
d->emulate_power_cut = val;
goto out; goto out;
} }
......
...@@ -426,8 +426,25 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, ...@@ -426,8 +426,25 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
pnum, vol_id, lnum); pnum, vol_id, lnum);
err = -EBADMSG; err = -EBADMSG;
} else { } else {
err = -EINVAL; /*
ubi_ro_mode(ubi); * Ending up here in the non-Fastmap case
* is a clear bug as the VID header had to
* be present at scan time to have it referenced.
* With fastmap the story is more complicated.
* Fastmap has the mapping info without the need
* of a full scan. So the LEB could have been
* unmapped, Fastmap cannot know this and keeps
* the LEB referenced.
* This is valid and works as the layer above UBI
* has to do bookkeeping about used/referenced
* LEBs in any case.
*/
if (ubi->fast_attach) {
err = -EBADMSG;
} else {
err = -EINVAL;
ubi_ro_mode(ubi);
}
} }
} }
goto out_free; goto out_free;
...@@ -1202,32 +1219,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1202,32 +1219,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
} }
cond_resched(); cond_resched();
/*
* We've written the data and are going to read it back to make
* sure it was written correctly.
*/
memset(ubi->peb_buf, 0xFF, aldata_size);
err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size);
if (err) {
if (err != UBI_IO_BITFLIPS) {
ubi_warn(ubi, "error %d while reading data back from PEB %d",
err, to);
if (is_error_sane(err))
err = MOVE_TARGET_RD_ERR;
} else
err = MOVE_TARGET_BITFLIPS;
goto out_unlock_buf;
}
cond_resched();
if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) {
ubi_warn(ubi, "read data back from PEB %d and it is different",
to);
err = -EINVAL;
goto out_unlock_buf;
}
} }
ubi_assert(vol->eba_tbl[lnum] == from); ubi_assert(vol->eba_tbl[lnum] == from);
......
...@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
ubi_msg(ubi, "fastmap WL pool size: %d", ubi_msg(ubi, "fastmap WL pool size: %d",
ubi->fm_wl_pool.max_size); ubi->fm_wl_pool.max_size);
ubi->fm_disabled = 0; ubi->fm_disabled = 0;
ubi->fast_attach = 1;
ubi_free_vid_hdr(ubi, vh); ubi_free_vid_hdr(ubi, vh);
kfree(ech); kfree(ech);
......
...@@ -705,7 +705,7 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum) ...@@ -705,7 +705,7 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum)
struct ubi_volume *vol = desc->vol; struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi; struct ubi_device *ubi = vol->ubi;
dbg_gen("unmap LEB %d:%d", vol->vol_id, lnum); dbg_gen("map LEB %d:%d", vol->vol_id, lnum);
if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS; return -EROFS;
......
...@@ -466,6 +466,7 @@ struct ubi_debug_info { ...@@ -466,6 +466,7 @@ struct ubi_debug_info {
* @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes
* @fm_work: fastmap work queue * @fm_work: fastmap work queue
* @fm_work_scheduled: non-zero if fastmap work was scheduled * @fm_work_scheduled: non-zero if fastmap work was scheduled
* @fast_attach: non-zero if UBI was attached by fastmap
* *
* @used: RB-tree of used physical eraseblocks * @used: RB-tree of used physical eraseblocks
* @erroneous: RB-tree of erroneous used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks
...@@ -574,6 +575,7 @@ struct ubi_device { ...@@ -574,6 +575,7 @@ struct ubi_device {
size_t fm_size; size_t fm_size;
struct work_struct fm_work; struct work_struct fm_work;
int fm_work_scheduled; int fm_work_scheduled;
int fast_attach;
/* Wear-leveling sub-system's stuff */ /* Wear-leveling sub-system's stuff */
struct rb_root used; struct rb_root used;
......
...@@ -405,7 +405,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) ...@@ -405,7 +405,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
if (!no_vtbl) if (!no_vtbl)
self_check_volumes(ubi); self_check_volumes(ubi);
return err; return 0;
out_err: out_err:
ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err); ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err);
......
...@@ -1534,6 +1534,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1534,6 +1534,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
INIT_LIST_HEAD(&ubi->pq[i]); INIT_LIST_HEAD(&ubi->pq[i]);
ubi->pq_head = 0; ubi->pq_head = 0;
ubi->free_count = 0;
list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) { list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
cond_resched(); cond_resched();
...@@ -1552,7 +1553,6 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1552,7 +1553,6 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
found_pebs++; found_pebs++;
} }
ubi->free_count = 0;
list_for_each_entry(aeb, &ai->free, u.list) { list_for_each_entry(aeb, &ai->free, u.list) {
cond_resched(); cond_resched();
......
...@@ -260,7 +260,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) ...@@ -260,7 +260,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
pr_err("\txattr_names %u\n", ui->xattr_names); pr_err("\txattr_names %u\n", ui->xattr_names);
pr_err("\tdirty %u\n", ui->dirty); pr_err("\tdirty %u\n", ui->dirty);
pr_err("\txattr %u\n", ui->xattr); pr_err("\txattr %u\n", ui->xattr);
pr_err("\tbulk_read %u\n", ui->xattr); pr_err("\tbulk_read %u\n", ui->bulk_read);
pr_err("\tsynced_i_size %llu\n", pr_err("\tsynced_i_size %llu\n",
(unsigned long long)ui->synced_i_size); (unsigned long long)ui->synced_i_size);
pr_err("\tui_size %llu\n", pr_err("\tui_size %llu\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment