drivers/md/dm-vdo/flush.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/flush.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/flush.c
Extension
.c
Size
17442 bytes
Lines
556
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct flusher {
	struct vdo_completion completion;
	/* The vdo to which this flusher belongs */
	struct vdo *vdo;
	/* The administrative state of the flusher */
	struct admin_state state;
	/* The current flush generation of the vdo */
	sequence_number_t flush_generation;
	/* The first unacknowledged flush generation */
	sequence_number_t first_unacknowledged_generation;
	/* The queue of flush requests waiting to notify other threads */
	struct vdo_wait_queue notifiers;
	/* The queue of flush requests waiting for VIOs to complete */
	struct vdo_wait_queue pending_flushes;
	/* The flush generation for which notifications are being sent */
	sequence_number_t notify_generation;
	/* The logical zone to notify next */
	struct logical_zone *logical_zone_to_notify;
	/* The ID of the thread on which flush requests should be made */
	thread_id_t thread_id;
	/* The pool of flush requests */
	mempool_t *flush_pool;
	/* Bios waiting for a flush request to become available */
	struct bio_list waiting_flush_bios;
	/* The lock to protect the previous fields */
	spinlock_t lock;
	/* The rotor for selecting the bio queue for submitting flush bios */
	zone_count_t bio_queue_rotor;
	/* The number of flushes submitted to the current bio queue */
	int flush_count;
};

/**
 * assert_on_flusher_thread() - Check that we are on the flusher thread.
 * @flusher: The flusher.
 * @caller: The function which is asserting.
 */
static inline void assert_on_flusher_thread(struct flusher *flusher, const char *caller)
{
	VDO_ASSERT_LOG_ONLY((vdo_get_callback_thread_id() == flusher->thread_id),
			    "%s() called from flusher thread", caller);
}

/**
 * as_flusher() - Convert a generic vdo_completion to a flusher.
 * @completion: The completion to convert.
 *
 * Return: The completion as a flusher.
 */
static struct flusher *as_flusher(struct vdo_completion *completion)
{
	vdo_assert_completion_type(completion, VDO_FLUSH_NOTIFICATION_COMPLETION);
	return container_of(completion, struct flusher, completion);
}

/**
 * completion_as_vdo_flush() - Convert a generic vdo_completion to a vdo_flush.
 * @completion: The completion to convert.
 *
 * Return: The completion as a vdo_flush.
 */
static inline struct vdo_flush *completion_as_vdo_flush(struct vdo_completion *completion)
{
	vdo_assert_completion_type(completion, VDO_FLUSH_COMPLETION);
	return container_of(completion, struct vdo_flush, completion);
}

/**
 * vdo_waiter_as_flush() - Convert a vdo_flush's generic wait queue entry back to the vdo_flush.
 * @waiter: The wait queue entry to convert.
 *
 * Return: The wait queue entry as a vdo_flush.
 */
static struct vdo_flush *vdo_waiter_as_flush(struct vdo_waiter *waiter)
{
	return container_of(waiter, struct vdo_flush, waiter);
}

static void *allocate_flush(gfp_t gfp_mask, void *pool_data)
{
	struct vdo_flush *flush = NULL;

	if ((gfp_mask & GFP_NOWAIT) == GFP_NOWAIT) {
		flush = vdo_allocate_memory_nowait(sizeof(struct vdo_flush), __func__);
	} else {
		int result = vdo_allocate(1, __func__, &flush);

		if (result != VDO_SUCCESS)
			vdo_log_error_strerror(result, "failed to allocate spare flush");
	}

Annotation

Implementation Notes