Commit f44cc269 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: fix seqmutex_relock()



We were grabbing the sequence number before unlock incremented it - fix
this by moving the increment to seqmutex_lock() (so the seqmutex_relock()
failure path skips the mutex_trylock()), and returning the sequence
number from unlock(), to make the API simpler and safer.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 9bd01500
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -575,7 +575,6 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
	struct bch_fs *c = i->c;
	struct btree_trans *trans;
	ssize_t ret = 0;
	u32 seq;

	i->ubuf = buf;
	i->size	= size;
@@ -589,8 +588,7 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
			continue;

		closure_get(&trans->ref);
		seq = seqmutex_seq(&c->btree_trans_lock);
		seqmutex_unlock(&c->btree_trans_lock);
		u32 seq = seqmutex_unlock(&c->btree_trans_lock);

		ret = flush_buf(i);
		if (ret) {
@@ -811,7 +809,6 @@ static ssize_t bch2_btree_deadlock_read(struct file *file, char __user *buf,
	struct bch_fs *c = i->c;
	struct btree_trans *trans;
	ssize_t ret = 0;
	u32 seq;

	i->ubuf = buf;
	i->size	= size;
@@ -828,8 +825,7 @@ static ssize_t bch2_btree_deadlock_read(struct file *file, char __user *buf,
			continue;

		closure_get(&trans->ref);
		seq = seqmutex_seq(&c->btree_trans_lock);
		seqmutex_unlock(&c->btree_trans_lock);
		u32 seq = seqmutex_unlock(&c->btree_trans_lock);

		ret = flush_buf(i);
		if (ret) {
+4 −7
Original line number Diff line number Diff line
@@ -19,17 +19,14 @@ static inline bool seqmutex_trylock(struct seqmutex *lock)
static inline void seqmutex_lock(struct seqmutex *lock)
{
	mutex_lock(&lock->lock);
}

static inline void seqmutex_unlock(struct seqmutex *lock)
{
	lock->seq++;
	mutex_unlock(&lock->lock);
}

static inline u32 seqmutex_seq(struct seqmutex *lock)
static inline u32 seqmutex_unlock(struct seqmutex *lock)
{
	return lock->seq;
	u32 seq = lock->seq;
	mutex_unlock(&lock->lock);
	return seq;
}

static inline bool seqmutex_relock(struct seqmutex *lock, u32 seq)