Skip to content

Commit 23ddf9b

Browse files
Luis Henriquesidryomov
authored andcommitted
libceph: support the RADOS copy-from operation
Add support for performing remote object copies using the 'copy-from' operation. [ Add COPY_FROM to get_num_data_items(). ] Signed-off-by: Luis Henriques <lhenriques@suse.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 2ee9dd9 commit 23ddf9b

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

include/linux/ceph/osd_client.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ struct ceph_osd_req_op {
136136
u64 expected_object_size;
137137
u64 expected_write_size;
138138
} alloc_hint;
139+
struct {
140+
u64 snapid;
141+
u64 src_version;
142+
u8 flags;
143+
u32 src_fadvise_flags;
144+
struct ceph_osd_data osd_data;
145+
} copy_from;
139146
};
140147
};
141148

@@ -510,6 +517,16 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
510517
struct timespec64 *mtime,
511518
struct page **pages, int nr_pages);
512519

520+
int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
521+
u64 src_snapid, u64 src_version,
522+
struct ceph_object_id *src_oid,
523+
struct ceph_object_locator *src_oloc,
524+
u32 src_fadvise_flags,
525+
struct ceph_object_id *dst_oid,
526+
struct ceph_object_locator *dst_oloc,
527+
u32 dst_fadvise_flags,
528+
u8 copy_from_flags);
529+
513530
/* watch/notify */
514531
struct ceph_osd_linger_request *
515532
ceph_osdc_watch(struct ceph_osd_client *osdc,

include/linux/ceph/rados.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@ enum {
410410
enum {
411411
CEPH_OSD_OP_FLAG_EXCL = 1, /* EXCL object create */
412412
CEPH_OSD_OP_FLAG_FAILOK = 2, /* continue despite failure */
413+
CEPH_OSD_OP_FLAG_FADVISE_RANDOM = 0x4, /* the op is random */
414+
CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL = 0x8, /* the op is sequential */
415+
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED = 0x10,/* data will be accessed in
416+
the near future */
417+
CEPH_OSD_OP_FLAG_FADVISE_DONTNEED = 0x20,/* data will not be accessed
418+
in the near future */
419+
CEPH_OSD_OP_FLAG_FADVISE_NOCACHE = 0x40,/* data will be accessed only
420+
once by this client */
413421
};
414422

415423
#define EOLDSNAPC ERESTART /* ORDERSNAP flag set; writer has old snapc*/
@@ -431,6 +439,15 @@ enum {
431439
CEPH_OSD_CMPXATTR_MODE_U64 = 2
432440
};
433441

442+
enum {
443+
CEPH_OSD_COPY_FROM_FLAG_FLUSH = 1, /* part of a flush operation */
444+
CEPH_OSD_COPY_FROM_FLAG_IGNORE_OVERLAY = 2, /* ignore pool overlay */
445+
CEPH_OSD_COPY_FROM_FLAG_IGNORE_CACHE = 4, /* ignore osd cache logic */
446+
CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE = 8, /* map snap direct to
447+
* cloneid */
448+
CEPH_OSD_COPY_FROM_FLAG_RWORDERED = 16, /* order with write */
449+
};
450+
434451
enum {
435452
CEPH_OSD_WATCH_OP_UNWATCH = 0,
436453
CEPH_OSD_WATCH_OP_LEGACY_WATCH = 1,
@@ -497,6 +514,17 @@ struct ceph_osd_op {
497514
__le64 expected_object_size;
498515
__le64 expected_write_size;
499516
} __attribute__ ((packed)) alloc_hint;
517+
struct {
518+
__le64 snapid;
519+
__le64 src_version;
520+
__u8 flags; /* CEPH_OSD_COPY_FROM_FLAG_* */
521+
/*
522+
* CEPH_OSD_OP_FLAG_FADVISE_*: fadvise flags
523+
* for src object, flags for dest object are in
524+
* ceph_osd_op::flags.
525+
*/
526+
__le32 src_fadvise_flags;
527+
} __attribute__ ((packed)) copy_from;
500528
};
501529
__le32 payload_len;
502530
} __attribute__ ((packed));

net/ceph/osd_client.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
410410
case CEPH_OSD_OP_LIST_WATCHERS:
411411
ceph_osd_data_release(&op->list_watchers.response_data);
412412
break;
413+
case CEPH_OSD_OP_COPY_FROM:
414+
ceph_osd_data_release(&op->copy_from.osd_data);
415+
break;
413416
default:
414417
break;
415418
}
@@ -702,6 +705,7 @@ static void get_num_data_items(struct ceph_osd_request *req,
702705
case CEPH_OSD_OP_SETXATTR:
703706
case CEPH_OSD_OP_CMPXATTR:
704707
case CEPH_OSD_OP_NOTIFY_ACK:
708+
case CEPH_OSD_OP_COPY_FROM:
705709
*num_request_data_items += 1;
706710
break;
707711

@@ -1016,6 +1020,14 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst,
10161020
case CEPH_OSD_OP_CREATE:
10171021
case CEPH_OSD_OP_DELETE:
10181022
break;
1023+
case CEPH_OSD_OP_COPY_FROM:
1024+
dst->copy_from.snapid = cpu_to_le64(src->copy_from.snapid);
1025+
dst->copy_from.src_version =
1026+
cpu_to_le64(src->copy_from.src_version);
1027+
dst->copy_from.flags = src->copy_from.flags;
1028+
dst->copy_from.src_fadvise_flags =
1029+
cpu_to_le32(src->copy_from.src_fadvise_flags);
1030+
break;
10191031
default:
10201032
pr_err("unsupported osd opcode %s\n",
10211033
ceph_osd_op_name(src->op));
@@ -1947,6 +1959,10 @@ static void setup_request_data(struct ceph_osd_request *req)
19471959
ceph_osdc_msg_data_add(request_msg,
19481960
&op->notify_ack.request_data);
19491961
break;
1962+
case CEPH_OSD_OP_COPY_FROM:
1963+
ceph_osdc_msg_data_add(request_msg,
1964+
&op->copy_from.osd_data);
1965+
break;
19501966

19511967
/* reply */
19521968
case CEPH_OSD_OP_STAT:
@@ -5255,6 +5271,80 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
52555271
}
52565272
EXPORT_SYMBOL(ceph_osdc_writepages);
52575273

