#ifndef VDO_PHYSICAL_ZONE_H
#define VDO_PHYSICAL_ZONE_H
#include <linux/atomic.h>
#include "types.h"
enum pbn_lock_type {
VIO_READ_LOCK,
VIO_WRITE_LOCK,
VIO_BLOCK_MAP_WRITE_LOCK,
};
struct pbn_lock_implementation;
struct pbn_lock {
const struct pbn_lock_implementation *implementation;
data_vio_count_t holder_count;
u8 fragment_locks;
bool has_provisional_reference;
u8 increment_limit;
atomic_t increments_claimed;
};
struct physical_zone {
zone_count_t zone_number;
thread_id_t thread_id;
struct int_map *pbn_operations;
struct pbn_lock_pool *lock_pool;
struct block_allocator *allocator;
struct physical_zone *next;
};
struct physical_zones {
zone_count_t zone_count;
struct physical_zone zones[];
};
bool __must_check vdo_is_pbn_read_lock(const struct pbn_lock *lock);
void vdo_downgrade_pbn_write_lock(struct pbn_lock *lock, bool compressed_write);
bool __must_check vdo_claim_pbn_lock_increment(struct pbn_lock *lock);
static inline bool vdo_pbn_lock_has_provisional_reference(struct pbn_lock *lock)
{
return ((lock != NULL) && lock->has_provisional_reference);
}
void vdo_assign_pbn_lock_provisional_reference(struct pbn_lock *lock);
void vdo_unassign_pbn_lock_provisional_reference(struct pbn_lock *lock);
int __must_check vdo_make_physical_zones(struct vdo *vdo,
struct physical_zones **zones_ptr);
void vdo_free_physical_zones(struct physical_zones *zones);
struct pbn_lock * __must_check vdo_get_physical_zone_pbn_lock(struct physical_zone *zone,
physical_block_number_t pbn);
int __must_check vdo_attempt_physical_zone_pbn_lock(struct physical_zone *zone,
physical_block_number_t pbn,
enum pbn_lock_type type,
struct pbn_lock **lock_ptr);
bool __must_check vdo_allocate_block_in_zone(struct data_vio *data_vio);
void vdo_release_physical_zone_pbn_lock(struct physical_zone *zone,
physical_block_number_t locked_pbn,
struct pbn_lock *lock);
void vdo_dump_physical_zone(const struct physical_zone *zone);
#endif