mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
bcachefs fixes for v6.8-rc2
- fix for REQ_OP_FLUSH usage; this fixes filesystems going read only with -EOPNOTSUPP from the block layer. (this really should have gone in with the block layer patch causing the -EOPNOTSUPP, or should have gone in before). - fix an allocation in non-sleepable context - fix one source of srcu lock latency, on devices with terrible discard latency - fix a reattach_inode() issue in fsck -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEKnAFLkS8Qha+jvQrE6szbY3KbnYFAmW0PmoACgkQE6szbY3K bnZpbQ//V2tTJOvnhfMNn7n0oq9TVRJnSmhuredkE4arhWgyfx8RF81mUajAS5GW u4S+i+g5BZDgb75vnAAXKxzCwr5TLAoOBU9jhKROzXykqgoyQPyNSAHxa9vHDEmp hfaML1ZuAq54N6ahuEhFjEGaImqF0Jv1K/F3pqDeBm1ulW+VDyLzLihKm/CJs7bp m9B35QyPx7/dqTrqCrmKPY0LH3lhv6DT3GbCS8D6B3OPgoqFBYvgnMj+uHiS4gAo pSqkMnoIFatTOuQYJXrLJsYUc72WHdXjZuAVmr0pGWyICZmOdGdrayYo48Xa/nBE a8qVdo8SWwn8zJKzZPxXK6ViYg8Gn7xCWx3V30SiPaLhcQddwlyRS+QemX3nNsmm 4w9Q/QwhfjJ1624vLH850ajfbIjYoUwhmIeVt1UYO7adBvNCzmDFI+HZqqWPP3Z1 FhZsjTs8JzByLMFL9N8z4Iy7DZ2it1EhoW+RoptvYp0K46NREeh1reDmiI9/RWp7 62IaX8/fqiiakXfflpPa0gXo+S/aZfaDy6QL9xSOLLf/7tbPwnmEZVw0V6imBTy6 E0ja7HDeBzlGk/IqMZGDva3FPGJZxjFQPBemiHMGYvMvm0qVPKum5behnZFRq6hc Z2SWm/jnDo4J/K9156GrWWvLU6WhZbt/1twp7YEdhefEjKRLH7g= =6Xv0 -----END PGP SIGNATURE----- Merge tag 'bcachefs-2024-01-26' of https://evilpiepirate.org/git/bcachefs Pull bcachefs fixes from Kent Overstreet: - fix for REQ_OP_FLUSH usage; this fixes filesystems going read only with -EOPNOTSUPP from the block layer. (this really should have gone in with the block layer patch causing the -EOPNOTSUPP, or should have gone in before). - fix an allocation in non-sleepable context - fix one source of srcu lock latency, on devices with terrible discard latency - fix a reattach_inode() issue in fsck * tag 'bcachefs-2024-01-26' of https://evilpiepirate.org/git/bcachefs: bcachefs: __lookup_dirent() works in snapshot, not subvol bcachefs: discard path uses unlock_long() bcachefs: fix incorrect usage of REQ_OP_FLUSH bcachefs: Add gfp flags param to bch2_prt_task_backtrace()
This commit is contained in:
commit
064a4a5bfa
@ -1715,7 +1715,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
|
||||
* This works without any other locks because this is the only
|
||||
* thread that removes items from the need_discard tree
|
||||
*/
|
||||
bch2_trans_unlock(trans);
|
||||
bch2_trans_unlock_long(trans);
|
||||
blkdev_issue_discard(ca->disk_sb.bdev,
|
||||
k.k->p.offset * ca->mi.bucket_size,
|
||||
ca->mi.bucket_size,
|
||||
|
@ -92,7 +92,7 @@ static noinline void print_cycle(struct printbuf *out, struct lock_graph *g)
|
||||
continue;
|
||||
|
||||
bch2_btree_trans_to_text(out, i->trans);
|
||||
bch2_prt_task_backtrace(out, task, i == g->g ? 5 : 1);
|
||||
bch2_prt_task_backtrace(out, task, i == g->g ? 5 : 1, GFP_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +227,7 @@ static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle)
|
||||
prt_printf(&buf, "backtrace:");
|
||||
prt_newline(&buf);
|
||||
printbuf_indent_add(&buf, 2);
|
||||
bch2_prt_task_backtrace(&buf, trans->locking_wait.task, 2);
|
||||
bch2_prt_task_backtrace(&buf, trans->locking_wait.task, 2, GFP_NOWAIT);
|
||||
printbuf_indent_sub(&buf, 2);
|
||||
prt_newline(&buf);
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ restart:
|
||||
prt_printf(&i->buf, "backtrace:");
|
||||
prt_newline(&i->buf);
|
||||
printbuf_indent_add(&i->buf, 2);
|
||||
bch2_prt_task_backtrace(&i->buf, task, 0);
|
||||
bch2_prt_task_backtrace(&i->buf, task, 0, GFP_KERNEL);
|
||||
printbuf_indent_sub(&i->buf, 2);
|
||||
prt_newline(&i->buf);
|
||||
|
||||
|
@ -79,7 +79,7 @@ void bch2_inode_flush_nocow_writes_async(struct bch_fs *c,
|
||||
continue;
|
||||
|
||||
bio = container_of(bio_alloc_bioset(ca->disk_sb.bdev, 0,
|
||||
REQ_OP_FLUSH,
|
||||
REQ_OP_WRITE|REQ_PREFLUSH,
|
||||
GFP_KERNEL,
|
||||
&c->nocow_flush_bioset),
|
||||
struct nocow_flush, bio);
|
||||
|
@ -119,22 +119,19 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr,
|
||||
if (!ret)
|
||||
*snapshot = iter.pos.snapshot;
|
||||
err:
|
||||
bch_err_msg(trans->c, ret, "fetching inode %llu:%u", inode_nr, *snapshot);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __lookup_dirent(struct btree_trans *trans,
|
||||
static int lookup_dirent_in_snapshot(struct btree_trans *trans,
|
||||
struct bch_hash_info hash_info,
|
||||
subvol_inum dir, struct qstr *name,
|
||||
u64 *target, unsigned *type)
|
||||
u64 *target, unsigned *type, u32 snapshot)
|
||||
{
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c_dirent d;
|
||||
int ret;
|
||||
|
||||
ret = bch2_hash_lookup(trans, &iter, bch2_dirent_hash_desc,
|
||||
&hash_info, dir, name, 0);
|
||||
int ret = bch2_hash_lookup_in_snapshot(trans, &iter, bch2_dirent_hash_desc,
|
||||
&hash_info, dir, name, 0, snapshot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -225,15 +222,16 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
||||
|
||||
struct bch_inode_unpacked root_inode;
|
||||
struct bch_hash_info root_hash_info;
|
||||
ret = lookup_inode(trans, root_inum.inum, &root_inode, &snapshot);
|
||||
u32 root_inode_snapshot = snapshot;
|
||||
ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot);
|
||||
bch_err_msg(c, ret, "looking up root inode");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
root_hash_info = bch2_hash_info_init(c, &root_inode);
|
||||
|
||||
ret = __lookup_dirent(trans, root_hash_info, root_inum,
|
||||
&lostfound_str, &inum, &d_type);
|
||||
ret = lookup_dirent_in_snapshot(trans, root_hash_info, root_inum,
|
||||
&lostfound_str, &inum, &d_type, snapshot);
|
||||
if (bch2_err_matches(ret, ENOENT))
|
||||
goto create_lostfound;
|
||||
|
||||
@ -250,7 +248,10 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
||||
* The bch2_check_dirents pass has already run, dangling dirents
|
||||
* shouldn't exist here:
|
||||
*/
|
||||
return lookup_inode(trans, inum, lostfound, &snapshot);
|
||||
ret = lookup_inode(trans, inum, lostfound, &snapshot);
|
||||
bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)",
|
||||
inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot));
|
||||
return ret;
|
||||
|
||||
create_lostfound:
|
||||
/*
|
||||
|
@ -233,7 +233,7 @@ static void __journal_entry_close(struct journal *j, unsigned closed_val, bool t
|
||||
prt_str(&pbuf, "entry size: ");
|
||||
prt_human_readable_u64(&pbuf, vstruct_bytes(buf->data));
|
||||
prt_newline(&pbuf);
|
||||
bch2_prt_task_backtrace(&pbuf, current, 1);
|
||||
bch2_prt_task_backtrace(&pbuf, current, 1, GFP_NOWAIT);
|
||||
trace_journal_entry_close(c, pbuf.buf);
|
||||
printbuf_exit(&pbuf);
|
||||
}
|
||||
|
@ -1988,7 +1988,8 @@ CLOSURE_CALLBACK(bch2_journal_write)
|
||||
percpu_ref_get(&ca->io_ref);
|
||||
|
||||
bio = ca->journal.bio;
|
||||
bio_reset(bio, ca->disk_sb.bdev, REQ_OP_FLUSH);
|
||||
bio_reset(bio, ca->disk_sb.bdev,
|
||||
REQ_OP_WRITE|REQ_PREFLUSH);
|
||||
bio->bi_end_io = journal_write_endio;
|
||||
bio->bi_private = ca;
|
||||
closure_bio_submit(bio, cl);
|
||||
|
@ -160,21 +160,16 @@ static inline bool is_visible_key(struct bch_hash_desc desc, subvol_inum inum, s
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
bch2_hash_lookup(struct btree_trans *trans,
|
||||
bch2_hash_lookup_in_snapshot(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
const struct bch_hash_desc desc,
|
||||
const struct bch_hash_info *info,
|
||||
subvol_inum inum, const void *key,
|
||||
unsigned flags)
|
||||
unsigned flags, u32 snapshot)
|
||||
{
|
||||
struct bkey_s_c k;
|
||||
u32 snapshot;
|
||||
int ret;
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
|
||||
SPOS(inum.inum, desc.hash_key(info, key), snapshot),
|
||||
POS(inum.inum, U64_MAX),
|
||||
@ -194,6 +189,19 @@ bch2_hash_lookup(struct btree_trans *trans,
|
||||
return ret ?: -BCH_ERR_ENOENT_str_hash_lookup;
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
bch2_hash_lookup(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
const struct bch_hash_desc desc,
|
||||
const struct bch_hash_info *info,
|
||||
subvol_inum inum, const void *key,
|
||||
unsigned flags)
|
||||
{
|
||||
u32 snapshot;
|
||||
return bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot) ?:
|
||||
bch2_hash_lookup_in_snapshot(trans, iter, desc, info, inum, key, flags, snapshot);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
bch2_hash_hole(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
|
@ -272,14 +272,14 @@ void bch2_print_string_as_lines(const char *prefix, const char *lines)
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr)
|
||||
int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr,
|
||||
gfp_t gfp)
|
||||
{
|
||||
#ifdef CONFIG_STACKTRACE
|
||||
unsigned nr_entries = 0;
|
||||
int ret = 0;
|
||||
|
||||
stack->nr = 0;
|
||||
ret = darray_make_room(stack, 32);
|
||||
int ret = darray_make_room_gfp(stack, 32, gfp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -308,10 +308,10 @@ void bch2_prt_backtrace(struct printbuf *out, bch_stacktrace *stack)
|
||||
}
|
||||
}
|
||||
|
||||
int bch2_prt_task_backtrace(struct printbuf *out, struct task_struct *task, unsigned skipnr)
|
||||
int bch2_prt_task_backtrace(struct printbuf *out, struct task_struct *task, unsigned skipnr, gfp_t gfp)
|
||||
{
|
||||
bch_stacktrace stack = { 0 };
|
||||
int ret = bch2_save_backtrace(&stack, task, skipnr + 1);
|
||||
int ret = bch2_save_backtrace(&stack, task, skipnr + 1, gfp);
|
||||
|
||||
bch2_prt_backtrace(out, &stack);
|
||||
darray_exit(&stack);
|
||||
|
@ -348,9 +348,9 @@ void bch2_prt_u64_base2(struct printbuf *, u64);
|
||||
void bch2_print_string_as_lines(const char *prefix, const char *lines);
|
||||
|
||||
typedef DARRAY(unsigned long) bch_stacktrace;
|
||||
int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *, unsigned);
|
||||
int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *, unsigned, gfp_t);
|
||||
void bch2_prt_backtrace(struct printbuf *, bch_stacktrace *);
|
||||
int bch2_prt_task_backtrace(struct printbuf *, struct task_struct *, unsigned);
|
||||
int bch2_prt_task_backtrace(struct printbuf *, struct task_struct *, unsigned, gfp_t);
|
||||
|
||||
static inline void prt_bdevname(struct printbuf *out, struct block_device *bdev)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user