@@ -235,6 +235,15 @@ static void finish_netfs_read(struct
ceph_osd_request *req)
subreq->rreq->origin != NETFS_DIO_READ)
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq-
>flags);
if (IS_ENCRYPTED(inode) && err > 0) {
+ struct ceph_sparse_extent *ext;
+ int i;
+
+ for (i = 0; i < op->extent.sparse_ext_cnt;
i++) {
+ ext = &op->extent.sparse_ext[i];
+ ceph_fscrypt_adjust_off_and_len(inode,
+ &ext->off, &ext->len);
+ }
+
err = ceph_fscrypt_decrypt_extents(inode,
osd_data->pages, subreq-
>start,
op->extent.sparse_ext,
@@ -357,13 +366,12 @@ static void ceph_netfs_issue_read(struct
netfs_io_subrequest *subreq)
if (ceph_has_inline_data(ci) &&
ceph_netfs_issue_op_inline(subreq))
return;
- // TODO: This rounding here is slightly dodgy. It *should*
work, for
- // now, as the cache only deals in blocks that are a multiple
of
- // PAGE_SIZE and fscrypt blocks are at most PAGE_SIZE. What
needs to
- // happen is for the fscrypt driving to be moved into netfslib
and the
- // data in the cache also to be stored encrypted.
+ /*
+ * It needs to provide the real legth (not aligned) for
network subsystem.
+ * Otherwise, ceph_msg_data_cursor_init() triggers BUG_ON() in
the case
+ * if msg->sparse_read_total > msg->data_length.
+ */
len = subreq->len;
- ceph_fscrypt_adjust_off_and_len(inode, &off, &len);
req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
vino,
off, &len, 0, 1, sparse ?
CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ,
@@ -375,6 +383,16 @@ static void ceph_netfs_issue_read(struct
netfs_io_subrequest *subreq)
goto out;
}
+ // TODO: This rounding here is slightly dodgy. It *should*
work, for
+ // now, as the cache only deals in blocks that are a multiple
of
+ // PAGE_SIZE and fscrypt blocks are at most PAGE_SIZE. What
needs to
+ // happen is for the fscrypt driving to be moved into netfslib
and the
+ // data in the cache also to be stored encrypted.
+ ceph_fscrypt_adjust_off_and_len(inode, &off, &len);
+
+ doutc(cl, "%llx.%llx pos=%llu orig_len=%zu len=%llu\n",
+ ceph_vinop(inode), subreq->start, subreq->len, len);
+
if (sparse) {
extent_cnt = __ceph_sparse_read_ext_count(inode, len);
err = ceph_alloc_sparse_ext_map(&req->r_ops[0],
extent_cnt);
@@ -1093,12 +1093,15 @@ ssize_t __ceph_sync_read(struct inode *inode,
loff_t *ki_pos,
u64 read_len = len;
int extent_cnt;
- /* determine new offset/length if encrypted */
- ceph_fscrypt_adjust_off_and_len(inode, &read_off,
&read_len);
-
doutc(cl, "orig %llu~%llu reading %llu~%llu", off,
len,
read_off, read_len);
+ /*
+ * It needs to provide the real legth (not aligned)
for network subsystem.
+ * Otherwise, ceph_msg_data_cursor_init() triggers
BUG_ON() in the case
+ * if msg->sparse_read_total > msg->data_length.