Commit 78beb0ff authored by Luis Henriques's avatar Luis Henriques Committed by Ilya Dryomov
Browse files

ceph: use copy-from2 op in copy_file_range



Instead of using the copy-from operation, switch copy_file_range to the
new copy-from2 operation, which allows to send the truncate_seq and
truncate_size parameters.

If an OSD does not support the copy-from2 operation it will return
-EOPNOTSUPP.  In that case, the kernel client will stop trying to do
remote object copies for this fs client and will always use the generic
VFS copy_file_range.

Signed-off-by: default avatarLuis Henriques <lhenriques@suse.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 045100cd
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -1974,6 +1974,9 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
	if (ceph_test_mount_opt(src_fsc, NOCOPYFROM))
		return -EOPNOTSUPP;

	if (!src_fsc->have_copy_from2)
		return -EOPNOTSUPP;

	/*
	 * Striped file layouts require that we copy partial objects, but the
	 * OSD copy-from operation only supports full-object copies.  Limit
@@ -2101,8 +2104,14 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
			CEPH_OSD_OP_FLAG_FADVISE_NOCACHE,
			&dst_oid, &dst_oloc,
			CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
			CEPH_OSD_OP_FLAG_FADVISE_DONTNEED, 0);
			CEPH_OSD_OP_FLAG_FADVISE_DONTNEED,
			dst_ci->i_truncate_seq, dst_ci->i_truncate_size,
			CEPH_OSD_COPY_FROM_FLAG_TRUNCATE_SEQ);
		if (err) {
			if (err == -EOPNOTSUPP) {
				src_fsc->have_copy_from2 = false;
				pr_notice("OSDs don't support copy-from2; disabling copy offload\n");
			}
			dout("ceph_osdc_copy_from returned %d\n", err);
			if (!ret)
				ret = err;
+1 −0
Original line number Diff line number Diff line
@@ -718,6 +718,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
	fsc->sb = NULL;
	fsc->mount_state = CEPH_MOUNT_MOUNTING;
	fsc->filp_gen = 1;
	fsc->have_copy_from2 = true;

	atomic_long_set(&fsc->writeback_count, 0);

+2 −0
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@ struct ceph_fs_client {
	unsigned long last_auto_reconnect;
	bool blacklisted;

	bool have_copy_from2;

	u32 filp_gen;
	loff_t max_file_size;

+1 −0
Original line number Diff line number Diff line
@@ -534,6 +534,7 @@ int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
			struct ceph_object_id *dst_oid,
			struct ceph_object_locator *dst_oloc,
			u32 dst_fadvise_flags,
			u32 truncate_seq, u64 truncate_size,
			u8 copy_from_flags);

/* watch/notify */
+2 −0
Original line number Diff line number Diff line
@@ -256,6 +256,7 @@ extern const char *ceph_osd_state_name(int s);
									    \
	/* tiering */							    \
	f(COPY_FROM,	__CEPH_OSD_OP(WR, DATA, 26),	"copy-from")	    \
	f(COPY_FROM2,	__CEPH_OSD_OP(WR, DATA, 45),	"copy-from2")	    \
	f(COPY_GET_CLASSIC, __CEPH_OSD_OP(RD, DATA, 27), "copy-get-classic") \
	f(UNDIRTY,	__CEPH_OSD_OP(WR, DATA, 28),	"undirty")	    \
	f(ISDIRTY,	__CEPH_OSD_OP(RD, DATA, 29),	"isdirty")	    \
@@ -446,6 +447,7 @@ enum {
	CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE = 8, /* map snap direct to
						     * cloneid */
	CEPH_OSD_COPY_FROM_FLAG_RWORDERED = 16,     /* order with write */
	CEPH_OSD_COPY_FROM_FLAG_TRUNCATE_SEQ = 32,  /* send truncate_{seq,size} */
};

enum {
Loading