diff options
| author | Joe Thornber <ejt@redhat.com> | 2013-03-01 17:45:51 -0500 |
|---|---|---|
| committer | Alasdair G Kergon <agk@redhat.com> | 2013-03-01 17:45:51 -0500 |
| commit | c6b4fcbad044e6fffcc75bba160e720eb8d67d17 (patch) | |
| tree | 1fb20e6ca157ebfbf2c97ae022fc6ba3e0550dd6 /drivers/md | |
| parent | 7a87edfee75151abb69d47dba2277ff2de0f6071 (diff) | |
dm: add cache target
Add a target that allows a fast device such as an SSD to be used as a
cache for a slower device such as a disk.
A plug-in architecture was chosen so that the decisions about which data
to migrate and when are delegated to interchangeable tunable policy
modules. The first general purpose module we have developed, called
"mq" (multiqueue), follows in the next patch. Other modules are
under development.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Heinz Mauelshagen <mauelshagen@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/md/Makefile | 2 | ||||
| -rw-r--r-- | drivers/md/dm-bio-prison.c | 9 | ||||
| -rw-r--r-- | drivers/md/dm-bio-prison.h | 11 | ||||
| -rw-r--r-- | drivers/md/dm-cache-block-types.h | 54 | ||||
| -rw-r--r-- | drivers/md/dm-cache-metadata.c | 1146 | ||||
| -rw-r--r-- | drivers/md/dm-cache-metadata.h | 142 | ||||
| -rw-r--r-- | drivers/md/dm-cache-policy-internal.h | 124 | ||||
| -rw-r--r-- | drivers/md/dm-cache-policy.c | 161 | ||||
| -rw-r--r-- | drivers/md/dm-cache-policy.h | 228 | ||||
| -rw-r--r-- | drivers/md/dm-cache-target.c | 2584 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-block-manager.c | 1 |
12 files changed, 4475 insertions, 0 deletions
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 7cdf359d6b23..1a4fbcdb5ca2 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
| @@ -268,6 +268,19 @@ config DM_DEBUG_BLOCK_STACK_TRACING | |||
| 268 | 268 | ||
| 269 | If unsure, say N. | 269 | If unsure, say N. |
| 270 | 270 | ||
| 271 | config DM_CACHE | ||
| 272 | tristate "Cache target (EXPERIMENTAL)" | ||
| 273 | depends on BLK_DEV_DM | ||
| 274 | default n | ||
| 275 | select DM_PERSISTENT_DATA | ||
| 276 | select DM_BIO_PRISON | ||
| 277 | ---help--- | ||
| 278 | dm-cache attempts to improve performance of a block device by | ||
| 279 | moving frequently used data to a smaller, higher performance | ||
| 280 | device. Different 'policy' plugins can be used to change the | ||
| 281 | algorithms used to select which blocks are promoted, demoted, | ||
| 282 | cleaned etc. It supports writeback and writethrough modes. | ||
| 283 | |||
| 271 | config DM_MIRROR | 284 | config DM_MIRROR |
| 272 | tristate "Mirror target" | 285 | tristate "Mirror target" |
| 273 | depends on BLK_DEV_DM | 286 | depends on BLK_DEV_DM |
diff --git a/drivers/md/Makefile b/drivers/md/Makefile index 94dce8b49324..24b52560f4d2 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile | |||
| @@ -11,6 +11,7 @@ dm-mirror-y += dm-raid1.o | |||
| 11 | dm-log-userspace-y \ | 11 | dm-log-userspace-y \ |
| 12 | += dm-log-userspace-base.o dm-log-userspace-transfer.o | 12 | += dm-log-userspace-base.o dm-log-userspace-transfer.o |
| 13 | dm-thin-pool-y += dm-thin.o dm-thin-metadata.o | 13 | dm-thin-pool-y += dm-thin.o dm-thin-metadata.o |
| 14 | dm-cache-y += dm-cache-target.o dm-cache-metadata.o dm-cache-policy.o | ||
| 14 | md-mod-y += md.o bitmap.o | 15 | md-mod-y += md.o bitmap.o |
| 15 | raid456-y += raid5.o | 16 | raid456-y += raid5.o |
| 16 | 17 | ||
| @@ -44,6 +45,7 @@ obj-$(CONFIG_DM_ZERO) += dm-zero.o | |||
| 44 | obj-$(CONFIG_DM_RAID) += dm-raid.o | 45 | obj-$(CONFIG_DM_RAID) += dm-raid.o |
| 45 | obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o | 46 | obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o |
| 46 | obj-$(CONFIG_DM_VERITY) += dm-verity.o | 47 | obj-$(CONFIG_DM_VERITY) += dm-verity.o |
| 48 | obj-$(CONFIG_DM_CACHE) += dm-cache.o | ||
| 47 | 49 | ||
| 48 | ifeq ($(CONFIG_DM_UEVENT),y) | 50 | ifeq ($(CONFIG_DM_UEVENT),y) |
| 49 | dm-mod-objs += dm-uevent.o | 51 | dm-mod-objs += dm-uevent.o |
diff --git a/drivers/md/dm-bio-prison.c b/drivers/md/dm-bio-prison.c index 144067c95aba..85f0b7074257 100644 --- a/drivers/md/dm-bio-prison.c +++ b/drivers/md/dm-bio-prison.c | |||
| @@ -179,6 +179,15 @@ int dm_bio_detain(struct dm_bio_prison *prison, | |||
| 179 | } | 179 | } |
| 180 | EXPORT_SYMBOL_GPL(dm_bio_detain); | 180 | EXPORT_SYMBOL_GPL(dm_bio_detain); |
| 181 | 181 | ||
| 182 | int dm_get_cell(struct dm_bio_prison *prison, | ||
| 183 | struct dm_cell_key *key, | ||
| 184 | struct dm_bio_prison_cell *cell_prealloc, | ||
| 185 | struct dm_bio_prison_cell **cell_result) | ||
| 186 | { | ||
| 187 | return bio_detain(prison, key, NULL, cell_prealloc, cell_result); | ||
| 188 | } | ||
| 189 | EXPORT_SYMBOL_GPL(dm_get_cell); | ||
| 190 | |||
| 182 | /* | 191 | /* |
| 183 | * @inmates must have been initialised prior to this call | 192 | * @inmates must have been initialised prior to this call |
| 184 | */ | 193 | */ |
diff --git a/drivers/md/dm-bio-prison.h b/drivers/md/dm-bio-prison.h index 981a02d3a055..3f833190eadf 100644 --- a/drivers/md/dm-bio-prison.h +++ b/drivers/md/dm-bio-prison.h | |||
| @@ -57,6 +57,17 @@ void dm_bio_prison_free_cell(struct dm_bio_prison *prison, | |||
| 57 | struct dm_bio_prison_cell *cell); | 57 | struct dm_bio_prison_cell *cell); |
| 58 | 58 | ||
| 59 | /* | 59 | /* |
| 60 | * Creates, or retrieves a cell for the given key. | ||
| 61 | * | ||
| 62 | * Returns 1 if pre-existing cell returned, zero if new cell created using | ||
| 63 | * @cell_prealloc. | ||
| 64 | */ | ||
| 65 | int dm_get_cell(struct dm_bio_prison *prison, | ||
| 66 | struct dm_cell_key *key, | ||
| 67 | struct dm_bio_prison_cell *cell_prealloc, | ||
| 68 | struct dm_bio_prison_cell **cell_result); | ||
| 69 | |||
| 70 | /* | ||
| 60 | * An atomic op that combines retrieving a cell, and adding a bio to it. | 71 | * An atomic op that combines retrieving a cell, and adding a bio to it. |
| 61 | * | 72 | * |
| 62 | * Returns 1 if the cell was already held, 0 if @inmate is the new holder. | 73 | * Returns 1 if the cell was already held, 0 if @inmate is the new holder. |
diff --git a/drivers/md/dm-cache-block-types.h b/drivers/md/dm-cache-block-types.h new file mode 100644 index 000000000000..bed4ad4e1b7c --- /dev/null +++ b/drivers/md/dm-cache-block-types.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Red Hat, Inc. | ||
| 3 | * | ||
| 4 | * This file is released under the GPL. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef DM_CACHE_BLOCK_TYPES_H | ||
| 8 | #define DM_CACHE_BLOCK_TYPES_H | ||
| 9 | |||
| 10 | #include "persistent-data/dm-block-manager.h" | ||
| 11 | |||
| 12 | /*----------------------------------------------------------------*/ | ||
| 13 | |||
| 14 | /* | ||
| 15 | * It's helpful to get sparse to differentiate between indexes into the | ||
| 16 | * origin device, indexes into the cache device, and indexes into the | ||
| 17 | * discard bitset. | ||
| 18 | */ | ||
| 19 | |||
| 20 | typedef dm_block_t __bitwise__ dm_oblock_t; | ||
| 21 | typedef uint32_t __bitwise__ dm_cblock_t; | ||
| 22 | typedef dm_block_t __bitwise__ dm_dblock_t; | ||
| 23 | |||
| 24 | static inline dm_oblock_t to_oblock(dm_block_t b) | ||
| 25 | { | ||
| 26 | return (__force dm_oblock_t) b; | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline dm_block_t from_oblock(dm_oblock_t b) | ||
| 30 | { | ||
| 31 | return (__force dm_block_t) b; | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline dm_cblock_t to_cblock(uint32_t b) | ||
| 35 | { | ||
| 36 | return (__force dm_cblock_t) b; | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline uint32_t from_cblock(dm_cblock_t b) | ||
| 40 | { | ||
| 41 | return (__force uint32_t) b; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline dm_dblock_t to_dblock(dm_block_t b) | ||
| 45 | { | ||
| 46 | return (__force dm_dblock_t) b; | ||
| 47 | } | ||
| 48 | |||
| 49 | static inline dm_block_t from_dblock(dm_dblock_t b) | ||
| 50 | { | ||
| 51 | return (__force dm_block_t) b; | ||
| 52 | } | ||
| 53 | |||
| 54 | #endif /* DM_CACHE_BLOCK_TYPES_H */ | ||
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c new file mode 100644 index 000000000000..fbd3625f2748 --- /dev/null +++ b/drivers/md/dm-cache-metadata.c | |||
| @@ -0,0 +1,1146 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Red Hat, Inc. | ||
| 3 | * | ||
| 4 | * This file is released under the GPL. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include "dm-cache-metadata.h" | ||
| 8 | |||
| 9 | #include "persistent-data/dm-array.h" | ||
| 10 | #include "persistent-data/dm-bitset.h" | ||
| 11 | #include "persistent-data/dm-space-map.h" | ||
| 12 | #include "persistent-data/dm-space-map-disk.h" | ||
| 13 | #include "persistent-data/dm-transaction-manager.h" | ||
| 14 | |||
| 15 | #include <linux/device-mapper.h> | ||
| 16 | |||
| 17 | /*----------------------------------------------------------------*/ | ||
| 18 | |||
| 19 | #define DM_MSG_PREFIX "cache metadata" | ||
| 20 | |||
| 21 | #define CACHE_SUPERBLOCK_MAGIC 06142003 | ||
| 22 | #define CACHE_SUPERBLOCK_LOCATION 0 | ||
| 23 | #define CACHE_VERSION 1 | ||
| 24 | #define CACHE_METADATA_CACHE_SIZE 64 | ||
| 25 | |||
| 26 | /* | ||
| 27 | * 3 for btree insert + | ||
| 28 | * 2 for btree lookup used within space map | ||
| 29 | */ | ||
| 30 | #define CACHE_MAX_CONCURRENT_LOCKS 5 | ||
