diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-14 15:41:12 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-17 19:49:27 -0800 |
commit | 040c07b61ec438a2e24ac0e6b35bd17230192e04 (patch) | |
tree | 378fca2488ba9d24ef487c668332f29a5773d0a5 | |
parent | 6c83127219ae48d5a7c8e6c30a491bbf3a6ed280 (diff) |
bcachefs: always bounce reads to user memory if encrypted
-rw-r--r-- | fs/bcachefs/io.c | 18 | ||||
-rw-r--r-- | fs/bcachefs/io.h | 1 |
2 files changed, 11 insertions, 8 deletions
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index ddec3bfb1bbb..2b2bae52e85a 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -1050,10 +1050,12 @@ static void __bch_read_endio(struct work_struct *work) * reading into buffers owned by userspace (that userspace can * scribble over) - retry the read, bouncing it this time: */ - if (!rbio->bounce) + if (!rbio->bounce && (rbio->flags & BCH_READ_USER_MAPPED)) { + rbio->flags |= BCH_READ_FORCE_BOUNCE; bch_rbio_retry(c, rbio); - else + } else { bch_rbio_error(rbio, -EIO); + } return; } @@ -1175,6 +1177,8 @@ void bch_read_extent_iter(struct bch_fs *c, struct bch_read_bio *orig, if (pick->crc.compression_type != BCH_COMPRESSION_NONE || (pick->crc.csum_type != BCH_CSUM_NONE && (bvec_iter_sectors(iter) != crc_uncompressed_size(NULL, &pick->crc) || + (bch_csum_type_is_encryption(pick->crc.csum_type) && + (flags & BCH_READ_USER_MAPPED)) || (flags & BCH_READ_FORCE_BOUNCE)))) { read_full = true; bounce = true; @@ -1376,9 +1380,9 @@ void bch_read(struct bch_fs *c, struct bch_read_bio *bio, u64 inode) bch_read_iter(c, bio, bio->bio.bi_iter, inode, BCH_READ_RETRY_IF_STALE| BCH_READ_PROMOTE| - BCH_READ_MAY_REUSE_BIO); + BCH_READ_MAY_REUSE_BIO| + BCH_READ_USER_MAPPED); } -EXPORT_SYMBOL(bch_read); /** * bch_read_retry - re-submit a bio originally from bch_read() @@ -1387,6 +1391,7 @@ static void bch_read_retry(struct bch_fs *c, struct bch_read_bio *rbio) { struct bch_read_bio *parent = bch_rbio_parent(rbio); struct bvec_iter iter = rbio->parent_iter; + unsigned flags = rbio->flags; u64 inode = rbio->inode; trace_bcache_read_retry(&rbio->bio); @@ -1396,10 +1401,7 @@ static void bch_read_retry(struct bch_fs *c, struct bch_read_bio *rbio) else rbio->bio.bi_end_io = rbio->orig_bi_end_io; - bch_read_iter(c, parent, iter, inode, - BCH_READ_FORCE_BOUNCE| - BCH_READ_RETRY_IF_STALE| - BCH_READ_PROMOTE); + bch_read_iter(c, parent, iter, inode, flags); } void bch_read_retry_work(struct work_struct *work) diff --git a/fs/bcachefs/io.h b/fs/bcachefs/io.h index 3d2d81fca297..9239ca4aac16 100644 --- a/fs/bcachefs/io.h +++ b/fs/bcachefs/io.h @@ -70,6 +70,7 @@ enum bch_read_flags { BCH_READ_IS_LAST = 1 << 3, BCH_READ_MAY_REUSE_BIO = 1 << 4, BCH_READ_ACCOUNT_TIMES = 1 << 5, + BCH_READ_USER_MAPPED = 1 << 6, }; void bch_read(struct bch_fs *, struct bch_read_bio *, u64); |