Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bcachefs-2024-08-16' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent OverstreetL

- New on disk format version, bcachefs_metadata_version_disk_accounting_inum

This adds one more disk accounting counter, which counts disk usage
and number of extents per inode number. This lets us track
fragmentation, for implementing defragmentation later, and it also
counts disk usage per inode in all snapshots, which will be a useful
thing to expose to users.

- One performance issue we've observed is threads spinning when they
should be waiting for dirty keys in the key cache to be flushed by
journal reclaim, so we now have hysteresis for the waiting thread, as
well as improving the tracepoint and a new time_stat, for tracking
time blocked waiting on key cache flushing.

... and various assorted smaller fixes.

* tag 'bcachefs-2024-08-16' of git://evilpiepirate.org/bcachefs:
bcachefs: Fix locking in __bch2_trans_mark_dev_sb()
bcachefs: fix incorrect i_state usage
bcachefs: avoid overflowing LRU_TIME_BITS for cached data lru
bcachefs: Fix forgetting to pass trans to fsck_err()
bcachefs: Increase size of cuckoo hash table on too many rehashes
bcachefs: bcachefs_metadata_version_disk_accounting_inum
bcachefs: Kill __bch2_accounting_mem_mod()
bcachefs: Make bkey_fsck_err() a wrapper around fsck_err()
bcachefs: Fix warning in __bch2_fsck_err() for trans not passed in
bcachefs: Add a time_stat for blocked on key cache flush
bcachefs: Improve trans_blocked_journal_reclaim tracepoint
bcachefs: Add hysteresis to waiting on btree key cache flush
lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
bcachefs: Convert for_each_btree_node() to lockrestart_do()
bcachefs: Add missing downgrade table entry
bcachefs: disk accounting: ignore unknown types
bcachefs: bch2_accounting_invalid() fixup
bcachefs: Fix bch2_trigger_alloc when upgrading from old versions
bcachefs: delete faulty fastpath in bch2_btree_path_traverse_cached()

+658 -680
+42 -35
fs/bcachefs/alloc_background.c
··· 196 196 return DIV_ROUND_UP(bytes, sizeof(u64)); 197 197 } 198 198 199 - int bch2_alloc_v1_invalid(struct bch_fs *c, struct bkey_s_c k, 200 - enum bch_validate_flags flags, 201 - struct printbuf *err) 199 + int bch2_alloc_v1_validate(struct bch_fs *c, struct bkey_s_c k, 200 + enum bch_validate_flags flags) 202 201 { 203 202 struct bkey_s_c_alloc a = bkey_s_c_to_alloc(k); 204 203 int ret = 0; 205 204 206 205 /* allow for unknown fields */ 207 - bkey_fsck_err_on(bkey_val_u64s(a.k) < bch_alloc_v1_val_u64s(a.v), c, err, 208 - alloc_v1_val_size_bad, 206 + bkey_fsck_err_on(bkey_val_u64s(a.k) < bch_alloc_v1_val_u64s(a.v), 207 + c, alloc_v1_val_size_bad, 209 208 "incorrect value size (%zu < %u)", 210 209 bkey_val_u64s(a.k), bch_alloc_v1_val_u64s(a.v)); 211 210 fsck_err: 212 211 return ret; 213 212 } 214 213 215 - int bch2_alloc_v2_invalid(struct bch_fs *c, struct bkey_s_c k, 216 - enum bch_validate_flags flags, 217 - struct printbuf *err) 214 + int bch2_alloc_v2_validate(struct bch_fs *c, struct bkey_s_c k, 215 + enum bch_validate_flags flags) 218 216 { 219 217 struct bkey_alloc_unpacked u; 220 218 int ret = 0; 221 219 222 - bkey_fsck_err_on(bch2_alloc_unpack_v2(&u, k), c, err, 223 - alloc_v2_unpack_error, 220 + bkey_fsck_err_on(bch2_alloc_unpack_v2(&u, k), 221 + c, alloc_v2_unpack_error, 224 222 "unpack error"); 225 223 fsck_err: 226 224 return ret; 227 225 } 228 226 229 - int bch2_alloc_v3_invalid(struct bch_fs *c, struct bkey_s_c k, 230 - enum bch_validate_flags flags, 231 - struct printbuf *err) 227 + int bch2_alloc_v3_validate(struct bch_fs *c, struct bkey_s_c k, 228 + enum bch_validate_flags flags) 232 229 { 233 230 struct bkey_alloc_unpacked u; 234 231 int ret = 0; 235 232 236 - bkey_fsck_err_on(bch2_alloc_unpack_v3(&u, k), c, err, 237 - alloc_v2_unpack_error, 233 + bkey_fsck_err_on(bch2_alloc_unpack_v3(&u, k), 234 + c, alloc_v2_unpack_error, 238 235 "unpack error"); 239 236 fsck_err: 240 237 return ret; 241 238 } 242 239 243 - int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k, 244 - enum bch_validate_flags flags, struct printbuf *err) 240 + int bch2_alloc_v4_validate(struct bch_fs *c, struct bkey_s_c k, 241 + enum bch_validate_flags flags) 245 242 { 246 243 struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k); 247 244 int ret = 0; 248 245 249 - bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k), c, err, 250 - alloc_v4_val_size_bad, 246 + bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k), 247 + c, alloc_v4_val_size_bad, 251 248 "bad val size (%u > %zu)", 252 249 alloc_v4_u64s_noerror(a.v), bkey_val_u64s(k.k)); 253 250 254 251 bkey_fsck_err_on(!BCH_ALLOC_V4_BACKPOINTERS_START(a.v) && 255 - BCH_ALLOC_V4_NR_BACKPOINTERS(a.v), c, err, 256 - alloc_v4_backpointers_start_bad, 252 + BCH_ALLOC_V4_NR_BACKPOINTERS(a.v), 253 + c, alloc_v4_backpointers_start_bad, 257 254 "invalid backpointers_start"); 258 255 259 - bkey_fsck_err_on(alloc_data_type(*a.v, a.v->data_type) != a.v->data_type, c, err, 260 - alloc_key_data_type_bad, 256 + bkey_fsck_err_on(alloc_data_type(*a.v, a.v->data_type) != a.v->data_type, 257 + c, alloc_key_data_type_bad, 261 258 "invalid data type (got %u should be %u)", 262 259 a.v->data_type, alloc_data_type(*a.v, a.v->data_type)); 263 260 264 261 for (unsigned i = 0; i < 2; i++) 265 262 bkey_fsck_err_on(a.v->io_time[i] > LRU_TIME_MAX, 266 - c, err, 267 - alloc_key_io_time_bad, 263 + c, alloc_key_io_time_bad, 268 264 "invalid io_time[%s]: %llu, max %llu", 269 265 i == READ ? "read" : "write", 270 266 a.v->io_time[i], LRU_TIME_MAX); ··· 278 282 a.v->dirty_sectors || 279 283 a.v->cached_sectors || 280 284 a.v->stripe, 281 - c, err, alloc_key_empty_but_have_data, 285 + c, alloc_key_empty_but_have_data, 282 286 "empty data type free but have data %u.%u.%u %u", 283 287 stripe_sectors, 284 288 a.v->dirty_sectors, ··· 292 296 case BCH_DATA_parity: 293 297 bkey_fsck_err_on(!a.v->dirty_sectors && 294 298 !stripe_sectors, 295 - c, err, alloc_key_dirty_sectors_0, 299 + c, alloc_key_dirty_sectors_0, 296 300 "data_type %s but dirty_sectors==0", 297 301 bch2_data_type_str(a.v->data_type)); 298 302 break; ··· 301 305 a.v->dirty_sectors || 302 306 stripe_sectors || 303 307 a.v->stripe, 304 - c, err, alloc_key_cached_inconsistency, 308 + c, alloc_key_cached_inconsistency, 305 309 "data type inconsistency"); 306 310 307 311 bkey_fsck_err_on(!a.v->io_time[READ] && 308 312 c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_to_lru_refs, 309 - c, err, alloc_key_cached_but_read_time_zero, 313 + c, alloc_key_cached_but_read_time_zero, 310 314 "cached bucket with read_time == 0"); 311 315 break; 312 316 case BCH_DATA_stripe: ··· 509 513 : 0; 510 514 } 511 515 512 - int bch2_bucket_gens_invalid(struct bch_fs *c, struct bkey_s_c k, 513 - enum bch_validate_flags flags, 514 - struct printbuf *err) 516 + int bch2_bucket_gens_validate(struct bch_fs *c, struct bkey_s_c k, 517 + enum bch_validate_flags flags) 515 518 { 516 519 int ret = 0; 517 520 518 - bkey_fsck_err_on(bkey_val_bytes(k.k) != sizeof(struct bch_bucket_gens), c, err, 519 - bucket_gens_val_size_bad, 521 + bkey_fsck_err_on(bkey_val_bytes(k.k) != sizeof(struct bch_bucket_gens), 522 + c, bucket_gens_val_size_bad, 520 523 "bad val size (%zu != %zu)", 521 524 bkey_val_bytes(k.k), sizeof(struct bch_bucket_gens)); 522 525 fsck_err: ··· 824 829 825 830 struct bch_alloc_v4 old_a_convert; 826 831 const struct bch_alloc_v4 *old_a = bch2_alloc_to_v4(old, &old_a_convert); 827 - struct bch_alloc_v4 *new_a = bkey_s_to_alloc_v4(new).v; 832 + 833 + struct bch_alloc_v4 *new_a; 834 + if (likely(new.k->type == KEY_TYPE_alloc_v4)) { 835 + new_a = bkey_s_to_alloc_v4(new).v; 836 + } else { 837 + BUG_ON(!(flags & BTREE_TRIGGER_gc)); 838 + 839 + struct bkey_i_alloc_v4 *new_ka = bch2_alloc_to_v4_mut_inlined(trans, new.s_c); 840 + ret = PTR_ERR_OR_ZERO(new_ka); 841 + if (unlikely(ret)) 842 + goto err; 843 + new_a = &new_ka->v; 844 + } 828 845 829 846 if (flags & BTREE_TRIGGER_transactional) { 830 847 alloc_data_type_set(new_a, new_a->data_type);
+14 -16
fs/bcachefs/alloc_background.h
··· 150 150 151 151 static inline u64 alloc_lru_idx_read(struct bch_alloc_v4 a) 152 152 { 153 - return a.data_type == BCH_DATA_cached ? a.io_time[READ] : 0; 153 + return a.data_type == BCH_DATA_cached 154 + ? a.io_time[READ] & LRU_TIME_MAX 155 + : 0; 154 156 } 155 157 156 158 #define DATA_TYPES_MOVABLE \ ··· 242 240 243 241 int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int); 244 242 245 - int bch2_alloc_v1_invalid(struct bch_fs *, struct bkey_s_c, 246 - enum bch_validate_flags, struct printbuf *); 247 - int bch2_alloc_v2_invalid(struct bch_fs *, struct bkey_s_c, 248 - enum bch_validate_flags, struct printbuf *); 249 - int bch2_alloc_v3_invalid(struct bch_fs *, struct bkey_s_c, 250 - enum bch_validate_flags, struct printbuf *); 251 - int bch2_alloc_v4_invalid(struct bch_fs *, struct bkey_s_c, 252 - enum bch_validate_flags, struct printbuf *); 243 + int bch2_alloc_v1_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 244 + int bch2_alloc_v2_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 245 + int bch2_alloc_v3_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 246 + int bch2_alloc_v4_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 253 247 void bch2_alloc_v4_swab(struct bkey_s); 254 248 void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 255 249 256 250 #define bch2_bkey_ops_alloc ((struct bkey_ops) { \ 257 - .key_invalid = bch2_alloc_v1_invalid, \ 251 + .key_validate = bch2_alloc_v1_validate, \ 258 252 .val_to_text = bch2_alloc_to_text, \ 259 253 .trigger = bch2_trigger_alloc, \ 260 254 .min_val_size = 8, \ 261 255 }) 262 256 263 257 #define bch2_bkey_ops_alloc_v2 ((struct bkey_ops) { \ 264 - .key_invalid = bch2_alloc_v2_invalid, \ 258 + .key_validate = bch2_alloc_v2_validate, \ 265 259 .val_to_text = bch2_alloc_to_text, \ 266 260 .trigger = bch2_trigger_alloc, \ 267 261 .min_val_size = 8, \ 268 262 }) 269 263 270 264 #define bch2_bkey_ops_alloc_v3 ((struct bkey_ops) { \ 271 - .key_invalid = bch2_alloc_v3_invalid, \ 265 + .key_validate = bch2_alloc_v3_validate, \ 272 266 .val_to_text = bch2_alloc_to_text, \ 273 267 .trigger = bch2_trigger_alloc, \ 274 268 .min_val_size = 16, \ 275 269 }) 276 270 277 271 #define bch2_bkey_ops_alloc_v4 ((struct bkey_ops) { \ 278 - .key_invalid = bch2_alloc_v4_invalid, \ 272 + .key_validate = bch2_alloc_v4_validate, \ 279 273 .val_to_text = bch2_alloc_to_text, \ 280 274 .swab = bch2_alloc_v4_swab, \ 281 275 .trigger = bch2_trigger_alloc, \ 282 276 .min_val_size = 48, \ 283 277 }) 284 278 285 - int bch2_bucket_gens_invalid(struct bch_fs *, struct bkey_s_c, 286 - enum bch_validate_flags, struct printbuf *); 279 + int bch2_bucket_gens_validate(struct bch_fs *, struct bkey_s_c, 280 + enum bch_validate_flags); 287 281 void bch2_bucket_gens_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 288 282 289 283 #define bch2_bkey_ops_bucket_gens ((struct bkey_ops) { \ 290 - .key_invalid = bch2_bucket_gens_invalid, \ 284 + .key_validate = bch2_bucket_gens_validate, \ 291 285 .val_to_text = bch2_bucket_gens_to_text, \ 292 286 }) 293 287
+8 -15
fs/bcachefs/backpointers.c
··· 47 47 return false; 48 48 } 49 49 50 - int bch2_backpointer_invalid(struct bch_fs *c, struct bkey_s_c k, 51 - enum bch_validate_flags flags, 52 - struct printbuf *err) 50 + int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k, 51 + enum bch_validate_flags flags) 53 52 { 54 53 struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k); 55 54 ··· 67 68 68 69 bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size || 69 70 !bpos_eq(bp.k->p, bp_pos), 70 - c, err, 71 - backpointer_bucket_offset_wrong, 71 + c, backpointer_bucket_offset_wrong, 72 72 "backpointer bucket_offset wrong"); 73 73 fsck_err: 74 74 return ret; ··· 761 763 btree < BTREE_ID_NR && !ret; 762 764 btree++) { 763 765 unsigned depth = (BIT_ULL(btree) & btree_leaf_mask) ? 0 : 1; 764 - struct btree_iter iter; 765 - struct btree *b; 766 766 767 767 if (!(BIT_ULL(btree) & btree_leaf_mask) && 768 768 !(BIT_ULL(btree) & btree_interior_mask)) 769 769 continue; 770 770 771 - bch2_trans_begin(trans); 772 - 773 - __for_each_btree_node(trans, iter, btree, 771 + ret = __for_each_btree_node(trans, iter, btree, 774 772 btree == start.btree ? start.pos : POS_MIN, 775 - 0, depth, BTREE_ITER_prefetch, b, ret) { 773 + 0, depth, BTREE_ITER_prefetch, b, ({ 776 774 mem_may_pin -= btree_buf_bytes(b); 777 775 if (mem_may_pin <= 0) { 778 776 c->btree_cache.pinned_nodes_end = *end = 779 777 BBPOS(btree, b->key.k.p); 780 - bch2_trans_iter_exit(trans, &iter); 781 - return 0; 778 + break; 782 779 } 783 - } 784 - bch2_trans_iter_exit(trans, &iter); 780 + 0; 781 + })); 785 782 } 786 783 787 784 return ret;
+2 -3
fs/bcachefs/backpointers.h
··· 18 18 ((x & 0xff00000000ULL) >> 32)); 19 19 } 20 20 21 - int bch2_backpointer_invalid(struct bch_fs *, struct bkey_s_c k, 22 - enum bch_validate_flags, struct printbuf *); 21 + int bch2_backpointer_validate(struct bch_fs *, struct bkey_s_c k, enum bch_validate_flags); 23 22 void bch2_backpointer_to_text(struct printbuf *, const struct bch_backpointer *); 24 23 void bch2_backpointer_k_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 25 24 void bch2_backpointer_swab(struct bkey_s); 26 25 27 26 #define bch2_bkey_ops_backpointer ((struct bkey_ops) { \ 28 - .key_invalid = bch2_backpointer_invalid, \ 27 + .key_validate = bch2_backpointer_validate, \ 29 28 .val_to_text = bch2_backpointer_k_to_text, \ 30 29 .swab = bch2_backpointer_swab, \ 31 30 .min_val_size = 32, \
+1
fs/bcachefs/bcachefs.h
··· 447 447 x(blocked_journal_low_on_space) \ 448 448 x(blocked_journal_low_on_pin) \ 449 449 x(blocked_journal_max_in_flight) \ 450 + x(blocked_key_cache_flush) \ 450 451 x(blocked_allocate) \ 451 452 x(blocked_allocate_open_bucket) \ 452 453 x(blocked_write_buffer_full) \
+2 -1
fs/bcachefs/bcachefs_format.h
··· 676 676 x(mi_btree_bitmap, BCH_VERSION(1, 7)) \ 677 677 x(bucket_stripe_sectors, BCH_VERSION(1, 8)) \ 678 678 x(disk_accounting_v2, BCH_VERSION(1, 9)) \ 679 - x(disk_accounting_v3, BCH_VERSION(1, 10)) 679 + x(disk_accounting_v3, BCH_VERSION(1, 10)) \ 680 + x(disk_accounting_inum, BCH_VERSION(1, 11)) 680 681 681 682 enum bcachefs_metadata_version { 682 683 bcachefs_metadata_version_min = 9,
+4 -3
fs/bcachefs/bkey.h
··· 10 10 #include "vstructs.h" 11 11 12 12 enum bch_validate_flags { 13 - BCH_VALIDATE_write = (1U << 0), 14 - BCH_VALIDATE_commit = (1U << 1), 15 - BCH_VALIDATE_journal = (1U << 2), 13 + BCH_VALIDATE_write = BIT(0), 14 + BCH_VALIDATE_commit = BIT(1), 15 + BCH_VALIDATE_journal = BIT(2), 16 + BCH_VALIDATE_silent = BIT(3), 16 17 }; 17 18 18 19 #if 0
+53 -56
fs/bcachefs/bkey_methods.c
··· 27 27 NULL 28 28 }; 29 29 30 - static int deleted_key_invalid(struct bch_fs *c, struct bkey_s_c k, 31 - enum bch_validate_flags flags, struct printbuf *err) 30 + static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k, 31 + enum bch_validate_flags flags) 32 32 { 33 33 return 0; 34 34 } 35 35 36 36 #define bch2_bkey_ops_deleted ((struct bkey_ops) { \ 37 - .key_invalid = deleted_key_invalid, \ 37 + .key_validate = deleted_key_validate, \ 38 38 }) 39 39 40 40 #define bch2_bkey_ops_whiteout ((struct bkey_ops) { \ 41 - .key_invalid = deleted_key_invalid, \ 41 + .key_validate = deleted_key_validate, \ 42 42 }) 43 43 44 - static int empty_val_key_invalid(struct bch_fs *c, struct bkey_s_c k, 45 - enum bch_validate_flags flags, struct printbuf *err) 44 + static int empty_val_key_validate(struct bch_fs *c, struct bkey_s_c k, 45 + enum bch_validate_flags flags) 46 46 { 47 47 int ret = 0; 48 48 49 - bkey_fsck_err_on(bkey_val_bytes(k.k), c, err, 50 - bkey_val_size_nonzero, 49 + bkey_fsck_err_on(bkey_val_bytes(k.k), 50 + c, bkey_val_size_nonzero, 51 51 "incorrect value size (%zu != 0)", 52 52 bkey_val_bytes(k.k)); 53 53 fsck_err: ··· 55 55 } 56 56 57 57 #define bch2_bkey_ops_error ((struct bkey_ops) { \ 58 - .key_invalid = empty_val_key_invalid, \ 58 + .key_validate = empty_val_key_validate, \ 59 59 }) 60 60 61 - static int key_type_cookie_invalid(struct bch_fs *c, struct bkey_s_c k, 62 - enum bch_validate_flags flags, struct printbuf *err) 61 + static int key_type_cookie_validate(struct bch_fs *c, struct bkey_s_c k, 62 + enum bch_validate_flags flags) 63 63 { 64 64 return 0; 65 65 } ··· 73 73 } 74 74 75 75 #define bch2_bkey_ops_cookie ((struct bkey_ops) { \ 76 - .key_invalid = key_type_cookie_invalid, \ 76 + .key_validate = key_type_cookie_validate, \ 77 77 .val_to_text = key_type_cookie_to_text, \ 78 78 .min_val_size = 8, \ 79 79 }) 80 80 81 81 #define bch2_bkey_ops_hash_whiteout ((struct bkey_ops) {\ 82 - .key_invalid = empty_val_key_invalid, \ 82 + .key_validate = empty_val_key_validate, \ 83 83 }) 84 84 85 - static int key_type_inline_data_invalid(struct bch_fs *c, struct bkey_s_c k, 86 - enum bch_validate_flags flags, struct printbuf *err) 85 + static int key_type_inline_data_validate(struct bch_fs *c, struct bkey_s_c k, 86 + enum bch_validate_flags flags) 87 87 { 88 88 return 0; 89 89 } ··· 98 98 datalen, min(datalen, 32U), d.v->data); 99 99 } 100 100 101 - #define bch2_bkey_ops_inline_data ((struct bkey_ops) { \ 102 - .key_invalid = key_type_inline_data_invalid, \ 103 - .val_to_text = key_type_inline_data_to_text, \ 101 + #define bch2_bkey_ops_inline_data ((struct bkey_ops) { \ 102 + .key_validate = key_type_inline_data_validate, \ 103 + .val_to_text = key_type_inline_data_to_text, \ 104 104 }) 105 105 106 106 static bool key_type_set_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r) ··· 110 110 } 111 111 112 112 #define bch2_bkey_ops_set ((struct bkey_ops) { \ 113 - .key_invalid = empty_val_key_invalid, \ 113 + .key_validate = empty_val_key_validate, \ 114 114 .key_merge = key_type_set_merge, \ 115 115 }) 116 116 ··· 123 123 const struct bkey_ops bch2_bkey_null_ops = { 124 124 }; 125 125 126 - int bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k, 127 - enum bch_validate_flags flags, 128 - struct printbuf *err) 126 + int bch2_bkey_val_validate(struct bch_fs *c, struct bkey_s_c k, 127 + enum bch_validate_flags flags) 129 128 { 130 129 if (test_bit(BCH_FS_no_invalid_checks, &c->flags)) 131 130 return 0; ··· 132 133 const struct bkey_ops *ops = bch2_bkey_type_ops(k.k->type); 133 134 int ret = 0; 134 135 135 - bkey_fsck_err_on(bkey_val_bytes(k.k) < ops->min_val_size, c, err, 136 - bkey_val_size_too_small, 136 + bkey_fsck_err_on(bkey_val_bytes(k.k) < ops->min_val_size, 137 + c, bkey_val_size_too_small, 137 138 "bad val size (%zu < %u)", 138 139 bkey_val_bytes(k.k), ops->min_val_size); 139 140 140 - if (!ops->key_invalid) 141 + if (!ops->key_validate) 141 142 return 0; 142 143 143 - ret = ops->key_invalid(c, k, flags, err); 144 + ret = ops->key_validate(c, k, flags); 144 145 fsck_err: 145 146 return ret; 146 147 } ··· 160 161 return type == BKEY_TYPE_btree ? "internal btree node" : bch2_btree_id_str(type - 1); 161 162 } 162 163 163 - int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k, 164 - enum btree_node_type type, 165 - enum bch_validate_flags flags, 166 - struct printbuf *err) 164 + int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k, 165 + enum btree_node_type type, 166 + enum bch_validate_flags flags) 167 167 { 168 168 if (test_bit(BCH_FS_no_invalid_checks, &c->flags)) 169 169 return 0; 170 170 171 171 int ret = 0; 172 172 173 - bkey_fsck_err_on(k.k->u64s < BKEY_U64s, c, err, 174 - bkey_u64s_too_small, 173 + bkey_fsck_err_on(k.k->u64s < BKEY_U64s, 174 + c, bkey_u64s_too_small, 175 175 "u64s too small (%u < %zu)", k.k->u64s, BKEY_U64s); 176 176 177 177 if (type >= BKEY_TYPE_NR) ··· 178 180 179 181 bkey_fsck_err_on(k.k->type < KEY_TYPE_MAX && 180 182 (type == BKEY_TYPE_btree || (flags & BCH_VALIDATE_commit)) && 181 - !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)), c, err, 182 - bkey_invalid_type_for_btree, 183 + !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)), 184 + c, bkey_invalid_type_for_btree, 183 185 "invalid key type for btree %s (%s)", 184 186 bch2_btree_node_type_str(type), 185 187 k.k->type < KEY_TYPE_MAX ··· 187 189 : "(unknown)"); 188 190 189 191 if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) { 190 - bkey_fsck_err_on(k.k->size == 0, c, err, 191 - bkey_extent_size_zero, 192 + bkey_fsck_err_on(k.k->size == 0, 193 + c, bkey_extent_size_zero, 192 194 "size == 0"); 193 195 194 - bkey_fsck_err_on(k.k->size > k.k->p.offset, c, err, 195 - bkey_extent_size_greater_than_offset, 196 + bkey_fsck_err_on(k.k->size > k.k->p.offset, 197 + c, bkey_extent_size_greater_than_offset, 196 198 "size greater than offset (%u > %llu)", 197 199 k.k->size, k.k->p.offset); 198 200 } else { 199 - bkey_fsck_err_on(k.k->size, c, err, 200 - bkey_size_nonzero, 201 + bkey_fsck_err_on(k.k->size, 202 + c, bkey_size_nonzero, 201 203 "size != 0"); 202 204 } 203 205 ··· 205 207 enum btree_id btree = type - 1; 206 208 207 209 if (btree_type_has_snapshots(btree)) { 208 - bkey_fsck_err_on(!k.k->p.snapshot, c, err, 209 - bkey_snapshot_zero, 210 + bkey_fsck_err_on(!k.k->p.snapshot, 211 + c, bkey_snapshot_zero, 210 212 "snapshot == 0"); 211 213 } else if (!btree_type_has_snapshot_field(btree)) { 212 - bkey_fsck_err_on(k.k->p.snapshot, c, err, 213 - bkey_snapshot_nonzero, 214 + bkey_fsck_err_on(k.k->p.snapshot, 215 + c, bkey_snapshot_nonzero, 214 216 "nonzero snapshot"); 215 217 } else { 216 218 /* ··· 219 221 */ 220 222 } 221 223 222 - bkey_fsck_err_on(bkey_eq(k.k->p, POS_MAX), c, err, 223 - bkey_at_pos_max, 224 + bkey_fsck_err_on(bkey_eq(k.k->p, POS_MAX), 225 + c, bkey_at_pos_max, 224 226 "key at POS_MAX"); 225 227 } 226 228 fsck_err: 227 229 return ret; 228 230 } 229 231 230 - int bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k, 232 + int bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k, 231 233 enum btree_node_type type, 232 - enum bch_validate_flags flags, 233 - struct printbuf *err) 234 + enum bch_validate_flags flags) 234 235 { 235 - return __bch2_bkey_invalid(c, k, type, flags, err) ?: 236 - bch2_bkey_val_invalid(c, k, flags, err); 236 + return __bch2_bkey_validate(c, k, type, flags) ?: 237 + bch2_bkey_val_validate(c, k, flags); 237 238 } 238 239 239 240 int bch2_bkey_in_btree_node(struct bch_fs *c, struct btree *b, 240 - struct bkey_s_c k, struct printbuf *err) 241 + struct bkey_s_c k, enum bch_validate_flags flags) 241 242 { 242 243 int ret = 0; 243 244 244 - bkey_fsck_err_on(bpos_lt(k.k->p, b->data->min_key), c, err, 245 - bkey_before_start_of_btree_node, 245 + bkey_fsck_err_on(bpos_lt(k.k->p, b->data->min_key), 246 + c, bkey_before_start_of_btree_node, 246 247 "key before start of btree node"); 247 248 248 - bkey_fsck_err_on(bpos_gt(k.k->p, b->data->max_key), c, err, 249 - bkey_after_end_of_btree_node, 249 + bkey_fsck_err_on(bpos_gt(k.k->p, b->data->max_key), 250 + c, bkey_after_end_of_btree_node, 250 251 "key past end of btree node"); 251 252 fsck_err: 252 253 return ret;
+10 -11
fs/bcachefs/bkey_methods.h
··· 14 14 extern const struct bkey_ops bch2_bkey_null_ops; 15 15 16 16 /* 17 - * key_invalid: checks validity of @k, returns 0 if good or -EINVAL if bad. If 17 + * key_validate: checks validity of @k, returns 0 if good or -EINVAL if bad. If 18 18 * invalid, entire key will be deleted. 19 19 * 20 20 * When invalid, error string is returned via @err. @rw indicates whether key is 21 21 * being read or written; more aggressive checks can be enabled when rw == WRITE. 22 22 */ 23 23 struct bkey_ops { 24 - int (*key_invalid)(struct bch_fs *c, struct bkey_s_c k, 25 - enum bch_validate_flags flags, struct printbuf *err); 24 + int (*key_validate)(struct bch_fs *c, struct bkey_s_c k, 25 + enum bch_validate_flags flags); 26 26 void (*val_to_text)(struct printbuf *, struct bch_fs *, 27 27 struct bkey_s_c); 28 28 void (*swab)(struct bkey_s); ··· 48 48 : &bch2_bkey_null_ops; 49 49 } 50 50 51 - int bch2_bkey_val_invalid(struct bch_fs *, struct bkey_s_c, 52 - enum bch_validate_flags, struct printbuf *); 53 - int __bch2_bkey_invalid(struct bch_fs *, struct bkey_s_c, enum btree_node_type, 54 - enum bch_validate_flags, struct printbuf *); 55 - int bch2_bkey_invalid(struct bch_fs *, struct bkey_s_c, enum btree_node_type, 56 - enum bch_validate_flags, struct printbuf *); 57 - int bch2_bkey_in_btree_node(struct bch_fs *, struct btree *, 58 - struct bkey_s_c, struct printbuf *); 51 + int bch2_bkey_val_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 52 + int __bch2_bkey_validate(struct bch_fs *, struct bkey_s_c, enum btree_node_type, 53 + enum bch_validate_flags); 54 + int bch2_bkey_validate(struct bch_fs *, struct bkey_s_c, enum btree_node_type, 55 + enum bch_validate_flags); 56 + int bch2_bkey_in_btree_node(struct bch_fs *, struct btree *, struct bkey_s_c, 57 + enum bch_validate_flags); 59 58 60 59 void bch2_bpos_to_text(struct printbuf *, struct bpos); 61 60 void bch2_bkey_to_text(struct printbuf *, const struct bkey *);
+1 -4
fs/bcachefs/btree_gc.c
··· 741 741 742 742 static int bch2_mark_superblocks(struct bch_fs *c) 743 743 { 744 - mutex_lock(&c->sb_lock); 745 744 gc_pos_set(c, gc_phase(GC_PHASE_sb)); 746 745 747 - int ret = bch2_trans_mark_dev_sbs_flags(c, BTREE_TRIGGER_gc); 748 - mutex_unlock(&c->sb_lock); 749 - return ret; 746 + return bch2_trans_mark_dev_sbs_flags(c, BTREE_TRIGGER_gc); 750 747 } 751 748 752 749 static void bch2_gc_free(struct bch_fs *c)
+22 -47
fs/bcachefs/btree_io.c
··· 836 836 return ret; 837 837 } 838 838 839 - static int bset_key_invalid(struct bch_fs *c, struct btree *b, 840 - struct bkey_s_c k, 841 - bool updated_range, int rw, 842 - struct printbuf *err) 839 + static int bset_key_validate(struct bch_fs *c, struct btree *b, 840 + struct bkey_s_c k, 841 + bool updated_range, int rw) 843 842 { 844 - return __bch2_bkey_invalid(c, k, btree_node_type(b), READ, err) ?: 845 - (!updated_range ? bch2_bkey_in_btree_node(c, b, k, err) : 0) ?: 846 - (rw == WRITE ? bch2_bkey_val_invalid(c, k, READ, err) : 0); 843 + return __bch2_bkey_validate(c, k, btree_node_type(b), 0) ?: 844 + (!updated_range ? bch2_bkey_in_btree_node(c, b, k, 0) : 0) ?: 845 + (rw == WRITE ? bch2_bkey_val_validate(c, k, 0) : 0); 847 846 } 848 847 849 848 static bool bkey_packed_valid(struct bch_fs *c, struct btree *b, ··· 857 858 if (!bkeyp_u64s_valid(&b->format, k)) 858 859 return false; 859 860 860 - struct printbuf buf = PRINTBUF; 861 861 struct bkey tmp; 862 862 struct bkey_s u = __bkey_disassemble(b, k, &tmp); 863 - bool ret = __bch2_bkey_invalid(c, u.s_c, btree_node_type(b), READ, &buf); 864 - printbuf_exit(&buf); 865 - return ret; 863 + return !__bch2_bkey_validate(c, u.s_c, btree_node_type(b), BCH_VALIDATE_silent); 866 864 } 867 865 868 866 static int validate_bset_keys(struct bch_fs *c, struct btree *b, ··· 911 915 912 916 u = __bkey_disassemble(b, k, &tmp); 913 917 914 - printbuf_reset(&buf); 915 - if (bset_key_invalid(c, b, u.s_c, updated_range, write, &buf)) { 916 - printbuf_reset(&buf); 917 - bset_key_invalid(c, b, u.s_c, updated_range, write, &buf); 918 - prt_printf(&buf, "\n "); 919 - bch2_bkey_val_to_text(&buf, c, u.s_c); 920 - 921 - btree_err(-BCH_ERR_btree_node_read_err_fixable, 922 - c, NULL, b, i, k, 923 - btree_node_bad_bkey, 924 - "invalid bkey: %s", buf.buf); 918 + ret = bset_key_validate(c, b, u.s_c, updated_range, write); 919 + if (ret == -BCH_ERR_fsck_delete_bkey) 925 920 goto drop_this_key; 926 - } 921 + if (ret) 922 + goto fsck_err; 927 923 928 924 if (write) 929 925 bch2_bkey_compat(b->c.level, b->c.btree_id, version, ··· 1216 1228 struct bkey tmp; 1217 1229 struct bkey_s u = __bkey_disassemble(b, k, &tmp); 1218 1230 1219 - printbuf_reset(&buf); 1220 - 1221 - if (bch2_bkey_val_invalid(c, u.s_c, READ, &buf) || 1231 + ret = bch2_bkey_val_validate(c, u.s_c, READ); 1232 + if (ret == -BCH_ERR_fsck_delete_bkey || 1222 1233 (bch2_inject_invalid_keys && 1223 1234 !bversion_cmp(u.k->version, MAX_VERSION))) { 1224 - printbuf_reset(&buf); 1225 - 1226 - prt_printf(&buf, "invalid bkey: "); 1227 - bch2_bkey_val_invalid(c, u.s_c, READ, &buf); 1228 - prt_printf(&buf, "\n "); 1229 - bch2_bkey_val_to_text(&buf, c, u.s_c); 1230 - 1231 - btree_err(-BCH_ERR_btree_node_read_err_fixable, 1232 - c, NULL, b, i, k, 1233 - btree_node_bad_bkey, 1234 - "%s", buf.buf); 1235 - 1236 1235 btree_keys_account_key_drop(&b->nr, 0, k); 1237 1236 1238 1237 i->u64s = cpu_to_le16(le16_to_cpu(i->u64s) - k->u64s); ··· 1228 1253 set_btree_bset_end(b, b->set); 1229 1254 continue; 1230 1255 } 1256 + if (ret) 1257 + goto fsck_err; 1231 1258 1232 1259 if (u.k->type == KEY_TYPE_btree_ptr_v2) { 1233 1260 struct bkey_s_btree_ptr_v2 bp = bkey_s_to_btree_ptr_v2(u); ··· 1744 1767 1745 1768 set_btree_node_read_in_flight(b); 1746 1769 1770 + /* we can't pass the trans to read_done() for fsck errors, so it must be unlocked */ 1771 + bch2_trans_unlock(trans); 1747 1772 bch2_btree_node_read(trans, b, true); 1748 1773 1749 1774 if (btree_node_read_error(b)) { ··· 1931 1952 static int validate_bset_for_write(struct bch_fs *c, struct btree *b, 1932 1953 struct bset *i, unsigned sectors) 1933 1954 { 1934 - struct printbuf buf = PRINTBUF; 1935 1955 bool saw_error; 1936 - int ret; 1937 1956 1938 - ret = bch2_bkey_invalid(c, bkey_i_to_s_c(&b->key), 1939 - BKEY_TYPE_btree, WRITE, &buf); 1940 - 1941 - if (ret) 1942 - bch2_fs_inconsistent(c, "invalid btree node key before write: %s", buf.buf); 1943 - printbuf_exit(&buf); 1944 - if (ret) 1957 + int ret = bch2_bkey_validate(c, bkey_i_to_s_c(&b->key), 1958 + BKEY_TYPE_btree, WRITE); 1959 + if (ret) { 1960 + bch2_fs_inconsistent(c, "invalid btree node key before write"); 1945 1961 return ret; 1962 + } 1946 1963 1947 1964 ret = validate_bset_keys(c, b, i, WRITE, false, &saw_error) ?: 1948 1965 validate_bset(c, NULL, b, i, b->written, sectors, WRITE, false, &saw_error);
+1
fs/bcachefs/btree_iter.c
··· 1900 1900 goto out; 1901 1901 } 1902 1902 1903 + /* Only kept for -tools */ 1903 1904 struct btree *bch2_btree_iter_peek_node_and_restart(struct btree_iter *iter) 1904 1905 { 1905 1906 struct btree *b;
+27 -15
fs/bcachefs/btree_iter.h
··· 600 600 601 601 u32 bch2_trans_begin(struct btree_trans *); 602 602 603 - /* 604 - * XXX 605 - * this does not handle transaction restarts from bch2_btree_iter_next_node() 606 - * correctly 607 - */ 608 - #define __for_each_btree_node(_trans, _iter, _btree_id, _start, \ 609 - _locks_want, _depth, _flags, _b, _ret) \ 610 - for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \ 611 - _start, _locks_want, _depth, _flags); \ 612 - (_b) = bch2_btree_iter_peek_node_and_restart(&(_iter)), \ 613 - !((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b); \ 614 - (_b) = bch2_btree_iter_next_node(&(_iter))) 603 + #define __for_each_btree_node(_trans, _iter, _btree_id, _start, \ 604 + _locks_want, _depth, _flags, _b, _do) \ 605 + ({ \ 606 + bch2_trans_begin((_trans)); \ 607 + \ 608 + struct btree_iter _iter; \ 609 + bch2_trans_node_iter_init((_trans), &_iter, (_btree_id), \ 610 + _start, _locks_want, _depth, _flags); \ 611 + int _ret3 = 0; \ 612 + do { \ 613 + _ret3 = lockrestart_do((_trans), ({ \ 614 + struct btree *_b = bch2_btree_iter_peek_node(&_iter); \ 615 + if (!_b) \ 616 + break; \ 617 + \ 618 + PTR_ERR_OR_ZERO(_b) ?: (_do); \ 619 + })) ?: \ 620 + lockrestart_do((_trans), \ 621 + PTR_ERR_OR_ZERO(bch2_btree_iter_next_node(&_iter))); \ 622 + } while (!_ret3); \ 623 + \ 624 + bch2_trans_iter_exit((_trans), &(_iter)); \ 625 + _ret3; \ 626 + }) 615 627 616 628 #define for_each_btree_node(_trans, _iter, _btree_id, _start, \ 617 - _flags, _b, _ret) \ 618 - __for_each_btree_node(_trans, _iter, _btree_id, _start, \ 619 - 0, 0, _flags, _b, _ret) 629 + _flags, _b, _do) \ 630 + __for_each_btree_node(_trans, _iter, _btree_id, _start, \ 631 + 0, 0, _flags, _b, _do) 620 632 621 633 static inline struct bkey_s_c bch2_btree_iter_peek_prev_type(struct btree_iter *iter, 622 634 unsigned flags)
-5
fs/bcachefs/btree_key_cache.c
··· 497 497 498 498 path->l[1].b = NULL; 499 499 500 - if (bch2_btree_node_relock_notrace(trans, path, 0)) { 501 - path->uptodate = BTREE_ITER_UPTODATE; 502 - return 0; 503 - } 504 - 505 500 int ret; 506 501 do { 507 502 ret = btree_path_traverse_cached_fast(trans, path);
+16 -2
fs/bcachefs/btree_key_cache.h
··· 11 11 return max_t(ssize_t, 0, nr_dirty - max_dirty); 12 12 } 13 13 14 - static inline bool bch2_btree_key_cache_must_wait(struct bch_fs *c) 14 + static inline ssize_t __bch2_btree_key_cache_must_wait(struct bch_fs *c) 15 15 { 16 16 size_t nr_dirty = atomic_long_read(&c->btree_key_cache.nr_dirty); 17 17 size_t nr_keys = atomic_long_read(&c->btree_key_cache.nr_keys); 18 18 size_t max_dirty = 4096 + (nr_keys * 3) / 4; 19 19 20 - return nr_dirty > max_dirty; 20 + return nr_dirty - max_dirty; 21 + } 22 + 23 + static inline bool bch2_btree_key_cache_must_wait(struct bch_fs *c) 24 + { 25 + return __bch2_btree_key_cache_must_wait(c) > 0; 26 + } 27 + 28 + static inline bool bch2_btree_key_cache_wait_done(struct bch_fs *c) 29 + { 30 + size_t nr_dirty = atomic_long_read(&c->btree_key_cache.nr_dirty); 31 + size_t nr_keys = atomic_long_read(&c->btree_key_cache.nr_keys); 32 + size_t max_dirty = 2048 + (nr_keys * 5) / 8; 33 + 34 + return nr_dirty <= max_dirty; 21 35 } 22 36 23 37 int bch2_btree_key_cache_journal_flush(struct journal *,
+1 -1
fs/bcachefs/btree_node_scan.c
··· 530 530 bch_verbose(c, "%s(): recovering %s", __func__, buf.buf); 531 531 printbuf_exit(&buf); 532 532 533 - BUG_ON(bch2_bkey_invalid(c, bkey_i_to_s_c(&tmp.k), BKEY_TYPE_btree, 0, NULL)); 533 + BUG_ON(bch2_bkey_validate(c, bkey_i_to_s_c(&tmp.k), BKEY_TYPE_btree, 0)); 534 534 535 535 ret = bch2_journal_key_insert(c, btree, level + 1, &tmp.k); 536 536 if (ret)
+21 -61
fs/bcachefs/btree_trans_commit.c
··· 712 712 a->k.version = journal_pos_to_bversion(&trans->journal_res, 713 713 (u64 *) entry - (u64 *) trans->journal_entries); 714 714 BUG_ON(bversion_zero(a->k.version)); 715 - ret = bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), false); 715 + ret = bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), false, false); 716 716 if (ret) 717 717 goto revert_fs_usage; 718 718 } ··· 798 798 struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start); 799 799 800 800 bch2_accounting_neg(a); 801 - bch2_accounting_mem_mod_locked(trans, a.c, false); 801 + bch2_accounting_mem_mod_locked(trans, a.c, false, false); 802 802 bch2_accounting_neg(a); 803 803 } 804 804 percpu_up_read(&c->mark_lock); ··· 816 816 trans_for_each_update(trans, i) 817 817 if (i->k->k.type != KEY_TYPE_accounting) 818 818 bch2_journal_key_overwritten(trans->c, i->btree_id, i->level, i->k->k.p); 819 - } 820 - 821 - static noinline int bch2_trans_commit_bkey_invalid(struct btree_trans *trans, 822 - enum bch_validate_flags flags, 823 - struct btree_insert_entry *i, 824 - struct printbuf *err) 825 - { 826 - struct bch_fs *c = trans->c; 827 - 828 - printbuf_reset(err); 829 - prt_printf(err, "invalid bkey on insert from %s -> %ps\n", 830 - trans->fn, (void *) i->ip_allocated); 831 - printbuf_indent_add(err, 2); 832 - 833 - bch2_bkey_val_to_text(err, c, bkey_i_to_s_c(i->k)); 834 - prt_newline(err); 835 - 836 - bch2_bkey_invalid(c, bkey_i_to_s_c(i->k), i->bkey_type, flags, err); 837 - bch2_print_string_as_lines(KERN_ERR, err->buf); 838 - 839 - bch2_inconsistent_error(c); 840 - bch2_dump_trans_updates(trans); 841 - 842 - return -EINVAL; 843 - } 844 - 845 - static noinline int bch2_trans_commit_journal_entry_invalid(struct btree_trans *trans, 846 - struct jset_entry *i) 847 - { 848 - struct bch_fs *c = trans->c; 849 - struct printbuf buf = PRINTBUF; 850 - 851 - prt_printf(&buf, "invalid bkey on insert from %s\n", trans->fn); 852 - printbuf_indent_add(&buf, 2); 853 - 854 - bch2_journal_entry_to_text(&buf, c, i); 855 - prt_newline(&buf); 856 - 857 - bch2_print_string_as_lines(KERN_ERR, buf.buf); 858 - 859 - bch2_inconsistent_error(c); 860 - bch2_dump_trans_updates(trans); 861 - 862 - return -EINVAL; 863 819 } 864 820 865 821 static int bch2_trans_commit_journal_pin_flush(struct journal *j, ··· 883 927 static int journal_reclaim_wait_done(struct bch_fs *c) 884 928 { 885 929 int ret = bch2_journal_error(&c->journal) ?: 886 - !bch2_btree_key_cache_must_wait(c); 930 + bch2_btree_key_cache_wait_done(c); 887 931 888 932 if (!ret) 889 933 journal_reclaim_kick(&c->journal); ··· 929 973 bch2_trans_unlock(trans); 930 974 931 975 trace_and_count(c, trans_blocked_journal_reclaim, trans, trace_ip); 976 + track_event_change(&c->times[BCH_TIME_blocked_key_cache_flush], true); 932 977 933 978 wait_event_freezable(c->journal.reclaim_wait, 934 979 (ret = journal_reclaim_wait_done(c))); 980 + 981 + track_event_change(&c->times[BCH_TIME_blocked_key_cache_flush], false); 982 + 935 983 if (ret < 0) 936 984 break; 937 985 ··· 1020 1060 goto out_reset; 1021 1061 1022 1062 trans_for_each_update(trans, i) { 1023 - struct printbuf buf = PRINTBUF; 1024 1063 enum bch_validate_flags invalid_flags = 0; 1025 1064 1026 1065 if (!(flags & BCH_TRANS_COMMIT_no_journal_res)) 1027 1066 invalid_flags |= BCH_VALIDATE_write|BCH_VALIDATE_commit; 1028 1067 1029 - if (unlikely(bch2_bkey_invalid(c, bkey_i_to_s_c(i->k), 1030 - i->bkey_type, invalid_flags, &buf))) 1031 - ret = bch2_trans_commit_bkey_invalid(trans, invalid_flags, i, &buf); 1032 - btree_insert_entry_checks(trans, i); 1033 - printbuf_exit(&buf); 1034 - 1035 - if (ret) 1068 + ret = bch2_bkey_validate(c, bkey_i_to_s_c(i->k), 1069 + i->bkey_type, invalid_flags); 1070 + if (unlikely(ret)){ 1071 + bch2_trans_inconsistent(trans, "invalid bkey on insert from %s -> %ps\n", 1072 + trans->fn, (void *) i->ip_allocated); 1036 1073 return ret; 1074 + } 1075 + btree_insert_entry_checks(trans, i); 1037 1076 } 1038 1077 1039 1078 for (struct jset_entry *i = trans->journal_entries; ··· 1043 1084 if (!(flags & BCH_TRANS_COMMIT_no_journal_res)) 1044 1085 invalid_flags |= BCH_VALIDATE_write|BCH_VALIDATE_commit; 1045 1086 1046 - if (unlikely(bch2_journal_entry_validate(c, NULL, i, 1047 - bcachefs_metadata_version_current, 1048 - CPU_BIG_ENDIAN, invalid_flags))) 1049 - ret = bch2_trans_commit_journal_entry_invalid(trans, i); 1050 - 1051 - if (ret) 1087 + ret = bch2_journal_entry_validate(c, NULL, i, 1088 + bcachefs_metadata_version_current, 1089 + CPU_BIG_ENDIAN, invalid_flags); 1090 + if (unlikely(ret)) { 1091 + bch2_trans_inconsistent(trans, "invalid journal entry on insert from %s\n", 1092 + trans->fn); 1052 1093 return ret; 1094 + } 1053 1095 } 1054 1096 1055 1097 if (unlikely(!test_bit(BCH_FS_may_go_rw, &c->flags))) {
+4 -12
fs/bcachefs/btree_update_interior.c
··· 1364 1364 if (unlikely(!test_bit(JOURNAL_replay_done, &c->journal.flags))) 1365 1365 bch2_journal_key_overwritten(c, b->c.btree_id, b->c.level, insert->k.p); 1366 1366 1367 - if (bch2_bkey_invalid(c, bkey_i_to_s_c(insert), 1368 - btree_node_type(b), WRITE, &buf) ?: 1369 - bch2_bkey_in_btree_node(c, b, bkey_i_to_s_c(insert), &buf)) { 1370 - printbuf_reset(&buf); 1371 - prt_printf(&buf, "inserting invalid bkey\n "); 1372 - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(insert)); 1373 - prt_printf(&buf, "\n "); 1374 - bch2_bkey_invalid(c, bkey_i_to_s_c(insert), 1375 - btree_node_type(b), WRITE, &buf); 1376 - bch2_bkey_in_btree_node(c, b, bkey_i_to_s_c(insert), &buf); 1377 - 1378 - bch2_fs_inconsistent(c, "%s", buf.buf); 1367 + if (bch2_bkey_validate(c, bkey_i_to_s_c(insert), 1368 + btree_node_type(b), BCH_VALIDATE_write) ?: 1369 + bch2_bkey_in_btree_node(c, b, bkey_i_to_s_c(insert), BCH_VALIDATE_write)) { 1370 + bch2_fs_inconsistent(c, "%s: inserting invalid bkey", __func__); 1379 1371 dump_stack(); 1380 1372 } 1381 1373
+24 -6
fs/bcachefs/buckets.c
··· 810 810 ret = bch2_disk_accounting_mod(trans, &acc_btree_key, &replicas_sectors, 1, gc); 811 811 if (ret) 812 812 return ret; 813 + } else { 814 + bool insert = !(flags & BTREE_TRIGGER_overwrite); 815 + struct disk_accounting_pos acc_inum_key = { 816 + .type = BCH_DISK_ACCOUNTING_inum, 817 + .inum.inum = k.k->p.inode, 818 + }; 819 + s64 v[3] = { 820 + insert ? 1 : -1, 821 + insert ? k.k->size : -((s64) k.k->size), 822 + replicas_sectors, 823 + }; 824 + ret = bch2_disk_accounting_mod(trans, &acc_inum_key, v, ARRAY_SIZE(v), gc); 825 + if (ret) 826 + return ret; 813 827 } 814 828 815 829 if (bch2_bkey_rebalance_opts(k)) { ··· 915 901 enum bch_data_type type, 916 902 unsigned sectors) 917 903 { 918 - struct bch_fs *c = trans->c; 919 904 struct btree_iter iter; 920 905 int ret = 0; 921 906 ··· 924 911 return PTR_ERR(a); 925 912 926 913 if (a->v.data_type && type && a->v.data_type != type) { 927 - bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, 914 + bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, 928 915 bucket_metadata_type_mismatch, 929 916 "bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n" 930 917 "while marking %s", ··· 1045 1032 static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, struct bch_dev *ca, 1046 1033 enum btree_iter_update_trigger_flags flags) 1047 1034 { 1048 - struct bch_sb_layout *layout = &ca->disk_sb.sb->layout; 1035 + struct bch_fs *c = trans->c; 1036 + 1037 + mutex_lock(&c->sb_lock); 1038 + struct bch_sb_layout layout = ca->disk_sb.sb->layout; 1039 + mutex_unlock(&c->sb_lock); 1040 + 1049 1041 u64 bucket = 0; 1050 1042 unsigned i, bucket_sectors = 0; 1051 1043 int ret; 1052 1044 1053 - for (i = 0; i < layout->nr_superblocks; i++) { 1054 - u64 offset = le64_to_cpu(layout->sb_offset[i]); 1045 + for (i = 0; i < layout.nr_superblocks; i++) { 1046 + u64 offset = le64_to_cpu(layout.sb_offset[i]); 1055 1047 1056 1048 if (offset == BCH_SB_SECTOR) { 1057 1049 ret = bch2_trans_mark_metadata_sectors(trans, ca, ··· 1067 1049 } 1068 1050 1069 1051 ret = bch2_trans_mark_metadata_sectors(trans, ca, offset, 1070 - offset + (1 << layout->sb_max_size_bits), 1052 + offset + (1 << layout.sb_max_size_bits), 1071 1053 BCH_DATA_sb, &bucket, &bucket_sectors, flags); 1072 1054 if (ret) 1073 1055 return ret;
+9 -2
fs/bcachefs/buckets_waiting_for_journal.c
··· 93 93 .dev_bucket = (u64) dev << 56 | bucket, 94 94 .journal_seq = journal_seq, 95 95 }; 96 - size_t i, size, new_bits, nr_elements = 1, nr_rehashes = 0; 96 + size_t i, size, new_bits, nr_elements = 1, nr_rehashes = 0, nr_rehashes_this_size = 0; 97 97 int ret = 0; 98 98 99 99 mutex_lock(&b->lock); ··· 106 106 for (i = 0; i < size; i++) 107 107 nr_elements += t->d[i].journal_seq > flushed_seq; 108 108 109 - new_bits = t->bits + (nr_elements * 3 > size); 109 + new_bits = ilog2(roundup_pow_of_two(nr_elements * 3)); 110 110 111 111 n = kvmalloc(sizeof(*n) + (sizeof(n->d[0]) << new_bits), GFP_KERNEL); 112 112 if (!n) { ··· 115 115 } 116 116 117 117 retry_rehash: 118 + if (nr_rehashes_this_size == 3) { 119 + new_bits++; 120 + nr_rehashes_this_size = 0; 121 + } 122 + 118 123 nr_rehashes++; 124 + nr_rehashes_this_size++; 125 + 119 126 bucket_table_init(n, new_bits); 120 127 121 128 tmp = new;
+2 -4
fs/bcachefs/data_update.c
··· 250 250 * it's been hard to reproduce, so this should give us some more 251 251 * information when it does occur: 252 252 */ 253 - struct printbuf err = PRINTBUF; 254 - int invalid = bch2_bkey_invalid(c, bkey_i_to_s_c(insert), __btree_node_type(0, m->btree_id), 0, &err); 255 - printbuf_exit(&err); 256 - 253 + int invalid = bch2_bkey_validate(c, bkey_i_to_s_c(insert), __btree_node_type(0, m->btree_id), 254 + BCH_VALIDATE_commit); 257 255 if (invalid) { 258 256 struct printbuf buf = PRINTBUF; 259 257
+9 -29
fs/bcachefs/debug.c
··· 397 397 size_t size, loff_t *ppos) 398 398 { 399 399 struct dump_iter *i = file->private_data; 400 - struct btree_trans *trans; 401 - struct btree_iter iter; 402 - struct btree *b; 403 - ssize_t ret; 404 400 405 401 i->ubuf = buf; 406 402 i->size = size; 407 403 i->ret = 0; 408 404 409 - ret = flush_buf(i); 405 + ssize_t ret = flush_buf(i); 410 406 if (ret) 411 407 return ret; 412 408 413 409 if (bpos_eq(SPOS_MAX, i->from)) 414 410 return i->ret; 415 411 416 - trans = bch2_trans_get(i->c); 417 - retry: 418 - bch2_trans_begin(trans); 412 + return bch2_trans_run(i->c, 413 + for_each_btree_node(trans, iter, i->id, i->from, 0, b, ({ 414 + bch2_btree_node_to_text(&i->buf, i->c, b); 415 + i->from = !bpos_eq(SPOS_MAX, b->key.k.p) 416 + ? bpos_successor(b->key.k.p) 417 + : b->key.k.p; 419 418 420 - for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) { 421 - bch2_btree_node_to_text(&i->buf, i->c, b); 422 - i->from = !bpos_eq(SPOS_MAX, b->key.k.p) 423 - ? bpos_successor(b->key.k.p) 424 - : b->key.k.p; 425 - 426 - ret = drop_locks_do(trans, flush_buf(i)); 427 - if (ret) 428 - break; 429 - } 430 - bch2_trans_iter_exit(trans, &iter); 431 - 432 - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) 433 - goto retry; 434 - 435 - bch2_trans_put(trans); 436 - 437 - if (!ret) 438 - ret = flush_buf(i); 439 - 440 - return ret ?: i->ret; 419 + drop_locks_do(trans, flush_buf(i)); 420 + }))) ?: i->ret; 441 421 } 442 422 443 423 static const struct file_operations btree_format_debug_ops = {
+16 -17
fs/bcachefs/dirent.c
··· 100 100 .is_visible = dirent_is_visible, 101 101 }; 102 102 103 - int bch2_dirent_invalid(struct bch_fs *c, struct bkey_s_c k, 104 - enum bch_validate_flags flags, 105 - struct printbuf *err) 103 + int bch2_dirent_validate(struct bch_fs *c, struct bkey_s_c k, 104 + enum bch_validate_flags flags) 106 105 { 107 106 struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); 108 107 struct qstr d_name = bch2_dirent_get_name(d); 109 108 int ret = 0; 110 109 111 - bkey_fsck_err_on(!d_name.len, c, err, 112 - dirent_empty_name, 110 + bkey_fsck_err_on(!d_name.len, 111 + c, dirent_empty_name, 113 112 "empty name"); 114 113 115 - bkey_fsck_err_on(bkey_val_u64s(k.k) > dirent_val_u64s(d_name.len), c, err, 116 - dirent_val_too_big, 114 + bkey_fsck_err_on(bkey_val_u64s(k.k) > dirent_val_u64s(d_name.len), 115 + c, dirent_val_too_big, 117 116 "value too big (%zu > %u)", 118 117 bkey_val_u64s(k.k), dirent_val_u64s(d_name.len)); 119 118 ··· 120 121 * Check new keys don't exceed the max length 121 122 * (older keys may be larger.) 122 123 */ 123 - bkey_fsck_err_on((flags & BCH_VALIDATE_commit) && d_name.len > BCH_NAME_MAX, c, err, 124 - dirent_name_too_long, 124 + bkey_fsck_err_on((flags & BCH_VALIDATE_commit) && d_name.len > BCH_NAME_MAX, 125 + c, dirent_name_too_long, 125 126 "dirent name too big (%u > %u)", 126 127 d_name.len, BCH_NAME_MAX); 127 128 128 - bkey_fsck_err_on(d_name.len != strnlen(d_name.name, d_name.len), c, err, 129 - dirent_name_embedded_nul, 129 + bkey_fsck_err_on(d_name.len != strnlen(d_name.name, d_name.len), 130 + c, dirent_name_embedded_nul, 130 131 "dirent has stray data after name's NUL"); 131 132 132 133 bkey_fsck_err_on((d_name.len == 1 && !memcmp(d_name.name, ".", 1)) || 133 - (d_name.len == 2 && !memcmp(d_name.name, "..", 2)), c, err, 134 - dirent_name_dot_or_dotdot, 134 + (d_name.len == 2 && !memcmp(d_name.name, "..", 2)), 135 + c, dirent_name_dot_or_dotdot, 135 136 "invalid name"); 136 137 137 - bkey_fsck_err_on(memchr(d_name.name, '/', d_name.len), c, err, 138 - dirent_name_has_slash, 138 + bkey_fsck_err_on(memchr(d_name.name, '/', d_name.len), 139 + c, dirent_name_has_slash, 139 140 "name with /"); 140 141 141 142 bkey_fsck_err_on(d.v->d_type != DT_SUBVOL && 142 - le64_to_cpu(d.v->d_inum) == d.k->p.inode, c, err, 143 - dirent_to_itself, 143 + le64_to_cpu(d.v->d_inum) == d.k->p.inode, 144 + c, dirent_to_itself, 144 145 "dirent points to own directory"); 145 146 fsck_err: 146 147 return ret;
+2 -3
fs/bcachefs/dirent.h
··· 7 7 enum bch_validate_flags; 8 8 extern const struct bch_hash_desc bch2_dirent_hash_desc; 9 9 10 - int bch2_dirent_invalid(struct bch_fs *, struct bkey_s_c, 11 - enum bch_validate_flags, struct printbuf *); 10 + int bch2_dirent_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 12 11 void bch2_dirent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 13 12 14 13 #define bch2_bkey_ops_dirent ((struct bkey_ops) { \ 15 - .key_invalid = bch2_dirent_invalid, \ 14 + .key_validate = bch2_dirent_validate, \ 16 15 .val_to_text = bch2_dirent_to_text, \ 17 16 .min_val_size = 16, \ 18 17 })
+21 -13
fs/bcachefs/disk_accounting.c
··· 126 126 127 127 #define field_end(p, member) (((void *) (&p.member)) + sizeof(p.member)) 128 128 129 - int bch2_accounting_invalid(struct bch_fs *c, struct bkey_s_c k, 130 - enum bch_validate_flags flags, 131 - struct printbuf *err) 129 + int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k, 130 + enum bch_validate_flags flags) 132 131 { 133 132 struct disk_accounting_pos acc_k; 134 133 bpos_to_disk_accounting_pos(&acc_k, k.k->p); ··· 143 144 break; 144 145 case BCH_DISK_ACCOUNTING_replicas: 145 146 bkey_fsck_err_on(!acc_k.replicas.nr_devs, 146 - c, err, accounting_key_replicas_nr_devs_0, 147 + c, accounting_key_replicas_nr_devs_0, 147 148 "accounting key replicas entry with nr_devs=0"); 148 149 149 150 bkey_fsck_err_on(acc_k.replicas.nr_required > acc_k.replicas.nr_devs || 150 151 (acc_k.replicas.nr_required > 1 && 151 152 acc_k.replicas.nr_required == acc_k.replicas.nr_devs), 152 - c, err, accounting_key_replicas_nr_required_bad, 153 + c, accounting_key_replicas_nr_required_bad, 153 154 "accounting key replicas entry with bad nr_required"); 154 155 155 156 for (unsigned i = 0; i + 1 < acc_k.replicas.nr_devs; i++) 156 - bkey_fsck_err_on(acc_k.replicas.devs[i] > acc_k.replicas.devs[i + 1], 157 - c, err, accounting_key_replicas_devs_unsorted, 157 + bkey_fsck_err_on(acc_k.replicas.devs[i] >= acc_k.replicas.devs[i + 1], 158 + c, accounting_key_replicas_devs_unsorted, 158 159 "accounting key replicas entry with unsorted devs"); 159 160 160 161 end = (void *) &acc_k.replicas + replicas_entry_bytes(&acc_k.replicas); ··· 177 178 } 178 179 179 180 bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)), 180 - c, err, accounting_key_junk_at_end, 181 + c, accounting_key_junk_at_end, 181 182 "junk at end of accounting key"); 182 183 fsck_err: 183 184 return ret; ··· 527 528 struct disk_accounting_pos acc_k; 528 529 bpos_to_disk_accounting_pos(&acc_k, e->pos); 529 530 531 + if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR) 532 + continue; 533 + 530 534 u64 src_v[BCH_ACCOUNTING_MAX_COUNTERS]; 531 535 u64 dst_v[BCH_ACCOUNTING_MAX_COUNTERS]; 532 536 ··· 566 564 struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i; 567 565 568 566 accounting_key_init(&k_i.k, &acc_k, src_v, nr); 569 - bch2_accounting_mem_mod_locked(trans, bkey_i_to_s_c_accounting(&k_i.k), false); 567 + bch2_accounting_mem_mod_locked(trans, bkey_i_to_s_c_accounting(&k_i.k), false, false); 570 568 571 569 preempt_disable(); 572 570 struct bch_fs_usage_base *dst = this_cpu_ptr(c->usage); ··· 595 593 return 0; 596 594 597 595 percpu_down_read(&c->mark_lock); 598 - int ret = __bch2_accounting_mem_mod(c, bkey_s_c_to_accounting(k), false); 596 + int ret = bch2_accounting_mem_mod_locked(trans, bkey_s_c_to_accounting(k), false, true); 599 597 percpu_up_read(&c->mark_lock); 600 598 601 599 if (bch2_accounting_key_is_zero(bkey_s_c_to_accounting(k)) && ··· 762 760 struct bkey_s_c_accounting a = bkey_s_c_to_accounting(k); 763 761 unsigned nr = bch2_accounting_counters(k.k); 764 762 763 + struct disk_accounting_pos acc_k; 764 + bpos_to_disk_accounting_pos(&acc_k, k.k->p); 765 + 766 + if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR) 767 + continue; 768 + 769 + if (acc_k.type == BCH_DISK_ACCOUNTING_inum) 770 + continue; 771 + 765 772 bch2_accounting_mem_read(c, k.k->p, v, nr); 766 773 767 774 if (memcmp(a.v->d, v, nr * sizeof(u64))) { ··· 785 774 printbuf_exit(&buf); 786 775 mismatch = true; 787 776 } 788 - 789 - struct disk_accounting_pos acc_k; 790 - bpos_to_disk_accounting_pos(&acc_k, a.k->p); 791 777 792 778 switch (acc_k.type) { 793 779 case BCH_DISK_ACCOUNTING_persistent_reserved:
+36 -40
fs/bcachefs/disk_accounting.h
··· 82 82 s64 *, unsigned, bool); 83 83 int bch2_mod_dev_cached_sectors(struct btree_trans *, unsigned, s64, bool); 84 84 85 - int bch2_accounting_invalid(struct bch_fs *, struct bkey_s_c, 86 - enum bch_validate_flags, struct printbuf *); 85 + int bch2_accounting_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 87 86 void bch2_accounting_key_to_text(struct printbuf *, struct disk_accounting_pos *); 88 87 void bch2_accounting_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 89 88 void bch2_accounting_swab(struct bkey_s); 90 89 91 90 #define bch2_bkey_ops_accounting ((struct bkey_ops) { \ 92 - .key_invalid = bch2_accounting_invalid, \ 91 + .key_validate = bch2_accounting_validate, \ 93 92 .val_to_text = bch2_accounting_to_text, \ 94 93 .swab = bch2_accounting_swab, \ 95 94 .min_val_size = 8, \ ··· 106 107 int bch2_accounting_mem_insert(struct bch_fs *, struct bkey_s_c_accounting, bool); 107 108 void bch2_accounting_mem_gc(struct bch_fs *); 108 109 109 - static inline int __bch2_accounting_mem_mod(struct bch_fs *c, struct bkey_s_c_accounting a, bool gc) 110 + /* 111 + * Update in memory counters so they match the btree update we're doing; called 112 + * from transaction commit path 113 + */ 114 + static inline int bch2_accounting_mem_mod_locked(struct btree_trans *trans, struct bkey_s_c_accounting a, bool gc, bool read) 110 115 { 116 + struct bch_fs *c = trans->c; 117 + struct disk_accounting_pos acc_k; 118 + bpos_to_disk_accounting_pos(&acc_k, a.k->p); 119 + 120 + if (acc_k.type == BCH_DISK_ACCOUNTING_inum) 121 + return 0; 122 + 123 + if (!gc && !read) { 124 + switch (acc_k.type) { 125 + case BCH_DISK_ACCOUNTING_persistent_reserved: 126 + trans->fs_usage_delta.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0]; 127 + break; 128 + case BCH_DISK_ACCOUNTING_replicas: 129 + fs_usage_data_type_to_base(&trans->fs_usage_delta, acc_k.replicas.data_type, a.v->d[0]); 130 + break; 131 + case BCH_DISK_ACCOUNTING_dev_data_type: 132 + rcu_read_lock(); 133 + struct bch_dev *ca = bch2_dev_rcu(c, acc_k.dev_data_type.dev); 134 + if (ca) { 135 + this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].buckets, a.v->d[0]); 136 + this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].sectors, a.v->d[1]); 137 + this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].fragmented, a.v->d[2]); 138 + } 139 + rcu_read_unlock(); 140 + break; 141 + } 142 + } 143 + 111 144 struct bch_accounting_mem *acc = &c->accounting; 112 145 unsigned idx; 113 146 ··· 161 130 return 0; 162 131 } 163 132 164 - /* 165 - * Update in memory counters so they match the btree update we're doing; called 166 - * from transaction commit path 167 - */ 168 - static inline int bch2_accounting_mem_mod_locked(struct btree_trans *trans, struct bkey_s_c_accounting a, bool gc) 169 - { 170 - struct bch_fs *c = trans->c; 171 - 172 - if (!gc) { 173 - struct disk_accounting_pos acc_k; 174 - bpos_to_disk_accounting_pos(&acc_k, a.k->p); 175 - 176 - switch (acc_k.type) { 177 - case BCH_DISK_ACCOUNTING_persistent_reserved: 178 - trans->fs_usage_delta.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0]; 179 - break; 180 - case BCH_DISK_ACCOUNTING_replicas: 181 - fs_usage_data_type_to_base(&trans->fs_usage_delta, acc_k.replicas.data_type, a.v->d[0]); 182 - break; 183 - case BCH_DISK_ACCOUNTING_dev_data_type: 184 - rcu_read_lock(); 185 - struct bch_dev *ca = bch2_dev_rcu(c, acc_k.dev_data_type.dev); 186 - if (ca) { 187 - this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].buckets, a.v->d[0]); 188 - this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].sectors, a.v->d[1]); 189 - this_cpu_add(ca->usage->d[acc_k.dev_data_type.data_type].fragmented, a.v->d[2]); 190 - } 191 - rcu_read_unlock(); 192 - break; 193 - } 194 - } 195 - 196 - return __bch2_accounting_mem_mod(c, a, gc); 197 - } 198 - 199 133 static inline int bch2_accounting_mem_add(struct btree_trans *trans, struct bkey_s_c_accounting a, bool gc) 200 134 { 201 135 percpu_down_read(&trans->c->mark_lock); 202 - int ret = bch2_accounting_mem_mod_locked(trans, a, gc); 136 + int ret = bch2_accounting_mem_mod_locked(trans, a, gc, false); 203 137 percpu_up_read(&trans->c->mark_lock); 204 138 return ret; 205 139 }
+7 -1
fs/bcachefs/disk_accounting_format.h
··· 103 103 x(compression, 4) \ 104 104 x(snapshot, 5) \ 105 105 x(btree, 6) \ 106 - x(rebalance_work, 7) 106 + x(rebalance_work, 7) \ 107 + x(inum, 8) 107 108 108 109 enum disk_accounting_type { 109 110 #define x(f, nr) BCH_DISK_ACCOUNTING_##f = nr, ··· 137 136 __u32 id; 138 137 } __packed; 139 138 139 + struct bch_acct_inum { 140 + __u64 inum; 141 + } __packed; 142 + 140 143 struct bch_acct_rebalance_work { 141 144 }; 142 145 ··· 157 152 struct bch_acct_snapshot snapshot; 158 153 struct bch_acct_btree btree; 159 154 struct bch_acct_rebalance_work rebalance_work; 155 + struct bch_acct_inum inum; 160 156 } __packed; 161 157 } __packed; 162 158 struct bpos _pad;
+7 -8
fs/bcachefs/ec.c
··· 107 107 108 108 /* Stripes btree keys: */ 109 109 110 - int bch2_stripe_invalid(struct bch_fs *c, struct bkey_s_c k, 111 - enum bch_validate_flags flags, 112 - struct printbuf *err) 110 + int bch2_stripe_validate(struct bch_fs *c, struct bkey_s_c k, 111 + enum bch_validate_flags flags) 113 112 { 114 113 const struct bch_stripe *s = bkey_s_c_to_stripe(k).v; 115 114 int ret = 0; 116 115 117 116 bkey_fsck_err_on(bkey_eq(k.k->p, POS_MIN) || 118 - bpos_gt(k.k->p, POS(0, U32_MAX)), c, err, 119 - stripe_pos_bad, 117 + bpos_gt(k.k->p, POS(0, U32_MAX)), 118 + c, stripe_pos_bad, 120 119 "stripe at bad pos"); 121 120 122 - bkey_fsck_err_on(bkey_val_u64s(k.k) < stripe_val_u64s(s), c, err, 123 - stripe_val_size_bad, 121 + bkey_fsck_err_on(bkey_val_u64s(k.k) < stripe_val_u64s(s), 122 + c, stripe_val_size_bad, 124 123 "incorrect value size (%zu < %u)", 125 124 bkey_val_u64s(k.k), stripe_val_u64s(s)); 126 125 127 - ret = bch2_bkey_ptrs_invalid(c, k, flags, err); 126 + ret = bch2_bkey_ptrs_validate(c, k, flags); 128 127 fsck_err: 129 128 return ret; 130 129 }
+2 -3
fs/bcachefs/ec.h
··· 8 8 9 9 enum bch_validate_flags; 10 10 11 - int bch2_stripe_invalid(struct bch_fs *, struct bkey_s_c, 12 - enum bch_validate_flags, struct printbuf *); 11 + int bch2_stripe_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 13 12 void bch2_stripe_to_text(struct printbuf *, struct bch_fs *, 14 13 struct bkey_s_c); 15 14 int bch2_trigger_stripe(struct btree_trans *, enum btree_id, unsigned, ··· 16 17 enum btree_iter_update_trigger_flags); 17 18 18 19 #define bch2_bkey_ops_stripe ((struct bkey_ops) { \ 19 - .key_invalid = bch2_stripe_invalid, \ 20 + .key_validate = bch2_stripe_validate, \ 20 21 .val_to_text = bch2_stripe_to_text, \ 21 22 .swab = bch2_ptr_swab, \ 22 23 .trigger = bch2_trigger_stripe, \
+1
fs/bcachefs/errcode.h
··· 166 166 x(0, journal_reclaim_would_deadlock) \ 167 167 x(EINVAL, fsck) \ 168 168 x(BCH_ERR_fsck, fsck_fix) \ 169 + x(BCH_ERR_fsck, fsck_delete_bkey) \ 169 170 x(BCH_ERR_fsck, fsck_ignore) \ 170 171 x(BCH_ERR_fsck, fsck_errors_not_fixed) \ 171 172 x(BCH_ERR_fsck, fsck_repair_unimplemented) \
+22
fs/bcachefs/error.c
··· 416 416 return ret; 417 417 } 418 418 419 + int __bch2_bkey_fsck_err(struct bch_fs *c, 420 + struct bkey_s_c k, 421 + enum bch_fsck_flags flags, 422 + enum bch_sb_error_id err, 423 + const char *fmt, ...) 424 + { 425 + struct printbuf buf = PRINTBUF; 426 + va_list args; 427 + 428 + prt_str(&buf, "invalid bkey "); 429 + bch2_bkey_val_to_text(&buf, c, k); 430 + prt_str(&buf, "\n "); 431 + va_start(args, fmt); 432 + prt_vprintf(&buf, fmt, args); 433 + va_end(args); 434 + prt_str(&buf, ": delete?"); 435 + 436 + int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf); 437 + printbuf_exit(&buf); 438 + return ret; 439 + } 440 + 419 441 void bch2_flush_fsck_errs(struct bch_fs *c) 420 442 { 421 443 struct fsck_err_state *s, *n;
+23 -16
fs/bcachefs/error.h
··· 4 4 5 5 #include <linux/list.h> 6 6 #include <linux/printk.h> 7 + #include "bkey_types.h" 7 8 #include "sb-errors.h" 8 9 9 10 struct bch_dev; ··· 167 166 #define fsck_err_on(cond, c, _err_type, ...) \ 168 167 __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__) 169 168 170 - __printf(4, 0) 171 - static inline void bch2_bkey_fsck_err(struct bch_fs *c, 172 - struct printbuf *err_msg, 173 - enum bch_sb_error_id err_type, 174 - const char *fmt, ...) 175 - { 176 - va_list args; 169 + __printf(5, 6) 170 + int __bch2_bkey_fsck_err(struct bch_fs *, 171 + struct bkey_s_c, 172 + enum bch_fsck_flags, 173 + enum bch_sb_error_id, 174 + const char *, ...); 177 175 178 - va_start(args, fmt); 179 - prt_vprintf(err_msg, fmt, args); 180 - va_end(args); 181 - } 182 - 183 - #define bkey_fsck_err(c, _err_msg, _err_type, ...) \ 176 + /* 177 + * for now, bkey fsck errors are always handled by deleting the entire key - 178 + * this will change at some point 179 + */ 180 + #define bkey_fsck_err(c, _err_type, _err_msg, ...) \ 184 181 do { \ 185 - prt_printf(_err_msg, __VA_ARGS__); \ 186 - bch2_sb_error_count(c, BCH_FSCK_ERR_##_err_type); \ 187 - ret = -BCH_ERR_invalid_bkey; \ 182 + if ((flags & BCH_VALIDATE_silent)) { \ 183 + ret = -BCH_ERR_fsck_delete_bkey; \ 184 + goto fsck_err; \ 185 + } \ 186 + int _ret = __bch2_bkey_fsck_err(c, k, FSCK_CAN_FIX, \ 187 + BCH_FSCK_ERR_##_err_type, \ 188 + _err_msg, ##__VA_ARGS__); \ 189 + if (_ret != -BCH_ERR_fsck_fix && \ 190 + _ret != -BCH_ERR_fsck_ignore) \ 191 + ret = _ret; \ 192 + ret = -BCH_ERR_fsck_delete_bkey; \ 188 193 goto fsck_err; \ 189 194 } while (0) 190 195
+72 -72
fs/bcachefs/extents.c
··· 171 171 172 172 /* KEY_TYPE_btree_ptr: */ 173 173 174 - int bch2_btree_ptr_invalid(struct bch_fs *c, struct bkey_s_c k, 175 - enum bch_validate_flags flags, 176 - struct printbuf *err) 174 + int bch2_btree_ptr_validate(struct bch_fs *c, struct bkey_s_c k, 175 + enum bch_validate_flags flags) 177 176 { 178 177 int ret = 0; 179 178 180 - bkey_fsck_err_on(bkey_val_u64s(k.k) > BCH_REPLICAS_MAX, c, err, 181 - btree_ptr_val_too_big, 179 + bkey_fsck_err_on(bkey_val_u64s(k.k) > BCH_REPLICAS_MAX, 180 + c, btree_ptr_val_too_big, 182 181 "value too big (%zu > %u)", bkey_val_u64s(k.k), BCH_REPLICAS_MAX); 183 182 184 - ret = bch2_bkey_ptrs_invalid(c, k, flags, err); 183 + ret = bch2_bkey_ptrs_validate(c, k, flags); 185 184 fsck_err: 186 185 return ret; 187 186 } ··· 191 192 bch2_bkey_ptrs_to_text(out, c, k); 192 193 } 193 194 194 - int bch2_btree_ptr_v2_invalid(struct bch_fs *c, struct bkey_s_c k, 195 - enum bch_validate_flags flags, 196 - struct printbuf *err) 195 + int bch2_btree_ptr_v2_validate(struct bch_fs *c, struct bkey_s_c k, 196 + enum bch_validate_flags flags) 197 197 { 198 198 struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k); 199 199 int ret = 0; 200 200 201 201 bkey_fsck_err_on(bkey_val_u64s(k.k) > BKEY_BTREE_PTR_VAL_U64s_MAX, 202 - c, err, btree_ptr_v2_val_too_big, 202 + c, btree_ptr_v2_val_too_big, 203 203 "value too big (%zu > %zu)", 204 204 bkey_val_u64s(k.k), BKEY_BTREE_PTR_VAL_U64s_MAX); 205 205 206 206 bkey_fsck_err_on(bpos_ge(bp.v->min_key, bp.k->p), 207 - c, err, btree_ptr_v2_min_key_bad, 207 + c, btree_ptr_v2_min_key_bad, 208 208 "min_key > key"); 209 209 210 210 if (flags & BCH_VALIDATE_write) 211 211 bkey_fsck_err_on(!bp.v->sectors_written, 212 - c, err, btree_ptr_v2_written_0, 212 + c, btree_ptr_v2_written_0, 213 213 "sectors_written == 0"); 214 214 215 - ret = bch2_bkey_ptrs_invalid(c, k, flags, err); 215 + ret = bch2_bkey_ptrs_validate(c, k, flags); 216 216 fsck_err: 217 217 return ret; 218 218 } ··· 397 399 398 400 /* KEY_TYPE_reservation: */ 399 401 400 - int bch2_reservation_invalid(struct bch_fs *c, struct bkey_s_c k, 401 - enum bch_validate_flags flags, 402 - struct printbuf *err) 402 + int bch2_reservation_validate(struct bch_fs *c, struct bkey_s_c k, 403 + enum bch_validate_flags flags) 403 404 { 404 405 struct bkey_s_c_reservation r = bkey_s_c_to_reservation(k); 405 406 int ret = 0; 406 407 407 - bkey_fsck_err_on(!r.v->nr_replicas || r.v->nr_replicas > BCH_REPLICAS_MAX, c, err, 408 - reservation_key_nr_replicas_invalid, 408 + bkey_fsck_err_on(!r.v->nr_replicas || r.v->nr_replicas > BCH_REPLICAS_MAX, 409 + c, reservation_key_nr_replicas_invalid, 409 410 "invalid nr_replicas (%u)", r.v->nr_replicas); 410 411 fsck_err: 411 412 return ret; ··· 1099 1102 } 1100 1103 } 1101 1104 1102 - 1103 - static int extent_ptr_invalid(struct bch_fs *c, 1104 - struct bkey_s_c k, 1105 - enum bch_validate_flags flags, 1106 - const struct bch_extent_ptr *ptr, 1107 - unsigned size_ondisk, 1108 - bool metadata, 1109 - struct printbuf *err) 1105 + static int extent_ptr_validate(struct bch_fs *c, 1106 + struct bkey_s_c k, 1107 + enum bch_validate_flags flags, 1108 + const struct bch_extent_ptr *ptr, 1109 + unsigned size_ondisk, 1110 + bool metadata) 1110 1111 { 1111 1112 int ret = 0; 1112 1113 ··· 1123 1128 1124 1129 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); 1125 1130 bkey_for_each_ptr(ptrs, ptr2) 1126 - bkey_fsck_err_on(ptr != ptr2 && ptr->dev == ptr2->dev, c, err, 1127 - ptr_to_duplicate_device, 1131 + bkey_fsck_err_on(ptr != ptr2 && ptr->dev == ptr2->dev, 1132 + c, ptr_to_duplicate_device, 1128 1133 "multiple pointers to same device (%u)", ptr->dev); 1129 1134 1130 1135 1131 - bkey_fsck_err_on(bucket >= nbuckets, c, err, 1132 - ptr_after_last_bucket, 1136 + bkey_fsck_err_on(bucket >= nbuckets, 1137 + c, ptr_after_last_bucket, 1133 1138 "pointer past last bucket (%llu > %llu)", bucket, nbuckets); 1134 - bkey_fsck_err_on(bucket < first_bucket, c, err, 1135 - ptr_before_first_bucket, 1139 + bkey_fsck_err_on(bucket < first_bucket, 1140 + c, ptr_before_first_bucket, 1136 1141 "pointer before first bucket (%llu < %u)", bucket, first_bucket); 1137 - bkey_fsck_err_on(bucket_offset + size_ondisk > bucket_size, c, err, 1138 - ptr_spans_multiple_buckets, 1142 + bkey_fsck_err_on(bucket_offset + size_ondisk > bucket_size, 1143 + c, ptr_spans_multiple_buckets, 1139 1144 "pointer spans multiple buckets (%u + %u > %u)", 1140 1145 bucket_offset, size_ondisk, bucket_size); 1141 1146 fsck_err: 1142 1147 return ret; 1143 1148 } 1144 1149 1145 - int bch2_bkey_ptrs_invalid(struct bch_fs *c, struct bkey_s_c k, 1146 - enum bch_validate_flags flags, 1147 - struct printbuf *err) 1150 + int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k, 1151 + enum bch_validate_flags flags) 1148 1152 { 1149 1153 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); 1150 1154 const union bch_extent_entry *entry; ··· 1158 1164 size_ondisk = btree_sectors(c); 1159 1165 1160 1166 bkey_extent_entry_for_each(ptrs, entry) { 1161 - bkey_fsck_err_on(__extent_entry_type(entry) >= BCH_EXTENT_ENTRY_MAX, c, err, 1162 - extent_ptrs_invalid_entry, 1163 - "invalid extent entry type (got %u, max %u)", 1164 - __extent_entry_type(entry), BCH_EXTENT_ENTRY_MAX); 1167 + bkey_fsck_err_on(__extent_entry_type(entry) >= BCH_EXTENT_ENTRY_MAX, 1168 + c, extent_ptrs_invalid_entry, 1169 + "invalid extent entry type (got %u, max %u)", 1170 + __extent_entry_type(entry), BCH_EXTENT_ENTRY_MAX); 1165 1171 1166 1172 bkey_fsck_err_on(bkey_is_btree_ptr(k.k) && 1167 - !extent_entry_is_ptr(entry), c, err, 1168 - btree_ptr_has_non_ptr, 1173 + !extent_entry_is_ptr(entry), 1174 + c, btree_ptr_has_non_ptr, 1169 1175 "has non ptr field"); 1170 1176 1171 1177 switch (extent_entry_type(entry)) { 1172 1178 case BCH_EXTENT_ENTRY_ptr: 1173 - ret = extent_ptr_invalid(c, k, flags, &entry->ptr, 1174 - size_ondisk, false, err); 1179 + ret = extent_ptr_validate(c, k, flags, &entry->ptr, size_ondisk, false); 1175 1180 if (ret) 1176 1181 return ret; 1177 1182 1178 - bkey_fsck_err_on(entry->ptr.cached && have_ec, c, err, 1179 - ptr_cached_and_erasure_coded, 1183 + bkey_fsck_err_on(entry->ptr.cached && have_ec, 1184 + c, ptr_cached_and_erasure_coded, 1180 1185 "cached, erasure coded ptr"); 1181 1186 1182 1187 if (!entry->ptr.unwritten) ··· 1192 1199 case BCH_EXTENT_ENTRY_crc128: 1193 1200 crc = bch2_extent_crc_unpack(k.k, entry_to_crc(entry)); 1194 1201 1195 - bkey_fsck_err_on(crc.offset + crc.live_size > crc.uncompressed_size, c, err, 1196 - ptr_crc_uncompressed_size_too_small, 1202 + bkey_fsck_err_on(crc.offset + crc.live_size > crc.uncompressed_size, 1203 + c, ptr_crc_uncompressed_size_too_small, 1197 1204 "checksum offset + key size > uncompressed size"); 1198 - bkey_fsck_err_on(!bch2_checksum_type_valid(c, crc.csum_type), c, err, 1199 - ptr_crc_csum_type_unknown, 1205 + bkey_fsck_err_on(!bch2_checksum_type_valid(c, crc.csum_type), 1206 + c, ptr_crc_csum_type_unknown, 1200 1207 "invalid checksum type"); 1201 - bkey_fsck_err_on(crc.compression_type >= BCH_COMPRESSION_TYPE_NR, c, err, 1202 - ptr_crc_compression_type_unknown, 1208 + bkey_fsck_err_on(crc.compression_type >= BCH_COMPRESSION_TYPE_NR, 1209 + c, ptr_crc_compression_type_unknown, 1203 1210 "invalid compression type"); 1204 1211 1205 1212 if (bch2_csum_type_is_encryption(crc.csum_type)) { 1206 1213 if (nonce == UINT_MAX) 1207 1214 nonce = crc.offset + crc.nonce; 1208 1215 else if (nonce != crc.offset + crc.nonce) 1209 - bkey_fsck_err(c, err, ptr_crc_nonce_mismatch, 1216 + bkey_fsck_err(c, ptr_crc_nonce_mismatch, 1210 1217 "incorrect nonce"); 1211 1218 } 1212 1219 1213 - bkey_fsck_err_on(crc_since_last_ptr, c, err, 1214 - ptr_crc_redundant, 1220 + bkey_fsck_err_on(crc_since_last_ptr, 1221 + c, ptr_crc_redundant, 1215 1222 "redundant crc entry"); 1216 1223 crc_since_last_ptr = true; 1217 1224 1218 1225 bkey_fsck_err_on(crc_is_encoded(crc) && 1219 1226 (crc.uncompressed_size > c->opts.encoded_extent_max >> 9) && 1220 - (flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)), c, err, 1221 - ptr_crc_uncompressed_size_too_big, 1227 + (flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)), 1228 + c, ptr_crc_uncompressed_size_too_big, 1222 1229 "too large encoded extent"); 1223 1230 1224 1231 size_ondisk = crc.compressed_size; 1225 1232 break; 1226 1233 case BCH_EXTENT_ENTRY_stripe_ptr: 1227 - bkey_fsck_err_on(have_ec, c, err, 1228 - ptr_stripe_redundant, 1234 + bkey_fsck_err_on(have_ec, 1235 + c, ptr_stripe_redundant, 1229 1236 "redundant stripe entry"); 1230 1237 have_ec = true; 1231 1238 break; 1232 1239 case BCH_EXTENT_ENTRY_rebalance: { 1240 + /* 1241 + * this shouldn't be a fsck error, for forward 1242 + * compatibility; the rebalance code should just refetch 1243 + * the compression opt if it's unknown 1244 + */ 1245 + #if 0 1233 1246 const struct bch_extent_rebalance *r = &entry->rebalance; 1234 1247 1235 1248 if (!bch2_compression_opt_valid(r->compression)) { ··· 1244 1245 opt.type, opt.level); 1245 1246 return -BCH_ERR_invalid_bkey; 1246 1247 } 1248 + #endif 1247 1249 break; 1248 1250 } 1249 1251 } 1250 1252 } 1251 1253 1252 - bkey_fsck_err_on(!nr_ptrs, c, err, 1253 - extent_ptrs_no_ptrs, 1254 + bkey_fsck_err_on(!nr_ptrs, 1255 + c, extent_ptrs_no_ptrs, 1254 1256 "no ptrs"); 1255 - bkey_fsck_err_on(nr_ptrs > BCH_BKEY_PTRS_MAX, c, err, 1256 - extent_ptrs_too_many_ptrs, 1257 + bkey_fsck_err_on(nr_ptrs > BCH_BKEY_PTRS_MAX, 1258 + c, extent_ptrs_too_many_ptrs, 1257 1259 "too many ptrs: %u > %u", nr_ptrs, BCH_BKEY_PTRS_MAX); 1258 - bkey_fsck_err_on(have_written && have_unwritten, c, err, 1259 - extent_ptrs_written_and_unwritten, 1260 + bkey_fsck_err_on(have_written && have_unwritten, 1261 + c, extent_ptrs_written_and_unwritten, 1260 1262 "extent with unwritten and written ptrs"); 1261 - bkey_fsck_err_on(k.k->type != KEY_TYPE_extent && have_unwritten, c, err, 1262 - extent_ptrs_unwritten, 1263 + bkey_fsck_err_on(k.k->type != KEY_TYPE_extent && have_unwritten, 1264 + c, extent_ptrs_unwritten, 1263 1265 "has unwritten ptrs"); 1264 - bkey_fsck_err_on(crc_since_last_ptr, c, err, 1265 - extent_ptrs_redundant_crc, 1266 + bkey_fsck_err_on(crc_since_last_ptr, 1267 + c, extent_ptrs_redundant_crc, 1266 1268 "redundant crc entry"); 1267 - bkey_fsck_err_on(have_ec, c, err, 1268 - extent_ptrs_redundant_stripe, 1269 + bkey_fsck_err_on(have_ec, 1270 + c, extent_ptrs_redundant_stripe, 1269 1271 "redundant stripe entry"); 1270 1272 fsck_err: 1271 1273 return ret;
+12 -12
fs/bcachefs/extents.h
··· 409 409 410 410 /* KEY_TYPE_btree_ptr: */ 411 411 412 - int bch2_btree_ptr_invalid(struct bch_fs *, struct bkey_s_c, 413 - enum bch_validate_flags, struct printbuf *); 412 + int bch2_btree_ptr_validate(struct bch_fs *, struct bkey_s_c, 413 + enum bch_validate_flags); 414 414 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 415 415 struct bkey_s_c); 416 416 417 - int bch2_btree_ptr_v2_invalid(struct bch_fs *, struct bkey_s_c, 418 - enum bch_validate_flags, struct printbuf *); 417 + int bch2_btree_ptr_v2_validate(struct bch_fs *, struct bkey_s_c, 418 + enum bch_validate_flags); 419 419 void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 420 420 void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned, 421 421 int, struct bkey_s); 422 422 423 423 #define bch2_bkey_ops_btree_ptr ((struct bkey_ops) { \ 424 - .key_invalid = bch2_btree_ptr_invalid, \ 424 + .key_validate = bch2_btree_ptr_validate, \ 425 425 .val_to_text = bch2_btree_ptr_to_text, \ 426 426 .swab = bch2_ptr_swab, \ 427 427 .trigger = bch2_trigger_extent, \ 428 428 }) 429 429 430 430 #define bch2_bkey_ops_btree_ptr_v2 ((struct bkey_ops) { \ 431 - .key_invalid = bch2_btree_ptr_v2_invalid, \ 431 + .key_validate = bch2_btree_ptr_v2_validate, \ 432 432 .val_to_text = bch2_btree_ptr_v2_to_text, \ 433 433 .swab = bch2_ptr_swab, \ 434 434 .compat = bch2_btree_ptr_v2_compat, \ ··· 441 441 bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 442 442 443 443 #define bch2_bkey_ops_extent ((struct bkey_ops) { \ 444 - .key_invalid = bch2_bkey_ptrs_invalid, \ 444 + .key_validate = bch2_bkey_ptrs_validate, \ 445 445 .val_to_text = bch2_bkey_ptrs_to_text, \ 446 446 .swab = bch2_ptr_swab, \ 447 447 .key_normalize = bch2_extent_normalize, \ ··· 451 451 452 452 /* KEY_TYPE_reservation: */ 453 453 454 - int bch2_reservation_invalid(struct bch_fs *, struct bkey_s_c, 455 - enum bch_validate_flags, struct printbuf *); 454 + int bch2_reservation_validate(struct bch_fs *, struct bkey_s_c, 455 + enum bch_validate_flags); 456 456 void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 457 457 bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 458 458 459 459 #define bch2_bkey_ops_reservation ((struct bkey_ops) { \ 460 - .key_invalid = bch2_reservation_invalid, \ 460 + .key_validate = bch2_reservation_validate, \ 461 461 .val_to_text = bch2_reservation_to_text, \ 462 462 .key_merge = bch2_reservation_merge, \ 463 463 .trigger = bch2_trigger_reservation, \ ··· 683 683 void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *, const struct bch_extent_ptr *); 684 684 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, 685 685 struct bkey_s_c); 686 - int bch2_bkey_ptrs_invalid(struct bch_fs *, struct bkey_s_c, 687 - enum bch_validate_flags, struct printbuf *); 686 + int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c, 687 + enum bch_validate_flags); 688 688 689 689 void bch2_ptr_swab(struct bkey_s); 690 690
+1 -1
fs/bcachefs/fs.c
··· 193 193 * only insert fully created inodes in the inode hash table. But 194 194 * discard_new_inode() expects it to be set... 195 195 */ 196 - inode->v.i_flags |= I_NEW; 196 + inode->v.i_state |= I_NEW; 197 197 /* 198 198 * We don't want bch2_evict_inode() to delete the inode on disk, 199 199 * we just raced and had another inode in cache. Normally new
+37 -40
fs/bcachefs/inode.c
··· 434 434 return &inode_p->inode.k_i; 435 435 } 436 436 437 - static int __bch2_inode_invalid(struct bch_fs *c, struct bkey_s_c k, struct printbuf *err) 437 + static int __bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k, 438 + enum bch_validate_flags flags) 438 439 { 439 440 struct bch_inode_unpacked unpacked; 440 441 int ret = 0; 441 442 442 - bkey_fsck_err_on(k.k->p.inode, c, err, 443 - inode_pos_inode_nonzero, 443 + bkey_fsck_err_on(k.k->p.inode, 444 + c, inode_pos_inode_nonzero, 444 445 "nonzero k.p.inode"); 445 446 446 - bkey_fsck_err_on(k.k->p.offset < BLOCKDEV_INODE_MAX, c, err, 447 - inode_pos_blockdev_range, 447 + bkey_fsck_err_on(k.k->p.offset < BLOCKDEV_INODE_MAX, 448 + c, inode_pos_blockdev_range, 448 449 "fs inode in blockdev range"); 449 450 450 - bkey_fsck_err_on(bch2_inode_unpack(k, &unpacked), c, err, 451 - inode_unpack_error, 451 + bkey_fsck_err_on(bch2_inode_unpack(k, &unpacked), 452 + c, inode_unpack_error, 452 453 "invalid variable length fields"); 453 454 454 - bkey_fsck_err_on(unpacked.bi_data_checksum >= BCH_CSUM_OPT_NR + 1, c, err, 455 - inode_checksum_type_invalid, 455 + bkey_fsck_err_on(unpacked.bi_data_checksum >= BCH_CSUM_OPT_NR + 1, 456 + c, inode_checksum_type_invalid, 456 457 "invalid data checksum type (%u >= %u", 457 458 unpacked.bi_data_checksum, BCH_CSUM_OPT_NR + 1); 458 459 459 460 bkey_fsck_err_on(unpacked.bi_compression && 460 - !bch2_compression_opt_valid(unpacked.bi_compression - 1), c, err, 461 - inode_compression_type_invalid, 461 + !bch2_compression_opt_valid(unpacked.bi_compression - 1), 462 + c, inode_compression_type_invalid, 462 463 "invalid compression opt %u", unpacked.bi_compression - 1); 463 464 464 465 bkey_fsck_err_on((unpacked.bi_flags & BCH_INODE_unlinked) && 465 - unpacked.bi_nlink != 0, c, err, 466 - inode_unlinked_but_nlink_nonzero, 466 + unpacked.bi_nlink != 0, 467 + c, inode_unlinked_but_nlink_nonzero, 467 468 "flagged as unlinked but bi_nlink != 0"); 468 469 469 - bkey_fsck_err_on(unpacked.bi_subvol && !S_ISDIR(unpacked.bi_mode), c, err, 470 - inode_subvol_root_but_not_dir, 470 + bkey_fsck_err_on(unpacked.bi_subvol && !S_ISDIR(unpacked.bi_mode), 471 + c, inode_subvol_root_but_not_dir, 471 472 "subvolume root but not a directory"); 472 473 fsck_err: 473 474 return ret; 474 475 } 475 476 476 - int bch2_inode_invalid(struct bch_fs *c, struct bkey_s_c k, 477 - enum bch_validate_flags flags, 478 - struct printbuf *err) 477 + int bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k, 478 + enum bch_validate_flags flags) 479 479 { 480 480 struct bkey_s_c_inode inode = bkey_s_c_to_inode(k); 481 481 int ret = 0; 482 482 483 - bkey_fsck_err_on(INODE_STR_HASH(inode.v) >= BCH_STR_HASH_NR, c, err, 484 - inode_str_hash_invalid, 483 + bkey_fsck_err_on(INODE_STR_HASH(inode.v) >= BCH_STR_HASH_NR, 484 + c, inode_str_hash_invalid, 485 485 "invalid str hash type (%llu >= %u)", 486 486 INODE_STR_HASH(inode.v), BCH_STR_HASH_NR); 487 487 488 - ret = __bch2_inode_invalid(c, k, err); 488 + ret = __bch2_inode_validate(c, k, flags); 489 489 fsck_err: 490 490 return ret; 491 491 } 492 492 493 - int bch2_inode_v2_invalid(struct bch_fs *c, struct bkey_s_c k, 494 - enum bch_validate_flags flags, 495 - struct printbuf *err) 493 + int bch2_inode_v2_validate(struct bch_fs *c, struct bkey_s_c k, 494 + enum bch_validate_flags flags) 496 495 { 497 496 struct bkey_s_c_inode_v2 inode = bkey_s_c_to_inode_v2(k); 498 497 int ret = 0; 499 498 500 - bkey_fsck_err_on(INODEv2_STR_HASH(inode.v) >= BCH_STR_HASH_NR, c, err, 501 - inode_str_hash_invalid, 499 + bkey_fsck_err_on(INODEv2_STR_HASH(inode.v) >= BCH_STR_HASH_NR, 500 + c, inode_str_hash_invalid, 502 501 "invalid str hash type (%llu >= %u)", 503 502 INODEv2_STR_HASH(inode.v), BCH_STR_HASH_NR); 504 503 505 - ret = __bch2_inode_invalid(c, k, err); 504 + ret = __bch2_inode_validate(c, k, flags); 506 505 fsck_err: 507 506 return ret; 508 507 } 509 508 510 - int bch2_inode_v3_invalid(struct bch_fs *c, struct bkey_s_c k, 511 - enum bch_validate_flags flags, 512 - struct printbuf *err) 509 + int bch2_inode_v3_validate(struct bch_fs *c, struct bkey_s_c k, 510 + enum bch_validate_flags flags) 513 511 { 514 512 struct bkey_s_c_inode_v3 inode = bkey_s_c_to_inode_v3(k); 515 513 int ret = 0; 516 514 517 515 bkey_fsck_err_on(INODEv3_FIELDS_START(inode.v) < INODEv3_FIELDS_START_INITIAL || 518 - INODEv3_FIELDS_START(inode.v) > bkey_val_u64s(inode.k), c, err, 519 - inode_v3_fields_start_bad, 516 + INODEv3_FIELDS_START(inode.v) > bkey_val_u64s(inode.k), 517 + c, inode_v3_fields_start_bad, 520 518 "invalid fields_start (got %llu, min %u max %zu)", 521 519 INODEv3_FIELDS_START(inode.v), 522 520 INODEv3_FIELDS_START_INITIAL, 523 521 bkey_val_u64s(inode.k)); 524 522 525 - bkey_fsck_err_on(INODEv3_STR_HASH(inode.v) >= BCH_STR_HASH_NR, c, err, 526 - inode_str_hash_invalid, 523 + bkey_fsck_err_on(INODEv3_STR_HASH(inode.v) >= BCH_STR_HASH_NR, 524 + c, inode_str_hash_invalid, 527 525 "invalid str hash type (%llu >= %u)", 528 526 INODEv3_STR_HASH(inode.v), BCH_STR_HASH_NR); 529 527 530 - ret = __bch2_inode_invalid(c, k, err); 528 + ret = __bch2_inode_validate(c, k, flags); 531 529 fsck_err: 532 530 return ret; 533 531 } ··· 623 625 return 0; 624 626 } 625 627 626 - int bch2_inode_generation_invalid(struct bch_fs *c, struct bkey_s_c k, 627 - enum bch_validate_flags flags, 628 - struct printbuf *err) 628 + int bch2_inode_generation_validate(struct bch_fs *c, struct bkey_s_c k, 629 + enum bch_validate_flags flags) 629 630 { 630 631 int ret = 0; 631 632 632 - bkey_fsck_err_on(k.k->p.inode, c, err, 633 - inode_pos_inode_nonzero, 633 + bkey_fsck_err_on(k.k->p.inode, 634 + c, inode_pos_inode_nonzero, 634 635 "nonzero k.p.inode"); 635 636 fsck_err: 636 637 return ret;
+12 -12
fs/bcachefs/inode.h
··· 9 9 enum bch_validate_flags; 10 10 extern const char * const bch2_inode_opts[]; 11 11 12 - int bch2_inode_invalid(struct bch_fs *, struct bkey_s_c, 13 - enum bch_validate_flags, struct printbuf *); 14 - int bch2_inode_v2_invalid(struct bch_fs *, struct bkey_s_c, 15 - enum bch_validate_flags, struct printbuf *); 16 - int bch2_inode_v3_invalid(struct bch_fs *, struct bkey_s_c, 17 - enum bch_validate_flags, struct printbuf *); 12 + int bch2_inode_validate(struct bch_fs *, struct bkey_s_c, 13 + enum bch_validate_flags); 14 + int bch2_inode_v2_validate(struct bch_fs *, struct bkey_s_c, 15 + enum bch_validate_flags); 16 + int bch2_inode_v3_validate(struct bch_fs *, struct bkey_s_c, 17 + enum bch_validate_flags); 18 18 void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 19 19 20 20 int bch2_trigger_inode(struct btree_trans *, enum btree_id, unsigned, ··· 22 22 enum btree_iter_update_trigger_flags); 23 23 24 24 #define bch2_bkey_ops_inode ((struct bkey_ops) { \ 25 - .key_invalid = bch2_inode_invalid, \ 25 + .key_validate = bch2_inode_validate, \ 26 26 .val_to_text = bch2_inode_to_text, \ 27 27 .trigger = bch2_trigger_inode, \ 28 28 .min_val_size = 16, \ 29 29 }) 30 30 31 31 #define bch2_bkey_ops_inode_v2 ((struct bkey_ops) { \ 32 - .key_invalid = bch2_inode_v2_invalid, \ 32 + .key_validate = bch2_inode_v2_validate, \ 33 33 .val_to_text = bch2_inode_to_text, \ 34 34 .trigger = bch2_trigger_inode, \ 35 35 .min_val_size = 32, \ 36 36 }) 37 37 38 38 #define bch2_bkey_ops_inode_v3 ((struct bkey_ops) { \ 39 - .key_invalid = bch2_inode_v3_invalid, \ 39 + .key_validate = bch2_inode_v3_validate, \ 40 40 .val_to_text = bch2_inode_to_text, \ 41 41 .trigger = bch2_trigger_inode, \ 42 42 .min_val_size = 48, \ ··· 49 49 k->type == KEY_TYPE_inode_v3; 50 50 } 51 51 52 - int bch2_inode_generation_invalid(struct bch_fs *, struct bkey_s_c, 53 - enum bch_validate_flags, struct printbuf *); 52 + int bch2_inode_generation_validate(struct bch_fs *, struct bkey_s_c, 53 + enum bch_validate_flags); 54 54 void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 55 55 56 56 #define bch2_bkey_ops_inode_generation ((struct bkey_ops) { \ 57 - .key_invalid = bch2_inode_generation_invalid, \ 57 + .key_validate = bch2_inode_generation_validate, \ 58 58 .val_to_text = bch2_inode_generation_to_text, \ 59 59 .min_val_size = 8, \ 60 60 })
+5 -19
fs/bcachefs/journal_io.c
··· 332 332 { 333 333 int write = flags & BCH_VALIDATE_write; 334 334 void *next = vstruct_next(entry); 335 - struct printbuf buf = PRINTBUF; 336 335 int ret = 0; 337 336 338 337 if (journal_entry_err_on(!k->k.u64s, ··· 367 368 bch2_bkey_compat(level, btree_id, version, big_endian, 368 369 write, NULL, bkey_to_packed(k)); 369 370 370 - if (bch2_bkey_invalid(c, bkey_i_to_s_c(k), 371 - __btree_node_type(level, btree_id), write, &buf)) { 372 - printbuf_reset(&buf); 373 - journal_entry_err_msg(&buf, version, jset, entry); 374 - prt_newline(&buf); 375 - printbuf_indent_add(&buf, 2); 376 - 377 - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k)); 378 - prt_newline(&buf); 379 - bch2_bkey_invalid(c, bkey_i_to_s_c(k), 380 - __btree_node_type(level, btree_id), write, &buf); 381 - 382 - mustfix_fsck_err(c, journal_entry_bkey_invalid, 383 - "%s", buf.buf); 384 - 371 + ret = bch2_bkey_validate(c, bkey_i_to_s_c(k), 372 + __btree_node_type(level, btree_id), write); 373 + if (ret == -BCH_ERR_fsck_delete_bkey) { 385 374 le16_add_cpu(&entry->u64s, -((u16) k->k.u64s)); 386 375 memmove(k, bkey_next(k), next - (void *) bkey_next(k)); 387 376 journal_entry_null_range(vstruct_next(entry), next); 388 - 389 - printbuf_exit(&buf); 390 377 return FSCK_DELETED_KEY; 391 378 } 379 + if (ret) 380 + goto fsck_err; 392 381 393 382 if (write) 394 383 bch2_bkey_compat(level, btree_id, version, big_endian, 395 384 write, NULL, bkey_to_packed(k)); 396 385 fsck_err: 397 - printbuf_exit(&buf); 398 386 return ret; 399 387 } 400 388
+4 -5
fs/bcachefs/lru.c
··· 10 10 #include "recovery.h" 11 11 12 12 /* KEY_TYPE_lru is obsolete: */ 13 - int bch2_lru_invalid(struct bch_fs *c, struct bkey_s_c k, 14 - enum bch_validate_flags flags, 15 - struct printbuf *err) 13 + int bch2_lru_validate(struct bch_fs *c, struct bkey_s_c k, 14 + enum bch_validate_flags flags) 16 15 { 17 16 int ret = 0; 18 17 19 - bkey_fsck_err_on(!lru_pos_time(k.k->p), c, err, 20 - lru_entry_at_time_0, 18 + bkey_fsck_err_on(!lru_pos_time(k.k->p), 19 + c, lru_entry_at_time_0, 21 20 "lru entry at time=0"); 22 21 fsck_err: 23 22 return ret;
+2 -3
fs/bcachefs/lru.h
··· 33 33 return BCH_LRU_read; 34 34 } 35 35 36 - int bch2_lru_invalid(struct bch_fs *, struct bkey_s_c, 37 - enum bch_validate_flags, struct printbuf *); 36 + int bch2_lru_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 38 37 void bch2_lru_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 39 38 40 39 void bch2_lru_pos_to_text(struct printbuf *, struct bpos); 41 40 42 41 #define bch2_bkey_ops_lru ((struct bkey_ops) { \ 43 - .key_invalid = bch2_lru_invalid, \ 42 + .key_validate = bch2_lru_validate, \ 44 43 .val_to_text = bch2_lru_to_text, \ 45 44 .min_val_size = 8, \ 46 45 })
+4 -4
fs/bcachefs/quota.c
··· 59 59 .to_text = bch2_sb_quota_to_text, 60 60 }; 61 61 62 - int bch2_quota_invalid(struct bch_fs *c, struct bkey_s_c k, 63 - enum bch_validate_flags flags, struct printbuf *err) 62 + int bch2_quota_validate(struct bch_fs *c, struct bkey_s_c k, 63 + enum bch_validate_flags flags) 64 64 { 65 65 int ret = 0; 66 66 67 - bkey_fsck_err_on(k.k->p.inode >= QTYP_NR, c, err, 68 - quota_type_invalid, 67 + bkey_fsck_err_on(k.k->p.inode >= QTYP_NR, 68 + c, quota_type_invalid, 69 69 "invalid quota type (%llu >= %u)", 70 70 k.k->p.inode, QTYP_NR); 71 71 fsck_err:
+2 -3
fs/bcachefs/quota.h
··· 8 8 enum bch_validate_flags; 9 9 extern const struct bch_sb_field_ops bch_sb_field_ops_quota; 10 10 11 - int bch2_quota_invalid(struct bch_fs *, struct bkey_s_c, 12 - enum bch_validate_flags, struct printbuf *); 11 + int bch2_quota_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 13 12 void bch2_quota_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 14 13 15 14 #define bch2_bkey_ops_quota ((struct bkey_ops) { \ 16 - .key_invalid = bch2_quota_invalid, \ 15 + .key_validate = bch2_quota_validate, \ 17 16 .val_to_text = bch2_quota_to_text, \ 18 17 .min_val_size = 32, \ 19 18 })
+8 -11
fs/bcachefs/reflink.c
··· 29 29 30 30 /* reflink pointers */ 31 31 32 - int bch2_reflink_p_invalid(struct bch_fs *c, struct bkey_s_c k, 33 - enum bch_validate_flags flags, 34 - struct printbuf *err) 32 + int bch2_reflink_p_validate(struct bch_fs *c, struct bkey_s_c k, 33 + enum bch_validate_flags flags) 35 34 { 36 35 struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k); 37 36 int ret = 0; 38 37 39 38 bkey_fsck_err_on(le64_to_cpu(p.v->idx) < le32_to_cpu(p.v->front_pad), 40 - c, err, reflink_p_front_pad_bad, 39 + c, reflink_p_front_pad_bad, 41 40 "idx < front_pad (%llu < %u)", 42 41 le64_to_cpu(p.v->idx), le32_to_cpu(p.v->front_pad)); 43 42 fsck_err: ··· 255 256 256 257 /* indirect extents */ 257 258 258 - int bch2_reflink_v_invalid(struct bch_fs *c, struct bkey_s_c k, 259 - enum bch_validate_flags flags, 260 - struct printbuf *err) 259 + int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k, 260 + enum bch_validate_flags flags) 261 261 { 262 - return bch2_bkey_ptrs_invalid(c, k, flags, err); 262 + return bch2_bkey_ptrs_validate(c, k, flags); 263 263 } 264 264 265 265 void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c, ··· 309 311 310 312 /* indirect inline data */ 311 313 312 - int bch2_indirect_inline_data_invalid(struct bch_fs *c, struct bkey_s_c k, 313 - enum bch_validate_flags flags, 314 - struct printbuf *err) 314 + int bch2_indirect_inline_data_validate(struct bch_fs *c, struct bkey_s_c k, 315 + enum bch_validate_flags flags) 315 316 { 316 317 return 0; 317 318 }
+9 -13
fs/bcachefs/reflink.h
··· 4 4 5 5 enum bch_validate_flags; 6 6 7 - int bch2_reflink_p_invalid(struct bch_fs *, struct bkey_s_c, 8 - enum bch_validate_flags, struct printbuf *); 9 - void bch2_reflink_p_to_text(struct printbuf *, struct bch_fs *, 10 - struct bkey_s_c); 7 + int bch2_reflink_p_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 8 + void bch2_reflink_p_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 11 9 bool bch2_reflink_p_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 12 10 int bch2_trigger_reflink_p(struct btree_trans *, enum btree_id, unsigned, 13 11 struct bkey_s_c, struct bkey_s, 14 12 enum btree_iter_update_trigger_flags); 15 13 16 14 #define bch2_bkey_ops_reflink_p ((struct bkey_ops) { \ 17 - .key_invalid = bch2_reflink_p_invalid, \ 15 + .key_validate = bch2_reflink_p_validate, \ 18 16 .val_to_text = bch2_reflink_p_to_text, \ 19 17 .key_merge = bch2_reflink_p_merge, \ 20 18 .trigger = bch2_trigger_reflink_p, \ 21 19 .min_val_size = 16, \ 22 20 }) 23 21 24 - int bch2_reflink_v_invalid(struct bch_fs *, struct bkey_s_c, 25 - enum bch_validate_flags, struct printbuf *); 26 - void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *, 27 - struct bkey_s_c); 22 + int bch2_reflink_v_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 23 + void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 28 24 int bch2_trigger_reflink_v(struct btree_trans *, enum btree_id, unsigned, 29 25 struct bkey_s_c, struct bkey_s, 30 26 enum btree_iter_update_trigger_flags); 31 27 32 28 #define bch2_bkey_ops_reflink_v ((struct bkey_ops) { \ 33 - .key_invalid = bch2_reflink_v_invalid, \ 29 + .key_validate = bch2_reflink_v_validate, \ 34 30 .val_to_text = bch2_reflink_v_to_text, \ 35 31 .swab = bch2_ptr_swab, \ 36 32 .trigger = bch2_trigger_reflink_v, \ 37 33 .min_val_size = 8, \ 38 34 }) 39 35 40 - int bch2_indirect_inline_data_invalid(struct bch_fs *, struct bkey_s_c, 41 - enum bch_validate_flags, struct printbuf *); 36 + int bch2_indirect_inline_data_validate(struct bch_fs *, struct bkey_s_c, 37 + enum bch_validate_flags); 42 38 void bch2_indirect_inline_data_to_text(struct printbuf *, 43 39 struct bch_fs *, struct bkey_s_c); 44 40 int bch2_trigger_indirect_inline_data(struct btree_trans *, ··· 43 47 enum btree_iter_update_trigger_flags); 44 48 45 49 #define bch2_bkey_ops_indirect_inline_data ((struct bkey_ops) { \ 46 - .key_invalid = bch2_indirect_inline_data_invalid, \ 50 + .key_validate = bch2_indirect_inline_data_validate, \ 47 51 .val_to_text = bch2_indirect_inline_data_to_text, \ 48 52 .trigger = bch2_trigger_indirect_inline_data, \ 49 53 .min_val_size = 8, \
+5 -1
fs/bcachefs/sb-downgrade.c
··· 72 72 BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0, \ 73 73 BCH_FSCK_ERR_accounting_key_replicas_nr_required_bad, \ 74 74 BCH_FSCK_ERR_accounting_key_replicas_devs_unsorted, \ 75 - BCH_FSCK_ERR_accounting_key_junk_at_end) 75 + BCH_FSCK_ERR_accounting_key_junk_at_end) \ 76 + x(disk_accounting_inum, \ 77 + BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \ 78 + BCH_FSCK_ERR_accounting_mismatch) 76 79 77 80 #define DOWNGRADE_TABLE() \ 78 81 x(bucket_stripe_sectors, \ ··· 107 104 BCH_FSCK_ERR_fs_usage_nr_inodes_wrong, \ 108 105 BCH_FSCK_ERR_fs_usage_persistent_reserved_wrong, \ 109 106 BCH_FSCK_ERR_fs_usage_replicas_wrong, \ 107 + BCH_FSCK_ERR_accounting_replicas_not_marked, \ 110 108 BCH_FSCK_ERR_bkey_version_in_future) 111 109 112 110 struct upgrade_downgrade_entry {
+20 -22
fs/bcachefs/snapshot.c
··· 31 31 le32_to_cpu(t.v->root_snapshot)); 32 32 } 33 33 34 - int bch2_snapshot_tree_invalid(struct bch_fs *c, struct bkey_s_c k, 35 - enum bch_validate_flags flags, 36 - struct printbuf *err) 34 + int bch2_snapshot_tree_validate(struct bch_fs *c, struct bkey_s_c k, 35 + enum bch_validate_flags flags) 37 36 { 38 37 int ret = 0; 39 38 40 39 bkey_fsck_err_on(bkey_gt(k.k->p, POS(0, U32_MAX)) || 41 - bkey_lt(k.k->p, POS(0, 1)), c, err, 42 - snapshot_tree_pos_bad, 40 + bkey_lt(k.k->p, POS(0, 1)), 41 + c, snapshot_tree_pos_bad, 43 42 "bad pos"); 44 43 fsck_err: 45 44 return ret; ··· 224 225 le32_to_cpu(s.v->skip[2])); 225 226 } 226 227 227 - int bch2_snapshot_invalid(struct bch_fs *c, struct bkey_s_c k, 228 - enum bch_validate_flags flags, 229 - struct printbuf *err) 228 + int bch2_snapshot_validate(struct bch_fs *c, struct bkey_s_c k, 229 + enum bch_validate_flags flags) 230 230 { 231 231 struct bkey_s_c_snapshot s; 232 232 u32 i, id; 233 233 int ret = 0; 234 234 235 235 bkey_fsck_err_on(bkey_gt(k.k->p, POS(0, U32_MAX)) || 236 - bkey_lt(k.k->p, POS(0, 1)), c, err, 237 - snapshot_pos_bad, 236 + bkey_lt(k.k->p, POS(0, 1)), 237 + c, snapshot_pos_bad, 238 238 "bad pos"); 239 239 240 240 s = bkey_s_c_to_snapshot(k); 241 241 242 242 id = le32_to_cpu(s.v->parent); 243 - bkey_fsck_err_on(id && id <= k.k->p.offset, c, err, 244 - snapshot_parent_bad, 243 + bkey_fsck_err_on(id && id <= k.k->p.offset, 244 + c, snapshot_parent_bad, 245 245 "bad parent node (%u <= %llu)", 246 246 id, k.k->p.offset); 247 247 248 - bkey_fsck_err_on(le32_to_cpu(s.v->children[0]) < le32_to_cpu(s.v->children[1]), c, err, 249 - snapshot_children_not_normalized, 248 + bkey_fsck_err_on(le32_to_cpu(s.v->children[0]) < le32_to_cpu(s.v->children[1]), 249 + c, snapshot_children_not_normalized, 250 250 "children not normalized"); 251 251 252 - bkey_fsck_err_on(s.v->children[0] && s.v->children[0] == s.v->children[1], c, err, 253 - snapshot_child_duplicate, 252 + bkey_fsck_err_on(s.v->children[0] && s.v->children[0] == s.v->children[1], 253 + c, snapshot_child_duplicate, 254 254 "duplicate child nodes"); 255 255 256 256 for (i = 0; i < 2; i++) { 257 257 id = le32_to_cpu(s.v->children[i]); 258 258 259 - bkey_fsck_err_on(id >= k.k->p.offset, c, err, 260 - snapshot_child_bad, 259 + bkey_fsck_err_on(id >= k.k->p.offset, 260 + c, snapshot_child_bad, 261 261 "bad child node (%u >= %llu)", 262 262 id, k.k->p.offset); 263 263 } 264 264 265 265 if (bkey_val_bytes(k.k) > offsetof(struct bch_snapshot, skip)) { 266 266 bkey_fsck_err_on(le32_to_cpu(s.v->skip[0]) > le32_to_cpu(s.v->skip[1]) || 267 - le32_to_cpu(s.v->skip[1]) > le32_to_cpu(s.v->skip[2]), c, err, 268 - snapshot_skiplist_not_normalized, 267 + le32_to_cpu(s.v->skip[1]) > le32_to_cpu(s.v->skip[2]), 268 + c, snapshot_skiplist_not_normalized, 269 269 "skiplist not normalized"); 270 270 271 271 for (i = 0; i < ARRAY_SIZE(s.v->skip); i++) { 272 272 id = le32_to_cpu(s.v->skip[i]); 273 273 274 - bkey_fsck_err_on(id && id < le32_to_cpu(s.v->parent), c, err, 275 - snapshot_skiplist_bad, 274 + bkey_fsck_err_on(id && id < le32_to_cpu(s.v->parent), 275 + c, snapshot_skiplist_bad, 276 276 "bad skiplist node %u", id); 277 277 } 278 278 }
+5 -6
fs/bcachefs/snapshot.h
··· 5 5 enum bch_validate_flags; 6 6 7 7 void bch2_snapshot_tree_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 8 - int bch2_snapshot_tree_invalid(struct bch_fs *, struct bkey_s_c, 9 - enum bch_validate_flags, struct printbuf *); 8 + int bch2_snapshot_tree_validate(struct bch_fs *, struct bkey_s_c, 9 + enum bch_validate_flags); 10 10 11 11 #define bch2_bkey_ops_snapshot_tree ((struct bkey_ops) { \ 12 - .key_invalid = bch2_snapshot_tree_invalid, \ 12 + .key_validate = bch2_snapshot_tree_validate, \ 13 13 .val_to_text = bch2_snapshot_tree_to_text, \ 14 14 .min_val_size = 8, \ 15 15 }) ··· 19 19 int bch2_snapshot_tree_lookup(struct btree_trans *, u32, struct bch_snapshot_tree *); 20 20 21 21 void bch2_snapshot_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 22 - int bch2_snapshot_invalid(struct bch_fs *, struct bkey_s_c, 23 - enum bch_validate_flags, struct printbuf *); 22 + int bch2_snapshot_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 24 23 int bch2_mark_snapshot(struct btree_trans *, enum btree_id, unsigned, 25 24 struct bkey_s_c, struct bkey_s, 26 25 enum btree_iter_update_trigger_flags); 27 26 28 27 #define bch2_bkey_ops_snapshot ((struct bkey_ops) { \ 29 - .key_invalid = bch2_snapshot_invalid, \ 28 + .key_validate = bch2_snapshot_validate, \ 30 29 .val_to_text = bch2_snapshot_to_text, \ 31 30 .trigger = bch2_mark_snapshot, \ 32 31 .min_val_size = 24, \
+8 -8
fs/bcachefs/subvolume.c
··· 207 207 208 208 /* Subvolumes: */ 209 209 210 - int bch2_subvolume_invalid(struct bch_fs *c, struct bkey_s_c k, 211 - enum bch_validate_flags flags, struct printbuf *err) 210 + int bch2_subvolume_validate(struct bch_fs *c, struct bkey_s_c k, 211 + enum bch_validate_flags flags) 212 212 { 213 213 struct bkey_s_c_subvolume subvol = bkey_s_c_to_subvolume(k); 214 214 int ret = 0; 215 215 216 216 bkey_fsck_err_on(bkey_lt(k.k->p, SUBVOL_POS_MIN) || 217 - bkey_gt(k.k->p, SUBVOL_POS_MAX), c, err, 218 - subvol_pos_bad, 217 + bkey_gt(k.k->p, SUBVOL_POS_MAX), 218 + c, subvol_pos_bad, 219 219 "invalid pos"); 220 220 221 - bkey_fsck_err_on(!subvol.v->snapshot, c, err, 222 - subvol_snapshot_bad, 221 + bkey_fsck_err_on(!subvol.v->snapshot, 222 + c, subvol_snapshot_bad, 223 223 "invalid snapshot"); 224 224 225 - bkey_fsck_err_on(!subvol.v->inode, c, err, 226 - subvol_inode_bad, 225 + bkey_fsck_err_on(!subvol.v->inode, 226 + c, subvol_inode_bad, 227 227 "invalid inode"); 228 228 fsck_err: 229 229 return ret;
+2 -3
fs/bcachefs/subvolume.h
··· 10 10 int bch2_check_subvols(struct bch_fs *); 11 11 int bch2_check_subvol_children(struct bch_fs *); 12 12 13 - int bch2_subvolume_invalid(struct bch_fs *, struct bkey_s_c, 14 - enum bch_validate_flags, struct printbuf *); 13 + int bch2_subvolume_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 15 14 void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 16 15 int bch2_subvolume_trigger(struct btree_trans *, enum btree_id, unsigned, 17 16 struct bkey_s_c, struct bkey_s, 18 17 enum btree_iter_update_trigger_flags); 19 18 20 19 #define bch2_bkey_ops_subvolume ((struct bkey_ops) { \ 21 - .key_invalid = bch2_subvolume_invalid, \ 20 + .key_validate = bch2_subvolume_validate, \ 22 21 .val_to_text = bch2_subvolume_to_text, \ 23 22 .trigger = bch2_subvolume_trigger, \ 24 23 .min_val_size = 16, \
+1
fs/bcachefs/trace.c
··· 4 4 #include "buckets.h" 5 5 #include "btree_cache.h" 6 6 #include "btree_iter.h" 7 + #include "btree_key_cache.h" 7 8 #include "btree_locking.h" 8 9 #include "btree_update_interior.h" 9 10 #include "keylist.h"
+25 -2
fs/bcachefs/trace.h
··· 988 988 __entry->u64s_remaining) 989 989 ); 990 990 991 - DEFINE_EVENT(transaction_event, trans_blocked_journal_reclaim, 991 + TRACE_EVENT(trans_blocked_journal_reclaim, 992 992 TP_PROTO(struct btree_trans *trans, 993 993 unsigned long caller_ip), 994 - TP_ARGS(trans, caller_ip) 994 + TP_ARGS(trans, caller_ip), 995 + 996 + TP_STRUCT__entry( 997 + __array(char, trans_fn, 32 ) 998 + __field(unsigned long, caller_ip ) 999 + 1000 + __field(unsigned long, key_cache_nr_keys ) 1001 + __field(unsigned long, key_cache_nr_dirty ) 1002 + __field(long, must_wait ) 1003 + ), 1004 + 1005 + TP_fast_assign( 1006 + strscpy(__entry->trans_fn, trans->fn, sizeof(__entry->trans_fn)); 1007 + __entry->caller_ip = caller_ip; 1008 + __entry->key_cache_nr_keys = atomic_long_read(&trans->c->btree_key_cache.nr_keys); 1009 + __entry->key_cache_nr_dirty = atomic_long_read(&trans->c->btree_key_cache.nr_dirty); 1010 + __entry->must_wait = __bch2_btree_key_cache_must_wait(trans->c); 1011 + ), 1012 + 1013 + TP_printk("%s %pS key cache keys %lu dirty %lu must_wait %li", 1014 + __entry->trans_fn, (void *) __entry->caller_ip, 1015 + __entry->key_cache_nr_keys, 1016 + __entry->key_cache_nr_dirty, 1017 + __entry->must_wait) 995 1018 ); 996 1019 997 1020 TRACE_EVENT(trans_restart_journal_preres_get,
+10 -11
fs/bcachefs/xattr.c
··· 70 70 .cmp_bkey = xattr_cmp_bkey, 71 71 }; 72 72 73 - int bch2_xattr_invalid(struct bch_fs *c, struct bkey_s_c k, 74 - enum bch_validate_flags flags, 75 - struct printbuf *err) 73 + int bch2_xattr_validate(struct bch_fs *c, struct bkey_s_c k, 74 + enum bch_validate_flags flags) 76 75 { 77 76 struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k); 78 77 unsigned val_u64s = xattr_val_u64s(xattr.v->x_name_len, 79 78 le16_to_cpu(xattr.v->x_val_len)); 80 79 int ret = 0; 81 80 82 - bkey_fsck_err_on(bkey_val_u64s(k.k) < val_u64s, c, err, 83 - xattr_val_size_too_small, 81 + bkey_fsck_err_on(bkey_val_u64s(k.k) < val_u64s, 82 + c, xattr_val_size_too_small, 84 83 "value too small (%zu < %u)", 85 84 bkey_val_u64s(k.k), val_u64s); 86 85 ··· 87 88 val_u64s = xattr_val_u64s(xattr.v->x_name_len, 88 89 le16_to_cpu(xattr.v->x_val_len) + 4); 89 90 90 - bkey_fsck_err_on(bkey_val_u64s(k.k) > val_u64s, c, err, 91 - xattr_val_size_too_big, 91 + bkey_fsck_err_on(bkey_val_u64s(k.k) > val_u64s, 92 + c, xattr_val_size_too_big, 92 93 "value too big (%zu > %u)", 93 94 bkey_val_u64s(k.k), val_u64s); 94 95 95 - bkey_fsck_err_on(!bch2_xattr_type_to_handler(xattr.v->x_type), c, err, 96 - xattr_invalid_type, 96 + bkey_fsck_err_on(!bch2_xattr_type_to_handler(xattr.v->x_type), 97 + c, xattr_invalid_type, 97 98 "invalid type (%u)", xattr.v->x_type); 98 99 99 - bkey_fsck_err_on(memchr(xattr.v->x_name, '\0', xattr.v->x_name_len), c, err, 100 - xattr_name_invalid_chars, 100 + bkey_fsck_err_on(memchr(xattr.v->x_name, '\0', xattr.v->x_name_len), 101 + c, xattr_name_invalid_chars, 101 102 "xattr name has invalid characters"); 102 103 fsck_err: 103 104 return ret;
+2 -3
fs/bcachefs/xattr.h
··· 6 6 7 7 extern const struct bch_hash_desc bch2_xattr_hash_desc; 8 8 9 - int bch2_xattr_invalid(struct bch_fs *, struct bkey_s_c, 10 - enum bch_validate_flags, struct printbuf *); 9 + int bch2_xattr_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags); 11 10 void bch2_xattr_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 12 11 13 12 #define bch2_bkey_ops_xattr ((struct bkey_ops) { \ 14 - .key_invalid = bch2_xattr_invalid, \ 13 + .key_validate = bch2_xattr_validate, \ 15 14 .val_to_text = bch2_xattr_to_text, \ 16 15 .min_val_size = 8, \ 17 16 })
+2
lib/generic-radix-tree.c
··· 121 121 if ((v = cmpxchg_release(&radix->root, r, new_root)) == r) { 122 122 v = new_root; 123 123 new_node = NULL; 124 + } else { 125 + new_node->children[0] = NULL; 124 126 } 125 127 } 126 128