Skip to content

Commit 3f53d05

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_data_update_init() cleanup
Factor out some helpers - this function has gotten much too big. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 2102bda commit 3f53d05

File tree

1 file changed

+101
-78
lines changed

1 file changed

+101
-78
lines changed

fs/bcachefs/data_update.c

Lines changed: 101 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,76 @@
2020
#include "subvolume.h"
2121
#include "trace.h"
2222

23+
static void bkey_put_dev_refs(struct bch_fs *c, struct bkey_s_c k)
24+
{
25+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
26+
27+
bkey_for_each_ptr(ptrs, ptr)
28+
bch2_dev_put(bch2_dev_have_ref(c, ptr->dev));
29+
}
30+
31+
static bool bkey_get_dev_refs(struct bch_fs *c, struct bkey_s_c k)
32+
{
33+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
34+
35+
bkey_for_each_ptr(ptrs, ptr) {
36+
if (!bch2_dev_tryget(c, ptr->dev)) {
37+
bkey_for_each_ptr(ptrs, ptr2) {
38+
if (ptr2 == ptr)
39+
break;
40+
bch2_dev_put(bch2_dev_have_ref(c, ptr2->dev));
41+
}
42+
return false;
43+
}
44+
}
45+
return true;
46+
}
47+
48+
static void bkey_nocow_unlock(struct bch_fs *c, struct bkey_s_c k)
49+
{
50+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
51+
52+
bkey_for_each_ptr(ptrs, ptr) {
53+
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
54+
struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
55+
56+
bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
57+
}
58+
}
59+
60+
static bool bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struct bkey_s_c k)
61+
{
62+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
63+
64+
bkey_for_each_ptr(ptrs, ptr) {
65+
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
66+
struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
67+
68+
if (ctxt) {
69+
bool locked;
70+
71+
move_ctxt_wait_event(ctxt,
72+
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) ||
73+
list_empty(&ctxt->ios));
74+
75+
if (!locked)
76+
bch2_bucket_nocow_lock(&c->nocow_locks, bucket, 0);
77+
} else {
78+
if (!bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) {
79+
bkey_for_each_ptr(ptrs, ptr2) {
80+
if (ptr2 == ptr)
81+
break;
82+
83+
bucket = PTR_BUCKET_POS(ca, ptr2);
84+
bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
85+
}
86+
return false;
87+
}
88+
}
89+
}
90+
return true;
91+
}
92+
2393
static void trace_move_extent_finish2(struct bch_fs *c, struct bkey_s_c k)
2494
{
2595
if (trace_move_extent_finish_enabled()) {
@@ -355,17 +425,11 @@ void bch2_data_update_read_done(struct data_update *m,
355425
void bch2_data_update_exit(struct data_update *update)
356426
{
357427
struct bch_fs *c = update->op.c;
358-
struct bkey_ptrs_c ptrs =
359-
bch2_bkey_ptrs_c(bkey_i_to_s_c(update->k.k));
360-
361-
bkey_for_each_ptr(ptrs, ptr) {
362-
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
363-
if (c->opts.nocow_enabled)
364-
bch2_bucket_nocow_unlock(&c->nocow_locks,
365-
PTR_BUCKET_POS(ca, ptr), 0);
366-
bch2_dev_put(ca);
367-
}
428+
struct bkey_s_c k = bkey_i_to_s_c(update->k.k);
368429

430+
if (c->opts.nocow_enabled)
431+
bkey_nocow_unlock(c, k);
432+
bkey_put_dev_refs(c, k);
369433
bch2_bkey_buf_exit(&update->k, c);
370434
bch2_disk_reservation_put(c, &update->op.res);
371435
bch2_bio_free_pages_pool(c, &update->op.wbio.bio);
@@ -546,7 +610,6 @@ int bch2_data_update_init(struct btree_trans *trans,
546610
const union bch_extent_entry *entry;
547611
struct extent_ptr_decoded p;
548612
unsigned i, reserve_sectors = k.k->size * data_opts.extra_replicas;
549-
unsigned ptrs_locked = 0;
550613
int ret = 0;
551614

552615
/*
@@ -557,6 +620,15 @@ int bch2_data_update_init(struct btree_trans *trans,
557620
if (unlikely(k.k->p.snapshot && !bch2_snapshot_equiv(c, k.k->p.snapshot)))
558621
return -BCH_ERR_data_update_done;
559622

623+
if (!bkey_get_dev_refs(c, k))
624+
return -BCH_ERR_data_update_done;
625+
626+
if (c->opts.nocow_enabled &&
627+
!bkey_nocow_lock(c, ctxt, k)) {
628+
bkey_put_dev_refs(c, k);
629+
return -BCH_ERR_nocow_lock_blocked;
630+
}
631+
560632
bch2_bkey_buf_init(&m->k);
561633
bch2_bkey_buf_reassemble(&m->k, c, k);
562634
m->btree_id = btree_id;
@@ -578,40 +650,24 @@ int bch2_data_update_init(struct btree_trans *trans,
578650
m->op.compression_opt = background_compression(io_opts);
579651
m->op.watermark = m->data_opts.btree_insert_flags & BCH_WATERMARK_MASK;
580652

581-
bkey_for_each_ptr(ptrs, ptr) {
582-
if (!bch2_dev_tryget(c, ptr->dev)) {
583-
bkey_for_each_ptr(ptrs, ptr2) {
584-
if (ptr2 == ptr)
585-
break;
586-
bch2_dev_put(bch2_dev_have_ref(c, ptr2->dev));
587-
}
588-
return -BCH_ERR_data_update_done;
589-
}
590-
}
591-
592653
unsigned durability_have = 0, durability_removing = 0;
593654

594655
i = 0;
595656
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
596-
struct bch_dev *ca = bch2_dev_have_ref(c, p.ptr.dev);
597-
struct bpos bucket = PTR_BUCKET_POS(ca, &p.ptr);
598-
bool locked;
599-
600-
rcu_read_lock();
601-
if (((1U << i) & m->data_opts.rewrite_ptrs)) {
602-
BUG_ON(p.ptr.cached);
603-
604-
if (crc_is_compressed(p.crc))
605-
reserve_sectors += k.k->size;
606-
607-
m->op.nr_replicas += bch2_extent_ptr_desired_durability(c, &p);
608-
durability_removing += bch2_extent_ptr_desired_durability(c, &p);
609-
} else if (!p.ptr.cached &&
610-
!((1U << i) & m->data_opts.kill_ptrs)) {
611-
bch2_dev_list_add_dev(&m->op.devs_have, p.ptr.dev);
612-
durability_have += bch2_extent_ptr_durability(c, &p);
657+
if (!p.ptr.cached) {
658+
rcu_read_lock();
659+
if (BIT(i) & m->data_opts.rewrite_ptrs) {
660+
if (crc_is_compressed(p.crc))
661+
reserve_sectors += k.k->size;
662+
663+
m->op.nr_replicas += bch2_extent_ptr_desired_durability(c, &p);
664+
durability_removing += bch2_extent_ptr_desired_durability(c, &p);
665+
} else if (!(BIT(i) & m->data_opts.kill_ptrs)) {
666+
bch2_dev_list_add_dev(&m->op.devs_have, p.ptr.dev);
667+
durability_have += bch2_extent_ptr_durability(c, &p);
668+
}
669+
rcu_read_unlock();
613670
}
614-
rcu_read_unlock();
615671

616672
/*
617673
* op->csum_type is normally initialized from the fs/file's
@@ -626,24 +682,6 @@ int bch2_data_update_init(struct btree_trans *trans,
626682
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible)
627683
m->op.incompressible = true;
628684

629-
if (c->opts.nocow_enabled) {
630-
if (ctxt) {
631-
move_ctxt_wait_event(ctxt,
632-
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks,
633-
bucket, 0)) ||
634-
list_empty(&ctxt->ios));
635-
636-
if (!locked)
637-
bch2_bucket_nocow_lock(&c->nocow_locks, bucket, 0);
638-
} else {
639-
if (!bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) {
640-
ret = -BCH_ERR_nocow_lock_blocked;
641-
goto err;
642-
}
643-
}
644-
ptrs_locked |= (1U << i);
645-
}
646-
647685
i++;
648686
}
649687

@@ -664,7 +702,7 @@ int bch2_data_update_init(struct btree_trans *trans,
664702
/* if iter == NULL, it's just a promote */
665703
if (iter)
666704
ret = bch2_extent_drop_ptrs(trans, iter, k, m->data_opts);
667-
goto done;
705+
goto out;
668706
}
669707

670708
m->op.nr_replicas = min(durability_removing, durability_required) +
@@ -684,8 +722,7 @@ int bch2_data_update_init(struct btree_trans *trans,
684722
bch2_data_update_to_text(&buf, m);
685723
WARN(1, "trying to move an extent, but nr_replicas=0\n%s", buf.buf);
686724
printbuf_exit(&buf);
687-
ret = -BCH_ERR_data_update_done;
688-
goto done;
725+
goto out;
689726
}
690727

691728
m->op.nr_replicas_required = m->op.nr_replicas;
@@ -696,30 +733,16 @@ int bch2_data_update_init(struct btree_trans *trans,
696733
? 0
697734
: BCH_DISK_RESERVATION_NOFAIL);
698735
if (ret)
699-
goto err;
736+
goto out;
700737
}
701738

702739
if (bkey_extent_is_unwritten(k)) {
703740
bch2_update_unwritten_extent(trans, m);
704-
goto done;
741+
goto out;
705742
}
706743

707744
return 0;
708-
err:
709-
i = 0;
710-
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
711-
struct bch_dev *ca = bch2_dev_have_ref(c, p.ptr.dev);
712-
struct bpos bucket = PTR_BUCKET_POS(ca, &p.ptr);
713-
if ((1U << i) & ptrs_locked)
714-
bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
715-
bch2_dev_put(ca);
716-
i++;
717-
}
718-
719-
bch2_bkey_buf_exit(&m->k, c);
720-
bch2_bio_free_pages_pool(c, &m->op.wbio.bio);
721-
return ret;
722-
done:
745+
out:
723746
bch2_data_update_exit(m);
724747
return ret ?: -BCH_ERR_data_update_done;
725748
}

0 commit comments

Comments
 (0)