diff options
Diffstat (limited to 'drivers/md/dm-cache-target.c')
-rw-r--r-- | drivers/md/dm-cache-target.c | 38 |
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 { | |||
179 | struct cache_features { | 179 | struct 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 | ||
184 | struct cache_stats { | 185 | struct 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 | ||
2546 | static int parse_features(struct cache_args *ca, struct dm_arg_set *as, | 2548 | static 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 | ||
3173 | static int write_dirty_bitset(struct cache *cache) | 3179 | static 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 | ||
3192 | static int write_discard_bitset(struct cache *cache) | 3193 | static 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 | ||
3818 | static struct target_type cache_target = { | 3824 | static 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, |