bcachefs fixes for 6.14-rc5
Couple small ones, the main user visible changes/fixes are: - Fix a bug where truncate would rarely fail and return 1 - Revert the directory i_size code: this turned out to have a number of issues that weren't noticed because the fsck code wasn't correctly reporting errors (ouch), and we're late enough in the cycle that it can just wait until 6.15. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEKnAFLkS8Qha+jvQrE6szbY3KbnYFAme/sxYACgkQE6szbY3K bnbxMQ//R1fnDiO51SpBFpNKbhW2XIVPKBJY7DbpG2nhFdcAhuPNeHR4y3+A25Ef 5/swn1z6X77A2QlEUA2KPJR+NHWm5MlBWVAvCZg7hjhZzIAHOje/xCvaQz3FmiYA aHgD9nVVwG6M9bOLN+DCwtLiwxpxHdRWsOnNj4tI/HuXHd889onAmb71nyxjpeol GF6Lj421E82htyH0wPhpb2u95xKwHkfeaMlV0jclSaK8QXZsxY7kDIumXh/SNnUQ FP+JA/zeGnc9oTbBH9C5FX+pyBHSOnb99Rf/YUIEsDpFwk3cKoWAhAI+V+zqcef7 YRUBYnAmOelgk8ssbGF8bCyGvLTlrFYS+AVtOnUKUUZnHG2i8FRrwzR0orJR8RxA qNVIhpt3wGtk1SNqRcAIFGY0TLHnBiMlu4/qvDxLKp4YcaoUn8kJNdyyIT/XKQcG s5mrg2sf8L7/xOQuOgHVd8fzg2HMdkIO7ikWTNr+NSf0cBbwCpWiJZjtbwiRHH7R NAucO1placOZnNs6NgYeusadPn7W7c70rcnRrlHuJxY6626fkmbxK0sjrGy9pHfJ nRzgJY9+87bH2pynxMp0mrvkgiDxfjajxWRJLtrnS8VNebq+b+kdb1/sxIEsiOqi DGHNKjm65TFIHDeqbqx1fKwFDGqS54Som7AZweWVqn3iHz81tf8= =vruy -----END PGP SIGNATURE----- Merge tag 'bcachefs-2025-02-26' of git://evilpiepirate.org/bcachefs Pull bcachefs fixes from Kent Overstreet: "A couple small ones, the main user visible changes/fixes are: - Fix a bug where truncate would rarely fail and return 1 - Revert the directory i_size code: this turned out to have a number of issues that weren't noticed because the fsck code wasn't correctly reporting errors (ouch), and we're late enough in the cycle that it can just wait until 6.15" * tag 'bcachefs-2025-02-26' of git://evilpiepirate.org/bcachefs: bcachefs: Fix truncate sometimes failing and returning 1 bcachefs: Fix deadlock bcachefs: Check for -BCH_ERR_open_buckets_empty in journal resize bcachefs: Revert directory i_size bcachefs: fix bch2_extent_ptr_eq() bcachefs: Fix memmove when move keys down bcachefs: print op->nonce on data update inconsistency
This commit is contained in:
commit
dd83757f6e
15 changed files with 25 additions and 57 deletions
|
@ -203,7 +203,7 @@ struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *c)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bch2_btree_lock_init(&b->c, 0);
|
||||
bch2_btree_lock_init(&b->c, 0, GFP_KERNEL);
|
||||
|
||||
__bch2_btree_node_to_freelist(bc, b);
|
||||
return b;
|
||||
|
@ -795,17 +795,18 @@ struct btree *bch2_btree_node_mem_alloc(struct btree_trans *trans, bool pcpu_rea
|
|||
}
|
||||
|
||||
b = __btree_node_mem_alloc(c, GFP_NOWAIT|__GFP_NOWARN);
|
||||
if (!b) {
|
||||
if (b) {
|
||||
bch2_btree_lock_init(&b->c, pcpu_read_locks ? SIX_LOCK_INIT_PCPU : 0, GFP_NOWAIT);
|
||||
} else {
|
||||
mutex_unlock(&bc->lock);
|
||||
bch2_trans_unlock(trans);
|
||||
b = __btree_node_mem_alloc(c, GFP_KERNEL);
|
||||
if (!b)
|
||||
goto err;
|
||||
bch2_btree_lock_init(&b->c, pcpu_read_locks ? SIX_LOCK_INIT_PCPU : 0, GFP_KERNEL);
|
||||
mutex_lock(&bc->lock);
|
||||
}
|
||||
|
||||
bch2_btree_lock_init(&b->c, pcpu_read_locks ? SIX_LOCK_INIT_PCPU : 0);
|
||||
|
||||
BUG_ON(!six_trylock_intent(&b->c.lock));
|
||||
BUG_ON(!six_trylock_write(&b->c.lock));
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@ drop_this_key:
|
|||
}
|
||||
got_good_key:
|
||||
le16_add_cpu(&i->u64s, -next_good_key);
|
||||
memmove_u64s_down(k, bkey_p_next(k), (u64 *) vstruct_end(i) - (u64 *) k);
|
||||
memmove_u64s_down(k, (u64 *) k + next_good_key, (u64 *) vstruct_end(i) - (u64 *) k);
|
||||
set_btree_node_need_rewrite(b);
|
||||
}
|
||||
fsck_err:
|
||||
|
|
|
@ -156,7 +156,7 @@ bkey_cached_alloc(struct btree_trans *trans, struct btree_path *path, unsigned k
|
|||
}
|
||||
|
||||
if (ck) {
|
||||
bch2_btree_lock_init(&ck->c, pcpu_readers ? SIX_LOCK_INIT_PCPU : 0);
|
||||
bch2_btree_lock_init(&ck->c, pcpu_readers ? SIX_LOCK_INIT_PCPU : 0, GFP_KERNEL);
|
||||
ck->c.cached = true;
|
||||
goto lock;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
static struct lock_class_key bch2_btree_node_lock_key;
|
||||
|
||||
void bch2_btree_lock_init(struct btree_bkey_cached_common *b,
|
||||
enum six_lock_init_flags flags)
|
||||
enum six_lock_init_flags flags,
|
||||
gfp_t gfp)
|
||||
{
|
||||
__six_lock_init(&b->lock, "b->c.lock", &bch2_btree_node_lock_key, flags);
|
||||
__six_lock_init(&b->lock, "b->c.lock", &bch2_btree_node_lock_key, flags, gfp);
|
||||
lockdep_set_notrack_class(&b->lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "btree_iter.h"
|
||||
#include "six.h"
|
||||
|
||||
void bch2_btree_lock_init(struct btree_bkey_cached_common *, enum six_lock_init_flags);
|
||||
void bch2_btree_lock_init(struct btree_bkey_cached_common *, enum six_lock_init_flags, gfp_t gfp);
|
||||
|
||||
void bch2_trans_unlock_noassert(struct btree_trans *);
|
||||
void bch2_trans_unlock_write(struct btree_trans *);
|
||||
|
|
|
@ -340,6 +340,7 @@ restart_drop_extra_replicas:
|
|||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
prt_str(&buf, "about to insert invalid key in data update path");
|
||||
prt_printf(&buf, "\nop.nonce: %u", m->op.nonce);
|
||||
prt_str(&buf, "\nold: ");
|
||||
bch2_bkey_val_to_text(&buf, c, old);
|
||||
prt_str(&buf, "\nk: ");
|
||||
|
|
|
@ -31,11 +31,6 @@ static inline unsigned dirent_val_u64s(unsigned len)
|
|||
sizeof(u64));
|
||||
}
|
||||
|
||||
static inline unsigned int dirent_occupied_size(const struct qstr *name)
|
||||
{
|
||||
return (BKEY_U64s + dirent_val_u64s(name->len)) * sizeof(u64);
|
||||
}
|
||||
|
||||
int bch2_dirent_read_target(struct btree_trans *, subvol_inum,
|
||||
struct bkey_s_c_dirent, subvol_inum *);
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1,
|
|||
ptr1.unwritten == ptr2.unwritten &&
|
||||
ptr1.offset == ptr2.offset &&
|
||||
ptr1.dev == ptr2.dev &&
|
||||
ptr1.dev == ptr2.dev);
|
||||
ptr1.gen == ptr2.gen);
|
||||
}
|
||||
|
||||
void bch2_ptr_swab(struct bkey_s);
|
||||
|
|
|
@ -152,7 +152,6 @@ int bch2_create_trans(struct btree_trans *trans,
|
|||
if (is_subdir_for_nlink(new_inode))
|
||||
dir_u->bi_nlink++;
|
||||
dir_u->bi_mtime = dir_u->bi_ctime = now;
|
||||
dir_u->bi_size += dirent_occupied_size(name);
|
||||
|
||||
ret = bch2_inode_write(trans, &dir_iter, dir_u);
|
||||
if (ret)
|
||||
|
@ -221,7 +220,6 @@ int bch2_link_trans(struct btree_trans *trans,
|
|||
}
|
||||
|
||||
dir_u->bi_mtime = dir_u->bi_ctime = now;
|
||||
dir_u->bi_size += dirent_occupied_size(name);
|
||||
|
||||
dir_hash = bch2_hash_info_init(c, dir_u);
|
||||
|
||||
|
@ -324,7 +322,6 @@ int bch2_unlink_trans(struct btree_trans *trans,
|
|||
|
||||
dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now;
|
||||
dir_u->bi_nlink -= is_subdir_for_nlink(inode_u);
|
||||
dir_u->bi_size -= dirent_occupied_size(name);
|
||||
|
||||
ret = bch2_hash_delete_at(trans, bch2_dirent_hash_desc,
|
||||
&dir_hash, &dirent_iter,
|
||||
|
@ -463,14 +460,6 @@ int bch2_rename_trans(struct btree_trans *trans,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (mode == BCH_RENAME) {
|
||||
src_dir_u->bi_size -= dirent_occupied_size(src_name);
|
||||
dst_dir_u->bi_size += dirent_occupied_size(dst_name);
|
||||
}
|
||||
|
||||
if (mode == BCH_RENAME_OVERWRITE)
|
||||
src_dir_u->bi_size -= dirent_occupied_size(src_name);
|
||||
|
||||
if (src_inode_u->bi_parent_subvol)
|
||||
src_inode_u->bi_parent_subvol = dst_dir.subvol;
|
||||
|
||||
|
|
|
@ -466,6 +466,7 @@ int bchfs_truncate(struct mnt_idmap *idmap,
|
|||
ret = bch2_truncate_folio(inode, iattr->ia_size);
|
||||
if (unlikely(ret < 0))
|
||||
goto err;
|
||||
ret = 0;
|
||||
|
||||
truncate_setsize(&inode->v, iattr->ia_size);
|
||||
|
||||
|
|
|
@ -1978,31 +1978,10 @@ fsck_err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int check_dir_i_size_notnested(struct btree_trans *trans, struct inode_walker *w)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
int ret = 0;
|
||||
|
||||
darray_for_each(w->inodes, i)
|
||||
if (fsck_err_on(i->inode.bi_size != i->i_size,
|
||||
trans, inode_dir_wrong_nlink,
|
||||
"directory %llu:%u with wrong i_size: got %llu, should be %llu",
|
||||
w->last_pos.inode, i->snapshot, i->inode.bi_size, i->i_size)) {
|
||||
i->inode.bi_size = i->i_size;
|
||||
ret = bch2_fsck_write_inode(trans, &i->inode);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
fsck_err:
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_subdir_dirents_count(struct btree_trans *trans, struct inode_walker *w)
|
||||
{
|
||||
u32 restart_count = trans->restart_count;
|
||||
return check_subdir_count_notnested(trans, w) ?:
|
||||
check_dir_i_size_notnested(trans, w) ?:
|
||||
trans_was_restarted(trans, restart_count);
|
||||
}
|
||||
|
||||
|
|
|
@ -1194,7 +1194,9 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
|
|||
|
||||
closure_sync(&cl);
|
||||
|
||||
if (ret && ret != -BCH_ERR_bucket_alloc_blocked)
|
||||
if (ret &&
|
||||
ret != -BCH_ERR_bucket_alloc_blocked &&
|
||||
ret != -BCH_ERR_open_buckets_empty)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,10 +90,7 @@
|
|||
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
|
||||
BCH_FSCK_ERR_accounting_mismatch, \
|
||||
BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0, \
|
||||
BCH_FSCK_ERR_accounting_key_junk_at_end) \
|
||||
x(directory_size, \
|
||||
BIT_ULL(BCH_RECOVERY_PASS_check_dirents), \
|
||||
BCH_FSCK_ERR_directory_size_mismatch) \
|
||||
BCH_FSCK_ERR_accounting_key_junk_at_end)
|
||||
|
||||
#define DOWNGRADE_TABLE() \
|
||||
x(bucket_stripe_sectors, \
|
||||
|
|
|
@ -850,7 +850,8 @@ void six_lock_exit(struct six_lock *lock)
|
|||
EXPORT_SYMBOL_GPL(six_lock_exit);
|
||||
|
||||
void __six_lock_init(struct six_lock *lock, const char *name,
|
||||
struct lock_class_key *key, enum six_lock_init_flags flags)
|
||||
struct lock_class_key *key, enum six_lock_init_flags flags,
|
||||
gfp_t gfp)
|
||||
{
|
||||
atomic_set(&lock->state, 0);
|
||||
raw_spin_lock_init(&lock->wait_lock);
|
||||
|
@ -873,7 +874,7 @@ void __six_lock_init(struct six_lock *lock, const char *name,
|
|||
* failure if they wish by checking lock->readers, but generally
|
||||
* will not want to treat it as an error.
|
||||
*/
|
||||
lock->readers = alloc_percpu(unsigned);
|
||||
lock->readers = alloc_percpu_gfp(unsigned, gfp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -164,18 +164,19 @@ enum six_lock_init_flags {
|
|||
};
|
||||
|
||||
void __six_lock_init(struct six_lock *lock, const char *name,
|
||||
struct lock_class_key *key, enum six_lock_init_flags flags);
|
||||
struct lock_class_key *key, enum six_lock_init_flags flags,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* six_lock_init - initialize a six lock
|
||||
* @lock: lock to initialize
|
||||
* @flags: optional flags, i.e. SIX_LOCK_INIT_PCPU
|
||||
*/
|
||||
#define six_lock_init(lock, flags) \
|
||||
#define six_lock_init(lock, flags, gfp) \
|
||||
do { \
|
||||
static struct lock_class_key __key; \
|
||||
\
|
||||
__six_lock_init((lock), #lock, &__key, flags); \
|
||||
__six_lock_init((lock), #lock, &__key, flags, gfp); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue