linux/drivers/md/dm-vdo/logical-zone.h
Matthew Sakai 062401f0de dm vdo: add flush support
This patch adds support for handling incoming flush and/or FUA bios. Each
such bio is assigned to a struct vdo_flush. These are allocated as needed,
but there is always one kept in reserve in case allocations fail. In the
event of an allocation failure, bios may need to wait for an outstanding
flush to complete.

The logical address space is partitioned into logical zones, each handled
by its own thread. Each zone keeps a list of all data_vios handling write
requests for logical addresses in that zone. When a flush bio is processed,
each logical zone is informed of the flush. When all of the writes which
are in progress at the time of the notification have completed in all
zones, the flush bio is then allowed to complete.

Co-developed-by: J. corwin Coburn <corwin@hurlbutnet.net>
Signed-off-by: J. corwin Coburn <corwin@hurlbutnet.net>
Co-developed-by: Michael Sclafani <dm-devel@lists.linux.dev>
Signed-off-by: Michael Sclafani <dm-devel@lists.linux.dev>
Co-developed-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Matthew Sakai <msakai@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
2024-02-20 13:43:14 -05:00

90 lines
2.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2023 Red Hat
*/
#ifndef VDO_LOGICAL_ZONE_H
#define VDO_LOGICAL_ZONE_H
#include <linux/list.h>
#include "admin-state.h"
#include "int-map.h"
#include "types.h"
struct physical_zone;
struct logical_zone {
/* The completion for flush notifications */
struct vdo_completion completion;
/* The owner of this zone */
struct logical_zones *zones;
/* Which logical zone this is */
zone_count_t zone_number;
/* The thread id for this zone */
thread_id_t thread_id;
/* In progress operations keyed by LBN */
struct int_map *lbn_operations;
/* The logical to physical map */
struct block_map_zone *block_map_zone;
/* The current flush generation */
sequence_number_t flush_generation;
/*
* The oldest active generation in this zone. This is mutated only on the logical zone
* thread but is queried from the flusher thread.
*/
sequence_number_t oldest_active_generation;
/* The number of IOs in the current flush generation */
block_count_t ios_in_flush_generation;
/* The youngest generation of the current notification */
sequence_number_t notification_generation;
/* Whether a notification is in progress */
bool notifying;
/* The queue of active data write VIOs */
struct list_head write_vios;
/* The administrative state of the zone */
struct admin_state state;
/* The physical zone from which to allocate */
struct physical_zone *allocation_zone;
/* The number of allocations done from the current allocation_zone */
block_count_t allocation_count;
/* The next zone */
struct logical_zone *next;
};
struct logical_zones {
/* The vdo whose zones these are */
struct vdo *vdo;
/* The manager for administrative actions */
struct action_manager *manager;
/* The number of zones */
zone_count_t zone_count;
/* The logical zones themselves */
struct logical_zone zones[];
};
int __must_check vdo_make_logical_zones(struct vdo *vdo,
struct logical_zones **zones_ptr);
void vdo_free_logical_zones(struct logical_zones *zones);
void vdo_drain_logical_zones(struct logical_zones *zones,
const struct admin_state_code *operation,
struct vdo_completion *completion);
void vdo_resume_logical_zones(struct logical_zones *zones,
struct vdo_completion *parent);
void vdo_increment_logical_zone_flush_generation(struct logical_zone *zone,
sequence_number_t expected_generation);
void vdo_acquire_flush_generation_lock(struct data_vio *data_vio);
void vdo_release_flush_generation_lock(struct data_vio *data_vio);
struct physical_zone * __must_check vdo_get_next_allocation_zone(struct logical_zone *zone);
void vdo_dump_logical_zone(const struct logical_zone *zone);
#endif /* VDO_LOGICAL_ZONE_H */