Skip to content

Commit 26aff84

Browse files
committed
Merge tag 'bcachefs-2023-12-10' of https://evilpiepirate.org/git/bcachefs
Pull more bcachefs bugfixes from Kent Overstreet: - Fix a rare emergency shutdown path bug: dropping journal pins after the filesystem has mostly been torn down is not what we want. - Fix some concurrency issues with the btree write buffer and journal replay by not using the btree write buffer until journal replay is finished - A fixup from the prior patch to kill journal pre-reservations: at the start of the btree update path, where previously we took a pre-reservation, we do at least want to check the journal watermark. - Fix a race between dropping device metadata and btree node writes, which would re-add a pointer to a device that had just been dropped - Fix one of the SCRU lock warnings, in bch2_compression_stats_to_text(). - Partial fix for a rare transaction paths overflow, when indirect extents had been split by background tasks, by not running certain triggers when they're not needed. - Fix for creating a snapshot with implicit source in a subdirectory of the containing subvolume - Don't unfreeze when we're emergency read-only - Fix for rebalance spinning trying to compress unwritten extentns - Another deleted_inodes fix, for directories - Fix a rare deadlock (usually just an unecessary wait) when flushing the journal with an open journal entry. * tag 'bcachefs-2023-12-10' of https://evilpiepirate.org/git/bcachefs: bcachefs: Close journal entry if necessary when flushing all pins bcachefs: Fix uninitialized var in bch2_journal_replay() bcachefs: Fix deleted inode check for dirs bcachefs: rebalance shouldn't attempt to compress unwritten extents bcachefs: don't attempt rw on unfreeze when shutdown bcachefs: Fix creating snapshot with implict source bcachefs: Don't run indirect extent trigger unless inserting/deleting bcachefs: Convert compression_stats to for_each_btree_key2 bcachefs: Fix bch2_extent_drop_ptrs() call bcachefs: Fix a journal deadlock in replay bcachefs; Don't use btree write buffer until journal replay is finished bcachefs: Don't drop journal pins in exit path
2 parents 52bf9f6 + a66ff26 commit 26aff84

20 files changed

Lines changed: 84 additions & 38 deletions

fs/bcachefs/btree_cache.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "debug.h"
1010
#include "errcode.h"
1111
#include "error.h"
12+
#include "journal.h"
1213
#include "trace.h"
1314

1415
#include <linux/prefetch.h>
@@ -424,14 +425,11 @@ void bch2_fs_btree_cache_exit(struct bch_fs *c)
424425
BUG_ON(btree_node_read_in_flight(b) ||
425426
btree_node_write_in_flight(b));
426427

427-
if (btree_node_dirty(b))
428-
bch2_btree_complete_write(c, b, btree_current_write(b));
429-
clear_btree_node_dirty_acct(c, b);
430-
431428
btree_node_data_free(c, b);
432429
}
433430

434-
BUG_ON(atomic_read(&c->btree_cache.dirty));
431+
BUG_ON(!bch2_journal_error(&c->journal) &&
432+
atomic_read(&c->btree_cache.dirty));
435433

436434
list_splice(&bc->freed_pcpu, &bc->freed_nonpcpu);
437435

fs/bcachefs/btree_io.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,8 +1704,8 @@ int bch2_btree_root_read(struct bch_fs *c, enum btree_id id,
17041704
return bch2_trans_run(c, __bch2_btree_root_read(trans, id, k, level));
17051705
}
17061706

