Skip to content

Commit d29460e

Browse files
author
Jaegeuk Kim
committed
f2fs: avoid deadlock caused by lock order of page and lock_op
- 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 <jaegeuk@kernel.org>
1 parent d1aa245 commit d29460e

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

fs/f2fs/data.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,8 +1404,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
14041404
}
14051405
}
14061406

1407-
if (fio->need_lock == LOCK_REQ)
1408-
f2fs_lock_op(fio->sbi);
1407+
/* Deadlock due to between page->lock and f2fs_lock_op */
1408+
if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
1409+
return -EAGAIN;
14091410

14101411
err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
14111412
if (err)
@@ -1667,7 +1668,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
16671668
}
16681669

16691670
done_index = page->index;
1670-
1671+
retry_write:
16711672
lock_page(page);
16721673

16731674
if (unlikely(page->mapping != mapping)) {
@@ -1703,6 +1704,15 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
17031704
unlock_page(page);
17041705
ret = 0;
17051706
continue;
1707+
} else if (ret == -EAGAIN) {
1708+
ret = 0;
1709+
if (wbc->sync_mode == WB_SYNC_ALL) {
1710+
cond_resched();
1711+
congestion_wait(BLK_RW_ASYNC,
1712+
HZ/50);
1713+
goto retry_write;
1714+
}
1715+
continue;
17061716
}
17071717
done_index = page->index + 1;
17081718
done = 1;

0 commit comments

Comments
 (0)