Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: make insert_inode_locked() wait for inode destruction

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 <mjguzik@gmail.com>
Link: https://patch.msgid.link/20260114094717.236202-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Mateusz Guzik and committed by
Christian Brauner
88ec797c aaf76839

+24 -17
+24 -17
fs/inode.c
··· 1028 1028 return freed; 1029 1029 } 1030 1030 1031 - static void __wait_on_freeing_inode(struct inode *inode, bool is_inode_hash_locked); 1031 + static void __wait_on_freeing_inode(struct inode *inode, bool hash_locked, bool rcu_locked); 1032 + 1032 1033 /* 1033 1034 * Called with the inode lock held. 1034 1035 */ 1035 1036 static struct inode *find_inode(struct super_block *sb, 1036 1037 struct hlist_head *head, 1037 1038 int (*test)(struct inode *, void *), 1038 - void *data, bool is_inode_hash_locked, 1039 + void *data, bool hash_locked, 1039 1040 bool *isnew) 1040 1041 { 1041 1042 struct inode *inode = NULL; 1042 1043 1043 - if (is_inode_hash_locked) 1044 + if (hash_locked) 1044 1045 lockdep_assert_held(&inode_hash_lock); 1045 1046 else 1046 1047 lockdep_assert_not_held(&inode_hash_lock); ··· 1055 1054 continue; 1056 1055 spin_lock(&inode->i_lock); 1057 1056 if (inode_state_read(inode) & (I_FREEING | I_WILL_FREE)) { 1058 - __wait_on_freeing_inode(inode, is_inode_hash_locked); 1057 + __wait_on_freeing_inode(inode, hash_locked, true); 1059 1058 goto repeat; 1060 1059 } 1061 1060 if (unlikely(inode_state_read(inode) & I_CREATING)) { ··· 1079 1078 */ 1080 1079 static struct inode *find_inode_fast(struct super_block *sb, 1081 1080 struct hlist_head *head, unsigned long ino, 1082 - bool is_inode_hash_locked, bool *isnew) 1081 + bool hash_locked, bool *isnew) 1083 1082 { 1084 1083 struct inode *inode = NULL; 1085 1084 1086 - if (is_inode_hash_locked) 1085 + if (hash_locked) 1087 1086 lockdep_assert_held(&inode_hash_lock); 1088 1087 else 1089 1088 lockdep_assert_not_held(&inode_hash_lock); ··· 1097 1096 continue; 1098 1097 spin_lock(&inode->i_lock); 1099 1098 if (inode_state_read(inode) & (I_FREEING | I_WILL_FREE)) { 1100 - __wait_on_freeing_inode(inode, is_inode_hash_locked); 1099 + __wait_on_freeing_inode(inode, hash_locked, true); 1101 1100 goto repeat; 1102 1101 } 1103 1102 if (unlikely(inode_state_read(inode) & I_CREATING)) { ··· 1833 1832 while (1) { 1834 1833 struct inode *old = NULL; 1835 1834 spin_lock(&inode_hash_lock); 1835 + repeat: 1836 1836 hlist_for_each_entry(old, head, i_hash) { 1837 1837 if (old->i_ino != ino) 1838 1838 continue; 1839 1839 if (old->i_sb != sb) 1840 1840 continue; 1841 1841 spin_lock(&old->i_lock); 1842 - if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) { 1843 - spin_unlock(&old->i_lock); 1844 - continue; 1845 - } 1846 1842 break; 1847 1843 } 1848 1844 if (likely(!old)) { ··· 1849 1851 spin_unlock(&inode->i_lock); 1850 1852 spin_unlock(&inode_hash_lock); 1851 1853 return 0; 1854 + } 1855 + if (inode_state_read(old) & (I_FREEING | I_WILL_FREE)) { 1856 + __wait_on_freeing_inode(old, true, false); 1857 + old = NULL; 1858 + goto repeat; 1852 1859 } 1853 1860 if (unlikely(inode_state_read(old) & I_CREATING)) { 1854 1861 spin_unlock(&old->i_lock); ··· 2507 2504 * wake_up_bit(&inode->i_state, __I_NEW) after removing from the hash list 2508 2505 * will DTRT. 2509 2506 */ 2510 - static void __wait_on_freeing_inode(struct inode *inode, bool is_inode_hash_locked) 2507 + static void __wait_on_freeing_inode(struct inode *inode, bool hash_locked, bool rcu_locked) 2511 2508 { 2512 2509 struct wait_bit_queue_entry wqe; 2513 2510 struct wait_queue_head *wq_head; 2511 + 2512 + VFS_BUG_ON(!hash_locked && !rcu_locked); 2514 2513 2515 2514 /* 2516 2515 * Handle racing against evict(), see that routine for more details. 2517 2516 */ 2518 2517 if (unlikely(inode_unhashed(inode))) { 2519 - WARN_ON(is_inode_hash_locked); 2518 + WARN_ON(hash_locked); 2520 2519 spin_unlock(&inode->i_lock); 2521 2520 return; 2522 2521 } ··· 2526 2521 wq_head = inode_bit_waitqueue(&wqe, inode, __I_NEW); 2527 2522 prepare_to_wait_event(wq_head, &wqe.wq_entry, TASK_UNINTERRUPTIBLE); 2528 2523 spin_unlock(&inode->i_lock); 2529 - rcu_read_unlock(); 2530 - if (is_inode_hash_locked) 2524 + if (rcu_locked) 2525 + rcu_read_unlock(); 2526 + if (hash_locked) 2531 2527 spin_unlock(&inode_hash_lock); 2532 2528 schedule(); 2533 2529 finish_wait(wq_head, &wqe.wq_entry); 2534 - if (is_inode_hash_locked) 2530 + if (hash_locked) 2535 2531 spin_lock(&inode_hash_lock); 2536 - rcu_read_lock(); 2532 + if (rcu_locked) 2533 + rcu_read_lock(); 2537 2534 } 2538 2535 2539 2536 static __initdata unsigned long ihash_entries;