Skip to content

Commit 2eecf3a

Browse files
committed
Merge tag 'for-4.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - DM cache metadata fixes to short-circuit operations that require the metadata not be in 'fail_io' mode. Otherwise crashes are possible. - a DM cache fix to address the inability to adapt to continuous IO that happened to also reflect a changing working set (which required old blocks be demoted before the new working set could be promoted) - a DM cache smq policy cleanup that fell out from reviewing the above - fix the Kconfig help text for CONFIG_DM_INTEGRITY * tag 'for-4.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm cache metadata: fail operations if fail_io mode has been established dm integrity: improve the Kconfig help text for DM_INTEGRITY dm cache policy smq: cleanup free_target_met() and clean_target_met() dm cache policy smq: allow demotions to happen even during continuous IO
2 parents 53ef7d0 + 10add84 commit 2eecf3a

File tree

3 files changed

+39
-18
lines changed

3 files changed

+39
-18
lines changed

drivers/md/Kconfig

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,13 +503,24 @@ config DM_LOG_WRITES
503503
If unsure, say N.
504504

505505
config DM_INTEGRITY
506-
tristate "Integrity target"
506+
tristate "Integrity target support"
507507
depends on BLK_DEV_DM
508508
select BLK_DEV_INTEGRITY
509509
select DM_BUFIO
510510
select CRYPTO
511511
select ASYNC_XOR
512512
---help---
513-
This is the integrity target.
513+
This device-mapper target emulates a block device that has
514+
additional per-sector tags that can be used for storing
515+
integrity information.
516+
517+
This integrity target is used with the dm-crypt target to
518+
provide authenticated disk encryption or it can be used
519+
standalone.
520+
521+
To compile this code as a module, choose M here: the module will
522+
be called dm-integrity.
523+
524+
If unsure, say N.
514525

515526
endif # MD

drivers/md/dm-cache-metadata.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,17 +1624,19 @@ void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
16241624

16251625
int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
16261626
{
1627-
int r;
1627+
int r = -EINVAL;
16281628
flags_mutator mutator = (clean_shutdown ? set_clean_shutdown :
16291629
clear_clean_shutdown);
16301630

16311631
WRITE_LOCK(cmd);
1632+
if (cmd->fail_io)
1633+
goto out;
1634+
16321635
r = __commit_transaction(cmd, mutator);
16331636
if (r)
16341637
goto out;
16351638

16361639
r = __begin_transaction(cmd);
1637-
16381640
out:
16391641
WRITE_UNLOCK(cmd);
16401642
return r;
@@ -1646,7 +1648,8 @@ int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
16461648
int r = -EINVAL;
16471649

16481650
READ_LOCK(cmd);
1649-
r = dm_sm_get_nr_free(cmd->metadata_sm, result);
1651+
if (!cmd->fail_io)
1652+
r = dm_sm_get_nr_free(cmd->metadata_sm, result);
16501653
READ_UNLOCK(cmd);
16511654

16521655
return r;
@@ -1658,7 +1661,8 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
16581661
int r = -EINVAL;
16591662

16601663
READ_LOCK(cmd);
1661-
r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
1664+
if (!cmd->fail_io)
1665+
r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
16621666
READ_UNLOCK(cmd);
16631667

16641668
return r;

drivers/md/dm-cache-policy-smq.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,28 +1120,30 @@ static bool clean_target_met(struct smq_policy *mq, bool idle)
11201120
* Cache entries may not be populated. So we cannot rely on the
11211121
* size of the clean queue.
11221122
*/
1123-
unsigned nr_clean = from_cblock(mq->cache_size) - q_size(&mq->dirty);
1123+
unsigned nr_clean;
11241124

1125-
if (idle)
1125+
if (idle) {
11261126
/*
11271127
* We'd like to clean everything.
11281128
*/
11291129
return q_size(&mq->dirty) == 0u;
1130-
else
1131-
return (nr_clean + btracker_nr_writebacks_queued(mq->bg_work)) >=
1132-
percent_to_target(mq, CLEAN_TARGET);
1130+
}
1131+
1132+
nr_clean = from_cblock(mq->cache_size) - q_size(&mq->dirty);
1133+
return (nr_clean + btracker_nr_writebacks_queued(mq->bg_work)) >=
1134+
percent_to_target(mq, CLEAN_TARGET);
11331135
}
11341136

11351137
static bool free_target_met(struct smq_policy *mq, bool idle)
11361138
{
1137-
unsigned nr_free = from_cblock(mq->cache_size) -
1138-
mq->cache_alloc.nr_allocated;
1139+
unsigned nr_free;
11391140

1140-
if (idle)
1141-
return (nr_free + btracker_nr_demotions_queued(mq->bg_work)) >=
1142-
percent_to_target(mq, FREE_TARGET);
1143-
else
1141+
if (!idle)
11441142
return true;
1143+
1144+
nr_free = from_cblock(mq->cache_size) - mq->cache_alloc.nr_allocated;
1145+
return (nr_free + btracker_nr_demotions_queued(mq->bg_work)) >=
1146+
percent_to_target(mq, FREE_TARGET);
11451147
}
11461148

11471149
/*----------------------------------------------------------------*/
@@ -1214,7 +1216,11 @@ static void queue_promotion(struct smq_policy *mq, dm_oblock_t oblock,
12141216
return;
12151217

12161218
if (allocator_empty(&mq->cache_alloc)) {
1217-
if (!free_target_met(mq, false))
1219+
/*
1220+
* We always claim to be 'idle' to ensure some demotions happen
1221+
* with continuous loads.
1222+
*/
1223+
if (!free_target_met(mq, true))
12181224
queue_demotion(mq);
12191225
return;
12201226
}

0 commit comments

Comments
 (0)