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
Unified · Split
| @@ -182,12 +182,15 @@ fix_padding · 181 unmodified lines | ||
| 182 | 182 | space-efficient. If this option is not present, large padding is |
| 183 | 183 | used - that is for compatibility with older kernels. |
| 184 | 184 | |
| 185 | − | |
| 186 | −The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can | |
| 187 | −be changed when reloading the target (load an inactive table and swap the | |
| 188 | −tables with suspend and resume). The other arguments should not be changed | |
| 189 | −when reloading the target because the layout of disk data depend on them | |
| 190 | −and the reloaded target would be non-functional. | |
| 185 | +allow_discards | |
| 186 | + Allow block discard requests (a.k.a. TRIM) for the integrity device. | |
| 187 | + Discards are only allowed to devices using internal hash. | |
| 188 | + | |
| 189 | +The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and | |
| 190 | +allow_discards can be changed when reloading the target (load an inactive | |
| 191 | +table and swap the tables with suspend and resume). The other arguments | |
| 192 | +should not be changed when reloading the target because the layout of disk | |
| 193 | +data depend on them and the reloaded target would be non-functional. | |
| 191 | 194 | |
| 192 | 195 | |
| 193 | 196 | The layout of the formatted block device: |
| @@ -585,10 +585,12 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) · 584 unmodified lines | ||
| 585 | 585 | |
| 586 | 586 | /* Do we need to select a new pgpath? */ |
| 587 | 587 | pgpath = READ_ONCE(m->current_pgpath); |
| 588 | − queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 589 | − if (!pgpath || !queue_io) | |
| 588 | + if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 590 | 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 | 594 | if ((pgpath && queue_io) || |
| 593 | 595 | (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { |
| 594 | 596 | /* Queue for the daemon to resubmit */ |
| @@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, · 434 unmodified lines | ||
| 435 | 435 | fio->level++; |
| 436 | 436 | |
| 437 | 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 | 441 | * For RS(M, N), the continuous FEC data is divided into blocks of N |
| @@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 930 unmodified lines | ||
| 931 | 931 | return 0; |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | +static 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, ®ion, NULL); | |
| 950 | +} | |
| 951 | + | |
| 934 | 952 | static void writecache_resume(struct dm_target *ti) |
| 935 | 953 | { |
| 936 | 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 | 960 | wc_lock(wc); |
| 943 | 961 | |
| 944 | − if (WC_MODE_PMEM(wc)) | |
| 962 | + if (WC_MODE_PMEM(wc)) { | |
| 945 | 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 | 975 | wc->tree = RB_ROOT; |
| 948 | 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 | 2130 | ti->error = "Invalid block size"; |
| 2103 | 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 | 2139 | wc->block_size_bits = __ffs(wc->block_size); |
| 2106 | 2140 | |
| 2107 | 2141 | wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; |
| @@ -2200,8 +2234,6 @@ invalid_optional: · 92 unmodified lines | ||
| 2200 | 2234 | goto bad; |
| 2201 | 2235 | } |
| 2202 | 2236 | } else { |
| 2203 | − struct dm_io_region region; | |
| 2204 | − struct dm_io_request req; | |
| 2205 | 2237 | size_t n_blocks, n_metadata_blocks; |
| 2206 | 2238 | uint64_t n_bitmap_bits; |
| 2207 | 2239 | |
| @@ -2258,19 +2290,9 @@ invalid_optional: · 50 unmodified lines | ||
| 2258 | 2290 | goto bad; |
| 2259 | 2291 | } |
| 2260 | 2292 | |
| 2261 | − region.bdev = wc->ssd_dev->bdev; | |
| 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, ®ion, NULL); | |
| 2293 | + r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT); | |
| 2272 | 2294 | if (r) { |
| 2273 | − ti->error = "Unable to read metadata"; | |
| 2295 | + ti->error = "Unable to read first block of metadata"; | |
| 2274 | 2296 | goto bad; |
| 2275 | 2297 | } |
| 2276 | 2298 | } |