From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oo1-f72.google.com (mail-oo1-f72.google.com [209.85.161.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DC0D285068 for ; Sat, 6 Dec 2025 08:50:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.72 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765011054; cv=none; b=mbGEilaP+3E2jhOFpKK+ZEJ7kFC5N1WEl2Cyp81BHGX1cdMIY0RCrmvntV2ZoZ9bmSsiB/itJTEzphsRm5/WX/cwHG1H9gwrMy/sE7d5oYKHRJKFEF8y2BB1VFvSEodNQCx2Rs7eTzqagzJEIvDcJMfblMrrwn08YJ6cohnmcUY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765011054; c=relaxed/simple; bh=6mJflFETH9axu64lovBR5v/zkAObosZlixOy/i9OKZU=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=qlLJjx8oVt5pQ0/T+/RtZ0AOoA0/Sqd3BR8y6NH+Kgwb5w2G+epgOYTrWTV/79Yg5rwBeb1wIDFy3Esy2/q17mMo6Gy3rEsOPgnx52vNl4XOVUN4JuV08eLqVWB9IA7MtghtXvQrZyflIti7unRDn2nCF3SjIxfHSssIK5eRxyg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.161.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-oo1-f72.google.com with SMTP id 006d021491bc7-657a6c9d45eso1963181eaf.2 for ; Sat, 06 Dec 2025 00:50:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765011052; x=1765615852; h=to:from:subject:message-id:in-reply-to:date:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gVGImFg3GBpCuZ/wRGCD/tntLlFOXNFk1PuKHbsSB7Y=; b=ZvsFg7jnWJnTBtUVTJv59M0wh5oTGkrp57Hh40nHMCAuFzmdtROPs1vv/tb/pGKPJM aABQu5Kq8ltt54REH+sSvJ2WmxIuKMCMLboVQEHJmKKcDa55GwMY1mOeBNXnnLKHFTpa itvESzPBXtLfJqOEVuJ3AfUrwnlbDYM7Lp1fZwn50H+qH2RdFYAXnnZHNFiS5otFtyQD yZ1lZXa+GQgtEgrZx/tq1JFXM5TrBKzIQrHz3OqsOlxPpDxtULstUJsUInH2IoB9mBS6 8/CADnLLEpCPhE28LaMX7YhDP8YnfmfzDG3C9Kp/FrPtyLUY+K2k0/H5JdNj/bfrR1qt rPNg== X-Gm-Message-State: AOJu0YxEixo72r6wt1Z18pDdHAxtUwid1dWL6GMMQN9mfKUtuTgvIKet RfBW/2YnAGaXiemaX0TNiOnL87upD2A02CT917MtwDZz2fqpzsMwtzNy8e9ucJ6aMkk1skcD8lw oNQ5tqEXWGTAFcU8kkni8xc/lCueGTE6Ocqgyt47UAhVe+DNajcSqC+4VXPI= X-Google-Smtp-Source: AGHT+IHQM3eJvNlgiIis79Ig/A5RxGi2MTkXycN6ty3otaIs18ZFA7E83ctlIWweaelfz4UpwQchSEAPp4tADXx3T6aWiHQ5SxZJ Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a05:6820:f028:b0:659:9a49:90ae with SMTP id 006d021491bc7-6599a956202mr826450eaf.45.1765011052323; Sat, 06 Dec 2025 00:50:52 -0800 (PST) Date: Sat, 06 Dec 2025 00:50:52 -0800 In-Reply-To: <69332cf9.a70a0220.243dc6.0011.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <6933ee6c.a70a0220.38f243.001c.GAE@google.com> Subject: Forwarded: [PATCH] f2fs: fix hung task in block_operations during checkpoint From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: [PATCH] f2fs: fix hung task in block_operations during checkpoint Author: kartikey406@gmail.com #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master f2fs_sync_inode_meta() can return 0 (success) even when f2fs_update_inode_page() fails and triggers f2fs_stop_checkpoint(). This happens because the error flag check only occurs at the start of each loop iteration, not after f2fs_update_inode_page() returns. When I/O errors occur: 1. f2fs_update_inode_page() retries 8 times then calls f2fs_stop_checkpoint(), which sets CP_ERROR_FLAG 2. f2fs_sync_inode_meta() returns 0 without checking the error flag 3. block_operations() sees success and loops back to retry_flush_quotas 4. Dirty inodes remain on list (sync failed), loop repeats forever 5. Checkpoint never completes, waiters block indefinitely This causes hung tasks when operations like unlink wait for checkpoint completion while holding locks that other tasks need. Fix by checking f2fs_cp_error() after processing each inode in f2fs_sync_inode_meta() to detect errors from f2fs_update_inode_page(). Reported-by: syzbot+4235e4d7b6fd75704528@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4235e4d7b6fd75704528 Signed-off-by: Deepanshu Kartikey --- fs/f2fs/checkpoint.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index bbe07e3a6c75..efe72e517955 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1216,8 +1216,9 @@ static int block_operations(struct f2fs_sb_info *sbi) * Let's flush inline_data in dirty node pages. */ f2fs_flush_inline_data(sbi); - + printk("f2fs: block_ops enter\n"); retry_flush_quotas: + printk("f2fs: block_ops retry_flush_quotas cnt=%d\n", cnt); f2fs_lock_all(sbi); if (__need_flush_quota(sbi)) { bool need_lock = sbi->umount_lock_holder != current; @@ -1242,6 +1243,8 @@ static int block_operations(struct f2fs_sb_info *sbi) retry_flush_dents: /* write all the dirty dentry pages */ + printk("f2fs: block_ops retry_flush_dents dirty_dents=%lld\n", + get_pages(sbi, F2FS_DIRTY_DENTS)); if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true); @@ -1256,7 +1259,8 @@ static int block_operations(struct f2fs_sb_info *sbi) * until finishing nat/sit flush. inode->i_blocks can be updated. */ f2fs_down_write(&sbi->node_change); - + printk("f2fs: block_ops check DIRTY_IMETA=%lld\n", + get_pages(sbi, F2FS_DIRTY_IMETA)); if (get_pages(sbi, F2FS_DIRTY_IMETA)) { f2fs_up_write(&sbi->node_change); f2fs_unlock_all(sbi); @@ -1268,6 +1272,8 @@ static int block_operations(struct f2fs_sb_info *sbi) } retry_flush_nodes: + printk("f2fs: block_ops retry_flush_nodes dirty_nodes=%lld\n", + get_pages(sbi, F2FS_DIRTY_NODES)); f2fs_down_write(&sbi->node_write); if (get_pages(sbi, F2FS_DIRTY_NODES)) { @@ -1290,6 +1296,7 @@ static int block_operations(struct f2fs_sb_info *sbi) */ __prepare_cp_block(sbi); f2fs_up_write(&sbi->node_change); + printk("f2fs: block_ops done\n"); return err; } @@ -1659,9 +1666,10 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) return 0; f2fs_warn(sbi, "Start checkpoint disabled!"); } + printk("f2fs_cp: 1 before cp_global_sem\n"); if (cpc->reason != CP_RESIZE) f2fs_down_write(&sbi->cp_global_sem); - + printk("f2fs_cp: 2 after cp_global_sem\n"); stat_cp_time(cpc, CP_TIME_LOCK); if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) && @@ -1669,16 +1677,18 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ((cpc->reason & CP_DISCARD) && !sbi->discard_blks))) goto out; if (unlikely(f2fs_cp_error(sbi))) { + printk("f2fs_cp: 3 cp_error detected early\n"); err = -EIO; goto out; } trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops"); - + printk("f2fs_cp: 4 before block_operations\n"); err = block_operations(sbi); + printk("f2fs_cp: 5 after block_operations err=%d cp_error=%d\n", err, f2fs_cp_error(sbi)); if (err) goto out; - + //printk("f2fs_cp: 6 before do_checkpoint\n"); stat_cp_time(cpc, CP_TIME_OP_LOCK); trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops"); @@ -1724,8 +1734,10 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* save inmem log status */ f2fs_save_inmem_curseg(sbi); + printk("f2fs_cp: 4 before block_operations\n"); err = do_checkpoint(sbi, cpc); + printk("f2fs_cp: 7 after do_checkpoint err=%d\n", err); if (err) { f2fs_err(sbi, "do_checkpoint failed err:%d, stop checkpoint", err); f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); -- 2.43.0