Re: [PATCH] fs: rotate inodes whose page cache could not be dropped
From: Nick Karaolidis
Date: Mon Oct 19 2026 - 04:51:37 EST
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.
- 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