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 | $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096' | 69 | $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096' |
| 70 | 70 | ||
| 71 | Check the status of the read behavior ("bypass" indicates that all I/O | 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 | $ sudo dmsetup status dust1 | 75 | $ sudo dmsetup status dust1 |
| 75 | 0 33552384 dust 252:17 bypass | 76 | 0 33552384 dust 252:17 bypass verbose |
| 76 | 77 | ||
| 77 | $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct | 78 | $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct |
| 78 | 128+0 records in | 79 | 128+0 records in |
| @@ -164,7 +165,7 @@ following message command:: · 85 unmodified lines | |||
| 164 | A message will print with the number of bad blocks currently | 165 | A message will print with the number of bad blocks currently |
| 165 | configured on the device:: | 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 | Querying for specific bad blocks | 170 | Querying for specific bad blocks |
| 170 | -------------------------------- | 171 | -------------------------------- |
| @@ -176,11 +177,11 @@ following message command:: · 5 unmodified lines | |||
| 176 | 177 | ||
| 177 | The following message will print if the block is in the list:: | 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 | The following message will print if the block is not in the list:: | 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 | The "queryblock" message command will work in both the "enabled" | 186 | The "queryblock" message command will work in both the "enabled" |
| 186 | and "disabled" modes, allowing the verification of whether a block | 187 | and "disabled" modes, allowing the verification of whether a block |
| @@ -198,12 +199,28 @@ following message command:: · 11 unmodified lines | |||
| 198 | 199 | ||
| 199 | After clearing the bad block list, the following message will appear:: | 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 | If there were no bad blocks to clear, the following message will | 204 | If there were no bad blocks to clear, the following message will |
| 204 | appear:: | 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 | Message commands list | 225 | Message commands list |
| 209 | --------------------- | 226 | --------------------- |
| @@ -223,6 +240,7 @@ Single argument message commands:: · 13 unmodified lines | |||
| 223 | 240 | ||
| 224 | countbadblocks | 241 | countbadblocks |
| 225 | clearbadblocks | 242 | clearbadblocks |
| 243 | listbadblocks | ||
| 226 | disable | 244 | disable |
| 227 | enable | 245 | enable |
| 228 | quiet | 246 | quiet |
| @@ -83,6 +83,10 @@ restart_on_corruption · 82 unmodified lines | |||
| 83 | not compatible with ignore_corruption and requires user space support to | 83 | not compatible with ignore_corruption and requires user space support to |
| 84 | avoid restart loops. | 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 | ignore_zero_blocks | 90 | ignore_zero_blocks |
| 87 | Do not verify blocks that are expected to contain zeroes and always return | 91 | Do not verify blocks that are expected to contain zeroes and always return |
| 88 | zeroes instead. This may be useful if the partition contains unused blocks | 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 | int async_write_error; | 108 | int async_write_error; |
| 109 | 109 | ||
| 110 | struct list_head client_list; | 110 | struct list_head client_list; |
| 111 | |||
| 111 | struct shrinker shrinker; | 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 | return retain_bytes; | 1637 | return retain_bytes; |
| 1635 | } | 1638 | } |
| 1636 | 1639 | ||
| 1637 | static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan, | 1640 | static void __scan(struct dm_bufio_client *c) |
| 1638 | gfp_t gfp_mask) | ||
| 1639 | { | 1641 | { |
| 1640 | int l; | 1642 | int l; |
| 1641 | struct dm_buffer *b, *tmp; | 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 | for (l = 0; l < LIST_SIZE; l++) { | 1649 | for (l = 0; l < LIST_SIZE; l++) { |
| 1648 | list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) { | 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 | freed++; | 1657 | freed++; |
| 1651 | if (!--nr_to_scan || ((count - freed) <= retain_target)) | 1658 | } |
| 1652 | return freed; | ||
| 1653 | cond_resched(); | 1659 | cond_resched(); |
| 1654 | } | 1660 | } |
| 1655 | } | 1661 | } |
| 1656 | return freed; | ||
| 1657 | } | 1662 | } |
| 1658 | 1663 | ||
| 1659 | static unsigned long | 1664 | static void shrink_work(struct work_struct *w) |
| 1660 | dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | 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 | struct dm_bufio_client *c; | 1675 | struct dm_bufio_client *c; |
| 1663 | unsigned long freed; | ||
| 1664 | 1676 | ||
| 1665 | c = container_of(shrink, struct dm_bufio_client, shrinker); | 1677 | c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1666 | if (sc->gfp_mask & __GFP_FS) | 1678 | atomic_long_add(sc->nr_to_scan, &c->need_shrink); |
| 1667 | dm_bufio_lock(c); | 1679 | queue_work(dm_bufio_wq, &c->shrink_work); |
| 1668 | else if (!dm_bufio_trylock(c)) | ||
| 1669 | return SHRINK_STOP; | ||
| 1670 | 1680 | ||
| 1671 | freed = __scan(c, sc->nr_to_scan, sc->gfp_mask); | 1681 | return sc->nr_to_scan; |
| 1672 | dm_bufio_unlock(c); | ||
| 1673 | return freed; | ||
| 1674 | } | 1682 | } |
| 1675 | 1683 | ||
| 1676 | static unsigned long | 1684 | static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) |
| 1677 | dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) | ||
| 1678 | { | 1685 | { |
| 1679 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); | 1686 | struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1680 | unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) + | 1687 | unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) + |
| 1681 | READ_ONCE(c->n_buffers[LIST_DIRTY]); | 1688 | READ_ONCE(c->n_buffers[LIST_DIRTY]); |
| 1682 | unsigned long retain_target = get_retain_buffers(c); | 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 | __free_buffer_wake(b); | 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 | c->shrinker.count_objects = dm_bufio_shrink_count; | 1796 | c->shrinker.count_objects = dm_bufio_shrink_count; |
| 1776 | c->shrinker.scan_objects = dm_bufio_shrink_scan; | 1797 | c->shrinker.scan_objects = dm_bufio_shrink_scan; |
| 1777 | c->shrinker.seeks = 1; | 1798 | c->shrinker.seeks = 1; |
| @@ -1817,6 +1838,7 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c) · 39 unmodified lines | |||
| 1817 | drop_buffers(c); | 1838 | drop_buffers(c); |
| 1818 | 1839 | ||
| 1819 | unregister_shrinker(&c->shrinker); | 1840 | unregister_shrinker(&c->shrinker); |
| 1841 | flush_work(&c->shrink_work); | ||
| 1820 | 1842 | ||
| 1821 | mutex_lock(&dm_bufio_clients_lock); | 1843 | mutex_lock(&dm_bufio_clients_lock); |
| 1822 | 1844 | ||
| @@ -69,6 +69,7 @@ struct dm_crypt_io { · 68 unmodified lines | |||
| 69 | u8 *integrity_metadata; | 69 | u8 *integrity_metadata; |
| 70 | bool integrity_metadata_from_pool; | 70 | bool integrity_metadata_from_pool; |
| 71 | struct work_struct work; | 71 | struct work_struct work; |
| 72 | struct tasklet_struct tasklet; | ||
| 72 | 73 | ||
| 73 | struct convert_context ctx; | 74 | struct convert_context ctx; |
| 74 | 75 | ||
| @@ -127,7 +128,9 @@ struct iv_elephant_private { · 52 unmodified lines | |||
| 127 | * and encrypts / decrypts at the same time. | 128 | * and encrypts / decrypts at the same time. |
| 128 | */ | 129 | */ |
| 129 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, | 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 | enum cipher_flags { | 135 | enum cipher_flags { |
| 133 | CRYPT_MODE_INTEGRITY_AEAD, /* Use authenticated mode for cihper */ | 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 | * Encrypt / decrypt data from one bio to another one (can be the same one) | 1526 | * Encrypt / decrypt data from one bio to another one (can be the same one) |
| 1524 | */ | 1527 | */ |
| 1525 | static blk_status_t crypt_convert(struct crypt_config *cc, | 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 | unsigned int tag_offset = 0; | 1531 | unsigned int tag_offset = 0; |
| 1529 | unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; | 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 | atomic_dec(&ctx->cc_pending); | 1569 | atomic_dec(&ctx->cc_pending); |
| 1567 | ctx->cc_sector += sector_step; | 1570 | ctx->cc_sector += sector_step; |
| 1568 | tag_offset++; | 1571 | tag_offset++; |
| 1569 | cond_resched(); | 1572 | if (!atomic) |
| 1573 | cond_resched(); | ||
| 1570 | continue; | 1574 | continue; |
| 1571 | /* | 1575 | /* |
| 1572 | * There was a data integrity error. | 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 | clone->bi_iter.bi_sector = cc->start + io->sector; | 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 | submit_bio_noacct(clone); | 1901 | submit_bio_noacct(clone); |
| 1897 | return; | 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 | spin_unlock_irqrestore(&cc->write_thread_lock, flags); | 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 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) | 1945 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) |
| 1919 | { | 1946 | { |
| 1920 | struct crypt_config *cc = io->cc; | 1947 | struct crypt_config *cc = io->cc; |
| 1948 | struct convert_context *ctx = &io->ctx; | ||
| 1921 | struct bio *clone; | 1949 | struct bio *clone; |
| 1922 | int crypt_finished; | 1950 | int crypt_finished; |
| 1923 | sector_t sector = io->sector; | 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 | * Prevent io from disappearing until this function completes. | 1955 | * Prevent io from disappearing until this function completes. |
| 1928 | */ | 1956 | */ |
| 1929 | crypt_inc_pending(io); | 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 | clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); | 1960 | clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); |
| 1933 | if (unlikely(!clone)) { | 1961 | if (unlikely(!clone)) { |
| @@ -1941,10 +1969,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) · 7 unmodified lines | |||
| 1941 | sector += bio_sectors(clone); | 1969 | sector += bio_sectors(clone); |
| 1942 | 1970 | ||
| 1943 | crypt_inc_pending(io); | 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 | if (r) | 1974 | if (r) |
| 1946 | io->error = r; | 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 | /* Encryption was already finished, submit io now */ | 1983 | /* Encryption was already finished, submit io now */ |
| 1950 | if (crypt_finished) { | 1984 | if (crypt_finished) { |
| @@ -1971,7 +2005,8 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) · 20 unmodified lines | |||
| 1971 | crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, | 2005 | crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, |
| 1972 | io->sector); | 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 | if (r) | 2010 | if (r) |
| 1976 | io->error = r; | 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 | if (!atomic_dec_and_test(&ctx->cc_pending)) | 2050 | if (!atomic_dec_and_test(&ctx->cc_pending)) |
| 2016 | return; | 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 | kcryptd_crypt_read_done(io); | 2058 | kcryptd_crypt_read_done(io); |
| 2020 | else | 2059 | return; |
| 2021 | kcryptd_crypt_write_io_submit(io, 1); | 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 | static void kcryptd_crypt(struct work_struct *work) | 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 | kcryptd_crypt_write_convert(io); | 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 | static void kcryptd_queue_crypt(struct dm_crypt_io *io) | 2085 | static void kcryptd_queue_crypt(struct dm_crypt_io *io) |
| 2035 | { | 2086 | { |
| 2036 | struct crypt_config *cc = io->cc; | 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 | INIT_WORK(&io->work, kcryptd_crypt); | 2102 | INIT_WORK(&io->work, kcryptd_crypt); |
| 2039 | queue_work(cc->crypt_queue, &io->work); | 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 | struct crypt_config *cc = ti->private; | 2902 | struct crypt_config *cc = ti->private; |
| 2839 | struct dm_arg_set as; | 2903 | struct dm_arg_set as; |
| 2840 | static const struct dm_arg _args[] = { | 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 | unsigned int opt_params, val; | 2907 | unsigned int opt_params, val; |
| 2844 | const char *opt_string, *sval; | 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 | else if (!strcasecmp(opt_string, "submit_from_crypt_cpus")) | 2933 | else if (!strcasecmp(opt_string, "submit_from_crypt_cpus")) |
| 2870 | set_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags); | 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 | else if (sscanf(opt_string, "integrity:%u:", &val) == 1) { | 2939 | else if (sscanf(opt_string, "integrity:%u:", &val) == 1) { |
| 2872 | if (val == 0 || val > MAX_TAG_SIZE) { | 2940 | if (val == 0 || val > MAX_TAG_SIZE) { |
| 2873 | ti->error = "Invalid integrity arguments"; | 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 | return 0; | 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 | * Construct an encryption mapping: | 2995 | * Construct an encryption mapping: |
| 2913 | * <cipher> [<key>|:<key_size>:<user|logon>:<key_description>] <iv_offset> <dev_path> <start> | 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 | cc->start = tmpll; | 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 | if (crypt_integrity_aead(cc) || cc->integrity_iv_size) { | 3137 | if (crypt_integrity_aead(cc) || cc->integrity_iv_size) { |
| 3045 | ret = crypt_integrity_ctr(cc, ti); | 3138 | ret = crypt_integrity_ctr(cc, ti); |
| 3046 | if (ret) | 3139 | if (ret) |
| @@ -3196,6 +3289,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type, · 149 unmodified lines | |||
| 3196 | num_feature_args += !!ti->num_discard_bios; | 3289 | num_feature_args += !!ti->num_discard_bios; |
| 3197 | num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags); | 3290 | num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags); |
| 3198 | num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags); | 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 | num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT); | 3294 | num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT); |
| 3200 | num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); | 3295 | num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); |
| 3201 | if (cc->on_disk_tag_size) | 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 | DMEMIT(" same_cpu_crypt"); | 3303 | DMEMIT(" same_cpu_crypt"); |
| 3209 | if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) | 3304 | if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) |
| 3210 | DMEMIT(" submit_from_crypt_cpus"); | 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 | if (cc->on_disk_tag_size) | 3310 | if (cc->on_disk_tag_size) |
| 3212 | DMEMIT(" integrity:%u:%s", cc->on_disk_tag_size, cc->cipher_auth); | 3311 | DMEMIT(" integrity:%u:%s", cc->on_disk_tag_size, cc->cipher_auth); |
| 3213 | if (cc->sector_size != (1 << SECTOR_SHIFT)) | 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 | static struct target_type crypt_target = { | 3420 | static struct target_type crypt_target = { |
| 3322 | .name = "crypt", | 3421 | .name = "crypt", |
| 3323 | .version = {1, 21, 0}, | 3422 | .version = {1, 22, 0}, |
| 3324 | .module = THIS_MODULE, | 3423 | .module = THIS_MODULE, |
| 3325 | .ctr = crypt_ctr, | 3424 | .ctr = crypt_ctr, |
| 3326 | .dtr = crypt_dtr, | 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 | .map = crypt_map, | 3430 | .map = crypt_map, |
| 3328 | .status = crypt_status, | 3431 | .status = crypt_status, |
| 3329 | .postsuspend = crypt_postsuspend, | 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 | return 0; | 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 | struct badblock *bblock; | 144 | struct badblock *bblock; |
| 144 | unsigned long flags; | 145 | unsigned long flags; |
| 146 | unsigned int sz = *sz_ptr; | ||
| 145 | 147 | ||
| 146 | spin_lock_irqsave(&dd->dust_lock, flags); | 148 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 147 | bblock = dust_rb_search(&dd->badblocklist, block); | 149 | bblock = dust_rb_search(&dd->badblocklist, block); |
| 148 | if (bblock != NULL) | 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 | else | 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 | spin_unlock_irqrestore(&dd->dust_lock, flags); | 154 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 153 | 155 | ||
| 154 | return 0; | 156 | return 1; |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | static int __dust_map_read(struct dust_device *dd, sector_t thisblock) | 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 | return true; | 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 | unsigned long flags; | 267 | unsigned long flags; |
| 265 | struct rb_root badblocklist; | 268 | struct rb_root badblocklist; |
| 266 | unsigned long long badblock_count; | 269 | unsigned long long badblock_count; |
| 270 | unsigned int sz = *sz_ptr; | ||
| 267 | 271 | ||
| 268 | spin_lock_irqsave(&dd->dust_lock, flags); | 272 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 269 | badblocklist = dd->badblocklist; | 273 | badblocklist = dd->badblocklist; |
| @@ -273,11 +277,36 @@ static int dust_clear_badblocks(struct dust_device *dd) · 3 unmodified lines | |||
| 273 | spin_unlock_irqrestore(&dd->dust_lock, flags); | 277 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 274 | 278 | ||
| 275 | if (!__dust_clear_badblocks(&badblocklist, badblock_count)) | 279 | if (!__dust_clear_badblocks(&badblocklist, badblock_count)) |
| 276 | DMINFO("%s: no badblocks found", __func__); | 280 | DMEMIT("%s: no badblocks found", __func__); |
| 277 | else | 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 | static int dust_message(struct dm_target *ti, unsigned int argc, char **argv, | 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 | struct dust_device *dd = ti->private; | 417 | struct dust_device *dd = ti->private; |
| 389 | sector_t size = i_size_read(dd->dev->bdev->bd_inode) >> SECTOR_SHIFT; | 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 | unsigned char wr_fail_cnt; | 422 | unsigned char wr_fail_cnt; |
| 394 | unsigned int tmp_ui; | 423 | unsigned int tmp_ui; |
| 395 | unsigned long flags; | 424 | unsigned long flags; |
| 425 | unsigned int sz = 0; | ||
| 396 | char dummy; | 426 | char dummy; |
| 397 | 427 | ||
| 398 | if (argc == 1) { | 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 | r = 0; | 440 | r = 0; |
| 411 | } else if (!strcasecmp(argv[0], "countbadblocks")) { | 441 | } else if (!strcasecmp(argv[0], "countbadblocks")) { |
| 412 | spin_lock_irqsave(&dd->dust_lock, flags); | 442 | spin_lock_irqsave(&dd->dust_lock, flags); |
| 413 | DMINFO("countbadblocks: %llu badblock(s) found", | 443 | DMEMIT("countbadblocks: %llu badblock(s) found", |
| 414 | dd->badblock_count); | 444 | dd->badblock_count); |
| 415 | spin_unlock_irqrestore(&dd->dust_lock, flags); | 445 | spin_unlock_irqrestore(&dd->dust_lock, flags); |
| 416 | r = 0; | 446 | r = 1; |
| 417 | } else if (!strcasecmp(argv[0], "clearbadblocks")) { | 447 | } else if (!strcasecmp(argv[0], "clearbadblocks")) { |
| 418 | r = dust_clear_badblocks(dd); | 448 | r = dust_clear_badblocks(dd, result, maxlen, &sz); |
| 419 | } else if (!strcasecmp(argv[0], "quiet")) { | 449 | } else if (!strcasecmp(argv[0], "quiet")) { |
| 420 | if (!dd->quiet_mode) | 450 | if (!dd->quiet_mode) |
| 421 | dd->quiet_mode = true; | 451 | dd->quiet_mode = true; |
| 422 | else | 452 | else |
| 423 | dd->quiet_mode = false; | 453 | dd->quiet_mode = false; |
| 424 | r = 0; | 454 | r = 0; |
| 455 | } else if (!strcasecmp(argv[0], "listbadblocks")) { | ||
| 456 | r = dust_list_badblocks(dd, result, maxlen, &sz); | ||
| 425 | } else { | 457 | } else { |
| 426 | invalid_msg = true; | 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 | else if (!strcasecmp(argv[0], "removebadblock")) | 473 | else if (!strcasecmp(argv[0], "removebadblock")) |
| 442 | r = dust_remove_block(dd, block); | 474 | r = dust_remove_block(dd, block); |
| 443 | else if (!strcasecmp(argv[0], "queryblock")) | 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 | else | 477 | else |
| 446 | invalid_msg = true; | 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 | bio_set_dev(bio, ec->dev->bdev); | 363 | bio_set_dev(bio, ec->dev->bdev); |
| 364 | bio->bi_iter.bi_sector = ec->start + dm_target_offset(ti, bio->bi_iter.bi_sector); | 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 | return DM_MAPIO_REMAPPED; | 367 | return DM_MAPIO_REMAPPED; |
| 368 | /* | 368 | /* |
| 369 | * Only queue for bufio processing in case of partial or overlapping buffers | 369 | * Only queue for bufio processing in case of partial or overlapping buffers |
| @@ -36,7 +36,7 @@ struct dm_device { · 35 unmodified lines | |||
| 36 | struct list_head list; | 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 | "crypt", | 40 | "crypt", |
| 41 | "delay", | 41 | "delay", |
| 42 | "linear", | 42 | "linear", |
| @@ -1168,7 +1168,7 @@ static void retrieve_status(struct dm_table *table, · 1167 unmodified lines | |||
| 1168 | spec->sector_start = ti->begin; | 1168 | spec->sector_start = ti->begin; |
| 1169 | spec->length = ti->len; | 1169 | spec->length = ti->len; |
| 1170 | strncpy(spec->target_type, ti->type->name, | 1170 | strncpy(spec->target_type, ti->type->name, |
| 1171 | sizeof(spec->target_type)); | 1171 | sizeof(spec->target_type) - 1); |
| 1172 | 1172 | ||
| 1173 | outptr += sizeof(struct dm_target_spec); | 1173 | outptr += sizeof(struct dm_target_spec); |
| 1174 | remaining = len - (outptr - outbuf); | 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 | #define MPATHF_PG_INIT_REQUIRED 5 /* pg_init needs calling? */ | 128 | #define MPATHF_PG_INIT_REQUIRED 5 /* pg_init needs calling? */ |
| 129 | #define MPATHF_PG_INIT_DELAY_RETRY 6 /* Delay pg_init retry? */ | 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 | * Allocation routines | 146 | * Allocation routines |
| 133 | *-----------------------------------------------*/ | 147 | *-----------------------------------------------*/ |
| @@ -335,6 +349,8 @@ static int pg_init_all_paths(struct multipath *m) · 201 unmodified lines | |||
| 335 | 349 | ||
| 336 | static void __switch_pg(struct multipath *m, struct priority_group *pg) | 350 | static void __switch_pg(struct multipath *m, struct priority_group *pg) |
| 337 | { | 351 | { |
| 352 | lockdep_assert_held(&m->lock); | ||
| 353 | |||
| 338 | m->current_pg = pg; | 354 | m->current_pg = pg; |
| 339 | 355 | ||
| 340 | /* Must we initialise the PG first, and queue I/O till it's ready? */ | 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 | unsigned bypassed = 1; | 398 | unsigned bypassed = 1; |
| 383 | 399 | ||
| 384 | if (!atomic_read(&m->nr_valid_paths)) { | 400 | if (!atomic_read(&m->nr_valid_paths)) { |
| 401 | spin_lock_irqsave(&m->lock, flags); | ||
| 385 | clear_bit(MPATHF_QUEUE_IO, &m->flags); | 402 | clear_bit(MPATHF_QUEUE_IO, &m->flags); |
| 403 | spin_unlock_irqrestore(&m->lock, flags); | ||
| 386 | goto failed; | 404 | goto failed; |
| 387 | } | 405 | } |
| 388 | 406 | ||
| @@ -422,8 +440,11 @@ check_current_pg: · 33 unmodified lines | |||
| 422 | continue; | 440 | continue; |
| 423 | pgpath = choose_path_in_pg(m, pg, nr_bytes); | 441 | pgpath = choose_path_in_pg(m, pg, nr_bytes); |
| 424 | if (!IS_ERR_OR_NULL(pgpath)) { | 442 | if (!IS_ERR_OR_NULL(pgpath)) { |
| 425 | if (!bypassed) | 443 | if (!bypassed) { |
| 444 | spin_lock_irqsave(&m->lock, flags); | ||
| 426 | set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags); | 445 | set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags); |
| 446 | spin_unlock_irqrestore(&m->lock, flags); | ||
| 447 | } | ||
| 427 | return pgpath; | 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 | static bool must_push_back_rq(struct multipath *m) | 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 | /* Do we need to select a new pgpath? */ | 514 | /* Do we need to select a new pgpath? */ |
| 487 | pgpath = READ_ONCE(m->current_pgpath); | 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 | pgpath = choose_pgpath(m, nr_bytes); | 517 | pgpath = choose_pgpath(m, nr_bytes); |
| 490 | 518 | ||
| 491 | if (!pgpath) { | 519 | if (!pgpath) { |
| @@ -493,8 +521,8 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, · 1 unmodified line | |||
| 493 | return DM_MAPIO_DELAY_REQUEUE; | 521 | return DM_MAPIO_DELAY_REQUEUE; |
| 494 | dm_report_EIO(m); /* Failed */ | 522 | dm_report_EIO(m); /* Failed */ |
| 495 | return DM_MAPIO_KILL; | 523 | return DM_MAPIO_KILL; |
| 496 | } else if (test_bit(MPATHF_QUEUE_IO, &m->flags) || | 524 | } else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) || |
| 497 | test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) { | 525 | mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) { |
| 498 | pg_init_all_paths(m); | 526 | pg_init_all_paths(m); |
| 499 | return DM_MAPIO_DELAY_REQUEUE; | 527 | return DM_MAPIO_DELAY_REQUEUE; |
| 500 | } | 528 | } |
| @@ -560,33 +588,45 @@ static void multipath_release_clone(struct request *clone, · 59 unmodified lines | |||
| 560 | * Map cloned bios (bio-based multipath) | 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 | static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) | 608 | static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) |
| 564 | { | 609 | { |
| 565 | struct pgpath *pgpath; | 610 | struct pgpath *pgpath; |
| 566 | unsigned long flags; | 611 | unsigned long flags; |
| 567 | bool queue_io; | ||
| 568 | 612 | ||
| 569 | /* Do we need to select a new pgpath? */ | 613 | /* Do we need to select a new pgpath? */ |
| 570 | pgpath = READ_ONCE(m->current_pgpath); | 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 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); | 616 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
| 573 | 617 | ||
| 574 | /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ | 618 | if (!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 */ | ||
| 580 | spin_lock_irqsave(&m->lock, flags); | 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 | spin_unlock_irqrestore(&m->lock, flags); | 624 | spin_unlock_irqrestore(&m->lock, flags); |
| 583 | 625 | ||
| 584 | /* PG_INIT_REQUIRED cannot be set without QUEUE_IO */ | 626 | } else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) || |
| 585 | if (queue_io || test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) | 627 | mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) { |
| 586 | pg_init_all_paths(m); | 628 | multipath_queue_bio(m, bio); |
| 587 | else if (!queue_io) | 629 | pg_init_all_paths(m); |
| 588 | queue_work(kmultipathd, &m->process_queued_bios); | ||
| 589 | |||
| 590 | return ERR_PTR(-EAGAIN); | 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 | struct request_queue *q = bdev_get_queue(bdev); | 875 | struct request_queue *q = bdev_get_queue(bdev); |
| 836 | int r; | 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 | retain: | 879 | retain: |
| 840 | if (*attached_handler_name) { | 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 | if (pgpath) | 1654 | if (pgpath) |
| 1615 | fail_path(pgpath); | 1655 | fail_path(pgpath); |
| 1616 | 1656 | ||
| 1617 | if (atomic_read(&m->nr_valid_paths) == 0 && | 1657 | if (!atomic_read(&m->nr_valid_paths) && |
| 1618 | !must_push_back_rq(m)) { | 1658 | !must_push_back_rq(m)) { |
| 1619 | if (error == BLK_STS_IOERR) | 1659 | if (error == BLK_STS_IOERR) |
| 1620 | dm_report_EIO(m); | 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 | if (pgpath) | 1689 | if (pgpath) |
| 1650 | fail_path(pgpath); | 1690 | fail_path(pgpath); |
| 1651 | 1691 | ||
| 1652 | if (atomic_read(&m->nr_valid_paths) == 0 && | 1692 | if (!atomic_read(&m->nr_valid_paths)) { |
| 1653 | !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { | 1693 | spin_lock_irqsave(&m->lock, flags); |
| 1654 | if (__must_push_back(m)) { | 1694 | if (!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { |
| 1655 | r = DM_ENDIO_REQUEUE; | 1695 | if (__must_push_back(m)) { |
| 1656 | } else { | 1696 | r = DM_ENDIO_REQUEUE; |
| 1657 | dm_report_EIO(m); | 1697 | } else { |
| 1658 | *error = BLK_STS_IOERR; | 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); | 1707 | multipath_queue_bio(m, clone); |
| 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 | |||
| 1669 | r = DM_ENDIO_INCOMPLETE; | 1708 | r = DM_ENDIO_INCOMPLETE; |
| 1670 | done: | 1709 | done: |
| 1671 | if (pgpath) { | 1710 | if (pgpath) { |
| @@ -1937,16 +1976,17 @@ static int multipath_prepare_ioctl(struct dm_target *ti, · 265 unmodified lines | |||
| 1937 | struct block_device **bdev) | 1976 | struct block_device **bdev) |
| 1938 | { | 1977 | { |
| 1939 | struct multipath *m = ti->private; | 1978 | struct multipath *m = ti->private; |
| 1940 | struct pgpath *current_pgpath; | 1979 | struct pgpath *pgpath; |
| 1980 | unsigned long flags; | ||
| 1941 | int r; | 1981 | int r; |
| 1942 | 1982 | ||
| 1943 | current_pgpath = READ_ONCE(m->current_pgpath); | 1983 | pgpath = READ_ONCE(m->current_pgpath); |
| 1944 | if (!current_pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | 1984 | if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) |
| 1945 | current_pgpath = choose_pgpath(m, 0); | 1985 | pgpath = choose_pgpath(m, 0); |
| 1946 | 1986 | ||
| 1947 | if (current_pgpath) { | 1987 | if (pgpath) { |
| 1948 | if (!test_bit(MPATHF_QUEUE_IO, &m->flags)) { | 1988 | if (!mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) { |
| 1949 | *bdev = current_pgpath->path.dev->bdev; | 1989 | *bdev = pgpath->path.dev->bdev; |
| 1950 | r = 0; | 1990 | r = 0; |
| 1951 | } else { | 1991 | } else { |
| 1952 | /* pg_init has not started or completed */ | 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 | } else { | 1995 | } else { |
| 1956 | /* No path is available */ | 1996 | /* No path is available */ |
| 1997 | r = -EIO; | ||
| 1998 | spin_lock_irqsave(&m->lock, flags); | ||
| 1957 | if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) | 1999 | if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) |
| 1958 | r = -ENOTCONN; | 2000 | r = -ENOTCONN; |
| 1959 | else | 2001 | spin_unlock_irqrestore(&m->lock, flags); |
| 1960 | r = -EIO; | ||
| 1961 | } | 2002 | } |
| 1962 | 2003 | ||
| 1963 | if (r == -ENOTCONN) { | 2004 | if (r == -ENOTCONN) { |
| @@ -1965,8 +2006,10 @@ static int multipath_prepare_ioctl(struct dm_target *ti, · 1 unmodified line | |||
| 1965 | /* Path status changed, redo selection */ | 2006 | /* Path status changed, redo selection */ |
| 1966 | (void) choose_pgpath(m, 0); | 2007 | (void) choose_pgpath(m, 0); |
| 1967 | } | 2008 | } |
| 2009 | spin_lock_irqsave(&m->lock, flags); | ||
| 1968 | if (test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) | 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 | dm_table_run_md_queue_async(m->ti->table); | 2013 | dm_table_run_md_queue_async(m->ti->table); |
| 1971 | process_queued_io_list(m); | 2014 | process_queued_io_list(m); |
| 1972 | } | 2015 | } |
| @@ -2026,8 +2069,15 @@ static int multipath_busy(struct dm_target *ti) · 53 unmodified lines | |||
| 2026 | return true; | 2069 | return true; |
| 2027 | 2070 | ||
| 2028 | /* no paths available, for blk-mq: rely on IO mapping to delay requeue */ | 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)) | 2072 | if (!atomic_read(&m->nr_valid_paths)) { |
| 2030 | return (m->queue_mode != DM_TYPE_REQUEST_BASED); | 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 | /* Guess which priority_group will be used at next mapping time */ | 2082 | /* Guess which priority_group will be used at next mapping time */ |
| 2033 | pg = READ_ONCE(m->current_pg); | 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 | if (new_devs == rs->raid_disks || !rebuilds) { | 2338 | if (new_devs == rs->raid_disks || !rebuilds) { |
| 2339 | /* Replace a broken device */ | 2339 | /* Replace a broken device */ |
| 2340 | if (new_devs == 1 && !rs->delta_disks) | ||
| 2341 | ; | ||
| 2342 | if (new_devs == rs->raid_disks) { | 2340 | if (new_devs == rs->raid_disks) { |
| 2343 | DMINFO("Superblocks created for new raid set"); | 2341 | DMINFO("Superblocks created for new raid set"); |
| 2344 | set_bit(MD_ARRAY_FIRST_USE, &mddev->flags); | 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 | void dm_stop_queue(struct request_queue *q) | 71 | void dm_stop_queue(struct request_queue *q) |
| 72 | { | 72 | { |
| 73 | if (blk_mq_queue_stopped(q)) | ||
| 74 | return; | ||
| 75 | |||
| 76 | blk_mq_quiesce_queue(q); | 73 | blk_mq_quiesce_queue(q); |
| 77 | } | 74 | } |
| 78 | 75 | ||
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | #define DM_VERITY_OPT_LOGGING "ignore_corruption" | 31 | #define DM_VERITY_OPT_LOGGING "ignore_corruption" |
| 32 | #define DM_VERITY_OPT_RESTART "restart_on_corruption" | 32 | #define DM_VERITY_OPT_RESTART "restart_on_corruption" |
| 33 | #define DM_VERITY_OPT_PANIC "panic_on_corruption" | ||
| 33 | #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" | 34 | #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" |
| 34 | #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" | 35 | #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" |
| 35 | 36 | ||
| @@ -254,6 +255,9 @@ out: · 218 unmodified lines | |||
| 254 | if (v->mode == DM_VERITY_MODE_RESTART) | 255 | if (v->mode == DM_VERITY_MODE_RESTART) |
| 255 | kernel_restart("dm-verity device corrupted"); | 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 | return 1; | 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 | case DM_VERITY_MODE_RESTART: | 746 | case DM_VERITY_MODE_RESTART: |
| 743 | DMEMIT(DM_VERITY_OPT_RESTART); | 747 | DMEMIT(DM_VERITY_OPT_RESTART); |
| 744 | break; | 748 | break; |
| 749 | case DM_VERITY_MODE_PANIC: | ||
| 750 | DMEMIT(DM_VERITY_OPT_PANIC); | ||
| 751 | break; | ||
| 745 | default: | 752 | default: |
| 746 | BUG(); | 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 | v->mode = DM_VERITY_MODE_RESTART; | 914 | v->mode = DM_VERITY_MODE_RESTART; |
| 908 | continue; | 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 | } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { | 921 | } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { |
| 911 | r = verity_alloc_zero_digest(v); | 922 | r = verity_alloc_zero_digest(v); |
| 912 | if (r) { | 923 | if (r) { |
| @@ -1221,7 +1232,7 @@ bad: · 308 unmodified lines | |||
| 1221 | 1232 | ||
| 1222 | static struct target_type verity_target = { | 1233 | static struct target_type verity_target = { |
| 1223 | .name = "verity", | 1234 | .name = "verity", |
| 1224 | .version = {1, 6, 0}, | 1235 | .version = {1, 7, 0}, |
| 1225 | .module = THIS_MODULE, | 1236 | .module = THIS_MODULE, |
| 1226 | .ctr = verity_ctr, | 1237 | .ctr = verity_ctr, |
| 1227 | .dtr = verity_dtr, | 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 | #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0 | 35 | #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0 |
| 36 | 36 | ||
| 37 | int verity_verify_root_hash(const void *data, size_t data_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) | 38 | const void *sig_data, size_t sig_len) |
| 39 | { | 39 | { |
| 40 | return 0; | 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 | return false; | 45 | return false; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, | 48 | static inline int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, |
| 49 | struct dm_verity_sig_opts *sig_opts, | 49 | struct dm_verity *v, struct dm_verity_sig_opts *sig_opts, |
| 50 | unsigned int *argc, const char *arg_name) | 50 | unsigned int *argc, const char *arg_name) |
| 51 | { | 51 | { |
| 52 | return -EINVAL; | 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 | enum verity_mode { | 20 | enum verity_mode { |
| 21 | DM_VERITY_MODE_EIO, | 21 | DM_VERITY_MODE_EIO, |
| 22 | DM_VERITY_MODE_LOGGING, | 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 | enum verity_block_type { | 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 | args.tgt = tgt; | 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 | if (ret < 0) | 509 | if (ret < 0) |
| 509 | goto out; | 510 | goto out; |
| 510 | } while (args.zone_idx < nr_zones && | 511 | } while (args.zone_idx < nr_zones && |