Skip to content

Commit c3a1309

Browse files
committed
Merge tag 'for-5.9/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - writecache fix to allow dax_direct_access() to partitioned pmem devices. - multipath fix to avoid any Path Group initialization if 'pg_init_in_progress' isn't set. - crypt fix to use DECLARE_CRYPTO_WAIT() for onstack wait structures. - integrity fix to properly check integrity after device creation when in bitmap mode. - thinp and cache target __create_persistent_data_objects() fixes to reset the metadata's dm_block_manager pointer from PTR_ERR to NULL before returning from error path. - persistent-data block manager fix to guard against dm_block_manager NULL pointer dereference in dm_bm_is_read_only() and update various opencoded bm->read_only checks to use dm_bm_is_read_only() instead. * tag 'for-5.9/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm thin metadata: Fix use-after-free in dm_bm_set_read_only dm thin metadata: Avoid returning cmd->bm wild pointer on error dm cache metadata: Avoid returning cmd->bm wild pointer on error dm integrity: fix error reporting in bitmap mode after creation dm crypt: Initialize crypto wait structures dm mpath: fix racey management of PG initialization dm writecache: handle DAX to partitions on persistent memory correctly
2 parents e1d0126 + 3a653b2 commit c3a1309

File tree

7 files changed

+60
-22
lines changed

7 files changed

+60
-22
lines changed

drivers/md/dm-cache-metadata.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,16 @@ static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
537537
CACHE_MAX_CONCURRENT_LOCKS);
538538
if (IS_ERR(cmd->bm)) {
539539
DMERR("could not create block manager");
540-
return PTR_ERR(cmd->bm);
540+
r = PTR_ERR(cmd->bm);
541+
cmd->bm = NULL;
542+
return r;
541543
}
542544

543545
r = __open_or_format_metadata(cmd, may_format_device);
544-
if (r)
546+
if (r) {
545547
dm_block_manager_destroy(cmd->bm);
548+
cmd->bm = NULL;
549+
}
546550

547551
return r;
548552
}

drivers/md/dm-crypt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
739739
u8 buf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(__le64));
740740
struct skcipher_request *req;
741741
struct scatterlist src, dst;
742-
struct crypto_wait wait;
742+
DECLARE_CRYPTO_WAIT(wait);
743743
int err;
744744

745745
req = skcipher_request_alloc(any_tfm(cc), GFP_NOIO);
@@ -936,7 +936,7 @@ static int crypt_iv_elephant(struct crypt_config *cc, struct dm_crypt_request *d
936936
u8 *es, *ks, *data, *data2, *data_offset;
937937
struct skcipher_request *req;
938938
struct scatterlist *sg, *sg2, src, dst;
939-
struct crypto_wait wait;
939+
DECLARE_CRYPTO_WAIT(wait);
940940
int i, r;
941941

942942
req = skcipher_request_alloc(elephant->tfm, GFP_NOIO);

drivers/md/dm-integrity.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,6 +2487,7 @@ static void integrity_recalc(struct work_struct *w)
24872487
range.logical_sector = le64_to_cpu(ic->sb->recalc_sector);
24882488
if (unlikely(range.logical_sector >= ic->provided_data_sectors)) {
24892489
if (ic->mode == 'B') {
2490+
block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
24902491
DEBUG_print("queue_delayed_work: bitmap_flush_work\n");
24912492
queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, 0);
24922493
}
@@ -2564,6 +2565,17 @@ static void integrity_recalc(struct work_struct *w)
25642565
goto err;
25652566
}
25662567

2568+
if (ic->mode == 'B') {
2569+
sector_t start, end;
2570+
start = (range.logical_sector >>
2571+
(ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit)) <<
2572+
(ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit);
2573+
end = ((range.logical_sector + range.n_sectors) >>
2574+
(ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit)) <<
2575+
(ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit);
2576+
block_bitmap_op(ic, ic->recalc_bitmap, start, end - start, BITMAP_OP_CLEAR);
2577+
}
2578+
25672579
advance_and_next:
25682580
cond_resched();
25692581

drivers/md/dm-mpath.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,17 +1287,25 @@ static void multipath_wait_for_pg_init_completion(struct multipath *m)
12871287
static void flush_multipath_work(struct multipath *m)
12881288
{
12891289
if (m->hw_handler_name) {
1290-
set_bit(MPATHF_PG_INIT_DISABLED, &m->flags);
1291-
smp_mb__after_atomic();
1290+
unsigned long flags;
1291+
1292+
if (!atomic_read(&m->pg_init_in_progress))
1293+
goto skip;
1294+
1295+
spin_lock_irqsave(&m->lock, flags);
1296+
if (atomic_read(&m->pg_init_in_progress) &&
1297+
!test_and_set_bit(MPATHF_PG_INIT_DISABLED, &m->flags)) {
1298+
spin_unlock_irqrestore(&m->lock, flags);
12921299

1293-
if (atomic_read(&m->pg_init_in_progress))
12941300
flush_workqueue(kmpath_handlerd);
1295-
multipath_wait_for_pg_init_completion(m);
1301+
multipath_wait_for_pg_init_completion(m);
12961302

1297-
clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags);
1298-
smp_mb__after_atomic();
1303+
spin_lock_irqsave(&m->lock, flags);
1304+
clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags);
1305+
}
1306+
spin_unlock_irqrestore(&m->lock, flags);
12991307
}
1300-
1308+
skip:
13011309
if (m->queue_mode == DM_TYPE_BIO_BASED)
13021310
flush_work(&m->process_queued_bios);
13031311
flush_work(&m->trigger_event);

