summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-03-14 15:41:12 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2017-03-17 19:49:27 -0800
commit040c07b61ec438a2e24ac0e6b35bd17230192e04 (patch)
tree378fca2488ba9d24ef487c668332f29a5773d0a5
parent6c83127219ae48d5a7c8e6c30a491bbf3a6ed280 (diff)
bcachefs: always bounce reads to user memory if encrypted
-rw-r--r--fs/bcachefs/io.c18
-rw-r--r--fs/bcachefs/io.h1
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);