This pull request contains several UBIFS fixes. One of them fixes a race
condition between the mmap page fault path and fsync. Another just removes a bogus assertion from the UBIFS memory shrinker. UBIFS also started honoring the MS_SILENT mount flag, so now it won't print many I/O errors when user-space just tries to probe for the FS. Rest of the changes are rather minor UBI/UBIFS fixes, improvements, and clean-ups. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTlqqmAAoJECmIfjd9wqK0cYAP+QGoB8+DOGv4+rTtUegNaWaG QAeAkvOBxDa72NrTYMtDFBKiPPYcz0BUnPgsCyvYIlYknRuZ4xMsu1BucLF3y8E3 P8aHpnNas0dA3el/M+M0qwpEG0pb1lQvFT1dJVP6/D4q4VexLlgt7PlQjP+98Dua jp9jBDMu3sEDsqA9NiO2hfuFuIqF6DFnBpglkNcGcAyOtzQ/Ps49nivhb1mFKuzI 2kSm2kWmZCTnLlGG1uj9+diCpTKWZoES2Jmo6gcZjQIjlejSzQw4Fo8LqdmhfwOg 0ba1D9kJuwPHmBeM0UW4fLtrJHkvs2F66YaRcbA7GUo5lNw6+yxTqi3jkGevsPOD 7eQB8FVCco14PFKu8Vx4lbkS2ekZN6aQuYYw/EeY2f+w8MpQTfcWINP5OVNHHGVA QDeRiu9mRMbm3JARRe9NeL0+sryGN402jCHtESAhONUDsCmZKX9k8HUMY1iaPAIp kGJWOjbyzYRMJiOfQiklv4N6rusmnECiRWGCliKDCU6TER8U6m9ZCUHUKmtX+56c 2yRtd6y6LVequ/p3wC3x66jF64wjh2PlTM5jrWSOIg42ihIGSMAbmB6MKA+4RxIv EejZ4lhCxUg6Xp7zd/qgdu3aJ/P2OM8yFL+BngGKFac54EnTDEUcc7d8c2DZZv8s 7YYjpiKK1NQGnih0FABA =CP7Z -----END PGP SIGNATURE----- Merge tag 'upstream-3.16-rc1-v2' of git://git.infradead.org/linux-ubifs Pull UBIFS updates from Artem Bityutskiy: "This contains several UBIFS fixes. One of them fixes a race condition between the mmap page fault path and fsync. Another just removes a bogus assertion from the UBIFS memory shrinker. UBIFS also started honoring the MS_SILENT mount flag, so now it won't print many I/O errors when user-space just tries to probe for the FS. Rest of the changes are rather minor UBI/UBIFS fixes, improvements, and clean-ups" * tag 'upstream-3.16-rc1-v2' of git://git.infradead.org/linux-ubifs: UBIFS: Add an assertion for clean_zn_cnt UBIFS: respect MS_SILENT mount flag UBIFS: Remove incorrect assertion in shrink_tnc() UBIFS: fix debugging check UBIFS: add missing ui pointer in debugging code UBI: block: Fix error path on alloc_workqueue failure UBIFS: Fix dump messages in ubifs_dump_lprops UBI: fix rb_tree node comparison in add_map UBIFS: Remove unused variables in ubifs_budget_space UBI: weaken the 'exclusive' constraint when opening volumes to rename UBIFS: fix an mmap and fsync race condition
This commit is contained in:
Коммит
d53b47c08d
|
@ -432,8 +432,10 @@ int ubiblock_create(struct ubi_volume_info *vi)
|
|||
* Rembember workqueues are cheap, they're not threads.
|
||||
*/
|
||||
dev->wq = alloc_workqueue("%s", 0, 0, gd->disk_name);
|
||||
if (!dev->wq)
|
||||
if (!dev->wq) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free_queue;
|
||||
}
|
||||
INIT_WORK(&dev->work, ubiblock_do_work);
|
||||
|
||||
mutex_lock(&devices_mutex);
|
||||
|
|
|
@ -731,7 +731,7 @@ static int rename_volumes(struct ubi_device *ubi,
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE);
|
||||
re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_READWRITE);
|
||||
if (IS_ERR(re->desc)) {
|
||||
err = PTR_ERR(re->desc);
|
||||
ubi_err("cannot open volume %d, error %d", vol_id, err);
|
||||
|
|
|
@ -125,9 +125,9 @@ static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
|
|||
parent = *p;
|
||||
av = rb_entry(parent, struct ubi_ainf_volume, rb);
|
||||
|
||||
if (vol_id > av->vol_id)
|
||||
if (vol_id < av->vol_id)
|
||||
p = &(*p)->rb_left;
|
||||
else if (vol_id > av->vol_id)
|
||||
else
|
||||
p = &(*p)->rb_right;
|
||||
}
|
||||
|
||||
|
|
|
@ -437,7 +437,6 @@ static int calc_dd_growth(const struct ubifs_info *c,
|
|||
*/
|
||||
int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
|
||||
{
|
||||
int uninitialized_var(cmt_retries), uninitialized_var(wb_retries);
|
||||
int err, idx_growth, data_growth, dd_growth, retried = 0;
|
||||
|
||||
ubifs_assert(req->new_page <= 1);
|
||||
|
|
|
@ -745,8 +745,10 @@ void ubifs_dump_lprops(struct ubifs_info *c)
|
|||
|
||||
for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) {
|
||||
err = ubifs_read_one_lp(c, lnum, &lp);
|
||||
if (err)
|
||||
if (err) {
|
||||
ubifs_err("cannot read lprops for LEB %d", lnum);
|
||||
continue;
|
||||
}
|
||||
|
||||
ubifs_dump_lprop(c, &lp);
|
||||
}
|
||||
|
|
|
@ -903,8 +903,9 @@ static int do_writepage(struct page *page, int len)
|
|||
struct ubifs_info *c = inode->i_sb->s_fs_info;
|
||||
|
||||
#ifdef UBIFS_DEBUG
|
||||
struct ubifs_inode *ui = ubifs_inode(inode);
|
||||
spin_lock(&ui->ui_lock);
|
||||
ubifs_assert(page->index <= ui->synced_i_size << PAGE_CACHE_SIZE);
|
||||
ubifs_assert(page->index <= ui->synced_i_size >> PAGE_CACHE_SHIFT);
|
||||
spin_unlock(&ui->ui_lock);
|
||||
#endif
|
||||
|
||||
|
@ -1525,8 +1526,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
|
|||
}
|
||||
|
||||
wait_for_stable_page(page);
|
||||
unlock_page(page);
|
||||
return 0;
|
||||
return VM_FAULT_LOCKED;
|
||||
|
||||
out_unlock:
|
||||
unlock_page(page);
|
||||
|
|
|
@ -988,30 +988,32 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
|
|||
return err;
|
||||
|
||||
if (type != ch->node_type) {
|
||||
ubifs_err("bad node type (%d but expected %d)",
|
||||
ch->node_type, type);
|
||||
ubifs_errc(c, "bad node type (%d but expected %d)",
|
||||
ch->node_type, type);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
|
||||
if (err) {
|
||||
ubifs_err("expected node type %d", type);
|
||||
ubifs_errc(c, "expected node type %d", type);
|
||||
return err;
|
||||
}
|
||||
|
||||
l = le32_to_cpu(ch->len);
|
||||
if (l != len) {
|
||||
ubifs_err("bad node length %d, expected %d", l, len);
|
||||
ubifs_errc(c, "bad node length %d, expected %d", l, len);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs,
|
||||
ubi_is_mapped(c->ubi, lnum));
|
||||
ubifs_dump_node(c, buf);
|
||||
dump_stack();
|
||||
ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum,
|
||||
offs, ubi_is_mapped(c->ubi, lnum));
|
||||
if (!c->probing) {
|
||||
ubifs_dump_node(c, buf);
|
||||
dump_stack();
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -128,7 +128,6 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
|
|||
freed = ubifs_destroy_tnc_subtree(znode);
|
||||
atomic_long_sub(freed, &ubifs_clean_zn_cnt);
|
||||
atomic_long_sub(freed, &c->clean_zn_cnt);
|
||||
ubifs_assert(atomic_long_read(&c->clean_zn_cnt) >= 0);
|
||||
total_freed += freed;
|
||||
znode = zprev;
|
||||
}
|
||||
|
|
|
@ -1149,6 +1149,9 @@ static int mount_ubifs(struct ubifs_info *c)
|
|||
size_t sz;
|
||||
|
||||
c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY);
|
||||
/* Suppress error messages while probing if MS_SILENT is set */
|
||||
c->probing = !!(c->vfs_sb->s_flags & MS_SILENT);
|
||||
|
||||
err = init_constants_early(c);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -1214,6 +1217,8 @@ static int mount_ubifs(struct ubifs_info *c)
|
|||
if (err)
|
||||
goto out_free;
|
||||
|
||||
c->probing = 0;
|
||||
|
||||
/*
|
||||
* Make sure the compressor which is set as default in the superblock
|
||||
* or overridden by mount options is actually compiled in.
|
||||
|
|
|
@ -2859,10 +2859,11 @@ void ubifs_tnc_close(struct ubifs_info *c)
|
|||
{
|
||||
tnc_destroy_cnext(c);
|
||||
if (c->zroot.znode) {
|
||||
long n;
|
||||
long n, freed;
|
||||
|
||||
ubifs_destroy_tnc_subtree(c->zroot.znode);
|
||||
n = atomic_long_read(&c->clean_zn_cnt);
|
||||
freed = ubifs_destroy_tnc_subtree(c->zroot.znode);
|
||||
ubifs_assert(freed == n);
|
||||
atomic_long_sub(n, &ubifs_clean_zn_cnt);
|
||||
}
|
||||
kfree(c->gap_lebs);
|
||||
|
|
|
@ -51,6 +51,15 @@
|
|||
#define ubifs_warn(fmt, ...) \
|
||||
pr_warn("UBIFS warning (pid %d): %s: " fmt "\n", \
|
||||
current->pid, __func__, ##__VA_ARGS__)
|
||||
/*
|
||||
* A variant of 'ubifs_err()' which takes the UBIFS file-sytem description
|
||||
* object as an argument.
|
||||
*/
|
||||
#define ubifs_errc(c, fmt, ...) \
|
||||
do { \
|
||||
if (!(c)->probing) \
|
||||
ubifs_err(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* UBIFS file system VFS magic number */
|
||||
#define UBIFS_SUPER_MAGIC 0x24051905
|
||||
|
@ -1209,6 +1218,7 @@ struct ubifs_debug_info;
|
|||
* @need_recovery: %1 if the file-system needs recovery
|
||||
* @replaying: %1 during journal replay
|
||||
* @mounting: %1 while mounting
|
||||
* @probing: %1 while attempting to mount if MS_SILENT mount flag is set
|
||||
* @remounting_rw: %1 while re-mounting from R/O mode to R/W mode
|
||||
* @replay_list: temporary list used during journal replay
|
||||
* @replay_buds: list of buds to replay
|
||||
|
@ -1441,6 +1451,7 @@ struct ubifs_info {
|
|||
unsigned int replaying:1;
|
||||
unsigned int mounting:1;
|
||||
unsigned int remounting_rw:1;
|
||||
unsigned int probing:1;
|
||||
struct list_head replay_list;
|
||||
struct list_head replay_buds;
|
||||
unsigned long long cs_sqnum;
|
||||
|
|
Загрузка…
Ссылка в новой задаче