- punch_hole
 - fill_zero
  - f2fs_lock_op
  - get_new_data_page
   - lock_page

- f2fs_write_data_pages
 - lock_page
 - do_write_data_page
  - f2fs_lock_op

Signed-off-by: Jaegeuk Kim <jaeg...@kernel.org>
---

 Change log from v1:
 - hide EAGAIN to users

 fs/f2fs/data.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 72fc866cad19..7dd5fb647d43 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1404,8 +1404,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
                }
        }
 
-       if (fio->need_lock == LOCK_REQ)
-               f2fs_lock_op(fio->sbi);
+       /* Deadlock due to between page->lock and f2fs_lock_op */
+       if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
+               return -EAGAIN;
 
        err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
        if (err)
@@ -1667,7 +1668,7 @@ static int f2fs_write_cache_pages(struct address_space 
*mapping,
                        }
 
                        done_index = page->index;
-
+retry_write:
                        lock_page(page);
 
                        if (unlikely(page->mapping != mapping)) {
@@ -1703,6 +1704,15 @@ static int f2fs_write_cache_pages(struct address_space 
*mapping,
                                        unlock_page(page);
                                        ret = 0;
                                        continue;
+                               } else if (ret == -EAGAIN) {
+                                       ret = 0;
+                                       if (wbc->sync_mode == WB_SYNC_ALL) {
+                                               cond_resched();
+                                               congestion_wait(BLK_RW_ASYNC,
+                                                                       HZ/50);
+                                               goto retry_write;
+                                       }
+                                       continue;
                                }
                                done_index = page->index + 1;
                                done = 1;
-- 
2.13.0.rc1.294.g07d810a77f-goog

Reply via email to