1
0
Fork 0

This pull request contains updates for both UBI and UBIFS:

- The UBI on-disk format header file is now dual licensed
 - New way to detect Fastmap problems during runtime
 - Bugfix for Fastmap
 - Minor updates for UBIFS (spelling, comments, vm_fault_t, ...)
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAlsdi6AWHHJpY2hhcmRA
 c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wVimEADam9dNKs7hVAlSR5G8fgoFMiPI
 PgP/cQ719PAYh8Zub0w8fIIvtSCaVZmPX/K40w4KAgP/jdQ/v4QD3ZYdHO3vn3/M
 6WI/cEB/Cn5lJp78tt14cGlqG3+xnlwyc9EEeiMCPDWmoSf66J7fwuL3xRq4dDet
 CBISYrF8ZMe6BJohT9kAYeqYoYLzALUmZoOx1DGhX7b2SEaLphCyW0A0rkxoHbYG
 sxAfUiR4/bdaFfqLAmEMgoovIHGYmOdnMJ3Hk+uUVrPEfBzxDQuGfpevDJ1u99hS
 D4qdvY3+VAcTpTK0XJUBgPaVpkYYMS5nfHtpObbyOT/kBmgCloCAmtvVcznxUwJ7
 R+8UBZH/SrxUw+R9JCP1hFgb/PlEAE0+Vsc2jgvqWOQ8xnOqojG5FdqAueGanX+l
 /on2/HNoZp5C8x15+cB9SiQwfdoZrH7vr9uzi1lqaWSV+ZMDpvG/QFMX1QX1gLl9
 TFeQJBojE41y+hjTnnUQZdy1oPaisffU44ymKlf1FR2SdzW6d7wIRBd0jnB+7Pjz
 KocSAA2kqDUcCjUtLFSSVfE7kUL9wwJQUfUxeQFViTGDvAnLcmy1a6mqQ1K5YWq9
 e5mpMQRWzoq0XrPyaVI5EEhvaqWalJwIa6GA7ZksOvS4W1pqFLLyFOKkHejUPou8
 lxcw0dDsyZdmnDRuMA==
 =b0lt
 -----END PGP SIGNATURE-----

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

Pull UBI and UBIFS updates from Richard Weinberger:

 - the UBI on-disk format header file is now dual licensed

 - new way to detect Fastmap problems during runtime

 - bugfix for Fastmap

 - minor updates for UBIFS (spelling, comments, vm_fault_t, ...)

* tag 'upstream-4.18-rc1' of git://git.infradead.org/linux-ubifs:
  mtd: ubi: Update ubi-media.h to dual license
  ubi: fastmap: Detect EBA mismatches on-the-fly
  ubi: fastmap: Check each mapping only once
  ubi: fastmap: Correctly handle interrupted erasures in EBA
  ubi: fastmap: Cancel work upon detach
  ubifs: lpt: Fix wrong pnode number range in comment
  ubifs: gc: Fix typo
  ubifs: log: Some spelling fixes
  ubifs: Spelling fix someting -> something
  ubifs: journal: Remove wrong comment
  ubifs: remove set but never used variable
  ubifs, xattr: remove misguided quota flags
  fs: ubifs: Adding new return type vm_fault_t
hifive-unleashed-5.1
Linus Torvalds 2018-06-10 15:52:09 -07:00
commit ab0b2e5932
16 changed files with 178 additions and 46 deletions

View File

@ -526,6 +526,7 @@ void ubi_free_internal_volumes(struct ubi_device *ubi)
for (i = ubi->vtbl_slots;
i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
ubi_eba_replace_table(ubi->volumes[i], NULL);
ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
kfree(ubi->volumes[i]);
}
}
@ -1091,6 +1092,9 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
if (ubi->bgt_thread)
kthread_stop(ubi->bgt_thread);
#ifdef CONFIG_MTD_UBI_FASTMAP
cancel_work_sync(&ubi->fm_work);
#endif
ubi_debugfs_exit_dev(ubi);
uif_close(ubi);

View File

