summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/fsck.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-04-16 21:49:12 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:00 -0400
commite3dc75eb551599c356a9a3f8c00ae6396164457d (patch)
tree91b9559d0eafaa0860752262c53b8c198d890f62 /fs/bcachefs/fsck.c
parent615fccada50247abbc61c6c0a0d9c717b3fb6290 (diff)
downloadlinux-stable-e3dc75eb551599c356a9a3f8c00ae6396164457d.tar.gz
linux-stable-e3dc75eb551599c356a9a3f8c00ae6396164457d.tar.bz2
linux-stable-e3dc75eb551599c356a9a3f8c00ae6396164457d.zip
bcachefs: Fix a null ptr deref in fsck check_extents()
It turns out, in rare situations we need to be passing in a disk reservation, which will be used internally by the transaction commit path when needed. Pass one in... Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fsck.c')
-rw-r--r--fs/bcachefs/fsck.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index ed2523ac2249..6319f2f7b16f 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -3,6 +3,7 @@
#include "bcachefs.h"
#include "bkey_buf.h"
#include "btree_update.h"
+#include "buckets.h"
#include "darray.h"
#include "dirent.h"
#include "error.h"
@@ -1407,6 +1408,7 @@ static int check_extents(struct bch_fs *c)
struct btree_iter iter;
struct bkey_s_c k;
extent_ends extent_ends = { 0 };
+ struct disk_reservation res = { 0 };
int ret = 0;
snapshots_seen_init(&s);
@@ -1417,10 +1419,13 @@ static int check_extents(struct bch_fs *c)
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_extents,
POS(BCACHEFS_ROOT_INO, 0),
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
- NULL, NULL,
- BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
- check_extent(&trans, &iter, k, &w, &s, &extent_ends));
+ &res, NULL,
+ BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL, ({
+ bch2_disk_reservation_put(c, &res);
+ check_extent(&trans, &iter, k, &w, &s, &extent_ends);
+ }));
+ bch2_disk_reservation_put(c, &res);
extent_ends_reset(&extent_ends);
darray_exit(&extent_ends);
inode_walker_exit(&w);