Now, discard thread will issue discards in parallel with fstrim,
which will cause problem as below:
i.  maybe too many discards commands at some point
ii. disturb the order of block address, which is continuous in fstrim

Signed-off-by: Yunlei He <[email protected]>
---
 fs/f2fs/f2fs.h    | 1 +
 fs/f2fs/segment.c | 7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 56204a8..fec596d2 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -330,6 +330,7 @@ struct discard_cmd_control {
        atomic_t discard_cmd_cnt;               /* # of cached cmd count */
        struct rb_root_cached root;             /* root of discard rb-tree */
        bool rbtree_check;                      /* config for consistence check 
*/
+       atomic_t in_fstrim_cnt;                 /* # of fstrim in progress */
 };
 
 /* for the list of fsync inodes, used only during recovery */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6edcf83..cea1d27 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1655,7 +1655,8 @@ static int issue_discard_thread(void *data)
                        continue;
                if (kthread_should_stop())
                        return 0;
-               if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
+               if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)
+                                       || atomic_read(&dcc->in_fstrim_cnt)) {
                        wait_ms = dpolicy.max_interval;
                        continue;
                }
@@ -1996,6 +1997,7 @@ static int create_discard_cmd_control(struct f2fs_sb_info 
*sbi)
        atomic_set(&dcc->issued_discard, 0);
        atomic_set(&dcc->issing_discard, 0);
        atomic_set(&dcc->discard_cmd_cnt, 0);
+       atomic_set(&dcc->in_fstrim_cnt, 0);
        dcc->nr_discards = 0;
        dcc->max_discards = MAIN_SEGS(sbi) << sbi->log_blocks_per_seg;
        dcc->undiscard_blks = 0;
@@ -2720,6 +2722,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct 
fstrim_range *range)
        block_t start_block, end_block;
        struct cp_control cpc;
        struct discard_policy dpolicy;
+       struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
        unsigned long long trimmed = 0;
        int err = 0;
        bool need_align = test_opt(sbi, LFS) && sbi->segs_per_sec > 1;
@@ -2772,11 +2775,13 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct 
fstrim_range *range)
        end_block = START_BLOCK(sbi, end_segno + 1);
 
        __init_discard_policy(sbi, &dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
+       atomic_inc(&dcc->in_fstrim_cnt);
        trimmed = __issue_discard_cmd_range(sbi, &dpolicy,
                                        start_block, end_block);
 
        trimmed += __wait_discard_cmd_range(sbi, &dpolicy,
                                        start_block, end_block);
+       atomic_dec(&dcc->in_fstrim_cnt);
 out:
        if (!err)
                range->len = F2FS_BLK_TO_BYTES(trimmed);
-- 
1.9.1



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to