%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /usr/src/blksnap-6.3.0.73/
Upload File :
Create Path :
Current File : //usr/src/blksnap-6.3.0.73/tracker.h

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __BLK_SNAP_TRACKER_H
#define __BLK_SNAP_TRACKER_H

#include <linux/kref.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/rwsem.h>
#include <linux/blkdev.h>
#include <linux/fs.h>

#ifdef STANDALONE_BDEVFILTER
#include "bdevfilter.h"
#endif

struct cbt_map;
struct diff_area;

/**
 * struct tracker - Tracker for a block device.
 *
 * @kref:
 *	Protects the structure from being released during processing of
 *	an ioctl.
 * @link:
 *	List header.
 * @dev_id:
 *	Original block device ID.
 * @snapshot_is_taken:
 *	Indicates that a snapshot was taken for the device whose bios are
 *	handled by this tracker.
 * @cbt_map:
 *	Pointer to a change block tracker map.
 * @diff_area:
 *	Pointer to a difference area.
 *
 * The main goal of the tracker is to handle bios. The tracker detectes
 * the range of sectors that will change and transmits them to the CBT map
 * and to the difference area.
 */
struct tracker {
	struct bdev_filter flt;
	struct list_head link;
	dev_t dev_id;

	struct percpu_rw_semaphore submit_lock;
	atomic_t snapshot_is_taken;
	uuid_t owner_id;

	struct cbt_map *cbt_map;
	struct diff_area *diff_area;
};

void tracker_lock(void);
void tracker_unlock(void);

static inline void tracker_put(struct tracker *tracker)
{
	if (likely(tracker))
		bdev_filter_put(&tracker->flt);
};

struct tracker *tracker_get_by_dev(struct block_device *bdev);

int tracker_init(void);
void tracker_done(void);

struct tracker *tracker_create_or_get(dev_t dev_id, const uuid_t* owner_id);
int tracker_remove(dev_t dev_id);
int tracker_collect(int max_count, struct blk_snap_cbt_info *cbt_info,
		    int *pcount);
int tracker_read_cbt_bitmap(dev_t dev_id, unsigned int offset, size_t length,
			    char __user *user_buff);
int tracker_mark_dirty_blocks(dev_t dev_id,
			      struct blk_snap_block_range *block_ranges,
			      unsigned int count);

int tracker_take_snapshot(struct tracker *tracker);
void tracker_release_snapshot(struct tracker *tracker);

#if defined(HAVE_SUPER_BLOCK_FREEZE)
static inline int _freeze_bdev(struct block_device *bdev,
			       struct super_block **psuperblock)
{
	struct super_block *superblock;

	pr_debug("Freezing device [%u:%u]\n", MAJOR(bdev->bd_dev),
		 MINOR(bdev->bd_dev));

	if (bdev->bd_super == NULL) {
		pr_warn("Unable to freeze device [%u:%u]: no superblock was found\n",
			MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
		return 0;
	}

	superblock = freeze_bdev(bdev);
	if (IS_ERR_OR_NULL(superblock)) {
		int result;

		pr_err("Failed to freeze device [%u:%u]\n", MAJOR(bdev->bd_dev),
		       MINOR(bdev->bd_dev));

		if (superblock == NULL)
			result = -ENODEV;
		else {
			result = PTR_ERR(superblock);
			pr_err("Error code: %d\n", result);
		}
		return result;
	}

	pr_debug("Device [%u:%u] was frozen\n", MAJOR(bdev->bd_dev),
		 MINOR(bdev->bd_dev));
	*psuperblock = superblock;

	return 0;
}
static inline void _thaw_bdev(struct block_device *bdev,
			      struct super_block *superblock)
{
	if (superblock == NULL)
		return;

	if (thaw_bdev(bdev, superblock))
		pr_err("Failed to unfreeze device [%u:%u]\n",
		       MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
	else
		pr_debug("Device [%u:%u] was unfrozen\n", MAJOR(bdev->bd_dev),
			 MINOR(bdev->bd_dev));
}
#endif
#endif /* __BLK_SNAP_TRACKER_H */

Zerion Mini Shell 1.0