| From: Deepanshu Kartikey <kartikey406@gmail.com> |
| Subject: ocfs2: clear extent cache after moving/defragmenting extents |
| Date: Thu, 9 Oct 2025 21:19:03 +0530 |
| |
| The extent map cache can become stale when extents are moved or |
| defragmented, causing subsequent operations to see outdated extent flags. |
| This triggers a BUG_ON in ocfs2_refcount_cal_cow_clusters(). |
| |
| The problem occurs when: |
| 1. copy_file_range() creates a reflinked extent with OCFS2_EXT_REFCOUNTED |
| 2. ioctl(FITRIM) triggers ocfs2_move_extents() |
| 3. __ocfs2_move_extents_range() reads and caches the extent (flags=0x2) |
| 4. ocfs2_move_extent()/ocfs2_defrag_extent() calls __ocfs2_move_extent() |
| which clears OCFS2_EXT_REFCOUNTED flag on disk (flags=0x0) |
| 5. The extent map cache is not invalidated after the move |
| 6. Later write() operations read stale cached flags (0x2) but disk has |
| updated flags (0x0), causing a mismatch |
| 7. BUG_ON(!(rec->e_flags & OCFS2_EXT_REFCOUNTED)) triggers |
| |
| Fix by clearing the extent map cache after each extent move/defrag |
| operation in __ocfs2_move_extents_range(). This ensures subsequent |
| operations read fresh extent data from disk. |
| |
| Link: https://lore.kernel.org/all/20251009142917.517229-1-kartikey406@gmail.com/T/ |
| Link: https://lkml.kernel.org/r/20251009154903.522339-1-kartikey406@gmail.com |
| Fixes: 53069d4e7695 ("Ocfs2/move_extents: move/defrag extents within a certain range.") |
| Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> |
| Reported-by: syzbot+6fdd8fa3380730a4b22c@syzkaller.appspotmail.com |
| Tested-by: syzbot+6fdd8fa3380730a4b22c@syzkaller.appspotmail.com |
| Closes: https://syzkaller.appspot.com/bug?id=2959889e1f6e216585ce522f7e8bc002b46ad9e7 |
| Reviewed-by: Mark Fasheh <mark@fasheh.com> |
| Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> |
| Cc: Joel Becker <jlbec@evilplan.org> |
| Cc: Junxiao Bi <junxiao.bi@oracle.com> |
| Cc: Changwei Ge <gechangwei@live.cn> |
| Cc: Jun Piao <piaojun@huawei.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| fs/ocfs2/move_extents.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/fs/ocfs2/move_extents.c~ocfs2-clear-extent-cache-after-moving-defragmenting-extents |
| +++ a/fs/ocfs2/move_extents.c |
| @@ -867,6 +867,11 @@ static int __ocfs2_move_extents_range(st |
| mlog_errno(ret); |
| goto out; |
| } |
| + /* |
| + * Invalidate extent cache after moving/defragging to prevent |
| + * stale cached data with outdated extent flags. |
| + */ |
| + ocfs2_extent_map_trunc(inode, cpos); |
| |
| context->clusters_moved += alloc_size; |
| next: |
| _ |