Re: [PATCH] fs: rotate inodes whose page cache could not be dropped

From: Zhihao Cheng

Date: Mon Oct 19 2026 - 08:56:24 EST


在 2026/10/19 16:50, Nick Karaolidis 写道:
On Saturday, October 17th, 2026 at 8:43 AM, Zhihao Cheng <chengzhihao1@xxxxxxxxxx> wrote:

Hi Nikolaos,
I find a possible BUG_ON if this patch applied, details shown as:
P1 P2
prune_icache_sb
lock(lru->lock)
inode_lru_isolate
if (!mapping_empty(&inode->i_data))
unlock(lru->lock)
spin_lock(&inode->i_lock)
inode_state_set(inode, I_REFERENCED)
inode_unpin_lru_isolating
spin_unlock(&inode->i_lock)
unlink
iget_locked // find_inode_fast gets the inode
iput
iput_final
drop = 1
evict
BUG_ON(inode_state_read_once(inode) !=
(I_FREEING | I_CLEAR)) // inode state with I_REFERENCED

Could that be possible?

Hi Zhihao,

Thanks for looking at this. I don't think that BUG_ON can trigger.

- The patch sets I_REFERENCED in the same i_lock section that clears
I_LRU_ISOLATING, and evict() waits in inode_wait_for_lru_isolating()
before calling ->evict_inode(), so the walker can only set the flag
before the filesystem's eviction runs.

- clear_inode(), which every ->evict_inode() calls, sets i_state to
I_FREEING | I_CLEAR.
OK, I missunderstand the realization of 'inode_state_assign_raw(inode, I_FREEING | I_CLEAR)' in the clear_inode().

- Evicting an inode that has I_REFERENCED set already happens.
iput_final() sets it through __inode_lru_list_add(inode, true) when
the inode is already on the LRU.

Did I miss a path that checks i_state before clear_inode()?

Thanks,
Nikolaos

.