1707-
void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
1708-
struct btree_write *w)
1707+
static void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
1708+
struct btree_write *w)
17091709
{
17101710
unsigned long old, new, v = READ_ONCE(b->will_make_reachable);
17111711

fs/bcachefs/btree_io.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,6 @@ void bch2_btree_node_read(struct bch_fs *, struct btree *, bool);
134134
int bch2_btree_root_read(struct bch_fs *, enum btree_id,
135135
const struct bkey_i *, unsigned);
136136

137-
void bch2_btree_complete_write(struct bch_fs *, struct btree *,
138-
struct btree_write *);
139-
140137
bool bch2_btree_post_write_cleanup(struct bch_fs *, struct btree *);
141138

142139
enum btree_write_flags {

fs/bcachefs/btree_key_cache.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -992,8 +992,6 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
992992
list_for_each_entry_safe(ck, n, &items, list) {
993993
cond_resched();
994994

995-
bch2_journal_pin_drop(&c->journal, &ck->journal);
996-
997995
list_del(&ck->list);
998996
kfree(ck->k);
999997
six_lock_exit(&ck->c.lock);

fs/bcachefs/btree_update.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,19 @@ int __must_check bch2_trans_update_seq(struct btree_trans *trans, u64 seq,
554554
BTREE_UPDATE_PREJOURNAL);
555555
}
556556

557+
static noinline int bch2_btree_insert_clone_trans(struct btree_trans *trans,
558+
enum btree_id btree,
559+
struct bkey_i *k)
560+
{
561+
struct bkey_i *n = bch2_trans_kmalloc(trans, bkey_bytes(&k->k));
562+
int ret = PTR_ERR_OR_ZERO(n);
563+
if (ret)
564+
return ret;
565+
566+
bkey_copy(n, k);
567+
return bch2_btree_insert_trans(trans, btree, n, 0);
568+
}
569+
557570
int __must_check bch2_trans_update_buffered(struct btree_trans *trans,
558571
enum btree_id btree,
559572
struct bkey_i *k)
@@ -564,6 +577,9 @@ int __must_check bch2_trans_update_buffered(struct btree_trans *trans,
564577
EBUG_ON(trans->nr_wb_updates > trans->wb_updates_size);
565578
EBUG_ON(k->k.u64s > BTREE_WRITE_BUFERED_U64s_MAX);
566579

580+
if (unlikely(trans->journal_replay_not_finished))
581+
return bch2_btree_insert_clone_trans(trans, btree, k);
582+
567583
trans_for_each_wb_update(trans, i) {
568584
if (i->btree == btree && bpos_eq(i->k.k.p, k->k.p)) {
569585
bkey_copy(&i->k, k);

fs/bcachefs/btree_update_interior.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,17 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
10561056
flags &= ~BCH_WATERMARK_MASK;
10571057
flags |= watermark;
10581058

1059+
if (!(flags & BTREE_INSERT_JOURNAL_RECLAIM) &&
1060+
watermark < c->journal.watermark) {
1061+
struct journal_res res = { 0 };
1062+
1063+
ret = drop_locks_do(trans,
1064+
bch2_journal_res_get(&c->journal, &res, 1,
1065+
watermark|JOURNAL_RES_GET_CHECK));
1066+
if (ret)
1067+
return ERR_PTR(ret);
1068+
}
1069+
10591070
while (1) {
10601071
nr_nodes[!!update_level] += 1 + split;
10611072
update_level++;

fs/bcachefs/data_update.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
471471
* we aren't using the extent overwrite path to delete, we're
472472
* just using the normal key deletion path:
473473
*/
474-
if (bkey_deleted(&n->k))
474+
if (bkey_deleted(&n->k) && !(iter->flags & BTREE_ITER_IS_EXTENTS))
475475
n->k.size = 0;
476476

477477
return bch2_trans_relock(trans) ?:
@@ -591,7 +591,7 @@ int bch2_data_update_init(struct btree_trans *trans,
591591
m->data_opts.rewrite_ptrs = 0;
592592
/* if iter == NULL, it's just a promote */
593593
if (iter)
594-
ret = bch2_extent_drop_ptrs(trans, iter, k, data_opts);
594+
ret = bch2_extent_drop_ptrs(trans, iter, k, m->data_opts);
595595
goto done;
596596
}
597597

fs/bcachefs/dirent.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -485,20 +485,15 @@ u64 bch2_dirent_lookup(struct bch_fs *c, subvol_inum dir,
485485
return ret;
486486
}
487487

488-
int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
488+
int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 snapshot)
489489
{
490490
struct btree_iter iter;
491491
struct bkey_s_c k;
492-
u32 snapshot;
493492
int ret;
494493

495-
ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot);
496-
if (ret)
497-
return ret;
498-
499494
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents,
500-
SPOS(dir.inum, 0, snapshot),
501-
POS(dir.inum, U64_MAX), 0, k, ret)
495+
SPOS(dir, 0, snapshot),
496+
POS(dir, U64_MAX), 0, k, ret)
502497
if (k.k->type == KEY_TYPE_dirent) {
503498
ret = -ENOTEMPTY;
504499
break;
@@ -508,6 +503,14 @@ int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
508503
return ret;
509504
}
510505

506+
int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
507+
{
508+
u32 snapshot;
509+
510+
return bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot) ?:
511+
bch2_empty_dir_snapshot(trans, dir.inum, snapshot);
512+
}
513+
511514
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
512515
{
513516
struct btree_trans *trans = bch2_trans_get(c);

fs/bcachefs/dirent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ u64 bch2_dirent_lookup(struct bch_fs *, subvol_inum,
6464
const struct bch_hash_info *,
6565
const struct qstr *, subvol_inum *);
6666

67+
int bch2_empty_dir_snapshot(struct btree_trans *, u64, u32);
6768
int bch2_empty_dir_trans(struct btree_trans *, subvol_inum);
6869
int bch2_readdir(struct bch_fs *, subvol_inum, struct dir_context *);
6970

fs/bcachefs/extents.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,8 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
12941294
unsigned i = 0;
12951295

12961296
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
1297-
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible) {
1297+
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
1298+
p.ptr.unwritten) {
12981299
rewrite_ptrs = 0;
12991300
goto incompressible;
13001301
}

0 commit comments

Comments
 (0)