Skip to content

Commit c1e8227

Browse files
committed
Merge tag 'bcachefs-2024-10-22' of https://github.com/koverstreet/bcachefs
Pull bcachefs fixes from Kent Overstreet: "Lots of hotfixes: - transaction restart injection has been shaking out a few things - fix a data corruption in the buffered write path on -ENOSPC, found by xfstests generic/299 - Some small show_options fixes - Repair mismatches in inode hash type, seed: different snapshot versions of an inode must have the same hash/type seed, used for directory entries and xattrs. We were checking the hash seed, but not the type, and a user contributed a filesystem where the hash type on one inode had somehow been flipped; these fixes allow his filesystem to repair. Additionally, the hash type flip made some directory entries invisible, which were then recreated by userspace; so the hash check code now checks for duplicate non dangling dirents, and renames one of them if necessary. - Don't use wait_event_interruptible() in recovery: this fixes some filesystems failing to mount with -ERESTARTSYS - Workaround for kvmalloc not supporting > INT_MAX allocations, causing an -ENOMEM when allocating the sorted array of journal keys: this allows a 75 TB filesystem to mount - Make sure bch_inode_unpacked.bi_snapshot is set in the old inode compat path: this alllows Marcin's filesystem (in use since before 6.7) to repair and mount" * tag 'bcachefs-2024-10-22' of https://github.com/koverstreet/bcachefs: (26 commits) bcachefs: Set bch_inode_unpacked.bi_snapshot in old inode path bcachefs: Mark more errors as AUTOFIX bcachefs: Workaround for kvmalloc() not supporting > INT_MAX allocations bcachefs: Don't use wait_event_interruptible() in recovery bcachefs: Fix __bch2_fsck_err() warning bcachefs: fsck: Improve hash_check_key() bcachefs: bch2_hash_set_or_get_in_snapshot() bcachefs: Repair mismatches in inode hash seed, type bcachefs: Add hash seed, type to inode_to_text() bcachefs: INODE_STR_HASH() for bch_inode_unpacked bcachefs: Run in-kernel offline fsck without ratelimit errors bcachefs: skip mount option handle for empty string. bcachefs: fix incorrect show_options results bcachefs: Fix data corruption on -ENOSPC in buffered write path bcachefs: bch2_folio_reservation_get_partial() is now better behaved bcachefs: fix disk reservation accounting in bch2_folio_reservation_get() bcachefS: ec: fix data type on stripe deletion bcachefs: Don't use commit_do() unnecessarily bcachefs: handle restarts in bch2_bucket_io_time_reset() bcachefs: fix restart handling in __bch2_resume_logged_op_finsert() ...
2 parents f009e94 + a069f01 commit c1e8227

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+475
-205
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,7 +1977,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
19771977
ca->mi.bucket_size,
19781978
GFP_KERNEL);
19791979

1980-
int ret = bch2_trans_do(c, NULL, NULL,
1980+
int ret = bch2_trans_commit_do(c, NULL, NULL,
19811981
BCH_WATERMARK_btree|
19821982
BCH_TRANS_COMMIT_no_enospc,
19831983
bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket)));
@@ -2137,14 +2137,15 @@ static void bch2_do_invalidates_work(struct work_struct *work)
21372137

21382138
struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped);
21392139
ret = bkey_err(k);
2140-
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
2141-
continue;
21422140
if (ret)
2143-
break;
2141+
goto restart_err;
21442142
if (!k.k)
21452143
break;
21462144

21472145
ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate);
2146+
restart_err:
2147+
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
2148+
continue;
21482149
if (ret)
21492150
break;
21502151

@@ -2350,24 +2351,19 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
23502351

23512352
/* Bucket IO clocks: */
23522353

2353-
int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
2354-
size_t bucket_nr, int rw)
2354+
static int __bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
2355+
size_t bucket_nr, int rw)
23552356
{
23562357
struct bch_fs *c = trans->c;
2357-
struct btree_iter iter;
2358-
struct bkey_i_alloc_v4 *a;
2359-
u64 now;
2360-
int ret = 0;
2361-
2362-
if (bch2_trans_relock(trans))
2363-
bch2_trans_begin(trans);
23642358

2365-
a = bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr));
2366-
ret = PTR_ERR_OR_ZERO(a);
2359+
struct btree_iter iter;
2360+
struct bkey_i_alloc_v4 *a =
2361+
bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr));
2362+
int ret = PTR_ERR_OR_ZERO(a);
23672363
if (ret)
23682364
return ret;
23692365

2370-
now = bch2_current_io_time(c, rw);
2366+
u64 now = bch2_current_io_time(c, rw);
23712367
if (a->v.io_time[rw] == now)
23722368
goto out;
23732369

@@ -2380,6 +2376,15 @@ int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
23802376
return ret;
23812377
}
23822378

2379+
int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
2380+
size_t bucket_nr, int rw)
2381+
{
2382+
if (bch2_trans_relock(trans))
2383+
bch2_trans_begin(trans);
2384+
2385+
return nested_lockrestart_do(trans, __bch2_bucket_io_time_reset(trans, dev, bucket_nr, rw));
2386+
}
2387+
23832388
/* Startup/shutdown (ro/rw): */
23842389

23852390
void bch2_recalc_capacity(struct bch_fs *c)

fs/bcachefs/alloc_foreground.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
684684
struct bch_dev_usage usage;
685685
struct open_bucket *ob;
686686

687-
bch2_trans_do(c, NULL, NULL, 0,
687+
bch2_trans_do(c,
688688
PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark,
689689
data_type, cl, false, &usage)));
690690
return ob;

