/** * as_logical_zone() - Convert a generic vdo_completion to a logical_zone. * @completion: The completion to convert. * * Return: The completion as a logical_zone.
*/ staticstruct logical_zone *as_logical_zone(struct vdo_completion *completion)
{
vdo_assert_completion_type(completion, VDO_GENERATION_FLUSHED_COMPLETION); return container_of(completion, struct logical_zone, completion);
}
/** * vdo_make_logical_zones() - Create a set of logical zones. * @vdo: The vdo to which the zones will belong. * @zones_ptr: A pointer to hold the new zones. * * Return: VDO_SUCCESS or an error code.
*/ int vdo_make_logical_zones(struct vdo *vdo, struct logical_zones **zones_ptr)
{ struct logical_zones *zones; int result;
zone_count_t zone;
zone_count_t zone_count = vdo->thread_config.logical_zone_count;
if (zone_count == 0) return VDO_SUCCESS;
result = vdo_allocate_extended(struct logical_zones, zone_count, struct logical_zone, __func__, &zones); if (result != VDO_SUCCESS) return result;
zones->vdo = vdo;
zones->zone_count = zone_count; for (zone = 0; zone < zone_count; zone++) {
result = initialize_zone(zones, zone); if (result != VDO_SUCCESS) {
vdo_free_logical_zones(zones); return result;
}
}
result = vdo_make_action_manager(zones->zone_count, get_thread_id_for_zone,
vdo->thread_config.admin_thread, zones, NULL,
vdo, &zones->manager); if (result != VDO_SUCCESS) {
vdo_free_logical_zones(zones); return result;
}
*zones_ptr = zones; return VDO_SUCCESS;
}
/** * vdo_free_logical_zones() - Free a set of logical zones. * @zones: The set of zones to free.
*/ void vdo_free_logical_zones(struct logical_zones *zones)
{
zone_count_t index;
if (zones == NULL) return;
vdo_free(vdo_forget(zones->manager));
for (index = 0; index < zones->zone_count; index++)
vdo_int_map_free(vdo_forget(zones->zones[index].lbn_operations));
vdo_free(zones);
}
staticinlinevoid assert_on_zone_thread(struct logical_zone *zone, constchar *what)
{
VDO_ASSERT_LOG_ONLY((vdo_get_callback_thread_id() == zone->thread_id), "%s() called on correct thread", what);
}
/** * check_for_drain_complete() - Check whether this zone has drained. * @zone: The zone to check.
*/ staticvoid check_for_drain_complete(struct logical_zone *zone)
{ if (!vdo_is_state_draining(&zone->state) || zone->notifying ||
!list_empty(&zone->write_vios)) return;
/** * vdo_resume_logical_zones() - Resume a set of logical zones. * @zones: The logical zones to resume. * @parent: The object to notify when the zones have resumed.
*/ void vdo_resume_logical_zones(struct logical_zones *zones, struct vdo_completion *parent)
{
vdo_schedule_operation(zones->manager, VDO_ADMIN_STATE_RESUMING, NULL,
resume_logical_zone, NULL, parent);
}
/** * update_oldest_active_generation() - Update the oldest active generation. * @zone: The zone. * * Return: true if the oldest active generation has changed.
*/ staticbool update_oldest_active_generation(struct logical_zone *zone)
{ struct data_vio *data_vio =
list_first_entry_or_null(&zone->write_vios, struct data_vio,
write_entry);
sequence_number_t oldest =
(data_vio == NULL) ? zone->flush_generation : data_vio->flush_generation;
if (oldest == zone->oldest_active_generation) returnfalse;
/** * vdo_increment_logical_zone_flush_generation() - Increment the flush generation in a logical * zone. * @zone: The logical zone. * @expected_generation: The expected value of the flush generation before the increment.
*/ void vdo_increment_logical_zone_flush_generation(struct logical_zone *zone,
sequence_number_t expected_generation)
{
assert_on_zone_thread(zone, __func__);
VDO_ASSERT_LOG_ONLY((zone->flush_generation == expected_generation), "logical zone %u flush generation %llu should be %llu before increment",
zone->zone_number, (unsignedlonglong) zone->flush_generation,
(unsignedlonglong) expected_generation);
/** * notify_flusher() - Notify the flush that at least one generation no longer has active VIOs. * @completion: The zone completion. * * This callback is registered in attempt_generation_complete_notification().
*/ staticvoid notify_flusher(struct vdo_completion *completion)
{ struct logical_zone *zone = as_logical_zone(completion);
/** * attempt_generation_complete_notification() - Notify the flusher if some generation no * longer has active VIOs. * @completion: The zone completion.
*/ staticvoid attempt_generation_complete_notification(struct vdo_completion *completion)
{ struct logical_zone *zone = as_logical_zone(completion);
/** * vdo_release_flush_generation_lock() - Release the shared lock on a flush generation held by a * write data_vio. * @data_vio: The data_vio whose lock is to be released. * * If there are pending flushes, and this data_vio completes the oldest generation active in this * zone, an attempt will be made to finish any flushes which may now be complete.
*/ void vdo_release_flush_generation_lock(struct data_vio *data_vio)
{ struct logical_zone *zone = data_vio->logical.zone;
assert_on_zone_thread(zone, __func__);
if (!data_vio_has_flush_generation_lock(data_vio)) return;
list_del_init(&data_vio->write_entry);
VDO_ASSERT_LOG_ONLY((zone->oldest_active_generation <= data_vio->flush_generation), "data_vio releasing lock on generation %llu is not older than oldest active generation %llu",
(unsignedlonglong) data_vio->flush_generation,
(unsignedlonglong) zone->oldest_active_generation);
if (!update_oldest_active_generation(zone) || zone->notifying) return;
/** * vdo_dump_logical_zone() - Dump information about a logical zone to the log for debugging. * @zone: The zone to dump * * Context: the information is dumped in a thread-unsafe fashion. *
*/ void vdo_dump_logical_zone(conststruct logical_zone *zone)
{
vdo_log_info("logical_zone %u", zone->zone_number);
vdo_log_info(" flush_generation=%llu oldest_active_generation=%llu notification_generation=%llu notifying=%s ios_in_flush_generation=%llu",
(unsignedlonglong) READ_ONCE(zone->flush_generation),
(unsignedlonglong) READ_ONCE(zone->oldest_active_generation),
(unsignedlonglong) READ_ONCE(zone->notification_generation),
vdo_bool_to_string(READ_ONCE(zone->notifying)),
(unsignedlonglong) READ_ONCE(zone->ios_in_flush_generation));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.