diff options
author | Chao Yu <yuchao0@huawei.com> | 2017-11-06 09:51:45 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2017-11-06 20:01:20 -0500 |
commit | a5fd505092863c520ddf26bd188716b532c1efcf (patch) | |
tree | 246d2326c249c6eb90b4677aed01dd0be017ea9d | |
parent | e8ed90a6d9a478938ef967a474a5c2a398759f4d (diff) |
f2fs: trace checkpoint reason in fsync()
This patch slightly changes need_do_checkpoint to return the detail
info that indicates why we need do checkpoint, then caller could print
it with trace message.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/f2fs.h | 12 | ||||
-rw-r--r-- | fs/f2fs/file.c | 34 | ||||
-rw-r--r-- | include/trace/events/f2fs.h | 24 |
3 files changed, 48 insertions, 22 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index cc46c22192ee..5c379a8ea075 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -913,6 +913,18 @@ enum need_lock_type { | |||
913 | LOCK_RETRY, | 913 | LOCK_RETRY, |
914 | }; | 914 | }; |
915 | 915 | ||
916 | enum cp_reason_type { | ||
917 | CP_NO_NEEDED, | ||
918 | CP_NON_REGULAR, | ||
919 | CP_HARDLINK, | ||
920 | CP_SB_NEED_CP, | ||
921 | CP_WRONG_PINO, | ||
922 | CP_NO_SPC_ROLL, | ||
923 | CP_NODE_NEED_CP, | ||
924 | CP_FASTBOOT_MODE, | ||
925 | CP_SPEC_LOG_NUM, | ||
926 | }; | ||
927 | |||
916 | enum iostat_type { | 928 | enum iostat_type { |
917 | APP_DIRECT_IO, /* app direct IOs */ | 929 | APP_DIRECT_IO, /* app direct IOs */ |
918 | APP_BUFFERED_IO, /* app buffered IOs */ | 930 | APP_BUFFERED_IO, /* app buffered IOs */ |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 847e933e4a84..8742c028acc6 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -144,27 +144,29 @@ static int get_parent_ino(struct inode *inode, nid_t *pino) | |||
144 | return 1; | 144 | return 1; |
145 | } | 145 | } |
146 | 146 | ||
147 | static inline bool need_do_checkpoint(struct inode *inode) | 147 | static inline enum cp_reason_type need_do_checkpoint(struct inode *inode) |
148 | { | 148 | { |
149 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 149 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
150 | bool need_cp = false; | 150 | enum cp_reason_type cp_reason = CP_NO_NEEDED; |
151 | 151 | ||
152 | if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) | 152 | if (!S_ISREG(inode->i_mode)) |
153 | need_cp = true; | 153 | cp_reason = CP_NON_REGULAR; |
154 | else if (inode->i_nlink != 1) | ||
155 | cp_reason = CP_HARDLINK; | ||
154 | else if (is_sbi_flag_set(sbi, SBI_NEED_CP)) | 156 | else if (is_sbi_flag_set(sbi, SBI_NEED_CP)) |
155 | need_cp = true; | 157 | cp_reason = CP_SB_NEED_CP; |
156 | else if (file_wrong_pino(inode)) | 158 | else if (file_wrong_pino(inode)) |
157 | need_cp = true; | 159 | cp_reason = CP_WRONG_PINO; |
158 | else if (!space_for_roll_forward(sbi)) | 160 | else if (!space_for_roll_forward(sbi)) |
159 | need_cp = true; | 161 | cp_reason = CP_NO_SPC_ROLL; |
160 | else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) | 162 | else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) |
161 | need_cp = true; | 163 | cp_reason = CP_NODE_NEED_CP; |
162 | else if (test_opt(sbi, FASTBOOT)) | 164 | else if (test_opt(sbi, FASTBOOT)) |
163 | need_cp = true; | 165 | cp_reason = CP_FASTBOOT_MODE; |
164 | else if (sbi->active_logs == 2) | 166 | else if (sbi->active_logs == 2) |
165 | need_cp = true; | 167 | cp_reason = CP_SPEC_LOG_NUM; |
166 | 168 | ||
167 | return need_cp; | 169 | return cp_reason; |
168 | } | 170 | } |
169 | 171 | ||
170 | static bool need_inode_page_update(struct f2fs_sb_info *sbi, nid_t ino) | 172 | static bool need_inode_page_update(struct f2fs_sb_info *sbi, nid_t ino) |
@@ -199,7 +201,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, | |||
199 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 201 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
200 | nid_t ino = inode->i_ino; | 202 | nid_t ino = inode->i_ino; |
201 | int ret = 0; | 203 | int ret = 0; |
202 | bool need_cp = false; | 204 | enum cp_reason_type cp_reason = 0; |
203 | struct writeback_control wbc = { | 205 | struct writeback_control wbc = { |
204 | .sync_mode = WB_SYNC_ALL, | 206 | .sync_mode = WB_SYNC_ALL, |
205 | .nr_to_write = LONG_MAX, | 207 | .nr_to_write = LONG_MAX, |
@@ -218,7 +220,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, | |||
218 | clear_inode_flag(inode, FI_NEED_IPU); | 220 | clear_inode_flag(inode, FI_NEED_IPU); |
219 | 221 | ||
220 | if (ret) { | 222 | if (ret) { |
221 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); | 223 | trace_f2fs_sync_file_exit(inode, cp_reason, datasync, ret); |
222 | return ret; | 224 | return ret; |
223 | } | 225 | } |
224 | 226 | ||
@@ -249,10 +251,10 @@ go_write: | |||
249 | * sudden-power-off. | 251 | * sudden-power-off. |
250 | */ | 252 | */ |
251 | down_read(&F2FS_I(inode)->i_sem); | 253 | down_read(&F2FS_I(inode)->i_sem); |
252 | need_cp = need_do_checkpoint(inode); | 254 | cp_reason = need_do_checkpoint(inode); |
253 | up_read(&F2FS_I(inode)->i_sem); | 255 | up_read(&F2FS_I(inode)->i_sem); |
254 | 256 | ||
255 | if (need_cp) { | 257 | if (cp_reason) { |
256 | /* all the dirty node pages should be flushed for POR */ | 258 | /* all the dirty node pages should be flushed for POR */ |
257 | ret = f2fs_sync_fs(inode->i_sb, 1); | 259 | ret = f2fs_sync_fs(inode->i_sb, 1); |
258 | 260 | ||
@@ -309,7 +311,7 @@ flush_out: | |||
309 | } | 311 | } |
310 | f2fs_update_time(sbi, REQ_TIME); | 312 | f2fs_update_time(sbi, REQ_TIME); |
311 | out: | 313 | out: |
312 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); | 314 | trace_f2fs_sync_file_exit(inode, cp_reason, datasync, ret); |
313 | f2fs_trace_ios(NULL, 1); | 315 | f2fs_trace_ios(NULL, 1); |
314 | return ret; | 316 | return ret; |
315 | } | 317 | } |
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 009745564214..30d30399db02 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h | |||
@@ -136,6 +136,18 @@ TRACE_DEFINE_ENUM(CP_TRIMMED); | |||
136 | { CP_UMOUNT, "Umount" }, \ | 136 | { CP_UMOUNT, "Umount" }, \ |
137 | { CP_TRIMMED, "Trimmed" }) | 137 | { CP_TRIMMED, "Trimmed" }) |
138 | 138 | ||
139 | #define show_fsync_cpreason(type) \ | ||
140 | __print_symbolic(type, \ | ||
141 | { CP_NO_NEEDED, "no needed" }, \ | ||
142 | { CP_NON_REGULAR, "non regular" }, \ | ||
143 | { CP_HARDLINK, "hardlink" }, \ | ||
144 | { CP_SB_NEED_CP, "sb needs cp" }, \ | ||
145 | { CP_WRONG_PINO, "wrong pino" }, \ | ||
146 | { CP_NO_SPC_ROLL, "no space roll forward" }, \ | ||
147 | { CP_NODE_NEED_CP, "node needs cp" }, \ | ||
148 | { CP_FASTBOOT_MODE, "fastboot mode" }, \ | ||
149 | { CP_SPEC_LOG_NUM, "log type is 2" }) | ||
150 | |||
139 | struct victim_sel_policy; | 151 | struct victim_sel_policy; |
140 | struct f2fs_map_blocks; | 152 | struct f2fs_map_blocks; |
141 | 153 | ||
@@ -210,14 +222,14 @@ DEFINE_EVENT(f2fs__inode, f2fs_sync_file_enter, | |||
210 | 222 | ||
211 | TRACE_EVENT(f2fs_sync_file_exit, | 223 | TRACE_EVENT(f2fs_sync_file_exit, |
212 | 224 | ||
213 | TP_PROTO(struct inode *inode, int need_cp, int datasync, int ret), | 225 | TP_PROTO(struct inode *inode, int cp_reason, int datasync, int ret), |
214 | 226 | ||
215 | TP_ARGS(inode, need_cp, datasync, ret), | 227 | TP_ARGS(inode, cp_reason, datasync, ret), |
216 | 228 | ||
217 | TP_STRUCT__entry( | 229 | TP_STRUCT__entry( |
218 | __field(dev_t, dev) | 230 | __field(dev_t, dev) |
219 | __field(ino_t, ino) | 231 | __field(ino_t, ino) |
220 | __field(int, need_cp) | 232 | __field(int, cp_reason) |
221 | __field(int, datasync) | 233 | __field(int, datasync) |
222 | __field(int, ret) | 234 | __field(int, ret) |
223 | ), | 235 | ), |
@@ -225,15 +237,15 @@ TRACE_EVENT(f2fs_sync_file_exit, | |||
225 | TP_fast_assign( | 237 | TP_fast_assign( |
226 | __entry->dev = inode->i_sb->s_dev; | 238 | __entry->dev = inode->i_sb->s_dev; |
227 | __entry->ino = inode->i_ino; | 239 | __entry->ino = inode->i_ino; |
228 | __entry->need_cp = need_cp; | 240 | __entry->cp_reason = cp_reason; |
229 | __entry->datasync = datasync; | 241 | __entry->datasync = datasync; |
230 | __entry->ret = ret; | 242 | __entry->ret = ret; |
231 | ), | 243 | ), |
232 | 244 | ||
233 | TP_printk("dev = (%d,%d), ino = %lu, checkpoint is %s, " | 245 | TP_printk("dev = (%d,%d), ino = %lu, cp_reason: %s, " |
234 | "datasync = %d, ret = %d", | 246 | "datasync = %d, ret = %d", |
235 | show_dev_ino(__entry), | 247 | show_dev_ino(__entry), |
236 | __entry->need_cp ? "needed" : "not needed", | 248 | show_fsync_cpreason(__entry->cp_reason), |
237 | __entry->datasync, | 249 | __entry->datasync, |
238 | __entry->ret) | 250 | __entry->ret) |
239 | ); | 251 | ); |