fs/bcachefs/btree_gc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,12 +820,22 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
820820
* fix that here:
821821
*/
822822
alloc_data_type_set(&gc, gc.data_type);
823-
824823
if (gc.data_type != old_gc.data_type ||
825824
gc.dirty_sectors != old_gc.dirty_sectors) {
826825
ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc);
827826
if (ret)
828827
return ret;
828+
829+
/*
830+
* Ugly: alloc_key_to_dev_counters(..., BTREE_TRIGGER_gc) is not
831+
* safe w.r.t. transaction restarts, so fixup the gc_bucket so
832+
* we don't run it twice:
833+
*/
834+
percpu_down_read(&c->mark_lock);
835+
struct bucket *gc_m = gc_bucket(ca, iter->pos.offset);
836+
gc_m->data_type = gc.data_type;
837+
gc_m->dirty_sectors = gc.dirty_sectors;
838+
percpu_up_read(&c->mark_lock);
829839
}
830840

831841
if (fsck_err_on(new.data_type != gc.data_type,

fs/bcachefs/btree_io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,7 @@ static void btree_node_write_work(struct work_struct *work)
18711871

18721872
}
18731873
} else {
1874-
ret = bch2_trans_do(c, NULL, NULL, 0,
1874+
ret = bch2_trans_do(c,
18751875
bch2_btree_node_update_key_get_iter(trans, b, &wbio->key,
18761876
BCH_WATERMARK_interior_updates|
18771877
BCH_TRANS_COMMIT_journal_reclaim|

fs/bcachefs/btree_iter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,8 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
912912
_ret; \
913913
})
914914

915+
#define bch2_trans_do(_c, _do) bch2_trans_run(_c, lockrestart_do(trans, _do))
916+
915917
struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
916918
void bch2_trans_put(struct btree_trans *);
917919

fs/bcachefs/btree_update.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
668668
struct disk_reservation *disk_res, int flags,
669669
enum btree_iter_update_trigger_flags iter_flags)
670670
{
671-
return bch2_trans_do(c, disk_res, NULL, flags,
671+
return bch2_trans_commit_do(c, disk_res, NULL, flags,
672672
bch2_btree_insert_trans(trans, id, k, iter_flags));
673673
}
674674

@@ -865,7 +865,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
865865
memcpy(l->d, buf.buf, buf.pos);
866866
c->journal.early_journal_entries.nr += jset_u64s(u64s);
867867
} else {
868-
ret = bch2_trans_do(c, NULL, NULL,
868+
ret = bch2_trans_commit_do(c, NULL, NULL,
869869
BCH_TRANS_COMMIT_lazy_rw|commit_flags,
870870
__bch2_trans_log_msg(trans, &buf, u64s));
871871
}

fs/bcachefs/btree_update.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static inline int bch2_trans_commit(struct btree_trans *trans,
192192
nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\
193193
(_journal_seq), (_flags)))
194194

195-
#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \
195+
#define bch2_trans_commit_do(_c, _disk_res, _journal_seq, _flags, _do) \
196196
bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do))
197197

198198
#define trans_for_each_update(_trans, _i) \

fs/bcachefs/btree_update_interior.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,10 +2239,8 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
22392239
struct async_btree_rewrite *a =
22402240
container_of(work, struct async_btree_rewrite, work);
22412241
struct bch_fs *c = a->c;
2242-
int ret;
22432242

2244-
ret = bch2_trans_do(c, NULL, NULL, 0,
2245-
async_btree_node_rewrite_trans(trans, a));
2243+
int ret = bch2_trans_do(c, async_btree_node_rewrite_trans(trans, a));
22462244
bch_err_fn_ratelimited(c, ret);
22472245
bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
22482246
kfree(a);

fs/bcachefs/buckets.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,11 +1160,11 @@ int bch2_trans_mark_dev_sbs(struct bch_fs *c)
11601160
#define SECTORS_CACHE 1024
11611161

11621162
int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
1163-
u64 sectors, int flags)
1163+
u64 sectors, enum bch_reservation_flags flags)
11641164
{
11651165
struct bch_fs_pcpu *pcpu;
11661166
u64 old, get;
1167-
s64 sectors_available;
1167+
u64 sectors_available;
11681168
int ret;
11691169

11701170
percpu_down_read(&c->mark_lock);
@@ -1202,6 +1202,9 @@ int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
12021202
percpu_u64_set(&c->pcpu->sectors_available, 0);
12031203
sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free);
12041204

1205+
if (sectors_available && (flags & BCH_DISK_RESERVATION_PARTIAL))
1206+
sectors = min(sectors, sectors_available);
1207+
12051208
if (sectors <= sectors_available ||
12061209
(flags & BCH_DISK_RESERVATION_NOFAIL)) {
12071210
atomic64_set(&c->sectors_available,

fs/bcachefs/buckets.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,16 @@ static inline void bch2_disk_reservation_put(struct bch_fs *c,
344344
}
345345
}
346346

347-
#define BCH_DISK_RESERVATION_NOFAIL (1 << 0)
347+
enum bch_reservation_flags {
348+
BCH_DISK_RESERVATION_NOFAIL = 1 << 0,
349+
BCH_DISK_RESERVATION_PARTIAL = 1 << 1,
350+
};
348351

349-
int __bch2_disk_reservation_add(struct bch_fs *,
350-
struct disk_reservation *,
351-
u64, int);
352+
int __bch2_disk_reservation_add(struct bch_fs *, struct disk_reservation *,
353+
u64, enum bch_reservation_flags);
352354

353355
static inline int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
354-
u64 sectors, int flags)
356+
u64 sectors, enum bch_reservation_flags flags)
355357
{
356358
#ifdef __KERNEL__
357359
u64 old, new;

0 commit comments

Comments
 (0)