Skip to content

Commit 0364249

Browse files
committed
Merge tag 'for-6.7/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - Update DM core to directly call the map function for both the linear and stripe targets; which are provided by DM core - Various updates to use new safer string functions - Update DM core to respect REQ_NOWAIT flag in normal bios so that memory allocations are always attempted with GFP_NOWAIT - Add Mikulas Patocka to MAINTAINERS as a DM maintainer! - Improve DM delay target's handling of short delays (< 50ms) by using a kthread to check expiration of IOs rather than timers and a wq - Update the DM error target so that it works with zoned storage. This helps xfstests to provide proper IO error handling coverage when testing a filesystem with native zoned storage support - Update both DM crypt and integrity targets to improve performance by using crypto_shash_digest() rather than init+update+final sequence - Fix DM crypt target by backfilling missing memory allocation accounting for compound pages * tag 'for-6.7/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm crypt: account large pages in cc->n_allocated_pages dm integrity: use crypto_shash_digest() in sb_mac() dm crypt: use crypto_shash_digest() in crypt_iv_tcw_whitening() dm error: Add support for zoned block devices dm delay: for short delays, use kthread instead of timers and wq MAINTAINERS: add Mikulas Patocka as a DM maintainer dm: respect REQ_NOWAIT flag in normal bios issued to DM dm: enhance alloc_multiple_bios() to be more versatile dm: make __send_duplicate_bios return unsigned int dm log userspace: replace deprecated strncpy with strscpy dm ioctl: replace deprecated strncpy with strscpy_pad dm crypt: replace open-coded kmemdup_nul dm cache metadata: replace deprecated strncpy with strscpy dm: shortcut the calls to linear_map and stripe_map
2 parents 39714ef + 9793c26 commit 0364249

File tree

13 files changed

+321
-107
lines changed

13 files changed

+321
-107
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6028,6 +6028,7 @@ F: include/linux/devm-helpers.h
60286028
DEVICE-MAPPER (LVM)
60296029
M: Alasdair Kergon <[email protected]>
60306030
M: Mike Snitzer <[email protected]>
6031+
M: Mikulas Patocka <[email protected]>
60316032
60326033
60336034
S: Maintained

drivers/md/dm-cache-metadata.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
597597
cmd->discard_nr_blocks = to_dblock(le64_to_cpu(disk_super->discard_nr_blocks));
598598
cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
599599
cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
600-
strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
600+
strscpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
601601
cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]);
602602
cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]);
603603
cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]);
@@ -707,7 +707,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
707707
disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
708708
disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
709709
disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
710-
strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
710+
strscpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
711711
disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
712712
disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
713713
disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
@@ -1726,7 +1726,7 @@ static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
17261726
(strlen(policy_name) > sizeof(cmd->policy_name) - 1))
17271727
return -EINVAL;
17281728

1729-
strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
1729+
strscpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
17301730
memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version));
17311731

17321732
hint_size = dm_cache_policy_get_hint_size(policy);

drivers/md/dm-crypt.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -652,13 +652,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
652652
/* calculate crc32 for every 32bit part and xor it */
653653
desc->tfm = tcw->crc32_tfm;
654654
for (i = 0; i < 4; i++) {
655-
r = crypto_shash_init(desc);
656-
if (r)
657-
goto out;
658-
r = crypto_shash_update(desc, &buf[i * 4], 4);
659-
if (r)
660-
goto out;
661-
r = crypto_shash_final(desc, &buf[i * 4]);
655+
r = crypto_shash_digest(desc, &buf[i * 4], 4, &buf[i * 4]);
662656
if (r)
663657
goto out;
664658
}
@@ -1699,11 +1693,17 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
16991693
order = min(order, remaining_order);
17001694

17011695
while (order > 0) {
1696+
if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) +
1697+
(1 << order) > dm_crypt_pages_per_client))
1698+
goto decrease_order;
17021699
pages = alloc_pages(gfp_mask
17031700
| __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | __GFP_COMP,
17041701
order);
1705-
if (likely(pages != NULL))
1702+
if (likely(pages != NULL)) {
1703+
percpu_counter_add(&cc->n_allocated_pages, 1 << order);
17061704
goto have_pages;
1705+
}
1706+
decrease_order:
17071707
order--;
17081708
}
17091709

@@ -1741,10 +1741,13 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
17411741

