Commit aaefabc4 authored by Xiubo Li's avatar Xiubo Li Committed by Ilya Dryomov
Browse files

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: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarIlya Dryomov <idryomov@gmail.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent b79e4a0a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
	u64 len = subreq->len;
	bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD);
	u64 off = subreq->start;
	int extent_cnt;

	if (ceph_inode_is_shutdown(inode)) {
		err = -EIO;
@@ -379,7 +380,8 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
	}

	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)
			goto out;
	}
+6 −2
Original line number Diff line number Diff line
@@ -1028,6 +1028,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
		struct ceph_osd_req_op *op;
		u64 read_off = off;
		u64 read_len = len;
		int extent_cnt;

		/* determine new offset/length if encrypted */
		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];
		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) {
				ceph_osdc_put_request(req);
				break;
@@ -1464,6 +1466,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
		ssize_t len;
		struct ceph_osd_req_op *op;
		int readop = sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ;
		int extent_cnt;

		if (write)
			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);
		op = &req->r_ops[0];
		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) {
				ceph_osdc_put_request(req);
				break;
+14 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#define _FS_CEPH_SUPER_H

#include <linux/ceph/ceph_debug.h>
#include <linux/ceph/osd_client.h>

#include <asm/unaligned.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);
}

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,
			      struct ceph_mds_session *session,
			      struct ceph_msg *msg);
+5 −2
Original line number Diff line number Diff line
@@ -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

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);