#ifndef VDO_H
#define VDO_H
#include <linux/atomic.h>
#include <linux/blk_types.h>
#include <linux/completion.h>
#include <linux/dm-kcopyd.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include "admin-state.h"
#include "encodings.h"
#include "funnel-workqueue.h"
#include "packer.h"
#include "physical-zone.h"
#include "statistics.h"
#include "thread-registry.h"
#include "types.h"
enum notifier_state {
MAY_NOTIFY,
NOTIFYING,
MAY_NOT_NOTIFY,
NOTIFIED,
};
typedef void (*vdo_read_only_notification_fn)(void *listener, struct vdo_completion *parent);
struct read_only_listener {
void *listener;
vdo_read_only_notification_fn notify;
struct read_only_listener *next;
};
struct vdo_thread {
struct vdo *vdo;
thread_id_t thread_id;
struct vdo_work_queue *queue;
bool is_read_only;
struct read_only_listener *listeners;
struct registered_thread allocating_thread;
};
struct atomic_bio_stats {
atomic64_t read;
atomic64_t write;
atomic64_t discard;
atomic64_t flush;
atomic64_t empty_flush;
atomic64_t fua;
};
struct atomic_statistics {
atomic64_t bios_submitted;
atomic64_t bios_completed;
atomic64_t flush_out;
atomic64_t invalid_advice_pbn_count;
atomic64_t no_space_error_count;
atomic64_t read_only_error_count;
struct atomic_bio_stats bios_in;
struct atomic_bio_stats bios_in_partial;
struct atomic_bio_stats bios_out;
struct atomic_bio_stats bios_out_completed;
struct atomic_bio_stats bios_acknowledged;
struct atomic_bio_stats bios_acknowledged_partial;
struct atomic_bio_stats bios_meta;
struct atomic_bio_stats bios_meta_completed;
struct atomic_bio_stats bios_journal;
struct atomic_bio_stats bios_journal_completed;
struct atomic_bio_stats bios_page_cache;
struct atomic_bio_stats bios_page_cache_completed;
};
struct read_only_notifier {
struct vdo_completion completion;
struct vdo_completion *waiter;
spinlock_t lock;
int read_only_error;
enum notifier_state state;
};
#define VDO_INVALID_THREAD_ID ((thread_id_t) -1)
struct thread_config {
zone_count_t logical_zone_count;
zone_count_t physical_zone_count;
zone_count_t hash_zone_count;
thread_count_t bio_thread_count;
thread_count_t thread_count;
thread_id_t admin_thread;
thread_id_t journal_thread;
thread_id_t packer_thread;
thread_id_t dedupe_thread;
thread_id_t bio_ack_thread;
thread_id_t cpu_thread;
thread_id_t *logical_threads;
thread_id_t *physical_threads;
thread_id_t *hash_zone_threads;
thread_id_t *bio_threads;
};
struct thread_count_config;
struct vdo_super_block {
struct vio vio;
u8 *buffer;
bool unwritable;
};
struct data_vio_pool;
struct vdo_administrator {
struct vdo_completion completion;
struct admin_state state;
atomic_t busy;
u32 phase;
struct completion callback_sync;
};
struct vdo {
char thread_name_prefix[MAX_VDO_WORK_QUEUE_NAME_LEN];
struct vdo_thread *threads;
vdo_action_fn action;
struct vdo_completion *completion;
struct vio_tracer *vio_tracer;
atomic_t state;
struct vdo_component_states states;
unsigned int instance;
struct read_only_notifier read_only_notifier;
struct device_config *device_config;
struct thread_config thread_config;
struct vdo_super_block super_block;
struct layout layout;
struct layout next_layout;
struct dm_kcopyd_client *partition_copier;
struct block_map *block_map;
struct recovery_journal *recovery_journal;
struct slab_depot *depot;
struct packer *packer;
bool compressing;
struct flusher *flusher;
enum vdo_state load_state;
struct logical_zones *logical_zones;
struct physical_zones *physical_zones;
struct hash_zones *hash_zones;
struct io_submitter *io_submitter;
struct data_vio_pool *data_vio_pool;
struct vdo_administrator admin;
const struct admin_state_code *suspend_type;
bool allocations_allowed;
bool dump_on_shutdown;
atomic_t processing_message;
struct atomic_statistics stats;
struct vdo_statistics stats_buffer;
struct mutex stats_mutex;
struct list_head device_config_list;
struct list_head registration;
u64 starting_sector_offset;
struct volume_geometry geometry;
char **compression_context;
};
static inline bool vdo_uses_bio_ack_queue(struct vdo *vdo)
{
return vdo->device_config->thread_counts.bio_ack_threads > 0;
}
typedef bool (*vdo_filter_fn)(struct vdo *vdo, const void *context);
void vdo_initialize_device_registry_once(void);
struct vdo * __must_check vdo_find_matching(vdo_filter_fn filter, const void *context);
int __must_check vdo_make_thread(struct vdo *vdo, thread_id_t thread_id,
const struct vdo_work_queue_type *type,
unsigned int queue_count, void *contexts[]);
static inline int __must_check vdo_make_default_thread(struct vdo *vdo,
thread_id_t thread_id)
{
return vdo_make_thread(vdo, thread_id, NULL, 1, NULL);
}
int __must_check vdo_make(unsigned int instance, struct device_config *config,
char **reason, struct vdo **vdo_ptr);
void vdo_destroy(struct vdo *vdo);
void vdo_load_super_block(struct vdo *vdo, struct vdo_completion *parent);
struct block_device * __must_check vdo_get_backing_device(const struct vdo *vdo);
const char * __must_check vdo_get_device_name(const struct dm_target *target);
int __must_check vdo_synchronous_flush(struct vdo *vdo);
const struct admin_state_code * __must_check vdo_get_admin_state(const struct vdo *vdo);
bool vdo_set_compressing(struct vdo *vdo, bool enable);
bool vdo_get_compressing(struct vdo *vdo);
void vdo_fetch_statistics(struct vdo *vdo, struct vdo_statistics *stats);
thread_id_t vdo_get_callback_thread_id(void);
enum vdo_state __must_check vdo_get_state(const struct vdo *vdo);
void vdo_set_state(struct vdo *vdo, enum vdo_state state);
void vdo_save_components(struct vdo *vdo, struct vdo_completion *parent);
int vdo_register_read_only_listener(struct vdo *vdo, void *listener,
vdo_read_only_notification_fn notification,
thread_id_t thread_id);
int vdo_enable_read_only_entry(struct vdo *vdo);
void vdo_wait_until_not_entering_read_only_mode(struct vdo_completion *parent);
void vdo_allow_read_only_mode_entry(struct vdo_completion *parent);
void vdo_enter_read_only_mode(struct vdo *vdo, int error_code);
bool __must_check vdo_is_read_only(struct vdo *vdo);
bool __must_check vdo_in_read_only_mode(const struct vdo *vdo);
bool __must_check vdo_in_recovery_mode(const struct vdo *vdo);
void vdo_enter_recovery_mode(struct vdo *vdo);
void vdo_assert_on_admin_thread(const struct vdo *vdo, const char *name);
void vdo_assert_on_logical_zone_thread(const struct vdo *vdo, zone_count_t logical_zone,
const char *name);
void vdo_assert_on_physical_zone_thread(const struct vdo *vdo, zone_count_t physical_zone,
const char *name);
int __must_check vdo_get_physical_zone(const struct vdo *vdo, physical_block_number_t pbn,
struct physical_zone **zone_ptr);
void vdo_dump_status(const struct vdo *vdo);
#endif