%PDF- %PDF-
Direktori : /usr/src/blksnap-6.3.0.73/ |
Current File : //usr/src/blksnap-6.3.0.73/cbt_map.h |
/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BLK_SNAP_CBT_MAP_H #define __BLK_SNAP_CBT_MAP_H #include <linux/kernel.h> #include <linux/kref.h> #include <linux/uuid.h> #include <linux/spinlock.h> #include <linux/blkdev.h> #include "big_buffer.h" struct blk_snap_block_range; /** * struct cbt_map - The table of changes for a block device. * * @kref: * Reference counter. * @locker: * Locking for atomic modification of structure members. * @blk_size_shift: * The power of 2 used to specify the change tracking block size. * @blk_count: * The number of change tracking blocks. * @device_capacity: * The actual capacity of the device. * @read_map: * A table of changes available for reading. This is the table that can * be read after taking a snapshot. * @write_map: * The current table for tracking changes. * @snap_number_active: * The current sequential number of changes. This is the number that is written to * the current table when the block data changes. * @snap_number_previous: * The previous sequential number of changes. This number is used to identify the * blocks that were changed between the penultimate snapshot and the last snapshot. * @generation_id: * UUID of the generation of changes. * @is_corrupted: * A flag that the change tracking data is no longer reliable. * * The change block tracking map is a byte table. Each byte stores the * sequential number of changes for one block. To determine which blocks have changed * since the previous snapshot with the change number 4, it is enough to * find all bytes with the number more than 4. * * Since one byte is allocated to track changes in one block, the change * table is created again at the 255th snapshot. At the same time, a new * unique generation identifier is generated. Tracking changes is * possible only for tables of the same generation. * * There are two tables on the change block tracking map. One is * available for reading, and the other is available for writing. At the moment of taking * a snapshot, the tables are synchronized. The user's process, when * calling the corresponding ioctl, can read the readable table. * At the same time, the change tracking mechanism continues to work with * the writable table. * * To provide the ability to mount a snapshot image as writeable, it is * possible to make changes to both of these tables simultaneously. * */ struct cbt_map { struct kref kref; spinlock_t locker; size_t blk_size_shift; size_t blk_count; sector_t device_capacity; struct big_buffer *read_map; struct big_buffer *write_map; unsigned long snap_number_active; unsigned long snap_number_previous; uuid_t generation_id; bool is_corrupted; }; struct cbt_map *cbt_map_create(struct block_device *bdev); int cbt_map_reset(struct cbt_map *cbt_map, sector_t device_capacity); void cbt_map_destroy_cb(struct kref *kref); static inline void cbt_map_get(struct cbt_map *cbt_map) { kref_get(&cbt_map->kref); }; static inline void cbt_map_put(struct cbt_map *cbt_map) { if (likely(cbt_map)) kref_put(&cbt_map->kref, cbt_map_destroy_cb); }; void cbt_map_switch(struct cbt_map *cbt_map); int cbt_map_set(struct cbt_map *cbt_map, sector_t sector_start, sector_t sector_cnt); int cbt_map_set_both(struct cbt_map *cbt_map, sector_t sector_start, sector_t sector_cnt); size_t cbt_map_read_to_user(struct cbt_map *cbt_map, char __user *user_buffer, size_t offset, size_t size); static inline size_t cbt_map_blk_size(struct cbt_map *cbt_map) { return 1 << cbt_map->blk_size_shift; }; int cbt_map_mark_dirty_blocks(struct cbt_map *cbt_map, struct blk_snap_block_range *block_ranges, unsigned int count); #ifdef BLK_SNAP_DEBUG_SECTOR_STATE int cbt_map_get_sector_state(struct cbt_map *cbt_map, sector_t sector, u8 *snap_number_prev, u8 *snap_number_curr); #endif #endif /* __BLK_SNAP_CBT_MAP_H */