summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRitesh Harjani <riteshh@codeaurora.org>2018-03-14 15:46:37 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2018-04-10 21:39:41 -0700
commitbb700dcf673dbcdbd586ba593e014dd1e4504fa3 (patch)
tree33a010a77d8cd5138ebffcc09c444ff1257ddeb0
parentef00227cce638b1ca8bd8c04d342a8688b7400e9 (diff)
f2fs: Set GF_NOFS in read_cache_page_gfp while doing f2fs_quota_read
Quota code itself is serializing the operations by taking mutex_lock. It seems a below race can happen if GF_NOFS is not used in f2fs_quota_read __switch_to+0x88 __schedule+0x5b0 schedule+0x78 schedule_preempt_disabled+0x20 __mutex_lock_slowpath+0xdc //mutex owner is itself mutex_lock+0x2c dquot_commit+0x30 //mutex_lock(&dqopt->dqio_mutex); dqput+0xe0 __dquot_drop+0x80 dquot_drop+0x48 f2fs_evict_inode+0x218 evict+0xa8 dispose_list+0x3c prune_icache_sb+0x58 super_cache_scan+0xf4 do_shrink_slab+0x208 shrink_slab.part.40+0xac shrink_zone+0x1b0 do_try_to_free_pages+0x25c try_to_free_pages+0x164 __alloc_pages_nodemask+0x534 do_read_cache_page+0x6c read_cache_page+0x14 f2fs_quota_read+0xa4 read_blk+0x54 find_tree_dqentry+0xe4 find_tree_dqentry+0xb8 find_tree_dqentry+0xb8 find_tree_dqentry+0xb8 qtree_read_dquot+0x68 v2_read_dquot+0x24 dquot_acquire+0x5c // mutex_lock(&dqopt->dqio_mutex); dqget+0x238 __dquot_initialize+0xd4 dquot_initialize+0x10 dquot_file_open+0x34 f2fs_file_open+0x6c do_dentry_open+0x1e4 vfs_open+0x6c path_openat+0xa20 do_filp_open+0x4c do_sys_open+0x178 Change-Id: I6cc8417ad00426fd93bb42841e20217c0e44103a Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
-rw-r--r--fs/f2fs/super.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index aaeba346e9d7..872f9c1078f0 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1457,7 +1457,7 @@ static ssize_t f2fs_quota_read(struct super_block *sb, int type, char *data,
while (toread > 0) {
tocopy = min_t(unsigned long, sb->s_blocksize - offset, toread);
repeat:
- page = read_mapping_page(mapping, blkidx, NULL);
+ page = read_cache_page_gfp(mapping, blkidx, GFP_NOFS);
if (IS_ERR(page)) {
if (PTR_ERR(page) == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);