bcachefs: Fix bch2_seek_hole() locking

We can't call bch2_seek_pagecache_hole(), and block on page locks, with
btree locks held.

This is easily fixed because we're at the end of the transaction - we
can just unlock, we don't need a drop_locks_do().

Reported-by: https://github.com/nagalun
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2025-03-27 13:34:13 -04:00
parent 2dd202dbaf
commit 1f4bb8254c

View file

@ -999,17 +999,19 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
POS(inode->v.i_ino, offset >> 9), POS(inode->v.i_ino, offset >> 9),
POS(inode->v.i_ino, U64_MAX), POS(inode->v.i_ino, U64_MAX),
inum.subvol, BTREE_ITER_slots, k, ({ inum.subvol, BTREE_ITER_slots, k, ({
if (k.k->p.inode != inode->v.i_ino) { if (k.k->p.inode != inode->v.i_ino ||
next_hole = bch2_seek_pagecache_hole(&inode->v, !bkey_extent_is_data(k.k)) {
offset, MAX_LFS_FILESIZE, 0, false); loff_t start_offset = k.k->p.inode == inode->v.i_ino
break; ? max(offset, bkey_start_offset(k.k) << 9)
} else if (!bkey_extent_is_data(k.k)) { : offset;
next_hole = bch2_seek_pagecache_hole(&inode->v, loff_t end_offset = k.k->p.inode == inode->v.i_ino
max(offset, bkey_start_offset(k.k) << 9), ? MAX_LFS_FILESIZE
k.k->p.offset << 9, 0, false); : k.k->p.offset << 9;
if (next_hole < k.k->p.offset << 9) bch2_trans_unlock(trans);
break; next_hole = bch2_seek_pagecache_hole(&inode->v,
start_offset, end_offset, 0, false);
break;
} else { } else {
offset = max(offset, bkey_start_offset(k.k) << 9); offset = max(offset, bkey_start_offset(k.k) << 9);
} }