17421742
if (clone->bi_vcnt > 0) { /* bio_for_each_folio_all crashes with an empty bio */
17431743
bio_for_each_folio_all(fi, clone) {
1744-
if (folio_test_large(fi.folio))
1744+
if (folio_test_large(fi.folio)) {
1745+
percpu_counter_sub(&cc->n_allocated_pages,
1746+
1 << folio_order(fi.folio));
17451747
folio_put(fi.folio);
1746-
else
1748+
} else {
17471749
mempool_free(&fi.folio->page, &cc->page_pool);
1750+
}
17481751
}
17491752
}
17501753
}
@@ -2859,10 +2862,9 @@ static int crypt_ctr_auth_cipher(struct crypt_config *cc, char *cipher_api)
28592862
if (!start || !end || ++start > end)
28602863
return -EINVAL;
28612864

2862-
mac_alg = kzalloc(end - start + 1, GFP_KERNEL);
2865+
mac_alg = kmemdup_nul(start, end - start, GFP_KERNEL);
28632866
if (!mac_alg)
28642867
return -ENOMEM;
2865-
strncpy(mac_alg, start, end - start);
28662868

28672869
mac = crypto_alloc_ahash(mac_alg, 0, CRYPTO_ALG_ALLOCATES_MEMORY);
28682870
kfree(mac_alg);

drivers/md/dm-delay.c

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/blkdev.h>
1414
#include <linux/bio.h>
1515
#include <linux/slab.h>
16+
#include <linux/kthread.h>
1617

1718
#include <linux/device-mapper.h>
1819

@@ -31,6 +32,7 @@ struct delay_c {
3132
struct workqueue_struct *kdelayd_wq;
3233
struct work_struct flush_expired_bios;
3334
struct list_head delayed_bios;
35+
struct task_struct *worker;
3436
atomic_t may_delay;
3537

3638
struct delay_class read;
@@ -66,6 +68,44 @@ static void queue_timeout(struct delay_c *dc, unsigned long expires)
6668
mutex_unlock(&dc->timer_lock);
6769
}
6870

71+
static inline bool delay_is_fast(struct delay_c *dc)
72+
{
73+
return !!dc->worker;
74+
}
75+
76+
static void flush_delayed_bios_fast(struct delay_c *dc, bool flush_all)
77+
{
78+
struct dm_delay_info *delayed, *next;
79+
80+
mutex_lock(&delayed_bios_lock);
81+
list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
82+
if (flush_all || time_after_eq(jiffies, delayed->expires)) {
83+
struct bio *bio = dm_bio_from_per_bio_data(delayed,
84+
sizeof(struct dm_delay_info));
85+
list_del(&delayed->list);
86+
dm_submit_bio_remap(bio, NULL);
87+
delayed->class->ops--;
88+
}
89+
}
90+
mutex_unlock(&delayed_bios_lock);
91+
}
92+
93+
static int flush_worker_fn(void *data)
94+
{
95+
struct delay_c *dc = data;
96+
97+
while (1) {
98+
flush_delayed_bios_fast(dc, false);
99+
if (unlikely(list_empty(&dc->delayed_bios))) {
100+
set_current_state(TASK_INTERRUPTIBLE);
101+
schedule();
102+
} else
103+
cond_resched();
104+
}
105+
106+
return 0;
107+
}
108+
69109
static void flush_bios(struct bio *bio)
70110
{
71111
struct bio *n;
@@ -78,7 +118,7 @@ static void flush_bios(struct bio *bio)
78118
}
79119
}
80120

81-
static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
121+
static struct bio *flush_delayed_bios(struct delay_c *dc, bool flush_all)
82122
{
83123
struct dm_delay_info *delayed, *next;
84124
unsigned long next_expires = 0;
@@ -115,7 +155,10 @@ static void flush_expired_bios(struct work_struct *work)
115155
struct delay_c *dc;
116156

117157
dc = container_of(work, struct delay_c, flush_expired_bios);
118-
flush_bios(flush_delayed_bios(dc, 0));
158+
if (delay_is_fast(dc))
159+
flush_delayed_bios_fast(dc, false);
160+
else
161+
flush_bios(flush_delayed_bios(dc, false));
119162
}
120163

121164
static void delay_dtr(struct dm_target *ti)
@@ -131,8 +174,11 @@ static void delay_dtr(struct dm_target *ti)
131174
dm_put_device(ti, dc->write.dev);
132175
if (dc->flush.dev)
133176
dm_put_device(ti, dc->flush.dev);
177+
if (dc->worker)
178+
kthread_stop(dc->worker);
134179