@ -490,6 +490,103 @@ out_unlock:
return err;
}
#ifdef CONFIG_MTD_UBI_FASTMAP
/**
* check_mapping - check and fixup a mapping
* @ubi: UBI device description object
* @vol: volume description object
* @lnum: logical eraseblock number
* @pnum: physical eraseblock number
*
* Checks whether a given mapping is valid. Fastmap cannot track LEB unmap
* operations, if such an operation is interrupted the mapping still looks
* good, but upon first read an ECC is reported to the upper layer.
* Normaly during the full-scan at attach time this is fixed, for Fastmap
* we have to deal with it while reading.
* If the PEB behind a LEB shows this symthom we change the mapping to
* %UBI_LEB_UNMAPPED and schedule the PEB for erasure.
*
* Returns 0 on success, negative error code in case of failure.
*/
static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int *pnum)
{
int err;
struct ubi_vid_io_buf *vidb;
struct ubi_vid_hdr *vid_hdr;
if (!ubi->fast_attach)
return 0;
if (!vol->checkmap || test_bit(lnum, vol->checkmap))
return 0;
vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS);
if (!vidb)
return -ENOMEM;
err = ubi_io_read_vid_hdr(ubi, *pnum, vidb, 0);
if (err > 0 && err != UBI_IO_BITFLIPS) {
int torture = 0;
switch (err) {
case UBI_IO_FF:
case UBI_IO_FF_BITFLIPS:
case UBI_IO_BAD_HDR:
case UBI_IO_BAD_HDR_EBADMSG:
break;
default:
ubi_assert(0);
}
if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_FF_BITFLIPS)
torture = 1;
down_read(&ubi->fm_eba_sem);
vol->eba_tbl->entries[lnum].pnum = UBI_LEB_UNMAPPED;
up_read(&ubi->fm_eba_sem);
ubi_wl_put_peb(ubi, vol->vol_id, lnum, *pnum, torture);
*pnum = UBI_LEB_UNMAPPED;
} else if (err < 0) {
ubi_err(ubi, "unable to read VID header back from PEB %i: %i",
*pnum, err);
goto out_free;
} else {
int found_vol_id, found_lnum;
ubi_assert(err == 0 || err == UBI_IO_BITFLIPS);
vid_hdr = ubi_get_vid_hdr(vidb);
found_vol_id = be32_to_cpu(vid_hdr->vol_id);
found_lnum = be32_to_cpu(vid_hdr->lnum);
if (found_lnum != lnum || found_vol_id != vol->vol_id) {
ubi_err(ubi, "EBA mismatch! PEB %i is LEB %i:%i instead of LEB %i:%i",
*pnum, found_vol_id, found_lnum, vol->vol_id, lnum);
ubi_ro_mode(ubi);
err = -EINVAL;
goto out_free;
}
}
set_bit(lnum, vol->checkmap);
err = 0;
out_free:
ubi_free_vid_buf(vidb);
return err;
}
#else
static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int *pnum)
{
return 0;
}
#endif
/**
* ubi_eba_read_leb - read data.
* @ubi: UBI device description object
@ -522,7 +619,13 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
return err;
pnum = vol->eba_tbl->entries[lnum].pnum;
if (pnum < 0) {
if (pnum >= 0) {
err = check_mapping(ubi, vol, lnum, &pnum);
if (err < 0)
goto out_unlock;
}
if (pnum == UBI_LEB_UNMAPPED) {
/*
* The logical eraseblock is not mapped, fill the whole buffer
* with 0xFF bytes. The exception is static volumes for which
@ -930,6 +1033,12 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
return err;
pnum = vol->eba_tbl->entries[lnum].pnum;
if (pnum >= 0) {
err = check_mapping(ubi, vol, lnum, &pnum);
if (err < 0)
goto out;
}
if (pnum >= 0) {
dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d",
len, offset, vol_id, lnum, pnum);

View File

@ -1100,6 +1100,26 @@ free_fm_sb:
goto out;
}
int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count)
{
struct ubi_device *ubi = vol->ubi;
if (!ubi->fast_attach)
return 0;
vol->checkmap = kcalloc(BITS_TO_LONGS(leb_count), sizeof(unsigned long),
GFP_KERNEL);
if (!vol->checkmap)
return -ENOMEM;
return 0;
}
void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol)
{
kfree(vol->checkmap);
}
/**
* ubi_write_fastmap - writes a fastmap.
* @ubi: UBI device object

View File

@ -1,28 +1,12 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/*
* 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
*
* Copyright (C) International Business Machines Corp., 2006
* Authors: Artem Bityutskiy (Битюцкий Артём)
* Thomas Gleixner
* Frank Haverkamp
* Oliver Lohmann
* Andreas Arnez
*/
/*
*
* This file defines the layout of UBI headers and all the other UBI on-flash
* data structures.
*/

