X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fjournal.c;h=c9c2ee9c67f633ac838ee94c52de42b63da993fa;hb=ec28e6bfa269daf953af95610c0d1af3e7df1c0a;hp=75be0a5f708c089e496e123d7f67b4fd4879eff7;hpb=986533d8d5b21c8eb512bbb3f0496d3d2a087c5d;p=bcachefs-tools-debian diff --git a/libbcachefs/journal.c b/libbcachefs/journal.c index 75be0a5..c9c2ee9 100644 --- a/libbcachefs/journal.c +++ b/libbcachefs/journal.c @@ -68,8 +68,9 @@ journal_seq_to_buf(struct journal *j, u64 seq) static void journal_pin_list_init(struct journal_entry_pin_list *p, int count) { - INIT_LIST_HEAD(&p->list); - INIT_LIST_HEAD(&p->key_cache_list); + unsigned i; + for (i = 0; i < ARRAY_SIZE(p->list); i++) + INIT_LIST_HEAD(&p->list[i]); INIT_LIST_HEAD(&p->flushed); atomic_set(&p->count, count); p->devs.nr = 0; @@ -199,12 +200,6 @@ static bool journal_entry_close(struct journal *j) /* * should _only_ called from journal_res_get() - when we actually want a * journal reservation - journal entry is open means journal is dirty: - * - * returns: - * 0: success - * -ENOSPC: journal currently full, must invoke reclaim - * -EAGAIN: journal blocked, must wait - * -EROFS: insufficient rw devices or journal error */ static int journal_entry_open(struct journal *j) { @@ -231,7 +226,7 @@ static int journal_entry_open(struct journal *j) if (!fifo_free(&j->pin)) return JOURNAL_ERR_journal_pin_full; - if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf) - 1) + if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf)) return JOURNAL_ERR_max_in_flight; BUG_ON(!j->cur_entry_sectors); @@ -250,7 +245,7 @@ static int journal_entry_open(struct journal *j) journal_entry_overhead(j); u64s = clamp_t(int, u64s, 0, JOURNAL_ENTRY_CLOSED_VAL - 1); - if (u64s <= 0) + if (u64s <= (ssize_t) j->early_journal_entries.nr) return JOURNAL_ERR_journal_full; if (fifo_empty(&j->pin) && j->reclaim_thread) @@ -275,6 +270,12 @@ static int journal_entry_open(struct journal *j) buf->data->seq = cpu_to_le64(journal_cur_seq(j)); buf->data->u64s = 0; + if (j->early_journal_entries.nr) { + memcpy(buf->data->_data, j->early_journal_entries.data, + j->early_journal_entries.nr * sizeof(u64)); + le32_add_cpu(&buf->data->u64s, j->early_journal_entries.nr); + } + /* * Must be set before marking the journal entry as open: */ @@ -291,7 +292,9 @@ static int journal_entry_open(struct journal *j) BUG_ON(new.idx != (journal_cur_seq(j) & JOURNAL_BUF_MASK)); journal_state_inc(&new); - new.cur_entry_offset = 0; + + /* Handle any already added entries */ + new.cur_entry_offset = le32_to_cpu(buf->data->u64s); } while ((v = atomic64_cmpxchg(&j->reservations.counter, old.v, new.v)) != old.v); @@ -304,6 +307,9 @@ static int journal_entry_open(struct journal *j) &j->write_work, msecs_to_jiffies(c->opts.journal_flush_delay)); journal_wake(j); + + if (j->early_journal_entries.nr) + darray_exit(&j->early_journal_entries); return 0; } @@ -353,7 +359,7 @@ retry: return 0; if (bch2_journal_error(j)) - return -EROFS; + return -BCH_ERR_erofs_journal_err; spin_lock(&j->lock); @@ -391,12 +397,12 @@ retry: ret = journal_entry_open(j); if (ret == JOURNAL_ERR_max_in_flight) - trace_journal_entry_full(c); + trace_and_count(c, journal_entry_full, c); unlock: if ((ret && ret != JOURNAL_ERR_insufficient_devices) && !j->res_get_blocked_start) { j->res_get_blocked_start = local_clock() ?: 1; - trace_journal_full(c); + trace_and_count(c, journal_full, c); } can_discard = j->can_discard; @@ -445,7 +451,9 @@ unlock: } } - return ret == JOURNAL_ERR_insufficient_devices ? -EROFS : -EAGAIN; + return ret == JOURNAL_ERR_insufficient_devices + ? -EROFS + : -BCH_ERR_journal_res_get_blocked; } /* @@ -464,7 +472,8 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res, int ret; closure_wait_event(&j->async_wait, - (ret = __journal_res_get(j, res, flags)) != -EAGAIN || + (ret = __journal_res_get(j, res, flags)) != + -BCH_ERR_journal_res_get_blocked|| (flags & JOURNAL_RES_GET_NONBLOCK)); return ret; } @@ -720,39 +729,6 @@ int bch2_journal_meta(struct journal *j) return bch2_journal_flush_seq(j, res.seq); } -int bch2_journal_log_msg(struct journal *j, const char *fmt, ...) -{ - struct jset_entry_log *entry; - struct journal_res res = { 0 }; - unsigned msglen, u64s; - va_list args; - int ret; - - va_start(args, fmt); - msglen = vsnprintf(NULL, 0, fmt, args) + 1; - va_end(args); - - u64s = jset_u64s(DIV_ROUND_UP(msglen, sizeof(u64))); - - ret = bch2_journal_res_get(j, &res, u64s, 0); - if (ret) - return ret; - - entry = container_of(journal_res_entry(j, &res), - struct jset_entry_log, entry);; - memset(entry, 0, u64s * sizeof(u64)); - entry->entry.type = BCH_JSET_ENTRY_log; - entry->entry.u64s = u64s - 1; - - va_start(args, fmt); - vsnprintf(entry->d, INT_MAX, fmt, args); - va_end(args); - - bch2_journal_res_put(j, &res); - - return bch2_journal_flush_seq(j, res.seq); -} - /* block/unlock the journal: */ void bch2_journal_unblock(struct journal *j) @@ -783,40 +759,40 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr, u64 *new_bucket_seq = NULL, *new_buckets = NULL; struct open_bucket **ob = NULL; long *bu = NULL; - unsigned i, nr_got = 0, nr_want = nr - ja->nr; - unsigned old_nr = ja->nr; - unsigned old_discard_idx = ja->discard_idx; - unsigned old_dirty_idx_ondisk = ja->dirty_idx_ondisk; - unsigned old_dirty_idx = ja->dirty_idx; - unsigned old_cur_idx = ja->cur_idx; + unsigned i, pos, nr_got = 0, nr_want = nr - ja->nr; int ret = 0; - if (c) { - bch2_journal_block(&c->journal); - bch2_journal_flush_all_pins(&c->journal); - } + BUG_ON(nr <= ja->nr); - bu = kzalloc(nr_want * sizeof(*bu), GFP_KERNEL); - ob = kzalloc(nr_want * sizeof(*ob), GFP_KERNEL); - new_buckets = kzalloc(nr * sizeof(u64), GFP_KERNEL); - new_bucket_seq = kzalloc(nr * sizeof(u64), GFP_KERNEL); + bu = kcalloc(nr_want, sizeof(*bu), GFP_KERNEL); + ob = kcalloc(nr_want, sizeof(*ob), GFP_KERNEL); + new_buckets = kcalloc(nr, sizeof(u64), GFP_KERNEL); + new_bucket_seq = kcalloc(nr, sizeof(u64), GFP_KERNEL); if (!bu || !ob || !new_buckets || !new_bucket_seq) { - ret = -ENOMEM; - goto err_unblock; + ret = -BCH_ERR_ENOMEM_set_nr_journal_buckets; + goto err_free; } for (nr_got = 0; nr_got < nr_want; nr_got++) { if (new_fs) { bu[nr_got] = bch2_bucket_alloc_new_fs(ca); if (bu[nr_got] < 0) { - ret = -ENOSPC; + ret = -BCH_ERR_ENOSPC_bucket_alloc; break; } } else { - ob[nr_got] = bch2_bucket_alloc(c, ca, RESERVE_none, - false, cl); - if (IS_ERR(ob[nr_got])) { - ret = cl ? -EAGAIN : -ENOSPC; + ob[nr_got] = bch2_bucket_alloc(c, ca, RESERVE_none, cl); + ret = PTR_ERR_OR_ZERO(ob[nr_got]); + if (ret) + break; + + ret = bch2_trans_run(c, + bch2_trans_mark_metadata_bucket(&trans, ca, + ob[nr_got]->bucket, BCH_DATA_journal, + ca->mi.bucket_size)); + if (ret) { + bch2_open_bucket_put(c, ob[nr_got]); + bch_err(c, "error marking new journal buckets: %s", bch2_err_str(ret)); break; } @@ -825,76 +801,77 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr, } if (!nr_got) - goto err_unblock; + goto err_free; - /* - * We may be called from the device add path, before the new device has - * actually been added to the running filesystem: - */ - if (!new_fs) - spin_lock(&c->journal.lock); + /* Don't return an error if we successfully allocated some buckets: */ + ret = 0; + + if (c) { + bch2_journal_flush_all_pins(&c->journal); + bch2_journal_block(&c->journal); + mutex_lock(&c->sb_lock); + } memcpy(new_buckets, ja->buckets, ja->nr * sizeof(u64)); memcpy(new_bucket_seq, ja->bucket_seq, ja->nr * sizeof(u64)); - swap(new_buckets, ja->buckets); - swap(new_bucket_seq, ja->bucket_seq); + + BUG_ON(ja->discard_idx > ja->nr); + + pos = ja->discard_idx ?: ja->nr; + + memmove(new_buckets + pos + nr_got, + new_buckets + pos, + sizeof(new_buckets[0]) * (ja->nr - pos)); + memmove(new_bucket_seq + pos + nr_got, + new_bucket_seq + pos, + sizeof(new_bucket_seq[0]) * (ja->nr - pos)); for (i = 0; i < nr_got; i++) { - unsigned pos = ja->discard_idx ?: ja->nr; - long b = bu[i]; - - __array_insert_item(ja->buckets, ja->nr, pos); - __array_insert_item(ja->bucket_seq, ja->nr, pos); - ja->nr++; - - ja->buckets[pos] = b; - ja->bucket_seq[pos] = 0; - - if (pos <= ja->discard_idx) - ja->discard_idx = (ja->discard_idx + 1) % ja->nr; - if (pos <= ja->dirty_idx_ondisk) - ja->dirty_idx_ondisk = (ja->dirty_idx_ondisk + 1) % ja->nr; - if (pos <= ja->dirty_idx) - ja->dirty_idx = (ja->dirty_idx + 1) % ja->nr; - if (pos <= ja->cur_idx) - ja->cur_idx = (ja->cur_idx + 1) % ja->nr; + new_buckets[pos + i] = bu[i]; + new_bucket_seq[pos + i] = 0; } - ret = bch2_journal_buckets_to_sb(c, ca); - if (ret) { - /* Revert: */ - swap(new_buckets, ja->buckets); - swap(new_bucket_seq, ja->bucket_seq); - ja->nr = old_nr; - ja->discard_idx = old_discard_idx; - ja->dirty_idx_ondisk = old_dirty_idx_ondisk; - ja->dirty_idx = old_dirty_idx; - ja->cur_idx = old_cur_idx; - } + nr = ja->nr + nr_got; + + ret = bch2_journal_buckets_to_sb(c, ca, new_buckets, nr); + if (ret) + goto err_unblock; if (!new_fs) - spin_unlock(&c->journal.lock); + bch2_write_super(c); + /* Commit: */ if (c) - bch2_journal_unblock(&c->journal); + spin_lock(&c->journal.lock); - if (ret) - goto err; + swap(new_buckets, ja->buckets); + swap(new_bucket_seq, ja->bucket_seq); + ja->nr = nr; - if (!new_fs) { - for (i = 0; i < nr_got; i++) { - ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL, - bch2_trans_mark_metadata_bucket(&trans, ca, - bu[i], BCH_DATA_journal, - ca->mi.bucket_size)); - if (ret) { - bch2_fs_inconsistent(c, "error marking new journal buckets: %i", ret); - goto err; - } - } + if (pos <= ja->discard_idx) + ja->discard_idx = (ja->discard_idx + nr_got) % ja->nr; + if (pos <= ja->dirty_idx_ondisk) + ja->dirty_idx_ondisk = (ja->dirty_idx_ondisk + nr_got) % ja->nr; + if (pos <= ja->dirty_idx) + ja->dirty_idx = (ja->dirty_idx + nr_got) % ja->nr; + if (pos <= ja->cur_idx) + ja->cur_idx = (ja->cur_idx + nr_got) % ja->nr; + + if (c) + spin_unlock(&c->journal.lock); +err_unblock: + if (c) { + bch2_journal_unblock(&c->journal); + mutex_unlock(&c->sb_lock); } -err: - if (ob && !new_fs) + + if (ret && !new_fs) + for (i = 0; i < nr_got; i++) + bch2_trans_run(c, + bch2_trans_mark_metadata_bucket(&trans, ca, + bu[i], BCH_DATA_free, 0)); +err_free: + if (!new_fs) for (i = 0; i < nr_got; i++) bch2_open_bucket_put(c, ob[i]); @@ -902,12 +879,7 @@ err: kfree(new_buckets); kfree(ob); kfree(bu); - return ret; -err_unblock: - if (c) - bch2_journal_unblock(&c->journal); - goto err; } /* @@ -919,55 +891,58 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca, { struct journal_device *ja = &ca->journal; struct closure cl; - unsigned current_nr; int ret = 0; - /* don't handle reducing nr of buckets yet: */ - if (nr < ja->nr) - return 0; - closure_init_stack(&cl); - while (ja->nr != nr && (ret == 0 || ret == -EAGAIN)) { - struct disk_reservation disk_res = { 0, 0 }; + down_write(&c->state_lock); - closure_sync(&cl); + /* don't handle reducing nr of buckets yet: */ + if (nr < ja->nr) + goto unlock; - mutex_lock(&c->sb_lock); - current_nr = ja->nr; + while (ja->nr < nr) { + struct disk_reservation disk_res = { 0, 0 }; /* * note: journal buckets aren't really counted as _sectors_ used yet, so * we don't need the disk reservation to avoid the BUG_ON() in buckets.c * when space used goes up without a reservation - but we do need the * reservation to ensure we'll actually be able to allocate: + * + * XXX: that's not right, disk reservations only ensure a + * filesystem-wide allocation will succeed, this is a device + * specific allocation - we can hang here: */ - if (bch2_disk_reservation_get(c, &disk_res, - bucket_to_sector(ca, nr - ja->nr), 1, 0)) { - mutex_unlock(&c->sb_lock); - return -ENOSPC; - } + ret = bch2_disk_reservation_get(c, &disk_res, + bucket_to_sector(ca, nr - ja->nr), 1, 0); + if (ret) + break; ret = __bch2_set_nr_journal_buckets(ca, nr, false, &cl); bch2_disk_reservation_put(c, &disk_res); - if (ja->nr != current_nr) - bch2_write_super(c); - mutex_unlock(&c->sb_lock); + closure_sync(&cl); + + if (ret && ret != -BCH_ERR_bucket_alloc_blocked) + break; } + if (ret) + bch_err(c, "%s: err %s", __func__, bch2_err_str(ret)); +unlock: + up_write(&c->state_lock); return ret; } int bch2_dev_journal_alloc(struct bch_dev *ca) { unsigned nr; - int ret; if (dynamic_fault("bcachefs:add:journal_alloc")) - return -ENOMEM; + return -BCH_ERR_ENOMEM_set_nr_journal_buckets; /* 1/128th of the device by default: */ nr = ca->mi.nbuckets >> 7; @@ -981,15 +956,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca) min(1 << 13, (1 << 24) / ca->mi.bucket_size)); - if (ca->fs) - mutex_lock(&ca->fs->sb_lock); - - ret = __bch2_set_nr_journal_buckets(ca, nr, true, NULL); - - if (ca->fs) - mutex_unlock(&ca->fs->sb_lock); - - return ret; + return __bch2_set_nr_journal_buckets(ca, nr, true, NULL); } /* startup/shutdown: */ @@ -1005,7 +972,7 @@ static bool bch2_journal_writing_to_device(struct journal *j, unsigned dev_idx) seq++) { struct journal_buf *buf = journal_seq_to_buf(j, seq); - if (bch2_bkey_has_device(bkey_i_to_s_c(&buf->key), dev_idx)) + if (bch2_bkey_has_device_c(bkey_i_to_s_c(&buf->key), dev_idx)) ret = true; } spin_unlock(&j->lock); @@ -1067,7 +1034,7 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq) init_fifo(&j->pin, roundup_pow_of_two(nr + 1), GFP_KERNEL); if (!j->pin.data) { bch_err(c, "error reallocating journal fifo (%llu open entries)", nr); - return -ENOMEM; + return -BCH_ERR_ENOMEM_journal_pin_fifo; } } @@ -1146,7 +1113,7 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) bch2_sb_get_journal(sb); struct bch_sb_field_journal_v2 *journal_buckets_v2 = bch2_sb_get_journal_v2(sb); - unsigned i; + unsigned i, nr_bvecs; ja->nr = 0; @@ -1161,16 +1128,19 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) ja->bucket_seq = kcalloc(ja->nr, sizeof(u64), GFP_KERNEL); if (!ja->bucket_seq) - return -ENOMEM; + return -BCH_ERR_ENOMEM_dev_journal_init; + + nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE); - ca->journal.bio = bio_kmalloc(GFP_KERNEL, - DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE)); + ca->journal.bio = bio_kmalloc(nr_bvecs, GFP_KERNEL); if (!ca->journal.bio) - return -ENOMEM; + return -BCH_ERR_ENOMEM_dev_journal_init; + + bio_init(ca->journal.bio, NULL, ca->journal.bio->bi_inline_vecs, nr_bvecs, 0); ja->buckets = kcalloc(ja->nr, sizeof(u64), GFP_KERNEL); if (!ja->buckets) - return -ENOMEM; + return -BCH_ERR_ENOMEM_dev_journal_init; if (journal_buckets_v2) { unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2); @@ -1192,6 +1162,8 @@ void bch2_fs_journal_exit(struct journal *j) { unsigned i; + darray_exit(&j->early_journal_entries); + for (i = 0; i < ARRAY_SIZE(j->buf); i++) kvpfree(j->buf[i].data, j->buf[i].buf_size); free_fifo(&j->pin); @@ -1222,7 +1194,7 @@ int bch2_fs_journal_init(struct journal *j) { .cur_entry_offset = JOURNAL_ENTRY_CLOSED_VAL }).v); if (!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL))) { - ret = -ENOMEM; + ret = -BCH_ERR_ENOMEM_journal_pin_fifo; goto out; } @@ -1230,7 +1202,7 @@ int bch2_fs_journal_init(struct journal *j) j->buf[i].buf_size = JOURNAL_ENTRY_SIZE_MIN; j->buf[i].data = kvpmalloc(j->buf[i].buf_size, GFP_KERNEL); if (!j->buf[i].data) { - ret = -ENOMEM; + ret = -BCH_ERR_ENOMEM_journal_buf; goto out; } } @@ -1252,90 +1224,91 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) u64 seq; unsigned i; + if (!out->nr_tabstops) + printbuf_tabstop_push(out, 24); out->atomic++; - out->tabstops[0] = 24; rcu_read_lock(); s = READ_ONCE(j->reservations); - pr_buf(out, "dirty journal entries:\t%llu/%llu\n",fifo_used(&j->pin), j->pin.size); - pr_buf(out, "seq:\t\t\t%llu\n", journal_cur_seq(j)); - pr_buf(out, "seq_ondisk:\t\t%llu\n", j->seq_ondisk); - pr_buf(out, "last_seq:\t\t%llu\n", journal_last_seq(j)); - pr_buf(out, "last_seq_ondisk:\t%llu\n", j->last_seq_ondisk); - pr_buf(out, "flushed_seq_ondisk:\t%llu\n", j->flushed_seq_ondisk); - pr_buf(out, "prereserved:\t\t%u/%u\n", j->prereserved.reserved, j->prereserved.remaining); - pr_buf(out, "watermark:\t\t%s\n", bch2_journal_watermarks[j->watermark]); - pr_buf(out, "each entry reserved:\t%u\n", j->entry_u64s_reserved); - pr_buf(out, "nr flush writes:\t%llu\n", j->nr_flush_writes); - pr_buf(out, "nr noflush writes:\t%llu\n", j->nr_noflush_writes); - pr_buf(out, "nr direct reclaim:\t%llu\n", j->nr_direct_reclaim); - pr_buf(out, "nr background reclaim:\t%llu\n", j->nr_background_reclaim); - pr_buf(out, "reclaim kicked:\t\t%u\n", j->reclaim_kicked); - pr_buf(out, "reclaim runs in:\t%u ms\n", time_after(j->next_reclaim, now) + prt_printf(out, "dirty journal entries:\t%llu/%llu\n", fifo_used(&j->pin), j->pin.size); + prt_printf(out, "seq:\t\t\t%llu\n", journal_cur_seq(j)); + prt_printf(out, "seq_ondisk:\t\t%llu\n", j->seq_ondisk); + prt_printf(out, "last_seq:\t\t%llu\n", journal_last_seq(j)); + prt_printf(out, "last_seq_ondisk:\t%llu\n", j->last_seq_ondisk); + prt_printf(out, "flushed_seq_ondisk:\t%llu\n", j->flushed_seq_ondisk); + prt_printf(out, "prereserved:\t\t%u/%u\n", j->prereserved.reserved, j->prereserved.remaining); + prt_printf(out, "watermark:\t\t%s\n", bch2_journal_watermarks[j->watermark]); + prt_printf(out, "each entry reserved:\t%u\n", j->entry_u64s_reserved); + prt_printf(out, "nr flush writes:\t%llu\n", j->nr_flush_writes); + prt_printf(out, "nr noflush writes:\t%llu\n", j->nr_noflush_writes); + prt_printf(out, "nr direct reclaim:\t%llu\n", j->nr_direct_reclaim); + prt_printf(out, "nr background reclaim:\t%llu\n", j->nr_background_reclaim); + prt_printf(out, "reclaim kicked:\t\t%u\n", j->reclaim_kicked); + prt_printf(out, "reclaim runs in:\t%u ms\n", time_after(j->next_reclaim, now) ? jiffies_to_msecs(j->next_reclaim - jiffies) : 0); - pr_buf(out, "current entry sectors:\t%u\n", j->cur_entry_sectors); - pr_buf(out, "current entry error:\t%s\n", bch2_journal_errors[j->cur_entry_error]); - pr_buf(out, "current entry:\t\t"); + prt_printf(out, "current entry sectors:\t%u\n", j->cur_entry_sectors); + prt_printf(out, "current entry error:\t%s\n", bch2_journal_errors[j->cur_entry_error]); + prt_printf(out, "current entry:\t\t"); switch (s.cur_entry_offset) { case JOURNAL_ENTRY_ERROR_VAL: - pr_buf(out, "error"); + prt_printf(out, "error"); break; case JOURNAL_ENTRY_CLOSED_VAL: - pr_buf(out, "closed"); + prt_printf(out, "closed"); break; default: - pr_buf(out, "%u/%u", s.cur_entry_offset, j->cur_entry_u64s); + prt_printf(out, "%u/%u", s.cur_entry_offset, j->cur_entry_u64s); break; } - pr_newline(out); + prt_newline(out); for (seq = journal_cur_seq(j); seq >= journal_last_unwritten_seq(j); --seq) { i = seq & JOURNAL_BUF_MASK; - pr_buf(out, "unwritten entry:"); - pr_tab(out); - pr_buf(out, "%llu", seq); - pr_newline(out); - pr_indent_push(out, 2); + prt_printf(out, "unwritten entry:"); + prt_tab(out); + prt_printf(out, "%llu", seq); + prt_newline(out); + printbuf_indent_add(out, 2); - pr_buf(out, "refcount:"); - pr_tab(out); - pr_buf(out, "%u", journal_state_count(s, i)); - pr_newline(out); + prt_printf(out, "refcount:"); + prt_tab(out); + prt_printf(out, "%u", journal_state_count(s, i)); + prt_newline(out); - pr_buf(out, "sectors:"); - pr_tab(out); - pr_buf(out, "%u", j->buf[i].sectors); - pr_newline(out); + prt_printf(out, "sectors:"); + prt_tab(out); + prt_printf(out, "%u", j->buf[i].sectors); + prt_newline(out); - pr_buf(out, "expires"); - pr_tab(out); - pr_buf(out, "%li jiffies", j->buf[i].expires - jiffies); - pr_newline(out); + prt_printf(out, "expires"); + prt_tab(out); + prt_printf(out, "%li jiffies", j->buf[i].expires - jiffies); + prt_newline(out); - pr_indent_pop(out, 2); + printbuf_indent_sub(out, 2); } - pr_buf(out, + prt_printf(out, "replay done:\t\t%i\n", test_bit(JOURNAL_REPLAY_DONE, &j->flags)); - pr_buf(out, "space:\n"); - pr_buf(out, "\tdiscarded\t%u:%u\n", + prt_printf(out, "space:\n"); + prt_printf(out, "\tdiscarded\t%u:%u\n", j->space[journal_space_discarded].next_entry, j->space[journal_space_discarded].total); - pr_buf(out, "\tclean ondisk\t%u:%u\n", + prt_printf(out, "\tclean ondisk\t%u:%u\n", j->space[journal_space_clean_ondisk].next_entry, j->space[journal_space_clean_ondisk].total); - pr_buf(out, "\tclean\t\t%u:%u\n", + prt_printf(out, "\tclean\t\t%u:%u\n", j->space[journal_space_clean].next_entry, j->space[journal_space_clean].total); - pr_buf(out, "\ttotal\t\t%u:%u\n", + prt_printf(out, "\ttotal\t\t%u:%u\n", j->space[journal_space_total].next_entry, j->space[journal_space_total].total); @@ -1349,14 +1322,14 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) if (!ja->nr) continue; - pr_buf(out, "dev %u:\n", i); - pr_buf(out, "\tnr\t\t%u\n", ja->nr); - pr_buf(out, "\tbucket size\t%u\n", ca->mi.bucket_size); - pr_buf(out, "\tavailable\t%u:%u\n", bch2_journal_dev_buckets_available(j, ja, journal_space_discarded), ja->sectors_free); - pr_buf(out, "\tdiscard_idx\t%u\n", ja->discard_idx); - pr_buf(out, "\tdirty_ondisk\t%u (seq %llu)\n", ja->dirty_idx_ondisk, ja->bucket_seq[ja->dirty_idx_ondisk]); - pr_buf(out, "\tdirty_idx\t%u (seq %llu)\n", ja->dirty_idx, ja->bucket_seq[ja->dirty_idx]); - pr_buf(out, "\tcur_idx\t\t%u (seq %llu)\n", ja->cur_idx, ja->bucket_seq[ja->cur_idx]); + prt_printf(out, "dev %u:\n", i); + prt_printf(out, "\tnr\t\t%u\n", ja->nr); + prt_printf(out, "\tbucket size\t%u\n", ca->mi.bucket_size); + prt_printf(out, "\tavailable\t%u:%u\n", bch2_journal_dev_buckets_available(j, ja, journal_space_discarded), ja->sectors_free); + prt_printf(out, "\tdiscard_idx\t%u\n", ja->discard_idx); + prt_printf(out, "\tdirty_ondisk\t%u (seq %llu)\n", ja->dirty_idx_ondisk, ja->bucket_seq[ja->dirty_idx_ondisk]); + prt_printf(out, "\tdirty_idx\t%u (seq %llu)\n", ja->dirty_idx, ja->bucket_seq[ja->dirty_idx]); + prt_printf(out, "\tcur_idx\t\t%u (seq %llu)\n", ja->cur_idx, ja->bucket_seq[ja->cur_idx]); } rcu_read_unlock(); @@ -1375,6 +1348,7 @@ bool bch2_journal_seq_pins_to_text(struct printbuf *out, struct journal *j, u64 { struct journal_entry_pin_list *pin_list; struct journal_entry_pin *pin; + unsigned i; spin_lock(&j->lock); *seq = max(*seq, j->pin.front); @@ -1388,31 +1362,27 @@ bool bch2_journal_seq_pins_to_text(struct printbuf *out, struct journal *j, u64 pin_list = journal_seq_pin(j, *seq); - pr_buf(out, "%llu: count %u", *seq, atomic_read(&pin_list->count)); - pr_newline(out); - pr_indent_push(out, 2); - - list_for_each_entry(pin, &pin_list->list, list) { - pr_buf(out, "\t%px %ps", pin, pin->flush); - pr_newline(out); - } + prt_printf(out, "%llu: count %u", *seq, atomic_read(&pin_list->count)); + prt_newline(out); + printbuf_indent_add(out, 2); - list_for_each_entry(pin, &pin_list->key_cache_list, list) { - pr_buf(out, "\t%px %ps", pin, pin->flush); - pr_newline(out); - } + for (i = 0; i < ARRAY_SIZE(pin_list->list); i++) + list_for_each_entry(pin, &pin_list->list[i], list) { + prt_printf(out, "\t%px %ps", pin, pin->flush); + prt_newline(out); + } if (!list_empty(&pin_list->flushed)) { - pr_buf(out, "flushed:"); - pr_newline(out); + prt_printf(out, "flushed:"); + prt_newline(out); } list_for_each_entry(pin, &pin_list->flushed, list) { - pr_buf(out, "\t%px %ps", pin, pin->flush); - pr_newline(out); + prt_printf(out, "\t%px %ps", pin, pin->flush); + prt_newline(out); } - pr_indent_pop(out, 2); + printbuf_indent_sub(out, 2); --out->atomic; spin_unlock(&j->lock);