Commit 0fe340a9 authored by Christian Brauner's avatar Christian Brauner
Browse files

inode: port __I_NEW to var event

Port the __I_NEW mechanism to use the new var event mechanism.

Link: https://lore.kernel.org/r/20240823-work-i_state-v3-4-5cd5fd207a57@kernel.org


Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 532980cb
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1644,14 +1644,16 @@ void bch2_evict_subvolume_inodes(struct bch_fs *c, snapshot_id_list *s)
				break;
			}
		} else if (clean_pass && this_pass_clean) {
			wait_queue_head_t *wq = bit_waitqueue(&inode->v.i_state, __I_NEW);
			DEFINE_WAIT_BIT(wait, &inode->v.i_state, __I_NEW);
			struct wait_bit_queue_entry wqe;
			struct wait_queue_head *wq_head;

			prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
			wq_head = inode_bit_waitqueue(&wqe, &inode->v, __I_NEW);
			prepare_to_wait_event(wq_head, &wqe.wq_entry,
					      TASK_UNINTERRUPTIBLE);
			mutex_unlock(&c->vfs_inodes_lock);

			schedule();
			finish_wait(wq, &wait.wq_entry);
			finish_wait(wq_head, &wqe.wq_entry);
			goto again;
		}
	}
+6 −1
Original line number Diff line number Diff line
@@ -1908,8 +1908,13 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode)
	__d_instantiate(entry, inode);
	WARN_ON(!(inode->i_state & I_NEW));
	inode->i_state &= ~I_NEW & ~I_CREATING;
	/*
	 * Pairs with the barrier in prepare_to_wait_event() to make sure
	 * ___wait_var_event() either sees the bit cleared or
	 * waitqueue_active() check in wake_up_var() sees the waiter.
	 */
	smp_mb();
	wake_up_bit(&inode->i_state, __I_NEW);
	inode_wake_up_bit(inode, __I_NEW);
	spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(d_instantiate_new);
+24 −8
Original line number Diff line number Diff line
@@ -734,7 +734,13 @@ static void evict(struct inode *inode)
	 * used as an indicator whether blocking on it is safe.
	 */
	spin_lock(&inode->i_lock);
	wake_up_bit(&inode->i_state, __I_NEW);
	/*
	 * Pairs with the barrier in prepare_to_wait_event() to make sure
	 * ___wait_var_event() either sees the bit cleared or
	 * waitqueue_active() check in wake_up_var() sees the waiter.
	 */
	smp_mb();
	inode_wake_up_bit(inode, __I_NEW);
	BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
	spin_unlock(&inode->i_lock);

@@ -1146,8 +1152,13 @@ void unlock_new_inode(struct inode *inode)
	spin_lock(&inode->i_lock);
	WARN_ON(!(inode->i_state & I_NEW));
	inode->i_state &= ~I_NEW & ~I_CREATING;
	/*
	 * Pairs with the barrier in prepare_to_wait_event() to make sure
	 * ___wait_var_event() either sees the bit cleared or
	 * waitqueue_active() check in wake_up_var() sees the waiter.
	 */
	smp_mb();
	wake_up_bit(&inode->i_state, __I_NEW);
	inode_wake_up_bit(inode, __I_NEW);
	spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(unlock_new_inode);
@@ -1158,8 +1169,13 @@ void discard_new_inode(struct inode *inode)
	spin_lock(&inode->i_lock);
	WARN_ON(!(inode->i_state & I_NEW));
	inode->i_state &= ~I_NEW;
	/*
	 * Pairs with the barrier in prepare_to_wait_event() to make sure
	 * ___wait_var_event() either sees the bit cleared or
	 * waitqueue_active() check in wake_up_var() sees the waiter.
	 */
	smp_mb();
	wake_up_bit(&inode->i_state, __I_NEW);
	inode_wake_up_bit(inode, __I_NEW);
	spin_unlock(&inode->i_lock);
	iput(inode);
}
@@ -2348,8 +2364,8 @@ EXPORT_SYMBOL(inode_needs_sync);
 */
static void __wait_on_freeing_inode(struct inode *inode, bool is_inode_hash_locked)
{
	wait_queue_head_t *wq;
	DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW);
	struct wait_bit_queue_entry wqe;
	struct wait_queue_head *wq_head;

	/*
	 * Handle racing against evict(), see that routine for more details.
@@ -2360,14 +2376,14 @@ static void __wait_on_freeing_inode(struct inode *inode, bool is_inode_hash_lock
		return;
	}

	wq = bit_waitqueue(&inode->i_state, __I_NEW);
	prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
	wq_head = inode_bit_waitqueue(&wqe, inode, __I_NEW);
	prepare_to_wait_event(wq_head, &wqe.wq_entry, TASK_UNINTERRUPTIBLE);
	spin_unlock(&inode->i_lock);
	rcu_read_unlock();
	if (is_inode_hash_locked)
		spin_unlock(&inode_hash_lock);
	schedule();
	finish_wait(wq, &wait.wq_entry);
	finish_wait(wq_head, &wqe.wq_entry);
	if (is_inode_hash_locked)
		spin_lock(&inode_hash_lock);
	rcu_read_lock();
+2 −1
Original line number Diff line number Diff line
@@ -200,7 +200,8 @@ void inode_io_list_del(struct inode *inode);
/* writeback.h requires fs.h; it, too, is not included from here. */
static inline void wait_on_inode(struct inode *inode)
{
	wait_on_bit(&inode->i_state, __I_NEW, TASK_UNINTERRUPTIBLE);
	wait_var_event(inode_state_wait_address(inode, __I_NEW),
		       !(READ_ONCE(inode->i_state) & I_NEW));
}

#ifdef CONFIG_CGROUP_WRITEBACK