writeback: Fix NULL pointer dereference issue with inode->i_wb
There is a potential race between evict() and __mark_inode_dirty()
observed with EXT4 FS. The ext4/jbd2 context is marking the inode as
dirty while at the same time evict() is happening on another core.
Due to this race, __mark_inode_dirty() is adding the inode to
bdi_writeback IO dirty list, after evict() path has removed this
inode from the writeback list. This results NULL pointer dereference
issue when accessing inode->i_wb from writeback thread as below -
locked_inode_to_wb_and_lock_list+0x2c/0x2a0
inode_to_wb_and_lock_list+0x24/0x30
writeback_sb_inodes+0x2cc/0x444
__writeback_inodes_wb+0x78/0xbc
wb_writeback+0x1c8/0x3d0
wb_workfn+0x1a8/0x4d4
process_one_work+0x1c0/0x3d4
worker_thread+0x224/0x344
kthread+0x120/0x130
ret_from_fork+0x10/0x18
Fix this by checking for the inode->i_state I_WILL_FREE or I_FREEING
before and after adding to the writeback list. If it is observed to be
in freeing path before adding, then simply return. If it is after adding
to the writeback list, then remove this inode from the writeback list
in __mark_inode_dirty() context itself.
Change-Id: I1e5f15d81dae01f0dd7a108b1861adc83105ed7b
Signed-off-by:
Sahitya Tummala <stummala@codeaurora.org>
Loading
Please register or sign in to comment