Skip to content

Commit 0f52fd4

Browse files
committed
Merge tag 'bcachefs-2025-03-06' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: - Fix a compatibility issue: we shouldn't be setting incompat feature bits unless explicitly requested - Fix another bug where the journal alloc/resize path could spuriously fail with -BCH_ERR_open_buckets_empty - Copygc shouldn't run on read-only devices: fragmentation isn't an issue if we're not currently writing to a given device, and it may not have anywhere to move the data to * tag 'bcachefs-2025-03-06' of git://evilpiepirate.org/bcachefs: bcachefs: copygc now skips non-rw devices bcachefs: Fix bch2_dev_journal_alloc() spuriously failing bcachefs: Don't set BCH_FEATURE_incompat_version_field unless requested
2 parents f315296 + 8ba73f5 commit 0f52fd4

File tree

4 files changed

+64
-55
lines changed

4 files changed

+64
-55
lines changed

fs/bcachefs/journal.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,8 +1021,8 @@ struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j,
10211021

10221022
/* allocate journal on a device: */
10231023

1024-
static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
1025-
bool new_fs, struct closure *cl)
1024+
static int bch2_set_nr_journal_buckets_iter(struct bch_dev *ca, unsigned nr,
1025+
bool new_fs, struct closure *cl)
10261026
{
10271027
struct bch_fs *c = ca->fs;
10281028
struct journal_device *ja = &ca->journal;
@@ -1150,26 +1150,20 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
11501150
return ret;
11511151
}
11521152

1153-
/*
1154-
* Allocate more journal space at runtime - not currently making use if it, but
1155-
* the code works:
1156-
*/
1157-
int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
1158-
unsigned nr)
1153+
static int bch2_set_nr_journal_buckets_loop(struct bch_fs *c, struct bch_dev *ca,
1154+
unsigned nr, bool new_fs)
11591155
{
11601156
struct journal_device *ja = &ca->journal;
1161-
struct closure cl;
11621157
int ret = 0;
11631158

1159+
struct closure cl;
11641160
closure_init_stack(&cl);
11651161

1166-
down_write(&c->state_lock);
1167-
11681162
/* don't handle reducing nr of buckets yet: */
11691163
if (nr < ja->nr)
1170-
goto unlock;
1164+
return 0;
11711165

1172-
while (ja->nr < nr) {
1166+
while (!ret && ja->nr < nr) {
11731167
struct disk_reservation disk_res = { 0, 0, 0 };
11741168

11751169
/*
@@ -1182,27 +1176,38 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
11821176
* filesystem-wide allocation will succeed, this is a device
11831177
* specific allocation - we can hang here:
11841178
*/
1179+
if (!new_fs) {
1180+
ret = bch2_disk_reservation_get(c, &disk_res,
1181+
bucket_to_sector(ca, nr - ja->nr), 1, 0);
1182+
if (ret)
1183+
break;
1184+
}
11851185

1186-
ret = bch2_disk_reservation_get(c, &disk_res,
1187-
bucket_to_sector(ca, nr - ja->nr), 1, 0);
1188-
if (ret)
1189-
break;
1186+
ret = bch2_set_nr_journal_buckets_iter(ca, nr, new_fs, &cl);
11901187

1191-
ret = __bch2_set_nr_journal_buckets(ca, nr, false, &cl);
1188+
if (ret == -BCH_ERR_bucket_alloc_blocked ||
1189+
ret == -BCH_ERR_open_buckets_empty)
1190+
ret = 0; /* wait and retry */
11921191

11931192
bch2_disk_reservation_put(c, &disk_res);
1194-
11951193
closure_sync(&cl);
1196-
1197-
if (ret &&
1198-
ret != -BCH_ERR_bucket_alloc_blocked &&
1199-
ret != -BCH_ERR_open_buckets_empty)
1200-
break;
12011194
}
12021195

1203-
bch_err_fn(c, ret);
1204-
unlock:
1196+
return ret;
1197+
}
1198+
1199+
/*
1200+
* Allocate more journal space at runtime - not currently making use if it, but
1201+
* the code works:
1202+
*/
1203+
int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
1204+
unsigned nr)
1205+
{
1206+
down_write(&c->state_lock);
1207+
int ret = bch2_set_nr_journal_buckets_loop(c, ca, nr, false);
12051208
up_write(&c->state_lock);
1209+
1210+
bch_err_fn(c, ret);
12061211
return ret;
12071212
}
12081213

@@ -1228,7 +1233,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
12281233
min(1 << 13,
12291234
(1 << 24) / ca->mi.bucket_size));
12301235

1231-
ret = __bch2_set_nr_journal_buckets(ca, nr, new_fs, NULL);
1236+
ret = bch2_set_nr_journal_buckets_loop(ca->fs, ca, nr, new_fs);
12321237
err:
12331238
bch_err_fn(ca, ret);
12341239
return ret;

