diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-04-26 04:22:15 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-04-26 04:22:59 -0400 |
commit | 07f9479a40cc778bc1462ada11f95b01360ae4ff (patch) | |
tree | 0676cf38df3844004bb3ebfd99dfa67a4a8998f5 /fs/ubifs | |
parent | 9d5e6bdb3013acfb311ab407eeca0b6a6a3dedbf (diff) | |
parent | cd2e49e90f1cae7726c9a2c54488d881d7f1cd1c (diff) |
Merge branch 'master' into for-next
Fast-forwarded to current state of Linus' tree as there are patches to be
applied for files that didn't exist on the old branch.
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/Kconfig | 11 | ||||
-rw-r--r-- | fs/ubifs/budget.c | 2 | ||||
-rw-r--r-- | fs/ubifs/commit.c | 2 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 65 | ||||
-rw-r--r-- | fs/ubifs/debug.h | 152 | ||||
-rw-r--r-- | fs/ubifs/file.c | 14 | ||||
-rw-r--r-- | fs/ubifs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/ubifs/lprops.c | 2 | ||||
-rw-r--r-- | fs/ubifs/lpt.c | 7 | ||||
-rw-r--r-- | fs/ubifs/lpt_commit.c | 4 | ||||
-rw-r--r-- | fs/ubifs/orphan.c | 2 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 26 | ||||
-rw-r--r-- | fs/ubifs/super.c | 33 | ||||
-rw-r--r-- | fs/ubifs/xattr.c | 4 |
14 files changed, 213 insertions, 113 deletions
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig index 1d1859dc3de5..f8b0160da2da 100644 --- a/fs/ubifs/Kconfig +++ b/fs/ubifs/Kconfig | |||
@@ -47,7 +47,7 @@ config UBIFS_FS_DEBUG | |||
47 | bool "Enable debugging support" | 47 | bool "Enable debugging support" |
48 | depends on UBIFS_FS | 48 | depends on UBIFS_FS |
49 | select DEBUG_FS | 49 | select DEBUG_FS |
50 | select KALLSYMS_ALL | 50 | select KALLSYMS |
51 | help | 51 | help |
52 | This option enables UBIFS debugging support. It makes sure various | 52 | This option enables UBIFS debugging support. It makes sure various |
53 | assertions, self-checks, debugging messages and test modes are compiled | 53 | assertions, self-checks, debugging messages and test modes are compiled |
@@ -58,12 +58,3 @@ config UBIFS_FS_DEBUG | |||
58 | down UBIFS. You can then further enable / disable individual debugging | 58 | down UBIFS. You can then further enable / disable individual debugging |
59 | features using UBIFS module parameters and the corresponding sysfs | 59 | features using UBIFS module parameters and the corresponding sysfs |
60 | interfaces. | 60 | interfaces. |
61 | |||
62 | config UBIFS_FS_DEBUG_CHKS | ||
63 | bool "Enable extra checks" | ||
64 | depends on UBIFS_FS_DEBUG | ||
65 | help | ||
66 | If extra checks are enabled UBIFS will check the consistency of its | ||
67 | internal data structures during operation. However, UBIFS performance | ||
68 | is dramatically slower when this option is selected especially if the | ||
69 | file system is large. | ||
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index c8ff0d1ae5d3..8b3a7da531eb 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -147,7 +147,7 @@ static int make_free_space(struct ubifs_info *c) | |||
147 | if (liab2 < liab1) | 147 | if (liab2 < liab1) |
148 | return -EAGAIN; | 148 | return -EAGAIN; |
149 | 149 | ||
150 | dbg_budg("new liability %lld (not shrinked)", liab2); | 150 | dbg_budg("new liability %lld (not shrunk)", liab2); |
151 | 151 | ||
152 | /* Liability did not shrink again, try GC */ | 152 | /* Liability did not shrink again, try GC */ |
153 | dbg_budg("Run GC"); | 153 | dbg_budg("Run GC"); |
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c index b148fbc80f8d..1bd01ded7123 100644 --- a/fs/ubifs/commit.c +++ b/fs/ubifs/commit.c | |||
@@ -577,7 +577,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
577 | size_t sz; | 577 | size_t sz; |
578 | 578 | ||
579 | if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) | 579 | if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) |
580 | goto out; | 580 | return 0; |
581 | 581 | ||
582 | INIT_LIST_HEAD(&list); | 582 | INIT_LIST_HEAD(&list); |
583 | 583 | ||
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 01c2b028e525..004d3745dc45 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -818,7 +818,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
818 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", | 818 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", |
819 | current->pid, lnum); | 819 | current->pid, lnum); |
820 | 820 | ||
821 | buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | 821 | buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); |
822 | if (!buf) { | 822 | if (!buf) { |
823 | ubifs_err("cannot allocate memory for dumping LEB %d", lnum); | 823 | ubifs_err("cannot allocate memory for dumping LEB %d", lnum); |
824 | return; | 824 | return; |
@@ -972,11 +972,39 @@ void dbg_dump_index(struct ubifs_info *c) | |||
972 | void dbg_save_space_info(struct ubifs_info *c) | 972 | void dbg_save_space_info(struct ubifs_info *c) |
973 | { | 973 | { |
974 | struct ubifs_debug_info *d = c->dbg; | 974 | struct ubifs_debug_info *d = c->dbg; |
975 | 975 | int freeable_cnt; | |
976 | ubifs_get_lp_stats(c, &d->saved_lst); | ||
977 | 976 | ||
978 | spin_lock(&c->space_lock); | 977 | spin_lock(&c->space_lock); |
978 | memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats)); | ||
979 | |||
980 | /* | ||
981 | * We use a dirty hack here and zero out @c->freeable_cnt, because it | ||
982 | * affects the free space calculations, and UBIFS might not know about | ||
983 | * all freeable eraseblocks. Indeed, we know about freeable eraseblocks | ||
984 | * only when we read their lprops, and we do this only lazily, upon the | ||
985 | * need. So at any given point of time @c->freeable_cnt might be not | ||
986 | * exactly accurate. | ||
987 | * | ||
988 | * Just one example about the issue we hit when we did not zero | ||
989 | * @c->freeable_cnt. | ||
990 | * 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the | ||
991 | * amount of free space in @d->saved_free | ||
992 | * 2. We re-mount R/W, which makes UBIFS to read the "lsave" | ||
993 | * information from flash, where we cache LEBs from various | ||
994 | * categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()' | ||
995 | * -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()' | ||
996 | * -> 'ubifs_get_pnode()' -> 'update_cats()' | ||
997 | * -> 'ubifs_add_to_cat()'). | ||
998 | * 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt | ||
999 | * becomes %1. | ||
1000 | * 4. We calculate the amount of free space when the re-mount is | ||
1001 | * finished in 'dbg_check_space_info()' and it does not match | ||
1002 | * @d->saved_free. | ||
1003 | */ | ||
1004 | freeable_cnt = c->freeable_cnt; | ||
1005 | c->freeable_cnt = 0; | ||
979 | d->saved_free = ubifs_get_free_space_nolock(c); | 1006 | d->saved_free = ubifs_get_free_space_nolock(c); |
1007 | c->freeable_cnt = freeable_cnt; | ||
980 | spin_unlock(&c->space_lock); | 1008 | spin_unlock(&c->space_lock); |
981 | } | 1009 | } |
982 | 1010 | ||
@@ -993,12 +1021,15 @@ int dbg_check_space_info(struct ubifs_info *c) | |||
993 | { | 1021 | { |
994 | struct ubifs_debug_info *d = c->dbg; | 1022 | struct ubifs_debug_info *d = c->dbg; |
995 | struct ubifs_lp_stats lst; | 1023 | struct ubifs_lp_stats lst; |
996 | long long avail, free; | 1024 | long long free; |
1025 | int freeable_cnt; | ||
997 | 1026 | ||
998 | spin_lock(&c->space_lock); | 1027 | spin_lock(&c->space_lock); |
999 | avail = ubifs_calc_available(c, c->min_idx_lebs); | 1028 | freeable_cnt = c->freeable_cnt; |
1029 | c->freeable_cnt = 0; | ||
1030 | free = ubifs_get_free_space_nolock(c); | ||
1031 | c->freeable_cnt = freeable_cnt; | ||
1000 | spin_unlock(&c->space_lock); | 1032 | spin_unlock(&c->space_lock); |
1001 | free = ubifs_get_free_space(c); | ||
1002 | 1033 | ||
1003 | if (free != d->saved_free) { | 1034 | if (free != d->saved_free) { |
1004 | ubifs_err("free space changed from %lld to %lld", | 1035 | ubifs_err("free space changed from %lld to %lld", |
@@ -2806,40 +2837,38 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) | |||
2806 | struct ubifs_debug_info *d = c->dbg; | 2837 | struct ubifs_debug_info *d = c->dbg; |
2807 | 2838 | ||
2808 | sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); | 2839 | sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); |
2809 | d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir); | 2840 | fname = d->dfs_dir_name; |
2810 | if (IS_ERR(d->dfs_dir)) { | 2841 | dent = debugfs_create_dir(fname, dfs_rootdir); |
2811 | err = PTR_ERR(d->dfs_dir); | 2842 | if (IS_ERR_OR_NULL(dent)) |
2812 | ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", | ||
2813 | d->dfs_dir_name, err); | ||
2814 | goto out; | 2843 | goto out; |
2815 | } | 2844 | d->dfs_dir = dent; |
2816 | 2845 | ||
2817 | fname = "dump_lprops"; | 2846 | fname = "dump_lprops"; |
2818 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); | 2847 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); |
2819 | if (IS_ERR(dent)) | 2848 | if (IS_ERR_OR_NULL(dent)) |
2820 | goto out_remove; | 2849 | goto out_remove; |
2821 | d->dfs_dump_lprops = dent; | 2850 | d->dfs_dump_lprops = dent; |
2822 | 2851 | ||
2823 | fname = "dump_budg"; | 2852 | fname = "dump_budg"; |
2824 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); | 2853 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); |
2825 | if (IS_ERR(dent)) | 2854 | if (IS_ERR_OR_NULL(dent)) |
2826 | goto out_remove; | 2855 | goto out_remove; |
2827 | d->dfs_dump_budg = dent; | 2856 | d->dfs_dump_budg = dent; |
2828 | 2857 | ||
2829 | fname = "dump_tnc"; | 2858 | fname = "dump_tnc"; |
2830 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); | 2859 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); |
2831 | if (IS_ERR(dent)) | 2860 | if (IS_ERR_OR_NULL(dent)) |
2832 | goto out_remove; | 2861 | goto out_remove; |
2833 | d->dfs_dump_tnc = dent; | 2862 | d->dfs_dump_tnc = dent; |
2834 | 2863 | ||
2835 | return 0; | 2864 | return 0; |
2836 | 2865 | ||
2837 | out_remove: | 2866 | out_remove: |
2838 | err = PTR_ERR(dent); | ||
2839 | ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", | ||
2840 | fname, err); | ||
2841 | debugfs_remove_recursive(d->dfs_dir); | 2867 | debugfs_remove_recursive(d->dfs_dir); |
2842 | out: | 2868 | out: |
2869 | err = dent ? PTR_ERR(dent) : -ENODEV; | ||
2870 | ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", | ||
2871 | fname, err); | ||
2843 | return err; | 2872 | return err; |
2844 | } | 2873 | } |
2845 | 2874 | ||
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 919f0de29d8f..e6493cac193d 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -23,6 +23,12 @@ | |||
23 | #ifndef __UBIFS_DEBUG_H__ | 23 | #ifndef __UBIFS_DEBUG_H__ |
24 | #define __UBIFS_DEBUG_H__ | 24 | #define __UBIFS_DEBUG_H__ |
25 | 25 | ||
26 | /* Checking helper functions */ | ||
27 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | ||
28 | struct ubifs_zbranch *zbr, void *priv); | ||
29 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | ||
30 | struct ubifs_znode *znode, void *priv); | ||
31 | |||
26 | #ifdef CONFIG_UBIFS_FS_DEBUG | 32 | #ifdef CONFIG_UBIFS_FS_DEBUG |
27 | 33 | ||
28 | /** | 34 | /** |
@@ -270,11 +276,6 @@ void dbg_dump_tnc(struct ubifs_info *c); | |||
270 | void dbg_dump_index(struct ubifs_info *c); | 276 | void dbg_dump_index(struct ubifs_info *c); |
271 | void dbg_dump_lpt_lebs(const struct ubifs_info *c); | 277 | void dbg_dump_lpt_lebs(const struct ubifs_info *c); |
272 | 278 | ||
273 | /* Checking helper functions */ | ||
274 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | ||
275 | struct ubifs_zbranch *zbr, void *priv); | ||
276 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | ||
277 | struct ubifs_znode *znode, void *priv); | ||
278 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, | 279 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, |
279 | dbg_znode_callback znode_cb, void *priv); | 280 | dbg_znode_callback znode_cb, void *priv); |
280 | 281 | ||
@@ -295,7 +296,6 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); | |||
295 | int dbg_check_filesystem(struct ubifs_info *c); | 296 | int dbg_check_filesystem(struct ubifs_info *c); |
296 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, | 297 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, |
297 | int add_pos); | 298 | int add_pos); |
298 | int dbg_check_lprops(struct ubifs_info *c); | ||
299 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, | 299 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, |
300 | int row, int col); | 300 | int row, int col); |
301 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, | 301 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, |
@@ -401,58 +401,94 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); | |||
401 | #define DBGKEY(key) ((char *)(key)) | 401 | #define DBGKEY(key) ((char *)(key)) |
402 | #define DBGKEY1(key) ((char *)(key)) | 402 | #define DBGKEY1(key) ((char *)(key)) |
403 | 403 | ||
404 | #define ubifs_debugging_init(c) 0 | 404 | static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; } |
405 | #define ubifs_debugging_exit(c) ({}) | 405 | static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; } |
406 | 406 | static inline const char *dbg_ntype(int type) { return ""; } | |
407 | #define dbg_ntype(type) "" | 407 | static inline const char *dbg_cstate(int cmt_state) { return ""; } |
408 | #define dbg_cstate(cmt_state) "" | 408 | static inline const char *dbg_jhead(int jhead) { return ""; } |
409 | #define dbg_jhead(jhead) "" | 409 | static inline const char * |
410 | #define dbg_get_key_dump(c, key) ({}) | 410 | dbg_get_key_dump(const struct ubifs_info *c, |
411 | #define dbg_dump_inode(c, inode) ({}) | 411 | const union ubifs_key *key) { return ""; } |
412 | #define dbg_dump_node(c, node) ({}) | 412 | static inline void dbg_dump_inode(const struct ubifs_info *c, |
413 | #define dbg_dump_lpt_node(c, node, lnum, offs) ({}) | 413 | const struct inode *inode) { return; } |
414 | #define dbg_dump_budget_req(req) ({}) | 414 | static inline void dbg_dump_node(const struct ubifs_info *c, |
415 | #define dbg_dump_lstats(lst) ({}) | 415 | const void *node) { return; } |
416 | #define dbg_dump_budg(c) ({}) | 416 | static inline void dbg_dump_lpt_node(const struct ubifs_info *c, |
417 | #define dbg_dump_lprop(c, lp) ({}) | 417 | void *node, int lnum, |
418 | #define dbg_dump_lprops(c) ({}) | 418 | int offs) { return; } |
419 | #define dbg_dump_lpt_info(c) ({}) | 419 | static inline void |
420 | #define dbg_dump_leb(c, lnum) ({}) | 420 | dbg_dump_budget_req(const struct ubifs_budget_req *req) { return; } |
421 | #define dbg_dump_znode(c, znode) ({}) | 421 | static inline void |
422 | #define dbg_dump_heap(c, heap, cat) ({}) | 422 | dbg_dump_lstats(const struct ubifs_lp_stats *lst) { return; } |
423 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | 423 | static inline void dbg_dump_budg(struct ubifs_info *c) { return; } |
424 | #define dbg_dump_tnc(c) ({}) | 424 | static inline void dbg_dump_lprop(const struct ubifs_info *c, |
425 | #define dbg_dump_index(c) ({}) | 425 | const struct ubifs_lprops *lp) { return; } |
426 | #define dbg_dump_lpt_lebs(c) ({}) | 426 | static inline void dbg_dump_lprops(struct ubifs_info *c) { return; } |
427 | 427 | static inline void dbg_dump_lpt_info(struct ubifs_info *c) { return; } | |
428 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 | 428 | static inline void dbg_dump_leb(const struct ubifs_info *c, |
429 | #define dbg_old_index_check_init(c, zroot) 0 | 429 | int lnum) { return; } |
430 | #define dbg_save_space_info(c) ({}) | 430 | static inline void |
431 | #define dbg_check_space_info(c) 0 | 431 | dbg_dump_znode(const struct ubifs_info *c, |
432 | #define dbg_check_old_index(c, zroot) 0 | 432 | const struct ubifs_znode *znode) { return; } |
433 | #define dbg_check_cats(c) 0 | 433 | static inline void dbg_dump_heap(struct ubifs_info *c, |
434 | #define dbg_check_ltab(c) 0 | 434 | struct ubifs_lpt_heap *heap, |
435 | #define dbg_chk_lpt_free_spc(c) 0 | 435 | int cat) { return; } |
436 | #define dbg_chk_lpt_sz(c, action, len) 0 | 436 | static inline void dbg_dump_pnode(struct ubifs_info *c, |
437 | #define dbg_check_synced_i_size(inode) 0 | 437 | struct ubifs_pnode *pnode, |
438 | #define dbg_check_dir_size(c, dir) 0 | 438 | struct ubifs_nnode *parent, |
439 | #define dbg_check_tnc(c, x) 0 | 439 | int iip) { return; } |
440 | #define dbg_check_idx_size(c, idx_size) 0 | 440 | static inline void dbg_dump_tnc(struct ubifs_info *c) { return; } |
441 | #define dbg_check_filesystem(c) 0 | 441 | static inline void dbg_dump_index(struct ubifs_info *c) { return; } |
442 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) | 442 | static inline void dbg_dump_lpt_lebs(const struct ubifs_info *c) { return; } |
443 | #define dbg_check_lprops(c) 0 | 443 | |
444 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 | 444 | static inline int dbg_walk_index(struct ubifs_info *c, |
445 | #define dbg_check_inode_size(c, inode, size) 0 | 445 | dbg_leaf_callback leaf_cb, |
446 | #define dbg_check_data_nodes_order(c, head) 0 | 446 | dbg_znode_callback znode_cb, |
447 | #define dbg_check_nondata_nodes_order(c, head) 0 | 447 | void *priv) { return 0; } |
448 | #define dbg_force_in_the_gaps_enabled 0 | 448 | static inline void dbg_save_space_info(struct ubifs_info *c) { return; } |
449 | #define dbg_force_in_the_gaps() 0 | 449 | static inline int dbg_check_space_info(struct ubifs_info *c) { return 0; } |
450 | #define dbg_failure_mode 0 | 450 | static inline int dbg_check_lprops(struct ubifs_info *c) { return 0; } |
451 | 451 | static inline int | |
452 | #define dbg_debugfs_init() 0 | 452 | dbg_old_index_check_init(struct ubifs_info *c, |
453 | #define dbg_debugfs_exit() | 453 | struct ubifs_zbranch *zroot) { return 0; } |
454 | #define dbg_debugfs_init_fs(c) 0 | 454 | static inline int |
455 | #define dbg_debugfs_exit_fs(c) 0 | 455 | dbg_check_old_index(struct ubifs_info *c, |
456 | struct ubifs_zbranch *zroot) { return 0; } | ||
457 | static inline int dbg_check_cats(struct ubifs_info *c) { return 0; } | ||
458 | static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; } | ||
459 | static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; } | ||
460 | static inline int dbg_chk_lpt_sz(struct ubifs_info *c, | ||
461 | int action, int len) { return 0; } | ||
462 | static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; } | ||
463 | static inline int dbg_check_dir_size(struct ubifs_info *c, | ||
464 | const struct inode *dir) { return 0; } | ||
465 | static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; } | ||
466 | static inline int dbg_check_idx_size(struct ubifs_info *c, | ||
467 | long long idx_size) { return 0; } | ||
468 | static inline int dbg_check_filesystem(struct ubifs_info *c) { return 0; } | ||
469 | static inline void dbg_check_heap(struct ubifs_info *c, | ||
470 | struct ubifs_lpt_heap *heap, | ||
471 | int cat, int add_pos) { return; } | ||
472 | static inline int dbg_check_lpt_nodes(struct ubifs_info *c, | ||
473 | struct ubifs_cnode *cnode, int row, int col) { return 0; } | ||
474 | static inline int dbg_check_inode_size(struct ubifs_info *c, | ||
475 | const struct inode *inode, | ||
476 | loff_t size) { return 0; } | ||
477 | static inline int | ||
478 | dbg_check_data_nodes_order(struct ubifs_info *c, | ||
479 | struct list_head *head) { return 0; } | ||
480 | static inline int | ||
481 | dbg_check_nondata_nodes_order(struct ubifs_info *c, | ||
482 | struct list_head *head) { return 0; } | ||
483 | |||
484 | static inline int dbg_force_in_the_gaps(void) { return 0; } | ||
485 | #define dbg_force_in_the_gaps_enabled 0 | ||
486 | #define dbg_failure_mode 0 | ||
487 | |||
488 | static inline int dbg_debugfs_init(void) { return 0; } | ||
489 | static inline void dbg_debugfs_exit(void) { return; } | ||
490 | static inline int dbg_debugfs_init_fs(struct ubifs_info *c) { return 0; } | ||
491 | static inline int dbg_debugfs_exit_fs(struct ubifs_info *c) { return 0; } | ||
456 | 492 | ||
457 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ | 493 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ |
458 | #endif /* !__UBIFS_DEBUG_H__ */ | 494 | #endif /* !__UBIFS_DEBUG_H__ */ |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index d77db7e36484..b286db79c686 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -448,10 +448,12 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
448 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) { | 448 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) { |
449 | /* | 449 | /* |
450 | * We change whole page so no need to load it. But we | 450 | * We change whole page so no need to load it. But we |
451 | * have to set the @PG_checked flag to make the further | 451 | * do not know whether this page exists on the media or |
452 | * code know that the page is new. This might be not | 452 | * not, so we assume the latter because it requires |
453 | * true, but it is better to budget more than to read | 453 | * larger budget. The assumption is that it is better |
454 | * the page from the media. | 454 | * to budget a bit more than to read the page from the |
455 | * media. Thus, we are setting the @PG_checked flag | ||
456 | * here. | ||
455 | */ | 457 | */ |
456 | SetPageChecked(page); | 458 | SetPageChecked(page); |
457 | skipped_read = 1; | 459 | skipped_read = 1; |
@@ -559,6 +561,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, | |||
559 | dbg_gen("copied %d instead of %d, read page and repeat", | 561 | dbg_gen("copied %d instead of %d, read page and repeat", |
560 | copied, len); | 562 | copied, len); |
561 | cancel_budget(c, page, ui, appending); | 563 | cancel_budget(c, page, ui, appending); |
564 | ClearPageChecked(page); | ||
562 | 565 | ||
563 | /* | 566 | /* |
564 | * Return 0 to force VFS to repeat the whole operation, or the | 567 | * Return 0 to force VFS to repeat the whole operation, or the |
@@ -1309,6 +1312,9 @@ int ubifs_fsync(struct file *file, int datasync) | |||
1309 | 1312 | ||
1310 | dbg_gen("syncing inode %lu", inode->i_ino); | 1313 | dbg_gen("syncing inode %lu", inode->i_ino); |
1311 | 1314 | ||
1315 | if (inode->i_sb->s_flags & MS_RDONLY) | ||
1316 | return 0; | ||
1317 | |||
1312 | /* | 1318 | /* |
1313 | * VFS has already synchronized dirty pages for this inode. Synchronize | 1319 | * VFS has already synchronized dirty pages for this inode. Synchronize |
1314 | * the inode unless this is a 'datasync()' call. | 1320 | * the inode unless this is a 'datasync()' call. |
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 8aacd64957a2..548acf494afd 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
@@ -160,7 +160,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
160 | if (IS_RDONLY(inode)) | 160 | if (IS_RDONLY(inode)) |
161 | return -EROFS; | 161 | return -EROFS; |
162 | 162 | ||
163 | if (!is_owner_or_cap(inode)) | 163 | if (!inode_owner_or_capable(inode)) |
164 | return -EACCES; | 164 | return -EACCES; |
165 | 165 | ||
166 | if (get_user(flags, (int __user *) arg)) | 166 | if (get_user(flags, (int __user *) arg)) |
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index c7b25e2f7764..0ee0847f2421 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c | |||
@@ -1094,7 +1094,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1094 | } | 1094 | } |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | 1097 | buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); |
1098 | if (!buf) { | 1098 | if (!buf) { |
1099 | ubifs_err("cannot allocate memory to scan LEB %d", lnum); | 1099 | ubifs_err("cannot allocate memory to scan LEB %d", lnum); |
1100 | goto out; | 1100 | goto out; |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index 72775d35b99e..ef5155e109a2 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
@@ -1270,10 +1270,9 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) | |||
1270 | lnum = branch->lnum; | 1270 | lnum = branch->lnum; |
1271 | offs = branch->offs; | 1271 | offs = branch->offs; |
1272 | pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); | 1272 | pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); |
1273 | if (!pnode) { | 1273 | if (!pnode) |
1274 | err = -ENOMEM; | 1274 | return -ENOMEM; |
1275 | goto out; | 1275 | |
1276 | } | ||
1277 | if (lnum == 0) { | 1276 | if (lnum == 0) { |
1278 | /* | 1277 | /* |
1279 | * This pnode was not written which just means that the LEB | 1278 | * This pnode was not written which just means that the LEB |
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 0a3c2c3f5c4a..0c9c69bd983a 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
@@ -1633,7 +1633,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) | |||
1633 | if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) | 1633 | if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) |
1634 | return 0; | 1634 | return 0; |
1635 | 1635 | ||
1636 | buf = p = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | 1636 | buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); |
1637 | if (!buf) { | 1637 | if (!buf) { |
1638 | ubifs_err("cannot allocate memory for ltab checking"); | 1638 | ubifs_err("cannot allocate memory for ltab checking"); |
1639 | return 0; | 1639 | return 0; |
@@ -1885,7 +1885,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) | |||
1885 | 1885 | ||
1886 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", | 1886 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", |
1887 | current->pid, lnum); | 1887 | current->pid, lnum); |
1888 | buf = p = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | 1888 | buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); |
1889 | if (!buf) { | 1889 | if (!buf) { |
1890 | ubifs_err("cannot allocate memory to dump LPT"); | 1890 | ubifs_err("cannot allocate memory to dump LPT"); |
1891 | return; | 1891 | return; |
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 2cdbd31641d7..09df318e368f 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
@@ -898,7 +898,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) | |||
898 | if (c->no_orphs) | 898 | if (c->no_orphs) |
899 | return 0; | 899 | return 0; |
900 | 900 | ||
901 | buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | 901 | buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); |
902 | if (!buf) { | 902 | if (!buf) { |
903 | ubifs_err("cannot allocate memory to check orphans"); | 903 | ubifs_err("cannot allocate memory to check orphans"); |
904 | return 0; | 904 | return 0; |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 936f2cbfe6b6..3dbad6fbd1eb 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -317,6 +317,32 @@ int ubifs_recover_master_node(struct ubifs_info *c) | |||
317 | goto out_free; | 317 | goto out_free; |
318 | } | 318 | } |
319 | memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); | 319 | memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); |
320 | |||
321 | /* | ||
322 | * We had to recover the master node, which means there was an | ||
323 | * unclean reboot. However, it is possible that the master node | ||
324 | * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set. | ||
325 | * E.g., consider the following chain of events: | ||
326 | * | ||
327 | * 1. UBIFS was cleanly unmounted, so the master node is clean | ||
328 | * 2. UBIFS is being mounted R/W and starts changing the master | ||
329 | * node in the first (%UBIFS_MST_LNUM). A power cut happens, | ||
330 | * so this LEB ends up with some amount of garbage at the | ||
331 | * end. | ||
332 | * 3. UBIFS is being mounted R/O. We reach this place and | ||
333 | * recover the master node from the second LEB | ||
334 | * (%UBIFS_MST_LNUM + 1). But we cannot update the media | ||
335 | * because we are being mounted R/O. We have to defer the | ||
336 | * operation. | ||
337 | * 4. However, this master node (@c->mst_node) is marked as | ||
338 | * clean (since the step 1). And if we just return, the | ||
339 | * mount code will be confused and won't recover the master | ||
340 | * node when it is re-mounter R/W later. | ||
341 | * | ||
342 | * Thus, to force the recovery by marking the master node as | ||
343 | * dirty. | ||
344 | */ | ||
345 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); | ||
320 | } else { | 346 | } else { |
321 | /* Write the recovered master node */ | 347 | /* Write the recovered master node */ |
322 | c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1; | 348 | c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index e5dc1e120e8d..be6c7b008f38 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1568,6 +1568,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1568 | mutex_lock(&c->umount_mutex); | 1568 | mutex_lock(&c->umount_mutex); |
1569 | dbg_save_space_info(c); | 1569 | dbg_save_space_info(c); |
1570 | c->remounting_rw = 1; | 1570 | c->remounting_rw = 1; |
1571 | c->ro_mount = 0; | ||
1571 | 1572 | ||
1572 | err = check_free_space(c); | 1573 | err = check_free_space(c); |
1573 | if (err) | 1574 | if (err) |
@@ -1670,19 +1671,30 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1670 | if (err) | 1671 | if (err) |
1671 | goto out; | 1672 | goto out; |
1672 | 1673 | ||
1674 | dbg_gen("re-mounted read-write"); | ||
1675 | c->remounting_rw = 0; | ||
1676 | |||
1673 | if (c->need_recovery) { | 1677 | if (c->need_recovery) { |
1674 | c->need_recovery = 0; | 1678 | c->need_recovery = 0; |
1675 | ubifs_msg("deferred recovery completed"); | 1679 | ubifs_msg("deferred recovery completed"); |
1680 | } else { | ||
1681 | /* | ||
1682 | * Do not run the debugging space check if the were doing | ||
1683 | * recovery, because when we saved the information we had the | ||
1684 | * file-system in a state where the TNC and lprops has been | ||
1685 | * modified in memory, but all the I/O operations (including a | ||
1686 | * commit) were deferred. So the file-system was in | ||
1687 | * "non-committed" state. Now the file-system is in committed | ||
1688 | * state, and of course the amount of free space will change | ||
1689 | * because, for example, the old index size was imprecise. | ||
1690 | */ | ||
1691 | err = dbg_check_space_info(c); | ||
1676 | } | 1692 | } |
1677 | |||
1678 | dbg_gen("re-mounted read-write"); | ||
1679 | c->ro_mount = 0; | ||
1680 | c->remounting_rw = 0; | ||
1681 | err = dbg_check_space_info(c); | ||
1682 | mutex_unlock(&c->umount_mutex); | 1693 | mutex_unlock(&c->umount_mutex); |
1683 | return err; | 1694 | return err; |
1684 | 1695 | ||
1685 | out: | 1696 | out: |
1697 | c->ro_mount = 1; | ||
1686 | vfree(c->orph_buf); | 1698 | vfree(c->orph_buf); |
1687 | c->orph_buf = NULL; | 1699 | c->orph_buf = NULL; |
1688 | if (c->bgt) { | 1700 | if (c->bgt) { |
@@ -1760,10 +1772,12 @@ static void ubifs_put_super(struct super_block *sb) | |||
1760 | * of the media. For example, there will be dirty inodes if we failed | 1772 | * of the media. For example, there will be dirty inodes if we failed |
1761 | * to write them back because of I/O errors. | 1773 | * to write them back because of I/O errors. |
1762 | */ | 1774 | */ |
1763 | ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); | 1775 | if (!c->ro_error) { |
1764 | ubifs_assert(c->budg_idx_growth == 0); | 1776 | ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); |
1765 | ubifs_assert(c->budg_dd_growth == 0); | 1777 | ubifs_assert(c->budg_idx_growth == 0); |
1766 | ubifs_assert(c->budg_data_growth == 0); | 1778 | ubifs_assert(c->budg_dd_growth == 0); |
1779 | ubifs_assert(c->budg_data_growth == 0); | ||
1780 | } | ||
1767 | 1781 | ||
1768 | /* | 1782 | /* |
1769 | * The 'c->umount_lock' prevents races between UBIFS memory shrinker | 1783 | * The 'c->umount_lock' prevents races between UBIFS memory shrinker |
@@ -2011,7 +2025,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
2011 | */ | 2025 | */ |
2012 | c->bdi.name = "ubifs", | 2026 | c->bdi.name = "ubifs", |
2013 | c->bdi.capabilities = BDI_CAP_MAP_COPY; | 2027 | c->bdi.capabilities = BDI_CAP_MAP_COPY; |
2014 | c->bdi.unplug_io_fn = default_unplug_io_fn; | ||
2015 | err = bdi_init(&c->bdi); | 2028 | err = bdi_init(&c->bdi); |
2016 | if (err) | 2029 | if (err) |
2017 | goto out_close; | 2030 | goto out_close; |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index c74400f88fe0..3299f469e712 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -56,6 +56,7 @@ | |||
56 | */ | 56 | */ |
57 | 57 | ||
58 | #include "ubifs.h" | 58 | #include "ubifs.h" |
59 | #include <linux/fs.h> | ||
59 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
60 | #include <linux/xattr.h> | 61 | #include <linux/xattr.h> |
61 | #include <linux/posix_acl_xattr.h> | 62 | #include <linux/posix_acl_xattr.h> |
@@ -80,7 +81,6 @@ enum { | |||
80 | }; | 81 | }; |
81 | 82 | ||
82 | static const struct inode_operations none_inode_operations; | 83 | static const struct inode_operations none_inode_operations; |
83 | static const struct address_space_operations none_address_operations; | ||
84 | static const struct file_operations none_file_operations; | 84 | static const struct file_operations none_file_operations; |
85 | 85 | ||
86 | /** | 86 | /** |
@@ -130,7 +130,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | /* Re-define all operations to be "nothing" */ | 132 | /* Re-define all operations to be "nothing" */ |
133 | inode->i_mapping->a_ops = &none_address_operations; | 133 | inode->i_mapping->a_ops = &empty_aops; |
134 | inode->i_op = &none_inode_operations; | 134 | inode->i_op = &none_inode_operations; |
135 | inode->i_fop = &none_file_operations; | 135 | inode->i_fop = &none_file_operations; |
136 | 136 | ||