diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2009-01-25 10:05:07 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-03-12 13:58:07 -0400 |
commit | 3e08613037fd4ec0b716a215602c4bdb3d0d9171 (patch) | |
tree | 3cfb068d7dd1b5e386f6ee6768287aaefa0bcb33 | |
parent | 345c435dbb0b77b00ffe73801102533e24c647af (diff) |
[SCSI] libosd: Add Flush and List-objects support
Add support for the various List-objects commands. List-partitions-in-device,
List-collections-in-partition, List-objects-in-partition,
List-objects-in-collection. All these support partial listing and continuation.
Add support for the different Flush commands and options.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Reviewed-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 6849f269cd1b..5d9457b7e455 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -104,6 +104,16 @@ static bool _osd_req_is_alist_type(struct osd_request *or, | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | /* This is for List-objects not Attributes-Lists */ | ||
108 | static void _osd_req_encode_olist(struct osd_request *or, | ||
109 | struct osd_obj_id_list *list) | ||
110 | { | ||
111 | struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); | ||
112 | |||
113 | cdbh->v1.list_identifier = list->list_identifier; | ||
114 | cdbh->v1.start_address = list->continuation_id; | ||
115 | } | ||
116 | |||
107 | static osd_cdb_offset osd_req_encode_offset(struct osd_request *or, | 117 | static osd_cdb_offset osd_req_encode_offset(struct osd_request *or, |
108 | u64 offset, unsigned *padding) | 118 | u64 offset, unsigned *padding) |
109 | { | 119 | { |
@@ -340,6 +350,29 @@ void osd_req_format(struct osd_request *or, u64 tot_capacity) | |||
340 | } | 350 | } |
341 | EXPORT_SYMBOL(osd_req_format); | 351 | EXPORT_SYMBOL(osd_req_format); |
342 | 352 | ||
353 | int osd_req_list_dev_partitions(struct osd_request *or, | ||
354 | osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem) | ||
355 | { | ||
356 | return osd_req_list_partition_objects(or, 0, initial_id, list, nelem); | ||
357 | } | ||
358 | EXPORT_SYMBOL(osd_req_list_dev_partitions); | ||
359 | |||
360 | static void _osd_req_encode_flush(struct osd_request *or, | ||
361 | enum osd_options_flush_scope_values op) | ||
362 | { | ||
363 | struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb); | ||
364 | |||
365 | ocdb->command_specific_options = op; | ||
366 | } | ||
367 | |||
368 | void osd_req_flush_obsd(struct osd_request *or, | ||
369 | enum osd_options_flush_scope_values op) | ||
370 | { | ||
371 | _osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0); | ||
372 | _osd_req_encode_flush(or, op); | ||
373 | } | ||
374 | EXPORT_SYMBOL(osd_req_flush_obsd); | ||
375 | |||
343 | /* | 376 | /* |
344 | * Partition commands | 377 | * Partition commands |
345 | */ | 378 | */ |
@@ -366,6 +399,88 @@ void osd_req_remove_partition(struct osd_request *or, osd_id partition) | |||
366 | } | 399 | } |
367 | EXPORT_SYMBOL(osd_req_remove_partition); | 400 | EXPORT_SYMBOL(osd_req_remove_partition); |
368 | 401 | ||
402 | static int _osd_req_list_objects(struct osd_request *or, | ||
403 | __be16 action, const struct osd_obj_id *obj, osd_id initial_id, | ||
404 | struct osd_obj_id_list *list, unsigned nelem) | ||
405 | { | ||
406 | struct request_queue *q = or->osd_dev->scsi_device->request_queue; | ||
407 | u64 len = nelem * sizeof(osd_id) + sizeof(*list); | ||
408 | struct bio *bio; | ||
409 | |||
410 | _osd_req_encode_common(or, action, obj, (u64)initial_id, len); | ||
411 | |||
412 | if (list->list_identifier) | ||
413 | _osd_req_encode_olist(or, list); | ||
414 | |||
415 | WARN_ON(or->in.bio); | ||
416 | bio = bio_map_kern(q, list, len, or->alloc_flags); | ||
417 | if (!bio) { | ||
418 | OSD_ERR("!!! Failed to allocate list_objects BIO\n"); | ||
419 | return -ENOMEM; | ||
420 | } | ||
421 | |||
422 | bio->bi_rw &= ~(1 << BIO_RW); | ||
423 | or->in.bio = bio; | ||
424 | or->in.total_bytes = bio->bi_size; | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | int osd_req_list_partition_collections(struct osd_request *or, | ||
429 | osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, | ||
430 | unsigned nelem) | ||
431 | { | ||
432 | struct osd_obj_id par = { | ||
433 | .partition = partition, | ||
434 | .id = 0, | ||
435 | }; | ||
436 | |||
437 | return osd_req_list_collection_objects(or, &par, initial_id, list, | ||
438 | nelem); | ||
439 | } | ||
440 | EXPORT_SYMBOL(osd_req_list_partition_collections); | ||
441 | |||
442 | int osd_req_list_partition_objects(struct osd_request *or, | ||
443 | osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, | ||
444 | unsigned nelem) | ||
445 | { | ||
446 | struct osd_obj_id par = { | ||
447 | .partition = partition, | ||
448 | .id = 0, | ||
449 | }; | ||
450 | |||
451 | return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list, | ||
452 | nelem); | ||
453 | } | ||
454 | EXPORT_SYMBOL(osd_req_list_partition_objects); | ||
455 | |||
456 | void osd_req_flush_partition(struct osd_request *or, | ||
457 | osd_id partition, enum osd_options_flush_scope_values op) | ||
458 | { | ||
459 | _osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition); | ||
460 | _osd_req_encode_flush(or, op); | ||
461 | } | ||
462 | EXPORT_SYMBOL(osd_req_flush_partition); | ||
463 | |||
464 | /* | ||
465 | * Collection commands | ||
466 | */ | ||
467 | int osd_req_list_collection_objects(struct osd_request *or, | ||
468 | const struct osd_obj_id *obj, osd_id initial_id, | ||
469 | struct osd_obj_id_list *list, unsigned nelem) | ||
470 | { | ||
471 | return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj, | ||
472 | initial_id, list, nelem); | ||
473 | } | ||
474 | EXPORT_SYMBOL(osd_req_list_collection_objects); | ||
475 | |||
476 | void osd_req_flush_collection(struct osd_request *or, | ||
477 | const struct osd_obj_id *obj, enum osd_options_flush_scope_values op) | ||
478 | { | ||
479 | _osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0); | ||
480 | _osd_req_encode_flush(or, op); | ||
481 | } | ||
482 | EXPORT_SYMBOL(osd_req_flush_collection); | ||
483 | |||
369 | /* | 484 | /* |
370 | * Object commands | 485 | * Object commands |
371 | */ | 486 | */ |
@@ -392,6 +507,15 @@ void osd_req_write(struct osd_request *or, | |||
392 | } | 507 | } |
393 | EXPORT_SYMBOL(osd_req_write); | 508 | EXPORT_SYMBOL(osd_req_write); |
394 | 509 | ||
510 | void osd_req_flush_object(struct osd_request *or, | ||
511 | const struct osd_obj_id *obj, enum osd_options_flush_scope_values op, | ||
512 | /*V2*/ u64 offset, /*V2*/ u64 len) | ||
513 | { | ||
514 | _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len); | ||
515 | _osd_req_encode_flush(or, op); | ||
516 | } | ||
517 | EXPORT_SYMBOL(osd_req_flush_object); | ||
518 | |||
395 | void osd_req_read(struct osd_request *or, | 519 | void osd_req_read(struct osd_request *or, |
396 | const struct osd_obj_id *obj, struct bio *bio, u64 offset) | 520 | const struct osd_obj_id *obj, struct bio *bio, u64 offset) |
397 | { | 521 | { |