summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/ec.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-03-09 10:18:09 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:56 -0400
commitfba053d2aaca8f9a4486e865452d80245a8cc215 (patch)
tree33b64ada1518141ca3053949166bc7b21d91616a /fs/bcachefs/ec.h
parent10d9f7d2853d5e4c6f21a0dc96f6e98c2d0828e7 (diff)
downloadlinux-fba053d2aaca8f9a4486e865452d80245a8cc215.tar.gz
linux-fba053d2aaca8f9a4486e865452d80245a8cc215.tar.bz2
linux-fba053d2aaca8f9a4486e865452d80245a8cc215.zip
bcachefs: Second layer of refcounting for new stripes
This will be used for move writes, which will be waiting until the stripe is created to do the index update. They need to prevent the stripe from being reclaimed until their index update is done, so we need another refcount that just keeps the stripe open. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> # Conflicts: # fs/bcachefs/ec.c # fs/bcachefs/io.c
Diffstat (limited to 'fs/bcachefs/ec.h')
-rw-r--r--fs/bcachefs/ec.h36
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h
index d112aea9ec56..8f777a37e43d 100644
--- a/fs/bcachefs/ec.h
+++ b/fs/bcachefs/ec.h
@@ -143,6 +143,12 @@ struct ec_stripe_buf {
struct ec_stripe_head;
+enum ec_stripe_ref {
+ STRIPE_REF_io,
+ STRIPE_REF_stripe,
+ STRIPE_REF_NR
+};
+
struct ec_stripe_new {
struct bch_fs *c;
struct ec_stripe_head *h;
@@ -154,8 +160,7 @@ struct ec_stripe_new {
struct closure iodone;
- /* counts in flight writes, stripe is created when pin == 0 */
- atomic_t pin;
+ atomic_t ref[STRIPE_REF_NR];
int err;
@@ -213,19 +218,30 @@ void bch2_stripes_heap_insert(struct bch_fs *, struct stripe *, size_t);
void bch2_do_stripe_deletes(struct bch_fs *);
void bch2_ec_do_stripe_creates(struct bch_fs *);
+void bch2_ec_stripe_new_free(struct bch_fs *, struct ec_stripe_new *);
-static inline void ec_stripe_new_get(struct ec_stripe_new *s)
+static inline void ec_stripe_new_get(struct ec_stripe_new *s,
+ enum ec_stripe_ref ref)
{
- atomic_inc(&s->pin);
+ atomic_inc(&s->ref[ref]);
}
-static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s)
+static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s,
+ enum ec_stripe_ref ref)
{
- BUG_ON(atomic_read(&s->pin) <= 0);
- BUG_ON(!s->err && !s->idx);
-
- if (atomic_dec_and_test(&s->pin))
- bch2_ec_do_stripe_creates(c);
+ BUG_ON(atomic_read(&s->ref[ref]) <= 0);
+
+ if (atomic_dec_and_test(&s->ref[ref]))
+ switch (ref) {
+ case STRIPE_REF_stripe:
+ bch2_ec_stripe_new_free(c, s);
+ break;
+ case STRIPE_REF_io:
+ bch2_ec_do_stripe_creates(c);
+ break;
+ default:
+ unreachable();
+ }
}
void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);