135-
mutex_destroy(&dc->timer_lock);
180+
if (!delay_is_fast(dc))
181+
mutex_destroy(&dc->timer_lock);
136182

137183
kfree(dc);
138184
}
@@ -175,6 +221,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
175221
{
176222
struct delay_c *dc;
177223
int ret;
224+
unsigned int max_delay;
178225

179226
if (argc != 3 && argc != 6 && argc != 9) {
180227
ti->error = "Requires exactly 3, 6 or 9 arguments";
@@ -188,16 +235,14 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
188235
}
189236

190237
ti->private = dc;
191-
timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
192-
INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
193238
INIT_LIST_HEAD(&dc->delayed_bios);
194-
mutex_init(&dc->timer_lock);
195239
atomic_set(&dc->may_delay, 1);
196240
dc->argc = argc;
197241

198242
ret = delay_class_ctr(ti, &dc->read, argv);
199243
if (ret)
200244
goto bad;
245+
max_delay = dc->read.delay;
201246

202247
if (argc == 3) {
203248
ret = delay_class_ctr(ti, &dc->write, argv);
@@ -206,6 +251,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
206251
ret = delay_class_ctr(ti, &dc->flush, argv);
207252
if (ret)
208253
goto bad;
254+
max_delay = max(max_delay, dc->write.delay);
255+
max_delay = max(max_delay, dc->flush.delay);
209256
goto out;
210257
}
211258

@@ -216,19 +263,37 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
216263
ret = delay_class_ctr(ti, &dc->flush, argv + 3);
217264
if (ret)
218265
goto bad;
266+
max_delay = max(max_delay, dc->flush.delay);
219267
goto out;
220268
}
221269

222270
ret = delay_class_ctr(ti, &dc->flush, argv + 6);
223271
if (ret)
224272
goto bad;
273+
max_delay = max(max_delay, dc->flush.delay);
225274

226275
out:
227-
dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
228-
if (!dc->kdelayd_wq) {
229-
ret = -EINVAL;
230-
DMERR("Couldn't start kdelayd");
231-
goto bad;
276+
if (max_delay < 50) {
277+
/*
278+
* In case of small requested delays, use kthread instead of
279+
* timers and workqueue to achieve better latency.
280+
*/
281+
dc->worker = kthread_create(&flush_worker_fn, dc,
282+
"dm-delay-flush-worker");
283+
if (IS_ERR(dc->worker)) {
284+
ret = PTR_ERR(dc->worker);
285+
goto bad;
286+
}
287+
} else {
288+
timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
289+
INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
290+
mutex_init(&dc->timer_lock);
291+
dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
292+
if (!dc->kdelayd_wq) {
293+
ret = -EINVAL;
294+
DMERR("Couldn't start kdelayd");
295+
goto bad;
296+
}
232297
}
233298

234299
ti->num_flush_bios = 1;
@@ -260,7 +325,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio)
260325
list_add_tail(&delayed->list, &dc->delayed_bios);
261326
mutex_unlock(&delayed_bios_lock);
262327

263-
queue_timeout(dc, expires);
328+
if (delay_is_fast(dc))
329+
wake_up_process(dc->worker);
330+
else
331+
queue_timeout(dc, expires);
264332

265333
return DM_MAPIO_SUBMITTED;
266334
}
@@ -270,8 +338,13 @@ static void delay_presuspend(struct dm_target *ti)
270338
struct delay_c *dc = ti->private;
271339

272340
atomic_set(&dc->may_delay, 0);
273-
del_timer_sync(&dc->delay_timer);
274-
flush_bios(flush_delayed_bios(dc, 1));
341+
342+
if (delay_is_fast(dc))
343+
flush_delayed_bios_fast(dc, true);
344+
else {
345+
del_timer_sync(&dc->delay_timer);
346+
flush_bios(flush_delayed_bios(dc, true));
347+
}
275348
}
276349

