Skip to content

Commit 4f1cbe0

Browse files
committed
Merge tag 'for-5.1/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - Two queue_limits stacking fixes: disable discards if underlying driver does. And propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors. - Fix that reverts a DM core limit that wasn't needed given that dm-crypt was already updated to impose an equivalent limit. - Fix dm-init to properly establish 'const' for __initconst array. - Fix deadlock in DM integrity target that occurs when overlapping IO is being issued to it. And two smaller fixes to the DM integrity target. * tag 'for-5.1/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm integrity: fix deadlock with overlapping I/O dm: disable DISCARD if the underlying storage no longer supports it dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors dm: revert 8f50e35 ("dm: limit the max bio size as BIO_MAX_PAGES * PAGE_SIZE") dm init: fix const confusion for dm_allowed_targets array dm integrity: make dm_integrity_init and dm_integrity_exit static dm integrity: change memcmp to strncmp in dm_integrity_ctr
2 parents 3e28fb0 + 4ed319c commit 4f1cbe0

File tree

6 files changed

+72
-27
lines changed

6 files changed

+72
-27
lines changed

drivers/md/dm-core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ struct mapped_device {
115115
struct srcu_struct io_barrier;
116116
};
117117

118+
void disable_discard(struct mapped_device *md);
118119
void disable_write_same(struct mapped_device *md);
119120
void disable_write_zeroes(struct mapped_device *md);
120121

drivers/md/dm-init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct dm_device {
3636
struct list_head list;
3737
};
3838

