Skip to content

Commit fa85c47

Browse files
author
Kent Overstreet
committed
bcachefs: bch_stripe.disk_label
When reshaping existing stripes, we should keep them on the same target that they were allocated on; to do this, we need to add a field to the btree stripe type. This is a tad awkward, because we only have 8 bits left, and targets are 16 bits - but we only need to store a label, not a full target. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 1b11c4d commit fa85c47

File tree

4 files changed

+43
-16
lines changed

4 files changed

+43
-16
lines changed

fs/bcachefs/ec.c

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,18 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
147147
bch2_prt_csum_type(out, s.csum_type);
148148
prt_printf(out, " gran %u", 1U << s.csum_granularity_bits);
149149

150+
if (s.disk_label) {
151+
prt_str(out, " label");
152+
bch2_disk_path_to_text(out, c, s.disk_label - 1);
153+
}
154+
150155
for (unsigned i = 0; i < s.nr_blocks; i++) {
151156
const struct bch_extent_ptr *ptr = sp->ptrs + i;
152157

153158
if ((void *) ptr >= bkey_val_end(k))
154159
break;
155160

161+
prt_char(out, ' ');
156162
bch2_extent_ptr_to_text(out, c, ptr);
157163

158164
if (s.csum_type < BCH_CSUM_NR &&
@@ -358,6 +364,7 @@ static inline void stripe_to_mem(struct stripe *m, const struct bch_stripe *s)
358364
m->algorithm = s->algorithm;
359365
m->nr_blocks = s->nr_blocks;
360366
m->nr_redundant = s->nr_redundant;
367+
m->disk_label = s->disk_label;
361368
m->blocks_nonempty = 0;
362369

363370
for (unsigned i = 0; i < s->nr_blocks; i++)
@@ -1647,7 +1654,8 @@ static void ec_stripe_key_init(struct bch_fs *c,
16471654
struct bkey_i *k,
16481655
unsigned nr_data,
16491656
unsigned nr_parity,
1650-
unsigned stripe_size)
1657+
unsigned stripe_size,
1658+
unsigned disk_label)
16511659
{
16521660
struct bkey_i_stripe *s = bkey_stripe_init(k);
16531661
unsigned u64s;
@@ -1658,7 +1666,7 @@ static void ec_stripe_key_init(struct bch_fs *c,
16581666
s->v.nr_redundant = nr_parity;
16591667
s->v.csum_granularity_bits = ilog2(c->opts.encoded_extent_max >> 9);
16601668
s->v.csum_type = BCH_CSUM_crc32c;
1661-
s->v.pad = 0;
1669+
s->v.disk_label = disk_label;
16621670

16631671
while ((u64s = stripe_val_u64s(&s->v)) > BKEY_VAL_U64s_MAX) {
16641672
BUG_ON(1 << s->v.csum_granularity_bits >=
@@ -1691,14 +1699,15 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
16911699
s->nr_parity = h->redundancy;
16921700

16931701
ec_stripe_key_init(c, &s->new_stripe.key,
1694-
s->nr_data, s->nr_parity, h->blocksize);
1702+
s->nr_data, s->nr_parity,
1703+
h->blocksize, h->disk_label);
16951704

16961705
h->s = s;
16971706
return 0;
16981707
}
16991708

17001709
static struct ec_stripe_head *
1701-
ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
1710+
ec_new_stripe_head_alloc(struct bch_fs *c, unsigned disk_label,
17021711
unsigned algo, unsigned redundancy,
17031712
enum bch_watermark watermark)
17041713
{
@@ -1711,13 +1720,13 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
17111720
mutex_init(&h->lock);
17121721
BUG_ON(!mutex_trylock(&h->lock));
17131722

1714-
h->target = target;
1723+
h->disk_label = disk_label;
17151724
h->algo = algo;
17161725
h->redundancy = redundancy;
17171726
h->watermark = watermark;
17181727

17191728
rcu_read_lock();
1720-
h->devs = target_rw_devs(c, BCH_DATA_user, target);
1729+
h->devs = target_rw_devs(c, BCH_DATA_user, disk_label ? group_to_target(disk_label - 1) : 0);
17211730

17221731
for_each_member_device_rcu(c, ca, &h->devs)
17231732
if (!ca->mi.durability)
@@ -1756,7 +1765,7 @@ void bch2_ec_stripe_head_put(struct bch_fs *c, struct ec_stripe_head *h)
17561765

17571766
static struct ec_stripe_head *
17581767
__bch2_ec_stripe_head_get(struct btree_trans *trans,
1759-
unsigned target,
1768+
unsigned disk_label,
17601769
unsigned algo,
17611770
unsigned redundancy,
17621771
enum bch_watermark watermark)
@@ -1778,7 +1787,7 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
17781787
}
17791788

17801789
list_for_each_entry(h, &c->ec_stripe_head_list, list)
1781-
if (h->target == target &&
1790+
if (h->disk_label == disk_label &&
17821791
h->algo == algo &&
17831792
h->redundancy == redundancy &&
17841793
h->watermark == watermark) {
@@ -1788,7 +1797,7 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
17881797
goto found;
17891798
}
17901799

1791-
h = ec_new_stripe_head_alloc(c, target, algo, redundancy, watermark);
1800+
h = ec_new_stripe_head_alloc(c, disk_label, algo, redundancy, watermark);
17921801
found:
17931802
if (!IS_ERR_OR_NULL(h) &&
17941803
h->nr_active_devs < h->redundancy + 2) {
@@ -1884,7 +1893,6 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
18841893
return 0;
18851894
}
18861895

1887-
/* XXX: doesn't obey target: */
18881896
static s64 get_existing_stripe(struct bch_fs *c,
18891897
struct ec_stripe_head *head)
18901898
{
@@ -1907,7 +1915,8 @@ static s64 get_existing_stripe(struct bch_fs *c,
19071915

19081916
m = genradix_ptr(&c->stripes, stripe_idx);
19091917

1910-
if (m->algorithm == head->algo &&
1918+
if (m->disk_label == head->disk_label &&
1919+
m->algorithm == head->algo &&
19111920
m->nr_redundant == head->redundancy &&
19121921
m->sectors == head->blocksize &&
19131922
m->blocks_nonempty < m->nr_blocks - m->nr_redundant &&
@@ -2052,9 +2061,19 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
20522061
struct bch_fs *c = trans->c;
20532062
struct ec_stripe_head *h;
20542063
bool waiting = false;
2064+
unsigned disk_label = 0;
2065+
struct target t = target_decode(target);
20552066
int ret;
20562067

2057-
h = __bch2_ec_stripe_head_get(trans, target, algo, redundancy, watermark);
2068+
if (t.type == TARGET_GROUP) {
2069+
if (t.group > U8_MAX) {
2070+
bch_err(c, "cannot create a stripe when disk_label > U8_MAX");
2071+
return NULL;
2072+
}
2073+
disk_label = t.group + 1; /* 0 == no label */
2074+
}
2075+
2076+
h = __bch2_ec_stripe_head_get(trans, disk_label, algo, redundancy, watermark);
20582077
if (IS_ERR_OR_NULL(h))
20592078
return h;
20602079

@@ -2259,8 +2278,8 @@ void bch2_new_stripes_to_text(struct printbuf *out, struct bch_fs *c)
22592278

22602279
mutex_lock(&c->ec_stripe_head_lock);
22612280
list_for_each_entry(h, &c->ec_stripe_head_list, list) {
2262-
prt_printf(out, "target %u algo %u redundancy %u %s:\n",
2263-
h->target, h->algo, h->redundancy,
2281+
prt_printf(out, "disk label %u algo %u redundancy %u %s:\n",
2282+
h->disk_label, h->algo, h->redundancy,
22642283
bch2_watermarks[h->watermark]);
22652284

22662285
if (h->s)

fs/bcachefs/ec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ struct ec_stripe_head {
188188
struct list_head list;
189189
struct mutex lock;
190190

191-
unsigned target;
191+
unsigned disk_label;
192192
unsigned algo;
193193
unsigned redundancy;
194194
enum bch_watermark watermark;

fs/bcachefs/ec_format.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@ struct bch_stripe {
1111

1212
__u8 csum_granularity_bits;
1313
__u8 csum_type;
14-
__u8 pad;
14+
15+
/*
16+
* XXX: targets should be 16 bits - fix this if we ever do a stripe_v2
17+
*
18+
* we can manage with this because this only needs to point to a
19+
* disk label, not a target:
20+
*/
21+
__u8 disk_label;
1522

1623
struct bch_extent_ptr ptrs[];
1724
} __packed __aligned(8);

fs/bcachefs/ec_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct stripe {
1616
u8 nr_blocks;
1717
u8 nr_redundant;
1818
u8 blocks_nonempty;
19+
u8 disk_label;
1920
};
2021

2122
struct gc_stripe {

0 commit comments

Comments
 (0)