summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-cache-target.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-cache-target.c')
-rw-r--r--drivers/md/dm-cache-target.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 897dc72f07c9..5813d2a7eefe 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -179,6 +179,7 @@ enum cache_io_mode {
179struct cache_features { 179struct cache_features {
180 enum cache_metadata_mode mode; 180 enum cache_metadata_mode mode;
181 enum cache_io_mode io_mode; 181 enum cache_io_mode io_mode;
182 unsigned metadata_version;
182}; 183};
183 184
184struct cache_stats { 185struct cache_stats {
@@ -2541,13 +2542,14 @@ static void init_features(struct cache_features *cf)
2541{ 2542{
2542 cf->mode = CM_WRITE; 2543 cf->mode = CM_WRITE;
2543 cf->io_mode = CM_IO_WRITEBACK; 2544 cf->io_mode = CM_IO_WRITEBACK;
2545 cf->metadata_version = 1;
2544} 2546}
2545 2547
2546static int parse_features(struct cache_args *ca, struct dm_arg_set *as, 2548static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
2547 char **error) 2549 char **error)
2548{ 2550{
2549 static struct dm_arg _args[] = { 2551 static struct dm_arg _args[] = {
2550 {0, 1, "Invalid number of cache feature arguments"}, 2552 {0, 2, "Invalid number of cache feature arguments"},
2551 }; 2553 };
2552 2554
2553 int r; 2555 int r;
@@ -2573,6 +2575,9 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
2573 else if (!strcasecmp(arg, "passthrough")) 2575 else if (!strcasecmp(arg, "passthrough"))
2574 cf->io_mode = CM_IO_PASSTHROUGH; 2576 cf->io_mode = CM_IO_PASSTHROUGH;
2575 2577
2578 else if (!strcasecmp(arg, "metadata2"))
2579 cf->metadata_version = 2;
2580
2576 else { 2581 else {
2577 *error = "Unrecognised cache feature requested"; 2582 *error = "Unrecognised cache feature requested";
2578 return -EINVAL; 2583 return -EINVAL;
@@ -2827,7 +2832,8 @@ static int cache_create(struct cache_args *ca, struct cache **result)
2827 2832
2828 cmd = dm_cache_metadata_open(cache->metadata_dev->bdev, 2833 cmd = dm_cache_metadata_open(cache->metadata_dev->bdev,
2829 ca->block_size, may_format, 2834 ca->block_size, may_format,
2830 dm_cache_policy_get_hint_size(cache->policy)); 2835 dm_cache_policy_get_hint_size(cache->policy),
2836 ca->features.metadata_version);
2831 if (IS_ERR(cmd)) { 2837 if (IS_ERR(cmd)) {
2832 *error = "Error creating metadata object"; 2838 *error = "Error creating metadata object";
2833 r = PTR_ERR(cmd); 2839 r = PTR_ERR(cmd);
@@ -3172,21 +3178,16 @@ static int cache_end_io(struct dm_target *ti, struct bio *bio, int error)
3172 3178
3173static int write_dirty_bitset(struct cache *cache) 3179static int write_dirty_bitset(struct cache *cache)
3174{ 3180{
3175 unsigned i, r; 3181 int r;
3176 3182
3177 if (get_cache_mode(cache) >= CM_READ_ONLY) 3183 if (get_cache_mode(cache) >= CM_READ_ONLY)
3178 return -EINVAL; 3184 return -EINVAL;
3179 3185
3180 for (i = 0; i < from_cblock(cache->cache_size); i++) { 3186 r = dm_cache_set_dirty_bits(cache->cmd, from_cblock(cache->cache_size), cache->dirty_bitset);
3181 r = dm_cache_set_dirty(cache->cmd, to_cblock(i), 3187 if (r)
3182 is_dirty(cache, to_cblock(i))); 3188 metadata_operation_failed(cache, "dm_cache_set_dirty_bits", r);
3183 if (r) {
3184 metadata_operation_failed(cache, "dm_cache_set_dirty", r);
3185 return r;
3186 }
3187 }
3188 3189
3189 return 0; 3190 return r;
3190} 3191}
3191 3192
3192static int write_discard_bitset(struct cache *cache) 3193static int write_discard_bitset(struct cache *cache)
@@ -3562,14 +3563,19 @@ static void cache_status(struct dm_target *ti, status_type_t type,
3562 (unsigned) atomic_read(&cache->stats.promotion), 3563 (unsigned) atomic_read(&cache->stats.promotion),
3563 (unsigned long) atomic_read(&cache->nr_dirty)); 3564 (unsigned long) atomic_read(&cache->nr_dirty));
3564 3565
3566 if (cache->features.metadata_version == 2)
3567 DMEMIT("2 metadata2 ");
3568 else
3569 DMEMIT("1 ");
3570
3565 if (writethrough_mode(&cache->features)) 3571 if (writethrough_mode(&cache->features))
3566 DMEMIT("1 writethrough "); 3572 DMEMIT("writethrough ");
3567 3573
3568 else if (passthrough_mode(&cache->features)) 3574 else if (passthrough_mode(&cache->features))
3569 DMEMIT("1 passthrough "); 3575 DMEMIT("passthrough ");
3570 3576
3571 else if (writeback_mode(&cache->features)) 3577 else if (writeback_mode(&cache->features))
3572 DMEMIT("1 writeback "); 3578 DMEMIT("writeback ");
3573 3579
3574 else { 3580 else {
3575 DMERR("%s: internal error: unknown io mode: %d", 3581 DMERR("%s: internal error: unknown io mode: %d",
@@ -3817,7 +3823,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
3817 3823
3818static struct target_type cache_target = { 3824static struct target_type cache_target = {
3819 .name = "cache", 3825 .name = "cache",
3820 .version = {1, 9, 0}, 3826 .version = {1, 10, 0},
3821 .module = THIS_MODULE, 3827 .module = THIS_MODULE,
3822 .ctr = cache_ctr, 3828 .ctr = cache_ctr,
3823 .dtr = cache_dtr, 3829 .dtr = cache_dtr,