This is the only routine which instead skipped instead of waiting. The current behavior is arguably a bug as it results in a corner case where the inode hash can have *two* matching inodes, one of which is on its way out. Ironing out this difference is an incremental step towards sanitizing the API. Signed-off-by: Mateusz Guzik --- fs/inode.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index f8904f813372..3b838f07cb40 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1832,16 +1832,13 @@ int insert_inode_locked(struct inode *inode) while (1) { struct inode *old = NULL; spin_lock(&inode_hash_lock); +repeat: hlist_for_each_entry(old, head, i_hash) { if (old->i_ino != ino) continue; if (old->i_sb != sb) continue; spin_lock(&old->i_lock); - if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) { - spin_unlock(&old->i_lock); - continue; - } break; } if (likely(!old)) { @@ -1852,6 +1849,11 @@ int insert_inode_locked(struct inode *inode) spin_unlock(&inode_hash_lock); return 0; } + if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) { + __wait_on_freeing_inode(old, true); + old = NULL; + goto repeat; + } if (unlikely(inode_state_read(old) & I_CREATING)) { spin_unlock(&old->i_lock); spin_unlock(&inode_hash_lock); -- 2.48.1