Skip to content

Commit b0e5c29

Browse files
committed
Merge tag 'for-4.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - A couple stable fixes for the DM writecache target. - A stable fix for the DM cache target that fixes the potential for data corruption after an unclean shutdown of a cache device using writeback mode. - Update DM integrity target to allow the metadata to be stored on a separate device from data. - Fix DM kcopyd and the snapshot target to cond_resched() where appropriate and be more efficient with processing completed work. - A few fixes and improvements for DM crypt. - Add DM delay target feature to configure delay of flushes independent of writes. - Update DM thin-provisioning target to include metadata_low_watermark threshold in pool status. - Fix stale DM thin-provisioning Documentation. * tag 'for-4.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (26 commits) dm writecache: fix a crash due to reading past end of dirty_bitmap dm crypt: don't decrease device limits dm cache metadata: set dirty on all cache blocks after a crash dm snapshot: remove stale FIXME in snapshot_map() dm snapshot: improve performance by switching out_of_order_list to rbtree dm kcopyd: avoid softlockup in run_complete_job dm cache metadata: save in-core policy_hint_size to on-disk superblock dm thin: stop no_space_timeout worker when switching to write-mode dm kcopyd: return void from dm_kcopyd_copy() dm thin: include metadata_low_watermark threshold in pool status dm writecache: report start_sector in status line dm crypt: convert essiv from ahash to shash dm crypt: use wake_up_process() instead of a wait queue dm integrity: recalculate checksums on creation dm integrity: flush journal on suspend when using separate metadata device dm integrity: use version 2 for separate metadata dm integrity: allow separate metadata device dm integrity: add ic->start in get_data_sector() dm integrity: report provided data sectors in the status dm integrity: implement fair range locks ...
2 parents 2645b9d + 1e1132e commit b0e5c29

File tree

15 files changed

+690
-334
lines changed

15 files changed

+690
-334
lines changed

Documentation/device-mapper/delay.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ Device-Mapper's "delay" target delays reads and/or writes
55
and maps them to different devices.
66

77
Parameters:
8-
<device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
8+
<device> <offset> <delay> [<write_device> <write_offset> <write_delay>
9+
[<flush_device> <flush_offset> <flush_delay>]]
910

1011
With separate write parameters, the first set is only used for reads.
1112
Offsets are specified in sectors.

Documentation/device-mapper/dm-integrity.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ internal_hash:algorithm(:key) (the key is optional)
113113
from an upper layer target, such as dm-crypt. The upper layer
114114
target should check the validity of the integrity tags.
115115

116+
recalculate
117+
Recalculate the integrity tags automatically. It is only valid
118+
when using internal hash.
119+
116120
journal_crypt:algorithm(:key) (the key is optional)
117121
Encrypt the journal using given algorithm to make sure that the
118122
attacker can't read the journal. You can use a block cipher here

Documentation/device-mapper/thin-provisioning.txt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,18 @@ administrator some freedom, for example to:
2828
Status
2929
======
3030

31-
These targets are very much still in the EXPERIMENTAL state. Please
32-
do not yet rely on them in production. But do experiment and offer us
33-
feedback. Different use cases will have different performance
34-
characteristics, for example due to fragmentation of the data volume.
31+
These targets are considered safe for production use. But different use
32+
cases will have different performance characteristics, for example due
33+
to fragmentation of the data volume.
3534

3635
If you find this software is not performing as expected please mail
3736
dm-devel@redhat.com with details and we'll try our best to improve
3837
things for you.
3938

40-
Userspace tools for checking and repairing the metadata are under
41-
development.
39+
Userspace tools for checking and repairing the metadata have been fully
40+
developed and are available as 'thin_check' and 'thin_repair'. The name
41+
of the package that provides these utilities varies by distribution (on
42+
a Red Hat distribution it is named 'device-mapper-persistent-data').
4243

4344
Cookbook
4445
========
@@ -280,7 +281,7 @@ ii) Status
280281
<transaction id> <used metadata blocks>/<total metadata blocks>
281282
<used data blocks>/<total data blocks> <held metadata root>
282283
ro|rw|out_of_data_space [no_]discard_passdown [error|queue]_if_no_space
283-
needs_check|-
284+
needs_check|- metadata_low_watermark
284285

285286
transaction id:
286287
A 64-bit number used by userspace to help synchronise with metadata
@@ -327,6 +328,11 @@ ii) Status
327328
thin-pool can be made fully operational again. '-' indicates
328329
needs_check is not set.
329330

331+
metadata_low_watermark:
332+
Value of metadata low watermark in blocks. The kernel sets this
333+
value internally but userspace needs to know this value to
334+
determine if an event was caused by crossing this threshold.
335+
330336
iii) Messages
331337

332338
create_thin <dev id>

drivers/md/dm-cache-metadata.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
363363
disk_super->version = cpu_to_le32(cmd->version);
364364
memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
365365
memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
366-
disk_super->policy_hint_size = 0;
366+
disk_super->policy_hint_size = cpu_to_le32(0);
367367

368368
__copy_sm_root(cmd, disk_super);
369369

@@ -701,6 +701,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
701701
disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
702702
disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
703703
disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
704+
disk_super->policy_hint_size = cpu_to_le32(cmd->policy_hint_size);
704705

705706
disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
706707
disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
@@ -1322,6 +1323,7 @@ static int __load_mapping_v1(struct dm_cache_metadata *cmd,
13221323

13231324
dm_oblock_t oblock;
13241325
unsigned flags;
1326+
bool dirty = true;
13251327

13261328
dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
13271329
memcpy(&mapping, mapping_value_le, sizeof(mapping));
@@ -1332,8 +1334,10 @@ static int __load_mapping_v1(struct dm_cache_metadata *cmd,
13321334
dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
13331335
memcpy(&hint, hint_value_le, sizeof(hint));
13341336
}
1337+
if (cmd->clean_when_opened)
1338+
dirty = flags & M_DIRTY;
13351339

1336-
r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY,
1340+
r = fn(context, oblock, to_cblock(cb), dirty,
13371341
le32_to_cpu(hint), hints_valid);
13381342
if (r) {
13391343
DMERR("policy couldn't load cache block %llu",
@@ -1361,7 +1365,7 @@ static int __load_mapping_v2(struct dm_cache_metadata *cmd,
13611365

13621366
dm_oblock_t oblock;
13631367
unsigned flags;
1364-
bool dirty;
1368+
bool dirty = true;
13651369

13661370
dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
13671371
memcpy(&mapping, mapping_value_le, sizeof(mapping));
@@ -1372,8 +1376,9 @@ static int __load_mapping_v2(struct dm_cache_metadata *cmd,
13721376
dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
13731377
memcpy(&hint, hint_value_le, sizeof(hint));
13741378
}
1379+
if (cmd->clean_when_opened)
1380+
dirty = dm_bitset_cursor_get_value(dirty_cursor);
13751381

1376-
dirty = dm_bitset_cursor_get_value(dirty_cursor);
13771382
r = fn(context, oblock, to_cblock(cb), dirty,
13781383
le32_to_cpu(hint), hints_valid);
13791384
if (r) {

drivers/md/dm-cache-target.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,9 +1188,8 @@ static void copy_complete(int read_err, unsigned long write_err, void *context)
11881188
queue_continuation(mg->cache->wq, &mg->k);
11891189
}
11901190

1191-
static int copy(struct dm_cache_migration *mg, bool promote)
1191+
static void copy(struct dm_cache_migration *mg, bool promote)
11921192
{
1193-
int r;
11941193
struct dm_io_region o_region, c_region;
11951194
struct cache *cache = mg->cache;
11961195

@@ -1203,11 +1202,9 @@ static int copy(struct dm_cache_migration *mg, bool promote)
12031202
c_region.count = cache->sectors_per_block;
12041203

12051204
if (promote)
1206-
r = dm_kcopyd_copy(cache->copier, &o_region, 1, &c_region, 0, copy_complete, &mg->k);
1205+
dm_kcopyd_copy(cache->copier, &o_region, 1, &c_region, 0, copy_complete, &mg->k);
12071206
else
1208-
r = dm_kcopyd_copy(cache->copier, &c_region, 1, &o_region, 0, copy_complete, &mg->k);
1209-
1210-
return r;
1207+
dm_kcopyd_copy(cache->copier, &c_region, 1, &o_region, 0, copy_complete, &mg->k);
12111208
}
12121209

12131210
static void bio_drop_shared_lock(struct cache *cache, struct bio *bio)
@@ -1449,12 +1446,7 @@ static void mg_full_copy(struct work_struct *ws)
14491446
}
14501447

14511448
init_continuation(&mg->k, mg_upgrade_lock);
1452-
1453-
if (copy(mg, is_policy_promote)) {
1454-
DMERR_LIMIT("%s: migration copy failed", cache_device_name(cache));
1455-
mg->k.input = BLK_STS_IOERR;
1456-
mg_complete(mg, false);
1457-
}
1449+
copy(mg, is_policy_promote);
14581450
}
14591451

14601452
static void mg_copy(struct work_struct *ws)
@@ -2250,7 +2242,7 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
22502242
{0, 2, "Invalid number of cache feature arguments"},
22512243
};
22522244

2253-
int r;
2245+
int r, mode_ctr = 0;
22542246
unsigned argc;
22552247
const char *arg;
22562248
struct cache_features *cf = &ca->features;
@@ -2264,14 +2256,20 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
22642256
while (argc--) {
22652257
arg = dm_shift_arg(as);
22662258

2267-
if (!strcasecmp(arg, "writeback"))
2259+
if (!strcasecmp(arg, "writeback")) {
22682260
cf->io_mode = CM_IO_WRITEBACK;
2261+
mode_ctr++;
2262+
}
22692263

2270-
else if (!strcasecmp(arg, "writethrough"))
2264+
else if (!strcasecmp(arg, "writethrough")) {
22712265
cf->io_mode = CM_IO_WRITETHROUGH;
2266+
mode_ctr++;
2267+
}
22722268

2273-
else if (!strcasecmp(arg, "passthrough"))
2269+
else if (!strcasecmp(arg, "passthrough")) {
22742270
cf->io_mode = CM_IO_PASSTHROUGH;
2271+
mode_ctr++;
2272+
}
22752273

22762274
else if (!strcasecmp(arg, "metadata2"))
22772275
cf->metadata_version = 2;
@@ -2282,6 +2280,11 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
22822280
}
22832281
}
22842282

2283+
if (mode_ctr > 1) {
2284+
*error = "Duplicate cache io_mode features requested";
2285+
return -EINVAL;
2286+
}
2287+
22852288
return 0;
22862289
}
22872290

0 commit comments

Comments
 (0)