For sync io, if it is blocked by cp, we try to do IPU for this page.

Signed-off-by: Hou Pengyang <[email protected]>
---
 fs/f2fs/data.c | 36 ++++++++++++++++++++++++++++++++----
 fs/f2fs/f2fs.h |  5 +++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index e41f5ed..26362ae 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1329,9 +1329,9 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
        return PTR_ERR(fio->encrypted_page);
 }
 
-static inline bool need_inplace_update(struct f2fs_io_info *fio)
+static inline bool safe_for_ipu(struct f2fs_io_info *fio)
 {
-       struct inode *inode = fio->page->mapping->host;
+       struct inode *inode = fio->page->mapping->host;
 
        if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode))
                return false;
@@ -1339,6 +1339,16 @@ static inline bool need_inplace_update(struct 
f2fs_io_info *fio)
                return false;
        if (IS_ATOMIC_WRITTEN_PAGE(fio->page))
                return false;
+       return true;
+
+}
+
+static inline bool need_inplace_update(struct f2fs_io_info *fio)
+{
+       struct inode *inode = fio->page->mapping->host;
+
+       if (!safe_for_ipu(fio))
+               return false;
 
        return need_inplace_update_policy(inode, fio);
 }
@@ -1352,6 +1362,13 @@ static inline bool valid_ipu_blkaddr(struct f2fs_io_info 
*fio)
        return true;
 }
 
+static inline bool is_sync_io(struct f2fs_io_info *fio)
+{
+       if (fio && fio->op == REQ_OP_WRITE && fio->op_flags & REQ_SYNC)
+               return true;
+       return false;
+}
+
 int do_write_data_page(struct f2fs_io_info *fio)
 {
        struct page *page = fio->page;
@@ -1393,8 +1410,19 @@ int do_write_data_page(struct f2fs_io_info *fio)
        } else
                return err;
 
-       if (fio->need_lock)
-               f2fs_lock_op(fio->sbi);
+       /*
+        * After checking all the IPU senario, we try to lock_op
+        * If lock_op fail, we do another IPU try for sync io.
+        */
+       if (fio->need_lock && !f2fs_try_lock_op(fio->sbi)) {
+               if (valid_ipu_blkaddr(fio) &&
+                               is_sync_io(fio) && safe_for_ipu(fio)) {
+                       fio->need_lock = false;
+                       ipu_force = true;
+               } else {
+                       f2fs_lock_op(fio->sbi);
+               }
+       }
 
        if (!dn.node_page_locked) {
                /*
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 2d50d7b..e820253 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1268,6 +1268,11 @@ static inline bool enabled_nat_bits(struct f2fs_sb_info 
*sbi,
        return (cpc) ? (cpc->reason & CP_UMOUNT) && set : set;
 }
 
+static inline int f2fs_try_lock_op(struct f2fs_sb_info *sbi)
+{
+       return down_read_trylock(&sbi->cp_rwsem);
+}
+
 static inline void f2fs_lock_op(struct f2fs_sb_info *sbi)
 {
        down_read(&sbi->cp_rwsem);
-- 
2.10.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to