39-
const char *dm_allowed_targets[] __initconst = {
39+
const char * const dm_allowed_targets[] __initconst = {
4040
"crypt",
4141
"delay",
4242
"linear",

drivers/md/dm-integrity.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ static void copy_from_journal(struct dm_integrity_c *ic, unsigned section, unsig
913913
static bool ranges_overlap(struct dm_integrity_range *range1, struct dm_integrity_range *range2)
914914
{
915915
return range1->logical_sector < range2->logical_sector + range2->n_sectors &&
916-
range2->logical_sector + range2->n_sectors > range2->logical_sector;
916+
range1->logical_sector + range1->n_sectors > range2->logical_sector;
917917
}
918918

919919
static bool add_new_range(struct dm_integrity_c *ic, struct dm_integrity_range *new_range, bool check_waiting)
@@ -959,8 +959,6 @@ static void remove_range_unlocked(struct dm_integrity_c *ic, struct dm_integrity
959959
struct dm_integrity_range *last_range =
960960
list_first_entry(&ic->wait_list, struct dm_integrity_range, wait_entry);
961961
struct task_struct *last_range_task;
962-
if (!ranges_overlap(range, last_range))
963-
break;
964962
last_range_task = last_range->task;
965963
list_del(&last_range->wait_entry);
966964
if (!add_new_range(ic, last_range, false)) {
@@ -3185,7 +3183,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
31853183
journal_watermark = val;
31863184
else if (sscanf(opt_string, "commit_time:%u%c", &val, &dummy) == 1)
31873185
sync_msec = val;
3188-
else if (!memcmp(opt_string, "meta_device:", strlen("meta_device:"))) {
3186+
else if (!strncmp(opt_string, "meta_device:", strlen("meta_device:"))) {
31893187
if (ic->meta_dev) {
31903188
dm_put_device(ti, ic->meta_dev);
31913189
ic->meta_dev = NULL;
@@ -3204,17 +3202,17 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
32043202
goto bad;
32053203
}
32063204
ic->sectors_per_block = val >> SECTOR_SHIFT;
3207-
} else if (!memcmp(opt_string, "internal_hash:", strlen("internal_hash:"))) {
3205+
} else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) {
32083206
r = get_alg_and_key(opt_string, &ic->internal_hash_alg, &ti->error,
32093207
"Invalid internal_hash argument");
32103208
if (r)
32113209
goto bad;
3212-
} else if (!memcmp(opt_string, "journal_crypt:", strlen("journal_crypt:"))) {
3210+
} else if (!strncmp(opt_string, "journal_crypt:", strlen("journal_crypt:"))) {
32133211
r = get_alg_and_key(opt_string, &ic->journal_crypt_alg, &ti->error,
32143212
"Invalid journal_crypt argument");
32153213
if (r)
32163214
goto bad;
3217-
} else if (!memcmp(opt_string, "journal_mac:", strlen("journal_mac:"))) {
3215+
} else if (!strncmp(opt_string, "journal_mac:", strlen("journal_mac:"))) {
32183216
r = get_alg_and_key(opt_string, &ic->journal_mac_alg, &ti->error,
32193217
"Invalid journal_mac argument");
32203218
if (r)
@@ -3616,7 +3614,7 @@ static struct target_type integrity_target = {
36163614
.io_hints = dm_integrity_io_hints,
36173615
};
36183616

3619-
int __init dm_integrity_init(void)
3617+
static int __init dm_integrity_init(void)
36203618
{
36213619
int r;
36223620

@@ -3635,7 +3633,7 @@ int __init dm_integrity_init(void)
36353633
return r;
36363634
}
36373635

3638-
void dm_integrity_exit(void)
3636+
static void __exit dm_integrity_exit(void)
36393637
{
36403638
dm_unregister_target(&integrity_target);
36413639
kmem_cache_destroy(journal_io_cache);

drivers/md/dm-rq.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,14 @@ static void dm_done(struct request *clone, blk_status_t error, bool mapped)
222222
}
223223

224224
if (unlikely(error == BLK_STS_TARGET)) {
225-
if (req_op(clone) == REQ_OP_WRITE_SAME &&
226-
!clone->q->limits.max_write_same_sectors)
225+
if (req_op(clone) == REQ_OP_DISCARD &&
226+
!clone->q->limits.max_discard_sectors)
227+
disable_discard(tio->md);
228+
else if (req_op(clone) == REQ_OP_WRITE_SAME &&
229+
!clone->q->limits.max_write_same_sectors)
227230
disable_write_same(tio->md);
228-
if (req_op(clone) == REQ_OP_WRITE_ZEROES &&
229-
!clone->q->limits.max_write_zeroes_sectors)
231+
else if (req_op(clone) == REQ_OP_WRITE_ZEROES &&
232+
!clone->q->limits.max_write_zeroes_sectors)
230233
disable_write_zeroes(tio->md);
231234
}
232235

drivers/md/dm-table.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,36 @@ static bool dm_table_supports_secure_erase(struct dm_table *t)
18441844
return true;
18451845
}
18461846

1847+
static int device_requires_stable_pages(struct dm_target *ti,
1848+
struct dm_dev *dev, sector_t start,
1849+
sector_t len, void *data)
1850+
{
1851+
struct request_queue *q = bdev_get_queue(dev->bdev);
1852+
1853+
return q && bdi_cap_stable_pages_required(q->backing_dev_info);
1854+
}
1855+
1856+
/*
1857+
* If any underlying device requires stable pages, a table must require
1858+
* them as well. Only targets that support iterate_devices are considered:
1859+
* don't want error, zero, etc to require stable pages.
1860+
*/
1861+
static bool dm_table_requires_stable_pages(struct dm_table *t)
1862+
{
1863+
struct dm_target *ti;
1864+
unsigned i;
1865+
1866+
for (i = 0; i < dm_table_get_num_targets(t); i++) {
1867+
ti = dm_table_get_target(t, i);
1868+
1869+
if (ti->type->iterate_devices &&
1870+
ti->type->iterate_devices(ti, device_requires_stable_pages, NULL))
1871+
return true;
1872+
}
1873+
1874+
return false;
1875+
}
1876+
18471877
void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
18481878
struct queue_limits *limits)
18491879
{
@@ -1896,6 +1926,15 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
18961926

18971927
dm_table_verify_integrity(t);
18981928

1929+
/*
1930+
* Some devices don't use blk_integrity but still want stable pages
1931+
* because they do their own checksumming.
1932+
*/
1933+
if (dm_table_requires_stable_pages(t))
1934+
q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
1935+
else
1936+
q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES;
1937+
18991938
/*
19001939
* Determine whether or not this queue's I/O timings contribute
19011940
* to the entropy pool, Only request-based targets use this.

drivers/md/dm.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,15 @@ static void dec_pending(struct dm_io *io, blk_status_t error)
945945
}
946946
}
947947

948+
void disable_discard(struct mapped_device *md)
949+
{
950+
struct queue_limits *limits = dm_get_queue_limits(md);
951+
952+
/* device doesn't really support DISCARD, disable it */
953+
limits->max_discard_sectors = 0;
954+
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, md->queue);
955+
}
956+
948957
void disable_write_same(struct mapped_device *md)
949958
{
950959
struct queue_limits *limits = dm_get_queue_limits(md);
@@ -970,11 +979,14 @@ static void clone_endio(struct bio *bio)
970979
dm_endio_fn endio = tio->ti->type->end_io;
971980

972981
if (unlikely(error == BLK_STS_TARGET) && md->type != DM_TYPE_NVME_BIO_BASED) {
973-
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
974-
!bio->bi_disk->queue->limits.max_write_same_sectors)
982+
if (bio_op(bio) == REQ_OP_DISCARD &&
983+
!bio->bi_disk->queue->limits.max_discard_sectors)
984+
disable_discard(md);
985+
else if (bio_op(bio) == REQ_OP_WRITE_SAME &&
986+
!bio->bi_disk->queue->limits.max_write_same_sectors)
975987
disable_write_same(md);
976-
if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
977-
!bio->bi_disk->queue->limits.max_write_zeroes_sectors)
988+
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
989+
!bio->bi_disk->queue->limits.max_write_zeroes_sectors)
978990
disable_write_zeroes(md);
979991
}
980992

@@ -1042,15 +1054,7 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
10421054
return -EINVAL;
10431055
}
10441056

1045-
/*
1046-
* BIO based queue uses its own splitting. When multipage bvecs
1047-
* is switched on, size of the incoming bio may be too big to
1048-
* be handled in some targets, such as crypt.
1049-
*
1050-
* When these targets are ready for the big bio, we can remove
1051-
* the limit.
1052-
*/
1053-
ti->max_io_len = min_t(uint32_t, len, BIO_MAX_PAGES * PAGE_SIZE);
1057+
ti->max_io_len = (uint32_t) len;
10541058

10551059
return 0;
10561060
}

0 commit comments

Comments
 (0)