Pull device mapper updates from Mike Snitzer: - DM multipath locking fixes around m->flags tests and improvements to bio-based code so that it follows patterns established by request-based code. - Request-based DM core improvement to eliminate unnecessary call to blk_mq_queue_stopped(). - Add "panic_on_corruption" error handling mode to DM verity target. - DM bufio fix to to perform buffer cleanup from a workqueue rather than wait for IO in reclaim context from shrinker. - DM crypt improvement to optionally avoid async processing via workqueues for reads and/or writes -- via "no_read_workqueue" and "no_write_workqueue" features. This more direct IO processing improves latency and throughput with faster storage. Avoiding workqueue IO submission for writes (DM_CRYPT_NO_WRITE_WORKQUEUE) is a requirement for adding zoned block device support to DM crypt. - Add zoned block device support to DM crypt. Makes use of DM_CRYPT_NO_WRITE_WORKQUEUE and a new optional feature (DM_CRYPT_WRITE_INLINE) that allows write completion to wait for encryption to complete. This allows write ordering to be preserved, which is needed for zoned block devices. - Fix DM ebs target's check for REQ_OP_FLUSH. - Fix DM core's report zones support to not report more zones than were requested. - A few small compiler warning fixes. - DM dust improvements to return output directly to the user rather than require they scrape the system log for output. * tag 'for-5.9/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm: don't call report zones for more than the user requested dm ebs: Fix incorrect checking for REQ_OP_FLUSH dm init: Set file local variable static dm ioctl: Fix compilation warning dm raid: Remove empty if statement dm verity: Fix compilation warning dm crypt: Enable zoned block device support dm crypt: add flags to optionally bypass kcryptd workqueues dm bufio: do buffer cleanup from a workqueue dm rq: don't call blk_mq_queue_stopped() in dm_stop_queue() dm dust: add interface to list all badblocks dm dust: report some message results directly back to user dm verity: add "panic_on_corruption" error handling mode dm mpath: use double checked locking in fast path dm mpath: rename current_pgpath to pgpath in multipath_prepare_ioctl dm mpath: rework __map_bio() dm mpath: factor out multipath_queue_bio dm mpath: push locking down to must_push_back_rq() dm mpath: take m->lock spinlock when testing QUEUE_IF_NO_PATH dm mpath: changes from initial m->flags locking audit
Unified · Split
| @@ -69,10 +69,11 @@ Create the dm-dust device: · 68 unmodified lines | ||
| 69 | 69 | $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096' |
| 70 | 70 | |
| 71 | 71 | Check the status of the read behavior ("bypass" indicates that all I/O |
| 72 | −will be passed through to the underlying device):: | |
| 72 | +will be passed through to the underlying device; "verbose" indicates that | |
| 73 | +bad block additions, removals, and remaps will be verbosely logged):: | |
| 73 | 74 | |
| 74 | 75 | $ sudo dmsetup status dust1 |
| 75 | − 0 33552384 dust 252:17 bypass | |
| 76 | + 0 33552384 dust 252:17 bypass verbose | |
| 76 | 77 | |
| 77 | 78 | $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct |
| 78 | 79 | 128+0 records in |
| @@ -164,7 +165,7 @@ following message command:: · 85 unmodified lines | ||
| 164 | 165 | A message will print with the number of bad blocks currently |
| 165 | 166 | configured on the device:: |
| 166 | 167 | |
| 167 | − kernel: device-mapper: dust: countbadblocks: 895 badblock(s) found | |
| 168 | + countbadblocks: 895 badblock(s) found | |
| 168 | 169 | |
| 169 | 170 | Querying for specific bad blocks |
| 170 | 171 | -------------------------------- |
| @@ -176,11 +177,11 @@ following message command:: · 5 unmodified lines | ||
| 176 | 177 | |
| 177 | 178 | The following message will print if the block is in the list:: |
| 178 | 179 | |
| 179 | − device-mapper: dust: queryblock: block 72 found in badblocklist | |
| 180 | + dust_query_block: block 72 found in badblocklist | |
| 180 | 181 | |
| 181 | 182 | The following message will print if the block is not in the list:: |
| 182 | 183 | |
| 183 | − device-mapper: dust: queryblock: block 72 not found in badblocklist | |
| 184 | + dust_query_block: block 72 not found in badblocklist | |
| 184 | 185 | |
| 185 | 186 | The "queryblock" message command will work in both the "enabled" |
| 186 | 187 | and "disabled" modes, allowing the verification of whether a block |
| @@ -198,12 +199,28 @@ following message command:: · 11 unmodified lines | ||
| 198 | 199 | |
| 199 | 200 | After clearing the bad block list, the following message will appear:: |
| 200 | 201 | |
| 201 | − kernel: device-mapper: dust: clearbadblocks: badblocks cleared | |
| 202 | + dust_clear_badblocks: badblocks cleared | |
| 202 | 203 | |
| 203 | 204 | If there were no bad blocks to clear, the following message will |
| 204 | 205 | appear:: |
| 205 | 206 | |
| 206 | − kernel: device-mapper: dust: clearbadblocks: no badblocks found | |
| 207 | + dust_clear_badblocks: no badblocks found | |
| 208 | + | |
| 209 | +Listing the bad block list | |
| 210 | +-------------------------- | |
| 211 | + | |
| 212 | +To list all bad blocks in the bad block list (using an example device | |
| 213 | +with blocks 1 and 2 in the bad block list), run the following message | |
| 214 | +command:: | |
| 215 | + | |
| 216 | + $ sudo dmsetup message dust1 0 listbadblocks | |
| 217 | + 1 | |
| 218 | + 2 | |
| 219 | + | |
| 220 | +If there are no bad blocks in the bad block list, the command will | |
| 221 | +execute with no output:: | |
| 222 | + | |
| 223 | + $ sudo dmsetup message dust1 0 listbadblocks | |
| 207 | 224 | |
| 208 | 225 | Message commands list |
| 209 | 226 | --------------------- |
| @@ -223,6 +240,7 @@ Single argument message commands:: · 13 unmodified lines | ||
| 223 | 240 | |
| 224 | 241 | countbadblocks |
| 225 | 242 | clearbadblocks |
| 243 | + listbadblocks | |
| 226 | 244 | disable |
| 227 | 245 | enable |
| 228 | 246 | quiet |
| @@ -83,6 +83,10 @@ restart_on_corruption · 82 unmodified lines | ||
| 83 | 83 | not compatible with ignore_corruption and requires user space support to |
| 84 | 84 | avoid restart loops. |
| 85 | 85 | |
| 86 | +panic_on_corruption | |
| 87 | + Panic the device when a corrupted block is discovered. This option is | |
| 88 | + not compatible with ignore_corruption and restart_on_corruption. | |
| 89 | + | |
| 86 | 90 | ignore_zero_blocks |
| 87 | 91 | Do not verify blocks that are expected to contain zeroes and always return |
| 88 | 92 | zeroes instead. This may be useful if the partition contains unused blocks |
| @@ -108,7 +108,10 @@ struct dm_bufio_client { · 107 unmodified lines | ||
| 108 | 108 | int async_write_error; |
| 109 | 109 | |
| 110 | 110 | struct list_head client_list; |
| 111 | + | |
| 111 | 112 | struct shrinker shrinker; |
| 113 | + struct work_struct shrink_work; | |
| 114 | + atomic_long_t need_shrink; | |
| 112 | 115 | }; |
| 113 | 116 | |
| 114 | 117 | /* |
| @@ -1634,8 +1637,7 @@ static unsigned long get_retain_buffers(struct dm_bufio_client *c) · 1519 unmodified lines | ||
| 1634 | 1637 | return retain_bytes; |
| 1635 | 1638 | } |
| 1636 | 1639 | |
| 1637 | −static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, | |
| 1638 | − gfp_t gfp_mask) | |
| 1640 | +static void __scan(struct dm_bufio_client *c) | |
| 1639 | 1641 | { |
| 1640 | 1642 | int l; |
| 1641 | 1643 | struct dm_buffer *b, *tmp; |
| @@ -1646,42 +1648,58 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, · 4 unmodified lines | ||
| 1646 | 1648 | |
| 1647 | 1649 | for (l = 0; l < LIST_SIZE; l++) { |
| 1648 | 1650 | list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) { |
| 1649 | − if (__try_evict_buffer(b, gfp_mask)) | |
| 1651 | + if (count - freed <= retain_target) | |
| 1652 | + atomic_long_set(&c->need_shrink, 0); | |
| 1653 | + if (!atomic_long_read(&c->need_shrink)) | |
| 1654 | + return; | |
| 1655 | + if (__try_evict_buffer(b, GFP_KERNEL)) { | |
| 1656 | + atomic_long_dec(&c->need_shrink); | |
| 1650 | 1657 | freed++; |
| 1651 | − if (!--nr_to_scan || ((count - freed) <= retain_target)) | |
| 1652 | − return freed; | |
| 1658 | + } | |
| 1653 | 1659 | cond_resched(); |
| 1654 | 1660 | } |
| 1655 | 1661 | } |
| 1656 | − return freed; | |
| 1657 | 1662 | } |
| 1658 | 1663 | |
| 1659 | −static unsigned long | |
| 1660 | −dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |
| 1664 | +static void shrink_work(struct work_struct *w) | |
| 1665 | +{ | |
| 1666 | + struct dm_bufio_client *c = container_of(w, struct dm_bufio_client, shrink_work); | |
| 1667 | + | |
| 1668 | + dm_bufio_lock(c); | |
| 1669 | + __scan(c); | |
| 1670 | + dm_bufio_unlock(c); | |
| 1671 | +} | |
| 1672 | + | |
| 1673 | +static unsigned long dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |
| 1661 | 1674 | { |
| 1662 | 1675 | struct dm_bufio_client *c; |
| 1663 | − unsigned long freed; | |
| 1664 | 1676 | |
| 1665 | 1677 | c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1666 | − if (sc->gfp_mask & __GFP_FS) | |
| 1667 | − dm_bufio_lock(c); | |
| 1668 | − else if (!dm_bufio_trylock(c)) | |
| 1669 | − return SHRINK_STOP; | |
| 1678 | + atomic_long_add(sc->nr_to_scan, &c->need_shrink); | |
| 1679 | + queue_work(dm_bufio_wq, &c->shrink_work); | |
| 1670 | 1680 | |
| 1671 | − freed = __scan(c, sc->nr_to_scan, sc->gfp_mask); | |
| 1672 | − dm_bufio_unlock(c); | |
| 1673 | − return freed; | |
| 1681 | + return sc->nr_to_scan; | |
| 1674 | 1682 | } |
| 1675 | 1683 | |
| 1676 | −static unsigned long | |
| 1677 | −dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) | |
| 1684 | +static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) | |
| 1678 | 1685 | { |
| 1679 | 1686 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1680 | 1687 | unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) + |
| 1681 | 1688 | READ_ONCE(c->n_buffers[LIST_DIRTY]); |
| 1682 | 1689 | unsigned long retain_target = get_retain_buffers(c); |
| 1690 | + unsigned long queued_for_cleanup = atomic_long_read(&c->need_shrink); | |
| 1691 | + | |
| 1692 | + if (unlikely(count < retain_target)) | |
| 1693 | + count = 0; | |
| 1694 | + else | |
| 1695 | + count -= retain_target; | |
| 1683 | 1696 | |
| 1684 | − return (count < retain_target) ? 0 : (count - retain_target); | |
| 1697 | + if (unlikely(count < queued_for_cleanup)) | |
| 1698 | + count = 0; | |
| 1699 | + else | |
| 1700 | + count -= queued_for_cleanup; | |
| 1701 | + | |
| 1702 | + return count; | |
| 1685 | 1703 | } |
| 1686 | 1704 | |
| 1687 | 1705 | /* |
| @@ -1772,6 +1790,9 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign · 84 unmodified lines | ||
| 1772 | 1790 | __free_buffer_wake(b); |
| 1773 | 1791 | } |
| 1774 | 1792 | |
| 1793 | + INIT_WORK(&c->shrink_work, shrink_work); | |
| 1794 | + atomic_long_set(&c->need_shrink, 0); | |
| 1795 | + | |
| 1775 | 1796 | c->shrinker.count_objects = dm_bufio_shrink_count; |
| 1776 | 1797 | c->shrinker.scan_objects = dm_bufio_shrink_scan; |
| 1777 | 1798 | c->shrinker.seeks = 1; |
| @@ -1817,6 +1838,7 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c) · 39 unmodified lines | ||
| 1817 | 1838 | drop_buffers(c); |
| 1818 | 1839 | |
| 1819 | 1840 | unregister_shrinker(&c->shrinker); |
| 1841 | + flush_work(&c->shrink_work); | |
| 1820 | 1842 | |
| 1821 | 1843 | mutex_lock(&dm_bufio_clients_lock); |
| 1822 | 1844 | |
| @@ -69,6 +69,7 @@ struct dm_crypt_io { · 68 unmodified lines | ||
| 69 | 69 | u8 *integrity_metadata; |
| 70 | 70 | bool integrity_metadata_from_pool; |
| 71 | 71 | struct work_struct work; |
| 72 | + struct tasklet_struct tasklet; | |
| 72 | 73 | |
| 73 | 74 | struct convert_context ctx; |
| 74 | 75 | |
| @@ -127,7 +128,9 @@ struct iv_elephant_private { · 52 unmodified lines | ||
| 127 | 128 | * and encrypts / decrypts at the same time. |
| 128 | 129 | */ |
| 129 | 130 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, |
| 130 | − DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD }; | |
| 131 | + DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD, | |
| 132 | + DM_CRYPT_NO_READ_WORKQUEUE, DM_CRYPT_NO_WRITE_WORKQUEUE, | |
| 133 | + DM_CRYPT_WRITE_INLINE }; | |
| 131 | 134 | |
| 132 | 135 | enum cipher_flags { |
| 133 | 136 | CRYPT_MODE_INTEGRITY_AEAD, /* Use authenticated mode for cihper */ |
| @@ -1523,7 +1526,7 @@ static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_ · 1389 unmodified lines | ||
| 1523 | 1526 | * Encrypt / decrypt data from one bio to another one (can be the same one) |
| 1524 | 1527 | */ |
| 1525 | 1528 | static blk_status_t crypt_convert(struct crypt_config *cc, |
| 1526 | − struct convert_context *ctx) | |
| 1529 | + struct convert_context *ctx, bool atomic) | |
| 1527 | 1530 | { |
| 1528 | 1531 | unsigned int tag_offset = 0; |
| 1529 | 1532 | unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; |
| @@ -1566,7 +1569,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, · 36 unmodified lines | ||
| 1566 | 1569 | atomic_dec(&ctx->cc_pending); |
| 1567 | 1570 | ctx->cc_sector += sector_step; |
| 1568 | 1571 | tag_offset++; |
| 1569 | − cond_resched(); | |
| 1572 | + if (!atomic) | |
| 1573 | + cond_resched(); | |
| 1570 | 1574 | continue; |
| 1571 | 1575 | /* |
| 1572 | 1576 | * There was a data integrity error. |
| @@ -1892,7 +1896,8 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async) · 319 unmodified lines | ||
| 1892 | 1896 | |
| 1893 | 1897 | clone->bi_iter.bi_sector = cc->start + io->sector; |
| 1894 | 1898 | |
| 1895 | − if (likely(!async) && test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) { | |
| 1899 | + if ((likely(!async) && test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) || | |
| 1900 | + test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags)) { | |
| 1896 | 1901 | submit_bio_noacct(clone); |
| 1897 | 1902 | return; |
| 1898 | 1903 | } |
| @@ -1915,9 +1920,32 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async) · 16 unmodified lines | ||
| 1915 | 1920 | spin_unlock_irqrestore(&cc->write_thread_lock, flags); |
| 1916 | 1921 | } |
| 1917 | 1922 | |
| 1923 | +static bool kcryptd_crypt_write_inline(struct crypt_config *cc, | |
| 1924 | + struct convert_context *ctx) | |
| 1925 | + | |
| 1926 | +{ | |
| 1927 | + if (!test_bit(DM_CRYPT_WRITE_INLINE, &cc->flags)) | |
| 1928 | + return false; | |
| 1929 | + | |
| 1930 | + /* | |
| 1931 | + * Note: zone append writes (REQ_OP_ZONE_APPEND) do not have ordering | |
| 1932 | + * constraints so they do not need to be issued inline by | |
| 1933 | + * kcryptd_crypt_write_convert(). | |
| 1934 | + */ | |
| 1935 | + switch (bio_op(ctx->bio_in)) { | |
| 1936 | + case REQ_OP_WRITE: | |
| 1937 | + case REQ_OP_WRITE_SAME: | |
| 1938 | + case REQ_OP_WRITE_ZEROES: | |
| 1939 | + return true; | |
| 1940 | + default: | |
| 1941 | + return false; | |
| 1942 | + } | |
| 1943 | +} | |
| 1944 | + | |
| 1918 | 1945 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) |
| 1919 | 1946 | { |
| 1920 | 1947 | struct crypt_config *cc = io->cc; |
| 1948 | + struct convert_context *ctx = &io->ctx; | |
| 1921 | 1949 | struct bio *clone; |
| 1922 | 1950 | int crypt_finished; |
| 1923 | 1951 | sector_t sector = io->sector; |
| @@ -1927,7 +1955,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) · 3 unmodified lines | ||
| 1927 | 1955 | * Prevent io from disappearing until this function completes. |
| 1928 | 1956 | */ |
| 1929 | 1957 | crypt_inc_pending(io); |
| 1930 | − crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, sector); | |
| 1958 | + crypt_convert_init(cc, ctx, NULL, io->base_bio, sector); | |
| 1931 | 1959 | |
| 1932 | 1960 | clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); |
| 1933 | 1961 | if (unlikely(!clone)) { |
| @@ -1941,10 +1969,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) · 7 unmodified lines | ||
| 1941 | 1969 | sector += bio_sectors(clone); |
| 1942 | 1970 | |
| 1943 | 1971 | crypt_inc_pending(io); |
| 1944 | − r = crypt_convert(cc, &io->ctx); | |
| 1972 | + r = crypt_convert(cc, ctx, | |
| 1973 | + test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags)); | |
| 1945 | 1974 | if (r) |
| 1946 | 1975 | io->error = r; |
| 1947 | − crypt_finished = atomic_dec_and_test(&io->ctx.cc_pending); | |
| 1976 | + crypt_finished = atomic_dec_and_test(&ctx->cc_pending); | |
| 1977 | + if (!crypt_finished && kcryptd_crypt_write_inline(cc, ctx)) { | |
| 1978 | + /* Wait for completion signaled by kcryptd_async_done() */ | |
| 1979 | + wait_for_completion(&ctx->restart); | |
| 1980 | + crypt_finished = 1; | |
| 1981 | + } | |
| 1948 | 1982 | |
| 1949 | 1983 | /* Encryption was already finished, submit io now */ |
| 1950 | 1984 | if (crypt_finished) { |
| @@ -1971,7 +2005,8 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) · 20 unmodified lines | ||
| 1971 | 2005 | crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, |
| 1972 | 2006 | io->sector); |
| 1973 | 2007 | |
| 1974 | − r = crypt_convert(cc, &io->ctx); | |
| 2008 | + r = crypt_convert(cc, &io->ctx, | |
| 2009 | + test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)); | |
| 1975 | 2010 | if (r) |
| 1976 | 2011 | io->error = r; |
| 1977 | 2012 | |
| @@ -2015,10 +2050,21 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, · 37 unmodified lines | ||
| 2015 | 2050 | if (!atomic_dec_and_test(&ctx->cc_pending)) |
| 2016 | 2051 | return; |
| 2017 | 2052 | |
| 2018 | − if (bio_data_dir(io->base_bio) == READ) | |
| 2053 | + /* | |
| 2054 | + * The request is fully completed: for inline writes, let | |
| 2055 | + * kcryptd_crypt_write_convert() do the IO submission. | |
| 2056 | + */ | |
| 2057 | + if (bio_data_dir(io->base_bio) == READ) { | |
| 2019 | 2058 | kcryptd_crypt_read_done(io); |
| 2020 | − else | |
| 2021 | − kcryptd_crypt_write_io_submit(io, 1); | |
| 2059 | + return; | |
| 2060 | + } | |
| 2061 | + | |
| 2062 | + if (kcryptd_crypt_write_inline(cc, ctx)) { | |
| 2063 | + complete(&ctx->restart); | |
| 2064 | + return; | |
| 2065 | + } | |
| 2066 | + | |
| 2067 | + kcryptd_crypt_write_io_submit(io, 1); | |
| 2022 | 2068 | } |
| 2023 | 2069 | |
| 2024 | 2070 | static void kcryptd_crypt(struct work_struct *work) |
| @@ -2031,10 +2077,28 @@ static void kcryptd_crypt(struct work_struct *work) · 6 unmodified lines | ||
| 2031 | 2077 | kcryptd_crypt_write_convert(io); |
| 2032 | 2078 | } |
| 2033 | 2079 | |
| 2080 | +static void kcryptd_crypt_tasklet(unsigned long work) | |
| 2081 | +{ | |
| 2082 | + kcryptd_crypt((struct work_struct *)work); | |
| 2083 | +} | |
| 2084 | + | |
| 2034 | 2085 | static void kcryptd_queue_crypt(struct dm_crypt_io *io) |
| 2035 | 2086 | { |
| 2036 | 2087 | struct crypt_config *cc = io->cc; |
| 2037 | 2088 | |
| 2089 | + if ((bio_data_dir(io->base_bio) == READ && test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) || | |
| 2090 | + (bio_data_dir(io->base_bio) == WRITE && test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags))) { | |
| 2091 | + if (in_irq()) { | |
| 2092 | + /* Crypto API's "skcipher_walk_first() refuses to work in hard IRQ context */ | |
| 2093 | + tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); | |
| 2094 | + tasklet_schedule(&io->tasklet); | |
| 2095 | + return; | |
| 2096 | + } | |
| 2097 | + | |
| 2098 | + kcryptd_crypt(&io->work); | |
| 2099 | + return; | |
| 2100 | + } | |
| 2101 | + | |
| 2038 | 2102 | INIT_WORK(&io->work, kcryptd_crypt); |
| 2039 | 2103 | queue_work(cc->crypt_queue, &io->work); |
| 2040 | 2104 | } |
| @@ -2838,7 +2902,7 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar · 797 unmodified lines | ||
| 2838 | 2902 | struct crypt_config *cc = ti->private; |
| 2839 | 2903 | struct dm_arg_set as; |
| 2840 | 2904 | static const struct dm_arg _args[] = { |
| 2841 | − {0, 6, "Invalid number of feature args"}, | |
| 2905 | + {0, 8, "Invalid number of feature args"}, | |
| 2842 | 2906 | }; |
| 2843 | 2907 | unsigned int opt_params, val; |
| 2844 | 2908 | const char *opt_string, *sval; |
| @@ -2868,6 +2932,10 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar · 23 unmodified lines | ||
| 2868 | 2932 | |
| 2869 | 2933 | else if (!strcasecmp(opt_string, "submit_from_crypt_cpus")) |
| 2870 | 2934 | set_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags); |
| 2935 | + else if (!strcasecmp(opt_string, "no_read_workqueue")) | |
| 2936 | + set_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags); | |
| 2937 | + else if (!strcasecmp(opt_string, "no_write_workqueue")) | |
| 2938 | + set_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags); | |
| 2871 | 2939 | else if (sscanf(opt_string, "integrity:%u:", &val) == 1) { |
| 2872 | 2940 | if (val == 0 || val > MAX_TAG_SIZE) { |
| 2873 | 2941 | ti->error = "Invalid integrity arguments"; |
| @@ -2908,6 +2976,21 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar · 34 unmodified lines | ||
| 2908 | 2976 | return 0; |
| 2909 | 2977 | } |
| 2910 | 2978 | |
| 2979 | +#ifdef CONFIG_BLK_DEV_ZONED | |
| 2980 | + | |
| 2981 | +static int crypt_report_zones(struct dm_target *ti, | |
| 2982 | + struct dm_report_zones_args *args, unsigned int nr_zones) | |
| 2983 | +{ | |
| 2984 | + struct crypt_config *cc = ti->private; | |
| 2985 | + sector_t sector = cc->start + dm_target_offset(ti, args->next_sector); | |
| 2986 | + | |
| 2987 | + args->start = cc->start; | |
| 2988 | + return blkdev_report_zones(cc->dev->bdev, sector, nr_zones, | |
| 2989 | + dm_report_zones_cb, args); | |
| 2990 | +} | |
| 2991 | + | |
| 2992 | +#endif | |
| 2993 | + | |
| 2911 | 2994 | /* |
| 2912 | 2995 | * Construct an encryption mapping: |
| 2913 | 2996 | * <cipher> [<key>|:<key_size>:<user|logon>:<key_description>] <iv_offset> <dev_path> <start> |
| @@ -3041,6 +3124,16 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 127 unmodified lines | ||
| 3041 | 3124 | } |
| 3042 | 3125 | cc->start = tmpll; |
| 3043 | 3126 | |
| 3127 | + /* | |
| 3128 | + * For zoned block devices, we need to preserve the issuer write | |
| 3129 | + * ordering. To do so, disable write workqueues and force inline | |
| 3130 | + * encryption completion. | |
| 3131 | + */ | |
| 3132 | + if (bdev_is_zoned(cc->dev->bdev)) { | |
| 3133 | + set_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags); | |
| 3134 | + set_bit(DM_CRYPT_WRITE_INLINE, &cc->flags); | |
| 3135 | + } | |
| 3136 | + | |
| 3044 | 3137 | if (crypt_integrity_aead(cc) || cc->integrity_iv_size) { |
| 3045 | 3138 | ret = crypt_integrity_ctr(cc, ti); |
| 3046 | 3139 | if (ret) |
| @@ -3196,6 +3289,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type, · 149 unmodified lines | ||
| 3196 | 3289 | num_feature_args += !!ti->num_discard_bios; |
| 3197 | 3290 | num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags); |
| 3198 | 3291 | num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags); |
| 3292 | + num_feature_args += test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags); | |
| 3293 | + num_feature_args += test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags); | |
| 3199 | 3294 | num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT); |
| 3200 | 3295 | num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); |
| 3201 | 3296 | if (cc->on_disk_tag_size) |
| @@ -3208,6 +3303,10 @@ static void crypt_status(struct dm_target *ti, status_type_t type, · 6 unmodified lines | ||
| 3208 | 3303 | DMEMIT(" same_cpu_crypt"); |
| 3209 | 3304 | if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) |
| 3210 | 3305 | DMEMIT(" submit_from_crypt_cpus"); |
| 3306 | + if (test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) | |
| 3307 | + DMEMIT(" no_read_workqueue"); | |
| 3308 | + if (test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags)) | |
| 3309 | + DMEMIT(" no_write_workqueue"); | |
| 3211 | 3310 | if (cc->on_disk_tag_size) |
| 3212 | 3311 | DMEMIT(" integrity:%u:%s", cc->on_disk_tag_size, cc->cipher_auth); |
| 3213 | 3312 | if (cc->sector_size != (1 << SECTOR_SHIFT)) |
| @@ -3320,10 +3419,14 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits) · 106 unmodified lines | ||
| 3320 | 3419 | |
| 3321 | 3420 | static struct target_type crypt_target = { |
| 3322 | 3421 | .name = "crypt", |
| 3323 | − .version = {1, 21, 0}, | |
| 3422 | + .version = {1, 22, 0}, | |
| 3324 | 3423 | .module = THIS_MODULE, |
| 3325 | 3424 | .ctr = crypt_ctr, |
| 3326 | 3425 | .dtr = crypt_dtr, |
| 3426 | +#ifdef CONFIG_BLK_DEV_ZONED | |
| 3427 | + .features = DM_TARGET_ZONED_HM, | |
| 3428 | + .report_zones = crypt_report_zones, | |
| 3429 | +#endif | |
| 3327 | 3430 | .map = crypt_map, |
| 3328 | 3431 | .status = crypt_status, |
| 3329 | 3432 | .postsuspend = crypt_postsuspend, |
| @@ -138,20 +138,22 @@ static int dust_add_block(struct dust_device *dd, unsigned long long block, · 137 unmodified lines | ||
| 138 | 138 | return 0; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | −static int dust_query_block(struct dust_device *dd, unsigned long long block) | |
| 141 | +static int dust_query_block(struct dust_device *dd, unsigned long long block, char *result, | |
| 142 | + unsigned int maxlen, unsigned int *sz_ptr) | |
| 142 | 143 | { |
| 143 | 144 | struct badblock *bblock; |
| 144 | 145 | unsigned long flags; |
| 146 | + unsigned int sz = *sz_ptr; | |
| 145 | 147 | |
| 146 | 148 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 147 | 149 | bblock = dust_rb_search(&dd->badblocklist, block); |
| 148 | 150 | if (bblock != NULL) |
| 149 | − DMINFO("%s: block %llu found in badblocklist", __func__, block); | |
| 151 | + DMEMIT("%s: block %llu found in badblocklist", __func__, block); | |
| 150 | 152 | else |
| 151 | − DMINFO("%s: block %llu not found in badblocklist", __func__, block); | |
| 153 | + DMEMIT("%s: block %llu not found in badblocklist", __func__, block); | |
| 152 | 154 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 153 | 155 | |
| 154 | − return 0; | |
| 156 | + return 1; | |
| 155 | 157 | } |
| 156 | 158 | |
| 157 | 159 | static int __dust_map_read(struct dust_device *dd, sector_t thisblock) |
| @@ -259,11 +261,13 @@ static bool __dust_clear_badblocks(struct rb_root *tree, · 101 unmodified lines | ||
| 259 | 261 | return true; |
| 260 | 262 | } |
| 261 | 263 | |
| 262 | −static int dust_clear_badblocks(struct dust_device *dd) | |
| 264 | +static int dust_clear_badblocks(struct dust_device *dd, char *result, unsigned int maxlen, | |
| 265 | + unsigned int *sz_ptr) | |
| 263 | 266 | { |
| 264 | 267 | unsigned long flags; |
| 265 | 268 | struct rb_root badblocklist; |
| 266 | 269 | unsigned long long badblock_count; |
| 270 | + unsigned int sz = *sz_ptr; | |
| 267 | 271 | |
| 268 | 272 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 269 | 273 | badblocklist = dd->badblocklist; |
| @@ -273,11 +277,36 @@ static int dust_clear_badblocks(struct dust_device *dd) · 3 unmodified lines | ||
| 273 | 277 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 274 | 278 | |
| 275 | 279 | if (!__dust_clear_badblocks(&badblocklist, badblock_count)) |
| 276 | − DMINFO("%s: no badblocks found", __func__); | |
| 280 | + DMEMIT("%s: no badblocks found", __func__); | |
| 277 | 281 | else |
| 278 | − DMINFO("%s: badblocks cleared", __func__); | |
| 282 | + DMEMIT("%s: badblocks cleared", __func__); | |
| 279 | 283 | |
| 280 | − return 0; | |
| 284 | + return 1; | |
| 285 | +} | |
| 286 | + | |
| 287 | +static int dust_list_badblocks(struct dust_device *dd, char *result, unsigned int maxlen, | |
| 288 | + unsigned int *sz_ptr) | |
| 289 | +{ | |
| 290 | + unsigned long flags; | |
| 291 | + struct rb_root badblocklist; | |
| 292 | + struct rb_node *node; | |
| 293 | + struct badblock *bblk; | |
| 294 | + unsigned int sz = *sz_ptr; | |
| 295 | + unsigned long long num = 0; | |
| 296 | + | |
| 297 | + spin_lock_irqsave(&dd->dust_lock, flags); | |
| 298 | + badblocklist = dd->badblocklist; | |
| 299 | + for (node = rb_first(&badblocklist); node; node = rb_next(node)) { | |
| 300 | + bblk = rb_entry(node, struct badblock, node); | |
| 301 | + DMEMIT("%llu\n", bblk->bb); | |
| 302 | + num++; | |
| 303 | + } | |
| 304 | + | |
| 305 | + spin_unlock_irqrestore(&dd->dust_lock, flags); | |
| 306 | + if (!num) | |
| 307 | + DMEMIT("No blocks in badblocklist"); | |
| 308 | + | |
| 309 | + return 1; | |
| 281 | 310 | } |
| 282 | 311 | |
| 283 | 312 | /* |
| @@ -383,7 +412,7 @@ static void dust_dtr(struct dm_target *ti) · 99 unmodified lines | ||
| 383 | 412 | } |
| 384 | 413 | |
| 385 | 414 | static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, |
| 386 | − char *result_buf, unsigned int maxlen) | |
| 415 | + char *result, unsigned int maxlen) | |
| 387 | 416 | { |
| 388 | 417 | struct dust_device *dd = ti->private; |
| 389 | 418 | sector_t size = i_size_read(dd->dev->bdev->bd_inode) >> SECTOR_SHIFT; |
| @@ -393,6 +422,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, · 3 unmodified lines | ||
| 393 | 422 | unsigned char wr_fail_cnt; |
| 394 | 423 | unsigned int tmp_ui; |
| 395 | 424 | unsigned long flags; |
| 425 | + unsigned int sz = 0; | |
| 396 | 426 | char dummy; |
| 397 | 427 | |
| 398 | 428 | if (argc == 1) { |
| @@ -410,18 +440,20 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, · 11 unmodified lines | ||
| 410 | 440 | r = 0; |
| 411 | 441 | } else if (!strcasecmp(argv[0], "countbadblocks")) { |
| 412 | 442 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 413 | − DMINFO("countbadblocks: %llu badblock(s) found", | |
| 443 | + DMEMIT("countbadblocks: %llu badblock(s) found", | |
| 414 | 444 | dd->badblock_count); |
| 415 | 445 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 416 | − r = 0; | |
| 446 | + r = 1; | |
| 417 | 447 | } else if (!strcasecmp(argv[0], "clearbadblocks")) { |
| 418 | − r = dust_clear_badblocks(dd); | |
| 448 | + r = dust_clear_badblocks(dd, result, maxlen, &sz); | |
| 419 | 449 | } else if (!strcasecmp(argv[0], "quiet")) { |
| 420 | 450 | if (!dd->quiet_mode) |
| 421 | 451 | dd->quiet_mode = true; |
| 422 | 452 | else |
| 423 | 453 | dd->quiet_mode = false; |
| 424 | 454 | r = 0; |
| 455 | + } else if (!strcasecmp(argv[0], "listbadblocks")) { | |
| 456 | + r = dust_list_badblocks(dd, result, maxlen, &sz); | |
| 425 | 457 | } else { |
| 426 | 458 | invalid_msg = true; |
| 427 | 459 | } |
| @@ -441,7 +473,7 @@ static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, · 13 unmodified lines | ||
| 441 | 473 | else if (!strcasecmp(argv[0], "removebadblock")) |
| 442 | 474 | r = dust_remove_block(dd, block); |
| 443 | 475 | else if (!strcasecmp(argv[0], "queryblock")) |
| 444 | − r = dust_query_block(dd, block); | |
| 476 | + r = dust_query_block(dd, block, result, maxlen, &sz); | |
| 445 | 477 | else |
| 446 | 478 | invalid_msg = true; |
| 447 | 479 | |
| @@ -363,7 +363,7 @@ static int ebs_map(struct dm_target *ti, struct bio *bio) · 362 unmodified lines | ||
| 363 | 363 | bio_set_dev(bio, ec->dev->bdev); |
| 364 | 364 | bio->bi_iter.bi_sector = ec->start + dm_target_offset(ti, bio->bi_iter.bi_sector); |
| 365 | 365 | |
| 366 | − if (unlikely(bio->bi_opf & REQ_OP_FLUSH)) | |
| 366 | + if (unlikely(bio_op(bio) == REQ_OP_FLUSH)) | |
| 367 | 367 | return DM_MAPIO_REMAPPED; |
| 368 | 368 | /* |
| 369 | 369 | * Only queue for bufio processing in case of partial or overlapping buffers |
| @@ -36,7 +36,7 @@ struct dm_device { · 35 unmodified lines | ||
| 36 | 36 | struct list_head list; |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | −const char * const dm_allowed_targets[] __initconst = { | |
| 39 | +static const char * const dm_allowed_targets[] __initconst = { | |
| 40 | 40 | "crypt", |
| 41 | 41 | "delay", |
| 42 | 42 | "linear", |
| @@ -1168,7 +1168,7 @@ static void retrieve_status(struct dm_table *table, · 1167 unmodified lines | ||
| 1168 | 1168 | spec->sector_start = ti->begin; |
| 1169 | 1169 | spec->length = ti->len; |
| 1170 | 1170 | strncpy(spec->target_type, ti->type->name, |
| 1171 | − sizeof(spec->target_type)); | |
| 1171 | + sizeof(spec->target_type) - 1); | |
| 1172 | 1172 | |
| 1173 | 1173 | outptr += sizeof(struct dm_target_spec); |
| 1174 | 1174 | remaining = len - (outptr - outbuf); |
| @@ -128,6 +128,20 @@ static void queue_if_no_path_timeout_work(struct timer_list *t); · 127 unmodified lines | ||
| 128 | 128 | #define MPATHF_PG_INIT_REQUIRED 5 /* pg_init needs calling? */ |
| 129 | 129 | #define MPATHF_PG_INIT_DELAY_RETRY 6 /* Delay pg_init retry? */ |
| 130 | 130 | |
| 131 | +static bool mpath_double_check_test_bit(int MPATHF_bit, struct multipath *m) | |
| 132 | +{ | |
| 133 | + bool r = test_bit(MPATHF_bit, &m->flags); | |
| 134 | + | |
| 135 | + if (r) { | |
| 136 | + unsigned long flags; | |
| 137 | + spin_lock_irqsave(&m->lock, flags); | |
| 138 | + r = test_bit(MPATHF_bit, &m->flags); | |
| 139 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 140 | + } | |
| 141 | + | |
| 142 | + return r; | |
| 143 | +} | |
| 144 | + | |
| 131 | 145 | /*----------------------------------------------- |
| 132 | 146 | * Allocation routines |
| 133 | 147 | *-----------------------------------------------*/ |
| @@ -335,6 +349,8 @@ static int pg_init_all_paths(struct multipath *m) · 201 unmodified lines | ||
| 335 | 349 | |
| 336 | 350 | static void __switch_pg(struct multipath *m, struct priority_group *pg) |
| 337 | 351 | { |
| 352 | + lockdep_assert_held(&m->lock); | |
| 353 | + | |
| 338 | 354 | m->current_pg = pg; |
| 339 | 355 | |
| 340 | 356 | /* Must we initialise the PG first, and queue I/O till it's ready? */ |
| @@ -382,7 +398,9 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes) · 41 unmodified lines | ||
| 382 | 398 | unsigned bypassed = 1; |
| 383 | 399 | |
| 384 | 400 | if (!atomic_read(&m->nr_valid_paths)) { |
| 401 | + spin_lock_irqsave(&m->lock, flags); | |
| 385 | 402 | clear_bit(MPATHF_QUEUE_IO, &m->flags); |
| 403 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 386 | 404 | goto failed; |
| 387 | 405 | } |
| 388 | 406 | |
| @@ -422,8 +440,11 @@ check_current_pg: · 33 unmodified lines | ||
| 422 | 440 | continue; |
| 423 | 441 | pgpath = choose_path_in_pg(m, pg, nr_bytes); |
| 424 | 442 | if (!IS_ERR_OR_NULL(pgpath)) { |
| 425 | − if (!bypassed) | |
| 443 | + if (!bypassed) { | |
| 444 | + spin_lock_irqsave(&m->lock, flags); | |
| 426 | 445 | set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags); |
| 446 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 447 | + } | |
| 427 | 448 | return pgpath; |
| 428 | 449 | } |
| 429 | 450 | } |
| @@ -465,7 +486,14 @@ static bool __must_push_back(struct multipath *m) · 35 unmodified lines | ||
| 465 | 486 | |
| 466 | 487 | static bool must_push_back_rq(struct multipath *m) |
| 467 | 488 | { |
| 468 | − return test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) || __must_push_back(m); | |
| 489 | + unsigned long flags; | |
| 490 | + bool ret; | |
| 491 | + | |
| 492 | + spin_lock_irqsave(&m->lock, flags); | |
| 493 | + ret = (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) || __must_push_back(m)); | |
| 494 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 495 | + | |
| 496 | + return ret; | |
| 469 | 497 | } |
| 470 | 498 | |
| 471 | 499 | /* |
| @@ -485,7 +513,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, · 13 unmodified lines | ||
| 485 | 513 | |
| 486 | 514 | /* Do we need to select a new pgpath? */ |
| 487 | 515 | pgpath = READ_ONCE(m->current_pgpath); |
| 488 | − if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 516 | + if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) | |
| 489 | 517 | pgpath = choose_pgpath(m, nr_bytes); |
| 490 | 518 | |
| 491 | 519 | if (!pgpath) { |
| @@ -493,8 +521,8 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, · 1 unmodified line | ||
| 493 | 521 | return DM_MAPIO_DELAY_REQUEUE; |
| 494 | 522 | dm_report_EIO(m); /* Failed */ |
| 495 | 523 | return DM_MAPIO_KILL; |
| 496 | − } else if (test_bit(MPATHF_QUEUE_IO, &m->flags) || | |
| 497 | − test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) { | |
| 524 | + } else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) || | |
| 525 | + mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) { | |
| 498 | 526 | pg_init_all_paths(m); |
| 499 | 527 | return DM_MAPIO_DELAY_REQUEUE; |
| 500 | 528 | } |
| @@ -560,33 +588,45 @@ static void multipath_release_clone(struct request *clone, · 59 unmodified lines | ||
| 560 | 588 | * Map cloned bios (bio-based multipath) |
| 561 | 589 | */ |
| 562 | 590 | |
| 591 | +static void __multipath_queue_bio(struct multipath *m, struct bio *bio) | |
| 592 | +{ | |
| 593 | + /* Queue for the daemon to resubmit */ | |
| 594 | + bio_list_add(&m->queued_bios, bio); | |
| 595 | + if (!test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 596 | + queue_work(kmultipathd, &m->process_queued_bios); | |
| 597 | +} | |
| 598 | + | |
| 599 | +static void multipath_queue_bio(struct multipath *m, struct bio *bio) | |
| 600 | +{ | |
| 601 | + unsigned long flags; | |
| 602 | + | |
| 603 | + spin_lock_irqsave(&m->lock, flags); | |
| 604 | + __multipath_queue_bio(m, bio); | |
| 605 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 606 | +} | |
| 607 | + | |
| 563 | 608 | static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) |
| 564 | 609 | { |
| 565 | 610 | struct pgpath *pgpath; |
| 566 | 611 | unsigned long flags; |
| 567 | − bool queue_io; | |
| 568 | 612 | |
| 569 | 613 | /* Do we need to select a new pgpath? */ |
| 570 | 614 | pgpath = READ_ONCE(m->current_pgpath); |
| 571 | − if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 615 | + if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) | |
| 572 | 616 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
| 573 | 617 | |
| 574 | − /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ | |
| 575 | − queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 576 | − | |
| 577 | − if ((pgpath && queue_io) || | |
| 578 | − (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { | |
| 579 | − /* Queue for the daemon to resubmit */ | |
| 618 | + if (!pgpath) { | |
| 580 | 619 | spin_lock_irqsave(&m->lock, flags); |
| 581 | − bio_list_add(&m->queued_bios, bio); | |
| 620 | + if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | |
| 621 | + __multipath_queue_bio(m, bio); | |
| 622 | + pgpath = ERR_PTR(-EAGAIN); | |
| 623 | + } | |
| 582 | 624 | spin_unlock_irqrestore(&m->lock, flags); |
| 583 | 625 | |
| 584 | − /* PG_INIT_REQUIRED cannot be set without QUEUE_IO */ | |
| 585 | − if (queue_io || test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) | |
| 586 | − pg_init_all_paths(m); | |
| 587 | − else if (!queue_io) | |
| 588 | − queue_work(kmultipathd, &m->process_queued_bios); | |
| 589 | − | |
| 626 | + } else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) || | |
| 627 | + mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) { | |
| 628 | + multipath_queue_bio(m, bio); | |
| 629 | + pg_init_all_paths(m); | |
| 590 | 630 | return ERR_PTR(-EAGAIN); |
| 591 | 631 | } |
| 592 | 632 | |
| @@ -835,7 +875,7 @@ static int setup_scsi_dh(struct block_device *bdev, struct multipath *m, · 242 unmodified lines | ||
| 835 | 875 | struct request_queue *q = bdev_get_queue(bdev); |
| 836 | 876 | int r; |
| 837 | 877 | |
| 838 | − if (test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags)) { | |
| 878 | + if (mpath_double_check_test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, m)) { | |
| 839 | 879 | retain: |
| 840 | 880 | if (*attached_handler_name) { |
| 841 | 881 | /* |
| @@ -1614,7 +1654,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, · 772 unmodified lines | ||
| 1614 | 1654 | if (pgpath) |
| 1615 | 1655 | fail_path(pgpath); |
| 1616 | 1656 | |
| 1617 | − if (atomic_read(&m->nr_valid_paths) == 0 && | |
| 1657 | + if (!atomic_read(&m->nr_valid_paths) && | |
| 1618 | 1658 | !must_push_back_rq(m)) { |
| 1619 | 1659 | if (error == BLK_STS_IOERR) |
| 1620 | 1660 | dm_report_EIO(m); |
| @@ -1649,23 +1689,22 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, · 28 unmodified lines | ||
| 1649 | 1689 | if (pgpath) |
| 1650 | 1690 | fail_path(pgpath); |
| 1651 | 1691 | |
| 1652 | − if (atomic_read(&m->nr_valid_paths) == 0 && | |
| 1653 | − !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | |
| 1654 | − if (__must_push_back(m)) { | |
| 1655 | − r = DM_ENDIO_REQUEUE; | |
| 1656 | − } else { | |
| 1657 | − dm_report_EIO(m); | |
| 1658 | − *error = BLK_STS_IOERR; | |
| 1692 | + if (!atomic_read(&m->nr_valid_paths)) { | |
| 1693 | + spin_lock_irqsave(&m->lock, flags); | |
| 1694 | + if (!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | |
| 1695 | + if (__must_push_back(m)) { | |
| 1696 | + r = DM_ENDIO_REQUEUE; | |
| 1697 | + } else { | |
| 1698 | + dm_report_EIO(m); | |
| 1699 | + *error = BLK_STS_IOERR; | |
| 1700 | + } | |
| 1701 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 1702 | + goto done; | |
| 1659 | 1703 | } |
| 1660 | − goto done; | |
| 1704 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 1661 | 1705 | } |
| 1662 | 1706 | |
| 1663 | − spin_lock_irqsave(&m->lock, flags); | |
| 1664 | − bio_list_add(&m->queued_bios, clone); | |
| 1665 | − spin_unlock_irqrestore(&m->lock, flags); | |
| 1666 | − if (!test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 1667 | − queue_work(kmultipathd, &m->process_queued_bios); | |
| 1668 | − | |
| 1707 | + multipath_queue_bio(m, clone); | |
| 1669 | 1708 | r = DM_ENDIO_INCOMPLETE; |
| 1670 | 1709 | done: |
| 1671 | 1710 | if (pgpath) { |
| @@ -1937,16 +1976,17 @@ static int multipath_prepare_ioctl(struct dm_target *ti, · 265 unmodified lines | ||
| 1937 | 1976 | struct block_device **bdev) |
| 1938 | 1977 | { |
| 1939 | 1978 | struct multipath *m = ti->private; |
| 1940 | − struct pgpath *current_pgpath; | |
| 1979 | + struct pgpath *pgpath; | |
| 1980 | + unsigned long flags; | |
| 1941 | 1981 | int r; |
| 1942 | 1982 | |
| 1943 | − current_pgpath = READ_ONCE(m->current_pgpath); | |
| 1944 | − if (!current_pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 1945 | − current_pgpath = choose_pgpath(m, 0); | |
| 1983 | + pgpath = READ_ONCE(m->current_pgpath); | |
| 1984 | + if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) | |
| 1985 | + pgpath = choose_pgpath(m, 0); | |
| 1946 | 1986 | |
| 1947 | − if (current_pgpath) { | |
| 1948 | − if (!test_bit(MPATHF_QUEUE_IO, &m->flags)) { | |
| 1949 | − *bdev = current_pgpath->path.dev->bdev; | |
| 1987 | + if (pgpath) { | |
| 1988 | + if (!mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) { | |
| 1989 | + *bdev = pgpath->path.dev->bdev; | |
| 1950 | 1990 | r = 0; |
| 1951 | 1991 | } else { |
| 1952 | 1992 | /* pg_init has not started or completed */ |
| @@ -1954,10 +1994,11 @@ static int multipath_prepare_ioctl(struct dm_target *ti, · 1 unmodified line | ||
| 1954 | 1994 | } |
| 1955 | 1995 | } else { |
| 1956 | 1996 | /* No path is available */ |
| 1997 | + r = -EIO; | |
| 1998 | + spin_lock_irqsave(&m->lock, flags); | |
| 1957 | 1999 | if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) |
| 1958 | 2000 | r = -ENOTCONN; |
| 1959 | − else | |
| 1960 | − r = -EIO; | |
| 2001 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 1961 | 2002 | } |
| 1962 | 2003 | |
| 1963 | 2004 | if (r == -ENOTCONN) { |
| @@ -1965,8 +2006,10 @@ static int multipath_prepare_ioctl(struct dm_target *ti, · 1 unmodified line | ||
| 1965 | 2006 | /* Path status changed, redo selection */ |
| 1966 | 2007 | (void) choose_pgpath(m, 0); |
| 1967 | 2008 | } |
| 2009 | + spin_lock_irqsave(&m->lock, flags); | |
| 1968 | 2010 | if (test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) |
| 1969 | − pg_init_all_paths(m); | |
| 2011 | + (void) __pg_init_all_paths(m); | |
| 2012 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 1970 | 2013 | dm_table_run_md_queue_async(m->ti->table); |
| 1971 | 2014 | process_queued_io_list(m); |
| 1972 | 2015 | } |
| @@ -2026,8 +2069,15 @@ static int multipath_busy(struct dm_target *ti) · 53 unmodified lines | ||
| 2026 | 2069 | return true; |
| 2027 | 2070 | |
| 2028 | 2071 | /* no paths available, for blk-mq: rely on IO mapping to delay requeue */ |
| 2029 | − if (!atomic_read(&m->nr_valid_paths) && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | |
| 2030 | − return (m->queue_mode != DM_TYPE_REQUEST_BASED); | |
| 2072 | + if (!atomic_read(&m->nr_valid_paths)) { | |
| 2073 | + unsigned long flags; | |
| 2074 | + spin_lock_irqsave(&m->lock, flags); | |
| 2075 | + if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | |
| 2076 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 2077 | + return (m->queue_mode != DM_TYPE_REQUEST_BASED); | |
| 2078 | + } | |
| 2079 | + spin_unlock_irqrestore(&m->lock, flags); | |
| 2080 | + } | |
| 2031 | 2081 | |
| 2032 | 2082 | /* Guess which priority_group will be used at next mapping time */ |
| 2033 | 2083 | pg = READ_ONCE(m->current_pg); |
| @@ -2337,8 +2337,6 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) · 2336 unmodified lines | ||
| 2337 | 2337 | |
| 2338 | 2338 | if (new_devs == rs->raid_disks || !rebuilds) { |
| 2339 | 2339 | /* Replace a broken device */ |
| 2340 | − if (new_devs == 1 && !rs->delta_disks) | |
| 2341 | − ; | |
| 2342 | 2340 | if (new_devs == rs->raid_disks) { |
| 2343 | 2341 | DMINFO("Superblocks created for new raid set"); |
| 2344 | 2342 | set_bit(MD_ARRAY_FIRST_USE, &mddev->flags); |
| @@ -70,9 +70,6 @@ void dm_start_queue(struct request_queue *q) · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | void dm_stop_queue(struct request_queue *q) |
| 72 | 72 | { |
| 73 | − if (blk_mq_queue_stopped(q)) | |
| 74 | − return; | |
| 75 | − | |
| 76 | 73 | blk_mq_quiesce_queue(q); |
| 77 | 74 | } |
| 78 | 75 | |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | #define DM_VERITY_OPT_LOGGING "ignore_corruption" |
| 32 | 32 | #define DM_VERITY_OPT_RESTART "restart_on_corruption" |
| 33 | +#define DM_VERITY_OPT_PANIC "panic_on_corruption" | |
| 33 | 34 | #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" |
| 34 | 35 | #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" |
| 35 | 36 | |
| @@ -254,6 +255,9 @@ out: · 218 unmodified lines | ||
| 254 | 255 | if (v->mode == DM_VERITY_MODE_RESTART) |
| 255 | 256 | kernel_restart("dm-verity device corrupted"); |
| 256 | 257 | |
| 258 | + if (v->mode == DM_VERITY_MODE_PANIC) | |
| 259 | + panic("dm-verity device corrupted"); | |
| 260 | + | |
| 257 | 261 | return 1; |
| 258 | 262 | } |
| 259 | 263 | |
| @@ -742,6 +746,9 @@ static void verity_status(struct dm_target *ti, status_type_t type, · 482 unmodified lines | ||
| 742 | 746 | case DM_VERITY_MODE_RESTART: |
| 743 | 747 | DMEMIT(DM_VERITY_OPT_RESTART); |
| 744 | 748 | break; |
| 749 | + case DM_VERITY_MODE_PANIC: | |
| 750 | + DMEMIT(DM_VERITY_OPT_PANIC); | |
| 751 | + break; | |
| 745 | 752 | default: |
| 746 | 753 | BUG(); |
| 747 | 754 | } |
| @@ -907,6 +914,10 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, · 159 unmodified lines | ||
| 907 | 914 | v->mode = DM_VERITY_MODE_RESTART; |
| 908 | 915 | continue; |
| 909 | 916 | |
| 917 | + } else if (!strcasecmp(arg_name, DM_VERITY_OPT_PANIC)) { | |
| 918 | + v->mode = DM_VERITY_MODE_PANIC; | |
| 919 | + continue; | |
| 920 | + | |
| 910 | 921 | } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { |
| 911 | 922 | r = verity_alloc_zero_digest(v); |
| 912 | 923 | if (r) { |
| @@ -1221,7 +1232,7 @@ bad: · 308 unmodified lines | ||
| 1221 | 1232 | |
| 1222 | 1233 | static struct target_type verity_target = { |
| 1223 | 1234 | .name = "verity", |
| 1224 | − .version = {1, 6, 0}, | |
| 1235 | + .version = {1, 7, 0}, | |
| 1225 | 1236 | .module = THIS_MODULE, |
| 1226 | 1237 | .ctr = verity_ctr, |
| 1227 | 1238 | .dtr = verity_dtr, |
| @@ -34,25 +34,25 @@ void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts); · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0 |
| 36 | 36 | |
| 37 | −int verity_verify_root_hash(const void *data, size_t data_len, | |
| 38 | − const void *sig_data, size_t sig_len) | |
| 37 | +static inline int verity_verify_root_hash(const void *data, size_t data_len, | |
| 38 | + const void *sig_data, size_t sig_len) | |
| 39 | 39 | { |
| 40 | 40 | return 0; |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | −bool verity_verify_is_sig_opt_arg(const char *arg_name) | |
| 43 | +static inline bool verity_verify_is_sig_opt_arg(const char *arg_name) | |
| 44 | 44 | { |
| 45 | 45 | return false; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | −int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, | |
| 49 | − struct dm_verity_sig_opts *sig_opts, | |
| 50 | − unsigned int *argc, const char *arg_name) | |
| 48 | +static inline int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, | |
| 49 | + struct dm_verity *v, struct dm_verity_sig_opts *sig_opts, | |
| 50 | + unsigned int *argc, const char *arg_name) | |
| 51 | 51 | { |
| 52 | 52 | return -EINVAL; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | −void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts) | |
| 55 | +static inline void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts) | |
| 56 | 56 | { |
| 57 | 57 | } |
| 58 | 58 | |
| @@ -20,7 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | enum verity_mode { |
| 21 | 21 | DM_VERITY_MODE_EIO, |
| 22 | 22 | DM_VERITY_MODE_LOGGING, |
| 23 | − DM_VERITY_MODE_RESTART | |
| 23 | + DM_VERITY_MODE_RESTART, | |
| 24 | + DM_VERITY_MODE_PANIC | |
| 24 | 25 | }; |
| 25 | 26 | |
| 26 | 27 | enum verity_block_type { |
| @@ -504,7 +504,8 @@ static int dm_blk_report_zones(struct gendisk *disk, sector_t sector, · 503 unmodified lines | ||
| 504 | 504 | } |
| 505 | 505 | |
| 506 | 506 | args.tgt = tgt; |
| 507 | − ret = tgt->type->report_zones(tgt, &args, nr_zones); | |
| 507 | + ret = tgt->type->report_zones(tgt, &args, | |
| 508 | + nr_zones - args.zone_idx); | |
| 508 | 509 | if (ret < 0) |
| 509 | 510 | goto out; |
| 510 | 511 | } while (args.zone_idx < nr_zones && |