View File

@ -334,6 +334,9 @@ struct ubi_eba_leb_desc {
* @changing_leb: %1 if the atomic LEB change ioctl command is in progress
* @direct_writes: %1 if direct writes are enabled for this volume
*
* @checkmap: bitmap to remember which PEB->LEB mappings got checked,
* protected by UBI LEB lock tree.
*
* The @corrupted field indicates that the volume's contents is corrupted.
* Since UBI protects only static volumes, this field is not relevant to
* dynamic volumes - it is user's responsibility to assure their data
@ -377,6 +380,10 @@ struct ubi_volume {
unsigned int updating:1;
unsigned int changing_leb:1;
unsigned int direct_writes:1;
#ifdef CONFIG_MTD_UBI_FASTMAP
unsigned long *checkmap;
#endif
};
/**
@ -965,8 +972,12 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi);
int ubi_update_fastmap(struct ubi_device *ubi);
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
struct ubi_attach_info *scan_ai);
int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count);
void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol);
#else
static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; }
int static inline ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) { return 0; }
static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {}
#endif
/* block.c */

View File

@ -139,6 +139,7 @@ static void vol_release(struct device *dev)
struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);
ubi_eba_replace_table(vol, NULL);
ubi_fastmap_destroy_checkmap(vol);
kfree(vol);
}

View File

