f2fs: fix a deadlock for summary page lock vs. sentry_lock
authorJaegeuk Kim <jaegeuk@kernel.org>
Fri, 29 May 2015 01:19:17 +0000 (18:19 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 1 Jun 2015 23:21:09 +0000 (16:21 -0700)
In f2fs_gc:                      In f2fs_replace_block:
 - lock_page(sum_page)
  - check_valid_map()            - mutex_lock(sentry_lock)
   - mutex_lock(sentry_lock)     - change_curseg()
                                  - lock_page(sum_page)

This patch fixes the deadlock condition.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c

index 43354cb3ce94927bf28241815c5c6ef3d592d7dc..e1e73617d13b6cb5e1fca434e4ab823dfa534eca 100644 (file)
@@ -750,6 +750,15 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
 
        sum = page_address(sum_page);
 
+       /*
+        * this is to avoid deadlock:
+        * - lock_page(sum_page)         - f2fs_replace_block
+        *  - check_valid_map()            - mutex_lock(sentry_lock)
+        *   - mutex_lock(sentry_lock)     - change_curseg()
+        *                                  - lock_page(sum_page)
+        */
+       unlock_page(sum_page);
+
        switch (GET_SUM_TYPE((&sum->footer))) {
        case SUM_TYPE_NODE:
                gc_node_segment(sbi, sum->entries, segno, gc_type);
@@ -763,7 +772,7 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
        stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer)), gc_type);
        stat_inc_call_count(sbi->stat_info);
 
-       f2fs_put_page(sum_page, 1);
+       f2fs_put_page(sum_page, 0);
 }
 
 int f2fs_gc(struct f2fs_sb_info *sbi)