@@ -410,6 +410,9 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
410
410
case CEPH_OSD_OP_LIST_WATCHERS :
411
411
ceph_osd_data_release (& op -> list_watchers .response_data );
412
412
break ;
413
+ case CEPH_OSD_OP_COPY_FROM :
414
+ ceph_osd_data_release (& op -> copy_from .osd_data );
415
+ break ;
413
416
default :
414
417
break ;
415
418
}
@@ -702,6 +705,7 @@ static void get_num_data_items(struct ceph_osd_request *req,
702
705
case CEPH_OSD_OP_SETXATTR :
703
706
case CEPH_OSD_OP_CMPXATTR :
704
707
case CEPH_OSD_OP_NOTIFY_ACK :
708
+ case CEPH_OSD_OP_COPY_FROM :
705
709
* num_request_data_items += 1 ;
706
710
break ;
707
711
@@ -1016,6 +1020,14 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst,
1016
1020
case CEPH_OSD_OP_CREATE :
1017
1021
case CEPH_OSD_OP_DELETE :
1018
1022
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 ;
1019
1031
default :
1020
1032
pr_err ("unsupported osd opcode %s\n" ,
1021
1033
ceph_osd_op_name (src -> op ));
@@ -1947,6 +1959,10 @@ static void setup_request_data(struct ceph_osd_request *req)
1947
1959
ceph_osdc_msg_data_add (request_msg ,
1948
1960
& op -> notify_ack .request_data );
1949
1961
break ;
1962
+ case CEPH_OSD_OP_COPY_FROM :
1963
+ ceph_osdc_msg_data_add (request_msg ,
1964
+ & op -> copy_from .osd_data );
1965
+ break ;
1950
1966
1951
1967
/* reply */
1952
1968
case CEPH_OSD_OP_STAT :
@@ -5255,6 +5271,80 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
5255
5271
}
5256
5272
EXPORT_SYMBOL (ceph_osdc_writepages );
5257
5273
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
+
5258
5348
int __init ceph_osdc_setup (void )
5259
5349
{
5260
5350
size_t size = sizeof (struct ceph_osd_request ) +
0 commit comments