History

Merge tag 'for-5.7/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer: - Document DM integrity allow_discard feature that was added during 5.7 merge window. - Fix potential for DM writecache data corruption during DM table reloads. - Fix DM verity's FEC support's hash block number calculation in verity_fec_decode(). - Fix bio-based DM multipath crash due to use of stale copy of MPATHF_QUEUE_IO flag state in __map_bio(). * tag 'for-5.7/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm multipath: use updated MPATHF_QUEUE_IO on mapping for bio-based mpath dm verity fec: fix hash block number in verity_fec_decode dm writecache: fix data corruption when reloading the target dm integrity: document allow_discard option

Linus Torvalds committed 6 years ago

Commit c45e8bc2 parents 39e16d9 5686dee4 files · +51 −24Browse files

Unified · Split

4 files
  1. Documentation/admin-guide/device-mapper/dm-integrity.rst +9 −6
  2. drivers/md/dm-mpath.c +4 −2
  3. drivers/md/dm-verity-fec.c +1 −1
  4. drivers/md/dm-writecache.c +37 −15
Documentation/admin-guide/device-mapper/dm-integrity.rst+9−6
@@ -182,12 +182,15 @@ fix_padding · 181 unmodified lines
182 space-efficient. If this option is not present, large padding is182 space-efficient. If this option is not present, large padding is
183 used - that is for compatibility with older kernels.183 used - that is for compatibility with older kernels.
184 184
185 185allow_discards
186The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can186 Allow block discard requests (a.k.a. TRIM) for the integrity device.
187be changed when reloading the target (load an inactive table and swap the187 Discards are only allowed to devices using internal hash.
188tables with suspend and resume). The other arguments should not be changed188
189when reloading the target because the layout of disk data depend on them189The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and
190and the reloaded target would be non-functional.190allow_discards can be changed when reloading the target (load an inactive
191table and swap the tables with suspend and resume). The other arguments
192should not be changed when reloading the target because the layout of disk
193data depend on them and the reloaded target would be non-functional.
191 194
192 195
193The layout of the formatted block device:196The layout of the formatted block device:
drivers/md/dm-mpath.c+4−2
@@ -585,10 +585,12 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) · 584 unmodified lines
585 585
586 /* Do we need to select a new pgpath? */586 /* Do we need to select a new pgpath? */
587 pgpath = READ_ONCE(m->current_pgpath);587 pgpath = READ_ONCE(m->current_pgpath);
588 queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags);588 if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags))
589 if (!pgpath || !queue_io)
590 pgpath = choose_pgpath(m, bio->bi_iter.bi_size);589 pgpath = choose_pgpath(m, bio->bi_iter.bi_size);
591 590
591 /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */
592 queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags);
593
592 if ((pgpath && queue_io) ||594 if ((pgpath && queue_io) ||
593 (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) {595 (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) {
594 /* Queue for the daemon to resubmit */596 /* Queue for the daemon to resubmit */
drivers/md/dm-verity-fec.c+1−1
@@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, · 434 unmodified lines
435 fio->level++;435 fio->level++;
436 436
437 if (type == DM_VERITY_BLOCK_TYPE_METADATA)437 if (type == DM_VERITY_BLOCK_TYPE_METADATA)
438 block += v->data_blocks;438 block = block - v->hash_start + v->data_blocks;
439 439
440 /*440 /*
441 * For RS(M, N), the continuous FEC data is divided into blocks of N441 * For RS(M, N), the continuous FEC data is divided into blocks of N
drivers/md/dm-writecache.c+37−15
@@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 930 unmodified lines
931 return 0;931 return 0;
932}932}
933 933
934static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors)
935{
936 struct dm_io_region region;
937 struct dm_io_request req;
938
939 region.bdev = wc->ssd_dev->bdev;
940 region.sector = wc->start_sector;
941 region.count = n_sectors;
942 req.bi_op = REQ_OP_READ;
943 req.bi_op_flags = REQ_SYNC;
944 req.mem.type = DM_IO_VMA;
945 req.mem.ptr.vma = (char *)wc->memory_map;
946 req.client = wc->dm_io;
947 req.notify.fn = NULL;
948
949 return dm_io(&req, 1, &region, NULL);
950}
951
934static void writecache_resume(struct dm_target *ti)952static void writecache_resume(struct dm_target *ti)
935{953{
936 struct dm_writecache *wc = ti->private;954 struct dm_writecache *wc = ti->private;
@@ -941,8 +959,18 @@ static void writecache_resume(struct dm_target *ti) · 4 unmodified lines
941 959
942 wc_lock(wc);960 wc_lock(wc);
943 961
944 if (WC_MODE_PMEM(wc))962 if (WC_MODE_PMEM(wc)) {
945 persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size);963 persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size);
964 } else {
965 r = writecache_read_metadata(wc, wc->metadata_sectors);
966 if (r) {
967 size_t sb_entries_offset;
968 writecache_error(wc, r, "unable to read metadata: %d", r);
969 sb_entries_offset = offsetof(struct wc_memory_superblock, entries);
970 memset((char *)wc->memory_map + sb_entries_offset, -1,
971 (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset);
972 }
973 }
946 974
947 wc->tree = RB_ROOT;975 wc->tree = RB_ROOT;
948 INIT_LIST_HEAD(&wc->lru);976 INIT_LIST_HEAD(&wc->lru);
@@ -2102,6 +2130,12 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) · 1153 unmodified lines
2102 ti->error = "Invalid block size";2130 ti->error = "Invalid block size";
2103 goto bad;2131 goto bad;
2104 }2132 }
2133 if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) ||
2134 wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) {
2135 r = -EINVAL;
2136 ti->error = "Block size is smaller than device logical block size";
2137 goto bad;
2138 }
2105 wc->block_size_bits = __ffs(wc->block_size);2139 wc->block_size_bits = __ffs(wc->block_size);
2106 2140
2107 wc->max_writeback_jobs = MAX_WRITEBACK_JOBS;2141 wc->max_writeback_jobs = MAX_WRITEBACK_JOBS;
@@ -2200,8 +2234,6 @@ invalid_optional: · 92 unmodified lines
2200 goto bad;2234 goto bad;
2201 }2235 }
2202 } else {2236 } else {
2203 struct dm_io_region region;
2204 struct dm_io_request req;
2205 size_t n_blocks, n_metadata_blocks;2237 size_t n_blocks, n_metadata_blocks;
2206 uint64_t n_bitmap_bits;2238 uint64_t n_bitmap_bits;
2207 2239
@@ -2258,19 +2290,9 @@ invalid_optional: · 50 unmodified lines
2258 goto bad;2290 goto bad;
2259 }2291 }
2260 2292
2261 region.bdev = wc->ssd_dev->bdev;2293 r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT);
2262 region.sector = wc->start_sector;
2263 region.count = wc->metadata_sectors;
2264 req.bi_op = REQ_OP_READ;
2265 req.bi_op_flags = REQ_SYNC;
2266 req.mem.type = DM_IO_VMA;
2267 req.mem.ptr.vma = (char *)wc->memory_map;
2268 req.client = wc->dm_io;
2269 req.notify.fn = NULL;
2270
2271 r = dm_io(&req, 1, &region, NULL);
2272 if (r) {2294 if (r) {
2273 ti->error = "Unable to read metadata";2295 ti->error = "Unable to read first block of metadata";
2274 goto bad;2296 goto bad;
2275 }2297 }
2276 }2298 }