diff --git a/fs/inode.c b/fs/inode.c index 1cb6293b237a..d6353b8d1e63 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -593,12 +593,11 @@ static void inode_pin_lru_isolating(struct inode *inode) static void inode_unpin_lru_isolating(struct inode *inode) { - spin_lock(&inode->i_lock); + lockdep_assert_held(&inode->i_lock); WARN_ON(!(inode_state_read(inode) & I_LRU_ISOLATING)); inode_state_clear(inode, I_LRU_ISOLATING); /* Called with inode->i_lock which ensures memory ordering. */ inode_wake_up_bit(inode, __I_LRU_ISOLATING); - spin_unlock(&inode->i_lock); } static void inode_wait_for_lru_isolating(struct inode *inode) @@ -981,7 +980,13 @@ static enum lru_status inode_lru_isolate(struct list_head *item, else __count_vm_events(PGINODESTEAL, reap); mm_account_reclaimed_pages(reap); + + spin_lock(&inode->i_lock); + /* The walk restarts here: don't retry leftovers right away */ + if (!mapping_empty(&inode->i_data)) + inode_state_set(inode, I_REFERENCED); inode_unpin_lru_isolating(inode); + spin_unlock(&inode->i_lock); return LRU_RETRY; }