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

bcachefs: Can now block journal activity without closing cur entry

parent c80f33b7
Loading
Loading
Loading
Loading
+42 −2
Original line number Diff line number Diff line
@@ -217,6 +217,12 @@ void bch2_journal_buf_put_final(struct journal *j, u64 seq)
	if (__bch2_journal_pin_put(j, seq))
		bch2_journal_reclaim_fast(j);
	bch2_journal_do_writes(j);

	/*
	 * for __bch2_next_write_buffer_flush_journal_buf(), when quiescing an
	 * open journal entry
	 */
	wake_up(&j->wait);
}

/*
@@ -251,6 +257,9 @@ static void __journal_entry_close(struct journal *j, unsigned closed_val, bool t
	if (!__journal_entry_is_open(old))
		return;

	if (old.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL)
		old.cur_entry_offset = j->cur_entry_offset_if_blocked;

	/* Close out old buffer: */
	buf->data->u64s		= cpu_to_le32(old.cur_entry_offset);

@@ -868,16 +877,44 @@ int bch2_journal_meta(struct journal *j)
void bch2_journal_unblock(struct journal *j)
{
	spin_lock(&j->lock);
	j->blocked--;
	if (!--j->blocked &&
	    j->cur_entry_offset_if_blocked < JOURNAL_ENTRY_CLOSED_VAL &&
	    j->reservations.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL) {
		union journal_res_state old, new;

		old.v = atomic64_read(&j->reservations.counter);
		do {
			new.v = old.v;
			new.cur_entry_offset = j->cur_entry_offset_if_blocked;
		} while (!atomic64_try_cmpxchg(&j->reservations.counter, &old.v, new.v));
	}
	spin_unlock(&j->lock);

	journal_wake(j);
}

static void __bch2_journal_block(struct journal *j)
{
	if (!j->blocked++) {
		union journal_res_state old, new;

		old.v = atomic64_read(&j->reservations.counter);
		do {
			j->cur_entry_offset_if_blocked = old.cur_entry_offset;

			if (j->cur_entry_offset_if_blocked >= JOURNAL_ENTRY_CLOSED_VAL)
				break;

			new.v = old.v;
			new.cur_entry_offset = JOURNAL_ENTRY_BLOCKED_VAL;
		} while (!atomic64_try_cmpxchg(&j->reservations.counter, &old.v, new.v));
	}
}

void bch2_journal_block(struct journal *j)
{
	spin_lock(&j->lock);
	j->blocked++;
	__bch2_journal_block(j);
	spin_unlock(&j->lock);

	journal_quiesce(j);
@@ -1481,6 +1518,9 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
	case JOURNAL_ENTRY_CLOSED_VAL:
		prt_printf(out, "closed\n");
		break;
	case JOURNAL_ENTRY_BLOCKED_VAL:
		prt_printf(out, "blocked\n");
		break;
	default:
		prt_printf(out, "%u/%u\n", s.cur_entry_offset, j->cur_entry_u64s);
		break;
+2 −1
Original line number Diff line number Diff line
@@ -285,7 +285,8 @@ static inline void bch2_journal_buf_put(struct journal *j, unsigned idx, u64 seq
		spin_lock(&j->lock);
		bch2_journal_buf_put_final(j, seq);
		spin_unlock(&j->lock);
	}
	} else if (unlikely(s.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL))
		wake_up(&j->wait);
}

/*
+2 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ union journal_res_state {
 */
#define JOURNAL_ENTRY_OFFSET_MAX	((1U << 20) - 1)

#define JOURNAL_ENTRY_BLOCKED_VAL	(JOURNAL_ENTRY_OFFSET_MAX - 2)
#define JOURNAL_ENTRY_CLOSED_VAL	(JOURNAL_ENTRY_OFFSET_MAX - 1)
#define JOURNAL_ENTRY_ERROR_VAL		(JOURNAL_ENTRY_OFFSET_MAX)

@@ -193,6 +194,7 @@ struct journal {
	 * insufficient devices:
	 */
	enum journal_errors	cur_entry_error;
	unsigned		cur_entry_offset_if_blocked;

	unsigned		buf_size_want;
	/*