diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-10 11:55:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-10 11:55:46 -0400 |
commit | d53b47c08d8fda1892f47393de8eeab4e34b3188 (patch) | |
tree | 717911fc55a24ad186b62890843e6125fe5907a1 /fs/ubifs | |
parent | a3c54931199565930d6d84f4c3456f6440aefd41 (diff) | |
parent | 380347e9ca76828ee9bac63cfc338ca99cdee4f3 (diff) |
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
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/budget.c | 1 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 4 | ||||
-rw-r--r-- | fs/ubifs/file.c | 6 | ||||
-rw-r--r-- | fs/ubifs/io.c | 18 | ||||
-rw-r--r-- | fs/ubifs/shrinker.c | 1 | ||||
-rw-r--r-- | fs/ubifs/super.c | 5 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 5 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 11 |
8 files changed, 35 insertions, 16 deletions
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index e8e01d74dc05..eb997e9c4ab0 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -437,7 +437,6 @@ static int calc_dd_growth(const struct ubifs_info *c, | |||
437 | */ | 437 | */ |
438 | int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) | 438 | int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) |
439 | { | 439 | { |
440 | int uninitialized_var(cmt_retries), uninitialized_var(wb_retries); | ||
441 | int err, idx_growth, data_growth, dd_growth, retried = 0; | 440 | int err, idx_growth, data_growth, dd_growth, retried = 0; |
442 | 441 | ||
443 | ubifs_assert(req->new_page <= 1); | 442 | ubifs_assert(req->new_page <= 1); |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 5157b866a853..177b0152fef4 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -745,8 +745,10 @@ void ubifs_dump_lprops(struct ubifs_info *c) | |||
745 | 745 | ||
746 | for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) { | 746 | for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) { |
747 | err = ubifs_read_one_lp(c, lnum, &lp); | 747 | err = ubifs_read_one_lp(c, lnum, &lp); |
748 | if (err) | 748 | if (err) { |
749 | ubifs_err("cannot read lprops for LEB %d", lnum); | 749 | ubifs_err("cannot read lprops for LEB %d", lnum); |
750 | continue; | ||
751 | } | ||
750 | 752 | ||
751 | ubifs_dump_lprop(c, &lp); | 753 | ubifs_dump_lprop(c, &lp); |
752 | } | 754 | } |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 4f34dbae823d..0ab7f7dfb98b 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -903,8 +903,9 @@ static int do_writepage(struct page *page, int len) | |||
903 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 903 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
904 | 904 | ||
905 | #ifdef UBIFS_DEBUG | 905 | #ifdef UBIFS_DEBUG |
906 | struct ubifs_inode *ui = ubifs_inode(inode); | ||
906 | spin_lock(&ui->ui_lock); | 907 | spin_lock(&ui->ui_lock); |
907 | ubifs_assert(page->index <= ui->synced_i_size << PAGE_CACHE_SIZE); | 908 | ubifs_assert(page->index <= ui->synced_i_size >> PAGE_CACHE_SHIFT); |
908 | spin_unlock(&ui->ui_lock); | 909 | spin_unlock(&ui->ui_lock); |
909 | #endif | 910 | #endif |
910 | 911 | ||
@@ -1525,8 +1526,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, | |||
1525 | } | 1526 | } |
1526 | 1527 | ||
1527 | wait_for_stable_page(page); | 1528 | wait_for_stable_page(page); |
1528 | unlock_page(page); | 1529 | return VM_FAULT_LOCKED; |
1529 | return 0; | ||
1530 | 1530 | ||
1531 | out_unlock: | 1531 | out_unlock: |
1532 | unlock_page(page); | 1532 | unlock_page(page); |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index e18b9889a51b..2290d5866725 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -988,30 +988,32 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, | |||
988 | return err; | 988 | return err; |
989 | 989 | ||
990 | if (type != ch->node_type) { | 990 | if (type != ch->node_type) { |
991 | ubifs_err("bad node type (%d but expected %d)", | 991 | ubifs_errc(c, "bad node type (%d but expected %d)", |
992 | ch->node_type, type); | 992 | ch->node_type, type); |
993 | goto out; | 993 | goto out; |
994 | } | 994 | } |
995 | 995 | ||
996 | err = ubifs_check_node(c, buf, lnum, offs, 0, 0); | 996 | err = ubifs_check_node(c, buf, lnum, offs, 0, 0); |
997 | if (err) { | 997 | if (err) { |
998 | ubifs_err("expected node type %d", type); | 998 | ubifs_errc(c, "expected node type %d", type); |
999 | return err; | 999 | return err; |
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | l = le32_to_cpu(ch->len); | 1002 | l = le32_to_cpu(ch->len); |
1003 | if (l != len) { | 1003 | if (l != len) { |
1004 | ubifs_err("bad node length %d, expected %d", l, len); | 1004 | ubifs_errc(c, "bad node length %d, expected %d", l, len); |
1005 | goto out; | 1005 | goto out; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | return 0; | 1008 | return 0; |
1009 | 1009 | ||
1010 | out: | 1010 | out: |
1011 | ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs, | 1011 | ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum, |
1012 | ubi_is_mapped(c->ubi, lnum)); | 1012 | offs, ubi_is_mapped(c->ubi, lnum)); |
1013 | ubifs_dump_node(c, buf); | 1013 | if (!c->probing) { |
1014 | dump_stack(); | 1014 | ubifs_dump_node(c, buf); |
1015 | dump_stack(); | ||
1016 | } | ||
1015 | return -EINVAL; | 1017 | return -EINVAL; |
1016 | } | 1018 | } |
1017 | 1019 | ||
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c index f35135e28e96..9a9fb94a41c6 100644 --- a/fs/ubifs/shrinker.c +++ b/fs/ubifs/shrinker.c | |||
@@ -128,7 +128,6 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention) | |||
128 | freed = ubifs_destroy_tnc_subtree(znode); | 128 | freed = ubifs_destroy_tnc_subtree(znode); |
129 | atomic_long_sub(freed, &ubifs_clean_zn_cnt); | 129 | atomic_long_sub(freed, &ubifs_clean_zn_cnt); |
130 | atomic_long_sub(freed, &c->clean_zn_cnt); | 130 | atomic_long_sub(freed, &c->clean_zn_cnt); |
131 | ubifs_assert(atomic_long_read(&c->clean_zn_cnt) >= 0); | ||
132 | total_freed += freed; | 131 | total_freed += freed; |
133 | znode = zprev; | 132 | znode = zprev; |
134 | } | 133 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index a81c7b556896..3904c8574ef9 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1149,6 +1149,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1149 | size_t sz; | 1149 | size_t sz; |
1150 | 1150 | ||
1151 | c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY); | 1151 | c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY); |
1152 | /* Suppress error messages while probing if MS_SILENT is set */ | ||
1153 | c->probing = !!(c->vfs_sb->s_flags & MS_SILENT); | ||
1154 | |||
1152 | err = init_constants_early(c); | 1155 | err = init_constants_early(c); |
1153 | if (err) | 1156 | if (err) |
1154 | return err; | 1157 | return err; |
@@ -1214,6 +1217,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1214 | if (err) | 1217 | if (err) |
1215 | goto out_free; | 1218 | goto out_free; |
1216 | 1219 | ||
1220 | c->probing = 0; | ||
1221 | |||
1217 | /* | 1222 | /* |
1218 | * Make sure the compressor which is set as default in the superblock | 1223 | * Make sure the compressor which is set as default in the superblock |
1219 | * or overridden by mount options is actually compiled in. | 1224 | * or overridden by mount options is actually compiled in. |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 9083bc7ed4ae..8a40cf9c02d7 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -2859,10 +2859,11 @@ void ubifs_tnc_close(struct ubifs_info *c) | |||
2859 | { | 2859 | { |
2860 | tnc_destroy_cnext(c); | 2860 | tnc_destroy_cnext(c); |
2861 | if (c->zroot.znode) { | 2861 | if (c->zroot.znode) { |
2862 | long n; | 2862 | long n, freed; |
2863 | 2863 | ||
2864 | ubifs_destroy_tnc_subtree(c->zroot.znode); | ||
2865 | n = atomic_long_read(&c->clean_zn_cnt); | 2864 | n = atomic_long_read(&c->clean_zn_cnt); |
2865 | freed = ubifs_destroy_tnc_subtree(c->zroot.znode); | ||
2866 | ubifs_assert(freed == n); | ||
2866 | atomic_long_sub(n, &ubifs_clean_zn_cnt); | 2867 | atomic_long_sub(n, &ubifs_clean_zn_cnt); |
2867 | } | 2868 | } |
2868 | kfree(c->gap_lebs); | 2869 | kfree(c->gap_lebs); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index e8c8cfe1435c..c1f71fe17cc0 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -51,6 +51,15 @@ | |||
51 | #define ubifs_warn(fmt, ...) \ | 51 | #define ubifs_warn(fmt, ...) \ |
52 | pr_warn("UBIFS warning (pid %d): %s: " fmt "\n", \ | 52 | pr_warn("UBIFS warning (pid %d): %s: " fmt "\n", \ |
53 | current->pid, __func__, ##__VA_ARGS__) | 53 | current->pid, __func__, ##__VA_ARGS__) |
54 | /* | ||
55 | * A variant of 'ubifs_err()' which takes the UBIFS file-sytem description | ||
56 | * object as an argument. | ||
57 | */ | ||
58 | #define ubifs_errc(c, fmt, ...) \ | ||
59 | do { \ | ||
60 | if (!(c)->probing) \ | ||
61 | ubifs_err(fmt, ##__VA_ARGS__); \ | ||
62 | } while (0) | ||
54 | 63 | ||
55 | /* UBIFS file system VFS magic number */ | 64 | /* UBIFS file system VFS magic number */ |
56 | #define UBIFS_SUPER_MAGIC 0x24051905 | 65 | #define UBIFS_SUPER_MAGIC 0x24051905 |
@@ -1209,6 +1218,7 @@ struct ubifs_debug_info; | |||
1209 | * @need_recovery: %1 if the file-system needs recovery | 1218 | * @need_recovery: %1 if the file-system needs recovery |
1210 | * @replaying: %1 during journal replay | 1219 | * @replaying: %1 during journal replay |
1211 | * @mounting: %1 while mounting | 1220 | * @mounting: %1 while mounting |
1221 | * @probing: %1 while attempting to mount if MS_SILENT mount flag is set | ||
1212 | * @remounting_rw: %1 while re-mounting from R/O mode to R/W mode | 1222 | * @remounting_rw: %1 while re-mounting from R/O mode to R/W mode |
1213 | * @replay_list: temporary list used during journal replay | 1223 | * @replay_list: temporary list used during journal replay |
1214 | * @replay_buds: list of buds to replay | 1224 | * @replay_buds: list of buds to replay |
@@ -1441,6 +1451,7 @@ struct ubifs_info { | |||
1441 | unsigned int replaying:1; | 1451 | unsigned int replaying:1; |
1442 | unsigned int mounting:1; | 1452 | unsigned int mounting:1; |
1443 | unsigned int remounting_rw:1; | 1453 | unsigned int remounting_rw:1; |
1454 | unsigned int probing:1; | ||
1444 | struct list_head replay_list; | 1455 | struct list_head replay_list; |
1445 | struct list_head replay_buds; | 1456 | struct list_head replay_buds; |
1446 | unsigned long long cs_sqnum; | 1457 | unsigned long long cs_sqnum; |