277350
static void delay_resume(struct dm_target *ti)
@@ -356,7 +429,7 @@ static int delay_iterate_devices(struct dm_target *ti,
356429

357430
static struct target_type delay_target = {
358431
.name = "delay",
359-
.version = {1, 3, 0},
432+
.version = {1, 4, 0},
360433
.features = DM_TARGET_PASSES_INTEGRITY,
361434
.module = THIS_MODULE,
362435
.ctr = delay_ctr,

drivers/md/dm-integrity.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -493,42 +493,32 @@ static int sb_mac(struct dm_integrity_c *ic, bool wr)
493493
{
494494
SHASH_DESC_ON_STACK(desc, ic->journal_mac);
495495
int r;
496-
unsigned int size = crypto_shash_digestsize(ic->journal_mac);
496+
unsigned int mac_size = crypto_shash_digestsize(ic->journal_mac);
497+
__u8 *sb = (__u8 *)ic->sb;
498+
__u8 *mac = sb + (1 << SECTOR_SHIFT) - mac_size;
497499

498-
if (sizeof(struct superblock) + size > 1 << SECTOR_SHIFT) {
500+
if (sizeof(struct superblock) + mac_size > 1 << SECTOR_SHIFT) {
499501
dm_integrity_io_error(ic, "digest is too long", -EINVAL);
500502
return -EINVAL;
501503
}
502504

503505
desc->tfm = ic->journal_mac;
504506

505-
r = crypto_shash_init(desc);
506-
if (unlikely(r < 0)) {
507-
dm_integrity_io_error(ic, "crypto_shash_init", r);
508-
return r;
509-
}
510-
511-
r = crypto_shash_update(desc, (__u8 *)ic->sb, (1 << SECTOR_SHIFT) - size);
512-
if (unlikely(r < 0)) {
513-
dm_integrity_io_error(ic, "crypto_shash_update", r);
514-
return r;
515-
}
516-
517507
if (likely(wr)) {
518-
r = crypto_shash_final(desc, (__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size);
508+
r = crypto_shash_digest(desc, sb, mac - sb, mac);
519509
if (unlikely(r < 0)) {
520-
dm_integrity_io_error(ic, "crypto_shash_final", r);
510+
dm_integrity_io_error(ic, "crypto_shash_digest", r);
521511
return r;
522512
}
523513
} else {
524-
__u8 result[HASH_MAX_DIGESTSIZE];
514+
__u8 actual_mac[HASH_MAX_DIGESTSIZE];
525515

526-
r = crypto_shash_final(desc, result);
516+
r = crypto_shash_digest(desc, sb, mac - sb, actual_mac);
527517
if (unlikely(r < 0)) {
528-
dm_integrity_io_error(ic, "crypto_shash_final", r);
518+
dm_integrity_io_error(ic, "crypto_shash_digest", r);
529519
return r;
530520
}
531-
if (memcmp((__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size, result, size)) {
521+
if (memcmp(mac, actual_mac, mac_size)) {
532522
dm_integrity_io_error(ic, "superblock mac", -EILSEQ);
533523
dm_audit_log_target(DM_MSG_PREFIX, "mac-superblock", ic->ti, 0);
534524
return -EILSEQ;

drivers/md/dm-ioctl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,8 +1295,8 @@ static void retrieve_status(struct dm_table *table,
12951295
spec->status = 0;
12961296
spec->sector_start = ti->begin;
12971297
spec->length = ti->len;
1298-
strncpy(spec->target_type, ti->type->name,
1299-
sizeof(spec->target_type) - 1);
1298+
strscpy_pad(spec->target_type, ti->type->name,
1299+
sizeof(spec->target_type));
13001300

13011301
outptr += sizeof(struct dm_target_spec);
13021302
remaining = len - (outptr - outbuf);

drivers/md/dm-linear.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
8585
return lc->start + dm_target_offset(ti, bi_sector);
8686
}
8787

88-
static int linear_map(struct dm_target *ti, struct bio *bio)
88+
int linear_map(struct dm_target *ti, struct bio *bio)
8989
{
9090
struct linear_c *lc = ti->private;
9191

drivers/md/dm-log-userspace-base.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
224224

225225
lc->usr_argc = argc;
226226

227-
strncpy(lc->uuid, argv[0], DM_UUID_LEN);
227+
strscpy(lc->uuid, argv[0], sizeof(lc->uuid));
228228
argc--;
229229
argv++;
230230
spin_lock_init(&lc->flush_lock);

drivers/md/dm-stripe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
268268
return DM_MAPIO_SUBMITTED;
269269
}
270270

271-
static int stripe_map(struct dm_target *ti, struct bio *bio)
271+
int stripe_map(struct dm_target *ti, struct bio *bio)
272272
{
273273
struct stripe_c *sc = ti->private;
274274
uint32_t stripe;

0 commit comments

Comments
 (0)