fs/bcachefs/movinggc.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,34 +74,33 @@ static int bch2_bucket_is_movable(struct btree_trans *trans,
7474
struct move_bucket *b, u64 time)
7575
{
7676
struct bch_fs *c = trans->c;
77-
struct btree_iter iter;
78-
struct bkey_s_c k;
79-
struct bch_alloc_v4 _a;
80-
const struct bch_alloc_v4 *a;
81-
int ret;
8277

83-
if (bch2_bucket_is_open(trans->c,
84-
b->k.bucket.inode,
85-
b->k.bucket.offset))
78+
if (bch2_bucket_is_open(c, b->k.bucket.inode, b->k.bucket.offset))
8679
return 0;
8780

88-
k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc,
89-
b->k.bucket, BTREE_ITER_cached);
90-
ret = bkey_err(k);
81+
struct btree_iter iter;
82+
struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc,
83+
b->k.bucket, BTREE_ITER_cached);
84+
int ret = bkey_err(k);
9185
if (ret)
9286
return ret;
9387

9488
struct bch_dev *ca = bch2_dev_tryget(c, k.k->p.inode);
9589
if (!ca)
9690
goto out;
9791

98-
a = bch2_alloc_to_v4(k, &_a);
92+
if (ca->mi.state != BCH_MEMBER_STATE_rw ||
93+
!bch2_dev_is_online(ca))
94+
goto out_put;
95+
96+
struct bch_alloc_v4 _a;
97+
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
9998
b->k.gen = a->gen;
10099
b->sectors = bch2_bucket_sectors_dirty(*a);
101100
u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca);
102101

103102
ret = lru_idx && lru_idx <= time;
104-
103+
out_put:
105104
bch2_dev_put(ca);
106105
out:
107106
bch2_trans_iter_exit(trans, &iter);

fs/bcachefs/super-io.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,20 @@ enum bcachefs_metadata_version bch2_latest_compatible_version(enum bcachefs_meta
6969
return v;
7070
}
7171

72-
void bch2_set_version_incompat(struct bch_fs *c, enum bcachefs_metadata_version version)
72+
bool bch2_set_version_incompat(struct bch_fs *c, enum bcachefs_metadata_version version)
7373
{
74-
mutex_lock(&c->sb_lock);
75-
SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb,
76-
max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version));
77-
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_FEATURE_incompat_version_field);
78-
bch2_write_super(c);
79-
mutex_unlock(&c->sb_lock);
74+
bool ret = (c->sb.features & BIT_ULL(BCH_FEATURE_incompat_version_field)) &&
75+
version <= c->sb.version_incompat_allowed;
76+
77+
if (ret) {
78+
mutex_lock(&c->sb_lock);
79+
SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb,
80+
max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version));
81+
bch2_write_super(c);
82+
mutex_unlock(&c->sb_lock);
83+
}
84+
85+
return ret;
8086
}
8187

8288
const char * const bch2_sb_fields[] = {
@@ -1219,9 +1225,11 @@ void bch2_sb_upgrade(struct bch_fs *c, unsigned new_version, bool incompat)
12191225
c->disk_sb.sb->version = cpu_to_le16(new_version);
12201226
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL);
12211227

1222-
if (incompat)
1228+
if (incompat) {
12231229
SET_BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb,
12241230
max(BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb), new_version));
1231+
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_FEATURE_incompat_version_field);
1232+
}
12251233
}
12261234

12271235
static int bch2_sb_ext_validate(struct bch_sb *sb, struct bch_sb_field *f,

fs/bcachefs/super-io.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,14 @@ static inline bool bch2_version_compatible(u16 version)
2121
void bch2_version_to_text(struct printbuf *, enum bcachefs_metadata_version);
2222
enum bcachefs_metadata_version bch2_latest_compatible_version(enum bcachefs_metadata_version);
2323

24-
void bch2_set_version_incompat(struct bch_fs *, enum bcachefs_metadata_version);
24+
bool bch2_set_version_incompat(struct bch_fs *, enum bcachefs_metadata_version);
2525

2626
static inline bool bch2_request_incompat_feature(struct bch_fs *c,
2727
enum bcachefs_metadata_version version)
2828
{
29-
if (unlikely(version > c->sb.version_incompat)) {
30-
if (version > c->sb.version_incompat_allowed)
31-
return false;
32-
bch2_set_version_incompat(c, version);
33-
}
34-
return true;
29+
return likely(version <= c->sb.version_incompat)
30+
? true
31+
: bch2_set_version_incompat(c, version);
3532
}
3633

3734
static inline size_t bch2_sb_field_bytes(struct bch_sb_field *f)

0 commit comments

Comments
 (0)