summaryrefslogtreecommitdiff
path: root/fs/bcachefs/io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-06-30 15:44:11 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:07 -0400
commit077ed08ec7edbcf0bfcadfa01260a5b0cb4ed4db (patch)
treee61508851031360f97793cbc8ea0cc89a29a941a /fs/bcachefs/io.c
parent50ad5d097977dc5c688e7a1a6dc2e74c37da5adf (diff)
downloadlwn-077ed08ec7edbcf0bfcadfa01260a5b0cb4ed4db.tar.gz
lwn-077ed08ec7edbcf0bfcadfa01260a5b0cb4ed4db.zip
bcachefs: Use memalloc_nofs_save() in bch2_read_endio()
This solves a problematic memory allocation in bch2_bio_uncompress() -> vmap(). Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/io.c')
-rw-r--r--fs/bcachefs/io.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index e13382fc5b01..f80b3ce4c7d7 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -1808,8 +1808,11 @@ static void __bch2_read_endio(struct work_struct *work)
struct bvec_iter dst_iter = rbio->bvec_iter;
struct bch_extent_crc_unpacked crc = rbio->pick.crc;
struct nonce nonce = extent_nonce(rbio->version, crc);
+ unsigned nofs_flags;
struct bch_csum csum;
+ nofs_flags = memalloc_nofs_save();
+
/* Reset iterator for checksumming and copying bounced data: */
if (rbio->bounce) {
src->bi_iter.bi_size = crc.compressed_size << 9;
@@ -1874,6 +1877,8 @@ nodecode:
rbio = bch2_rbio_free(rbio);
bch2_rbio_done(rbio);
}
+out:
+ memalloc_nofs_restore(nofs_flags);
return;
csum_err:
/*
@@ -1884,7 +1889,7 @@ csum_err:
if (!rbio->bounce && (rbio->flags & BCH_READ_USER_MAPPED)) {
rbio->flags |= BCH_READ_MUST_BOUNCE;
bch2_rbio_error(rbio, READ_RETRY, BLK_STS_IOERR);
- return;
+ goto out;
}
bch2_dev_inum_io_error(ca, rbio->read_pos.inode, (u64) rbio->bvec_iter.bi_sector,
@@ -1892,12 +1897,12 @@ csum_err:
rbio->pick.crc.csum.hi, rbio->pick.crc.csum.lo,
csum.hi, csum.lo, crc.csum_type);
bch2_rbio_error(rbio, READ_RETRY_AVOID, BLK_STS_IOERR);
- return;
+ goto out;
decompression_err:
bch_err_inum_ratelimited(c, rbio->read_pos.inode,
"decompression error");
bch2_rbio_error(rbio, READ_ERR, BLK_STS_IOERR);
- return;
+ goto out;
}
static void bch2_read_endio(struct bio *bio)