*/
#include <linux/hash.h>
-#include <linux/prefetch.h>
#include "journal_types.h"
int bch2_journal_res_get_slowpath(struct journal *, struct journal_res *,
unsigned);
-/* First two bits for JOURNAL_WATERMARK: */
-#define JOURNAL_RES_GET_NONBLOCK (1 << 2)
-#define JOURNAL_RES_GET_CHECK (1 << 3)
+/* First bits for BCH_WATERMARK: */
+enum journal_res_flags {
+ __JOURNAL_RES_GET_NONBLOCK = BCH_WATERMARK_BITS,
+ __JOURNAL_RES_GET_CHECK,
+};
+
+#define JOURNAL_RES_GET_NONBLOCK (1 << __JOURNAL_RES_GET_NONBLOCK)
+#define JOURNAL_RES_GET_CHECK (1 << __JOURNAL_RES_GET_CHECK)
static inline int journal_res_get_fast(struct journal *j,
struct journal_res *res,
{
union journal_res_state old, new;
u64 v = atomic64_read(&j->reservations.counter);
- unsigned u64s, offset;
do {
old.v = new.v = v;
- /*
- * Round up the end of the journal reservation to the next
- * cacheline boundary:
- */
- u64s = res->u64s;
- offset = sizeof(struct jset) / sizeof(u64) +
- new.cur_entry_offset + u64s;
- u64s += ((offset - 1) & ((SMP_CACHE_BYTES / sizeof(u64)) - 1)) + 1;
-
-
/*
* Check if there is still room in the current journal
* entry:
*/
- if (new.cur_entry_offset + u64s > j->cur_entry_u64s)
+ if (new.cur_entry_offset + res->u64s > j->cur_entry_u64s)
return 0;
EBUG_ON(!journal_state_count(new, new.idx));
- if ((flags & JOURNAL_WATERMARK_MASK) < j->watermark)
+ if ((flags & BCH_WATERMARK_MASK) < j->watermark)
return 0;
- new.cur_entry_offset += u64s;
+ new.cur_entry_offset += res->u64s;
journal_state_inc(&new);
/*
res->ref = true;
res->idx = old.idx;
- res->u64s = u64s;
res->offset = old.cur_entry_offset;
res->seq = le64_to_cpu(j->buf[old.idx].data->seq);
-
- offset = res->offset;
- while (offset < res->offset + res->u64s) {
- prefetchw(vstruct_idx(j->buf[res->idx].data, offset));
- offset += SMP_CACHE_BYTES / sizeof(u64);
- }
return 1;
}
static inline void journal_set_watermark(struct journal *j)
{
union journal_preres_state s = READ_ONCE(j->prereserved);
- unsigned watermark = JOURNAL_WATERMARK_any;
+ unsigned watermark = BCH_WATERMARK_stripe;
if (fifo_free(&j->pin) < j->pin.size / 4)
- watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_copygc);
+ watermark = max_t(unsigned, watermark, BCH_WATERMARK_copygc);
if (fifo_free(&j->pin) < j->pin.size / 8)
- watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_reserved);
+ watermark = max_t(unsigned, watermark, BCH_WATERMARK_reclaim);
if (s.reserved > s.remaining)
- watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_copygc);
+ watermark = max_t(unsigned, watermark, BCH_WATERMARK_copygc);
if (!s.remaining)
- watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_reserved);
+ watermark = max_t(unsigned, watermark, BCH_WATERMARK_reclaim);
if (watermark == j->watermark)
return;
int d = new_u64s - res->u64s;
union journal_preres_state old, new;
u64 v = atomic64_read(&j->prereserved.counter);
+ enum bch_watermark watermark = flags & BCH_WATERMARK_MASK;
int ret;
do {
old.v = new.v = v;
ret = 0;
- if ((flags & JOURNAL_WATERMARK_reserved) ||
+ if (watermark == BCH_WATERMARK_reclaim ||
new.reserved + d < new.remaining) {
new.reserved += d;
ret = 1;
return 0;
if (flags & JOURNAL_RES_GET_NONBLOCK)
- return -EAGAIN;
+ return -BCH_ERR_journal_preres_get_blocked;
return __bch2_journal_preres_get(j, res, new_u64s, flags);
}
int bch2_journal_flush(struct journal *);
bool bch2_journal_noflush_seq(struct journal *, u64);
int bch2_journal_meta(struct journal *);
-int bch2_journal_log_msg(struct journal *, const char *, ...);
void bch2_journal_halt(struct journal *);