18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (C) 2012 Red Hat. All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * This file is released under the GPL.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include "dm.h"
88c2ecf20Sopenharmony_ci#include "dm-bio-prison-v2.h"
98c2ecf20Sopenharmony_ci#include "dm-bio-record.h"
108c2ecf20Sopenharmony_ci#include "dm-cache-metadata.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/dm-io.h>
138c2ecf20Sopenharmony_ci#include <linux/dm-kcopyd.h>
148c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
158c2ecf20Sopenharmony_ci#include <linux/init.h>
168c2ecf20Sopenharmony_ci#include <linux/mempool.h>
178c2ecf20Sopenharmony_ci#include <linux/module.h>
188c2ecf20Sopenharmony_ci#include <linux/rwsem.h>
198c2ecf20Sopenharmony_ci#include <linux/slab.h>
208c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define DM_MSG_PREFIX "cache"
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciDECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(cache_copy_throttle,
258c2ecf20Sopenharmony_ci	"A percentage of time allocated for copying to and/or from cache");
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/*
308c2ecf20Sopenharmony_ci * Glossary:
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * oblock: index of an origin block
338c2ecf20Sopenharmony_ci * cblock: index of a cache block
348c2ecf20Sopenharmony_ci * promotion: movement of a block from origin to cache
358c2ecf20Sopenharmony_ci * demotion: movement of a block from cache to origin
368c2ecf20Sopenharmony_ci * migration: movement of a block between the origin and cache device,
378c2ecf20Sopenharmony_ci *	      either direction
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistruct io_tracker {
438c2ecf20Sopenharmony_ci	spinlock_t lock;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	/*
468c2ecf20Sopenharmony_ci	 * Sectors of in-flight IO.
478c2ecf20Sopenharmony_ci	 */
488c2ecf20Sopenharmony_ci	sector_t in_flight;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	/*
518c2ecf20Sopenharmony_ci	 * The time, in jiffies, when this device became idle (if it is
528c2ecf20Sopenharmony_ci	 * indeed idle).
538c2ecf20Sopenharmony_ci	 */
548c2ecf20Sopenharmony_ci	unsigned long idle_time;
558c2ecf20Sopenharmony_ci	unsigned long last_update_time;
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic void iot_init(struct io_tracker *iot)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	spin_lock_init(&iot->lock);
618c2ecf20Sopenharmony_ci	iot->in_flight = 0ul;
628c2ecf20Sopenharmony_ci	iot->idle_time = 0ul;
638c2ecf20Sopenharmony_ci	iot->last_update_time = jiffies;
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic bool __iot_idle_for(struct io_tracker *iot, unsigned long jifs)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	if (iot->in_flight)
698c2ecf20Sopenharmony_ci		return false;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	return time_after(jiffies, iot->idle_time + jifs);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic bool iot_idle_for(struct io_tracker *iot, unsigned long jifs)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	bool r;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	spin_lock_irq(&iot->lock);
798c2ecf20Sopenharmony_ci	r = __iot_idle_for(iot, jifs);
808c2ecf20Sopenharmony_ci	spin_unlock_irq(&iot->lock);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	return r;
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic void iot_io_begin(struct io_tracker *iot, sector_t len)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	spin_lock_irq(&iot->lock);
888c2ecf20Sopenharmony_ci	iot->in_flight += len;
898c2ecf20Sopenharmony_ci	spin_unlock_irq(&iot->lock);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic void __iot_io_end(struct io_tracker *iot, sector_t len)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	if (!len)
958c2ecf20Sopenharmony_ci		return;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	iot->in_flight -= len;
988c2ecf20Sopenharmony_ci	if (!iot->in_flight)
998c2ecf20Sopenharmony_ci		iot->idle_time = jiffies;
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic void iot_io_end(struct io_tracker *iot, sector_t len)
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	unsigned long flags;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	spin_lock_irqsave(&iot->lock, flags);
1078c2ecf20Sopenharmony_ci	__iot_io_end(iot, len);
1088c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&iot->lock, flags);
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci/*
1148c2ecf20Sopenharmony_ci * Represents a chunk of future work.  'input' allows continuations to pass
1158c2ecf20Sopenharmony_ci * values between themselves, typically error values.
1168c2ecf20Sopenharmony_ci */
1178c2ecf20Sopenharmony_cistruct continuation {
1188c2ecf20Sopenharmony_ci	struct work_struct ws;
1198c2ecf20Sopenharmony_ci	blk_status_t input;
1208c2ecf20Sopenharmony_ci};
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic inline void init_continuation(struct continuation *k,
1238c2ecf20Sopenharmony_ci				     void (*fn)(struct work_struct *))
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	INIT_WORK(&k->ws, fn);
1268c2ecf20Sopenharmony_ci	k->input = 0;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistatic inline void queue_continuation(struct workqueue_struct *wq,
1308c2ecf20Sopenharmony_ci				      struct continuation *k)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	queue_work(wq, &k->ws);
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci/*
1388c2ecf20Sopenharmony_ci * The batcher collects together pieces of work that need a particular
1398c2ecf20Sopenharmony_ci * operation to occur before they can proceed (typically a commit).
1408c2ecf20Sopenharmony_ci */
1418c2ecf20Sopenharmony_cistruct batcher {
1428c2ecf20Sopenharmony_ci	/*
1438c2ecf20Sopenharmony_ci	 * The operation that everyone is waiting for.
1448c2ecf20Sopenharmony_ci	 */
1458c2ecf20Sopenharmony_ci	blk_status_t (*commit_op)(void *context);
1468c2ecf20Sopenharmony_ci	void *commit_context;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	/*
1498c2ecf20Sopenharmony_ci	 * This is how bios should be issued once the commit op is complete
1508c2ecf20Sopenharmony_ci	 * (accounted_request).
1518c2ecf20Sopenharmony_ci	 */
1528c2ecf20Sopenharmony_ci	void (*issue_op)(struct bio *bio, void *context);
1538c2ecf20Sopenharmony_ci	void *issue_context;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	/*
1568c2ecf20Sopenharmony_ci	 * Queued work gets put on here after commit.
1578c2ecf20Sopenharmony_ci	 */
1588c2ecf20Sopenharmony_ci	struct workqueue_struct *wq;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	spinlock_t lock;
1618c2ecf20Sopenharmony_ci	struct list_head work_items;
1628c2ecf20Sopenharmony_ci	struct bio_list bios;
1638c2ecf20Sopenharmony_ci	struct work_struct commit_work;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	bool commit_scheduled;
1668c2ecf20Sopenharmony_ci};
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void __commit(struct work_struct *_ws)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	struct batcher *b = container_of(_ws, struct batcher, commit_work);
1718c2ecf20Sopenharmony_ci	blk_status_t r;
1728c2ecf20Sopenharmony_ci	struct list_head work_items;
1738c2ecf20Sopenharmony_ci	struct work_struct *ws, *tmp;
1748c2ecf20Sopenharmony_ci	struct continuation *k;
1758c2ecf20Sopenharmony_ci	struct bio *bio;
1768c2ecf20Sopenharmony_ci	struct bio_list bios;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&work_items);
1798c2ecf20Sopenharmony_ci	bio_list_init(&bios);
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	/*
1828c2ecf20Sopenharmony_ci	 * We have to grab these before the commit_op to avoid a race
1838c2ecf20Sopenharmony_ci	 * condition.
1848c2ecf20Sopenharmony_ci	 */
1858c2ecf20Sopenharmony_ci	spin_lock_irq(&b->lock);
1868c2ecf20Sopenharmony_ci	list_splice_init(&b->work_items, &work_items);
1878c2ecf20Sopenharmony_ci	bio_list_merge(&bios, &b->bios);
1888c2ecf20Sopenharmony_ci	bio_list_init(&b->bios);
1898c2ecf20Sopenharmony_ci	b->commit_scheduled = false;
1908c2ecf20Sopenharmony_ci	spin_unlock_irq(&b->lock);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	r = b->commit_op(b->commit_context);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	list_for_each_entry_safe(ws, tmp, &work_items, entry) {
1958c2ecf20Sopenharmony_ci		k = container_of(ws, struct continuation, ws);
1968c2ecf20Sopenharmony_ci		k->input = r;
1978c2ecf20Sopenharmony_ci		INIT_LIST_HEAD(&ws->entry); /* to avoid a WARN_ON */
1988c2ecf20Sopenharmony_ci		queue_work(b->wq, ws);
1998c2ecf20Sopenharmony_ci	}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	while ((bio = bio_list_pop(&bios))) {
2028c2ecf20Sopenharmony_ci		if (r) {
2038c2ecf20Sopenharmony_ci			bio->bi_status = r;
2048c2ecf20Sopenharmony_ci			bio_endio(bio);
2058c2ecf20Sopenharmony_ci		} else
2068c2ecf20Sopenharmony_ci			b->issue_op(bio, b->issue_context);
2078c2ecf20Sopenharmony_ci	}
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic void batcher_init(struct batcher *b,
2118c2ecf20Sopenharmony_ci			 blk_status_t (*commit_op)(void *),
2128c2ecf20Sopenharmony_ci			 void *commit_context,
2138c2ecf20Sopenharmony_ci			 void (*issue_op)(struct bio *bio, void *),
2148c2ecf20Sopenharmony_ci			 void *issue_context,
2158c2ecf20Sopenharmony_ci			 struct workqueue_struct *wq)
2168c2ecf20Sopenharmony_ci{
2178c2ecf20Sopenharmony_ci	b->commit_op = commit_op;
2188c2ecf20Sopenharmony_ci	b->commit_context = commit_context;
2198c2ecf20Sopenharmony_ci	b->issue_op = issue_op;
2208c2ecf20Sopenharmony_ci	b->issue_context = issue_context;
2218c2ecf20Sopenharmony_ci	b->wq = wq;
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	spin_lock_init(&b->lock);
2248c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&b->work_items);
2258c2ecf20Sopenharmony_ci	bio_list_init(&b->bios);
2268c2ecf20Sopenharmony_ci	INIT_WORK(&b->commit_work, __commit);
2278c2ecf20Sopenharmony_ci	b->commit_scheduled = false;
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cistatic void async_commit(struct batcher *b)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	queue_work(b->wq, &b->commit_work);
2338c2ecf20Sopenharmony_ci}
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_cistatic void continue_after_commit(struct batcher *b, struct continuation *k)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	bool commit_scheduled;
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	spin_lock_irq(&b->lock);
2408c2ecf20Sopenharmony_ci	commit_scheduled = b->commit_scheduled;
2418c2ecf20Sopenharmony_ci	list_add_tail(&k->ws.entry, &b->work_items);
2428c2ecf20Sopenharmony_ci	spin_unlock_irq(&b->lock);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	if (commit_scheduled)
2458c2ecf20Sopenharmony_ci		async_commit(b);
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci/*
2498c2ecf20Sopenharmony_ci * Bios are errored if commit failed.
2508c2ecf20Sopenharmony_ci */
2518c2ecf20Sopenharmony_cistatic void issue_after_commit(struct batcher *b, struct bio *bio)
2528c2ecf20Sopenharmony_ci{
2538c2ecf20Sopenharmony_ci       bool commit_scheduled;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci       spin_lock_irq(&b->lock);
2568c2ecf20Sopenharmony_ci       commit_scheduled = b->commit_scheduled;
2578c2ecf20Sopenharmony_ci       bio_list_add(&b->bios, bio);
2588c2ecf20Sopenharmony_ci       spin_unlock_irq(&b->lock);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci       if (commit_scheduled)
2618c2ecf20Sopenharmony_ci	       async_commit(b);
2628c2ecf20Sopenharmony_ci}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci/*
2658c2ecf20Sopenharmony_ci * Call this if some urgent work is waiting for the commit to complete.
2668c2ecf20Sopenharmony_ci */
2678c2ecf20Sopenharmony_cistatic void schedule_commit(struct batcher *b)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	bool immediate;
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	spin_lock_irq(&b->lock);
2728c2ecf20Sopenharmony_ci	immediate = !list_empty(&b->work_items) || !bio_list_empty(&b->bios);
2738c2ecf20Sopenharmony_ci	b->commit_scheduled = true;
2748c2ecf20Sopenharmony_ci	spin_unlock_irq(&b->lock);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	if (immediate)
2778c2ecf20Sopenharmony_ci		async_commit(b);
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci/*
2818c2ecf20Sopenharmony_ci * There are a couple of places where we let a bio run, but want to do some
2828c2ecf20Sopenharmony_ci * work before calling its endio function.  We do this by temporarily
2838c2ecf20Sopenharmony_ci * changing the endio fn.
2848c2ecf20Sopenharmony_ci */
2858c2ecf20Sopenharmony_cistruct dm_hook_info {
2868c2ecf20Sopenharmony_ci	bio_end_io_t *bi_end_io;
2878c2ecf20Sopenharmony_ci};
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_cistatic void dm_hook_bio(struct dm_hook_info *h, struct bio *bio,
2908c2ecf20Sopenharmony_ci			bio_end_io_t *bi_end_io, void *bi_private)
2918c2ecf20Sopenharmony_ci{
2928c2ecf20Sopenharmony_ci	h->bi_end_io = bio->bi_end_io;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	bio->bi_end_io = bi_end_io;
2958c2ecf20Sopenharmony_ci	bio->bi_private = bi_private;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_cistatic void dm_unhook_bio(struct dm_hook_info *h, struct bio *bio)
2998c2ecf20Sopenharmony_ci{
3008c2ecf20Sopenharmony_ci	bio->bi_end_io = h->bi_end_io;
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci#define MIGRATION_POOL_SIZE 128
3068c2ecf20Sopenharmony_ci#define COMMIT_PERIOD HZ
3078c2ecf20Sopenharmony_ci#define MIGRATION_COUNT_WINDOW 10
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci/*
3108c2ecf20Sopenharmony_ci * The block size of the device holding cache data must be
3118c2ecf20Sopenharmony_ci * between 32KB and 1GB.
3128c2ecf20Sopenharmony_ci */
3138c2ecf20Sopenharmony_ci#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (32 * 1024 >> SECTOR_SHIFT)
3148c2ecf20Sopenharmony_ci#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cienum cache_metadata_mode {
3178c2ecf20Sopenharmony_ci	CM_WRITE,		/* metadata may be changed */
3188c2ecf20Sopenharmony_ci	CM_READ_ONLY,		/* metadata may not be changed */
3198c2ecf20Sopenharmony_ci	CM_FAIL
3208c2ecf20Sopenharmony_ci};
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_cienum cache_io_mode {
3238c2ecf20Sopenharmony_ci	/*
3248c2ecf20Sopenharmony_ci	 * Data is written to cached blocks only.  These blocks are marked
3258c2ecf20Sopenharmony_ci	 * dirty.  If you lose the cache device you will lose data.
3268c2ecf20Sopenharmony_ci	 * Potential performance increase for both reads and writes.
3278c2ecf20Sopenharmony_ci	 */
3288c2ecf20Sopenharmony_ci	CM_IO_WRITEBACK,
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	/*
3318c2ecf20Sopenharmony_ci	 * Data is written to both cache and origin.  Blocks are never
3328c2ecf20Sopenharmony_ci	 * dirty.  Potential performance benfit for reads only.
3338c2ecf20Sopenharmony_ci	 */
3348c2ecf20Sopenharmony_ci	CM_IO_WRITETHROUGH,
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	/*
3378c2ecf20Sopenharmony_ci	 * A degraded mode useful for various cache coherency situations
3388c2ecf20Sopenharmony_ci	 * (eg, rolling back snapshots).  Reads and writes always go to the
3398c2ecf20Sopenharmony_ci	 * origin.  If a write goes to a cached oblock, then the cache
3408c2ecf20Sopenharmony_ci	 * block is invalidated.
3418c2ecf20Sopenharmony_ci	 */
3428c2ecf20Sopenharmony_ci	CM_IO_PASSTHROUGH
3438c2ecf20Sopenharmony_ci};
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_cistruct cache_features {
3468c2ecf20Sopenharmony_ci	enum cache_metadata_mode mode;
3478c2ecf20Sopenharmony_ci	enum cache_io_mode io_mode;
3488c2ecf20Sopenharmony_ci	unsigned metadata_version;
3498c2ecf20Sopenharmony_ci	bool discard_passdown:1;
3508c2ecf20Sopenharmony_ci};
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_cistruct cache_stats {
3538c2ecf20Sopenharmony_ci	atomic_t read_hit;
3548c2ecf20Sopenharmony_ci	atomic_t read_miss;
3558c2ecf20Sopenharmony_ci	atomic_t write_hit;
3568c2ecf20Sopenharmony_ci	atomic_t write_miss;
3578c2ecf20Sopenharmony_ci	atomic_t demotion;
3588c2ecf20Sopenharmony_ci	atomic_t promotion;
3598c2ecf20Sopenharmony_ci	atomic_t writeback;
3608c2ecf20Sopenharmony_ci	atomic_t copies_avoided;
3618c2ecf20Sopenharmony_ci	atomic_t cache_cell_clash;
3628c2ecf20Sopenharmony_ci	atomic_t commit_count;
3638c2ecf20Sopenharmony_ci	atomic_t discard_count;
3648c2ecf20Sopenharmony_ci};
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_cistruct cache {
3678c2ecf20Sopenharmony_ci	struct dm_target *ti;
3688c2ecf20Sopenharmony_ci	spinlock_t lock;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	/*
3718c2ecf20Sopenharmony_ci	 * Fields for converting from sectors to blocks.
3728c2ecf20Sopenharmony_ci	 */
3738c2ecf20Sopenharmony_ci	int sectors_per_block_shift;
3748c2ecf20Sopenharmony_ci	sector_t sectors_per_block;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	struct dm_cache_metadata *cmd;
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci	/*
3798c2ecf20Sopenharmony_ci	 * Metadata is written to this device.
3808c2ecf20Sopenharmony_ci	 */
3818c2ecf20Sopenharmony_ci	struct dm_dev *metadata_dev;
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci	/*
3848c2ecf20Sopenharmony_ci	 * The slower of the two data devices.  Typically a spindle.
3858c2ecf20Sopenharmony_ci	 */
3868c2ecf20Sopenharmony_ci	struct dm_dev *origin_dev;
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	/*
3898c2ecf20Sopenharmony_ci	 * The faster of the two data devices.  Typically an SSD.
3908c2ecf20Sopenharmony_ci	 */
3918c2ecf20Sopenharmony_ci	struct dm_dev *cache_dev;
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	/*
3948c2ecf20Sopenharmony_ci	 * Size of the origin device in _complete_ blocks and native sectors.
3958c2ecf20Sopenharmony_ci	 */
3968c2ecf20Sopenharmony_ci	dm_oblock_t origin_blocks;
3978c2ecf20Sopenharmony_ci	sector_t origin_sectors;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	/*
4008c2ecf20Sopenharmony_ci	 * Size of the cache device in blocks.
4018c2ecf20Sopenharmony_ci	 */
4028c2ecf20Sopenharmony_ci	dm_cblock_t cache_size;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	/*
4058c2ecf20Sopenharmony_ci	 * Invalidation fields.
4068c2ecf20Sopenharmony_ci	 */
4078c2ecf20Sopenharmony_ci	spinlock_t invalidation_lock;
4088c2ecf20Sopenharmony_ci	struct list_head invalidation_requests;
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	sector_t migration_threshold;
4118c2ecf20Sopenharmony_ci	wait_queue_head_t migration_wait;
4128c2ecf20Sopenharmony_ci	atomic_t nr_allocated_migrations;
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	/*
4158c2ecf20Sopenharmony_ci	 * The number of in flight migrations that are performing
4168c2ecf20Sopenharmony_ci	 * background io. eg, promotion, writeback.
4178c2ecf20Sopenharmony_ci	 */
4188c2ecf20Sopenharmony_ci	atomic_t nr_io_migrations;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	struct bio_list deferred_bios;
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci	struct rw_semaphore quiesce_lock;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	/*
4258c2ecf20Sopenharmony_ci	 * origin_blocks entries, discarded if set.
4268c2ecf20Sopenharmony_ci	 */
4278c2ecf20Sopenharmony_ci	dm_dblock_t discard_nr_blocks;
4288c2ecf20Sopenharmony_ci	unsigned long *discard_bitset;
4298c2ecf20Sopenharmony_ci	uint32_t discard_block_size; /* a power of 2 times sectors per block */
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	/*
4328c2ecf20Sopenharmony_ci	 * Rather than reconstructing the table line for the status we just
4338c2ecf20Sopenharmony_ci	 * save it and regurgitate.
4348c2ecf20Sopenharmony_ci	 */
4358c2ecf20Sopenharmony_ci	unsigned nr_ctr_args;
4368c2ecf20Sopenharmony_ci	const char **ctr_args;
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci	struct dm_kcopyd_client *copier;
4398c2ecf20Sopenharmony_ci	struct work_struct deferred_bio_worker;
4408c2ecf20Sopenharmony_ci	struct work_struct migration_worker;
4418c2ecf20Sopenharmony_ci	struct workqueue_struct *wq;
4428c2ecf20Sopenharmony_ci	struct delayed_work waker;
4438c2ecf20Sopenharmony_ci	struct dm_bio_prison_v2 *prison;
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	/*
4468c2ecf20Sopenharmony_ci	 * cache_size entries, dirty if set
4478c2ecf20Sopenharmony_ci	 */
4488c2ecf20Sopenharmony_ci	unsigned long *dirty_bitset;
4498c2ecf20Sopenharmony_ci	atomic_t nr_dirty;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	unsigned policy_nr_args;
4528c2ecf20Sopenharmony_ci	struct dm_cache_policy *policy;
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	/*
4558c2ecf20Sopenharmony_ci	 * Cache features such as write-through.
4568c2ecf20Sopenharmony_ci	 */
4578c2ecf20Sopenharmony_ci	struct cache_features features;
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	struct cache_stats stats;
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	bool need_tick_bio:1;
4628c2ecf20Sopenharmony_ci	bool sized:1;
4638c2ecf20Sopenharmony_ci	bool invalidate:1;
4648c2ecf20Sopenharmony_ci	bool commit_requested:1;
4658c2ecf20Sopenharmony_ci	bool loaded_mappings:1;
4668c2ecf20Sopenharmony_ci	bool loaded_discards:1;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	struct rw_semaphore background_work_lock;
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	struct batcher committer;
4718c2ecf20Sopenharmony_ci	struct work_struct commit_ws;
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	struct io_tracker tracker;
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci	mempool_t migration_pool;
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci	struct bio_set bs;
4788c2ecf20Sopenharmony_ci};
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_cistruct per_bio_data {
4818c2ecf20Sopenharmony_ci	bool tick:1;
4828c2ecf20Sopenharmony_ci	unsigned req_nr:2;
4838c2ecf20Sopenharmony_ci	struct dm_bio_prison_cell_v2 *cell;
4848c2ecf20Sopenharmony_ci	struct dm_hook_info hook_info;
4858c2ecf20Sopenharmony_ci	sector_t len;
4868c2ecf20Sopenharmony_ci};
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_cistruct dm_cache_migration {
4898c2ecf20Sopenharmony_ci	struct continuation k;
4908c2ecf20Sopenharmony_ci	struct cache *cache;
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	struct policy_work *op;
4938c2ecf20Sopenharmony_ci	struct bio *overwrite_bio;
4948c2ecf20Sopenharmony_ci	struct dm_bio_prison_cell_v2 *cell;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	dm_cblock_t invalidate_cblock;
4978c2ecf20Sopenharmony_ci	dm_oblock_t invalidate_oblock;
4988c2ecf20Sopenharmony_ci};
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_cistatic bool writethrough_mode(struct cache *cache)
5038c2ecf20Sopenharmony_ci{
5048c2ecf20Sopenharmony_ci	return cache->features.io_mode == CM_IO_WRITETHROUGH;
5058c2ecf20Sopenharmony_ci}
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_cistatic bool writeback_mode(struct cache *cache)
5088c2ecf20Sopenharmony_ci{
5098c2ecf20Sopenharmony_ci	return cache->features.io_mode == CM_IO_WRITEBACK;
5108c2ecf20Sopenharmony_ci}
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_cistatic inline bool passthrough_mode(struct cache *cache)
5138c2ecf20Sopenharmony_ci{
5148c2ecf20Sopenharmony_ci	return unlikely(cache->features.io_mode == CM_IO_PASSTHROUGH);
5158c2ecf20Sopenharmony_ci}
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_cistatic void wake_deferred_bio_worker(struct cache *cache)
5208c2ecf20Sopenharmony_ci{
5218c2ecf20Sopenharmony_ci	queue_work(cache->wq, &cache->deferred_bio_worker);
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_cistatic void wake_migration_worker(struct cache *cache)
5258c2ecf20Sopenharmony_ci{
5268c2ecf20Sopenharmony_ci	if (passthrough_mode(cache))
5278c2ecf20Sopenharmony_ci		return;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	queue_work(cache->wq, &cache->migration_worker);
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_cistatic struct dm_bio_prison_cell_v2 *alloc_prison_cell(struct cache *cache)
5358c2ecf20Sopenharmony_ci{
5368c2ecf20Sopenharmony_ci	return dm_bio_prison_alloc_cell_v2(cache->prison, GFP_NOIO);
5378c2ecf20Sopenharmony_ci}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_cistatic void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell_v2 *cell)
5408c2ecf20Sopenharmony_ci{
5418c2ecf20Sopenharmony_ci	dm_bio_prison_free_cell_v2(cache->prison, cell);
5428c2ecf20Sopenharmony_ci}
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_cistatic struct dm_cache_migration *alloc_migration(struct cache *cache)
5458c2ecf20Sopenharmony_ci{
5468c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg;
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	mg = mempool_alloc(&cache->migration_pool, GFP_NOIO);
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	memset(mg, 0, sizeof(*mg));
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	mg->cache = cache;
5538c2ecf20Sopenharmony_ci	atomic_inc(&cache->nr_allocated_migrations);
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci	return mg;
5568c2ecf20Sopenharmony_ci}
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_cistatic void free_migration(struct dm_cache_migration *mg)
5598c2ecf20Sopenharmony_ci{
5608c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	if (atomic_dec_and_test(&cache->nr_allocated_migrations))
5638c2ecf20Sopenharmony_ci		wake_up(&cache->migration_wait);
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_ci	mempool_free(mg, &cache->migration_pool);
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_cistatic inline dm_oblock_t oblock_succ(dm_oblock_t b)
5718c2ecf20Sopenharmony_ci{
5728c2ecf20Sopenharmony_ci	return to_oblock(from_oblock(b) + 1ull);
5738c2ecf20Sopenharmony_ci}
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_cistatic void build_key(dm_oblock_t begin, dm_oblock_t end, struct dm_cell_key_v2 *key)
5768c2ecf20Sopenharmony_ci{
5778c2ecf20Sopenharmony_ci	key->virtual = 0;
5788c2ecf20Sopenharmony_ci	key->dev = 0;
5798c2ecf20Sopenharmony_ci	key->block_begin = from_oblock(begin);
5808c2ecf20Sopenharmony_ci	key->block_end = from_oblock(end);
5818c2ecf20Sopenharmony_ci}
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci/*
5848c2ecf20Sopenharmony_ci * We have two lock levels.  Level 0, which is used to prevent WRITEs, and
5858c2ecf20Sopenharmony_ci * level 1 which prevents *both* READs and WRITEs.
5868c2ecf20Sopenharmony_ci */
5878c2ecf20Sopenharmony_ci#define WRITE_LOCK_LEVEL 0
5888c2ecf20Sopenharmony_ci#define READ_WRITE_LOCK_LEVEL 1
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_cistatic unsigned lock_level(struct bio *bio)
5918c2ecf20Sopenharmony_ci{
5928c2ecf20Sopenharmony_ci	return bio_data_dir(bio) == WRITE ?
5938c2ecf20Sopenharmony_ci		WRITE_LOCK_LEVEL :
5948c2ecf20Sopenharmony_ci		READ_WRITE_LOCK_LEVEL;
5958c2ecf20Sopenharmony_ci}
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
5988c2ecf20Sopenharmony_ci * Per bio data
5998c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_cistatic struct per_bio_data *get_per_bio_data(struct bio *bio)
6028c2ecf20Sopenharmony_ci{
6038c2ecf20Sopenharmony_ci	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
6048c2ecf20Sopenharmony_ci	BUG_ON(!pb);
6058c2ecf20Sopenharmony_ci	return pb;
6068c2ecf20Sopenharmony_ci}
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_cistatic struct per_bio_data *init_per_bio_data(struct bio *bio)
6098c2ecf20Sopenharmony_ci{
6108c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci	pb->tick = false;
6138c2ecf20Sopenharmony_ci	pb->req_nr = dm_bio_get_target_bio_nr(bio);
6148c2ecf20Sopenharmony_ci	pb->cell = NULL;
6158c2ecf20Sopenharmony_ci	pb->len = 0;
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci	return pb;
6188c2ecf20Sopenharmony_ci}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_cistatic void defer_bio(struct cache *cache, struct bio *bio)
6238c2ecf20Sopenharmony_ci{
6248c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
6258c2ecf20Sopenharmony_ci	bio_list_add(&cache->deferred_bios, bio);
6268c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci	wake_deferred_bio_worker(cache);
6298c2ecf20Sopenharmony_ci}
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_cistatic void defer_bios(struct cache *cache, struct bio_list *bios)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
6348c2ecf20Sopenharmony_ci	bio_list_merge(&cache->deferred_bios, bios);
6358c2ecf20Sopenharmony_ci	bio_list_init(bios);
6368c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	wake_deferred_bio_worker(cache);
6398c2ecf20Sopenharmony_ci}
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_cistatic bool bio_detain_shared(struct cache *cache, dm_oblock_t oblock, struct bio *bio)
6448c2ecf20Sopenharmony_ci{
6458c2ecf20Sopenharmony_ci	bool r;
6468c2ecf20Sopenharmony_ci	struct per_bio_data *pb;
6478c2ecf20Sopenharmony_ci	struct dm_cell_key_v2 key;
6488c2ecf20Sopenharmony_ci	dm_oblock_t end = to_oblock(from_oblock(oblock) + 1ULL);
6498c2ecf20Sopenharmony_ci	struct dm_bio_prison_cell_v2 *cell_prealloc, *cell;
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci	cell_prealloc = alloc_prison_cell(cache); /* FIXME: allow wait if calling from worker */
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	build_key(oblock, end, &key);
6548c2ecf20Sopenharmony_ci	r = dm_cell_get_v2(cache->prison, &key, lock_level(bio), bio, cell_prealloc, &cell);
6558c2ecf20Sopenharmony_ci	if (!r) {
6568c2ecf20Sopenharmony_ci		/*
6578c2ecf20Sopenharmony_ci		 * Failed to get the lock.
6588c2ecf20Sopenharmony_ci		 */
6598c2ecf20Sopenharmony_ci		free_prison_cell(cache, cell_prealloc);
6608c2ecf20Sopenharmony_ci		return r;
6618c2ecf20Sopenharmony_ci	}
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci	if (cell != cell_prealloc)
6648c2ecf20Sopenharmony_ci		free_prison_cell(cache, cell_prealloc);
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	pb = get_per_bio_data(bio);
6678c2ecf20Sopenharmony_ci	pb->cell = cell;
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci	return r;
6708c2ecf20Sopenharmony_ci}
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_cistatic bool is_dirty(struct cache *cache, dm_cblock_t b)
6758c2ecf20Sopenharmony_ci{
6768c2ecf20Sopenharmony_ci	return test_bit(from_cblock(b), cache->dirty_bitset);
6778c2ecf20Sopenharmony_ci}
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_cistatic void set_dirty(struct cache *cache, dm_cblock_t cblock)
6808c2ecf20Sopenharmony_ci{
6818c2ecf20Sopenharmony_ci	if (!test_and_set_bit(from_cblock(cblock), cache->dirty_bitset)) {
6828c2ecf20Sopenharmony_ci		atomic_inc(&cache->nr_dirty);
6838c2ecf20Sopenharmony_ci		policy_set_dirty(cache->policy, cblock);
6848c2ecf20Sopenharmony_ci	}
6858c2ecf20Sopenharmony_ci}
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci/*
6888c2ecf20Sopenharmony_ci * These two are called when setting after migrations to force the policy
6898c2ecf20Sopenharmony_ci * and dirty bitset to be in sync.
6908c2ecf20Sopenharmony_ci */
6918c2ecf20Sopenharmony_cistatic void force_set_dirty(struct cache *cache, dm_cblock_t cblock)
6928c2ecf20Sopenharmony_ci{
6938c2ecf20Sopenharmony_ci	if (!test_and_set_bit(from_cblock(cblock), cache->dirty_bitset))
6948c2ecf20Sopenharmony_ci		atomic_inc(&cache->nr_dirty);
6958c2ecf20Sopenharmony_ci	policy_set_dirty(cache->policy, cblock);
6968c2ecf20Sopenharmony_ci}
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_cistatic void force_clear_dirty(struct cache *cache, dm_cblock_t cblock)
6998c2ecf20Sopenharmony_ci{
7008c2ecf20Sopenharmony_ci	if (test_and_clear_bit(from_cblock(cblock), cache->dirty_bitset)) {
7018c2ecf20Sopenharmony_ci		if (atomic_dec_return(&cache->nr_dirty) == 0)
7028c2ecf20Sopenharmony_ci			dm_table_event(cache->ti->table);
7038c2ecf20Sopenharmony_ci	}
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ci	policy_clear_dirty(cache->policy, cblock);
7068c2ecf20Sopenharmony_ci}
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_cistatic bool block_size_is_power_of_two(struct cache *cache)
7118c2ecf20Sopenharmony_ci{
7128c2ecf20Sopenharmony_ci	return cache->sectors_per_block_shift >= 0;
7138c2ecf20Sopenharmony_ci}
7148c2ecf20Sopenharmony_ci
7158c2ecf20Sopenharmony_cistatic dm_block_t block_div(dm_block_t b, uint32_t n)
7168c2ecf20Sopenharmony_ci{
7178c2ecf20Sopenharmony_ci	do_div(b, n);
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci	return b;
7208c2ecf20Sopenharmony_ci}
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_cistatic dm_block_t oblocks_per_dblock(struct cache *cache)
7238c2ecf20Sopenharmony_ci{
7248c2ecf20Sopenharmony_ci	dm_block_t oblocks = cache->discard_block_size;
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci	if (block_size_is_power_of_two(cache))
7278c2ecf20Sopenharmony_ci		oblocks >>= cache->sectors_per_block_shift;
7288c2ecf20Sopenharmony_ci	else
7298c2ecf20Sopenharmony_ci		oblocks = block_div(oblocks, cache->sectors_per_block);
7308c2ecf20Sopenharmony_ci
7318c2ecf20Sopenharmony_ci	return oblocks;
7328c2ecf20Sopenharmony_ci}
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_cistatic dm_dblock_t oblock_to_dblock(struct cache *cache, dm_oblock_t oblock)
7358c2ecf20Sopenharmony_ci{
7368c2ecf20Sopenharmony_ci	return to_dblock(block_div(from_oblock(oblock),
7378c2ecf20Sopenharmony_ci				   oblocks_per_dblock(cache)));
7388c2ecf20Sopenharmony_ci}
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_cistatic void set_discard(struct cache *cache, dm_dblock_t b)
7418c2ecf20Sopenharmony_ci{
7428c2ecf20Sopenharmony_ci	BUG_ON(from_dblock(b) >= from_dblock(cache->discard_nr_blocks));
7438c2ecf20Sopenharmony_ci	atomic_inc(&cache->stats.discard_count);
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
7468c2ecf20Sopenharmony_ci	set_bit(from_dblock(b), cache->discard_bitset);
7478c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
7488c2ecf20Sopenharmony_ci}
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_cistatic void clear_discard(struct cache *cache, dm_dblock_t b)
7518c2ecf20Sopenharmony_ci{
7528c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
7538c2ecf20Sopenharmony_ci	clear_bit(from_dblock(b), cache->discard_bitset);
7548c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
7558c2ecf20Sopenharmony_ci}
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_cistatic bool is_discarded(struct cache *cache, dm_dblock_t b)
7588c2ecf20Sopenharmony_ci{
7598c2ecf20Sopenharmony_ci	int r;
7608c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
7618c2ecf20Sopenharmony_ci	r = test_bit(from_dblock(b), cache->discard_bitset);
7628c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
7638c2ecf20Sopenharmony_ci
7648c2ecf20Sopenharmony_ci	return r;
7658c2ecf20Sopenharmony_ci}
7668c2ecf20Sopenharmony_ci
7678c2ecf20Sopenharmony_cistatic bool is_discarded_oblock(struct cache *cache, dm_oblock_t b)
7688c2ecf20Sopenharmony_ci{
7698c2ecf20Sopenharmony_ci	int r;
7708c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
7718c2ecf20Sopenharmony_ci	r = test_bit(from_dblock(oblock_to_dblock(cache, b)),
7728c2ecf20Sopenharmony_ci		     cache->discard_bitset);
7738c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	return r;
7768c2ecf20Sopenharmony_ci}
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
7798c2ecf20Sopenharmony_ci * Remapping
7808c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
7818c2ecf20Sopenharmony_cistatic void remap_to_origin(struct cache *cache, struct bio *bio)
7828c2ecf20Sopenharmony_ci{
7838c2ecf20Sopenharmony_ci	bio_set_dev(bio, cache->origin_dev->bdev);
7848c2ecf20Sopenharmony_ci}
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_cistatic void remap_to_cache(struct cache *cache, struct bio *bio,
7878c2ecf20Sopenharmony_ci			   dm_cblock_t cblock)
7888c2ecf20Sopenharmony_ci{
7898c2ecf20Sopenharmony_ci	sector_t bi_sector = bio->bi_iter.bi_sector;
7908c2ecf20Sopenharmony_ci	sector_t block = from_cblock(cblock);
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci	bio_set_dev(bio, cache->cache_dev->bdev);
7938c2ecf20Sopenharmony_ci	if (!block_size_is_power_of_two(cache))
7948c2ecf20Sopenharmony_ci		bio->bi_iter.bi_sector =
7958c2ecf20Sopenharmony_ci			(block * cache->sectors_per_block) +
7968c2ecf20Sopenharmony_ci			sector_div(bi_sector, cache->sectors_per_block);
7978c2ecf20Sopenharmony_ci	else
7988c2ecf20Sopenharmony_ci		bio->bi_iter.bi_sector =
7998c2ecf20Sopenharmony_ci			(block << cache->sectors_per_block_shift) |
8008c2ecf20Sopenharmony_ci			(bi_sector & (cache->sectors_per_block - 1));
8018c2ecf20Sopenharmony_ci}
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_cistatic void check_if_tick_bio_needed(struct cache *cache, struct bio *bio)
8048c2ecf20Sopenharmony_ci{
8058c2ecf20Sopenharmony_ci	struct per_bio_data *pb;
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
8088c2ecf20Sopenharmony_ci	if (cache->need_tick_bio && !op_is_flush(bio->bi_opf) &&
8098c2ecf20Sopenharmony_ci	    bio_op(bio) != REQ_OP_DISCARD) {
8108c2ecf20Sopenharmony_ci		pb = get_per_bio_data(bio);
8118c2ecf20Sopenharmony_ci		pb->tick = true;
8128c2ecf20Sopenharmony_ci		cache->need_tick_bio = false;
8138c2ecf20Sopenharmony_ci	}
8148c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
8158c2ecf20Sopenharmony_ci}
8168c2ecf20Sopenharmony_ci
8178c2ecf20Sopenharmony_cistatic void __remap_to_origin_clear_discard(struct cache *cache, struct bio *bio,
8188c2ecf20Sopenharmony_ci					    dm_oblock_t oblock, bool bio_has_pbd)
8198c2ecf20Sopenharmony_ci{
8208c2ecf20Sopenharmony_ci	if (bio_has_pbd)
8218c2ecf20Sopenharmony_ci		check_if_tick_bio_needed(cache, bio);
8228c2ecf20Sopenharmony_ci	remap_to_origin(cache, bio);
8238c2ecf20Sopenharmony_ci	if (bio_data_dir(bio) == WRITE)
8248c2ecf20Sopenharmony_ci		clear_discard(cache, oblock_to_dblock(cache, oblock));
8258c2ecf20Sopenharmony_ci}
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_cistatic void remap_to_origin_clear_discard(struct cache *cache, struct bio *bio,
8288c2ecf20Sopenharmony_ci					  dm_oblock_t oblock)
8298c2ecf20Sopenharmony_ci{
8308c2ecf20Sopenharmony_ci	// FIXME: check_if_tick_bio_needed() is called way too much through this interface
8318c2ecf20Sopenharmony_ci	__remap_to_origin_clear_discard(cache, bio, oblock, true);
8328c2ecf20Sopenharmony_ci}
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_cistatic void remap_to_cache_dirty(struct cache *cache, struct bio *bio,
8358c2ecf20Sopenharmony_ci				 dm_oblock_t oblock, dm_cblock_t cblock)
8368c2ecf20Sopenharmony_ci{
8378c2ecf20Sopenharmony_ci	check_if_tick_bio_needed(cache, bio);
8388c2ecf20Sopenharmony_ci	remap_to_cache(cache, bio, cblock);
8398c2ecf20Sopenharmony_ci	if (bio_data_dir(bio) == WRITE) {
8408c2ecf20Sopenharmony_ci		set_dirty(cache, cblock);
8418c2ecf20Sopenharmony_ci		clear_discard(cache, oblock_to_dblock(cache, oblock));
8428c2ecf20Sopenharmony_ci	}
8438c2ecf20Sopenharmony_ci}
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_cistatic dm_oblock_t get_bio_block(struct cache *cache, struct bio *bio)
8468c2ecf20Sopenharmony_ci{
8478c2ecf20Sopenharmony_ci	sector_t block_nr = bio->bi_iter.bi_sector;
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_ci	if (!block_size_is_power_of_two(cache))
8508c2ecf20Sopenharmony_ci		(void) sector_div(block_nr, cache->sectors_per_block);
8518c2ecf20Sopenharmony_ci	else
8528c2ecf20Sopenharmony_ci		block_nr >>= cache->sectors_per_block_shift;
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	return to_oblock(block_nr);
8558c2ecf20Sopenharmony_ci}
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_cistatic bool accountable_bio(struct cache *cache, struct bio *bio)
8588c2ecf20Sopenharmony_ci{
8598c2ecf20Sopenharmony_ci	return bio_op(bio) != REQ_OP_DISCARD;
8608c2ecf20Sopenharmony_ci}
8618c2ecf20Sopenharmony_ci
8628c2ecf20Sopenharmony_cistatic void accounted_begin(struct cache *cache, struct bio *bio)
8638c2ecf20Sopenharmony_ci{
8648c2ecf20Sopenharmony_ci	struct per_bio_data *pb;
8658c2ecf20Sopenharmony_ci
8668c2ecf20Sopenharmony_ci	if (accountable_bio(cache, bio)) {
8678c2ecf20Sopenharmony_ci		pb = get_per_bio_data(bio);
8688c2ecf20Sopenharmony_ci		pb->len = bio_sectors(bio);
8698c2ecf20Sopenharmony_ci		iot_io_begin(&cache->tracker, pb->len);
8708c2ecf20Sopenharmony_ci	}
8718c2ecf20Sopenharmony_ci}
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_cistatic void accounted_complete(struct cache *cache, struct bio *bio)
8748c2ecf20Sopenharmony_ci{
8758c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci	iot_io_end(&cache->tracker, pb->len);
8788c2ecf20Sopenharmony_ci}
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_cistatic void accounted_request(struct cache *cache, struct bio *bio)
8818c2ecf20Sopenharmony_ci{
8828c2ecf20Sopenharmony_ci	accounted_begin(cache, bio);
8838c2ecf20Sopenharmony_ci	submit_bio_noacct(bio);
8848c2ecf20Sopenharmony_ci}
8858c2ecf20Sopenharmony_ci
8868c2ecf20Sopenharmony_cistatic void issue_op(struct bio *bio, void *context)
8878c2ecf20Sopenharmony_ci{
8888c2ecf20Sopenharmony_ci	struct cache *cache = context;
8898c2ecf20Sopenharmony_ci	accounted_request(cache, bio);
8908c2ecf20Sopenharmony_ci}
8918c2ecf20Sopenharmony_ci
8928c2ecf20Sopenharmony_ci/*
8938c2ecf20Sopenharmony_ci * When running in writethrough mode we need to send writes to clean blocks
8948c2ecf20Sopenharmony_ci * to both the cache and origin devices.  Clone the bio and send them in parallel.
8958c2ecf20Sopenharmony_ci */
8968c2ecf20Sopenharmony_cistatic void remap_to_origin_and_cache(struct cache *cache, struct bio *bio,
8978c2ecf20Sopenharmony_ci				      dm_oblock_t oblock, dm_cblock_t cblock)
8988c2ecf20Sopenharmony_ci{
8998c2ecf20Sopenharmony_ci	struct bio *origin_bio = bio_clone_fast(bio, GFP_NOIO, &cache->bs);
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	BUG_ON(!origin_bio);
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ci	bio_chain(origin_bio, bio);
9048c2ecf20Sopenharmony_ci	/*
9058c2ecf20Sopenharmony_ci	 * Passing false to __remap_to_origin_clear_discard() skips
9068c2ecf20Sopenharmony_ci	 * all code that might use per_bio_data (since clone doesn't have it)
9078c2ecf20Sopenharmony_ci	 */
9088c2ecf20Sopenharmony_ci	__remap_to_origin_clear_discard(cache, origin_bio, oblock, false);
9098c2ecf20Sopenharmony_ci	submit_bio(origin_bio);
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_ci	remap_to_cache(cache, bio, cblock);
9128c2ecf20Sopenharmony_ci}
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
9158c2ecf20Sopenharmony_ci * Failure modes
9168c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
9178c2ecf20Sopenharmony_cistatic enum cache_metadata_mode get_cache_mode(struct cache *cache)
9188c2ecf20Sopenharmony_ci{
9198c2ecf20Sopenharmony_ci	return cache->features.mode;
9208c2ecf20Sopenharmony_ci}
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_cistatic const char *cache_device_name(struct cache *cache)
9238c2ecf20Sopenharmony_ci{
9248c2ecf20Sopenharmony_ci	return dm_table_device_name(cache->ti->table);
9258c2ecf20Sopenharmony_ci}
9268c2ecf20Sopenharmony_ci
9278c2ecf20Sopenharmony_cistatic void notify_mode_switch(struct cache *cache, enum cache_metadata_mode mode)
9288c2ecf20Sopenharmony_ci{
9298c2ecf20Sopenharmony_ci	const char *descs[] = {
9308c2ecf20Sopenharmony_ci		"write",
9318c2ecf20Sopenharmony_ci		"read-only",
9328c2ecf20Sopenharmony_ci		"fail"
9338c2ecf20Sopenharmony_ci	};
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	dm_table_event(cache->ti->table);
9368c2ecf20Sopenharmony_ci	DMINFO("%s: switching cache to %s mode",
9378c2ecf20Sopenharmony_ci	       cache_device_name(cache), descs[(int)mode]);
9388c2ecf20Sopenharmony_ci}
9398c2ecf20Sopenharmony_ci
9408c2ecf20Sopenharmony_cistatic void set_cache_mode(struct cache *cache, enum cache_metadata_mode new_mode)
9418c2ecf20Sopenharmony_ci{
9428c2ecf20Sopenharmony_ci	bool needs_check;
9438c2ecf20Sopenharmony_ci	enum cache_metadata_mode old_mode = get_cache_mode(cache);
9448c2ecf20Sopenharmony_ci
9458c2ecf20Sopenharmony_ci	if (dm_cache_metadata_needs_check(cache->cmd, &needs_check)) {
9468c2ecf20Sopenharmony_ci		DMERR("%s: unable to read needs_check flag, setting failure mode.",
9478c2ecf20Sopenharmony_ci		      cache_device_name(cache));
9488c2ecf20Sopenharmony_ci		new_mode = CM_FAIL;
9498c2ecf20Sopenharmony_ci	}
9508c2ecf20Sopenharmony_ci
9518c2ecf20Sopenharmony_ci	if (new_mode == CM_WRITE && needs_check) {
9528c2ecf20Sopenharmony_ci		DMERR("%s: unable to switch cache to write mode until repaired.",
9538c2ecf20Sopenharmony_ci		      cache_device_name(cache));
9548c2ecf20Sopenharmony_ci		if (old_mode != new_mode)
9558c2ecf20Sopenharmony_ci			new_mode = old_mode;
9568c2ecf20Sopenharmony_ci		else
9578c2ecf20Sopenharmony_ci			new_mode = CM_READ_ONLY;
9588c2ecf20Sopenharmony_ci	}
9598c2ecf20Sopenharmony_ci
9608c2ecf20Sopenharmony_ci	/* Never move out of fail mode */
9618c2ecf20Sopenharmony_ci	if (old_mode == CM_FAIL)
9628c2ecf20Sopenharmony_ci		new_mode = CM_FAIL;
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	switch (new_mode) {
9658c2ecf20Sopenharmony_ci	case CM_FAIL:
9668c2ecf20Sopenharmony_ci	case CM_READ_ONLY:
9678c2ecf20Sopenharmony_ci		dm_cache_metadata_set_read_only(cache->cmd);
9688c2ecf20Sopenharmony_ci		break;
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci	case CM_WRITE:
9718c2ecf20Sopenharmony_ci		dm_cache_metadata_set_read_write(cache->cmd);
9728c2ecf20Sopenharmony_ci		break;
9738c2ecf20Sopenharmony_ci	}
9748c2ecf20Sopenharmony_ci
9758c2ecf20Sopenharmony_ci	cache->features.mode = new_mode;
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci	if (new_mode != old_mode)
9788c2ecf20Sopenharmony_ci		notify_mode_switch(cache, new_mode);
9798c2ecf20Sopenharmony_ci}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_cistatic void abort_transaction(struct cache *cache)
9828c2ecf20Sopenharmony_ci{
9838c2ecf20Sopenharmony_ci	const char *dev_name = cache_device_name(cache);
9848c2ecf20Sopenharmony_ci
9858c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
9868c2ecf20Sopenharmony_ci		return;
9878c2ecf20Sopenharmony_ci
9888c2ecf20Sopenharmony_ci	DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
9898c2ecf20Sopenharmony_ci	if (dm_cache_metadata_abort(cache->cmd)) {
9908c2ecf20Sopenharmony_ci		DMERR("%s: failed to abort metadata transaction", dev_name);
9918c2ecf20Sopenharmony_ci		set_cache_mode(cache, CM_FAIL);
9928c2ecf20Sopenharmony_ci	}
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
9958c2ecf20Sopenharmony_ci		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
9968c2ecf20Sopenharmony_ci		set_cache_mode(cache, CM_FAIL);
9978c2ecf20Sopenharmony_ci	}
9988c2ecf20Sopenharmony_ci}
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_cistatic void metadata_operation_failed(struct cache *cache, const char *op, int r)
10018c2ecf20Sopenharmony_ci{
10028c2ecf20Sopenharmony_ci	DMERR_LIMIT("%s: metadata operation '%s' failed: error = %d",
10038c2ecf20Sopenharmony_ci		    cache_device_name(cache), op, r);
10048c2ecf20Sopenharmony_ci	abort_transaction(cache);
10058c2ecf20Sopenharmony_ci	set_cache_mode(cache, CM_READ_ONLY);
10068c2ecf20Sopenharmony_ci}
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_cistatic void load_stats(struct cache *cache)
10118c2ecf20Sopenharmony_ci{
10128c2ecf20Sopenharmony_ci	struct dm_cache_statistics stats;
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_ci	dm_cache_metadata_get_stats(cache->cmd, &stats);
10158c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.read_hit, stats.read_hits);
10168c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.read_miss, stats.read_misses);
10178c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.write_hit, stats.write_hits);
10188c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.write_miss, stats.write_misses);
10198c2ecf20Sopenharmony_ci}
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_cistatic void save_stats(struct cache *cache)
10228c2ecf20Sopenharmony_ci{
10238c2ecf20Sopenharmony_ci	struct dm_cache_statistics stats;
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
10268c2ecf20Sopenharmony_ci		return;
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	stats.read_hits = atomic_read(&cache->stats.read_hit);
10298c2ecf20Sopenharmony_ci	stats.read_misses = atomic_read(&cache->stats.read_miss);
10308c2ecf20Sopenharmony_ci	stats.write_hits = atomic_read(&cache->stats.write_hit);
10318c2ecf20Sopenharmony_ci	stats.write_misses = atomic_read(&cache->stats.write_miss);
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci	dm_cache_metadata_set_stats(cache->cmd, &stats);
10348c2ecf20Sopenharmony_ci}
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_cistatic void update_stats(struct cache_stats *stats, enum policy_operation op)
10378c2ecf20Sopenharmony_ci{
10388c2ecf20Sopenharmony_ci	switch (op) {
10398c2ecf20Sopenharmony_ci	case POLICY_PROMOTE:
10408c2ecf20Sopenharmony_ci		atomic_inc(&stats->promotion);
10418c2ecf20Sopenharmony_ci		break;
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_ci	case POLICY_DEMOTE:
10448c2ecf20Sopenharmony_ci		atomic_inc(&stats->demotion);
10458c2ecf20Sopenharmony_ci		break;
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ci	case POLICY_WRITEBACK:
10488c2ecf20Sopenharmony_ci		atomic_inc(&stats->writeback);
10498c2ecf20Sopenharmony_ci		break;
10508c2ecf20Sopenharmony_ci	}
10518c2ecf20Sopenharmony_ci}
10528c2ecf20Sopenharmony_ci
10538c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
10548c2ecf20Sopenharmony_ci * Migration processing
10558c2ecf20Sopenharmony_ci *
10568c2ecf20Sopenharmony_ci * Migration covers moving data from the origin device to the cache, or
10578c2ecf20Sopenharmony_ci * vice versa.
10588c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_cistatic void inc_io_migrations(struct cache *cache)
10618c2ecf20Sopenharmony_ci{
10628c2ecf20Sopenharmony_ci	atomic_inc(&cache->nr_io_migrations);
10638c2ecf20Sopenharmony_ci}
10648c2ecf20Sopenharmony_ci
10658c2ecf20Sopenharmony_cistatic void dec_io_migrations(struct cache *cache)
10668c2ecf20Sopenharmony_ci{
10678c2ecf20Sopenharmony_ci	atomic_dec(&cache->nr_io_migrations);
10688c2ecf20Sopenharmony_ci}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_cistatic bool discard_or_flush(struct bio *bio)
10718c2ecf20Sopenharmony_ci{
10728c2ecf20Sopenharmony_ci	return bio_op(bio) == REQ_OP_DISCARD || op_is_flush(bio->bi_opf);
10738c2ecf20Sopenharmony_ci}
10748c2ecf20Sopenharmony_ci
10758c2ecf20Sopenharmony_cistatic void calc_discard_block_range(struct cache *cache, struct bio *bio,
10768c2ecf20Sopenharmony_ci				     dm_dblock_t *b, dm_dblock_t *e)
10778c2ecf20Sopenharmony_ci{
10788c2ecf20Sopenharmony_ci	sector_t sb = bio->bi_iter.bi_sector;
10798c2ecf20Sopenharmony_ci	sector_t se = bio_end_sector(bio);
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci	*b = to_dblock(dm_sector_div_up(sb, cache->discard_block_size));
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	if (se - sb < cache->discard_block_size)
10848c2ecf20Sopenharmony_ci		*e = *b;
10858c2ecf20Sopenharmony_ci	else
10868c2ecf20Sopenharmony_ci		*e = to_dblock(block_div(se, cache->discard_block_size));
10878c2ecf20Sopenharmony_ci}
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_cistatic void prevent_background_work(struct cache *cache)
10928c2ecf20Sopenharmony_ci{
10938c2ecf20Sopenharmony_ci	lockdep_off();
10948c2ecf20Sopenharmony_ci	down_write(&cache->background_work_lock);
10958c2ecf20Sopenharmony_ci	lockdep_on();
10968c2ecf20Sopenharmony_ci}
10978c2ecf20Sopenharmony_ci
10988c2ecf20Sopenharmony_cistatic void allow_background_work(struct cache *cache)
10998c2ecf20Sopenharmony_ci{
11008c2ecf20Sopenharmony_ci	lockdep_off();
11018c2ecf20Sopenharmony_ci	up_write(&cache->background_work_lock);
11028c2ecf20Sopenharmony_ci	lockdep_on();
11038c2ecf20Sopenharmony_ci}
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_cistatic bool background_work_begin(struct cache *cache)
11068c2ecf20Sopenharmony_ci{
11078c2ecf20Sopenharmony_ci	bool r;
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci	lockdep_off();
11108c2ecf20Sopenharmony_ci	r = down_read_trylock(&cache->background_work_lock);
11118c2ecf20Sopenharmony_ci	lockdep_on();
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci	return r;
11148c2ecf20Sopenharmony_ci}
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_cistatic void background_work_end(struct cache *cache)
11178c2ecf20Sopenharmony_ci{
11188c2ecf20Sopenharmony_ci	lockdep_off();
11198c2ecf20Sopenharmony_ci	up_read(&cache->background_work_lock);
11208c2ecf20Sopenharmony_ci	lockdep_on();
11218c2ecf20Sopenharmony_ci}
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_cistatic bool bio_writes_complete_block(struct cache *cache, struct bio *bio)
11268c2ecf20Sopenharmony_ci{
11278c2ecf20Sopenharmony_ci	return (bio_data_dir(bio) == WRITE) &&
11288c2ecf20Sopenharmony_ci		(bio->bi_iter.bi_size == (cache->sectors_per_block << SECTOR_SHIFT));
11298c2ecf20Sopenharmony_ci}
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_cistatic bool optimisable_bio(struct cache *cache, struct bio *bio, dm_oblock_t block)
11328c2ecf20Sopenharmony_ci{
11338c2ecf20Sopenharmony_ci	return writeback_mode(cache) &&
11348c2ecf20Sopenharmony_ci		(is_discarded_oblock(cache, block) || bio_writes_complete_block(cache, bio));
11358c2ecf20Sopenharmony_ci}
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_cistatic void quiesce(struct dm_cache_migration *mg,
11388c2ecf20Sopenharmony_ci		    void (*continuation)(struct work_struct *))
11398c2ecf20Sopenharmony_ci{
11408c2ecf20Sopenharmony_ci	init_continuation(&mg->k, continuation);
11418c2ecf20Sopenharmony_ci	dm_cell_quiesce_v2(mg->cache->prison, mg->cell, &mg->k.ws);
11428c2ecf20Sopenharmony_ci}
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_cistatic struct dm_cache_migration *ws_to_mg(struct work_struct *ws)
11458c2ecf20Sopenharmony_ci{
11468c2ecf20Sopenharmony_ci	struct continuation *k = container_of(ws, struct continuation, ws);
11478c2ecf20Sopenharmony_ci	return container_of(k, struct dm_cache_migration, k);
11488c2ecf20Sopenharmony_ci}
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_cistatic void copy_complete(int read_err, unsigned long write_err, void *context)
11518c2ecf20Sopenharmony_ci{
11528c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = container_of(context, struct dm_cache_migration, k);
11538c2ecf20Sopenharmony_ci
11548c2ecf20Sopenharmony_ci	if (read_err || write_err)
11558c2ecf20Sopenharmony_ci		mg->k.input = BLK_STS_IOERR;
11568c2ecf20Sopenharmony_ci
11578c2ecf20Sopenharmony_ci	queue_continuation(mg->cache->wq, &mg->k);
11588c2ecf20Sopenharmony_ci}
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_cistatic void copy(struct dm_cache_migration *mg, bool promote)
11618c2ecf20Sopenharmony_ci{
11628c2ecf20Sopenharmony_ci	struct dm_io_region o_region, c_region;
11638c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
11648c2ecf20Sopenharmony_ci
11658c2ecf20Sopenharmony_ci	o_region.bdev = cache->origin_dev->bdev;
11668c2ecf20Sopenharmony_ci	o_region.sector = from_oblock(mg->op->oblock) * cache->sectors_per_block;
11678c2ecf20Sopenharmony_ci	o_region.count = cache->sectors_per_block;
11688c2ecf20Sopenharmony_ci
11698c2ecf20Sopenharmony_ci	c_region.bdev = cache->cache_dev->bdev;
11708c2ecf20Sopenharmony_ci	c_region.sector = from_cblock(mg->op->cblock) * cache->sectors_per_block;
11718c2ecf20Sopenharmony_ci	c_region.count = cache->sectors_per_block;
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_ci	if (promote)
11748c2ecf20Sopenharmony_ci		dm_kcopyd_copy(cache->copier, &o_region, 1, &c_region, 0, copy_complete, &mg->k);
11758c2ecf20Sopenharmony_ci	else
11768c2ecf20Sopenharmony_ci		dm_kcopyd_copy(cache->copier, &c_region, 1, &o_region, 0, copy_complete, &mg->k);
11778c2ecf20Sopenharmony_ci}
11788c2ecf20Sopenharmony_ci
11798c2ecf20Sopenharmony_cistatic void bio_drop_shared_lock(struct cache *cache, struct bio *bio)
11808c2ecf20Sopenharmony_ci{
11818c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
11828c2ecf20Sopenharmony_ci
11838c2ecf20Sopenharmony_ci	if (pb->cell && dm_cell_put_v2(cache->prison, pb->cell))
11848c2ecf20Sopenharmony_ci		free_prison_cell(cache, pb->cell);
11858c2ecf20Sopenharmony_ci	pb->cell = NULL;
11868c2ecf20Sopenharmony_ci}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_cistatic void overwrite_endio(struct bio *bio)
11898c2ecf20Sopenharmony_ci{
11908c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = bio->bi_private;
11918c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
11928c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
11938c2ecf20Sopenharmony_ci
11948c2ecf20Sopenharmony_ci	dm_unhook_bio(&pb->hook_info, bio);
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci	if (bio->bi_status)
11978c2ecf20Sopenharmony_ci		mg->k.input = bio->bi_status;
11988c2ecf20Sopenharmony_ci
11998c2ecf20Sopenharmony_ci	queue_continuation(cache->wq, &mg->k);
12008c2ecf20Sopenharmony_ci}
12018c2ecf20Sopenharmony_ci
12028c2ecf20Sopenharmony_cistatic void overwrite(struct dm_cache_migration *mg,
12038c2ecf20Sopenharmony_ci		      void (*continuation)(struct work_struct *))
12048c2ecf20Sopenharmony_ci{
12058c2ecf20Sopenharmony_ci	struct bio *bio = mg->overwrite_bio;
12068c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci	dm_hook_bio(&pb->hook_info, bio, overwrite_endio, mg);
12098c2ecf20Sopenharmony_ci
12108c2ecf20Sopenharmony_ci	/*
12118c2ecf20Sopenharmony_ci	 * The overwrite bio is part of the copy operation, as such it does
12128c2ecf20Sopenharmony_ci	 * not set/clear discard or dirty flags.
12138c2ecf20Sopenharmony_ci	 */
12148c2ecf20Sopenharmony_ci	if (mg->op->op == POLICY_PROMOTE)
12158c2ecf20Sopenharmony_ci		remap_to_cache(mg->cache, bio, mg->op->cblock);
12168c2ecf20Sopenharmony_ci	else
12178c2ecf20Sopenharmony_ci		remap_to_origin(mg->cache, bio);
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci	init_continuation(&mg->k, continuation);
12208c2ecf20Sopenharmony_ci	accounted_request(mg->cache, bio);
12218c2ecf20Sopenharmony_ci}
12228c2ecf20Sopenharmony_ci
12238c2ecf20Sopenharmony_ci/*
12248c2ecf20Sopenharmony_ci * Migration steps:
12258c2ecf20Sopenharmony_ci *
12268c2ecf20Sopenharmony_ci * 1) exclusive lock preventing WRITEs
12278c2ecf20Sopenharmony_ci * 2) quiesce
12288c2ecf20Sopenharmony_ci * 3) copy or issue overwrite bio
12298c2ecf20Sopenharmony_ci * 4) upgrade to exclusive lock preventing READs and WRITEs
12308c2ecf20Sopenharmony_ci * 5) quiesce
12318c2ecf20Sopenharmony_ci * 6) update metadata and commit
12328c2ecf20Sopenharmony_ci * 7) unlock
12338c2ecf20Sopenharmony_ci */
12348c2ecf20Sopenharmony_cistatic void mg_complete(struct dm_cache_migration *mg, bool success)
12358c2ecf20Sopenharmony_ci{
12368c2ecf20Sopenharmony_ci	struct bio_list bios;
12378c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
12388c2ecf20Sopenharmony_ci	struct policy_work *op = mg->op;
12398c2ecf20Sopenharmony_ci	dm_cblock_t cblock = op->cblock;
12408c2ecf20Sopenharmony_ci
12418c2ecf20Sopenharmony_ci	if (success)
12428c2ecf20Sopenharmony_ci		update_stats(&cache->stats, op->op);
12438c2ecf20Sopenharmony_ci
12448c2ecf20Sopenharmony_ci	switch (op->op) {
12458c2ecf20Sopenharmony_ci	case POLICY_PROMOTE:
12468c2ecf20Sopenharmony_ci		clear_discard(cache, oblock_to_dblock(cache, op->oblock));
12478c2ecf20Sopenharmony_ci		policy_complete_background_work(cache->policy, op, success);
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_ci		if (mg->overwrite_bio) {
12508c2ecf20Sopenharmony_ci			if (success)
12518c2ecf20Sopenharmony_ci				force_set_dirty(cache, cblock);
12528c2ecf20Sopenharmony_ci			else if (mg->k.input)
12538c2ecf20Sopenharmony_ci				mg->overwrite_bio->bi_status = mg->k.input;
12548c2ecf20Sopenharmony_ci			else
12558c2ecf20Sopenharmony_ci				mg->overwrite_bio->bi_status = BLK_STS_IOERR;
12568c2ecf20Sopenharmony_ci			bio_endio(mg->overwrite_bio);
12578c2ecf20Sopenharmony_ci		} else {
12588c2ecf20Sopenharmony_ci			if (success)
12598c2ecf20Sopenharmony_ci				force_clear_dirty(cache, cblock);
12608c2ecf20Sopenharmony_ci			dec_io_migrations(cache);
12618c2ecf20Sopenharmony_ci		}
12628c2ecf20Sopenharmony_ci		break;
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	case POLICY_DEMOTE:
12658c2ecf20Sopenharmony_ci		/*
12668c2ecf20Sopenharmony_ci		 * We clear dirty here to update the nr_dirty counter.
12678c2ecf20Sopenharmony_ci		 */
12688c2ecf20Sopenharmony_ci		if (success)
12698c2ecf20Sopenharmony_ci			force_clear_dirty(cache, cblock);
12708c2ecf20Sopenharmony_ci		policy_complete_background_work(cache->policy, op, success);
12718c2ecf20Sopenharmony_ci		dec_io_migrations(cache);
12728c2ecf20Sopenharmony_ci		break;
12738c2ecf20Sopenharmony_ci
12748c2ecf20Sopenharmony_ci	case POLICY_WRITEBACK:
12758c2ecf20Sopenharmony_ci		if (success)
12768c2ecf20Sopenharmony_ci			force_clear_dirty(cache, cblock);
12778c2ecf20Sopenharmony_ci		policy_complete_background_work(cache->policy, op, success);
12788c2ecf20Sopenharmony_ci		dec_io_migrations(cache);
12798c2ecf20Sopenharmony_ci		break;
12808c2ecf20Sopenharmony_ci	}
12818c2ecf20Sopenharmony_ci
12828c2ecf20Sopenharmony_ci	bio_list_init(&bios);
12838c2ecf20Sopenharmony_ci	if (mg->cell) {
12848c2ecf20Sopenharmony_ci		if (dm_cell_unlock_v2(cache->prison, mg->cell, &bios))
12858c2ecf20Sopenharmony_ci			free_prison_cell(cache, mg->cell);
12868c2ecf20Sopenharmony_ci	}
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_ci	free_migration(mg);
12898c2ecf20Sopenharmony_ci	defer_bios(cache, &bios);
12908c2ecf20Sopenharmony_ci	wake_migration_worker(cache);
12918c2ecf20Sopenharmony_ci
12928c2ecf20Sopenharmony_ci	background_work_end(cache);
12938c2ecf20Sopenharmony_ci}
12948c2ecf20Sopenharmony_ci
12958c2ecf20Sopenharmony_cistatic void mg_success(struct work_struct *ws)
12968c2ecf20Sopenharmony_ci{
12978c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
12988c2ecf20Sopenharmony_ci	mg_complete(mg, mg->k.input == 0);
12998c2ecf20Sopenharmony_ci}
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_cistatic void mg_update_metadata(struct work_struct *ws)
13028c2ecf20Sopenharmony_ci{
13038c2ecf20Sopenharmony_ci	int r;
13048c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
13058c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
13068c2ecf20Sopenharmony_ci	struct policy_work *op = mg->op;
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_ci	switch (op->op) {
13098c2ecf20Sopenharmony_ci	case POLICY_PROMOTE:
13108c2ecf20Sopenharmony_ci		r = dm_cache_insert_mapping(cache->cmd, op->cblock, op->oblock);
13118c2ecf20Sopenharmony_ci		if (r) {
13128c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: migration failed; couldn't insert mapping",
13138c2ecf20Sopenharmony_ci				    cache_device_name(cache));
13148c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_insert_mapping", r);
13158c2ecf20Sopenharmony_ci
13168c2ecf20Sopenharmony_ci			mg_complete(mg, false);
13178c2ecf20Sopenharmony_ci			return;
13188c2ecf20Sopenharmony_ci		}
13198c2ecf20Sopenharmony_ci		mg_complete(mg, true);
13208c2ecf20Sopenharmony_ci		break;
13218c2ecf20Sopenharmony_ci
13228c2ecf20Sopenharmony_ci	case POLICY_DEMOTE:
13238c2ecf20Sopenharmony_ci		r = dm_cache_remove_mapping(cache->cmd, op->cblock);
13248c2ecf20Sopenharmony_ci		if (r) {
13258c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: migration failed; couldn't update on disk metadata",
13268c2ecf20Sopenharmony_ci				    cache_device_name(cache));
13278c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_remove_mapping", r);
13288c2ecf20Sopenharmony_ci
13298c2ecf20Sopenharmony_ci			mg_complete(mg, false);
13308c2ecf20Sopenharmony_ci			return;
13318c2ecf20Sopenharmony_ci		}
13328c2ecf20Sopenharmony_ci
13338c2ecf20Sopenharmony_ci		/*
13348c2ecf20Sopenharmony_ci		 * It would be nice if we only had to commit when a REQ_FLUSH
13358c2ecf20Sopenharmony_ci		 * comes through.  But there's one scenario that we have to
13368c2ecf20Sopenharmony_ci		 * look out for:
13378c2ecf20Sopenharmony_ci		 *
13388c2ecf20Sopenharmony_ci		 * - vblock x in a cache block
13398c2ecf20Sopenharmony_ci		 * - domotion occurs
13408c2ecf20Sopenharmony_ci		 * - cache block gets reallocated and over written
13418c2ecf20Sopenharmony_ci		 * - crash
13428c2ecf20Sopenharmony_ci		 *
13438c2ecf20Sopenharmony_ci		 * When we recover, because there was no commit the cache will
13448c2ecf20Sopenharmony_ci		 * rollback to having the data for vblock x in the cache block.
13458c2ecf20Sopenharmony_ci		 * But the cache block has since been overwritten, so it'll end
13468c2ecf20Sopenharmony_ci		 * up pointing to data that was never in 'x' during the history
13478c2ecf20Sopenharmony_ci		 * of the device.
13488c2ecf20Sopenharmony_ci		 *
13498c2ecf20Sopenharmony_ci		 * To avoid this issue we require a commit as part of the
13508c2ecf20Sopenharmony_ci		 * demotion operation.
13518c2ecf20Sopenharmony_ci		 */
13528c2ecf20Sopenharmony_ci		init_continuation(&mg->k, mg_success);
13538c2ecf20Sopenharmony_ci		continue_after_commit(&cache->committer, &mg->k);
13548c2ecf20Sopenharmony_ci		schedule_commit(&cache->committer);
13558c2ecf20Sopenharmony_ci		break;
13568c2ecf20Sopenharmony_ci
13578c2ecf20Sopenharmony_ci	case POLICY_WRITEBACK:
13588c2ecf20Sopenharmony_ci		mg_complete(mg, true);
13598c2ecf20Sopenharmony_ci		break;
13608c2ecf20Sopenharmony_ci	}
13618c2ecf20Sopenharmony_ci}
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_cistatic void mg_update_metadata_after_copy(struct work_struct *ws)
13648c2ecf20Sopenharmony_ci{
13658c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
13668c2ecf20Sopenharmony_ci
13678c2ecf20Sopenharmony_ci	/*
13688c2ecf20Sopenharmony_ci	 * Did the copy succeed?
13698c2ecf20Sopenharmony_ci	 */
13708c2ecf20Sopenharmony_ci	if (mg->k.input)
13718c2ecf20Sopenharmony_ci		mg_complete(mg, false);
13728c2ecf20Sopenharmony_ci	else
13738c2ecf20Sopenharmony_ci		mg_update_metadata(ws);
13748c2ecf20Sopenharmony_ci}
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_cistatic void mg_upgrade_lock(struct work_struct *ws)
13778c2ecf20Sopenharmony_ci{
13788c2ecf20Sopenharmony_ci	int r;
13798c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
13808c2ecf20Sopenharmony_ci
13818c2ecf20Sopenharmony_ci	/*
13828c2ecf20Sopenharmony_ci	 * Did the copy succeed?
13838c2ecf20Sopenharmony_ci	 */
13848c2ecf20Sopenharmony_ci	if (mg->k.input)
13858c2ecf20Sopenharmony_ci		mg_complete(mg, false);
13868c2ecf20Sopenharmony_ci
13878c2ecf20Sopenharmony_ci	else {
13888c2ecf20Sopenharmony_ci		/*
13898c2ecf20Sopenharmony_ci		 * Now we want the lock to prevent both reads and writes.
13908c2ecf20Sopenharmony_ci		 */
13918c2ecf20Sopenharmony_ci		r = dm_cell_lock_promote_v2(mg->cache->prison, mg->cell,
13928c2ecf20Sopenharmony_ci					    READ_WRITE_LOCK_LEVEL);
13938c2ecf20Sopenharmony_ci		if (r < 0)
13948c2ecf20Sopenharmony_ci			mg_complete(mg, false);
13958c2ecf20Sopenharmony_ci
13968c2ecf20Sopenharmony_ci		else if (r)
13978c2ecf20Sopenharmony_ci			quiesce(mg, mg_update_metadata);
13988c2ecf20Sopenharmony_ci
13998c2ecf20Sopenharmony_ci		else
14008c2ecf20Sopenharmony_ci			mg_update_metadata(ws);
14018c2ecf20Sopenharmony_ci	}
14028c2ecf20Sopenharmony_ci}
14038c2ecf20Sopenharmony_ci
14048c2ecf20Sopenharmony_cistatic void mg_full_copy(struct work_struct *ws)
14058c2ecf20Sopenharmony_ci{
14068c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
14078c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
14088c2ecf20Sopenharmony_ci	struct policy_work *op = mg->op;
14098c2ecf20Sopenharmony_ci	bool is_policy_promote = (op->op == POLICY_PROMOTE);
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	if ((!is_policy_promote && !is_dirty(cache, op->cblock)) ||
14128c2ecf20Sopenharmony_ci	    is_discarded_oblock(cache, op->oblock)) {
14138c2ecf20Sopenharmony_ci		mg_upgrade_lock(ws);
14148c2ecf20Sopenharmony_ci		return;
14158c2ecf20Sopenharmony_ci	}
14168c2ecf20Sopenharmony_ci
14178c2ecf20Sopenharmony_ci	init_continuation(&mg->k, mg_upgrade_lock);
14188c2ecf20Sopenharmony_ci	copy(mg, is_policy_promote);
14198c2ecf20Sopenharmony_ci}
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_cistatic void mg_copy(struct work_struct *ws)
14228c2ecf20Sopenharmony_ci{
14238c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_ci	if (mg->overwrite_bio) {
14268c2ecf20Sopenharmony_ci		/*
14278c2ecf20Sopenharmony_ci		 * No exclusive lock was held when we last checked if the bio
14288c2ecf20Sopenharmony_ci		 * was optimisable.  So we have to check again in case things
14298c2ecf20Sopenharmony_ci		 * have changed (eg, the block may no longer be discarded).
14308c2ecf20Sopenharmony_ci		 */
14318c2ecf20Sopenharmony_ci		if (!optimisable_bio(mg->cache, mg->overwrite_bio, mg->op->oblock)) {
14328c2ecf20Sopenharmony_ci			/*
14338c2ecf20Sopenharmony_ci			 * Fallback to a real full copy after doing some tidying up.
14348c2ecf20Sopenharmony_ci			 */
14358c2ecf20Sopenharmony_ci			bool rb = bio_detain_shared(mg->cache, mg->op->oblock, mg->overwrite_bio);
14368c2ecf20Sopenharmony_ci			BUG_ON(rb); /* An exclussive lock must _not_ be held for this block */
14378c2ecf20Sopenharmony_ci			mg->overwrite_bio = NULL;
14388c2ecf20Sopenharmony_ci			inc_io_migrations(mg->cache);
14398c2ecf20Sopenharmony_ci			mg_full_copy(ws);
14408c2ecf20Sopenharmony_ci			return;
14418c2ecf20Sopenharmony_ci		}
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci		/*
14448c2ecf20Sopenharmony_ci		 * It's safe to do this here, even though it's new data
14458c2ecf20Sopenharmony_ci		 * because all IO has been locked out of the block.
14468c2ecf20Sopenharmony_ci		 *
14478c2ecf20Sopenharmony_ci		 * mg_lock_writes() already took READ_WRITE_LOCK_LEVEL
14488c2ecf20Sopenharmony_ci		 * so _not_ using mg_upgrade_lock() as continutation.
14498c2ecf20Sopenharmony_ci		 */
14508c2ecf20Sopenharmony_ci		overwrite(mg, mg_update_metadata_after_copy);
14518c2ecf20Sopenharmony_ci
14528c2ecf20Sopenharmony_ci	} else
14538c2ecf20Sopenharmony_ci		mg_full_copy(ws);
14548c2ecf20Sopenharmony_ci}
14558c2ecf20Sopenharmony_ci
14568c2ecf20Sopenharmony_cistatic int mg_lock_writes(struct dm_cache_migration *mg)
14578c2ecf20Sopenharmony_ci{
14588c2ecf20Sopenharmony_ci	int r;
14598c2ecf20Sopenharmony_ci	struct dm_cell_key_v2 key;
14608c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
14618c2ecf20Sopenharmony_ci	struct dm_bio_prison_cell_v2 *prealloc;
14628c2ecf20Sopenharmony_ci
14638c2ecf20Sopenharmony_ci	prealloc = alloc_prison_cell(cache);
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_ci	/*
14668c2ecf20Sopenharmony_ci	 * Prevent writes to the block, but allow reads to continue.
14678c2ecf20Sopenharmony_ci	 * Unless we're using an overwrite bio, in which case we lock
14688c2ecf20Sopenharmony_ci	 * everything.
14698c2ecf20Sopenharmony_ci	 */
14708c2ecf20Sopenharmony_ci	build_key(mg->op->oblock, oblock_succ(mg->op->oblock), &key);
14718c2ecf20Sopenharmony_ci	r = dm_cell_lock_v2(cache->prison, &key,
14728c2ecf20Sopenharmony_ci			    mg->overwrite_bio ?  READ_WRITE_LOCK_LEVEL : WRITE_LOCK_LEVEL,
14738c2ecf20Sopenharmony_ci			    prealloc, &mg->cell);
14748c2ecf20Sopenharmony_ci	if (r < 0) {
14758c2ecf20Sopenharmony_ci		free_prison_cell(cache, prealloc);
14768c2ecf20Sopenharmony_ci		mg_complete(mg, false);
14778c2ecf20Sopenharmony_ci		return r;
14788c2ecf20Sopenharmony_ci	}
14798c2ecf20Sopenharmony_ci
14808c2ecf20Sopenharmony_ci	if (mg->cell != prealloc)
14818c2ecf20Sopenharmony_ci		free_prison_cell(cache, prealloc);
14828c2ecf20Sopenharmony_ci
14838c2ecf20Sopenharmony_ci	if (r == 0)
14848c2ecf20Sopenharmony_ci		mg_copy(&mg->k.ws);
14858c2ecf20Sopenharmony_ci	else
14868c2ecf20Sopenharmony_ci		quiesce(mg, mg_copy);
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_ci	return 0;
14898c2ecf20Sopenharmony_ci}
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_cistatic int mg_start(struct cache *cache, struct policy_work *op, struct bio *bio)
14928c2ecf20Sopenharmony_ci{
14938c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg;
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ci	if (!background_work_begin(cache)) {
14968c2ecf20Sopenharmony_ci		policy_complete_background_work(cache->policy, op, false);
14978c2ecf20Sopenharmony_ci		return -EPERM;
14988c2ecf20Sopenharmony_ci	}
14998c2ecf20Sopenharmony_ci
15008c2ecf20Sopenharmony_ci	mg = alloc_migration(cache);
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	mg->op = op;
15038c2ecf20Sopenharmony_ci	mg->overwrite_bio = bio;
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci	if (!bio)
15068c2ecf20Sopenharmony_ci		inc_io_migrations(cache);
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_ci	return mg_lock_writes(mg);
15098c2ecf20Sopenharmony_ci}
15108c2ecf20Sopenharmony_ci
15118c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
15128c2ecf20Sopenharmony_ci * invalidation processing
15138c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
15148c2ecf20Sopenharmony_ci
15158c2ecf20Sopenharmony_cistatic void invalidate_complete(struct dm_cache_migration *mg, bool success)
15168c2ecf20Sopenharmony_ci{
15178c2ecf20Sopenharmony_ci	struct bio_list bios;
15188c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
15198c2ecf20Sopenharmony_ci
15208c2ecf20Sopenharmony_ci	bio_list_init(&bios);
15218c2ecf20Sopenharmony_ci	if (dm_cell_unlock_v2(cache->prison, mg->cell, &bios))
15228c2ecf20Sopenharmony_ci		free_prison_cell(cache, mg->cell);
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci	if (!success && mg->overwrite_bio)
15258c2ecf20Sopenharmony_ci		bio_io_error(mg->overwrite_bio);
15268c2ecf20Sopenharmony_ci
15278c2ecf20Sopenharmony_ci	free_migration(mg);
15288c2ecf20Sopenharmony_ci	defer_bios(cache, &bios);
15298c2ecf20Sopenharmony_ci
15308c2ecf20Sopenharmony_ci	background_work_end(cache);
15318c2ecf20Sopenharmony_ci}
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_cistatic void invalidate_completed(struct work_struct *ws)
15348c2ecf20Sopenharmony_ci{
15358c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
15368c2ecf20Sopenharmony_ci	invalidate_complete(mg, !mg->k.input);
15378c2ecf20Sopenharmony_ci}
15388c2ecf20Sopenharmony_ci
15398c2ecf20Sopenharmony_cistatic int invalidate_cblock(struct cache *cache, dm_cblock_t cblock)
15408c2ecf20Sopenharmony_ci{
15418c2ecf20Sopenharmony_ci	int r = policy_invalidate_mapping(cache->policy, cblock);
15428c2ecf20Sopenharmony_ci	if (!r) {
15438c2ecf20Sopenharmony_ci		r = dm_cache_remove_mapping(cache->cmd, cblock);
15448c2ecf20Sopenharmony_ci		if (r) {
15458c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: invalidation failed; couldn't update on disk metadata",
15468c2ecf20Sopenharmony_ci				    cache_device_name(cache));
15478c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_remove_mapping", r);
15488c2ecf20Sopenharmony_ci		}
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_ci	} else if (r == -ENODATA) {
15518c2ecf20Sopenharmony_ci		/*
15528c2ecf20Sopenharmony_ci		 * Harmless, already unmapped.
15538c2ecf20Sopenharmony_ci		 */
15548c2ecf20Sopenharmony_ci		r = 0;
15558c2ecf20Sopenharmony_ci
15568c2ecf20Sopenharmony_ci	} else
15578c2ecf20Sopenharmony_ci		DMERR("%s: policy_invalidate_mapping failed", cache_device_name(cache));
15588c2ecf20Sopenharmony_ci
15598c2ecf20Sopenharmony_ci	return r;
15608c2ecf20Sopenharmony_ci}
15618c2ecf20Sopenharmony_ci
15628c2ecf20Sopenharmony_cistatic void invalidate_remove(struct work_struct *ws)
15638c2ecf20Sopenharmony_ci{
15648c2ecf20Sopenharmony_ci	int r;
15658c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg = ws_to_mg(ws);
15668c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci	r = invalidate_cblock(cache, mg->invalidate_cblock);
15698c2ecf20Sopenharmony_ci	if (r) {
15708c2ecf20Sopenharmony_ci		invalidate_complete(mg, false);
15718c2ecf20Sopenharmony_ci		return;
15728c2ecf20Sopenharmony_ci	}
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci	init_continuation(&mg->k, invalidate_completed);
15758c2ecf20Sopenharmony_ci	continue_after_commit(&cache->committer, &mg->k);
15768c2ecf20Sopenharmony_ci	remap_to_origin_clear_discard(cache, mg->overwrite_bio, mg->invalidate_oblock);
15778c2ecf20Sopenharmony_ci	mg->overwrite_bio = NULL;
15788c2ecf20Sopenharmony_ci	schedule_commit(&cache->committer);
15798c2ecf20Sopenharmony_ci}
15808c2ecf20Sopenharmony_ci
15818c2ecf20Sopenharmony_cistatic int invalidate_lock(struct dm_cache_migration *mg)
15828c2ecf20Sopenharmony_ci{
15838c2ecf20Sopenharmony_ci	int r;
15848c2ecf20Sopenharmony_ci	struct dm_cell_key_v2 key;
15858c2ecf20Sopenharmony_ci	struct cache *cache = mg->cache;
15868c2ecf20Sopenharmony_ci	struct dm_bio_prison_cell_v2 *prealloc;
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci	prealloc = alloc_prison_cell(cache);
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_ci	build_key(mg->invalidate_oblock, oblock_succ(mg->invalidate_oblock), &key);
15918c2ecf20Sopenharmony_ci	r = dm_cell_lock_v2(cache->prison, &key,
15928c2ecf20Sopenharmony_ci			    READ_WRITE_LOCK_LEVEL, prealloc, &mg->cell);
15938c2ecf20Sopenharmony_ci	if (r < 0) {
15948c2ecf20Sopenharmony_ci		free_prison_cell(cache, prealloc);
15958c2ecf20Sopenharmony_ci		invalidate_complete(mg, false);
15968c2ecf20Sopenharmony_ci		return r;
15978c2ecf20Sopenharmony_ci	}
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_ci	if (mg->cell != prealloc)
16008c2ecf20Sopenharmony_ci		free_prison_cell(cache, prealloc);
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_ci	if (r)
16038c2ecf20Sopenharmony_ci		quiesce(mg, invalidate_remove);
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_ci	else {
16068c2ecf20Sopenharmony_ci		/*
16078c2ecf20Sopenharmony_ci		 * We can't call invalidate_remove() directly here because we
16088c2ecf20Sopenharmony_ci		 * might still be in request context.
16098c2ecf20Sopenharmony_ci		 */
16108c2ecf20Sopenharmony_ci		init_continuation(&mg->k, invalidate_remove);
16118c2ecf20Sopenharmony_ci		queue_work(cache->wq, &mg->k.ws);
16128c2ecf20Sopenharmony_ci	}
16138c2ecf20Sopenharmony_ci
16148c2ecf20Sopenharmony_ci	return 0;
16158c2ecf20Sopenharmony_ci}
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_cistatic int invalidate_start(struct cache *cache, dm_cblock_t cblock,
16188c2ecf20Sopenharmony_ci			    dm_oblock_t oblock, struct bio *bio)
16198c2ecf20Sopenharmony_ci{
16208c2ecf20Sopenharmony_ci	struct dm_cache_migration *mg;
16218c2ecf20Sopenharmony_ci
16228c2ecf20Sopenharmony_ci	if (!background_work_begin(cache))
16238c2ecf20Sopenharmony_ci		return -EPERM;
16248c2ecf20Sopenharmony_ci
16258c2ecf20Sopenharmony_ci	mg = alloc_migration(cache);
16268c2ecf20Sopenharmony_ci
16278c2ecf20Sopenharmony_ci	mg->overwrite_bio = bio;
16288c2ecf20Sopenharmony_ci	mg->invalidate_cblock = cblock;
16298c2ecf20Sopenharmony_ci	mg->invalidate_oblock = oblock;
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci	return invalidate_lock(mg);
16328c2ecf20Sopenharmony_ci}
16338c2ecf20Sopenharmony_ci
16348c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
16358c2ecf20Sopenharmony_ci * bio processing
16368c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
16378c2ecf20Sopenharmony_ci
16388c2ecf20Sopenharmony_cienum busy {
16398c2ecf20Sopenharmony_ci	IDLE,
16408c2ecf20Sopenharmony_ci	BUSY
16418c2ecf20Sopenharmony_ci};
16428c2ecf20Sopenharmony_ci
16438c2ecf20Sopenharmony_cistatic enum busy spare_migration_bandwidth(struct cache *cache)
16448c2ecf20Sopenharmony_ci{
16458c2ecf20Sopenharmony_ci	bool idle = iot_idle_for(&cache->tracker, HZ);
16468c2ecf20Sopenharmony_ci	sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
16478c2ecf20Sopenharmony_ci		cache->sectors_per_block;
16488c2ecf20Sopenharmony_ci
16498c2ecf20Sopenharmony_ci	if (idle && current_volume <= cache->migration_threshold)
16508c2ecf20Sopenharmony_ci		return IDLE;
16518c2ecf20Sopenharmony_ci	else
16528c2ecf20Sopenharmony_ci		return BUSY;
16538c2ecf20Sopenharmony_ci}
16548c2ecf20Sopenharmony_ci
16558c2ecf20Sopenharmony_cistatic void inc_hit_counter(struct cache *cache, struct bio *bio)
16568c2ecf20Sopenharmony_ci{
16578c2ecf20Sopenharmony_ci	atomic_inc(bio_data_dir(bio) == READ ?
16588c2ecf20Sopenharmony_ci		   &cache->stats.read_hit : &cache->stats.write_hit);
16598c2ecf20Sopenharmony_ci}
16608c2ecf20Sopenharmony_ci
16618c2ecf20Sopenharmony_cistatic void inc_miss_counter(struct cache *cache, struct bio *bio)
16628c2ecf20Sopenharmony_ci{
16638c2ecf20Sopenharmony_ci	atomic_inc(bio_data_dir(bio) == READ ?
16648c2ecf20Sopenharmony_ci		   &cache->stats.read_miss : &cache->stats.write_miss);
16658c2ecf20Sopenharmony_ci}
16668c2ecf20Sopenharmony_ci
16678c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
16688c2ecf20Sopenharmony_ci
16698c2ecf20Sopenharmony_cistatic int map_bio(struct cache *cache, struct bio *bio, dm_oblock_t block,
16708c2ecf20Sopenharmony_ci		   bool *commit_needed)
16718c2ecf20Sopenharmony_ci{
16728c2ecf20Sopenharmony_ci	int r, data_dir;
16738c2ecf20Sopenharmony_ci	bool rb, background_queued;
16748c2ecf20Sopenharmony_ci	dm_cblock_t cblock;
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci	*commit_needed = false;
16778c2ecf20Sopenharmony_ci
16788c2ecf20Sopenharmony_ci	rb = bio_detain_shared(cache, block, bio);
16798c2ecf20Sopenharmony_ci	if (!rb) {
16808c2ecf20Sopenharmony_ci		/*
16818c2ecf20Sopenharmony_ci		 * An exclusive lock is held for this block, so we have to
16828c2ecf20Sopenharmony_ci		 * wait.  We set the commit_needed flag so the current
16838c2ecf20Sopenharmony_ci		 * transaction will be committed asap, allowing this lock
16848c2ecf20Sopenharmony_ci		 * to be dropped.
16858c2ecf20Sopenharmony_ci		 */
16868c2ecf20Sopenharmony_ci		*commit_needed = true;
16878c2ecf20Sopenharmony_ci		return DM_MAPIO_SUBMITTED;
16888c2ecf20Sopenharmony_ci	}
16898c2ecf20Sopenharmony_ci
16908c2ecf20Sopenharmony_ci	data_dir = bio_data_dir(bio);
16918c2ecf20Sopenharmony_ci
16928c2ecf20Sopenharmony_ci	if (optimisable_bio(cache, bio, block)) {
16938c2ecf20Sopenharmony_ci		struct policy_work *op = NULL;
16948c2ecf20Sopenharmony_ci
16958c2ecf20Sopenharmony_ci		r = policy_lookup_with_work(cache->policy, block, &cblock, data_dir, true, &op);
16968c2ecf20Sopenharmony_ci		if (unlikely(r && r != -ENOENT)) {
16978c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: policy_lookup_with_work() failed with r = %d",
16988c2ecf20Sopenharmony_ci				    cache_device_name(cache), r);
16998c2ecf20Sopenharmony_ci			bio_io_error(bio);
17008c2ecf20Sopenharmony_ci			return DM_MAPIO_SUBMITTED;
17018c2ecf20Sopenharmony_ci		}
17028c2ecf20Sopenharmony_ci
17038c2ecf20Sopenharmony_ci		if (r == -ENOENT && op) {
17048c2ecf20Sopenharmony_ci			bio_drop_shared_lock(cache, bio);
17058c2ecf20Sopenharmony_ci			BUG_ON(op->op != POLICY_PROMOTE);
17068c2ecf20Sopenharmony_ci			mg_start(cache, op, bio);
17078c2ecf20Sopenharmony_ci			return DM_MAPIO_SUBMITTED;
17088c2ecf20Sopenharmony_ci		}
17098c2ecf20Sopenharmony_ci	} else {
17108c2ecf20Sopenharmony_ci		r = policy_lookup(cache->policy, block, &cblock, data_dir, false, &background_queued);
17118c2ecf20Sopenharmony_ci		if (unlikely(r && r != -ENOENT)) {
17128c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: policy_lookup() failed with r = %d",
17138c2ecf20Sopenharmony_ci				    cache_device_name(cache), r);
17148c2ecf20Sopenharmony_ci			bio_io_error(bio);
17158c2ecf20Sopenharmony_ci			return DM_MAPIO_SUBMITTED;
17168c2ecf20Sopenharmony_ci		}
17178c2ecf20Sopenharmony_ci
17188c2ecf20Sopenharmony_ci		if (background_queued)
17198c2ecf20Sopenharmony_ci			wake_migration_worker(cache);
17208c2ecf20Sopenharmony_ci	}
17218c2ecf20Sopenharmony_ci
17228c2ecf20Sopenharmony_ci	if (r == -ENOENT) {
17238c2ecf20Sopenharmony_ci		struct per_bio_data *pb = get_per_bio_data(bio);
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci		/*
17268c2ecf20Sopenharmony_ci		 * Miss.
17278c2ecf20Sopenharmony_ci		 */
17288c2ecf20Sopenharmony_ci		inc_miss_counter(cache, bio);
17298c2ecf20Sopenharmony_ci		if (pb->req_nr == 0) {
17308c2ecf20Sopenharmony_ci			accounted_begin(cache, bio);
17318c2ecf20Sopenharmony_ci			remap_to_origin_clear_discard(cache, bio, block);
17328c2ecf20Sopenharmony_ci		} else {
17338c2ecf20Sopenharmony_ci			/*
17348c2ecf20Sopenharmony_ci			 * This is a duplicate writethrough io that is no
17358c2ecf20Sopenharmony_ci			 * longer needed because the block has been demoted.
17368c2ecf20Sopenharmony_ci			 */
17378c2ecf20Sopenharmony_ci			bio_endio(bio);
17388c2ecf20Sopenharmony_ci			return DM_MAPIO_SUBMITTED;
17398c2ecf20Sopenharmony_ci		}
17408c2ecf20Sopenharmony_ci	} else {
17418c2ecf20Sopenharmony_ci		/*
17428c2ecf20Sopenharmony_ci		 * Hit.
17438c2ecf20Sopenharmony_ci		 */
17448c2ecf20Sopenharmony_ci		inc_hit_counter(cache, bio);
17458c2ecf20Sopenharmony_ci
17468c2ecf20Sopenharmony_ci		/*
17478c2ecf20Sopenharmony_ci		 * Passthrough always maps to the origin, invalidating any
17488c2ecf20Sopenharmony_ci		 * cache blocks that are written to.
17498c2ecf20Sopenharmony_ci		 */
17508c2ecf20Sopenharmony_ci		if (passthrough_mode(cache)) {
17518c2ecf20Sopenharmony_ci			if (bio_data_dir(bio) == WRITE) {
17528c2ecf20Sopenharmony_ci				bio_drop_shared_lock(cache, bio);
17538c2ecf20Sopenharmony_ci				atomic_inc(&cache->stats.demotion);
17548c2ecf20Sopenharmony_ci				invalidate_start(cache, cblock, block, bio);
17558c2ecf20Sopenharmony_ci			} else
17568c2ecf20Sopenharmony_ci				remap_to_origin_clear_discard(cache, bio, block);
17578c2ecf20Sopenharmony_ci		} else {
17588c2ecf20Sopenharmony_ci			if (bio_data_dir(bio) == WRITE && writethrough_mode(cache) &&
17598c2ecf20Sopenharmony_ci			    !is_dirty(cache, cblock)) {
17608c2ecf20Sopenharmony_ci				remap_to_origin_and_cache(cache, bio, block, cblock);
17618c2ecf20Sopenharmony_ci				accounted_begin(cache, bio);
17628c2ecf20Sopenharmony_ci			} else
17638c2ecf20Sopenharmony_ci				remap_to_cache_dirty(cache, bio, block, cblock);
17648c2ecf20Sopenharmony_ci		}
17658c2ecf20Sopenharmony_ci	}
17668c2ecf20Sopenharmony_ci
17678c2ecf20Sopenharmony_ci	/*
17688c2ecf20Sopenharmony_ci	 * dm core turns FUA requests into a separate payload and FLUSH req.
17698c2ecf20Sopenharmony_ci	 */
17708c2ecf20Sopenharmony_ci	if (bio->bi_opf & REQ_FUA) {
17718c2ecf20Sopenharmony_ci		/*
17728c2ecf20Sopenharmony_ci		 * issue_after_commit will call accounted_begin a second time.  So
17738c2ecf20Sopenharmony_ci		 * we call accounted_complete() to avoid double accounting.
17748c2ecf20Sopenharmony_ci		 */
17758c2ecf20Sopenharmony_ci		accounted_complete(cache, bio);
17768c2ecf20Sopenharmony_ci		issue_after_commit(&cache->committer, bio);
17778c2ecf20Sopenharmony_ci		*commit_needed = true;
17788c2ecf20Sopenharmony_ci		return DM_MAPIO_SUBMITTED;
17798c2ecf20Sopenharmony_ci	}
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci	return DM_MAPIO_REMAPPED;
17828c2ecf20Sopenharmony_ci}
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_cistatic bool process_bio(struct cache *cache, struct bio *bio)
17858c2ecf20Sopenharmony_ci{
17868c2ecf20Sopenharmony_ci	bool commit_needed;
17878c2ecf20Sopenharmony_ci
17888c2ecf20Sopenharmony_ci	if (map_bio(cache, bio, get_bio_block(cache, bio), &commit_needed) == DM_MAPIO_REMAPPED)
17898c2ecf20Sopenharmony_ci		submit_bio_noacct(bio);
17908c2ecf20Sopenharmony_ci
17918c2ecf20Sopenharmony_ci	return commit_needed;
17928c2ecf20Sopenharmony_ci}
17938c2ecf20Sopenharmony_ci
17948c2ecf20Sopenharmony_ci/*
17958c2ecf20Sopenharmony_ci * A non-zero return indicates read_only or fail_io mode.
17968c2ecf20Sopenharmony_ci */
17978c2ecf20Sopenharmony_cistatic int commit(struct cache *cache, bool clean_shutdown)
17988c2ecf20Sopenharmony_ci{
17998c2ecf20Sopenharmony_ci	int r;
18008c2ecf20Sopenharmony_ci
18018c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
18028c2ecf20Sopenharmony_ci		return -EINVAL;
18038c2ecf20Sopenharmony_ci
18048c2ecf20Sopenharmony_ci	atomic_inc(&cache->stats.commit_count);
18058c2ecf20Sopenharmony_ci	r = dm_cache_commit(cache->cmd, clean_shutdown);
18068c2ecf20Sopenharmony_ci	if (r)
18078c2ecf20Sopenharmony_ci		metadata_operation_failed(cache, "dm_cache_commit", r);
18088c2ecf20Sopenharmony_ci
18098c2ecf20Sopenharmony_ci	return r;
18108c2ecf20Sopenharmony_ci}
18118c2ecf20Sopenharmony_ci
18128c2ecf20Sopenharmony_ci/*
18138c2ecf20Sopenharmony_ci * Used by the batcher.
18148c2ecf20Sopenharmony_ci */
18158c2ecf20Sopenharmony_cistatic blk_status_t commit_op(void *context)
18168c2ecf20Sopenharmony_ci{
18178c2ecf20Sopenharmony_ci	struct cache *cache = context;
18188c2ecf20Sopenharmony_ci
18198c2ecf20Sopenharmony_ci	if (dm_cache_changed_this_transaction(cache->cmd))
18208c2ecf20Sopenharmony_ci		return errno_to_blk_status(commit(cache, false));
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci	return 0;
18238c2ecf20Sopenharmony_ci}
18248c2ecf20Sopenharmony_ci
18258c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_cistatic bool process_flush_bio(struct cache *cache, struct bio *bio)
18288c2ecf20Sopenharmony_ci{
18298c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
18308c2ecf20Sopenharmony_ci
18318c2ecf20Sopenharmony_ci	if (!pb->req_nr)
18328c2ecf20Sopenharmony_ci		remap_to_origin(cache, bio);
18338c2ecf20Sopenharmony_ci	else
18348c2ecf20Sopenharmony_ci		remap_to_cache(cache, bio, 0);
18358c2ecf20Sopenharmony_ci
18368c2ecf20Sopenharmony_ci	issue_after_commit(&cache->committer, bio);
18378c2ecf20Sopenharmony_ci	return true;
18388c2ecf20Sopenharmony_ci}
18398c2ecf20Sopenharmony_ci
18408c2ecf20Sopenharmony_cistatic bool process_discard_bio(struct cache *cache, struct bio *bio)
18418c2ecf20Sopenharmony_ci{
18428c2ecf20Sopenharmony_ci	dm_dblock_t b, e;
18438c2ecf20Sopenharmony_ci
18448c2ecf20Sopenharmony_ci	// FIXME: do we need to lock the region?  Or can we just assume the
18458c2ecf20Sopenharmony_ci	// user wont be so foolish as to issue discard concurrently with
18468c2ecf20Sopenharmony_ci	// other IO?
18478c2ecf20Sopenharmony_ci	calc_discard_block_range(cache, bio, &b, &e);
18488c2ecf20Sopenharmony_ci	while (b != e) {
18498c2ecf20Sopenharmony_ci		set_discard(cache, b);
18508c2ecf20Sopenharmony_ci		b = to_dblock(from_dblock(b) + 1);
18518c2ecf20Sopenharmony_ci	}
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci	if (cache->features.discard_passdown) {
18548c2ecf20Sopenharmony_ci		remap_to_origin(cache, bio);
18558c2ecf20Sopenharmony_ci		submit_bio_noacct(bio);
18568c2ecf20Sopenharmony_ci	} else
18578c2ecf20Sopenharmony_ci		bio_endio(bio);
18588c2ecf20Sopenharmony_ci
18598c2ecf20Sopenharmony_ci	return false;
18608c2ecf20Sopenharmony_ci}
18618c2ecf20Sopenharmony_ci
18628c2ecf20Sopenharmony_cistatic void process_deferred_bios(struct work_struct *ws)
18638c2ecf20Sopenharmony_ci{
18648c2ecf20Sopenharmony_ci	struct cache *cache = container_of(ws, struct cache, deferred_bio_worker);
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci	bool commit_needed = false;
18678c2ecf20Sopenharmony_ci	struct bio_list bios;
18688c2ecf20Sopenharmony_ci	struct bio *bio;
18698c2ecf20Sopenharmony_ci
18708c2ecf20Sopenharmony_ci	bio_list_init(&bios);
18718c2ecf20Sopenharmony_ci
18728c2ecf20Sopenharmony_ci	spin_lock_irq(&cache->lock);
18738c2ecf20Sopenharmony_ci	bio_list_merge(&bios, &cache->deferred_bios);
18748c2ecf20Sopenharmony_ci	bio_list_init(&cache->deferred_bios);
18758c2ecf20Sopenharmony_ci	spin_unlock_irq(&cache->lock);
18768c2ecf20Sopenharmony_ci
18778c2ecf20Sopenharmony_ci	while ((bio = bio_list_pop(&bios))) {
18788c2ecf20Sopenharmony_ci		if (bio->bi_opf & REQ_PREFLUSH)
18798c2ecf20Sopenharmony_ci			commit_needed = process_flush_bio(cache, bio) || commit_needed;
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci		else if (bio_op(bio) == REQ_OP_DISCARD)
18828c2ecf20Sopenharmony_ci			commit_needed = process_discard_bio(cache, bio) || commit_needed;
18838c2ecf20Sopenharmony_ci
18848c2ecf20Sopenharmony_ci		else
18858c2ecf20Sopenharmony_ci			commit_needed = process_bio(cache, bio) || commit_needed;
18868c2ecf20Sopenharmony_ci		cond_resched();
18878c2ecf20Sopenharmony_ci	}
18888c2ecf20Sopenharmony_ci
18898c2ecf20Sopenharmony_ci	if (commit_needed)
18908c2ecf20Sopenharmony_ci		schedule_commit(&cache->committer);
18918c2ecf20Sopenharmony_ci}
18928c2ecf20Sopenharmony_ci
18938c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
18948c2ecf20Sopenharmony_ci * Main worker loop
18958c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
18968c2ecf20Sopenharmony_ci
18978c2ecf20Sopenharmony_cistatic void requeue_deferred_bios(struct cache *cache)
18988c2ecf20Sopenharmony_ci{
18998c2ecf20Sopenharmony_ci	struct bio *bio;
19008c2ecf20Sopenharmony_ci	struct bio_list bios;
19018c2ecf20Sopenharmony_ci
19028c2ecf20Sopenharmony_ci	bio_list_init(&bios);
19038c2ecf20Sopenharmony_ci	bio_list_merge(&bios, &cache->deferred_bios);
19048c2ecf20Sopenharmony_ci	bio_list_init(&cache->deferred_bios);
19058c2ecf20Sopenharmony_ci
19068c2ecf20Sopenharmony_ci	while ((bio = bio_list_pop(&bios))) {
19078c2ecf20Sopenharmony_ci		bio->bi_status = BLK_STS_DM_REQUEUE;
19088c2ecf20Sopenharmony_ci		bio_endio(bio);
19098c2ecf20Sopenharmony_ci		cond_resched();
19108c2ecf20Sopenharmony_ci	}
19118c2ecf20Sopenharmony_ci}
19128c2ecf20Sopenharmony_ci
19138c2ecf20Sopenharmony_ci/*
19148c2ecf20Sopenharmony_ci * We want to commit periodically so that not too much
19158c2ecf20Sopenharmony_ci * unwritten metadata builds up.
19168c2ecf20Sopenharmony_ci */
19178c2ecf20Sopenharmony_cistatic void do_waker(struct work_struct *ws)
19188c2ecf20Sopenharmony_ci{
19198c2ecf20Sopenharmony_ci	struct cache *cache = container_of(to_delayed_work(ws), struct cache, waker);
19208c2ecf20Sopenharmony_ci
19218c2ecf20Sopenharmony_ci	policy_tick(cache->policy, true);
19228c2ecf20Sopenharmony_ci	wake_migration_worker(cache);
19238c2ecf20Sopenharmony_ci	schedule_commit(&cache->committer);
19248c2ecf20Sopenharmony_ci	queue_delayed_work(cache->wq, &cache->waker, COMMIT_PERIOD);
19258c2ecf20Sopenharmony_ci}
19268c2ecf20Sopenharmony_ci
19278c2ecf20Sopenharmony_cistatic void check_migrations(struct work_struct *ws)
19288c2ecf20Sopenharmony_ci{
19298c2ecf20Sopenharmony_ci	int r;
19308c2ecf20Sopenharmony_ci	struct policy_work *op;
19318c2ecf20Sopenharmony_ci	struct cache *cache = container_of(ws, struct cache, migration_worker);
19328c2ecf20Sopenharmony_ci	enum busy b;
19338c2ecf20Sopenharmony_ci
19348c2ecf20Sopenharmony_ci	for (;;) {
19358c2ecf20Sopenharmony_ci		b = spare_migration_bandwidth(cache);
19368c2ecf20Sopenharmony_ci
19378c2ecf20Sopenharmony_ci		r = policy_get_background_work(cache->policy, b == IDLE, &op);
19388c2ecf20Sopenharmony_ci		if (r == -ENODATA)
19398c2ecf20Sopenharmony_ci			break;
19408c2ecf20Sopenharmony_ci
19418c2ecf20Sopenharmony_ci		if (r) {
19428c2ecf20Sopenharmony_ci			DMERR_LIMIT("%s: policy_background_work failed",
19438c2ecf20Sopenharmony_ci				    cache_device_name(cache));
19448c2ecf20Sopenharmony_ci			break;
19458c2ecf20Sopenharmony_ci		}
19468c2ecf20Sopenharmony_ci
19478c2ecf20Sopenharmony_ci		r = mg_start(cache, op, NULL);
19488c2ecf20Sopenharmony_ci		if (r)
19498c2ecf20Sopenharmony_ci			break;
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ci		cond_resched();
19528c2ecf20Sopenharmony_ci	}
19538c2ecf20Sopenharmony_ci}
19548c2ecf20Sopenharmony_ci
19558c2ecf20Sopenharmony_ci/*----------------------------------------------------------------
19568c2ecf20Sopenharmony_ci * Target methods
19578c2ecf20Sopenharmony_ci *--------------------------------------------------------------*/
19588c2ecf20Sopenharmony_ci
19598c2ecf20Sopenharmony_ci/*
19608c2ecf20Sopenharmony_ci * This function gets called on the error paths of the constructor, so we
19618c2ecf20Sopenharmony_ci * have to cope with a partially initialised struct.
19628c2ecf20Sopenharmony_ci */
19638c2ecf20Sopenharmony_cistatic void destroy(struct cache *cache)
19648c2ecf20Sopenharmony_ci{
19658c2ecf20Sopenharmony_ci	unsigned i;
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_ci	mempool_exit(&cache->migration_pool);
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_ci	if (cache->prison)
19708c2ecf20Sopenharmony_ci		dm_bio_prison_destroy_v2(cache->prison);
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ci	cancel_delayed_work_sync(&cache->waker);
19738c2ecf20Sopenharmony_ci	if (cache->wq)
19748c2ecf20Sopenharmony_ci		destroy_workqueue(cache->wq);
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_ci	if (cache->dirty_bitset)
19778c2ecf20Sopenharmony_ci		free_bitset(cache->dirty_bitset);
19788c2ecf20Sopenharmony_ci
19798c2ecf20Sopenharmony_ci	if (cache->discard_bitset)
19808c2ecf20Sopenharmony_ci		free_bitset(cache->discard_bitset);
19818c2ecf20Sopenharmony_ci
19828c2ecf20Sopenharmony_ci	if (cache->copier)
19838c2ecf20Sopenharmony_ci		dm_kcopyd_client_destroy(cache->copier);
19848c2ecf20Sopenharmony_ci
19858c2ecf20Sopenharmony_ci	if (cache->cmd)
19868c2ecf20Sopenharmony_ci		dm_cache_metadata_close(cache->cmd);
19878c2ecf20Sopenharmony_ci
19888c2ecf20Sopenharmony_ci	if (cache->metadata_dev)
19898c2ecf20Sopenharmony_ci		dm_put_device(cache->ti, cache->metadata_dev);
19908c2ecf20Sopenharmony_ci
19918c2ecf20Sopenharmony_ci	if (cache->origin_dev)
19928c2ecf20Sopenharmony_ci		dm_put_device(cache->ti, cache->origin_dev);
19938c2ecf20Sopenharmony_ci
19948c2ecf20Sopenharmony_ci	if (cache->cache_dev)
19958c2ecf20Sopenharmony_ci		dm_put_device(cache->ti, cache->cache_dev);
19968c2ecf20Sopenharmony_ci
19978c2ecf20Sopenharmony_ci	if (cache->policy)
19988c2ecf20Sopenharmony_ci		dm_cache_policy_destroy(cache->policy);
19998c2ecf20Sopenharmony_ci
20008c2ecf20Sopenharmony_ci	for (i = 0; i < cache->nr_ctr_args ; i++)
20018c2ecf20Sopenharmony_ci		kfree(cache->ctr_args[i]);
20028c2ecf20Sopenharmony_ci	kfree(cache->ctr_args);
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	bioset_exit(&cache->bs);
20058c2ecf20Sopenharmony_ci
20068c2ecf20Sopenharmony_ci	kfree(cache);
20078c2ecf20Sopenharmony_ci}
20088c2ecf20Sopenharmony_ci
20098c2ecf20Sopenharmony_cistatic void cache_dtr(struct dm_target *ti)
20108c2ecf20Sopenharmony_ci{
20118c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci	destroy(cache);
20148c2ecf20Sopenharmony_ci}
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_cistatic sector_t get_dev_size(struct dm_dev *dev)
20178c2ecf20Sopenharmony_ci{
20188c2ecf20Sopenharmony_ci	return i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT;
20198c2ecf20Sopenharmony_ci}
20208c2ecf20Sopenharmony_ci
20218c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_ci/*
20248c2ecf20Sopenharmony_ci * Construct a cache device mapping.
20258c2ecf20Sopenharmony_ci *
20268c2ecf20Sopenharmony_ci * cache <metadata dev> <cache dev> <origin dev> <block size>
20278c2ecf20Sopenharmony_ci *       <#feature args> [<feature arg>]*
20288c2ecf20Sopenharmony_ci *       <policy> <#policy args> [<policy arg>]*
20298c2ecf20Sopenharmony_ci *
20308c2ecf20Sopenharmony_ci * metadata dev    : fast device holding the persistent metadata
20318c2ecf20Sopenharmony_ci * cache dev	   : fast device holding cached data blocks
20328c2ecf20Sopenharmony_ci * origin dev	   : slow device holding original data blocks
20338c2ecf20Sopenharmony_ci * block size	   : cache unit size in sectors
20348c2ecf20Sopenharmony_ci *
20358c2ecf20Sopenharmony_ci * #feature args   : number of feature arguments passed
20368c2ecf20Sopenharmony_ci * feature args    : writethrough.  (The default is writeback.)
20378c2ecf20Sopenharmony_ci *
20388c2ecf20Sopenharmony_ci * policy	   : the replacement policy to use
20398c2ecf20Sopenharmony_ci * #policy args    : an even number of policy arguments corresponding
20408c2ecf20Sopenharmony_ci *		     to key/value pairs passed to the policy
20418c2ecf20Sopenharmony_ci * policy args	   : key/value pairs passed to the policy
20428c2ecf20Sopenharmony_ci *		     E.g. 'sequential_threshold 1024'
20438c2ecf20Sopenharmony_ci *		     See cache-policies.txt for details.
20448c2ecf20Sopenharmony_ci *
20458c2ecf20Sopenharmony_ci * Optional feature arguments are:
20468c2ecf20Sopenharmony_ci *   writethrough  : write through caching that prohibits cache block
20478c2ecf20Sopenharmony_ci *		     content from being different from origin block content.
20488c2ecf20Sopenharmony_ci *		     Without this argument, the default behaviour is to write
20498c2ecf20Sopenharmony_ci *		     back cache block contents later for performance reasons,
20508c2ecf20Sopenharmony_ci *		     so they may differ from the corresponding origin blocks.
20518c2ecf20Sopenharmony_ci */
20528c2ecf20Sopenharmony_cistruct cache_args {
20538c2ecf20Sopenharmony_ci	struct dm_target *ti;
20548c2ecf20Sopenharmony_ci
20558c2ecf20Sopenharmony_ci	struct dm_dev *metadata_dev;
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci	struct dm_dev *cache_dev;
20588c2ecf20Sopenharmony_ci	sector_t cache_sectors;
20598c2ecf20Sopenharmony_ci
20608c2ecf20Sopenharmony_ci	struct dm_dev *origin_dev;
20618c2ecf20Sopenharmony_ci	sector_t origin_sectors;
20628c2ecf20Sopenharmony_ci
20638c2ecf20Sopenharmony_ci	uint32_t block_size;
20648c2ecf20Sopenharmony_ci
20658c2ecf20Sopenharmony_ci	const char *policy_name;
20668c2ecf20Sopenharmony_ci	int policy_argc;
20678c2ecf20Sopenharmony_ci	const char **policy_argv;
20688c2ecf20Sopenharmony_ci
20698c2ecf20Sopenharmony_ci	struct cache_features features;
20708c2ecf20Sopenharmony_ci};
20718c2ecf20Sopenharmony_ci
20728c2ecf20Sopenharmony_cistatic void destroy_cache_args(struct cache_args *ca)
20738c2ecf20Sopenharmony_ci{
20748c2ecf20Sopenharmony_ci	if (ca->metadata_dev)
20758c2ecf20Sopenharmony_ci		dm_put_device(ca->ti, ca->metadata_dev);
20768c2ecf20Sopenharmony_ci
20778c2ecf20Sopenharmony_ci	if (ca->cache_dev)
20788c2ecf20Sopenharmony_ci		dm_put_device(ca->ti, ca->cache_dev);
20798c2ecf20Sopenharmony_ci
20808c2ecf20Sopenharmony_ci	if (ca->origin_dev)
20818c2ecf20Sopenharmony_ci		dm_put_device(ca->ti, ca->origin_dev);
20828c2ecf20Sopenharmony_ci
20838c2ecf20Sopenharmony_ci	kfree(ca);
20848c2ecf20Sopenharmony_ci}
20858c2ecf20Sopenharmony_ci
20868c2ecf20Sopenharmony_cistatic bool at_least_one_arg(struct dm_arg_set *as, char **error)
20878c2ecf20Sopenharmony_ci{
20888c2ecf20Sopenharmony_ci	if (!as->argc) {
20898c2ecf20Sopenharmony_ci		*error = "Insufficient args";
20908c2ecf20Sopenharmony_ci		return false;
20918c2ecf20Sopenharmony_ci	}
20928c2ecf20Sopenharmony_ci
20938c2ecf20Sopenharmony_ci	return true;
20948c2ecf20Sopenharmony_ci}
20958c2ecf20Sopenharmony_ci
20968c2ecf20Sopenharmony_cistatic int parse_metadata_dev(struct cache_args *ca, struct dm_arg_set *as,
20978c2ecf20Sopenharmony_ci			      char **error)
20988c2ecf20Sopenharmony_ci{
20998c2ecf20Sopenharmony_ci	int r;
21008c2ecf20Sopenharmony_ci	sector_t metadata_dev_size;
21018c2ecf20Sopenharmony_ci	char b[BDEVNAME_SIZE];
21028c2ecf20Sopenharmony_ci
21038c2ecf20Sopenharmony_ci	if (!at_least_one_arg(as, error))
21048c2ecf20Sopenharmony_ci		return -EINVAL;
21058c2ecf20Sopenharmony_ci
21068c2ecf20Sopenharmony_ci	r = dm_get_device(ca->ti, dm_shift_arg(as), FMODE_READ | FMODE_WRITE,
21078c2ecf20Sopenharmony_ci			  &ca->metadata_dev);
21088c2ecf20Sopenharmony_ci	if (r) {
21098c2ecf20Sopenharmony_ci		*error = "Error opening metadata device";
21108c2ecf20Sopenharmony_ci		return r;
21118c2ecf20Sopenharmony_ci	}
21128c2ecf20Sopenharmony_ci
21138c2ecf20Sopenharmony_ci	metadata_dev_size = get_dev_size(ca->metadata_dev);
21148c2ecf20Sopenharmony_ci	if (metadata_dev_size > DM_CACHE_METADATA_MAX_SECTORS_WARNING)
21158c2ecf20Sopenharmony_ci		DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.",
21168c2ecf20Sopenharmony_ci		       bdevname(ca->metadata_dev->bdev, b), THIN_METADATA_MAX_SECTORS);
21178c2ecf20Sopenharmony_ci
21188c2ecf20Sopenharmony_ci	return 0;
21198c2ecf20Sopenharmony_ci}
21208c2ecf20Sopenharmony_ci
21218c2ecf20Sopenharmony_cistatic int parse_cache_dev(struct cache_args *ca, struct dm_arg_set *as,
21228c2ecf20Sopenharmony_ci			   char **error)
21238c2ecf20Sopenharmony_ci{
21248c2ecf20Sopenharmony_ci	int r;
21258c2ecf20Sopenharmony_ci
21268c2ecf20Sopenharmony_ci	if (!at_least_one_arg(as, error))
21278c2ecf20Sopenharmony_ci		return -EINVAL;
21288c2ecf20Sopenharmony_ci
21298c2ecf20Sopenharmony_ci	r = dm_get_device(ca->ti, dm_shift_arg(as), FMODE_READ | FMODE_WRITE,
21308c2ecf20Sopenharmony_ci			  &ca->cache_dev);
21318c2ecf20Sopenharmony_ci	if (r) {
21328c2ecf20Sopenharmony_ci		*error = "Error opening cache device";
21338c2ecf20Sopenharmony_ci		return r;
21348c2ecf20Sopenharmony_ci	}
21358c2ecf20Sopenharmony_ci	ca->cache_sectors = get_dev_size(ca->cache_dev);
21368c2ecf20Sopenharmony_ci
21378c2ecf20Sopenharmony_ci	return 0;
21388c2ecf20Sopenharmony_ci}
21398c2ecf20Sopenharmony_ci
21408c2ecf20Sopenharmony_cistatic int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as,
21418c2ecf20Sopenharmony_ci			    char **error)
21428c2ecf20Sopenharmony_ci{
21438c2ecf20Sopenharmony_ci	int r;
21448c2ecf20Sopenharmony_ci
21458c2ecf20Sopenharmony_ci	if (!at_least_one_arg(as, error))
21468c2ecf20Sopenharmony_ci		return -EINVAL;
21478c2ecf20Sopenharmony_ci
21488c2ecf20Sopenharmony_ci	r = dm_get_device(ca->ti, dm_shift_arg(as), FMODE_READ | FMODE_WRITE,
21498c2ecf20Sopenharmony_ci			  &ca->origin_dev);
21508c2ecf20Sopenharmony_ci	if (r) {
21518c2ecf20Sopenharmony_ci		*error = "Error opening origin device";
21528c2ecf20Sopenharmony_ci		return r;
21538c2ecf20Sopenharmony_ci	}
21548c2ecf20Sopenharmony_ci
21558c2ecf20Sopenharmony_ci	ca->origin_sectors = get_dev_size(ca->origin_dev);
21568c2ecf20Sopenharmony_ci	if (ca->ti->len > ca->origin_sectors) {
21578c2ecf20Sopenharmony_ci		*error = "Device size larger than cached device";
21588c2ecf20Sopenharmony_ci		return -EINVAL;
21598c2ecf20Sopenharmony_ci	}
21608c2ecf20Sopenharmony_ci
21618c2ecf20Sopenharmony_ci	return 0;
21628c2ecf20Sopenharmony_ci}
21638c2ecf20Sopenharmony_ci
21648c2ecf20Sopenharmony_cistatic int parse_block_size(struct cache_args *ca, struct dm_arg_set *as,
21658c2ecf20Sopenharmony_ci			    char **error)
21668c2ecf20Sopenharmony_ci{
21678c2ecf20Sopenharmony_ci	unsigned long block_size;
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_ci	if (!at_least_one_arg(as, error))
21708c2ecf20Sopenharmony_ci		return -EINVAL;
21718c2ecf20Sopenharmony_ci
21728c2ecf20Sopenharmony_ci	if (kstrtoul(dm_shift_arg(as), 10, &block_size) || !block_size ||
21738c2ecf20Sopenharmony_ci	    block_size < DATA_DEV_BLOCK_SIZE_MIN_SECTORS ||
21748c2ecf20Sopenharmony_ci	    block_size > DATA_DEV_BLOCK_SIZE_MAX_SECTORS ||
21758c2ecf20Sopenharmony_ci	    block_size & (DATA_DEV_BLOCK_SIZE_MIN_SECTORS - 1)) {
21768c2ecf20Sopenharmony_ci		*error = "Invalid data block size";
21778c2ecf20Sopenharmony_ci		return -EINVAL;
21788c2ecf20Sopenharmony_ci	}
21798c2ecf20Sopenharmony_ci
21808c2ecf20Sopenharmony_ci	if (block_size > ca->cache_sectors) {
21818c2ecf20Sopenharmony_ci		*error = "Data block size is larger than the cache device";
21828c2ecf20Sopenharmony_ci		return -EINVAL;
21838c2ecf20Sopenharmony_ci	}
21848c2ecf20Sopenharmony_ci
21858c2ecf20Sopenharmony_ci	ca->block_size = block_size;
21868c2ecf20Sopenharmony_ci
21878c2ecf20Sopenharmony_ci	return 0;
21888c2ecf20Sopenharmony_ci}
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_cistatic void init_features(struct cache_features *cf)
21918c2ecf20Sopenharmony_ci{
21928c2ecf20Sopenharmony_ci	cf->mode = CM_WRITE;
21938c2ecf20Sopenharmony_ci	cf->io_mode = CM_IO_WRITEBACK;
21948c2ecf20Sopenharmony_ci	cf->metadata_version = 1;
21958c2ecf20Sopenharmony_ci	cf->discard_passdown = true;
21968c2ecf20Sopenharmony_ci}
21978c2ecf20Sopenharmony_ci
21988c2ecf20Sopenharmony_cistatic int parse_features(struct cache_args *ca, struct dm_arg_set *as,
21998c2ecf20Sopenharmony_ci			  char **error)
22008c2ecf20Sopenharmony_ci{
22018c2ecf20Sopenharmony_ci	static const struct dm_arg _args[] = {
22028c2ecf20Sopenharmony_ci		{0, 3, "Invalid number of cache feature arguments"},
22038c2ecf20Sopenharmony_ci	};
22048c2ecf20Sopenharmony_ci
22058c2ecf20Sopenharmony_ci	int r, mode_ctr = 0;
22068c2ecf20Sopenharmony_ci	unsigned argc;
22078c2ecf20Sopenharmony_ci	const char *arg;
22088c2ecf20Sopenharmony_ci	struct cache_features *cf = &ca->features;
22098c2ecf20Sopenharmony_ci
22108c2ecf20Sopenharmony_ci	init_features(cf);
22118c2ecf20Sopenharmony_ci
22128c2ecf20Sopenharmony_ci	r = dm_read_arg_group(_args, as, &argc, error);
22138c2ecf20Sopenharmony_ci	if (r)
22148c2ecf20Sopenharmony_ci		return -EINVAL;
22158c2ecf20Sopenharmony_ci
22168c2ecf20Sopenharmony_ci	while (argc--) {
22178c2ecf20Sopenharmony_ci		arg = dm_shift_arg(as);
22188c2ecf20Sopenharmony_ci
22198c2ecf20Sopenharmony_ci		if (!strcasecmp(arg, "writeback")) {
22208c2ecf20Sopenharmony_ci			cf->io_mode = CM_IO_WRITEBACK;
22218c2ecf20Sopenharmony_ci			mode_ctr++;
22228c2ecf20Sopenharmony_ci		}
22238c2ecf20Sopenharmony_ci
22248c2ecf20Sopenharmony_ci		else if (!strcasecmp(arg, "writethrough")) {
22258c2ecf20Sopenharmony_ci			cf->io_mode = CM_IO_WRITETHROUGH;
22268c2ecf20Sopenharmony_ci			mode_ctr++;
22278c2ecf20Sopenharmony_ci		}
22288c2ecf20Sopenharmony_ci
22298c2ecf20Sopenharmony_ci		else if (!strcasecmp(arg, "passthrough")) {
22308c2ecf20Sopenharmony_ci			cf->io_mode = CM_IO_PASSTHROUGH;
22318c2ecf20Sopenharmony_ci			mode_ctr++;
22328c2ecf20Sopenharmony_ci		}
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_ci		else if (!strcasecmp(arg, "metadata2"))
22358c2ecf20Sopenharmony_ci			cf->metadata_version = 2;
22368c2ecf20Sopenharmony_ci
22378c2ecf20Sopenharmony_ci		else if (!strcasecmp(arg, "no_discard_passdown"))
22388c2ecf20Sopenharmony_ci			cf->discard_passdown = false;
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci		else {
22418c2ecf20Sopenharmony_ci			*error = "Unrecognised cache feature requested";
22428c2ecf20Sopenharmony_ci			return -EINVAL;
22438c2ecf20Sopenharmony_ci		}
22448c2ecf20Sopenharmony_ci	}
22458c2ecf20Sopenharmony_ci
22468c2ecf20Sopenharmony_ci	if (mode_ctr > 1) {
22478c2ecf20Sopenharmony_ci		*error = "Duplicate cache io_mode features requested";
22488c2ecf20Sopenharmony_ci		return -EINVAL;
22498c2ecf20Sopenharmony_ci	}
22508c2ecf20Sopenharmony_ci
22518c2ecf20Sopenharmony_ci	return 0;
22528c2ecf20Sopenharmony_ci}
22538c2ecf20Sopenharmony_ci
22548c2ecf20Sopenharmony_cistatic int parse_policy(struct cache_args *ca, struct dm_arg_set *as,
22558c2ecf20Sopenharmony_ci			char **error)
22568c2ecf20Sopenharmony_ci{
22578c2ecf20Sopenharmony_ci	static const struct dm_arg _args[] = {
22588c2ecf20Sopenharmony_ci		{0, 1024, "Invalid number of policy arguments"},
22598c2ecf20Sopenharmony_ci	};
22608c2ecf20Sopenharmony_ci
22618c2ecf20Sopenharmony_ci	int r;
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_ci	if (!at_least_one_arg(as, error))
22648c2ecf20Sopenharmony_ci		return -EINVAL;
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_ci	ca->policy_name = dm_shift_arg(as);
22678c2ecf20Sopenharmony_ci
22688c2ecf20Sopenharmony_ci	r = dm_read_arg_group(_args, as, &ca->policy_argc, error);
22698c2ecf20Sopenharmony_ci	if (r)
22708c2ecf20Sopenharmony_ci		return -EINVAL;
22718c2ecf20Sopenharmony_ci
22728c2ecf20Sopenharmony_ci	ca->policy_argv = (const char **)as->argv;
22738c2ecf20Sopenharmony_ci	dm_consume_args(as, ca->policy_argc);
22748c2ecf20Sopenharmony_ci
22758c2ecf20Sopenharmony_ci	return 0;
22768c2ecf20Sopenharmony_ci}
22778c2ecf20Sopenharmony_ci
22788c2ecf20Sopenharmony_cistatic int parse_cache_args(struct cache_args *ca, int argc, char **argv,
22798c2ecf20Sopenharmony_ci			    char **error)
22808c2ecf20Sopenharmony_ci{
22818c2ecf20Sopenharmony_ci	int r;
22828c2ecf20Sopenharmony_ci	struct dm_arg_set as;
22838c2ecf20Sopenharmony_ci
22848c2ecf20Sopenharmony_ci	as.argc = argc;
22858c2ecf20Sopenharmony_ci	as.argv = argv;
22868c2ecf20Sopenharmony_ci
22878c2ecf20Sopenharmony_ci	r = parse_metadata_dev(ca, &as, error);
22888c2ecf20Sopenharmony_ci	if (r)
22898c2ecf20Sopenharmony_ci		return r;
22908c2ecf20Sopenharmony_ci
22918c2ecf20Sopenharmony_ci	r = parse_cache_dev(ca, &as, error);
22928c2ecf20Sopenharmony_ci	if (r)
22938c2ecf20Sopenharmony_ci		return r;
22948c2ecf20Sopenharmony_ci
22958c2ecf20Sopenharmony_ci	r = parse_origin_dev(ca, &as, error);
22968c2ecf20Sopenharmony_ci	if (r)
22978c2ecf20Sopenharmony_ci		return r;
22988c2ecf20Sopenharmony_ci
22998c2ecf20Sopenharmony_ci	r = parse_block_size(ca, &as, error);
23008c2ecf20Sopenharmony_ci	if (r)
23018c2ecf20Sopenharmony_ci		return r;
23028c2ecf20Sopenharmony_ci
23038c2ecf20Sopenharmony_ci	r = parse_features(ca, &as, error);
23048c2ecf20Sopenharmony_ci	if (r)
23058c2ecf20Sopenharmony_ci		return r;
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_ci	r = parse_policy(ca, &as, error);
23088c2ecf20Sopenharmony_ci	if (r)
23098c2ecf20Sopenharmony_ci		return r;
23108c2ecf20Sopenharmony_ci
23118c2ecf20Sopenharmony_ci	return 0;
23128c2ecf20Sopenharmony_ci}
23138c2ecf20Sopenharmony_ci
23148c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
23158c2ecf20Sopenharmony_ci
23168c2ecf20Sopenharmony_cistatic struct kmem_cache *migration_cache;
23178c2ecf20Sopenharmony_ci
23188c2ecf20Sopenharmony_ci#define NOT_CORE_OPTION 1
23198c2ecf20Sopenharmony_ci
23208c2ecf20Sopenharmony_cistatic int process_config_option(struct cache *cache, const char *key, const char *value)
23218c2ecf20Sopenharmony_ci{
23228c2ecf20Sopenharmony_ci	unsigned long tmp;
23238c2ecf20Sopenharmony_ci
23248c2ecf20Sopenharmony_ci	if (!strcasecmp(key, "migration_threshold")) {
23258c2ecf20Sopenharmony_ci		if (kstrtoul(value, 10, &tmp))
23268c2ecf20Sopenharmony_ci			return -EINVAL;
23278c2ecf20Sopenharmony_ci
23288c2ecf20Sopenharmony_ci		cache->migration_threshold = tmp;
23298c2ecf20Sopenharmony_ci		return 0;
23308c2ecf20Sopenharmony_ci	}
23318c2ecf20Sopenharmony_ci
23328c2ecf20Sopenharmony_ci	return NOT_CORE_OPTION;
23338c2ecf20Sopenharmony_ci}
23348c2ecf20Sopenharmony_ci
23358c2ecf20Sopenharmony_cistatic int set_config_value(struct cache *cache, const char *key, const char *value)
23368c2ecf20Sopenharmony_ci{
23378c2ecf20Sopenharmony_ci	int r = process_config_option(cache, key, value);
23388c2ecf20Sopenharmony_ci
23398c2ecf20Sopenharmony_ci	if (r == NOT_CORE_OPTION)
23408c2ecf20Sopenharmony_ci		r = policy_set_config_value(cache->policy, key, value);
23418c2ecf20Sopenharmony_ci
23428c2ecf20Sopenharmony_ci	if (r)
23438c2ecf20Sopenharmony_ci		DMWARN("bad config value for %s: %s", key, value);
23448c2ecf20Sopenharmony_ci
23458c2ecf20Sopenharmony_ci	return r;
23468c2ecf20Sopenharmony_ci}
23478c2ecf20Sopenharmony_ci
23488c2ecf20Sopenharmony_cistatic int set_config_values(struct cache *cache, int argc, const char **argv)
23498c2ecf20Sopenharmony_ci{
23508c2ecf20Sopenharmony_ci	int r = 0;
23518c2ecf20Sopenharmony_ci
23528c2ecf20Sopenharmony_ci	if (argc & 1) {
23538c2ecf20Sopenharmony_ci		DMWARN("Odd number of policy arguments given but they should be <key> <value> pairs.");
23548c2ecf20Sopenharmony_ci		return -EINVAL;
23558c2ecf20Sopenharmony_ci	}
23568c2ecf20Sopenharmony_ci
23578c2ecf20Sopenharmony_ci	while (argc) {
23588c2ecf20Sopenharmony_ci		r = set_config_value(cache, argv[0], argv[1]);
23598c2ecf20Sopenharmony_ci		if (r)
23608c2ecf20Sopenharmony_ci			break;
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ci		argc -= 2;
23638c2ecf20Sopenharmony_ci		argv += 2;
23648c2ecf20Sopenharmony_ci	}
23658c2ecf20Sopenharmony_ci
23668c2ecf20Sopenharmony_ci	return r;
23678c2ecf20Sopenharmony_ci}
23688c2ecf20Sopenharmony_ci
23698c2ecf20Sopenharmony_cistatic int create_cache_policy(struct cache *cache, struct cache_args *ca,
23708c2ecf20Sopenharmony_ci			       char **error)
23718c2ecf20Sopenharmony_ci{
23728c2ecf20Sopenharmony_ci	struct dm_cache_policy *p = dm_cache_policy_create(ca->policy_name,
23738c2ecf20Sopenharmony_ci							   cache->cache_size,
23748c2ecf20Sopenharmony_ci							   cache->origin_sectors,
23758c2ecf20Sopenharmony_ci							   cache->sectors_per_block);
23768c2ecf20Sopenharmony_ci	if (IS_ERR(p)) {
23778c2ecf20Sopenharmony_ci		*error = "Error creating cache's policy";
23788c2ecf20Sopenharmony_ci		return PTR_ERR(p);
23798c2ecf20Sopenharmony_ci	}
23808c2ecf20Sopenharmony_ci	cache->policy = p;
23818c2ecf20Sopenharmony_ci	BUG_ON(!cache->policy);
23828c2ecf20Sopenharmony_ci
23838c2ecf20Sopenharmony_ci	return 0;
23848c2ecf20Sopenharmony_ci}
23858c2ecf20Sopenharmony_ci
23868c2ecf20Sopenharmony_ci/*
23878c2ecf20Sopenharmony_ci * We want the discard block size to be at least the size of the cache
23888c2ecf20Sopenharmony_ci * block size and have no more than 2^14 discard blocks across the origin.
23898c2ecf20Sopenharmony_ci */
23908c2ecf20Sopenharmony_ci#define MAX_DISCARD_BLOCKS (1 << 14)
23918c2ecf20Sopenharmony_ci
23928c2ecf20Sopenharmony_cistatic bool too_many_discard_blocks(sector_t discard_block_size,
23938c2ecf20Sopenharmony_ci				    sector_t origin_size)
23948c2ecf20Sopenharmony_ci{
23958c2ecf20Sopenharmony_ci	(void) sector_div(origin_size, discard_block_size);
23968c2ecf20Sopenharmony_ci
23978c2ecf20Sopenharmony_ci	return origin_size > MAX_DISCARD_BLOCKS;
23988c2ecf20Sopenharmony_ci}
23998c2ecf20Sopenharmony_ci
24008c2ecf20Sopenharmony_cistatic sector_t calculate_discard_block_size(sector_t cache_block_size,
24018c2ecf20Sopenharmony_ci					     sector_t origin_size)
24028c2ecf20Sopenharmony_ci{
24038c2ecf20Sopenharmony_ci	sector_t discard_block_size = cache_block_size;
24048c2ecf20Sopenharmony_ci
24058c2ecf20Sopenharmony_ci	if (origin_size)
24068c2ecf20Sopenharmony_ci		while (too_many_discard_blocks(discard_block_size, origin_size))
24078c2ecf20Sopenharmony_ci			discard_block_size *= 2;
24088c2ecf20Sopenharmony_ci
24098c2ecf20Sopenharmony_ci	return discard_block_size;
24108c2ecf20Sopenharmony_ci}
24118c2ecf20Sopenharmony_ci
24128c2ecf20Sopenharmony_cistatic void set_cache_size(struct cache *cache, dm_cblock_t size)
24138c2ecf20Sopenharmony_ci{
24148c2ecf20Sopenharmony_ci	dm_block_t nr_blocks = from_cblock(size);
24158c2ecf20Sopenharmony_ci
24168c2ecf20Sopenharmony_ci	if (nr_blocks > (1 << 20) && cache->cache_size != size)
24178c2ecf20Sopenharmony_ci		DMWARN_LIMIT("You have created a cache device with a lot of individual cache blocks (%llu)\n"
24188c2ecf20Sopenharmony_ci			     "All these mappings can consume a lot of kernel memory, and take some time to read/write.\n"
24198c2ecf20Sopenharmony_ci			     "Please consider increasing the cache block size to reduce the overall cache block count.",
24208c2ecf20Sopenharmony_ci			     (unsigned long long) nr_blocks);
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci	cache->cache_size = size;
24238c2ecf20Sopenharmony_ci}
24248c2ecf20Sopenharmony_ci
24258c2ecf20Sopenharmony_ci#define DEFAULT_MIGRATION_THRESHOLD 2048
24268c2ecf20Sopenharmony_ci
24278c2ecf20Sopenharmony_cistatic int cache_create(struct cache_args *ca, struct cache **result)
24288c2ecf20Sopenharmony_ci{
24298c2ecf20Sopenharmony_ci	int r = 0;
24308c2ecf20Sopenharmony_ci	char **error = &ca->ti->error;
24318c2ecf20Sopenharmony_ci	struct cache *cache;
24328c2ecf20Sopenharmony_ci	struct dm_target *ti = ca->ti;
24338c2ecf20Sopenharmony_ci	dm_block_t origin_blocks;
24348c2ecf20Sopenharmony_ci	struct dm_cache_metadata *cmd;
24358c2ecf20Sopenharmony_ci	bool may_format = ca->features.mode == CM_WRITE;
24368c2ecf20Sopenharmony_ci
24378c2ecf20Sopenharmony_ci	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
24388c2ecf20Sopenharmony_ci	if (!cache)
24398c2ecf20Sopenharmony_ci		return -ENOMEM;
24408c2ecf20Sopenharmony_ci
24418c2ecf20Sopenharmony_ci	cache->ti = ca->ti;
24428c2ecf20Sopenharmony_ci	ti->private = cache;
24438c2ecf20Sopenharmony_ci	ti->num_flush_bios = 2;
24448c2ecf20Sopenharmony_ci	ti->flush_supported = true;
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci	ti->num_discard_bios = 1;
24478c2ecf20Sopenharmony_ci	ti->discards_supported = true;
24488c2ecf20Sopenharmony_ci
24498c2ecf20Sopenharmony_ci	ti->per_io_data_size = sizeof(struct per_bio_data);
24508c2ecf20Sopenharmony_ci
24518c2ecf20Sopenharmony_ci	cache->features = ca->features;
24528c2ecf20Sopenharmony_ci	if (writethrough_mode(cache)) {
24538c2ecf20Sopenharmony_ci		/* Create bioset for writethrough bios issued to origin */
24548c2ecf20Sopenharmony_ci		r = bioset_init(&cache->bs, BIO_POOL_SIZE, 0, 0);
24558c2ecf20Sopenharmony_ci		if (r)
24568c2ecf20Sopenharmony_ci			goto bad;
24578c2ecf20Sopenharmony_ci	}
24588c2ecf20Sopenharmony_ci
24598c2ecf20Sopenharmony_ci	cache->metadata_dev = ca->metadata_dev;
24608c2ecf20Sopenharmony_ci	cache->origin_dev = ca->origin_dev;
24618c2ecf20Sopenharmony_ci	cache->cache_dev = ca->cache_dev;
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_ci	ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL;
24648c2ecf20Sopenharmony_ci
24658c2ecf20Sopenharmony_ci	origin_blocks = cache->origin_sectors = ca->origin_sectors;
24668c2ecf20Sopenharmony_ci	origin_blocks = block_div(origin_blocks, ca->block_size);
24678c2ecf20Sopenharmony_ci	cache->origin_blocks = to_oblock(origin_blocks);
24688c2ecf20Sopenharmony_ci
24698c2ecf20Sopenharmony_ci	cache->sectors_per_block = ca->block_size;
24708c2ecf20Sopenharmony_ci	if (dm_set_target_max_io_len(ti, cache->sectors_per_block)) {
24718c2ecf20Sopenharmony_ci		r = -EINVAL;
24728c2ecf20Sopenharmony_ci		goto bad;
24738c2ecf20Sopenharmony_ci	}
24748c2ecf20Sopenharmony_ci
24758c2ecf20Sopenharmony_ci	if (ca->block_size & (ca->block_size - 1)) {
24768c2ecf20Sopenharmony_ci		dm_block_t cache_size = ca->cache_sectors;
24778c2ecf20Sopenharmony_ci
24788c2ecf20Sopenharmony_ci		cache->sectors_per_block_shift = -1;
24798c2ecf20Sopenharmony_ci		cache_size = block_div(cache_size, ca->block_size);
24808c2ecf20Sopenharmony_ci		set_cache_size(cache, to_cblock(cache_size));
24818c2ecf20Sopenharmony_ci	} else {
24828c2ecf20Sopenharmony_ci		cache->sectors_per_block_shift = __ffs(ca->block_size);
24838c2ecf20Sopenharmony_ci		set_cache_size(cache, to_cblock(ca->cache_sectors >> cache->sectors_per_block_shift));
24848c2ecf20Sopenharmony_ci	}
24858c2ecf20Sopenharmony_ci
24868c2ecf20Sopenharmony_ci	r = create_cache_policy(cache, ca, error);
24878c2ecf20Sopenharmony_ci	if (r)
24888c2ecf20Sopenharmony_ci		goto bad;
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci	cache->policy_nr_args = ca->policy_argc;
24918c2ecf20Sopenharmony_ci	cache->migration_threshold = DEFAULT_MIGRATION_THRESHOLD;
24928c2ecf20Sopenharmony_ci
24938c2ecf20Sopenharmony_ci	r = set_config_values(cache, ca->policy_argc, ca->policy_argv);
24948c2ecf20Sopenharmony_ci	if (r) {
24958c2ecf20Sopenharmony_ci		*error = "Error setting cache policy's config values";
24968c2ecf20Sopenharmony_ci		goto bad;
24978c2ecf20Sopenharmony_ci	}
24988c2ecf20Sopenharmony_ci
24998c2ecf20Sopenharmony_ci	cmd = dm_cache_metadata_open(cache->metadata_dev->bdev,
25008c2ecf20Sopenharmony_ci				     ca->block_size, may_format,
25018c2ecf20Sopenharmony_ci				     dm_cache_policy_get_hint_size(cache->policy),
25028c2ecf20Sopenharmony_ci				     ca->features.metadata_version);
25038c2ecf20Sopenharmony_ci	if (IS_ERR(cmd)) {
25048c2ecf20Sopenharmony_ci		*error = "Error creating metadata object";
25058c2ecf20Sopenharmony_ci		r = PTR_ERR(cmd);
25068c2ecf20Sopenharmony_ci		goto bad;
25078c2ecf20Sopenharmony_ci	}
25088c2ecf20Sopenharmony_ci	cache->cmd = cmd;
25098c2ecf20Sopenharmony_ci	set_cache_mode(cache, CM_WRITE);
25108c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) != CM_WRITE) {
25118c2ecf20Sopenharmony_ci		*error = "Unable to get write access to metadata, please check/repair metadata.";
25128c2ecf20Sopenharmony_ci		r = -EINVAL;
25138c2ecf20Sopenharmony_ci		goto bad;
25148c2ecf20Sopenharmony_ci	}
25158c2ecf20Sopenharmony_ci
25168c2ecf20Sopenharmony_ci	if (passthrough_mode(cache)) {
25178c2ecf20Sopenharmony_ci		bool all_clean;
25188c2ecf20Sopenharmony_ci
25198c2ecf20Sopenharmony_ci		r = dm_cache_metadata_all_clean(cache->cmd, &all_clean);
25208c2ecf20Sopenharmony_ci		if (r) {
25218c2ecf20Sopenharmony_ci			*error = "dm_cache_metadata_all_clean() failed";
25228c2ecf20Sopenharmony_ci			goto bad;
25238c2ecf20Sopenharmony_ci		}
25248c2ecf20Sopenharmony_ci
25258c2ecf20Sopenharmony_ci		if (!all_clean) {
25268c2ecf20Sopenharmony_ci			*error = "Cannot enter passthrough mode unless all blocks are clean";
25278c2ecf20Sopenharmony_ci			r = -EINVAL;
25288c2ecf20Sopenharmony_ci			goto bad;
25298c2ecf20Sopenharmony_ci		}
25308c2ecf20Sopenharmony_ci
25318c2ecf20Sopenharmony_ci		policy_allow_migrations(cache->policy, false);
25328c2ecf20Sopenharmony_ci	}
25338c2ecf20Sopenharmony_ci
25348c2ecf20Sopenharmony_ci	spin_lock_init(&cache->lock);
25358c2ecf20Sopenharmony_ci	bio_list_init(&cache->deferred_bios);
25368c2ecf20Sopenharmony_ci	atomic_set(&cache->nr_allocated_migrations, 0);
25378c2ecf20Sopenharmony_ci	atomic_set(&cache->nr_io_migrations, 0);
25388c2ecf20Sopenharmony_ci	init_waitqueue_head(&cache->migration_wait);
25398c2ecf20Sopenharmony_ci
25408c2ecf20Sopenharmony_ci	r = -ENOMEM;
25418c2ecf20Sopenharmony_ci	atomic_set(&cache->nr_dirty, 0);
25428c2ecf20Sopenharmony_ci	cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
25438c2ecf20Sopenharmony_ci	if (!cache->dirty_bitset) {
25448c2ecf20Sopenharmony_ci		*error = "could not allocate dirty bitset";
25458c2ecf20Sopenharmony_ci		goto bad;
25468c2ecf20Sopenharmony_ci	}
25478c2ecf20Sopenharmony_ci	clear_bitset(cache->dirty_bitset, from_cblock(cache->cache_size));
25488c2ecf20Sopenharmony_ci
25498c2ecf20Sopenharmony_ci	cache->discard_block_size =
25508c2ecf20Sopenharmony_ci		calculate_discard_block_size(cache->sectors_per_block,
25518c2ecf20Sopenharmony_ci					     cache->origin_sectors);
25528c2ecf20Sopenharmony_ci	cache->discard_nr_blocks = to_dblock(dm_sector_div_up(cache->origin_sectors,
25538c2ecf20Sopenharmony_ci							      cache->discard_block_size));
25548c2ecf20Sopenharmony_ci	cache->discard_bitset = alloc_bitset(from_dblock(cache->discard_nr_blocks));
25558c2ecf20Sopenharmony_ci	if (!cache->discard_bitset) {
25568c2ecf20Sopenharmony_ci		*error = "could not allocate discard bitset";
25578c2ecf20Sopenharmony_ci		goto bad;
25588c2ecf20Sopenharmony_ci	}
25598c2ecf20Sopenharmony_ci	clear_bitset(cache->discard_bitset, from_dblock(cache->discard_nr_blocks));
25608c2ecf20Sopenharmony_ci
25618c2ecf20Sopenharmony_ci	cache->copier = dm_kcopyd_client_create(&dm_kcopyd_throttle);
25628c2ecf20Sopenharmony_ci	if (IS_ERR(cache->copier)) {
25638c2ecf20Sopenharmony_ci		*error = "could not create kcopyd client";
25648c2ecf20Sopenharmony_ci		r = PTR_ERR(cache->copier);
25658c2ecf20Sopenharmony_ci		goto bad;
25668c2ecf20Sopenharmony_ci	}
25678c2ecf20Sopenharmony_ci
25688c2ecf20Sopenharmony_ci	cache->wq = alloc_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM, 0);
25698c2ecf20Sopenharmony_ci	if (!cache->wq) {
25708c2ecf20Sopenharmony_ci		*error = "could not create workqueue for metadata object";
25718c2ecf20Sopenharmony_ci		goto bad;
25728c2ecf20Sopenharmony_ci	}
25738c2ecf20Sopenharmony_ci	INIT_WORK(&cache->deferred_bio_worker, process_deferred_bios);
25748c2ecf20Sopenharmony_ci	INIT_WORK(&cache->migration_worker, check_migrations);
25758c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&cache->waker, do_waker);
25768c2ecf20Sopenharmony_ci
25778c2ecf20Sopenharmony_ci	cache->prison = dm_bio_prison_create_v2(cache->wq);
25788c2ecf20Sopenharmony_ci	if (!cache->prison) {
25798c2ecf20Sopenharmony_ci		*error = "could not create bio prison";
25808c2ecf20Sopenharmony_ci		goto bad;
25818c2ecf20Sopenharmony_ci	}
25828c2ecf20Sopenharmony_ci
25838c2ecf20Sopenharmony_ci	r = mempool_init_slab_pool(&cache->migration_pool, MIGRATION_POOL_SIZE,
25848c2ecf20Sopenharmony_ci				   migration_cache);
25858c2ecf20Sopenharmony_ci	if (r) {
25868c2ecf20Sopenharmony_ci		*error = "Error creating cache's migration mempool";
25878c2ecf20Sopenharmony_ci		goto bad;
25888c2ecf20Sopenharmony_ci	}
25898c2ecf20Sopenharmony_ci
25908c2ecf20Sopenharmony_ci	cache->need_tick_bio = true;
25918c2ecf20Sopenharmony_ci	cache->sized = false;
25928c2ecf20Sopenharmony_ci	cache->invalidate = false;
25938c2ecf20Sopenharmony_ci	cache->commit_requested = false;
25948c2ecf20Sopenharmony_ci	cache->loaded_mappings = false;
25958c2ecf20Sopenharmony_ci	cache->loaded_discards = false;
25968c2ecf20Sopenharmony_ci
25978c2ecf20Sopenharmony_ci	load_stats(cache);
25988c2ecf20Sopenharmony_ci
25998c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.demotion, 0);
26008c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.promotion, 0);
26018c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.copies_avoided, 0);
26028c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.cache_cell_clash, 0);
26038c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.commit_count, 0);
26048c2ecf20Sopenharmony_ci	atomic_set(&cache->stats.discard_count, 0);
26058c2ecf20Sopenharmony_ci
26068c2ecf20Sopenharmony_ci	spin_lock_init(&cache->invalidation_lock);
26078c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&cache->invalidation_requests);
26088c2ecf20Sopenharmony_ci
26098c2ecf20Sopenharmony_ci	batcher_init(&cache->committer, commit_op, cache,
26108c2ecf20Sopenharmony_ci		     issue_op, cache, cache->wq);
26118c2ecf20Sopenharmony_ci	iot_init(&cache->tracker);
26128c2ecf20Sopenharmony_ci
26138c2ecf20Sopenharmony_ci	init_rwsem(&cache->background_work_lock);
26148c2ecf20Sopenharmony_ci	prevent_background_work(cache);
26158c2ecf20Sopenharmony_ci
26168c2ecf20Sopenharmony_ci	*result = cache;
26178c2ecf20Sopenharmony_ci	return 0;
26188c2ecf20Sopenharmony_cibad:
26198c2ecf20Sopenharmony_ci	destroy(cache);
26208c2ecf20Sopenharmony_ci	return r;
26218c2ecf20Sopenharmony_ci}
26228c2ecf20Sopenharmony_ci
26238c2ecf20Sopenharmony_cistatic int copy_ctr_args(struct cache *cache, int argc, const char **argv)
26248c2ecf20Sopenharmony_ci{
26258c2ecf20Sopenharmony_ci	unsigned i;
26268c2ecf20Sopenharmony_ci	const char **copy;
26278c2ecf20Sopenharmony_ci
26288c2ecf20Sopenharmony_ci	copy = kcalloc(argc, sizeof(*copy), GFP_KERNEL);
26298c2ecf20Sopenharmony_ci	if (!copy)
26308c2ecf20Sopenharmony_ci		return -ENOMEM;
26318c2ecf20Sopenharmony_ci	for (i = 0; i < argc; i++) {
26328c2ecf20Sopenharmony_ci		copy[i] = kstrdup(argv[i], GFP_KERNEL);
26338c2ecf20Sopenharmony_ci		if (!copy[i]) {
26348c2ecf20Sopenharmony_ci			while (i--)
26358c2ecf20Sopenharmony_ci				kfree(copy[i]);
26368c2ecf20Sopenharmony_ci			kfree(copy);
26378c2ecf20Sopenharmony_ci			return -ENOMEM;
26388c2ecf20Sopenharmony_ci		}
26398c2ecf20Sopenharmony_ci	}
26408c2ecf20Sopenharmony_ci
26418c2ecf20Sopenharmony_ci	cache->nr_ctr_args = argc;
26428c2ecf20Sopenharmony_ci	cache->ctr_args = copy;
26438c2ecf20Sopenharmony_ci
26448c2ecf20Sopenharmony_ci	return 0;
26458c2ecf20Sopenharmony_ci}
26468c2ecf20Sopenharmony_ci
26478c2ecf20Sopenharmony_cistatic int cache_ctr(struct dm_target *ti, unsigned argc, char **argv)
26488c2ecf20Sopenharmony_ci{
26498c2ecf20Sopenharmony_ci	int r = -EINVAL;
26508c2ecf20Sopenharmony_ci	struct cache_args *ca;
26518c2ecf20Sopenharmony_ci	struct cache *cache = NULL;
26528c2ecf20Sopenharmony_ci
26538c2ecf20Sopenharmony_ci	ca = kzalloc(sizeof(*ca), GFP_KERNEL);
26548c2ecf20Sopenharmony_ci	if (!ca) {
26558c2ecf20Sopenharmony_ci		ti->error = "Error allocating memory for cache";
26568c2ecf20Sopenharmony_ci		return -ENOMEM;
26578c2ecf20Sopenharmony_ci	}
26588c2ecf20Sopenharmony_ci	ca->ti = ti;
26598c2ecf20Sopenharmony_ci
26608c2ecf20Sopenharmony_ci	r = parse_cache_args(ca, argc, argv, &ti->error);
26618c2ecf20Sopenharmony_ci	if (r)
26628c2ecf20Sopenharmony_ci		goto out;
26638c2ecf20Sopenharmony_ci
26648c2ecf20Sopenharmony_ci	r = cache_create(ca, &cache);
26658c2ecf20Sopenharmony_ci	if (r)
26668c2ecf20Sopenharmony_ci		goto out;
26678c2ecf20Sopenharmony_ci
26688c2ecf20Sopenharmony_ci	r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3);
26698c2ecf20Sopenharmony_ci	if (r) {
26708c2ecf20Sopenharmony_ci		destroy(cache);
26718c2ecf20Sopenharmony_ci		goto out;
26728c2ecf20Sopenharmony_ci	}
26738c2ecf20Sopenharmony_ci
26748c2ecf20Sopenharmony_ci	ti->private = cache;
26758c2ecf20Sopenharmony_ciout:
26768c2ecf20Sopenharmony_ci	destroy_cache_args(ca);
26778c2ecf20Sopenharmony_ci	return r;
26788c2ecf20Sopenharmony_ci}
26798c2ecf20Sopenharmony_ci
26808c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
26818c2ecf20Sopenharmony_ci
26828c2ecf20Sopenharmony_cistatic int cache_map(struct dm_target *ti, struct bio *bio)
26838c2ecf20Sopenharmony_ci{
26848c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
26858c2ecf20Sopenharmony_ci
26868c2ecf20Sopenharmony_ci	int r;
26878c2ecf20Sopenharmony_ci	bool commit_needed;
26888c2ecf20Sopenharmony_ci	dm_oblock_t block = get_bio_block(cache, bio);
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci	init_per_bio_data(bio);
26918c2ecf20Sopenharmony_ci	if (unlikely(from_oblock(block) >= from_oblock(cache->origin_blocks))) {
26928c2ecf20Sopenharmony_ci		/*
26938c2ecf20Sopenharmony_ci		 * This can only occur if the io goes to a partial block at
26948c2ecf20Sopenharmony_ci		 * the end of the origin device.  We don't cache these.
26958c2ecf20Sopenharmony_ci		 * Just remap to the origin and carry on.
26968c2ecf20Sopenharmony_ci		 */
26978c2ecf20Sopenharmony_ci		remap_to_origin(cache, bio);
26988c2ecf20Sopenharmony_ci		accounted_begin(cache, bio);
26998c2ecf20Sopenharmony_ci		return DM_MAPIO_REMAPPED;
27008c2ecf20Sopenharmony_ci	}
27018c2ecf20Sopenharmony_ci
27028c2ecf20Sopenharmony_ci	if (discard_or_flush(bio)) {
27038c2ecf20Sopenharmony_ci		defer_bio(cache, bio);
27048c2ecf20Sopenharmony_ci		return DM_MAPIO_SUBMITTED;
27058c2ecf20Sopenharmony_ci	}
27068c2ecf20Sopenharmony_ci
27078c2ecf20Sopenharmony_ci	r = map_bio(cache, bio, block, &commit_needed);
27088c2ecf20Sopenharmony_ci	if (commit_needed)
27098c2ecf20Sopenharmony_ci		schedule_commit(&cache->committer);
27108c2ecf20Sopenharmony_ci
27118c2ecf20Sopenharmony_ci	return r;
27128c2ecf20Sopenharmony_ci}
27138c2ecf20Sopenharmony_ci
27148c2ecf20Sopenharmony_cistatic int cache_end_io(struct dm_target *ti, struct bio *bio, blk_status_t *error)
27158c2ecf20Sopenharmony_ci{
27168c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
27178c2ecf20Sopenharmony_ci	unsigned long flags;
27188c2ecf20Sopenharmony_ci	struct per_bio_data *pb = get_per_bio_data(bio);
27198c2ecf20Sopenharmony_ci
27208c2ecf20Sopenharmony_ci	if (pb->tick) {
27218c2ecf20Sopenharmony_ci		policy_tick(cache->policy, false);
27228c2ecf20Sopenharmony_ci
27238c2ecf20Sopenharmony_ci		spin_lock_irqsave(&cache->lock, flags);
27248c2ecf20Sopenharmony_ci		cache->need_tick_bio = true;
27258c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&cache->lock, flags);
27268c2ecf20Sopenharmony_ci	}
27278c2ecf20Sopenharmony_ci
27288c2ecf20Sopenharmony_ci	bio_drop_shared_lock(cache, bio);
27298c2ecf20Sopenharmony_ci	accounted_complete(cache, bio);
27308c2ecf20Sopenharmony_ci
27318c2ecf20Sopenharmony_ci	return DM_ENDIO_DONE;
27328c2ecf20Sopenharmony_ci}
27338c2ecf20Sopenharmony_ci
27348c2ecf20Sopenharmony_cistatic int write_dirty_bitset(struct cache *cache)
27358c2ecf20Sopenharmony_ci{
27368c2ecf20Sopenharmony_ci	int r;
27378c2ecf20Sopenharmony_ci
27388c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
27398c2ecf20Sopenharmony_ci		return -EINVAL;
27408c2ecf20Sopenharmony_ci
27418c2ecf20Sopenharmony_ci	r = dm_cache_set_dirty_bits(cache->cmd, from_cblock(cache->cache_size), cache->dirty_bitset);
27428c2ecf20Sopenharmony_ci	if (r)
27438c2ecf20Sopenharmony_ci		metadata_operation_failed(cache, "dm_cache_set_dirty_bits", r);
27448c2ecf20Sopenharmony_ci
27458c2ecf20Sopenharmony_ci	return r;
27468c2ecf20Sopenharmony_ci}
27478c2ecf20Sopenharmony_ci
27488c2ecf20Sopenharmony_cistatic int write_discard_bitset(struct cache *cache)
27498c2ecf20Sopenharmony_ci{
27508c2ecf20Sopenharmony_ci	unsigned i, r;
27518c2ecf20Sopenharmony_ci
27528c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
27538c2ecf20Sopenharmony_ci		return -EINVAL;
27548c2ecf20Sopenharmony_ci
27558c2ecf20Sopenharmony_ci	r = dm_cache_discard_bitset_resize(cache->cmd, cache->discard_block_size,
27568c2ecf20Sopenharmony_ci					   cache->discard_nr_blocks);
27578c2ecf20Sopenharmony_ci	if (r) {
27588c2ecf20Sopenharmony_ci		DMERR("%s: could not resize on-disk discard bitset", cache_device_name(cache));
27598c2ecf20Sopenharmony_ci		metadata_operation_failed(cache, "dm_cache_discard_bitset_resize", r);
27608c2ecf20Sopenharmony_ci		return r;
27618c2ecf20Sopenharmony_ci	}
27628c2ecf20Sopenharmony_ci
27638c2ecf20Sopenharmony_ci	for (i = 0; i < from_dblock(cache->discard_nr_blocks); i++) {
27648c2ecf20Sopenharmony_ci		r = dm_cache_set_discard(cache->cmd, to_dblock(i),
27658c2ecf20Sopenharmony_ci					 is_discarded(cache, to_dblock(i)));
27668c2ecf20Sopenharmony_ci		if (r) {
27678c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_set_discard", r);
27688c2ecf20Sopenharmony_ci			return r;
27698c2ecf20Sopenharmony_ci		}
27708c2ecf20Sopenharmony_ci	}
27718c2ecf20Sopenharmony_ci
27728c2ecf20Sopenharmony_ci	return 0;
27738c2ecf20Sopenharmony_ci}
27748c2ecf20Sopenharmony_ci
27758c2ecf20Sopenharmony_cistatic int write_hints(struct cache *cache)
27768c2ecf20Sopenharmony_ci{
27778c2ecf20Sopenharmony_ci	int r;
27788c2ecf20Sopenharmony_ci
27798c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY)
27808c2ecf20Sopenharmony_ci		return -EINVAL;
27818c2ecf20Sopenharmony_ci
27828c2ecf20Sopenharmony_ci	r = dm_cache_write_hints(cache->cmd, cache->policy);
27838c2ecf20Sopenharmony_ci	if (r) {
27848c2ecf20Sopenharmony_ci		metadata_operation_failed(cache, "dm_cache_write_hints", r);
27858c2ecf20Sopenharmony_ci		return r;
27868c2ecf20Sopenharmony_ci	}
27878c2ecf20Sopenharmony_ci
27888c2ecf20Sopenharmony_ci	return 0;
27898c2ecf20Sopenharmony_ci}
27908c2ecf20Sopenharmony_ci
27918c2ecf20Sopenharmony_ci/*
27928c2ecf20Sopenharmony_ci * returns true on success
27938c2ecf20Sopenharmony_ci */
27948c2ecf20Sopenharmony_cistatic bool sync_metadata(struct cache *cache)
27958c2ecf20Sopenharmony_ci{
27968c2ecf20Sopenharmony_ci	int r1, r2, r3, r4;
27978c2ecf20Sopenharmony_ci
27988c2ecf20Sopenharmony_ci	r1 = write_dirty_bitset(cache);
27998c2ecf20Sopenharmony_ci	if (r1)
28008c2ecf20Sopenharmony_ci		DMERR("%s: could not write dirty bitset", cache_device_name(cache));
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	r2 = write_discard_bitset(cache);
28038c2ecf20Sopenharmony_ci	if (r2)
28048c2ecf20Sopenharmony_ci		DMERR("%s: could not write discard bitset", cache_device_name(cache));
28058c2ecf20Sopenharmony_ci
28068c2ecf20Sopenharmony_ci	save_stats(cache);
28078c2ecf20Sopenharmony_ci
28088c2ecf20Sopenharmony_ci	r3 = write_hints(cache);
28098c2ecf20Sopenharmony_ci	if (r3)
28108c2ecf20Sopenharmony_ci		DMERR("%s: could not write hints", cache_device_name(cache));
28118c2ecf20Sopenharmony_ci
28128c2ecf20Sopenharmony_ci	/*
28138c2ecf20Sopenharmony_ci	 * If writing the above metadata failed, we still commit, but don't
28148c2ecf20Sopenharmony_ci	 * set the clean shutdown flag.  This will effectively force every
28158c2ecf20Sopenharmony_ci	 * dirty bit to be set on reload.
28168c2ecf20Sopenharmony_ci	 */
28178c2ecf20Sopenharmony_ci	r4 = commit(cache, !r1 && !r2 && !r3);
28188c2ecf20Sopenharmony_ci	if (r4)
28198c2ecf20Sopenharmony_ci		DMERR("%s: could not write cache metadata", cache_device_name(cache));
28208c2ecf20Sopenharmony_ci
28218c2ecf20Sopenharmony_ci	return !r1 && !r2 && !r3 && !r4;
28228c2ecf20Sopenharmony_ci}
28238c2ecf20Sopenharmony_ci
28248c2ecf20Sopenharmony_cistatic void cache_postsuspend(struct dm_target *ti)
28258c2ecf20Sopenharmony_ci{
28268c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
28278c2ecf20Sopenharmony_ci
28288c2ecf20Sopenharmony_ci	prevent_background_work(cache);
28298c2ecf20Sopenharmony_ci	BUG_ON(atomic_read(&cache->nr_io_migrations));
28308c2ecf20Sopenharmony_ci
28318c2ecf20Sopenharmony_ci	cancel_delayed_work_sync(&cache->waker);
28328c2ecf20Sopenharmony_ci	drain_workqueue(cache->wq);
28338c2ecf20Sopenharmony_ci	WARN_ON(cache->tracker.in_flight);
28348c2ecf20Sopenharmony_ci
28358c2ecf20Sopenharmony_ci	/*
28368c2ecf20Sopenharmony_ci	 * If it's a flush suspend there won't be any deferred bios, so this
28378c2ecf20Sopenharmony_ci	 * call is harmless.
28388c2ecf20Sopenharmony_ci	 */
28398c2ecf20Sopenharmony_ci	requeue_deferred_bios(cache);
28408c2ecf20Sopenharmony_ci
28418c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) == CM_WRITE)
28428c2ecf20Sopenharmony_ci		(void) sync_metadata(cache);
28438c2ecf20Sopenharmony_ci}
28448c2ecf20Sopenharmony_ci
28458c2ecf20Sopenharmony_cistatic int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
28468c2ecf20Sopenharmony_ci			bool dirty, uint32_t hint, bool hint_valid)
28478c2ecf20Sopenharmony_ci{
28488c2ecf20Sopenharmony_ci	int r;
28498c2ecf20Sopenharmony_ci	struct cache *cache = context;
28508c2ecf20Sopenharmony_ci
28518c2ecf20Sopenharmony_ci	if (dirty) {
28528c2ecf20Sopenharmony_ci		set_bit(from_cblock(cblock), cache->dirty_bitset);
28538c2ecf20Sopenharmony_ci		atomic_inc(&cache->nr_dirty);
28548c2ecf20Sopenharmony_ci	} else
28558c2ecf20Sopenharmony_ci		clear_bit(from_cblock(cblock), cache->dirty_bitset);
28568c2ecf20Sopenharmony_ci
28578c2ecf20Sopenharmony_ci	r = policy_load_mapping(cache->policy, oblock, cblock, dirty, hint, hint_valid);
28588c2ecf20Sopenharmony_ci	if (r)
28598c2ecf20Sopenharmony_ci		return r;
28608c2ecf20Sopenharmony_ci
28618c2ecf20Sopenharmony_ci	return 0;
28628c2ecf20Sopenharmony_ci}
28638c2ecf20Sopenharmony_ci
28648c2ecf20Sopenharmony_ci/*
28658c2ecf20Sopenharmony_ci * The discard block size in the on disk metadata is not
28668c2ecf20Sopenharmony_ci * neccessarily the same as we're currently using.  So we have to
28678c2ecf20Sopenharmony_ci * be careful to only set the discarded attribute if we know it
28688c2ecf20Sopenharmony_ci * covers a complete block of the new size.
28698c2ecf20Sopenharmony_ci */
28708c2ecf20Sopenharmony_cistruct discard_load_info {
28718c2ecf20Sopenharmony_ci	struct cache *cache;
28728c2ecf20Sopenharmony_ci
28738c2ecf20Sopenharmony_ci	/*
28748c2ecf20Sopenharmony_ci	 * These blocks are sized using the on disk dblock size, rather
28758c2ecf20Sopenharmony_ci	 * than the current one.
28768c2ecf20Sopenharmony_ci	 */
28778c2ecf20Sopenharmony_ci	dm_block_t block_size;
28788c2ecf20Sopenharmony_ci	dm_block_t discard_begin, discard_end;
28798c2ecf20Sopenharmony_ci};
28808c2ecf20Sopenharmony_ci
28818c2ecf20Sopenharmony_cistatic void discard_load_info_init(struct cache *cache,
28828c2ecf20Sopenharmony_ci				   struct discard_load_info *li)
28838c2ecf20Sopenharmony_ci{
28848c2ecf20Sopenharmony_ci	li->cache = cache;
28858c2ecf20Sopenharmony_ci	li->discard_begin = li->discard_end = 0;
28868c2ecf20Sopenharmony_ci}
28878c2ecf20Sopenharmony_ci
28888c2ecf20Sopenharmony_cistatic void set_discard_range(struct discard_load_info *li)
28898c2ecf20Sopenharmony_ci{
28908c2ecf20Sopenharmony_ci	sector_t b, e;
28918c2ecf20Sopenharmony_ci
28928c2ecf20Sopenharmony_ci	if (li->discard_begin == li->discard_end)
28938c2ecf20Sopenharmony_ci		return;
28948c2ecf20Sopenharmony_ci
28958c2ecf20Sopenharmony_ci	/*
28968c2ecf20Sopenharmony_ci	 * Convert to sectors.
28978c2ecf20Sopenharmony_ci	 */
28988c2ecf20Sopenharmony_ci	b = li->discard_begin * li->block_size;
28998c2ecf20Sopenharmony_ci	e = li->discard_end * li->block_size;
29008c2ecf20Sopenharmony_ci
29018c2ecf20Sopenharmony_ci	/*
29028c2ecf20Sopenharmony_ci	 * Then convert back to the current dblock size.
29038c2ecf20Sopenharmony_ci	 */
29048c2ecf20Sopenharmony_ci	b = dm_sector_div_up(b, li->cache->discard_block_size);
29058c2ecf20Sopenharmony_ci	sector_div(e, li->cache->discard_block_size);
29068c2ecf20Sopenharmony_ci
29078c2ecf20Sopenharmony_ci	/*
29088c2ecf20Sopenharmony_ci	 * The origin may have shrunk, so we need to check we're still in
29098c2ecf20Sopenharmony_ci	 * bounds.
29108c2ecf20Sopenharmony_ci	 */
29118c2ecf20Sopenharmony_ci	if (e > from_dblock(li->cache->discard_nr_blocks))
29128c2ecf20Sopenharmony_ci		e = from_dblock(li->cache->discard_nr_blocks);
29138c2ecf20Sopenharmony_ci
29148c2ecf20Sopenharmony_ci	for (; b < e; b++)
29158c2ecf20Sopenharmony_ci		set_discard(li->cache, to_dblock(b));
29168c2ecf20Sopenharmony_ci}
29178c2ecf20Sopenharmony_ci
29188c2ecf20Sopenharmony_cistatic int load_discard(void *context, sector_t discard_block_size,
29198c2ecf20Sopenharmony_ci			dm_dblock_t dblock, bool discard)
29208c2ecf20Sopenharmony_ci{
29218c2ecf20Sopenharmony_ci	struct discard_load_info *li = context;
29228c2ecf20Sopenharmony_ci
29238c2ecf20Sopenharmony_ci	li->block_size = discard_block_size;
29248c2ecf20Sopenharmony_ci
29258c2ecf20Sopenharmony_ci	if (discard) {
29268c2ecf20Sopenharmony_ci		if (from_dblock(dblock) == li->discard_end)
29278c2ecf20Sopenharmony_ci			/*
29288c2ecf20Sopenharmony_ci			 * We're already in a discard range, just extend it.
29298c2ecf20Sopenharmony_ci			 */
29308c2ecf20Sopenharmony_ci			li->discard_end = li->discard_end + 1ULL;
29318c2ecf20Sopenharmony_ci
29328c2ecf20Sopenharmony_ci		else {
29338c2ecf20Sopenharmony_ci			/*
29348c2ecf20Sopenharmony_ci			 * Emit the old range and start a new one.
29358c2ecf20Sopenharmony_ci			 */
29368c2ecf20Sopenharmony_ci			set_discard_range(li);
29378c2ecf20Sopenharmony_ci			li->discard_begin = from_dblock(dblock);
29388c2ecf20Sopenharmony_ci			li->discard_end = li->discard_begin + 1ULL;
29398c2ecf20Sopenharmony_ci		}
29408c2ecf20Sopenharmony_ci	} else {
29418c2ecf20Sopenharmony_ci		set_discard_range(li);
29428c2ecf20Sopenharmony_ci		li->discard_begin = li->discard_end = 0;
29438c2ecf20Sopenharmony_ci	}
29448c2ecf20Sopenharmony_ci
29458c2ecf20Sopenharmony_ci	return 0;
29468c2ecf20Sopenharmony_ci}
29478c2ecf20Sopenharmony_ci
29488c2ecf20Sopenharmony_cistatic dm_cblock_t get_cache_dev_size(struct cache *cache)
29498c2ecf20Sopenharmony_ci{
29508c2ecf20Sopenharmony_ci	sector_t size = get_dev_size(cache->cache_dev);
29518c2ecf20Sopenharmony_ci	(void) sector_div(size, cache->sectors_per_block);
29528c2ecf20Sopenharmony_ci	return to_cblock(size);
29538c2ecf20Sopenharmony_ci}
29548c2ecf20Sopenharmony_ci
29558c2ecf20Sopenharmony_cistatic bool can_resize(struct cache *cache, dm_cblock_t new_size)
29568c2ecf20Sopenharmony_ci{
29578c2ecf20Sopenharmony_ci	if (from_cblock(new_size) > from_cblock(cache->cache_size)) {
29588c2ecf20Sopenharmony_ci		if (cache->sized) {
29598c2ecf20Sopenharmony_ci			DMERR("%s: unable to extend cache due to missing cache table reload",
29608c2ecf20Sopenharmony_ci			      cache_device_name(cache));
29618c2ecf20Sopenharmony_ci			return false;
29628c2ecf20Sopenharmony_ci		}
29638c2ecf20Sopenharmony_ci	}
29648c2ecf20Sopenharmony_ci
29658c2ecf20Sopenharmony_ci	/*
29668c2ecf20Sopenharmony_ci	 * We can't drop a dirty block when shrinking the cache.
29678c2ecf20Sopenharmony_ci	 */
29688c2ecf20Sopenharmony_ci	while (from_cblock(new_size) < from_cblock(cache->cache_size)) {
29698c2ecf20Sopenharmony_ci		new_size = to_cblock(from_cblock(new_size) + 1);
29708c2ecf20Sopenharmony_ci		if (is_dirty(cache, new_size)) {
29718c2ecf20Sopenharmony_ci			DMERR("%s: unable to shrink cache; cache block %llu is dirty",
29728c2ecf20Sopenharmony_ci			      cache_device_name(cache),
29738c2ecf20Sopenharmony_ci			      (unsigned long long) from_cblock(new_size));
29748c2ecf20Sopenharmony_ci			return false;
29758c2ecf20Sopenharmony_ci		}
29768c2ecf20Sopenharmony_ci	}
29778c2ecf20Sopenharmony_ci
29788c2ecf20Sopenharmony_ci	return true;
29798c2ecf20Sopenharmony_ci}
29808c2ecf20Sopenharmony_ci
29818c2ecf20Sopenharmony_cistatic int resize_cache_dev(struct cache *cache, dm_cblock_t new_size)
29828c2ecf20Sopenharmony_ci{
29838c2ecf20Sopenharmony_ci	int r;
29848c2ecf20Sopenharmony_ci
29858c2ecf20Sopenharmony_ci	r = dm_cache_resize(cache->cmd, new_size);
29868c2ecf20Sopenharmony_ci	if (r) {
29878c2ecf20Sopenharmony_ci		DMERR("%s: could not resize cache metadata", cache_device_name(cache));
29888c2ecf20Sopenharmony_ci		metadata_operation_failed(cache, "dm_cache_resize", r);
29898c2ecf20Sopenharmony_ci		return r;
29908c2ecf20Sopenharmony_ci	}
29918c2ecf20Sopenharmony_ci
29928c2ecf20Sopenharmony_ci	set_cache_size(cache, new_size);
29938c2ecf20Sopenharmony_ci
29948c2ecf20Sopenharmony_ci	return 0;
29958c2ecf20Sopenharmony_ci}
29968c2ecf20Sopenharmony_ci
29978c2ecf20Sopenharmony_cistatic int cache_preresume(struct dm_target *ti)
29988c2ecf20Sopenharmony_ci{
29998c2ecf20Sopenharmony_ci	int r = 0;
30008c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
30018c2ecf20Sopenharmony_ci	dm_cblock_t csize = get_cache_dev_size(cache);
30028c2ecf20Sopenharmony_ci
30038c2ecf20Sopenharmony_ci	/*
30048c2ecf20Sopenharmony_ci	 * Check to see if the cache has resized.
30058c2ecf20Sopenharmony_ci	 */
30068c2ecf20Sopenharmony_ci	if (!cache->sized) {
30078c2ecf20Sopenharmony_ci		r = resize_cache_dev(cache, csize);
30088c2ecf20Sopenharmony_ci		if (r)
30098c2ecf20Sopenharmony_ci			return r;
30108c2ecf20Sopenharmony_ci
30118c2ecf20Sopenharmony_ci		cache->sized = true;
30128c2ecf20Sopenharmony_ci
30138c2ecf20Sopenharmony_ci	} else if (csize != cache->cache_size) {
30148c2ecf20Sopenharmony_ci		if (!can_resize(cache, csize))
30158c2ecf20Sopenharmony_ci			return -EINVAL;
30168c2ecf20Sopenharmony_ci
30178c2ecf20Sopenharmony_ci		r = resize_cache_dev(cache, csize);
30188c2ecf20Sopenharmony_ci		if (r)
30198c2ecf20Sopenharmony_ci			return r;
30208c2ecf20Sopenharmony_ci	}
30218c2ecf20Sopenharmony_ci
30228c2ecf20Sopenharmony_ci	if (!cache->loaded_mappings) {
30238c2ecf20Sopenharmony_ci		r = dm_cache_load_mappings(cache->cmd, cache->policy,
30248c2ecf20Sopenharmony_ci					   load_mapping, cache);
30258c2ecf20Sopenharmony_ci		if (r) {
30268c2ecf20Sopenharmony_ci			DMERR("%s: could not load cache mappings", cache_device_name(cache));
30278c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_load_mappings", r);
30288c2ecf20Sopenharmony_ci			return r;
30298c2ecf20Sopenharmony_ci		}
30308c2ecf20Sopenharmony_ci
30318c2ecf20Sopenharmony_ci		cache->loaded_mappings = true;
30328c2ecf20Sopenharmony_ci	}
30338c2ecf20Sopenharmony_ci
30348c2ecf20Sopenharmony_ci	if (!cache->loaded_discards) {
30358c2ecf20Sopenharmony_ci		struct discard_load_info li;
30368c2ecf20Sopenharmony_ci
30378c2ecf20Sopenharmony_ci		/*
30388c2ecf20Sopenharmony_ci		 * The discard bitset could have been resized, or the
30398c2ecf20Sopenharmony_ci		 * discard block size changed.  To be safe we start by
30408c2ecf20Sopenharmony_ci		 * setting every dblock to not discarded.
30418c2ecf20Sopenharmony_ci		 */
30428c2ecf20Sopenharmony_ci		clear_bitset(cache->discard_bitset, from_dblock(cache->discard_nr_blocks));
30438c2ecf20Sopenharmony_ci
30448c2ecf20Sopenharmony_ci		discard_load_info_init(cache, &li);
30458c2ecf20Sopenharmony_ci		r = dm_cache_load_discards(cache->cmd, load_discard, &li);
30468c2ecf20Sopenharmony_ci		if (r) {
30478c2ecf20Sopenharmony_ci			DMERR("%s: could not load origin discards", cache_device_name(cache));
30488c2ecf20Sopenharmony_ci			metadata_operation_failed(cache, "dm_cache_load_discards", r);
30498c2ecf20Sopenharmony_ci			return r;
30508c2ecf20Sopenharmony_ci		}
30518c2ecf20Sopenharmony_ci		set_discard_range(&li);
30528c2ecf20Sopenharmony_ci
30538c2ecf20Sopenharmony_ci		cache->loaded_discards = true;
30548c2ecf20Sopenharmony_ci	}
30558c2ecf20Sopenharmony_ci
30568c2ecf20Sopenharmony_ci	return r;
30578c2ecf20Sopenharmony_ci}
30588c2ecf20Sopenharmony_ci
30598c2ecf20Sopenharmony_cistatic void cache_resume(struct dm_target *ti)
30608c2ecf20Sopenharmony_ci{
30618c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
30628c2ecf20Sopenharmony_ci
30638c2ecf20Sopenharmony_ci	cache->need_tick_bio = true;
30648c2ecf20Sopenharmony_ci	allow_background_work(cache);
30658c2ecf20Sopenharmony_ci	do_waker(&cache->waker.work);
30668c2ecf20Sopenharmony_ci}
30678c2ecf20Sopenharmony_ci
30688c2ecf20Sopenharmony_cistatic void emit_flags(struct cache *cache, char *result,
30698c2ecf20Sopenharmony_ci		       unsigned maxlen, ssize_t *sz_ptr)
30708c2ecf20Sopenharmony_ci{
30718c2ecf20Sopenharmony_ci	ssize_t sz = *sz_ptr;
30728c2ecf20Sopenharmony_ci	struct cache_features *cf = &cache->features;
30738c2ecf20Sopenharmony_ci	unsigned count = (cf->metadata_version == 2) + !cf->discard_passdown + 1;
30748c2ecf20Sopenharmony_ci
30758c2ecf20Sopenharmony_ci	DMEMIT("%u ", count);
30768c2ecf20Sopenharmony_ci
30778c2ecf20Sopenharmony_ci	if (cf->metadata_version == 2)
30788c2ecf20Sopenharmony_ci		DMEMIT("metadata2 ");
30798c2ecf20Sopenharmony_ci
30808c2ecf20Sopenharmony_ci	if (writethrough_mode(cache))
30818c2ecf20Sopenharmony_ci		DMEMIT("writethrough ");
30828c2ecf20Sopenharmony_ci
30838c2ecf20Sopenharmony_ci	else if (passthrough_mode(cache))
30848c2ecf20Sopenharmony_ci		DMEMIT("passthrough ");
30858c2ecf20Sopenharmony_ci
30868c2ecf20Sopenharmony_ci	else if (writeback_mode(cache))
30878c2ecf20Sopenharmony_ci		DMEMIT("writeback ");
30888c2ecf20Sopenharmony_ci
30898c2ecf20Sopenharmony_ci	else {
30908c2ecf20Sopenharmony_ci		DMEMIT("unknown ");
30918c2ecf20Sopenharmony_ci		DMERR("%s: internal error: unknown io mode: %d",
30928c2ecf20Sopenharmony_ci		      cache_device_name(cache), (int) cf->io_mode);
30938c2ecf20Sopenharmony_ci	}
30948c2ecf20Sopenharmony_ci
30958c2ecf20Sopenharmony_ci	if (!cf->discard_passdown)
30968c2ecf20Sopenharmony_ci		DMEMIT("no_discard_passdown ");
30978c2ecf20Sopenharmony_ci
30988c2ecf20Sopenharmony_ci	*sz_ptr = sz;
30998c2ecf20Sopenharmony_ci}
31008c2ecf20Sopenharmony_ci
31018c2ecf20Sopenharmony_ci/*
31028c2ecf20Sopenharmony_ci * Status format:
31038c2ecf20Sopenharmony_ci *
31048c2ecf20Sopenharmony_ci * <metadata block size> <#used metadata blocks>/<#total metadata blocks>
31058c2ecf20Sopenharmony_ci * <cache block size> <#used cache blocks>/<#total cache blocks>
31068c2ecf20Sopenharmony_ci * <#read hits> <#read misses> <#write hits> <#write misses>
31078c2ecf20Sopenharmony_ci * <#demotions> <#promotions> <#dirty>
31088c2ecf20Sopenharmony_ci * <#features> <features>*
31098c2ecf20Sopenharmony_ci * <#core args> <core args>
31108c2ecf20Sopenharmony_ci * <policy name> <#policy args> <policy args>* <cache metadata mode> <needs_check>
31118c2ecf20Sopenharmony_ci */
31128c2ecf20Sopenharmony_cistatic void cache_status(struct dm_target *ti, status_type_t type,
31138c2ecf20Sopenharmony_ci			 unsigned status_flags, char *result, unsigned maxlen)
31148c2ecf20Sopenharmony_ci{
31158c2ecf20Sopenharmony_ci	int r = 0;
31168c2ecf20Sopenharmony_ci	unsigned i;
31178c2ecf20Sopenharmony_ci	ssize_t sz = 0;
31188c2ecf20Sopenharmony_ci	dm_block_t nr_free_blocks_metadata = 0;
31198c2ecf20Sopenharmony_ci	dm_block_t nr_blocks_metadata = 0;
31208c2ecf20Sopenharmony_ci	char buf[BDEVNAME_SIZE];
31218c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
31228c2ecf20Sopenharmony_ci	dm_cblock_t residency;
31238c2ecf20Sopenharmony_ci	bool needs_check;
31248c2ecf20Sopenharmony_ci
31258c2ecf20Sopenharmony_ci	switch (type) {
31268c2ecf20Sopenharmony_ci	case STATUSTYPE_INFO:
31278c2ecf20Sopenharmony_ci		if (get_cache_mode(cache) == CM_FAIL) {
31288c2ecf20Sopenharmony_ci			DMEMIT("Fail");
31298c2ecf20Sopenharmony_ci			break;
31308c2ecf20Sopenharmony_ci		}
31318c2ecf20Sopenharmony_ci
31328c2ecf20Sopenharmony_ci		/* Commit to ensure statistics aren't out-of-date */
31338c2ecf20Sopenharmony_ci		if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
31348c2ecf20Sopenharmony_ci			(void) commit(cache, false);
31358c2ecf20Sopenharmony_ci
31368c2ecf20Sopenharmony_ci		r = dm_cache_get_free_metadata_block_count(cache->cmd, &nr_free_blocks_metadata);
31378c2ecf20Sopenharmony_ci		if (r) {
31388c2ecf20Sopenharmony_ci			DMERR("%s: dm_cache_get_free_metadata_block_count returned %d",
31398c2ecf20Sopenharmony_ci			      cache_device_name(cache), r);
31408c2ecf20Sopenharmony_ci			goto err;
31418c2ecf20Sopenharmony_ci		}
31428c2ecf20Sopenharmony_ci
31438c2ecf20Sopenharmony_ci		r = dm_cache_get_metadata_dev_size(cache->cmd, &nr_blocks_metadata);
31448c2ecf20Sopenharmony_ci		if (r) {
31458c2ecf20Sopenharmony_ci			DMERR("%s: dm_cache_get_metadata_dev_size returned %d",
31468c2ecf20Sopenharmony_ci			      cache_device_name(cache), r);
31478c2ecf20Sopenharmony_ci			goto err;
31488c2ecf20Sopenharmony_ci		}
31498c2ecf20Sopenharmony_ci
31508c2ecf20Sopenharmony_ci		residency = policy_residency(cache->policy);
31518c2ecf20Sopenharmony_ci
31528c2ecf20Sopenharmony_ci		DMEMIT("%u %llu/%llu %llu %llu/%llu %u %u %u %u %u %u %lu ",
31538c2ecf20Sopenharmony_ci		       (unsigned)DM_CACHE_METADATA_BLOCK_SIZE,
31548c2ecf20Sopenharmony_ci		       (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
31558c2ecf20Sopenharmony_ci		       (unsigned long long)nr_blocks_metadata,
31568c2ecf20Sopenharmony_ci		       (unsigned long long)cache->sectors_per_block,
31578c2ecf20Sopenharmony_ci		       (unsigned long long) from_cblock(residency),
31588c2ecf20Sopenharmony_ci		       (unsigned long long) from_cblock(cache->cache_size),
31598c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.read_hit),
31608c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.read_miss),
31618c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.write_hit),
31628c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.write_miss),
31638c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.demotion),
31648c2ecf20Sopenharmony_ci		       (unsigned) atomic_read(&cache->stats.promotion),
31658c2ecf20Sopenharmony_ci		       (unsigned long) atomic_read(&cache->nr_dirty));
31668c2ecf20Sopenharmony_ci
31678c2ecf20Sopenharmony_ci		emit_flags(cache, result, maxlen, &sz);
31688c2ecf20Sopenharmony_ci
31698c2ecf20Sopenharmony_ci		DMEMIT("2 migration_threshold %llu ", (unsigned long long) cache->migration_threshold);
31708c2ecf20Sopenharmony_ci
31718c2ecf20Sopenharmony_ci		DMEMIT("%s ", dm_cache_policy_get_name(cache->policy));
31728c2ecf20Sopenharmony_ci		if (sz < maxlen) {
31738c2ecf20Sopenharmony_ci			r = policy_emit_config_values(cache->policy, result, maxlen, &sz);
31748c2ecf20Sopenharmony_ci			if (r)
31758c2ecf20Sopenharmony_ci				DMERR("%s: policy_emit_config_values returned %d",
31768c2ecf20Sopenharmony_ci				      cache_device_name(cache), r);
31778c2ecf20Sopenharmony_ci		}
31788c2ecf20Sopenharmony_ci
31798c2ecf20Sopenharmony_ci		if (get_cache_mode(cache) == CM_READ_ONLY)
31808c2ecf20Sopenharmony_ci			DMEMIT("ro ");
31818c2ecf20Sopenharmony_ci		else
31828c2ecf20Sopenharmony_ci			DMEMIT("rw ");
31838c2ecf20Sopenharmony_ci
31848c2ecf20Sopenharmony_ci		r = dm_cache_metadata_needs_check(cache->cmd, &needs_check);
31858c2ecf20Sopenharmony_ci
31868c2ecf20Sopenharmony_ci		if (r || needs_check)
31878c2ecf20Sopenharmony_ci			DMEMIT("needs_check ");
31888c2ecf20Sopenharmony_ci		else
31898c2ecf20Sopenharmony_ci			DMEMIT("- ");
31908c2ecf20Sopenharmony_ci
31918c2ecf20Sopenharmony_ci		break;
31928c2ecf20Sopenharmony_ci
31938c2ecf20Sopenharmony_ci	case STATUSTYPE_TABLE:
31948c2ecf20Sopenharmony_ci		format_dev_t(buf, cache->metadata_dev->bdev->bd_dev);
31958c2ecf20Sopenharmony_ci		DMEMIT("%s ", buf);
31968c2ecf20Sopenharmony_ci		format_dev_t(buf, cache->cache_dev->bdev->bd_dev);
31978c2ecf20Sopenharmony_ci		DMEMIT("%s ", buf);
31988c2ecf20Sopenharmony_ci		format_dev_t(buf, cache->origin_dev->bdev->bd_dev);
31998c2ecf20Sopenharmony_ci		DMEMIT("%s", buf);
32008c2ecf20Sopenharmony_ci
32018c2ecf20Sopenharmony_ci		for (i = 0; i < cache->nr_ctr_args - 1; i++)
32028c2ecf20Sopenharmony_ci			DMEMIT(" %s", cache->ctr_args[i]);
32038c2ecf20Sopenharmony_ci		if (cache->nr_ctr_args)
32048c2ecf20Sopenharmony_ci			DMEMIT(" %s", cache->ctr_args[cache->nr_ctr_args - 1]);
32058c2ecf20Sopenharmony_ci	}
32068c2ecf20Sopenharmony_ci
32078c2ecf20Sopenharmony_ci	return;
32088c2ecf20Sopenharmony_ci
32098c2ecf20Sopenharmony_cierr:
32108c2ecf20Sopenharmony_ci	DMEMIT("Error");
32118c2ecf20Sopenharmony_ci}
32128c2ecf20Sopenharmony_ci
32138c2ecf20Sopenharmony_ci/*
32148c2ecf20Sopenharmony_ci * Defines a range of cblocks, begin to (end - 1) are in the range.  end is
32158c2ecf20Sopenharmony_ci * the one-past-the-end value.
32168c2ecf20Sopenharmony_ci */
32178c2ecf20Sopenharmony_cistruct cblock_range {
32188c2ecf20Sopenharmony_ci	dm_cblock_t begin;
32198c2ecf20Sopenharmony_ci	dm_cblock_t end;
32208c2ecf20Sopenharmony_ci};
32218c2ecf20Sopenharmony_ci
32228c2ecf20Sopenharmony_ci/*
32238c2ecf20Sopenharmony_ci * A cache block range can take two forms:
32248c2ecf20Sopenharmony_ci *
32258c2ecf20Sopenharmony_ci * i) A single cblock, eg. '3456'
32268c2ecf20Sopenharmony_ci * ii) A begin and end cblock with a dash between, eg. 123-234
32278c2ecf20Sopenharmony_ci */
32288c2ecf20Sopenharmony_cistatic int parse_cblock_range(struct cache *cache, const char *str,
32298c2ecf20Sopenharmony_ci			      struct cblock_range *result)
32308c2ecf20Sopenharmony_ci{
32318c2ecf20Sopenharmony_ci	char dummy;
32328c2ecf20Sopenharmony_ci	uint64_t b, e;
32338c2ecf20Sopenharmony_ci	int r;
32348c2ecf20Sopenharmony_ci
32358c2ecf20Sopenharmony_ci	/*
32368c2ecf20Sopenharmony_ci	 * Try and parse form (ii) first.
32378c2ecf20Sopenharmony_ci	 */
32388c2ecf20Sopenharmony_ci	r = sscanf(str, "%llu-%llu%c", &b, &e, &dummy);
32398c2ecf20Sopenharmony_ci	if (r < 0)
32408c2ecf20Sopenharmony_ci		return r;
32418c2ecf20Sopenharmony_ci
32428c2ecf20Sopenharmony_ci	if (r == 2) {
32438c2ecf20Sopenharmony_ci		result->begin = to_cblock(b);
32448c2ecf20Sopenharmony_ci		result->end = to_cblock(e);
32458c2ecf20Sopenharmony_ci		return 0;
32468c2ecf20Sopenharmony_ci	}
32478c2ecf20Sopenharmony_ci
32488c2ecf20Sopenharmony_ci	/*
32498c2ecf20Sopenharmony_ci	 * That didn't work, try form (i).
32508c2ecf20Sopenharmony_ci	 */
32518c2ecf20Sopenharmony_ci	r = sscanf(str, "%llu%c", &b, &dummy);
32528c2ecf20Sopenharmony_ci	if (r < 0)
32538c2ecf20Sopenharmony_ci		return r;
32548c2ecf20Sopenharmony_ci
32558c2ecf20Sopenharmony_ci	if (r == 1) {
32568c2ecf20Sopenharmony_ci		result->begin = to_cblock(b);
32578c2ecf20Sopenharmony_ci		result->end = to_cblock(from_cblock(result->begin) + 1u);
32588c2ecf20Sopenharmony_ci		return 0;
32598c2ecf20Sopenharmony_ci	}
32608c2ecf20Sopenharmony_ci
32618c2ecf20Sopenharmony_ci	DMERR("%s: invalid cblock range '%s'", cache_device_name(cache), str);
32628c2ecf20Sopenharmony_ci	return -EINVAL;
32638c2ecf20Sopenharmony_ci}
32648c2ecf20Sopenharmony_ci
32658c2ecf20Sopenharmony_cistatic int validate_cblock_range(struct cache *cache, struct cblock_range *range)
32668c2ecf20Sopenharmony_ci{
32678c2ecf20Sopenharmony_ci	uint64_t b = from_cblock(range->begin);
32688c2ecf20Sopenharmony_ci	uint64_t e = from_cblock(range->end);
32698c2ecf20Sopenharmony_ci	uint64_t n = from_cblock(cache->cache_size);
32708c2ecf20Sopenharmony_ci
32718c2ecf20Sopenharmony_ci	if (b >= n) {
32728c2ecf20Sopenharmony_ci		DMERR("%s: begin cblock out of range: %llu >= %llu",
32738c2ecf20Sopenharmony_ci		      cache_device_name(cache), b, n);
32748c2ecf20Sopenharmony_ci		return -EINVAL;
32758c2ecf20Sopenharmony_ci	}
32768c2ecf20Sopenharmony_ci
32778c2ecf20Sopenharmony_ci	if (e > n) {
32788c2ecf20Sopenharmony_ci		DMERR("%s: end cblock out of range: %llu > %llu",
32798c2ecf20Sopenharmony_ci		      cache_device_name(cache), e, n);
32808c2ecf20Sopenharmony_ci		return -EINVAL;
32818c2ecf20Sopenharmony_ci	}
32828c2ecf20Sopenharmony_ci
32838c2ecf20Sopenharmony_ci	if (b >= e) {
32848c2ecf20Sopenharmony_ci		DMERR("%s: invalid cblock range: %llu >= %llu",
32858c2ecf20Sopenharmony_ci		      cache_device_name(cache), b, e);
32868c2ecf20Sopenharmony_ci		return -EINVAL;
32878c2ecf20Sopenharmony_ci	}
32888c2ecf20Sopenharmony_ci
32898c2ecf20Sopenharmony_ci	return 0;
32908c2ecf20Sopenharmony_ci}
32918c2ecf20Sopenharmony_ci
32928c2ecf20Sopenharmony_cistatic inline dm_cblock_t cblock_succ(dm_cblock_t b)
32938c2ecf20Sopenharmony_ci{
32948c2ecf20Sopenharmony_ci	return to_cblock(from_cblock(b) + 1);
32958c2ecf20Sopenharmony_ci}
32968c2ecf20Sopenharmony_ci
32978c2ecf20Sopenharmony_cistatic int request_invalidation(struct cache *cache, struct cblock_range *range)
32988c2ecf20Sopenharmony_ci{
32998c2ecf20Sopenharmony_ci	int r = 0;
33008c2ecf20Sopenharmony_ci
33018c2ecf20Sopenharmony_ci	/*
33028c2ecf20Sopenharmony_ci	 * We don't need to do any locking here because we know we're in
33038c2ecf20Sopenharmony_ci	 * passthrough mode.  There's is potential for a race between an
33048c2ecf20Sopenharmony_ci	 * invalidation triggered by an io and an invalidation message.  This
33058c2ecf20Sopenharmony_ci	 * is harmless, we must not worry if the policy call fails.
33068c2ecf20Sopenharmony_ci	 */
33078c2ecf20Sopenharmony_ci	while (range->begin != range->end) {
33088c2ecf20Sopenharmony_ci		r = invalidate_cblock(cache, range->begin);
33098c2ecf20Sopenharmony_ci		if (r)
33108c2ecf20Sopenharmony_ci			return r;
33118c2ecf20Sopenharmony_ci
33128c2ecf20Sopenharmony_ci		range->begin = cblock_succ(range->begin);
33138c2ecf20Sopenharmony_ci	}
33148c2ecf20Sopenharmony_ci
33158c2ecf20Sopenharmony_ci	cache->commit_requested = true;
33168c2ecf20Sopenharmony_ci	return r;
33178c2ecf20Sopenharmony_ci}
33188c2ecf20Sopenharmony_ci
33198c2ecf20Sopenharmony_cistatic int process_invalidate_cblocks_message(struct cache *cache, unsigned count,
33208c2ecf20Sopenharmony_ci					      const char **cblock_ranges)
33218c2ecf20Sopenharmony_ci{
33228c2ecf20Sopenharmony_ci	int r = 0;
33238c2ecf20Sopenharmony_ci	unsigned i;
33248c2ecf20Sopenharmony_ci	struct cblock_range range;
33258c2ecf20Sopenharmony_ci
33268c2ecf20Sopenharmony_ci	if (!passthrough_mode(cache)) {
33278c2ecf20Sopenharmony_ci		DMERR("%s: cache has to be in passthrough mode for invalidation",
33288c2ecf20Sopenharmony_ci		      cache_device_name(cache));
33298c2ecf20Sopenharmony_ci		return -EPERM;
33308c2ecf20Sopenharmony_ci	}
33318c2ecf20Sopenharmony_ci
33328c2ecf20Sopenharmony_ci	for (i = 0; i < count; i++) {
33338c2ecf20Sopenharmony_ci		r = parse_cblock_range(cache, cblock_ranges[i], &range);
33348c2ecf20Sopenharmony_ci		if (r)
33358c2ecf20Sopenharmony_ci			break;
33368c2ecf20Sopenharmony_ci
33378c2ecf20Sopenharmony_ci		r = validate_cblock_range(cache, &range);
33388c2ecf20Sopenharmony_ci		if (r)
33398c2ecf20Sopenharmony_ci			break;
33408c2ecf20Sopenharmony_ci
33418c2ecf20Sopenharmony_ci		/*
33428c2ecf20Sopenharmony_ci		 * Pass begin and end origin blocks to the worker and wake it.
33438c2ecf20Sopenharmony_ci		 */
33448c2ecf20Sopenharmony_ci		r = request_invalidation(cache, &range);
33458c2ecf20Sopenharmony_ci		if (r)
33468c2ecf20Sopenharmony_ci			break;
33478c2ecf20Sopenharmony_ci	}
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci	return r;
33508c2ecf20Sopenharmony_ci}
33518c2ecf20Sopenharmony_ci
33528c2ecf20Sopenharmony_ci/*
33538c2ecf20Sopenharmony_ci * Supports
33548c2ecf20Sopenharmony_ci *	"<key> <value>"
33558c2ecf20Sopenharmony_ci * and
33568c2ecf20Sopenharmony_ci *     "invalidate_cblocks [(<begin>)|(<begin>-<end>)]*
33578c2ecf20Sopenharmony_ci *
33588c2ecf20Sopenharmony_ci * The key migration_threshold is supported by the cache target core.
33598c2ecf20Sopenharmony_ci */
33608c2ecf20Sopenharmony_cistatic int cache_message(struct dm_target *ti, unsigned argc, char **argv,
33618c2ecf20Sopenharmony_ci			 char *result, unsigned maxlen)
33628c2ecf20Sopenharmony_ci{
33638c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
33648c2ecf20Sopenharmony_ci
33658c2ecf20Sopenharmony_ci	if (!argc)
33668c2ecf20Sopenharmony_ci		return -EINVAL;
33678c2ecf20Sopenharmony_ci
33688c2ecf20Sopenharmony_ci	if (get_cache_mode(cache) >= CM_READ_ONLY) {
33698c2ecf20Sopenharmony_ci		DMERR("%s: unable to service cache target messages in READ_ONLY or FAIL mode",
33708c2ecf20Sopenharmony_ci		      cache_device_name(cache));
33718c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
33728c2ecf20Sopenharmony_ci	}
33738c2ecf20Sopenharmony_ci
33748c2ecf20Sopenharmony_ci	if (!strcasecmp(argv[0], "invalidate_cblocks"))
33758c2ecf20Sopenharmony_ci		return process_invalidate_cblocks_message(cache, argc - 1, (const char **) argv + 1);
33768c2ecf20Sopenharmony_ci
33778c2ecf20Sopenharmony_ci	if (argc != 2)
33788c2ecf20Sopenharmony_ci		return -EINVAL;
33798c2ecf20Sopenharmony_ci
33808c2ecf20Sopenharmony_ci	return set_config_value(cache, argv[0], argv[1]);
33818c2ecf20Sopenharmony_ci}
33828c2ecf20Sopenharmony_ci
33838c2ecf20Sopenharmony_cistatic int cache_iterate_devices(struct dm_target *ti,
33848c2ecf20Sopenharmony_ci				 iterate_devices_callout_fn fn, void *data)
33858c2ecf20Sopenharmony_ci{
33868c2ecf20Sopenharmony_ci	int r = 0;
33878c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
33888c2ecf20Sopenharmony_ci
33898c2ecf20Sopenharmony_ci	r = fn(ti, cache->cache_dev, 0, get_dev_size(cache->cache_dev), data);
33908c2ecf20Sopenharmony_ci	if (!r)
33918c2ecf20Sopenharmony_ci		r = fn(ti, cache->origin_dev, 0, ti->len, data);
33928c2ecf20Sopenharmony_ci
33938c2ecf20Sopenharmony_ci	return r;
33948c2ecf20Sopenharmony_ci}
33958c2ecf20Sopenharmony_ci
33968c2ecf20Sopenharmony_cistatic bool origin_dev_supports_discard(struct block_device *origin_bdev)
33978c2ecf20Sopenharmony_ci{
33988c2ecf20Sopenharmony_ci	struct request_queue *q = bdev_get_queue(origin_bdev);
33998c2ecf20Sopenharmony_ci
34008c2ecf20Sopenharmony_ci	return q && blk_queue_discard(q);
34018c2ecf20Sopenharmony_ci}
34028c2ecf20Sopenharmony_ci
34038c2ecf20Sopenharmony_ci/*
34048c2ecf20Sopenharmony_ci * If discard_passdown was enabled verify that the origin device
34058c2ecf20Sopenharmony_ci * supports discards.  Disable discard_passdown if not.
34068c2ecf20Sopenharmony_ci */
34078c2ecf20Sopenharmony_cistatic void disable_passdown_if_not_supported(struct cache *cache)
34088c2ecf20Sopenharmony_ci{
34098c2ecf20Sopenharmony_ci	struct block_device *origin_bdev = cache->origin_dev->bdev;
34108c2ecf20Sopenharmony_ci	struct queue_limits *origin_limits = &bdev_get_queue(origin_bdev)->limits;
34118c2ecf20Sopenharmony_ci	const char *reason = NULL;
34128c2ecf20Sopenharmony_ci	char buf[BDEVNAME_SIZE];
34138c2ecf20Sopenharmony_ci
34148c2ecf20Sopenharmony_ci	if (!cache->features.discard_passdown)
34158c2ecf20Sopenharmony_ci		return;
34168c2ecf20Sopenharmony_ci
34178c2ecf20Sopenharmony_ci	if (!origin_dev_supports_discard(origin_bdev))
34188c2ecf20Sopenharmony_ci		reason = "discard unsupported";
34198c2ecf20Sopenharmony_ci
34208c2ecf20Sopenharmony_ci	else if (origin_limits->max_discard_sectors < cache->sectors_per_block)
34218c2ecf20Sopenharmony_ci		reason = "max discard sectors smaller than a block";
34228c2ecf20Sopenharmony_ci
34238c2ecf20Sopenharmony_ci	if (reason) {
34248c2ecf20Sopenharmony_ci		DMWARN("Origin device (%s) %s: Disabling discard passdown.",
34258c2ecf20Sopenharmony_ci		       bdevname(origin_bdev, buf), reason);
34268c2ecf20Sopenharmony_ci		cache->features.discard_passdown = false;
34278c2ecf20Sopenharmony_ci	}
34288c2ecf20Sopenharmony_ci}
34298c2ecf20Sopenharmony_ci
34308c2ecf20Sopenharmony_cistatic void set_discard_limits(struct cache *cache, struct queue_limits *limits)
34318c2ecf20Sopenharmony_ci{
34328c2ecf20Sopenharmony_ci	struct block_device *origin_bdev = cache->origin_dev->bdev;
34338c2ecf20Sopenharmony_ci	struct queue_limits *origin_limits = &bdev_get_queue(origin_bdev)->limits;
34348c2ecf20Sopenharmony_ci
34358c2ecf20Sopenharmony_ci	if (!cache->features.discard_passdown) {
34368c2ecf20Sopenharmony_ci		/* No passdown is done so setting own virtual limits */
34378c2ecf20Sopenharmony_ci		limits->max_discard_sectors = min_t(sector_t, cache->discard_block_size * 1024,
34388c2ecf20Sopenharmony_ci						    cache->origin_sectors);
34398c2ecf20Sopenharmony_ci		limits->discard_granularity = cache->discard_block_size << SECTOR_SHIFT;
34408c2ecf20Sopenharmony_ci		return;
34418c2ecf20Sopenharmony_ci	}
34428c2ecf20Sopenharmony_ci
34438c2ecf20Sopenharmony_ci	/*
34448c2ecf20Sopenharmony_ci	 * cache_iterate_devices() is stacking both origin and fast device limits
34458c2ecf20Sopenharmony_ci	 * but discards aren't passed to fast device, so inherit origin's limits.
34468c2ecf20Sopenharmony_ci	 */
34478c2ecf20Sopenharmony_ci	limits->max_discard_sectors = origin_limits->max_discard_sectors;
34488c2ecf20Sopenharmony_ci	limits->max_hw_discard_sectors = origin_limits->max_hw_discard_sectors;
34498c2ecf20Sopenharmony_ci	limits->discard_granularity = origin_limits->discard_granularity;
34508c2ecf20Sopenharmony_ci	limits->discard_alignment = origin_limits->discard_alignment;
34518c2ecf20Sopenharmony_ci	limits->discard_misaligned = origin_limits->discard_misaligned;
34528c2ecf20Sopenharmony_ci}
34538c2ecf20Sopenharmony_ci
34548c2ecf20Sopenharmony_cistatic void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
34558c2ecf20Sopenharmony_ci{
34568c2ecf20Sopenharmony_ci	struct cache *cache = ti->private;
34578c2ecf20Sopenharmony_ci	uint64_t io_opt_sectors = limits->io_opt >> SECTOR_SHIFT;
34588c2ecf20Sopenharmony_ci
34598c2ecf20Sopenharmony_ci	/*
34608c2ecf20Sopenharmony_ci	 * If the system-determined stacked limits are compatible with the
34618c2ecf20Sopenharmony_ci	 * cache's blocksize (io_opt is a factor) do not override them.
34628c2ecf20Sopenharmony_ci	 */
34638c2ecf20Sopenharmony_ci	if (io_opt_sectors < cache->sectors_per_block ||
34648c2ecf20Sopenharmony_ci	    do_div(io_opt_sectors, cache->sectors_per_block)) {
34658c2ecf20Sopenharmony_ci		blk_limits_io_min(limits, cache->sectors_per_block << SECTOR_SHIFT);
34668c2ecf20Sopenharmony_ci		blk_limits_io_opt(limits, cache->sectors_per_block << SECTOR_SHIFT);
34678c2ecf20Sopenharmony_ci	}
34688c2ecf20Sopenharmony_ci
34698c2ecf20Sopenharmony_ci	disable_passdown_if_not_supported(cache);
34708c2ecf20Sopenharmony_ci	set_discard_limits(cache, limits);
34718c2ecf20Sopenharmony_ci}
34728c2ecf20Sopenharmony_ci
34738c2ecf20Sopenharmony_ci/*----------------------------------------------------------------*/
34748c2ecf20Sopenharmony_ci
34758c2ecf20Sopenharmony_cistatic struct target_type cache_target = {
34768c2ecf20Sopenharmony_ci	.name = "cache",
34778c2ecf20Sopenharmony_ci	.version = {2, 2, 0},
34788c2ecf20Sopenharmony_ci	.module = THIS_MODULE,
34798c2ecf20Sopenharmony_ci	.ctr = cache_ctr,
34808c2ecf20Sopenharmony_ci	.dtr = cache_dtr,
34818c2ecf20Sopenharmony_ci	.map = cache_map,
34828c2ecf20Sopenharmony_ci	.end_io = cache_end_io,
34838c2ecf20Sopenharmony_ci	.postsuspend = cache_postsuspend,
34848c2ecf20Sopenharmony_ci	.preresume = cache_preresume,
34858c2ecf20Sopenharmony_ci	.resume = cache_resume,
34868c2ecf20Sopenharmony_ci	.status = cache_status,
34878c2ecf20Sopenharmony_ci	.message = cache_message,
34888c2ecf20Sopenharmony_ci	.iterate_devices = cache_iterate_devices,
34898c2ecf20Sopenharmony_ci	.io_hints = cache_io_hints,
34908c2ecf20Sopenharmony_ci};
34918c2ecf20Sopenharmony_ci
34928c2ecf20Sopenharmony_cistatic int __init dm_cache_init(void)
34938c2ecf20Sopenharmony_ci{
34948c2ecf20Sopenharmony_ci	int r;
34958c2ecf20Sopenharmony_ci
34968c2ecf20Sopenharmony_ci	migration_cache = KMEM_CACHE(dm_cache_migration, 0);
34978c2ecf20Sopenharmony_ci	if (!migration_cache)
34988c2ecf20Sopenharmony_ci		return -ENOMEM;
34998c2ecf20Sopenharmony_ci
35008c2ecf20Sopenharmony_ci	r = dm_register_target(&cache_target);
35018c2ecf20Sopenharmony_ci	if (r) {
35028c2ecf20Sopenharmony_ci		DMERR("cache target registration failed: %d", r);
35038c2ecf20Sopenharmony_ci		kmem_cache_destroy(migration_cache);
35048c2ecf20Sopenharmony_ci		return r;
35058c2ecf20Sopenharmony_ci	}
35068c2ecf20Sopenharmony_ci
35078c2ecf20Sopenharmony_ci	return 0;
35088c2ecf20Sopenharmony_ci}
35098c2ecf20Sopenharmony_ci
35108c2ecf20Sopenharmony_cistatic void __exit dm_cache_exit(void)
35118c2ecf20Sopenharmony_ci{
35128c2ecf20Sopenharmony_ci	dm_unregister_target(&cache_target);
35138c2ecf20Sopenharmony_ci	kmem_cache_destroy(migration_cache);
35148c2ecf20Sopenharmony_ci}
35158c2ecf20Sopenharmony_ci
35168c2ecf20Sopenharmony_cimodule_init(dm_cache_init);
35178c2ecf20Sopenharmony_cimodule_exit(dm_cache_exit);
35188c2ecf20Sopenharmony_ci
35198c2ecf20Sopenharmony_ciMODULE_DESCRIPTION(DM_NAME " cache target");
35208c2ecf20Sopenharmony_ciMODULE_AUTHOR("Joe Thornber <ejt@redhat.com>");
35218c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
3522