ceph: try to allocate a smaller extent map for sparse read

In fscrypt case and for a smaller read length we can predict the
max count of the extent map. And for small read length use cases
this could save some memories.

[ idryomov: squash into a single patch to avoid build break, drop
  redundant variable in ceph_alloc_sparse_ext_map() ]

Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Xiubo Li 2023-11-07 10:44:41 +08:00 committed by Ilya Dryomov
parent b79e4a0aa9
commit aaefabc4a5
4 changed files with 28 additions and 5 deletions

View File

@ -357,6 +357,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
u64 len = subreq->len; u64 len = subreq->len;
bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD); bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD);
u64 off = subreq->start; u64 off = subreq->start;
int extent_cnt;
if (ceph_inode_is_shutdown(inode)) { if (ceph_inode_is_shutdown(inode)) {
err = -EIO; err = -EIO;
@ -379,7 +380,8 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
} }
if (sparse) { if (sparse) {
err = ceph_alloc_sparse_ext_map(&req->r_ops[0]); extent_cnt = __ceph_sparse_read_ext_count(inode, len);
err = ceph_alloc_sparse_ext_map(&req->r_ops[0], extent_cnt);
if (err) if (err)
goto out; goto out;
} }

View File

@ -1028,6 +1028,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
struct ceph_osd_req_op *op; struct ceph_osd_req_op *op;
u64 read_off = off; u64 read_off = off;
u64 read_len = len; u64 read_len = len;
int extent_cnt;
/* determine new offset/length if encrypted */ /* determine new offset/length if encrypted */
ceph_fscrypt_adjust_off_and_len(inode, &read_off, &read_len); ceph_fscrypt_adjust_off_and_len(inode, &read_off, &read_len);
@ -1067,7 +1068,8 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
op = &req->r_ops[0]; op = &req->r_ops[0];
if (sparse) { if (sparse) {
ret = ceph_alloc_sparse_ext_map(op); extent_cnt = __ceph_sparse_read_ext_count(inode, read_len);
ret = ceph_alloc_sparse_ext_map(op, extent_cnt);
if (ret) { if (ret) {
ceph_osdc_put_request(req); ceph_osdc_put_request(req);
break; break;
@ -1464,6 +1466,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
ssize_t len; ssize_t len;
struct ceph_osd_req_op *op; struct ceph_osd_req_op *op;
int readop = sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ; int readop = sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ;
int extent_cnt;
if (write) if (write)
size = min_t(u64, size, fsc->mount_options->wsize); size = min_t(u64, size, fsc->mount_options->wsize);
@ -1527,7 +1530,8 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len); osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len);
op = &req->r_ops[0]; op = &req->r_ops[0];
if (sparse) { if (sparse) {
ret = ceph_alloc_sparse_ext_map(op); extent_cnt = __ceph_sparse_read_ext_count(inode, size);
ret = ceph_alloc_sparse_ext_map(op, extent_cnt);
if (ret) { if (ret) {
ceph_osdc_put_request(req); ceph_osdc_put_request(req);
break; break;

View File

@ -3,6 +3,7 @@
#define _FS_CEPH_SUPER_H #define _FS_CEPH_SUPER_H
#include <linux/ceph/ceph_debug.h> #include <linux/ceph/ceph_debug.h>
#include <linux/ceph/osd_client.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
@ -1407,6 +1408,19 @@ static inline void __ceph_update_quota(struct ceph_inode_info *ci,
ceph_adjust_quota_realms_count(&ci->netfs.inode, has_quota); ceph_adjust_quota_realms_count(&ci->netfs.inode, has_quota);
} }
static inline int __ceph_sparse_read_ext_count(struct inode *inode, u64 len)
{
int cnt = 0;
if (IS_ENCRYPTED(inode)) {
cnt = len >> CEPH_FSCRYPT_BLOCK_SHIFT;
if (cnt > CEPH_SPARSE_EXT_ARRAY_INITIAL)
cnt = 0;
}
return cnt;
}
extern void ceph_handle_quota(struct ceph_mds_client *mdsc, extern void ceph_handle_quota(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session, struct ceph_mds_session *session,
struct ceph_msg *msg); struct ceph_msg *msg);

View File

@ -572,9 +572,12 @@ int __ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt);
*/ */
#define CEPH_SPARSE_EXT_ARRAY_INITIAL 16 #define CEPH_SPARSE_EXT_ARRAY_INITIAL 16
static inline int ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op) static inline int ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt)
{ {
return __ceph_alloc_sparse_ext_map(op, CEPH_SPARSE_EXT_ARRAY_INITIAL); if (!cnt)
cnt = CEPH_SPARSE_EXT_ARRAY_INITIAL;
return __ceph_alloc_sparse_ext_map(op, cnt);
} }
extern void ceph_osdc_get_request(struct ceph_osd_request *req); extern void ceph_osdc_get_request(struct ceph_osd_request *req);