[lvc-project] [PATCH] ocfs2: uncache inode after ocfs2_search_dirblock() search failure
Joseph Qi
joseph.qi at linux.alibaba.com
Mon Dec 30 04:57:36 MSK 2024
On 2024/12/29 00:33, Dmitry Antipov wrote:
> On 12/28/24 3:27 PM, Joseph Qi wrote:
>
>> Hi, don't see the relationship between above logic and the triggered
>> bug.
>> Could you please elobrate more how it happens?
>
> As triggered by the syzbot's reproducer, the problem is initiated by
> 'mknodat()'...
>
> -> mknodat()
> ...
> -> filename_create()
> ...
> -> ocfs2_lookup()
> -> ocfs2_find_files_on_disk()
> -> ocfs2_find_entry()
> -> ocfs2_find_entry_id()
> ...
> -> ocfs2_read_inode_block()
> -> ocfs2_read_blocks()
> -> ocfs2_set_buffer_uptodate() ;; [1] Buffer head is now cached
> ...
> if (found == 1)
> return di_bh; ;; Buffer head will be used
> /* Hmm..... */ ;; [2]
> brelse(di_bh); ;; [3] Buffer head is now unused
>
> ...with followed 'ioctl()':
>
> -> ioctl(..., OCFS2_IOC_GROUP_ADD, ...)
> -> ocfs2_ioctl()
> -> ocfs2_group_add()
> -> ocfs2_read_blocks_sync()
> -> ocfs2_set_new_buffer_uptodate() ;; OOPS [4]
This is a group bh, but the above bh in ocfs2_find_entry() seems not.
>
> OOPS at [4] happens becase the corresponding buffer head is not actually
> "new". It was "new" at [1] but was not exprunged from the inode cache
> before 'brelse()' at [3]. I.e. OCFS2 cache has an inconsistent view of
> the data provided by the block layer, and it is expected that adding
> 'ocfs2_remove_from_cache()' at [2] should fix this problem.
>
Even if found, the returned di_bh will also be brelsed in
ocfs2_free_dir_lookup_result() without removing from cache.
So if it is the case, it seems that it will also BUG when found.
Thanks,
Joseph
More information about the lvc-project
mailing list