+ return 0;
+}
+
+static int bucket_set_stripe(struct bch_fs *c, struct bkey_s_c k,
+ unsigned ptr_idx,
+ struct bch_fs_usage *fs_usage,
+ u64 journal_seq, unsigned flags,
+ bool enabled)
+{
+ const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
+ unsigned nr_data = s->nr_blocks - s->nr_redundant;
+ bool parity = ptr_idx >= nr_data;
+ const struct bch_extent_ptr *ptr = s->ptrs + ptr_idx;
+ bool gc = flags & BTREE_TRIGGER_GC;
+ struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
+ struct bucket *g = PTR_BUCKET(ca, ptr, gc);
+ struct bucket_mark new, old;
+ char buf[200];
+ int ret;
+
+ if (enabled)
+ g->ec_redundancy = s->nr_redundant;
+
+ old = bucket_cmpxchg(g, new, ({
+ ret = check_bucket_ref(c, k, ptr, 0, 0, new.gen, new.data_type,
+ new.dirty_sectors, new.cached_sectors);
+ if (ret)
+ return ret;
+
+ if (new.stripe && enabled)
+ bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+ "bucket %u:%zu gen %u: multiple stripes using same bucket\n%s",
+ ptr->dev, PTR_BUCKET_NR(ca, ptr), new.gen,
+ (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf));
+
+ if (!new.stripe && !enabled)
+ bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+ "bucket %u:%zu gen %u: deleting stripe but not marked\n%s",
+ ptr->dev, PTR_BUCKET_NR(ca, ptr), new.gen,
+ (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf));
+
+ new.stripe = enabled;
+
+ if ((flags & BTREE_TRIGGER_GC) && parity) {
+ new.data_type = enabled ? BCH_DATA_parity : 0;
+ new.dirty_sectors = enabled ? le16_to_cpu(s->sectors): 0;
+ }
+
+ if (journal_seq) {
+ new.journal_seq_valid = 1;
+ new.journal_seq = journal_seq;
+ }
+ }));
+
+ if (!enabled)
+ g->ec_redundancy = 0;
+
+ bch2_dev_usage_update(c, ca, fs_usage, old, new, gc);
+ return 0;
+}
+
+static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
+ const struct bch_extent_ptr *ptr,
+ s64 sectors, enum bch_data_type ptr_data_type,
+ u8 bucket_gen, u8 *bucket_data_type,
+ u16 *dirty_sectors, u16 *cached_sectors)
+{
+ u16 *dst_sectors = !ptr->cached
+ ? dirty_sectors
+ : cached_sectors;
+ int ret = check_bucket_ref(c, k, ptr, sectors, ptr_data_type,
+ bucket_gen, *bucket_data_type,
+ *dirty_sectors, *cached_sectors);
+
+ if (ret)
+ return ret;
+
+ *dst_sectors += sectors;