drivers/md/dm-thin-metadata.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,12 +739,16 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f
739739
THIN_MAX_CONCURRENT_LOCKS);
740740
if (IS_ERR(pmd->bm)) {
741741
DMERR("could not create block manager");
742-
return PTR_ERR(pmd->bm);
742+
r = PTR_ERR(pmd->bm);
743+
pmd->bm = NULL;
744+
return r;
743745
}
744746

745747
r = __open_or_format_metadata(pmd, format_device);
746-
if (r)
748+
if (r) {
747749
dm_block_manager_destroy(pmd->bm);
750+
pmd->bm = NULL;
751+
}
748752

749753
return r;
750754
}
@@ -954,7 +958,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
954958
}
955959

956960
pmd_write_lock_in_core(pmd);
957-
if (!dm_bm_is_read_only(pmd->bm) && !pmd->fail_io) {
961+
if (!pmd->fail_io && !dm_bm_is_read_only(pmd->bm)) {
958962
r = __commit_transaction(pmd);
959963
if (r < 0)
960964
DMWARN("%s: __commit_transaction() failed, error = %d",

drivers/md/dm-writecache.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ static int persistent_memory_claim(struct dm_writecache *wc)
231231
pfn_t pfn;
232232
int id;
233233
struct page **pages;
234+
sector_t offset;
234235

235236
wc->memory_vmapped = false;
236237

@@ -245,9 +246,16 @@ static int persistent_memory_claim(struct dm_writecache *wc)
245246
goto err1;
246247
}
247248

249+
offset = get_start_sect(wc->ssd_dev->bdev);
250+
if (offset & (PAGE_SIZE / 512 - 1)) {
251+
r = -EINVAL;
252+
goto err1;
253+
}
254+
offset >>= PAGE_SHIFT - 9;
255+
248256
id = dax_read_lock();
249257

250-
da = dax_direct_access(wc->ssd_dev->dax_dev, 0, p, &wc->memory_map, &pfn);
258+
da = dax_direct_access(wc->ssd_dev->dax_dev, offset, p, &wc->memory_map, &pfn);
251259
if (da < 0) {
252260
wc->memory_map = NULL;
253261
r = da;
@@ -269,7 +277,7 @@ static int persistent_memory_claim(struct dm_writecache *wc)
269277
i = 0;
270278
do {
271279
long daa;
272-
daa = dax_direct_access(wc->ssd_dev->dax_dev, i, p - i,
280+
daa = dax_direct_access(wc->ssd_dev->dax_dev, offset + i, p - i,
273281
NULL, &pfn);
274282
if (daa <= 0) {
275283
r = daa ? daa : -EINVAL;

drivers/md/persistent-data/dm-block-manager.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ int dm_bm_write_lock(struct dm_block_manager *bm,
493493
void *p;
494494
int r;
495495

496-
if (bm->read_only)
496+
if (dm_bm_is_read_only(bm))
497497
return -EPERM;
498498

499499
p = dm_bufio_read(bm->bufio, b, (struct dm_buffer **) result);
@@ -562,7 +562,7 @@ int dm_bm_write_lock_zero(struct dm_block_manager *bm,
562562
struct buffer_aux *aux;
563563
void *p;
564564

565-
if (bm->read_only)
565+
if (dm_bm_is_read_only(bm))
566566
return -EPERM;
567567

568568
p = dm_bufio_new(bm->bufio, b, (struct dm_buffer **) result);
@@ -602,7 +602,7 @@ EXPORT_SYMBOL_GPL(dm_bm_unlock);
602602

603603
int dm_bm_flush(struct dm_block_manager *bm)
604604
{
605-
if (bm->read_only)
605+
if (dm_bm_is_read_only(bm))
606606
return -EPERM;
607607

608608
return dm_bufio_write_dirty_buffers(bm->bufio);
@@ -616,19 +616,21 @@ void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b)
616616

617617
bool dm_bm_is_read_only(struct dm_block_manager *bm)
618618
{
619-
return bm->read_only;
619+
return (bm ? bm->read_only : true);
620620
}
621621
EXPORT_SYMBOL_GPL(dm_bm_is_read_only);
622622

623623
void dm_bm_set_read_only(struct dm_block_manager *bm)
624624
{
625-
bm->read_only = true;
625+
if (bm)
626+
bm->read_only = true;
626627
}
627628
EXPORT_SYMBOL_GPL(dm_bm_set_read_only);
628629

629630
void dm_bm_set_read_write(struct dm_block_manager *bm)
630631
{
631-
bm->read_only = false;
632+
if (bm)
633+
bm->read_only = false;
632634
}
633635
EXPORT_SYMBOL_GPL(dm_bm_set_read_write);
634636

0 commit comments

Comments
 (0)