@ -534,7 +534,7 @@ 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;
int i, err, reserved_pebs = 0;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
@ -620,6 +620,16 @@ static int init_volumes(struct ubi_device *ubi,
(long long)(vol->used_ebs - 1) * vol->usable_leb_size;
vol->used_bytes += av->last_data_size;
vol->last_eb_bytes = av->last_data_size;
/*
* We use ubi->peb_count and not vol->reserved_pebs because
* we want to keep the code simple. Otherwise we'd have to
* resize/check the bitmap upon volume resize too.
* Allocating a few bytes more does not hurt.
*/
err = ubi_fastmap_init_checkmap(vol, ubi->peb_count);
if (err)
return err;
}
/* And add the layout volume */
@ -645,6 +655,9 @@ static int init_volumes(struct ubi_device *ubi,
reserved_pebs += vol->reserved_pebs;
ubi->vol_count += 1;
vol->ubi = ubi;
err = ubi_fastmap_init_checkmap(vol, UBI_LAYOUT_VOLUME_EBS);
if (err)
return err;
if (reserved_pebs > ubi->avail_pebs) {
ubi_err(ubi, "not enough PEBs, required %d, available %d",
@ -849,6 +862,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
out_free:
vfree(ubi->vtbl);
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
kfree(ubi->volumes[i]);
ubi->volumes[i] = NULL;
}

View File

@ -1505,6 +1505,7 @@ int ubi_thread(void *u)
}
dbg_wl("background thread \"%s\" is killed", ubi->bgt_name);
ubi->thread_enabled = 0;
return 0;
}
@ -1514,9 +1515,6 @@ int ubi_thread(void *u)
*/
static void shutdown_work(struct ubi_device *ubi)
{
#ifdef CONFIG_MTD_UBI_FASTMAP
flush_work(&ubi->fm_work);
#endif
while (!list_empty(&ubi->works)) {
struct ubi_work *wrk;

View File

@ -1513,7 +1513,7 @@ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
* mmap()d file has taken write protection fault and is being made writable.
* UBIFS must ensure page is budgeted for.
*/
static int ubifs_vm_page_mkwrite(struct vm_fault *vmf)
static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf)
{
struct page *page = vmf->page;
struct inode *inode = file_inode(vmf->vma->vm_file);
@ -1567,8 +1567,7 @@ static int ubifs_vm_page_mkwrite(struct vm_fault *vmf)
if (unlikely(page->mapping != inode->i_mapping ||
page_offset(page) > i_size_read(inode))) {
/* Page got truncated out from underneath us */
err = -EINVAL;
goto out_unlock;
goto sigbus;
}
if (PagePrivate(page))
@ -1597,12 +1596,10 @@ static int ubifs_vm_page_mkwrite(struct vm_fault *vmf)
wait_for_stable_page(page);
return VM_FAULT_LOCKED;
out_unlock:
sigbus:
unlock_page(page);
ubifs_release_budget(c, &req);
if (err)
err = VM_FAULT_SIGBUS;
return err;
return VM_FAULT_SIGBUS;
}
static const struct vm_operations_struct ubifs_file_vm_ops = {

View File

@ -49,7 +49,7 @@
* maximum size. So dark watermark is the amount of free + dirty space in LEB
* which are guaranteed to be reclaimable. If LEB has less space, the GC might
* be unable to reclaim it. So, LEBs with free + dirty greater than dark
* watermark are "good" LEBs from GC's point of few. The other LEBs are not so
* watermark are "good" LEBs from GC's point of view. The other LEBs are not so
* good, and GC takes extra care when moving them.
*/

View File

@ -98,9 +98,8 @@ static inline void zero_trun_node_unused(struct ubifs_trun_node *trun)
*
* This function reserves space in journal head @head. If the reservation
* succeeded, the journal head stays locked and later has to be unlocked using
* 'release_head()'. 'write_node()' and 'write_head()' functions also unlock
* it. Returns zero in case of success, %-EAGAIN if commit has to be done, and
* other negative error codes in case of other failures.
* 'release_head()'. Returns zero in case of success, %-EAGAIN if commit has to
* be done, and other negative error codes in case of other failures.
*/
static int reserve_space(struct ubifs_info *c, int jhead, int len)
{

View File

@ -167,10 +167,10 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
* @lnum: LEB number of the bud
* @offs: starting offset of the bud
*
* This function writes reference node for the new bud LEB @lnum it to the log,
* and adds it to the buds tress. It also makes sure that log size does not
* This function writes a reference node for the new bud LEB @lnum to the log,
* and adds it to the buds trees. It also makes sure that log size does not
* exceed the 'c->max_bud_bytes' limit. Returns zero in case of success,
* %-EAGAIN if commit is required, and a negative error codes in case of
* %-EAGAIN if commit is required, and a negative error code in case of
* failure.
*/
int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)

View File

@ -619,7 +619,7 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
/**
* pnode_lookup - lookup a pnode in the LPT.
* @c: UBIFS file-system description object
* @i: pnode number (0 to main_lebs - 1)
* @i: pnode number (0 to (main_lebs - 1) / UBIFS_LPT_FANOUT))
*
* This function returns a pointer to the pnode on success or a negative
* error code on failure.

View File

@ -223,9 +223,6 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
dbg_mntk(&r->key, "LEB %d:%d len %d deletion %d sqnum %llu key ",
r->lnum, r->offs, r->len, r->deletion, r->sqnum);
/* Set c->replay_sqnum to help deal with dangling branches. */
c->replay_sqnum = r->sqnum;
if (is_hash_key(c, &r->key)) {
if (r->deletion)
err = ubifs_tnc_remove_nm(c, &r->key, &r->nm);
@ -1037,7 +1034,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
* The head of the log must always start with the
* "commit start" node on a properly formatted UBIFS.
* But we found no nodes at all, which means that
* someting went wrong and we cannot proceed mounting
* something went wrong and we cannot proceed mounting
* the file-system.
*/
ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted",

View File

@ -1206,7 +1206,6 @@ struct ubifs_debug_info;
* @replay_list: temporary list used during journal replay
* @replay_buds: list of buds to replay
* @cs_sqnum: sequence number of first node in the log (commit start node)
* @replay_sqnum: sequence number of node currently being replayed
* @unclean_leb_list: LEBs to recover when re-mounting R/O mounted FS to R/W
* mode
* @rcvrd_mst_node: recovered master node to write when re-mounting R/O mounted
@ -1438,7 +1437,6 @@ struct ubifs_info {
struct list_head replay_list;
struct list_head replay_buds;
unsigned long long cs_sqnum;
unsigned long long replay_sqnum;
struct list_head unclean_leb_list;
struct ubifs_mst_node *rcvrd_mst_node;
struct rb_root size_tree;

View File

@ -139,7 +139,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
inode->i_op = &empty_iops;
inode->i_fop = &empty_fops;
inode->i_flags |= S_SYNC | S_NOATIME | S_NOCMTIME | S_NOQUOTA;
inode->i_flags |= S_SYNC | S_NOATIME | S_NOCMTIME;
ui = ubifs_inode(inode);
ui->xattr = 1;
ui->flags |= UBIFS_XATTR_FL;