5274+
static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
5275+
u64 src_snapid, u64 src_version,
5276+
struct ceph_object_id *src_oid,
5277+
struct ceph_object_locator *src_oloc,
5278+
u32 src_fadvise_flags,
5279+
u32 dst_fadvise_flags,
5280+
u8 copy_from_flags)
5281+
{
5282+
struct ceph_osd_req_op *op;
5283+
struct page **pages;
5284+
void *p, *end;
5285+
5286+
pages = ceph_alloc_page_vector(1, GFP_KERNEL);
5287+
if (IS_ERR(pages))
5288+
return PTR_ERR(pages);
5289+
5290+
op = _osd_req_op_init(req, 0, CEPH_OSD_OP_COPY_FROM, dst_fadvise_flags);
5291+
op->copy_from.snapid = src_snapid;
5292+
op->copy_from.src_version = src_version;
5293+
op->copy_from.flags = copy_from_flags;
5294+
op->copy_from.src_fadvise_flags = src_fadvise_flags;
5295+
5296+
p = page_address(pages[0]);
5297+
end = p + PAGE_SIZE;
5298+
ceph_encode_string(&p, end, src_oid->name, src_oid->name_len);
5299+
encode_oloc(&p, end, src_oloc);
5300+
op->indata_len = PAGE_SIZE - (end - p);
5301+
5302+
ceph_osd_data_pages_init(&op->copy_from.osd_data, pages,
5303+
op->indata_len, 0, false, true);
5304+
return 0;
5305+
}
5306+
5307+
int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
5308+
u64 src_snapid, u64 src_version,
5309+
struct ceph_object_id *src_oid,
5310+
struct ceph_object_locator *src_oloc,
5311+
u32 src_fadvise_flags,
5312+
struct ceph_object_id *dst_oid,
5313+
struct ceph_object_locator *dst_oloc,
5314+
u32 dst_fadvise_flags,
5315+
u8 copy_from_flags)
5316+
{
5317+
struct ceph_osd_request *req;
5318+
int ret;
5319+
5320+
req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_KERNEL);
5321+
if (!req)
5322+
return -ENOMEM;
5323+
5324+
req->r_flags = CEPH_OSD_FLAG_WRITE;
5325+
5326+
ceph_oloc_copy(&req->r_t.base_oloc, dst_oloc);
5327+
ceph_oid_copy(&req->r_t.base_oid, dst_oid);
5328+
5329+
ret = osd_req_op_copy_from_init(req, src_snapid, src_version, src_oid,
5330+
src_oloc, src_fadvise_flags,
5331+
dst_fadvise_flags, copy_from_flags);
5332+
if (ret)
5333+
goto out;
5334+
5335+
ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
5336+
if (ret)
5337+
goto out;
5338+
5339+
ceph_osdc_start_request(osdc, req, false);
5340+
ret = ceph_osdc_wait_request(osdc, req);
5341+
5342+
out:
5343+
ceph_osdc_put_request(req);
5344+
return ret;
5345+
}
5346+
EXPORT_SYMBOL(ceph_osdc_copy_from);
5347+
52585348
int __init ceph_osdc_setup(void)
52595349
{
52605350
size_t size = sizeof(struct ceph_osd_request) +

0 commit comments

Comments
 (0)