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: add missing fences to I_NEW handling

Suppose there are 2 CPUs racing inode hash lookup func (say ilookup5())
and unlock_new_inode().

In principle the latter can clear the I_NEW flag before prior stores
into the inode were made visible.

The former can in turn observe I_NEW is cleared and proceed to use the
inode, while possibly reading from not-yet-published areas.

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Mateusz Guzik and committed by
Christian Brauner
31e332b9 0f607a89

+16
+4
fs/dcache.c
··· 1981 1981 spin_lock(&inode->i_lock); 1982 1982 __d_instantiate(entry, inode); 1983 1983 WARN_ON(!(inode->i_state & I_NEW)); 1984 + /* 1985 + * Pairs with smp_rmb in wait_on_inode(). 1986 + */ 1987 + smp_wmb(); 1984 1988 inode->i_state &= ~I_NEW & ~I_CREATING; 1985 1989 /* 1986 1990 * Pairs with the barrier in prepare_to_wait_event() to make sure
+8
fs/inode.c
··· 1181 1181 lockdep_annotate_inode_mutex_key(inode); 1182 1182 spin_lock(&inode->i_lock); 1183 1183 WARN_ON(!(inode->i_state & I_NEW)); 1184 + /* 1185 + * Pairs with smp_rmb in wait_on_inode(). 1186 + */ 1187 + smp_wmb(); 1184 1188 inode->i_state &= ~I_NEW & ~I_CREATING; 1185 1189 /* 1186 1190 * Pairs with the barrier in prepare_to_wait_event() to make sure ··· 1202 1198 lockdep_annotate_inode_mutex_key(inode); 1203 1199 spin_lock(&inode->i_lock); 1204 1200 WARN_ON(!(inode->i_state & I_NEW)); 1201 + /* 1202 + * Pairs with smp_rmb in wait_on_inode(). 1203 + */ 1204 + smp_wmb(); 1205 1205 inode->i_state &= ~I_NEW; 1206 1206 /* 1207 1207 * Pairs with the barrier in prepare_to_wait_event() to make sure
+4
include/linux/writeback.h
··· 194 194 { 195 195 wait_var_event(inode_state_wait_address(inode, __I_NEW), 196 196 !(READ_ONCE(inode->i_state) & I_NEW)); 197 + /* 198 + * Pairs with routines clearing I_NEW. 199 + */ 200 + smp_rmb(); 197 201 } 198 202 199 203 #ifdef CONFIG_CGROUP_WRITEBACK