Commit 4a8521b6 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Inodes need extra padding for varint_decode_fast()

Reported-by: syzbot+66b9b74f6520068596a9@syzkaller.appspotmail.com
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent b30b70ad
...@@ -199,9 +199,6 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans, ...@@ -199,9 +199,6 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
u64 new_i_size, u64 new_i_size,
s64 i_sectors_delta) s64 i_sectors_delta)
{ {
struct btree_iter iter;
struct bkey_i *k;
struct bkey_i_inode_v3 *inode;
/* /*
* Crazy performance optimization: * Crazy performance optimization:
* Every extent update needs to also update the inode: the inode trigger * Every extent update needs to also update the inode: the inode trigger
...@@ -214,25 +211,36 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans, ...@@ -214,25 +211,36 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
* lost, but that's fine. * lost, but that's fine.
*/ */
unsigned inode_update_flags = BTREE_UPDATE_NOJOURNAL; unsigned inode_update_flags = BTREE_UPDATE_NOJOURNAL;
int ret;
k = bch2_bkey_get_mut_noupdate(trans, &iter, BTREE_ID_inodes, struct btree_iter iter;
struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
SPOS(0, SPOS(0,
extent_iter->pos.inode, extent_iter->pos.inode,
extent_iter->snapshot), extent_iter->snapshot),
BTREE_ITER_CACHED); BTREE_ITER_CACHED);
ret = PTR_ERR_OR_ZERO(k); int ret = bkey_err(k);
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
if (unlikely(k->k.type != KEY_TYPE_inode_v3)) { /*
k = bch2_inode_to_v3(trans, k); * varint_decode_fast(), in the inode .invalid method, reads up to 7
ret = PTR_ERR_OR_ZERO(k); * bytes past the end of the buffer:
*/
struct bkey_i *k_mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k) + 8);
ret = PTR_ERR_OR_ZERO(k_mut);
if (unlikely(ret))
goto err;
bkey_reassemble(k_mut, k);
if (unlikely(k_mut->k.type != KEY_TYPE_inode_v3)) {
k_mut = bch2_inode_to_v3(trans, k_mut);
ret = PTR_ERR_OR_ZERO(k_mut);
if (unlikely(ret)) if (unlikely(ret))
goto err; goto err;
} }
inode = bkey_i_to_inode_v3(k); struct bkey_i_inode_v3 *inode = bkey_i_to_inode_v3(k_mut);
if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_i_size_dirty) && if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_i_size_dirty) &&
new_i_size > le64_to_cpu(inode->v.bi_size)) { new_i_size > le64_to_cpu(inode->v.bi_size)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment