diff options
author | Chao Yu <yuchao0@huawei.com> | 2018-06-04 11:20:17 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2018-06-04 17:31:11 -0400 |
commit | a1f72ac2c0a8d8a3488b31867c9255264331a4db (patch) | |
tree | f61d166a69bd130f8cade778733f9170a52ce4c0 | |
parent | 1061fd484bd442392c7bd491f7f154b1ce233173 (diff) |
f2fs: fix to update mtime correctly
If we change system time to the past, get_mtime() will return a
overflowed time, and SIT_I(sbi)->max_mtime will be udpated
incorrectly, this patch fixes the two issues.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/checkpoint.c | 2 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 7 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 17 |
3 files changed, 19 insertions, 7 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 8eb184c3de84..40b39db317ea 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -1233,7 +1233,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1233 | * modify checkpoint | 1233 | * modify checkpoint |
1234 | * version number is already updated | 1234 | * version number is already updated |
1235 | */ | 1235 | */ |
1236 | ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi)); | 1236 | ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi, true)); |
1237 | ckpt->free_segment_count = cpu_to_le32(free_segments(sbi)); | 1237 | ckpt->free_segment_count = cpu_to_le32(free_segments(sbi)); |
1238 | for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { | 1238 | for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { |
1239 | ckpt->cur_node_segno[i] = | 1239 | ckpt->cur_node_segno[i] = |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f0f9593185a7..6dbdf2c48fba 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -1822,8 +1822,9 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) | |||
1822 | (new_vblocks > sbi->blocks_per_seg))); | 1822 | (new_vblocks > sbi->blocks_per_seg))); |
1823 | 1823 | ||
1824 | se->valid_blocks = new_vblocks; | 1824 | se->valid_blocks = new_vblocks; |
1825 | se->mtime = get_mtime(sbi); | 1825 | se->mtime = get_mtime(sbi, false); |
1826 | SIT_I(sbi)->max_mtime = se->mtime; | 1826 | if (se->mtime > SIT_I(sbi)->max_mtime) |
1827 | SIT_I(sbi)->max_mtime = se->mtime; | ||
1827 | 1828 | ||
1828 | /* Update valid block bitmap */ | 1829 | /* Update valid block bitmap */ |
1829 | if (del > 0) { | 1830 | if (del > 0) { |
@@ -3884,7 +3885,7 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi) | |||
3884 | if (sit_i->min_mtime > mtime) | 3885 | if (sit_i->min_mtime > mtime) |
3885 | sit_i->min_mtime = mtime; | 3886 | sit_i->min_mtime = mtime; |
3886 | } | 3887 | } |
3887 | sit_i->max_mtime = get_mtime(sbi); | 3888 | sit_i->max_mtime = get_mtime(sbi, false); |
3888 | up_write(&sit_i->sentry_lock); | 3889 | up_write(&sit_i->sentry_lock); |
3889 | } | 3890 | } |
3890 | 3891 | ||
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index c574131ac7e1..f18fc82fbe99 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -745,12 +745,23 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start) | |||
745 | #endif | 745 | #endif |
746 | } | 746 | } |
747 | 747 | ||
748 | static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) | 748 | static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi, |
749 | bool base_time) | ||
749 | { | 750 | { |
750 | struct sit_info *sit_i = SIT_I(sbi); | 751 | struct sit_info *sit_i = SIT_I(sbi); |
751 | time64_t now = ktime_get_real_seconds(); | 752 | time64_t diff, now = ktime_get_real_seconds(); |
752 | 753 | ||
753 | return sit_i->elapsed_time + now - sit_i->mounted_time; | 754 | if (now >= sit_i->mounted_time) |
755 | return sit_i->elapsed_time + now - sit_i->mounted_time; | ||
756 | |||
757 | /* system time is set to the past */ | ||
758 | if (!base_time) { | ||
759 | diff = sit_i->mounted_time - now; | ||
760 | if (sit_i->elapsed_time >= diff) | ||
761 | return sit_i->elapsed_time - diff; | ||
762 | return 0; | ||
763 | } | ||
764 | return sit_i->elapsed_time; | ||
754 | } | 765 | } |
755 | 766 | ||
756 | static inline void set_summary(struct f2fs_summary *sum, nid_t nid, | 767 | static inline void set_summary(struct f2fs_summary *sum, nid_t nid, |