]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
f2fs: introduce CP_TRIMMED_FLAG to avoid unneeded discard
authorChao Yu <yuchao0@huawei.com>
Fri, 28 Apr 2017 05:56:08 +0000 (13:56 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Wed, 3 May 2017 17:04:56 +0000 (10:04 -0700)
Introduce CP_TRIMMED_FLAG to indicate all invalid block were trimmed
before umount, so once we do mount with image which contain the flag,
we don't record invalid blocks as undiscard one, when fstrim is being
triggered, we can avoid issuing redundant discard commands.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/f2fs.h
fs/f2fs/segment.c
fs/f2fs/super.c
include/linux/f2fs_fs.h
include/trace/events/f2fs.h

index 27578903eeb66146ff2cbf8c737d8f4264e06621..ea9c317b5916ee51610069c2c58cdb504f95969d 100644 (file)
@@ -1059,6 +1059,9 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
                        sbi->blocks_per_seg - NM_I(sbi)->nat_bits_blocks)
                disable_nat_bits(sbi, false);
 
+       if (cpc->reason & CP_TRIMMED)
+               __set_ckpt_flags(ckpt, CP_TRIMMED_FLAG);
+
        if (cpc->reason & CP_UMOUNT)
                __set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
        else
index 37360b9ad2631acc7563e25cdd15ad2626e38c87..f0481fb521424875d0fc8fcb3bafcf638664985d 100644 (file)
@@ -130,6 +130,7 @@ enum {
 #define        CP_SYNC         0x00000004
 #define        CP_RECOVERY     0x00000008
 #define        CP_DISCARD      0x00000010
+#define CP_TRIMMED     0x00000020
 
 #define DEF_BATCHED_TRIM_SECTIONS      2048
 #define BATCHED_TRIM_SEGMENTS(sbi)     \
index 69b99a8f9a01293a1f7620c2dff3eccfa633ecd5..a32268eeb47273668bcea4cc76e7c8df882679d1 100644 (file)
@@ -3005,10 +3005,17 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
 
                        /* build discard map only one time */
                        if (f2fs_discard_en(sbi)) {
-                               memcpy(se->discard_map, se->cur_valid_map,
-                                                       SIT_VBLOCK_MAP_SIZE);
-                               sbi->discard_blks += sbi->blocks_per_seg -
-                                                       se->valid_blocks;
+                               if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) {
+                                       memset(se->discard_map, 0xff,
+                                               SIT_VBLOCK_MAP_SIZE);
+                               } else {
+                                       memcpy(se->discard_map,
+                                               se->cur_valid_map,
+                                               SIT_VBLOCK_MAP_SIZE);
+                                       sbi->discard_blks +=
+                                               sbi->blocks_per_seg -
+                                               se->valid_blocks;
+                               }
                        }
 
                        if (sbi->segs_per_sec > 1)
@@ -3032,10 +3039,15 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
                seg_info_from_raw_sit(se, &sit);
 
                if (f2fs_discard_en(sbi)) {
-                       memcpy(se->discard_map, se->cur_valid_map,
-                                               SIT_VBLOCK_MAP_SIZE);
-                       sbi->discard_blks += old_valid_blocks -
-                                               se->valid_blocks;
+                       if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) {
+                               memset(se->discard_map, 0xff,
+                                                       SIT_VBLOCK_MAP_SIZE);
+                       } else {
+                               memcpy(se->discard_map, se->cur_valid_map,
+                                                       SIT_VBLOCK_MAP_SIZE);
+                               sbi->discard_blks += old_valid_blocks -
+                                                       se->valid_blocks;
+                       }
                }
 
                if (sbi->segs_per_sec > 1)
index 4cd3bee6775f2349c94a30b8e8b7c37f05cb2f59..9a14b25903378ac351b8129a06b94e7d868a6017 100644 (file)
@@ -797,6 +797,13 @@ static void f2fs_put_super(struct super_block *sb)
        /* be sure to wait for any on-going discard commands */
        f2fs_wait_discard_bios(sbi);
 
+       if (!sbi->discard_blks) {
+               struct cp_control cpc = {
+                       .reason = CP_UMOUNT | CP_TRIMMED,
+               };
+               write_checkpoint(sbi, &cpc);
+       }
+
        /* write_checkpoint can update stat informaion */
        f2fs_destroy_stats(sbi);
 
index 093549e10ee267a8be8bb92765e1ad53762c4e53..b6feed6547ce92862acaf3153c5859d3eb132ccb 100644 (file)
@@ -114,6 +114,7 @@ struct f2fs_super_block {
 /*
  * For checkpoint
  */
+#define CP_TRIMMED_FLAG                0x00000100
 #define CP_NAT_BITS_FLAG       0x00000080
 #define CP_CRC_RECOVERY_FLAG   0x00000040
 #define CP_FASTBOOT_FLAG       0x00000020
index 2e8f68f244d4656a1693f6e51e0913a38f0db460..c78a223a0d9c633266724273b39fbcbadf282a1a 100644 (file)
@@ -44,6 +44,7 @@ TRACE_DEFINE_ENUM(CP_FASTBOOT);
 TRACE_DEFINE_ENUM(CP_SYNC);
 TRACE_DEFINE_ENUM(CP_RECOVERY);
 TRACE_DEFINE_ENUM(CP_DISCARD);
+TRACE_DEFINE_ENUM(CP_TRIMMED);
 
 #define show_block_type(type)                                          \
        __print_symbolic(type,                                          \
@@ -125,7 +126,8 @@ TRACE_DEFINE_ENUM(CP_DISCARD);
                { CP_FASTBOOT,  "Fastboot" },                           \
                { CP_SYNC,      "Sync" },                               \
                { CP_RECOVERY,  "Recovery" },                           \
-               { CP_DISCARD,   "Discard" })
+               { CP_DISCARD,   "Discard" },                            \
+               { CP_UMOUNT | CP_TRIMMED,       "Umount,Trimmed" })
 
 struct victim_sel_policy;
 struct f2fs_map_blocks;