]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.11.2/f2fs-fix-fs-corruption-due-to-zero-inode-page.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.11.2 / f2fs-fix-fs-corruption-due-to-zero-inode-page.patch
1 From 9bb02c3627f46e50246bf7ab957b56ffbef623cb Mon Sep 17 00:00:00 2001
2 From: Jaegeuk Kim <jaegeuk@kernel.org>
3 Date: Tue, 11 Apr 2017 19:01:26 -0700
4 Subject: f2fs: fix fs corruption due to zero inode page
5
6 From: Jaegeuk Kim <jaegeuk@kernel.org>
7
8 commit 9bb02c3627f46e50246bf7ab957b56ffbef623cb upstream.
9
10 This patch fixes the following scenario.
11
12 - f2fs_create/f2fs_mkdir - write_checkpoint
13 - f2fs_mark_inode_dirty_sync - block_operations
14 - f2fs_lock_all
15 - f2fs_sync_inode_meta
16 - f2fs_unlock_all
17 - sync_inode_metadata
18 - f2fs_lock_op
19 - f2fs_write_inode
20 - update_inode_page
21 - get_node_page
22 return -ENOENT
23 - new_inode_page
24 - fill_node_footer
25 - f2fs_mark_inode_dirty_sync
26 - ...
27 - f2fs_unlock_op
28 - f2fs_inode_synced
29 - f2fs_lock_all
30 - do_checkpoint
31
32 In this checkpoint, we can get an inode page which contains zeros having valid
33 node footer only.
34
35 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37
38 ---
39 fs/f2fs/inode.c | 2 +-
40 fs/f2fs/namei.c | 20 ++++++++++----------
41 2 files changed, 11 insertions(+), 11 deletions(-)
42
43 --- a/fs/f2fs/inode.c
44 +++ b/fs/f2fs/inode.c
45 @@ -316,7 +316,6 @@ retry:
46 } else if (err != -ENOENT) {
47 f2fs_stop_checkpoint(sbi, false);
48 }
49 - f2fs_inode_synced(inode);
50 return 0;
51 }
52 ret = update_inode(inode, node_page);
53 @@ -448,6 +447,7 @@ void handle_failed_inode(struct inode *i
54 * in a panic when flushing dirty inodes in gdirty_list.
55 */
56 update_inode_page(inode);
57 + f2fs_inode_synced(inode);
58
59 /* don't make bad inode, since it becomes a regular file. */
60 unlock_new_inode(inode);
61 --- a/fs/f2fs/namei.c
62 +++ b/fs/f2fs/namei.c
63 @@ -148,8 +148,6 @@ static int f2fs_create(struct inode *dir
64 inode->i_mapping->a_ops = &f2fs_dblock_aops;
65 ino = inode->i_ino;
66
67 - f2fs_balance_fs(sbi, true);
68 -
69 f2fs_lock_op(sbi);
70 err = f2fs_add_link(dentry, inode);
71 if (err)
72 @@ -163,6 +161,8 @@ static int f2fs_create(struct inode *dir
73
74 if (IS_DIRSYNC(dir))
75 f2fs_sync_fs(sbi->sb, 1);
76 +
77 + f2fs_balance_fs(sbi, true);
78 return 0;
79 out:
80 handle_failed_inode(inode);
81 @@ -423,8 +423,6 @@ static int f2fs_symlink(struct inode *di
82 inode_nohighmem(inode);
83 inode->i_mapping->a_ops = &f2fs_dblock_aops;
84
85 - f2fs_balance_fs(sbi, true);
86 -
87 f2fs_lock_op(sbi);
88 err = f2fs_add_link(dentry, inode);
89 if (err)
90 @@ -487,6 +485,8 @@ err_out:
91 }
92
93 kfree(sd);
94 +
95 + f2fs_balance_fs(sbi, true);
96 return err;
97 out:
98 handle_failed_inode(inode);
99 @@ -508,8 +508,6 @@ static int f2fs_mkdir(struct inode *dir,
100 inode->i_mapping->a_ops = &f2fs_dblock_aops;
101 mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);
102
103 - f2fs_balance_fs(sbi, true);
104 -
105 set_inode_flag(inode, FI_INC_LINK);
106 f2fs_lock_op(sbi);
107 err = f2fs_add_link(dentry, inode);
108 @@ -524,6 +522,8 @@ static int f2fs_mkdir(struct inode *dir,
109
110 if (IS_DIRSYNC(dir))
111 f2fs_sync_fs(sbi->sb, 1);
112 +
113 + f2fs_balance_fs(sbi, true);
114 return 0;
115
116 out_fail:
117 @@ -554,8 +554,6 @@ static int f2fs_mknod(struct inode *dir,
118 init_special_inode(inode, inode->i_mode, rdev);
119 inode->i_op = &f2fs_special_inode_operations;
120
121 - f2fs_balance_fs(sbi, true);
122 -
123 f2fs_lock_op(sbi);
124 err = f2fs_add_link(dentry, inode);
125 if (err)
126 @@ -569,6 +567,8 @@ static int f2fs_mknod(struct inode *dir,
127
128 if (IS_DIRSYNC(dir))
129 f2fs_sync_fs(sbi->sb, 1);
130 +
131 + f2fs_balance_fs(sbi, true);
132 return 0;
133 out:
134 handle_failed_inode(inode);
135 @@ -595,8 +595,6 @@ static int __f2fs_tmpfile(struct inode *
136 inode->i_mapping->a_ops = &f2fs_dblock_aops;
137 }
138
139 - f2fs_balance_fs(sbi, true);
140 -
141 f2fs_lock_op(sbi);
142 err = acquire_orphan_inode(sbi);
143 if (err)
144 @@ -622,6 +620,8 @@ static int __f2fs_tmpfile(struct inode *
145 /* link_count was changed by d_tmpfile as well. */
146 f2fs_unlock_op(sbi);
147 unlock_new_inode(inode);
148 +
149 + f2fs_balance_fs(sbi, true);
150 return 0;
151
152 release_out: