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-2025-05-22' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent Overstreet:
"Small stuff, main ones users will be interested in:

- Couple more casefolding fixes; we can now detect and repair
casefolded dirents in non-casefolded dir and vice versa

- Fix for massive write inflation with mmapped io, which hit certain
databases"

* tag 'bcachefs-2025-05-22' of git://evilpiepirate.org/bcachefs:
bcachefs: Check for casefolded dirents in non casefolded dirs
bcachefs: Fix bch2_dirent_create_snapshot() for casefolding
bcachefs: Fix casefold opt via xattr interface
bcachefs: mkwrite() now only dirties one page
bcachefs: fix extent_has_stripe_ptr()
bcachefs: Fix bch2_btree_path_traverse_cached() when paths realloced

+143 -86
+1 -1
fs/bcachefs/btree_iter.c
··· 1162 1162 } 1163 1163 1164 1164 if (path->cached) { 1165 - ret = bch2_btree_path_traverse_cached(trans, path, flags); 1165 + ret = bch2_btree_path_traverse_cached(trans, path_idx, flags); 1166 1166 goto out; 1167 1167 } 1168 1168
+17 -8
fs/bcachefs/btree_key_cache.c
··· 301 301 } 302 302 303 303 static noinline int btree_key_cache_fill(struct btree_trans *trans, 304 - struct btree_path *ck_path, 304 + btree_path_idx_t ck_path_idx, 305 305 unsigned flags) 306 306 { 307 + struct btree_path *ck_path = trans->paths + ck_path_idx; 308 + 307 309 if (flags & BTREE_ITER_cached_nofill) { 308 310 ck_path->l[0].b = NULL; 309 311 return 0; ··· 327 325 goto err; 328 326 329 327 /* Recheck after btree lookup, before allocating: */ 328 + ck_path = trans->paths + ck_path_idx; 330 329 ret = bch2_btree_key_cache_find(c, ck_path->btree_id, ck_path->pos) ? -EEXIST : 0; 331 330 if (unlikely(ret)) 332 331 goto out; ··· 347 344 } 348 345 349 346 static inline int btree_path_traverse_cached_fast(struct btree_trans *trans, 350 - struct btree_path *path) 347 + btree_path_idx_t path_idx) 351 348 { 352 349 struct bch_fs *c = trans->c; 353 350 struct bkey_cached *ck; 351 + struct btree_path *path = trans->paths + path_idx; 354 352 retry: 355 353 ck = bch2_btree_key_cache_find(c, path->btree_id, path->pos); 356 354 if (!ck) ··· 377 373 return 0; 378 374 } 379 375 380 - int bch2_btree_path_traverse_cached(struct btree_trans *trans, struct btree_path *path, 376 + int bch2_btree_path_traverse_cached(struct btree_trans *trans, 377 + btree_path_idx_t path_idx, 381 378 unsigned flags) 382 379 { 383 - EBUG_ON(path->level); 384 - 385 - path->l[1].b = NULL; 380 + EBUG_ON(trans->paths[path_idx].level); 386 381 387 382 int ret; 388 383 do { 389 - ret = btree_path_traverse_cached_fast(trans, path); 384 + ret = btree_path_traverse_cached_fast(trans, path_idx); 390 385 if (unlikely(ret == -ENOENT)) 391 - ret = btree_key_cache_fill(trans, path, flags); 386 + ret = btree_key_cache_fill(trans, path_idx, flags); 392 387 } while (ret == -EEXIST); 388 + 389 + struct btree_path *path = trans->paths + path_idx; 393 390 394 391 if (unlikely(ret)) { 395 392 path->uptodate = BTREE_ITER_NEED_TRAVERSE; ··· 398 393 btree_node_unlock(trans, path, 0); 399 394 path->l[0].b = ERR_PTR(ret); 400 395 } 396 + } else { 397 + BUG_ON(path->uptodate); 398 + BUG_ON(!path->nodes_locked); 401 399 } 400 + 402 401 return ret; 403 402 } 404 403
+1 -2
fs/bcachefs/btree_key_cache.h
··· 40 40 struct bkey_cached * 41 41 bch2_btree_key_cache_find(struct bch_fs *, enum btree_id, struct bpos); 42 42 43 - int bch2_btree_path_traverse_cached(struct btree_trans *, struct btree_path *, 44 - unsigned); 43 + int bch2_btree_path_traverse_cached(struct btree_trans *, btree_path_idx_t, unsigned); 45 44 46 45 bool bch2_btree_insert_key_cached(struct btree_trans *, unsigned, 47 46 struct btree_insert_entry *);
+15 -18
fs/bcachefs/dirent.c
··· 288 288 } 289 289 290 290 static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans, 291 + const struct bch_hash_info *hash_info, 291 292 subvol_inum dir, 292 293 u8 type, 293 294 const struct qstr *name, ··· 296 295 u64 dst) 297 296 { 298 297 struct bkey_i_dirent *dirent; 298 + struct qstr _cf_name; 299 299 300 300 if (name->len > BCH_NAME_MAX) 301 301 return ERR_PTR(-ENAMETOOLONG); 302 + 303 + if (hash_info->cf_encoding && !cf_name) { 304 + int ret = bch2_casefold(trans, hash_info, name, &_cf_name); 305 + if (ret) 306 + return ERR_PTR(ret); 307 + 308 + cf_name = &_cf_name; 309 + } 302 310 303 311 dirent = dirent_alloc_key(trans, dir, type, name->len, cf_name ? cf_name->len : 0, dst); 304 312 if (IS_ERR(dirent)) ··· 334 324 struct bkey_i_dirent *dirent; 335 325 int ret; 336 326 337 - dirent = dirent_create_key(trans, dir_inum, type, name, NULL, dst_inum); 327 + dirent = dirent_create_key(trans, hash_info, dir_inum, type, name, NULL, dst_inum); 338 328 ret = PTR_ERR_OR_ZERO(dirent); 339 329 if (ret) 340 330 return ret; ··· 343 333 dirent->k.p.snapshot = snapshot; 344 334 345 335 ret = bch2_hash_set_in_snapshot(trans, bch2_dirent_hash_desc, hash_info, 346 - dir_inum, snapshot, &dirent->k_i, 347 - flags|BTREE_UPDATE_internal_snapshot_node); 336 + dir_inum, snapshot, &dirent->k_i, flags); 348 337 *dir_offset = dirent->k.p.offset; 349 338 350 339 return ret; ··· 353 344 const struct bch_hash_info *hash_info, 354 345 u8 type, const struct qstr *name, u64 dst_inum, 355 346 u64 *dir_offset, 356 - u64 *i_size, 357 347 enum btree_iter_update_trigger_flags flags) 358 348 { 359 349 struct bkey_i_dirent *dirent; 360 350 int ret; 361 351 362 - if (hash_info->cf_encoding) { 363 - struct qstr cf_name; 364 - ret = bch2_casefold(trans, hash_info, name, &cf_name); 365 - if (ret) 366 - return ret; 367 - dirent = dirent_create_key(trans, dir, type, name, &cf_name, dst_inum); 368 - } else { 369 - dirent = dirent_create_key(trans, dir, type, name, NULL, dst_inum); 370 - } 371 - 352 + dirent = dirent_create_key(trans, hash_info, dir, type, name, NULL, dst_inum); 372 353 ret = PTR_ERR_OR_ZERO(dirent); 373 354 if (ret) 374 355 return ret; 375 - 376 - *i_size += bkey_bytes(&dirent->k); 377 356 378 357 ret = bch2_hash_set(trans, bch2_dirent_hash_desc, hash_info, 379 358 dir, &dirent->k_i, flags); ··· 463 466 *src_offset = dst_iter.pos.offset; 464 467 465 468 /* Create new dst key: */ 466 - new_dst = dirent_create_key(trans, dst_dir, 0, dst_name, 469 + new_dst = dirent_create_key(trans, dst_hash, dst_dir, 0, dst_name, 467 470 dst_hash->cf_encoding ? &dst_name_lookup : NULL, 0); 468 471 ret = PTR_ERR_OR_ZERO(new_dst); 469 472 if (ret) ··· 474 477 475 478 /* Create new src key: */ 476 479 if (mode == BCH_RENAME_EXCHANGE) { 477 - new_src = dirent_create_key(trans, src_dir, 0, src_name, 480 + new_src = dirent_create_key(trans, src_hash, src_dir, 0, src_name, 478 481 src_hash->cf_encoding ? &src_name_lookup : NULL, 0); 479 482 ret = PTR_ERR_OR_ZERO(new_src); 480 483 if (ret)
+1 -1
fs/bcachefs/dirent.h
··· 65 65 enum btree_iter_update_trigger_flags); 66 66 int bch2_dirent_create(struct btree_trans *, subvol_inum, 67 67 const struct bch_hash_info *, u8, 68 - const struct qstr *, u64, u64 *, u64 *, 68 + const struct qstr *, u64, u64 *, 69 69 enum btree_iter_update_trigger_flags); 70 70 71 71 static inline unsigned vfs_d_type(unsigned type)
+7 -13
fs/bcachefs/ec.c
··· 507 507 508 508 static bool extent_has_stripe_ptr(struct bkey_s_c k, u64 idx) 509 509 { 510 - switch (k.k->type) { 511 - case KEY_TYPE_extent: { 512 - struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 513 - const union bch_extent_entry *entry; 510 + struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); 511 + const union bch_extent_entry *entry; 514 512 515 - extent_for_each_entry(e, entry) 516 - if (extent_entry_type(entry) == 517 - BCH_EXTENT_ENTRY_stripe_ptr && 518 - entry->stripe_ptr.idx == idx) 519 - return true; 520 - 521 - break; 522 - } 523 - } 513 + bkey_extent_entry_for_each(ptrs, entry) 514 + if (extent_entry_type(entry) == 515 + BCH_EXTENT_ENTRY_stripe_ptr && 516 + entry->stripe_ptr.idx == idx) 517 + return true; 524 518 525 519 return false; 526 520 }
-7
fs/bcachefs/extents.h
··· 380 380 381 381 /* Iterate over pointers in KEY_TYPE_extent: */ 382 382 383 - #define extent_for_each_entry_from(_e, _entry, _start) \ 384 - __bkey_extent_entry_for_each_from(_start, \ 385 - extent_entry_last(_e), _entry) 386 - 387 - #define extent_for_each_entry(_e, _entry) \ 388 - extent_for_each_entry_from(_e, _entry, (_e).v->start) 389 - 390 383 #define extent_ptr_next(_e, _ptr) \ 391 384 __bkey_ptr_next(_ptr, extent_entry_last(_e)) 392 385
+11 -7
fs/bcachefs/fs-io-pagecache.c
··· 605 605 struct address_space *mapping = file->f_mapping; 606 606 struct bch_fs *c = inode->v.i_sb->s_fs_info; 607 607 struct bch2_folio_reservation res; 608 - unsigned len; 609 - loff_t isize; 610 608 vm_fault_t ret; 609 + 610 + loff_t file_offset = round_down(vmf->pgoff << PAGE_SHIFT, block_bytes(c)); 611 + unsigned offset = file_offset - folio_pos(folio); 612 + unsigned len = max(PAGE_SIZE, block_bytes(c)); 613 + 614 + BUG_ON(offset + len > folio_size(folio)); 611 615 612 616 bch2_folio_reservation_init(c, inode, &res); 613 617 ··· 627 623 bch2_pagecache_add_get(inode); 628 624 629 625 folio_lock(folio); 630 - isize = i_size_read(&inode->v); 626 + u64 isize = i_size_read(&inode->v); 631 627 632 - if (folio->mapping != mapping || folio_pos(folio) >= isize) { 628 + if (folio->mapping != mapping || file_offset >= isize) { 633 629 folio_unlock(folio); 634 630 ret = VM_FAULT_NOPAGE; 635 631 goto out; 636 632 } 637 633 638 - len = min_t(loff_t, folio_size(folio), isize - folio_pos(folio)); 634 + len = min_t(unsigned, len, isize - file_offset); 639 635 640 636 if (bch2_folio_set(c, inode_inum(inode), &folio, 1) ?: 641 - bch2_folio_reservation_get(c, inode, folio, &res, 0, len)) { 637 + bch2_folio_reservation_get(c, inode, folio, &res, offset, len)) { 642 638 folio_unlock(folio); 643 639 ret = VM_FAULT_SIGBUS; 644 640 goto out; 645 641 } 646 642 647 - bch2_set_folio_dirty(c, inode, folio, &res, 0, len); 643 + bch2_set_folio_dirty(c, inode, folio, &res, offset, len); 648 644 bch2_folio_reservation_put(c, inode, &res); 649 645 650 646 folio_wait_stable(folio);
+1 -25
fs/bcachefs/fs.c
··· 1664 1664 return -EINVAL; 1665 1665 1666 1666 if (s->casefold != bch2_inode_casefold(c, bi)) { 1667 - #ifdef CONFIG_UNICODE 1668 - int ret = 0; 1669 - /* Not supported on individual files. */ 1670 - if (!S_ISDIR(bi->bi_mode)) 1671 - return -EOPNOTSUPP; 1672 - 1673 - /* 1674 - * Make sure the dir is empty, as otherwise we'd need to 1675 - * rehash everything and update the dirent keys. 1676 - */ 1677 - ret = bch2_empty_dir_trans(trans, inode_inum(inode)); 1678 - if (ret < 0) 1679 - return ret; 1680 - 1681 - ret = bch2_request_incompat_feature(c, bcachefs_metadata_version_casefolding); 1667 + int ret = bch2_inode_set_casefold(trans, inode_inum(inode), bi, s->casefold); 1682 1668 if (ret) 1683 1669 return ret; 1684 - 1685 - bch2_check_set_feature(c, BCH_FEATURE_casefolding); 1686 - 1687 - bi->bi_casefold = s->casefold + 1; 1688 - bi->bi_fields_set |= BIT(Inode_opt_casefold); 1689 - 1690 - #else 1691 - printk(KERN_ERR "Cannot use casefolding on a kernel without CONFIG_UNICODE\n"); 1692 - return -EOPNOTSUPP; 1693 - #endif 1694 1670 } 1695 1671 1696 1672 if (s->set_project) {
+37
fs/bcachefs/fsck.c
··· 306 306 &lostfound_str, 307 307 lostfound->bi_inum, 308 308 &lostfound->bi_dir_offset, 309 + BTREE_UPDATE_internal_snapshot_node| 309 310 STR_HASH_must_create) ?: 310 311 bch2_inode_write_flags(trans, &lostfound_iter, lostfound, 311 312 BTREE_UPDATE_internal_snapshot_node); ··· 432 431 &name, 433 432 inode->bi_subvol ?: inode->bi_inum, 434 433 &inode->bi_dir_offset, 434 + BTREE_UPDATE_internal_snapshot_node| 435 435 STR_HASH_must_create); 436 436 if (ret) { 437 437 bch_err_msg(c, ret, "error creating dirent"); ··· 2189 2187 goto out; 2190 2188 2191 2189 struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); 2190 + 2191 + /* check casefold */ 2192 + if (fsck_err_on(d.v->d_casefold != !!hash_info->cf_encoding, 2193 + trans, dirent_casefold_mismatch, 2194 + "dirent casefold does not match dir casefold\n%s", 2195 + (printbuf_reset(&buf), 2196 + bch2_bkey_val_to_text(&buf, c, k), 2197 + buf.buf))) { 2198 + struct qstr name = bch2_dirent_get_name(d); 2199 + u32 subvol = d.v->d_type == DT_SUBVOL 2200 + ? d.v->d_parent_subvol 2201 + : 0; 2202 + u64 target = d.v->d_type == DT_SUBVOL 2203 + ? d.v->d_child_subvol 2204 + : d.v->d_inum; 2205 + u64 dir_offset; 2206 + 2207 + ret = bch2_hash_delete_at(trans, 2208 + bch2_dirent_hash_desc, hash_info, iter, 2209 + BTREE_UPDATE_internal_snapshot_node) ?: 2210 + bch2_dirent_create_snapshot(trans, subvol, 2211 + d.k->p.inode, d.k->p.snapshot, 2212 + hash_info, 2213 + d.v->d_type, 2214 + &name, 2215 + target, 2216 + &dir_offset, 2217 + BTREE_ITER_with_updates| 2218 + BTREE_UPDATE_internal_snapshot_node| 2219 + STR_HASH_must_create) ?: 2220 + bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc); 2221 + 2222 + /* might need another check_dirents pass */ 2223 + goto out; 2224 + } 2192 2225 2193 2226 if (d.v->d_type == DT_SUBVOL) { 2194 2227 ret = check_dirent_to_subvol(trans, iter, d);
+36
fs/bcachefs/inode.c
··· 14 14 #include "extent_update.h" 15 15 #include "fs.h" 16 16 #include "inode.h" 17 + #include "namei.h" 17 18 #include "opts.h" 18 19 #include "str_hash.h" 19 20 #include "snapshot.h" ··· 1203 1202 1204 1203 bch2_inode_opts_get(opts, trans->c, &inode); 1205 1204 return 0; 1205 + } 1206 + 1207 + int bch2_inode_set_casefold(struct btree_trans *trans, subvol_inum inum, 1208 + struct bch_inode_unpacked *bi, unsigned v) 1209 + { 1210 + struct bch_fs *c = trans->c; 1211 + 1212 + #ifdef CONFIG_UNICODE 1213 + int ret = 0; 1214 + /* Not supported on individual files. */ 1215 + if (!S_ISDIR(bi->bi_mode)) 1216 + return -EOPNOTSUPP; 1217 + 1218 + /* 1219 + * Make sure the dir is empty, as otherwise we'd need to 1220 + * rehash everything and update the dirent keys. 1221 + */ 1222 + ret = bch2_empty_dir_trans(trans, inum); 1223 + if (ret < 0) 1224 + return ret; 1225 + 1226 + ret = bch2_request_incompat_feature(c, bcachefs_metadata_version_casefolding); 1227 + if (ret) 1228 + return ret; 1229 + 1230 + bch2_check_set_feature(c, BCH_FEATURE_casefolding); 1231 + 1232 + bi->bi_casefold = v + 1; 1233 + bi->bi_fields_set |= BIT(Inode_opt_casefold); 1234 + 1235 + return 0; 1236 + #else 1237 + bch_err(c, "Cannot use casefolding on a kernel without CONFIG_UNICODE"); 1238 + return -EOPNOTSUPP; 1239 + #endif 1206 1240 } 1207 1241 1208 1242 static noinline int __bch2_inode_rm_snapshot(struct btree_trans *trans, u64 inum, u32 snapshot)
+3 -1
fs/bcachefs/inode.h
··· 292 292 struct bch_opts bch2_inode_opts_to_opts(struct bch_inode_unpacked *); 293 293 void bch2_inode_opts_get(struct bch_io_opts *, struct bch_fs *, 294 294 struct bch_inode_unpacked *); 295 - int bch2_inum_opts_get(struct btree_trans*, subvol_inum, struct bch_io_opts *); 295 + int bch2_inum_opts_get(struct btree_trans *, subvol_inum, struct bch_io_opts *); 296 + int bch2_inode_set_casefold(struct btree_trans *, subvol_inum, 297 + struct bch_inode_unpacked *, unsigned); 296 298 297 299 #include "rebalance.h" 298 300
-2
fs/bcachefs/namei.c
··· 158 158 name, 159 159 dir_target, 160 160 &dir_offset, 161 - &dir_u->bi_size, 162 161 STR_HASH_must_create|BTREE_ITER_with_updates) ?: 163 162 bch2_inode_write(trans, &dir_iter, dir_u); 164 163 if (ret) ··· 224 225 mode_to_type(inode_u->bi_mode), 225 226 name, inum.inum, 226 227 &dir_offset, 227 - &dir_u->bi_size, 228 228 STR_HASH_must_create); 229 229 if (ret) 230 230 goto err;
+7 -1
fs/bcachefs/sb-errors_format.h
··· 209 209 x(subvol_to_missing_root, 188, 0) \ 210 210 x(subvol_root_wrong_bi_subvol, 189, FSCK_AUTOFIX) \ 211 211 x(bkey_in_missing_snapshot, 190, 0) \ 212 + x(bkey_in_deleted_snapshot, 315, 0) \ 212 213 x(inode_pos_inode_nonzero, 191, 0) \ 213 214 x(inode_pos_blockdev_range, 192, 0) \ 214 215 x(inode_alloc_cursor_inode_bad, 301, 0) \ ··· 217 216 x(inode_str_hash_invalid, 194, 0) \ 218 217 x(inode_v3_fields_start_bad, 195, 0) \ 219 218 x(inode_snapshot_mismatch, 196, 0) \ 219 + x(snapshot_key_missing_inode_snapshot, 314, 0) \ 220 220 x(inode_unlinked_but_clean, 197, 0) \ 221 221 x(inode_unlinked_but_nlink_nonzero, 198, 0) \ 222 222 x(inode_unlinked_and_not_open, 281, 0) \ ··· 239 237 x(inode_unreachable, 210, FSCK_AUTOFIX) \ 240 238 x(inode_journal_seq_in_future, 299, FSCK_AUTOFIX) \ 241 239 x(inode_i_sectors_underflow, 312, FSCK_AUTOFIX) \ 240 + x(inode_has_case_insensitive_not_set, 316, FSCK_AUTOFIX) \ 241 + x(inode_parent_has_case_insensitive_not_set, 317, FSCK_AUTOFIX) \ 242 242 x(vfs_inode_i_blocks_underflow, 311, FSCK_AUTOFIX) \ 243 243 x(vfs_inode_i_blocks_not_zero_at_truncate, 313, FSCK_AUTOFIX) \ 244 244 x(deleted_inode_but_clean, 211, FSCK_AUTOFIX) \ ··· 266 262 x(dirent_to_overwritten_inode, 302, 0) \ 267 263 x(dirent_to_missing_subvol, 230, 0) \ 268 264 x(dirent_to_itself, 231, 0) \ 265 + x(dirent_casefold_mismatch, 318, FSCK_AUTOFIX) \ 269 266 x(quota_type_invalid, 232, 0) \ 270 267 x(xattr_val_size_too_small, 233, 0) \ 271 268 x(xattr_val_size_too_big, 234, 0) \ ··· 306 301 x(btree_ptr_v2_written_0, 268, 0) \ 307 302 x(subvol_snapshot_bad, 269, 0) \ 308 303 x(subvol_inode_bad, 270, 0) \ 304 + x(subvol_missing, 308, FSCK_AUTOFIX) \ 309 305 x(alloc_key_stripe_sectors_wrong, 271, FSCK_AUTOFIX) \ 310 306 x(accounting_mismatch, 272, FSCK_AUTOFIX) \ 311 307 x(accounting_replicas_not_marked, 273, 0) \ ··· 328 322 x(dirent_stray_data_after_cf_name, 305, 0) \ 329 323 x(rebalance_work_incorrectly_set, 309, FSCK_AUTOFIX) \ 330 324 x(rebalance_work_incorrectly_unset, 310, FSCK_AUTOFIX) \ 331 - x(MAX, 314, 0) 325 + x(MAX, 319, 0) 332 326 333 327 enum bch_sb_error_id { 334 328 #define x(t, n, ...) BCH_FSCK_ERR_##t = n,
+6
fs/bcachefs/xattr.c
··· 473 473 { 474 474 struct inode_opt_set *s = p; 475 475 476 + if (s->id == Inode_opt_casefold) { 477 + int ret = bch2_inode_set_casefold(trans, inode_inum(inode), bi, s->v); 478 + if (ret) 479 + return ret; 480 + } 481 + 476 482 if (s->defined) 477 483 bi->bi_fields_set |= 1U << s->id; 478 484 else