.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | drbd_receiver.c |
---|
3 | 4 | |
---|
.. | .. |
---|
7 | 8 | Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>. |
---|
8 | 9 | Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>. |
---|
9 | 10 | |
---|
10 | | - drbd is free software; you can redistribute it and/or modify |
---|
11 | | - it under the terms of the GNU General Public License as published by |
---|
12 | | - the Free Software Foundation; either version 2, or (at your option) |
---|
13 | | - any later version. |
---|
14 | | - |
---|
15 | | - drbd is distributed in the hope that it will be useful, |
---|
16 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - GNU General Public License for more details. |
---|
19 | | - |
---|
20 | | - You should have received a copy of the GNU General Public License |
---|
21 | | - along with drbd; see the file COPYING. If not, write to |
---|
22 | | - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
23 | 11 | */ |
---|
24 | 12 | |
---|
25 | 13 | |
---|
.. | .. |
---|
45 | 33 | #include <linux/random.h> |
---|
46 | 34 | #include <linux/string.h> |
---|
47 | 35 | #include <linux/scatterlist.h> |
---|
| 36 | +#include <linux/part_stat.h> |
---|
48 | 37 | #include "drbd_int.h" |
---|
49 | 38 | #include "drbd_protocol.h" |
---|
50 | 39 | #include "drbd_req.h" |
---|
51 | 40 | #include "drbd_vli.h" |
---|
52 | 41 | |
---|
53 | | -#define PRO_FEATURES (DRBD_FF_TRIM|DRBD_FF_THIN_RESYNC|DRBD_FF_WSAME) |
---|
| 42 | +#define PRO_FEATURES (DRBD_FF_TRIM|DRBD_FF_THIN_RESYNC|DRBD_FF_WSAME|DRBD_FF_WZEROES) |
---|
54 | 43 | |
---|
55 | 44 | struct packet_info { |
---|
56 | 45 | enum drbd_packet cmd; |
---|
.. | .. |
---|
516 | 505 | struct msghdr msg = { |
---|
517 | 506 | .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) |
---|
518 | 507 | }; |
---|
519 | | - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, size); |
---|
| 508 | + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, size); |
---|
520 | 509 | return sock_recvmsg(sock, &msg, msg.msg_flags); |
---|
521 | 510 | } |
---|
522 | 511 | |
---|
.. | .. |
---|
1062 | 1051 | |
---|
1063 | 1052 | /* we don't want delays. |
---|
1064 | 1053 | * we use TCP_CORK where appropriate, though */ |
---|
1065 | | - drbd_tcp_nodelay(sock.socket); |
---|
1066 | | - drbd_tcp_nodelay(msock.socket); |
---|
| 1054 | + tcp_sock_set_nodelay(sock.socket->sk); |
---|
| 1055 | + tcp_sock_set_nodelay(msock.socket->sk); |
---|
1067 | 1056 | |
---|
1068 | 1057 | connection->data.socket = sock.socket; |
---|
1069 | 1058 | connection->meta.socket = msock.socket; |
---|
.. | .. |
---|
1234 | 1223 | * quickly as possible, and let remote TCP know what we have |
---|
1235 | 1224 | * received so far. */ |
---|
1236 | 1225 | if (err == -EAGAIN) { |
---|
1237 | | - drbd_tcp_quickack(connection->data.socket); |
---|
| 1226 | + tcp_sock_set_quickack(connection->data.socket->sk, 2); |
---|
1238 | 1227 | drbd_unplug_all_devices(connection); |
---|
1239 | 1228 | } |
---|
1240 | 1229 | if (err > 0) { |
---|
.. | .. |
---|
1310 | 1299 | bio_set_dev(bio, device->ldev->backing_bdev); |
---|
1311 | 1300 | bio->bi_private = octx; |
---|
1312 | 1301 | bio->bi_end_io = one_flush_endio; |
---|
1313 | | - bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH; |
---|
| 1302 | + bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; |
---|
1314 | 1303 | |
---|
1315 | 1304 | device->flush_jif = jiffies; |
---|
1316 | 1305 | set_bit(FLUSH_PENDING, &device->flags); |
---|
.. | .. |
---|
1490 | 1479 | drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]); |
---|
1491 | 1480 | } |
---|
1492 | 1481 | |
---|
1493 | | -static void drbd_issue_peer_discard(struct drbd_device *device, struct drbd_peer_request *peer_req) |
---|
| 1482 | +/* |
---|
| 1483 | + * Mapping "discard" to ZEROOUT with UNMAP does not work for us: |
---|
| 1484 | + * Drivers have to "announce" q->limits.max_write_zeroes_sectors, or it |
---|
| 1485 | + * will directly go to fallback mode, submitting normal writes, and |
---|
| 1486 | + * never even try to UNMAP. |
---|
| 1487 | + * |
---|
| 1488 | + * And dm-thin does not do this (yet), mostly because in general it has |
---|
| 1489 | + * to assume that "skip_block_zeroing" is set. See also: |
---|
| 1490 | + * https://www.mail-archive.com/dm-devel%40redhat.com/msg07965.html |
---|
| 1491 | + * https://www.redhat.com/archives/dm-devel/2018-January/msg00271.html |
---|
| 1492 | + * |
---|
| 1493 | + * We *may* ignore the discard-zeroes-data setting, if so configured. |
---|
| 1494 | + * |
---|
| 1495 | + * Assumption is that this "discard_zeroes_data=0" is only because the backend |
---|
| 1496 | + * may ignore partial unaligned discards. |
---|
| 1497 | + * |
---|
| 1498 | + * LVM/DM thin as of at least |
---|
| 1499 | + * LVM version: 2.02.115(2)-RHEL7 (2015-01-28) |
---|
| 1500 | + * Library version: 1.02.93-RHEL7 (2015-01-28) |
---|
| 1501 | + * Driver version: 4.29.0 |
---|
| 1502 | + * still behaves this way. |
---|
| 1503 | + * |
---|
| 1504 | + * For unaligned (wrt. alignment and granularity) or too small discards, |
---|
| 1505 | + * we zero-out the initial (and/or) trailing unaligned partial chunks, |
---|
| 1506 | + * but discard all the aligned full chunks. |
---|
| 1507 | + * |
---|
| 1508 | + * At least for LVM/DM thin, with skip_block_zeroing=false, |
---|
| 1509 | + * the result is effectively "discard_zeroes_data=1". |
---|
| 1510 | + */ |
---|
| 1511 | +/* flags: EE_TRIM|EE_ZEROOUT */ |
---|
| 1512 | +int drbd_issue_discard_or_zero_out(struct drbd_device *device, sector_t start, unsigned int nr_sectors, int flags) |
---|
1494 | 1513 | { |
---|
1495 | 1514 | struct block_device *bdev = device->ldev->backing_bdev; |
---|
| 1515 | + struct request_queue *q = bdev_get_queue(bdev); |
---|
| 1516 | + sector_t tmp, nr; |
---|
| 1517 | + unsigned int max_discard_sectors, granularity; |
---|
| 1518 | + int alignment; |
---|
| 1519 | + int err = 0; |
---|
1496 | 1520 | |
---|
1497 | | - if (blkdev_issue_zeroout(bdev, peer_req->i.sector, peer_req->i.size >> 9, |
---|
1498 | | - GFP_NOIO, 0)) |
---|
| 1521 | + if ((flags & EE_ZEROOUT) || !(flags & EE_TRIM)) |
---|
| 1522 | + goto zero_out; |
---|
| 1523 | + |
---|
| 1524 | + /* Zero-sector (unknown) and one-sector granularities are the same. */ |
---|
| 1525 | + granularity = max(q->limits.discard_granularity >> 9, 1U); |
---|
| 1526 | + alignment = (bdev_discard_alignment(bdev) >> 9) % granularity; |
---|
| 1527 | + |
---|
| 1528 | + max_discard_sectors = min(q->limits.max_discard_sectors, (1U << 22)); |
---|
| 1529 | + max_discard_sectors -= max_discard_sectors % granularity; |
---|
| 1530 | + if (unlikely(!max_discard_sectors)) |
---|
| 1531 | + goto zero_out; |
---|
| 1532 | + |
---|
| 1533 | + if (nr_sectors < granularity) |
---|
| 1534 | + goto zero_out; |
---|
| 1535 | + |
---|
| 1536 | + tmp = start; |
---|
| 1537 | + if (sector_div(tmp, granularity) != alignment) { |
---|
| 1538 | + if (nr_sectors < 2*granularity) |
---|
| 1539 | + goto zero_out; |
---|
| 1540 | + /* start + gran - (start + gran - align) % gran */ |
---|
| 1541 | + tmp = start + granularity - alignment; |
---|
| 1542 | + tmp = start + granularity - sector_div(tmp, granularity); |
---|
| 1543 | + |
---|
| 1544 | + nr = tmp - start; |
---|
| 1545 | + /* don't flag BLKDEV_ZERO_NOUNMAP, we don't know how many |
---|
| 1546 | + * layers are below us, some may have smaller granularity */ |
---|
| 1547 | + err |= blkdev_issue_zeroout(bdev, start, nr, GFP_NOIO, 0); |
---|
| 1548 | + nr_sectors -= nr; |
---|
| 1549 | + start = tmp; |
---|
| 1550 | + } |
---|
| 1551 | + while (nr_sectors >= max_discard_sectors) { |
---|
| 1552 | + err |= blkdev_issue_discard(bdev, start, max_discard_sectors, GFP_NOIO, 0); |
---|
| 1553 | + nr_sectors -= max_discard_sectors; |
---|
| 1554 | + start += max_discard_sectors; |
---|
| 1555 | + } |
---|
| 1556 | + if (nr_sectors) { |
---|
| 1557 | + /* max_discard_sectors is unsigned int (and a multiple of |
---|
| 1558 | + * granularity, we made sure of that above already); |
---|
| 1559 | + * nr is < max_discard_sectors; |
---|
| 1560 | + * I don't need sector_div here, even though nr is sector_t */ |
---|
| 1561 | + nr = nr_sectors; |
---|
| 1562 | + nr -= (unsigned int)nr % granularity; |
---|
| 1563 | + if (nr) { |
---|
| 1564 | + err |= blkdev_issue_discard(bdev, start, nr, GFP_NOIO, 0); |
---|
| 1565 | + nr_sectors -= nr; |
---|
| 1566 | + start += nr; |
---|
| 1567 | + } |
---|
| 1568 | + } |
---|
| 1569 | + zero_out: |
---|
| 1570 | + if (nr_sectors) { |
---|
| 1571 | + err |= blkdev_issue_zeroout(bdev, start, nr_sectors, GFP_NOIO, |
---|
| 1572 | + (flags & EE_TRIM) ? 0 : BLKDEV_ZERO_NOUNMAP); |
---|
| 1573 | + } |
---|
| 1574 | + return err != 0; |
---|
| 1575 | +} |
---|
| 1576 | + |
---|
| 1577 | +static bool can_do_reliable_discards(struct drbd_device *device) |
---|
| 1578 | +{ |
---|
| 1579 | + struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev); |
---|
| 1580 | + struct disk_conf *dc; |
---|
| 1581 | + bool can_do; |
---|
| 1582 | + |
---|
| 1583 | + if (!blk_queue_discard(q)) |
---|
| 1584 | + return false; |
---|
| 1585 | + |
---|
| 1586 | + rcu_read_lock(); |
---|
| 1587 | + dc = rcu_dereference(device->ldev->disk_conf); |
---|
| 1588 | + can_do = dc->discard_zeroes_if_aligned; |
---|
| 1589 | + rcu_read_unlock(); |
---|
| 1590 | + return can_do; |
---|
| 1591 | +} |
---|
| 1592 | + |
---|
| 1593 | +static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, struct drbd_peer_request *peer_req) |
---|
| 1594 | +{ |
---|
| 1595 | + /* If the backend cannot discard, or does not guarantee |
---|
| 1596 | + * read-back zeroes in discarded ranges, we fall back to |
---|
| 1597 | + * zero-out. Unless configuration specifically requested |
---|
| 1598 | + * otherwise. */ |
---|
| 1599 | + if (!can_do_reliable_discards(device)) |
---|
| 1600 | + peer_req->flags |= EE_ZEROOUT; |
---|
| 1601 | + |
---|
| 1602 | + if (drbd_issue_discard_or_zero_out(device, peer_req->i.sector, |
---|
| 1603 | + peer_req->i.size >> 9, peer_req->flags & (EE_ZEROOUT|EE_TRIM))) |
---|
1499 | 1604 | peer_req->flags |= EE_WAS_ERROR; |
---|
1500 | | - |
---|
1501 | 1605 | drbd_endio_write_sec_final(peer_req); |
---|
1502 | 1606 | } |
---|
1503 | 1607 | |
---|
.. | .. |
---|
1550 | 1654 | * Correctness first, performance later. Next step is to code an |
---|
1551 | 1655 | * asynchronous variant of the same. |
---|
1552 | 1656 | */ |
---|
1553 | | - if (peer_req->flags & (EE_IS_TRIM|EE_WRITE_SAME)) { |
---|
| 1657 | + if (peer_req->flags & (EE_TRIM|EE_WRITE_SAME|EE_ZEROOUT)) { |
---|
1554 | 1658 | /* wait for all pending IO completions, before we start |
---|
1555 | 1659 | * zeroing things out. */ |
---|
1556 | 1660 | conn_wait_active_ee_empty(peer_req->peer_device->connection); |
---|
.. | .. |
---|
1567 | 1671 | spin_unlock_irq(&device->resource->req_lock); |
---|
1568 | 1672 | } |
---|
1569 | 1673 | |
---|
1570 | | - if (peer_req->flags & EE_IS_TRIM) |
---|
1571 | | - drbd_issue_peer_discard(device, peer_req); |
---|
| 1674 | + if (peer_req->flags & (EE_TRIM|EE_ZEROOUT)) |
---|
| 1675 | + drbd_issue_peer_discard_or_zero_out(device, peer_req); |
---|
1572 | 1676 | else /* EE_WRITE_SAME */ |
---|
1573 | 1677 | drbd_issue_peer_wsame(device, peer_req); |
---|
1574 | 1678 | return 0; |
---|
.. | .. |
---|
1619 | 1723 | bios = bios->bi_next; |
---|
1620 | 1724 | bio->bi_next = NULL; |
---|
1621 | 1725 | |
---|
1622 | | - drbd_generic_make_request(device, fault_type, bio); |
---|
| 1726 | + drbd_submit_bio_noacct(device, fault_type, bio); |
---|
1623 | 1727 | } while (bios); |
---|
1624 | 1728 | return 0; |
---|
1625 | 1729 | |
---|
.. | .. |
---|
1693 | 1797 | break; |
---|
1694 | 1798 | else |
---|
1695 | 1799 | drbd_warn(connection, "Allocation of an epoch failed, slowing down\n"); |
---|
1696 | | - /* Fall through */ |
---|
| 1800 | + fallthrough; |
---|
1697 | 1801 | |
---|
1698 | 1802 | case WO_BDEV_FLUSH: |
---|
1699 | 1803 | case WO_DRAIN_IO: |
---|
.. | .. |
---|
1732 | 1836 | } |
---|
1733 | 1837 | |
---|
1734 | 1838 | /* quick wrapper in case payload size != request_size (write same) */ |
---|
1735 | | -static void drbd_csum_ee_size(struct crypto_ahash *h, |
---|
| 1839 | +static void drbd_csum_ee_size(struct crypto_shash *h, |
---|
1736 | 1840 | struct drbd_peer_request *r, void *d, |
---|
1737 | 1841 | unsigned int payload_size) |
---|
1738 | 1842 | { |
---|
.. | .. |
---|
1756 | 1860 | struct packet_info *pi) __must_hold(local) |
---|
1757 | 1861 | { |
---|
1758 | 1862 | struct drbd_device *device = peer_device->device; |
---|
1759 | | - const sector_t capacity = drbd_get_capacity(device->this_bdev); |
---|
| 1863 | + const sector_t capacity = get_capacity(device->vdisk); |
---|
1760 | 1864 | struct drbd_peer_request *peer_req; |
---|
1761 | 1865 | struct page *page; |
---|
1762 | 1866 | int digest_size, err; |
---|
.. | .. |
---|
1765 | 1869 | void *dig_vv = peer_device->connection->int_dig_vv; |
---|
1766 | 1870 | unsigned long *data; |
---|
1767 | 1871 | struct p_trim *trim = (pi->cmd == P_TRIM) ? pi->data : NULL; |
---|
| 1872 | + struct p_trim *zeroes = (pi->cmd == P_ZEROES) ? pi->data : NULL; |
---|
1768 | 1873 | struct p_trim *wsame = (pi->cmd == P_WSAME) ? pi->data : NULL; |
---|
1769 | 1874 | |
---|
1770 | 1875 | digest_size = 0; |
---|
1771 | 1876 | if (!trim && peer_device->connection->peer_integrity_tfm) { |
---|
1772 | | - digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); |
---|
| 1877 | + digest_size = crypto_shash_digestsize(peer_device->connection->peer_integrity_tfm); |
---|
1773 | 1878 | /* |
---|
1774 | 1879 | * FIXME: Receive the incoming digest into the receive buffer |
---|
1775 | 1880 | * here, together with its struct p_data? |
---|
.. | .. |
---|
1786 | 1891 | if (!expect(data_size == 0)) |
---|
1787 | 1892 | return NULL; |
---|
1788 | 1893 | ds = be32_to_cpu(trim->size); |
---|
| 1894 | + } else if (zeroes) { |
---|
| 1895 | + if (!expect(data_size == 0)) |
---|
| 1896 | + return NULL; |
---|
| 1897 | + ds = be32_to_cpu(zeroes->size); |
---|
1789 | 1898 | } else if (wsame) { |
---|
1790 | 1899 | if (data_size != queue_logical_block_size(device->rq_queue)) { |
---|
1791 | 1900 | drbd_err(peer_device, "data size (%u) != drbd logical block size (%u)\n", |
---|
.. | .. |
---|
1802 | 1911 | |
---|
1803 | 1912 | if (!expect(IS_ALIGNED(ds, 512))) |
---|
1804 | 1913 | return NULL; |
---|
1805 | | - if (trim || wsame) { |
---|
| 1914 | + if (trim || wsame || zeroes) { |
---|
1806 | 1915 | if (!expect(ds <= (DRBD_MAX_BBIO_SECTORS << 9))) |
---|
1807 | 1916 | return NULL; |
---|
1808 | 1917 | } else if (!expect(ds <= DRBD_MAX_BIO_SIZE)) |
---|
.. | .. |
---|
1827 | 1936 | |
---|
1828 | 1937 | peer_req->flags |= EE_WRITE; |
---|
1829 | 1938 | if (trim) { |
---|
1830 | | - peer_req->flags |= EE_IS_TRIM; |
---|
| 1939 | + peer_req->flags |= EE_TRIM; |
---|
| 1940 | + return peer_req; |
---|
| 1941 | + } |
---|
| 1942 | + if (zeroes) { |
---|
| 1943 | + peer_req->flags |= EE_ZEROOUT; |
---|
1831 | 1944 | return peer_req; |
---|
1832 | 1945 | } |
---|
1833 | 1946 | if (wsame) |
---|
.. | .. |
---|
1905 | 2018 | |
---|
1906 | 2019 | digest_size = 0; |
---|
1907 | 2020 | if (peer_device->connection->peer_integrity_tfm) { |
---|
1908 | | - digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); |
---|
| 2021 | + digest_size = crypto_shash_digestsize(peer_device->connection->peer_integrity_tfm); |
---|
1909 | 2022 | err = drbd_recv_all_warn(peer_device->connection, dig_in, digest_size); |
---|
1910 | 2023 | if (err) |
---|
1911 | 2024 | return err; |
---|
.. | .. |
---|
2326 | 2439 | |
---|
2327 | 2440 | static unsigned long wire_flags_to_bio_op(u32 dpf) |
---|
2328 | 2441 | { |
---|
2329 | | - if (dpf & DP_DISCARD) |
---|
| 2442 | + if (dpf & DP_ZEROES) |
---|
2330 | 2443 | return REQ_OP_WRITE_ZEROES; |
---|
| 2444 | + if (dpf & DP_DISCARD) |
---|
| 2445 | + return REQ_OP_DISCARD; |
---|
| 2446 | + if (dpf & DP_WSAME) |
---|
| 2447 | + return REQ_OP_WRITE_SAME; |
---|
2331 | 2448 | else |
---|
2332 | 2449 | return REQ_OP_WRITE; |
---|
2333 | 2450 | } |
---|
.. | .. |
---|
2518 | 2635 | op_flags = wire_flags_to_bio_flags(dp_flags); |
---|
2519 | 2636 | if (pi->cmd == P_TRIM) { |
---|
2520 | 2637 | D_ASSERT(peer_device, peer_req->i.size > 0); |
---|
| 2638 | + D_ASSERT(peer_device, op == REQ_OP_DISCARD); |
---|
| 2639 | + D_ASSERT(peer_device, peer_req->pages == NULL); |
---|
| 2640 | + /* need to play safe: an older DRBD sender |
---|
| 2641 | + * may mean zero-out while sending P_TRIM. */ |
---|
| 2642 | + if (0 == (connection->agreed_features & DRBD_FF_WZEROES)) |
---|
| 2643 | + peer_req->flags |= EE_ZEROOUT; |
---|
| 2644 | + } else if (pi->cmd == P_ZEROES) { |
---|
| 2645 | + D_ASSERT(peer_device, peer_req->i.size > 0); |
---|
2521 | 2646 | D_ASSERT(peer_device, op == REQ_OP_WRITE_ZEROES); |
---|
2522 | 2647 | D_ASSERT(peer_device, peer_req->pages == NULL); |
---|
| 2648 | + /* Do (not) pass down BLKDEV_ZERO_NOUNMAP? */ |
---|
| 2649 | + if (dp_flags & DP_DISCARD) |
---|
| 2650 | + peer_req->flags |= EE_TRIM; |
---|
2523 | 2651 | } else if (peer_req->pages == NULL) { |
---|
2524 | 2652 | D_ASSERT(device, peer_req->i.size == 0); |
---|
2525 | 2653 | D_ASSERT(device, dp_flags & DP_FLUSH); |
---|
.. | .. |
---|
2587 | 2715 | * we wait for all pending requests, respectively wait for |
---|
2588 | 2716 | * active_ee to become empty in drbd_submit_peer_request(); |
---|
2589 | 2717 | * better not add ourselves here. */ |
---|
2590 | | - if ((peer_req->flags & (EE_IS_TRIM|EE_WRITE_SAME)) == 0) |
---|
| 2718 | + if ((peer_req->flags & (EE_TRIM|EE_WRITE_SAME|EE_ZEROOUT)) == 0) |
---|
2591 | 2719 | list_add_tail(&peer_req->w.list, &device->active_ee); |
---|
2592 | 2720 | spin_unlock_irq(&device->resource->req_lock); |
---|
2593 | 2721 | |
---|
.. | .. |
---|
2661 | 2789 | |
---|
2662 | 2790 | bool drbd_rs_c_min_rate_throttle(struct drbd_device *device) |
---|
2663 | 2791 | { |
---|
2664 | | - struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk; |
---|
| 2792 | + struct gendisk *disk = device->ldev->backing_bdev->bd_disk; |
---|
2665 | 2793 | unsigned long db, dt, dbdt; |
---|
2666 | 2794 | unsigned int c_min_rate; |
---|
2667 | 2795 | int curr_events; |
---|
.. | .. |
---|
2721 | 2849 | if (!peer_device) |
---|
2722 | 2850 | return -EIO; |
---|
2723 | 2851 | device = peer_device->device; |
---|
2724 | | - capacity = drbd_get_capacity(device->this_bdev); |
---|
| 2852 | + capacity = get_capacity(device->vdisk); |
---|
2725 | 2853 | |
---|
2726 | 2854 | sector = be64_to_cpu(p->sector); |
---|
2727 | 2855 | size = be32_to_cpu(p->blksize); |
---|
.. | .. |
---|
2789 | 2917 | then we would do something smarter here than reading |
---|
2790 | 2918 | the block... */ |
---|
2791 | 2919 | peer_req->flags |= EE_RS_THIN_REQ; |
---|
2792 | | - /* fall through */ |
---|
| 2920 | + fallthrough; |
---|
2793 | 2921 | case P_RS_DATA_REQUEST: |
---|
2794 | 2922 | peer_req->w.cb = w_e_end_rsdata_req; |
---|
2795 | 2923 | fault_type = DRBD_FAULT_RS_RD; |
---|
.. | .. |
---|
2955 | 3083 | rv = 1; |
---|
2956 | 3084 | break; |
---|
2957 | 3085 | } |
---|
2958 | | - /* Else fall through to one of the other strategies... */ |
---|
| 3086 | + fallthrough; /* to one of the other strategies */ |
---|
2959 | 3087 | case ASB_DISCARD_OLDER_PRI: |
---|
2960 | 3088 | if (self == 0 && peer == 1) { |
---|
2961 | 3089 | rv = 1; |
---|
.. | .. |
---|
2968 | 3096 | /* Else fall through to one of the other strategies... */ |
---|
2969 | 3097 | drbd_warn(device, "Discard younger/older primary did not find a decision\n" |
---|
2970 | 3098 | "Using discard-least-changes instead\n"); |
---|
2971 | | - /* fall through */ |
---|
| 3099 | + fallthrough; |
---|
2972 | 3100 | case ASB_DISCARD_ZERO_CHG: |
---|
2973 | 3101 | if (ch_peer == 0 && ch_self == 0) { |
---|
2974 | 3102 | rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) |
---|
.. | .. |
---|
2980 | 3108 | } |
---|
2981 | 3109 | if (after_sb_0p == ASB_DISCARD_ZERO_CHG) |
---|
2982 | 3110 | break; |
---|
2983 | | - /* else: fall through */ |
---|
| 3111 | + fallthrough; |
---|
2984 | 3112 | case ASB_DISCARD_LEAST_CHG: |
---|
2985 | 3113 | if (ch_self < ch_peer) |
---|
2986 | 3114 | rv = -1; |
---|
.. | .. |
---|
3480 | 3608 | switch (rr_conflict) { |
---|
3481 | 3609 | case ASB_CALL_HELPER: |
---|
3482 | 3610 | drbd_khelper(device, "pri-lost"); |
---|
3483 | | - /* fall through */ |
---|
| 3611 | + fallthrough; |
---|
3484 | 3612 | case ASB_DISCONNECT: |
---|
3485 | 3613 | drbd_err(device, "I shall become SyncTarget, but I am primary!\n"); |
---|
3486 | 3614 | return C_MASK; |
---|
.. | .. |
---|
3543 | 3671 | int p_proto, p_discard_my_data, p_two_primaries, cf; |
---|
3544 | 3672 | struct net_conf *nc, *old_net_conf, *new_net_conf = NULL; |
---|
3545 | 3673 | char integrity_alg[SHARED_SECRET_MAX] = ""; |
---|
3546 | | - struct crypto_ahash *peer_integrity_tfm = NULL; |
---|
| 3674 | + struct crypto_shash *peer_integrity_tfm = NULL; |
---|
3547 | 3675 | void *int_dig_in = NULL, *int_dig_vv = NULL; |
---|
3548 | 3676 | |
---|
3549 | 3677 | p_proto = be32_to_cpu(p->protocol); |
---|
.. | .. |
---|
3624 | 3752 | * change. |
---|
3625 | 3753 | */ |
---|
3626 | 3754 | |
---|
3627 | | - peer_integrity_tfm = crypto_alloc_ahash(integrity_alg, 0, CRYPTO_ALG_ASYNC); |
---|
| 3755 | + peer_integrity_tfm = crypto_alloc_shash(integrity_alg, 0, 0); |
---|
3628 | 3756 | if (IS_ERR(peer_integrity_tfm)) { |
---|
3629 | 3757 | peer_integrity_tfm = NULL; |
---|
3630 | 3758 | drbd_err(connection, "peer data-integrity-alg %s not supported\n", |
---|
.. | .. |
---|
3632 | 3760 | goto disconnect; |
---|
3633 | 3761 | } |
---|
3634 | 3762 | |
---|
3635 | | - hash_size = crypto_ahash_digestsize(peer_integrity_tfm); |
---|
| 3763 | + hash_size = crypto_shash_digestsize(peer_integrity_tfm); |
---|
3636 | 3764 | int_dig_in = kmalloc(hash_size, GFP_KERNEL); |
---|
3637 | 3765 | int_dig_vv = kmalloc(hash_size, GFP_KERNEL); |
---|
3638 | 3766 | if (!(int_dig_in && int_dig_vv)) { |
---|
.. | .. |
---|
3662 | 3790 | mutex_unlock(&connection->resource->conf_update); |
---|
3663 | 3791 | mutex_unlock(&connection->data.mutex); |
---|
3664 | 3792 | |
---|
3665 | | - crypto_free_ahash(connection->peer_integrity_tfm); |
---|
| 3793 | + crypto_free_shash(connection->peer_integrity_tfm); |
---|
3666 | 3794 | kfree(connection->int_dig_in); |
---|
3667 | 3795 | kfree(connection->int_dig_vv); |
---|
3668 | 3796 | connection->peer_integrity_tfm = peer_integrity_tfm; |
---|
.. | .. |
---|
3680 | 3808 | disconnect_rcu_unlock: |
---|
3681 | 3809 | rcu_read_unlock(); |
---|
3682 | 3810 | disconnect: |
---|
3683 | | - crypto_free_ahash(peer_integrity_tfm); |
---|
| 3811 | + crypto_free_shash(peer_integrity_tfm); |
---|
3684 | 3812 | kfree(int_dig_in); |
---|
3685 | 3813 | kfree(int_dig_vv); |
---|
3686 | 3814 | conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD); |
---|
.. | .. |
---|
3692 | 3820 | * return: NULL (alg name was "") |
---|
3693 | 3821 | * ERR_PTR(error) if something goes wrong |
---|
3694 | 3822 | * or the crypto hash ptr, if it worked out ok. */ |
---|
3695 | | -static struct crypto_ahash *drbd_crypto_alloc_digest_safe(const struct drbd_device *device, |
---|
| 3823 | +static struct crypto_shash *drbd_crypto_alloc_digest_safe( |
---|
| 3824 | + const struct drbd_device *device, |
---|
3696 | 3825 | const char *alg, const char *name) |
---|
3697 | 3826 | { |
---|
3698 | | - struct crypto_ahash *tfm; |
---|
| 3827 | + struct crypto_shash *tfm; |
---|
3699 | 3828 | |
---|
3700 | 3829 | if (!alg[0]) |
---|
3701 | 3830 | return NULL; |
---|
3702 | 3831 | |
---|
3703 | | - tfm = crypto_alloc_ahash(alg, 0, CRYPTO_ALG_ASYNC); |
---|
| 3832 | + tfm = crypto_alloc_shash(alg, 0, 0); |
---|
3704 | 3833 | if (IS_ERR(tfm)) { |
---|
3705 | 3834 | drbd_err(device, "Can not allocate \"%s\" as %s (reason: %ld)\n", |
---|
3706 | 3835 | alg, name, PTR_ERR(tfm)); |
---|
.. | .. |
---|
3753 | 3882 | struct drbd_device *device; |
---|
3754 | 3883 | struct p_rs_param_95 *p; |
---|
3755 | 3884 | unsigned int header_size, data_size, exp_max_sz; |
---|
3756 | | - struct crypto_ahash *verify_tfm = NULL; |
---|
3757 | | - struct crypto_ahash *csums_tfm = NULL; |
---|
| 3885 | + struct crypto_shash *verify_tfm = NULL; |
---|
| 3886 | + struct crypto_shash *csums_tfm = NULL; |
---|
3758 | 3887 | struct net_conf *old_net_conf, *new_net_conf = NULL; |
---|
3759 | 3888 | struct disk_conf *old_disk_conf = NULL, *new_disk_conf = NULL; |
---|
3760 | 3889 | const int apv = connection->agreed_pro_version; |
---|
3761 | 3890 | struct fifo_buffer *old_plan = NULL, *new_plan = NULL; |
---|
3762 | | - int fifo_size = 0; |
---|
| 3891 | + unsigned int fifo_size = 0; |
---|
3763 | 3892 | int err; |
---|
3764 | 3893 | |
---|
3765 | 3894 | peer_device = conn_peer_device(connection, pi->vnr); |
---|
.. | .. |
---|
3901 | 4030 | if (verify_tfm) { |
---|
3902 | 4031 | strcpy(new_net_conf->verify_alg, p->verify_alg); |
---|
3903 | 4032 | new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1; |
---|
3904 | | - crypto_free_ahash(peer_device->connection->verify_tfm); |
---|
| 4033 | + crypto_free_shash(peer_device->connection->verify_tfm); |
---|
3905 | 4034 | peer_device->connection->verify_tfm = verify_tfm; |
---|
3906 | 4035 | drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg); |
---|
3907 | 4036 | } |
---|
3908 | 4037 | if (csums_tfm) { |
---|
3909 | 4038 | strcpy(new_net_conf->csums_alg, p->csums_alg); |
---|
3910 | 4039 | new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1; |
---|
3911 | | - crypto_free_ahash(peer_device->connection->csums_tfm); |
---|
| 4040 | + crypto_free_shash(peer_device->connection->csums_tfm); |
---|
3912 | 4041 | peer_device->connection->csums_tfm = csums_tfm; |
---|
3913 | 4042 | drbd_info(device, "using csums-alg: \"%s\"\n", p->csums_alg); |
---|
3914 | 4043 | } |
---|
.. | .. |
---|
3952 | 4081 | mutex_unlock(&connection->resource->conf_update); |
---|
3953 | 4082 | /* just for completeness: actually not needed, |
---|
3954 | 4083 | * as this is not reached if csums_tfm was ok. */ |
---|
3955 | | - crypto_free_ahash(csums_tfm); |
---|
| 4084 | + crypto_free_shash(csums_tfm); |
---|
3956 | 4085 | /* but free the verify_tfm again, if csums_tfm did not work out */ |
---|
3957 | | - crypto_free_ahash(verify_tfm); |
---|
| 4086 | + crypto_free_shash(verify_tfm); |
---|
3958 | 4087 | conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD); |
---|
3959 | 4088 | return -EIO; |
---|
3960 | 4089 | } |
---|
.. | .. |
---|
3988 | 4117 | if (!peer_device) |
---|
3989 | 4118 | return config_unknown_volume(connection, pi); |
---|
3990 | 4119 | device = peer_device->device; |
---|
3991 | | - cur_size = drbd_get_capacity(device->this_bdev); |
---|
| 4120 | + cur_size = get_capacity(device->vdisk); |
---|
3992 | 4121 | |
---|
3993 | 4122 | p_size = be64_to_cpu(p->d_size); |
---|
3994 | 4123 | p_usize = be64_to_cpu(p->u_size); |
---|
.. | .. |
---|
4013 | 4142 | if (device->state.conn == C_WF_REPORT_PARAMS) |
---|
4014 | 4143 | p_usize = min_not_zero(my_usize, p_usize); |
---|
4015 | 4144 | |
---|
4016 | | - /* Never shrink a device with usable data during connect. |
---|
4017 | | - But allow online shrinking if we are connected. */ |
---|
| 4145 | + /* Never shrink a device with usable data during connect, |
---|
| 4146 | + * or "attach" on the peer. |
---|
| 4147 | + * But allow online shrinking if we are connected. */ |
---|
4018 | 4148 | new_size = drbd_new_dev_size(device, device->ldev, p_usize, 0); |
---|
4019 | 4149 | if (new_size < cur_size && |
---|
4020 | 4150 | device->state.disk >= D_OUTDATED && |
---|
4021 | | - device->state.conn < C_CONNECTED) { |
---|
| 4151 | + (device->state.conn < C_CONNECTED || device->state.pdsk == D_DISKLESS)) { |
---|
4022 | 4152 | drbd_err(device, "The peer's disk size is too small! (%llu < %llu sectors)\n", |
---|
4023 | 4153 | (unsigned long long)new_size, (unsigned long long)cur_size); |
---|
4024 | 4154 | conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD); |
---|
.. | .. |
---|
4046 | 4176 | synchronize_rcu(); |
---|
4047 | 4177 | kfree(old_disk_conf); |
---|
4048 | 4178 | |
---|
4049 | | - drbd_info(device, "Peer sets u_size to %lu sectors\n", |
---|
4050 | | - (unsigned long)my_usize); |
---|
| 4179 | + drbd_info(device, "Peer sets u_size to %lu sectors (old: %lu)\n", |
---|
| 4180 | + (unsigned long)p_usize, (unsigned long)my_usize); |
---|
4051 | 4181 | } |
---|
4052 | 4182 | |
---|
4053 | 4183 | put_ldev(device); |
---|
.. | .. |
---|
4122 | 4252 | } |
---|
4123 | 4253 | |
---|
4124 | 4254 | if (device->state.conn > C_WF_REPORT_PARAMS) { |
---|
4125 | | - if (be64_to_cpu(p->c_size) != |
---|
4126 | | - drbd_get_capacity(device->this_bdev) || ldsc) { |
---|
| 4255 | + if (be64_to_cpu(p->c_size) != get_capacity(device->vdisk) || |
---|
| 4256 | + ldsc) { |
---|
4127 | 4257 | /* we have different sizes, probably peer |
---|
4128 | 4258 | * needs to know my new size... */ |
---|
4129 | 4259 | drbd_send_sizes(peer_device, 0, ddsf); |
---|
.. | .. |
---|
4426 | 4556 | (peer_state.disk == D_NEGOTIATING || |
---|
4427 | 4557 | os.disk == D_NEGOTIATING)); |
---|
4428 | 4558 | /* if we have both been inconsistent, and the peer has been |
---|
4429 | | - * forced to be UpToDate with --overwrite-data */ |
---|
| 4559 | + * forced to be UpToDate with --force */ |
---|
4430 | 4560 | cr |= test_bit(CONSIDER_RESYNC, &device->flags); |
---|
4431 | 4561 | /* if we had been plain connected, and the admin requested to |
---|
4432 | 4562 | * start a sync by "invalidate" or "invalidate-remote" */ |
---|
.. | .. |
---|
4829 | 4959 | { |
---|
4830 | 4960 | /* Make sure we've acked all the TCP data associated |
---|
4831 | 4961 | * with the data requests being unplugged */ |
---|
4832 | | - drbd_tcp_quickack(connection->data.socket); |
---|
4833 | | - |
---|
| 4962 | + tcp_sock_set_quickack(connection->data.socket->sk, 2); |
---|
4834 | 4963 | return 0; |
---|
4835 | 4964 | } |
---|
4836 | 4965 | |
---|
.. | .. |
---|
4891 | 5020 | |
---|
4892 | 5021 | peer_req->w.cb = e_end_resync_block; |
---|
4893 | 5022 | peer_req->submit_jif = jiffies; |
---|
4894 | | - peer_req->flags |= EE_IS_TRIM; |
---|
| 5023 | + peer_req->flags |= EE_TRIM; |
---|
4895 | 5024 | |
---|
4896 | 5025 | spin_lock_irq(&device->resource->req_lock); |
---|
4897 | 5026 | list_add_tail(&peer_req->w.list, &device->sync_ee); |
---|
.. | .. |
---|
4959 | 5088 | [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state }, |
---|
4960 | 5089 | [P_PROTOCOL_UPDATE] = { 1, sizeof(struct p_protocol), receive_protocol }, |
---|
4961 | 5090 | [P_TRIM] = { 0, sizeof(struct p_trim), receive_Data }, |
---|
| 5091 | + [P_ZEROES] = { 0, sizeof(struct p_trim), receive_Data }, |
---|
4962 | 5092 | [P_RS_DEALLOCATED] = { 0, sizeof(struct p_block_desc), receive_rs_deallocated }, |
---|
4963 | 5093 | [P_WSAME] = { 1, sizeof(struct p_wsame), receive_Data }, |
---|
4964 | 5094 | }; |
---|
.. | .. |
---|
5243 | 5373 | drbd_info(connection, "Handshake successful: " |
---|
5244 | 5374 | "Agreed network protocol version %d\n", connection->agreed_pro_version); |
---|
5245 | 5375 | |
---|
5246 | | - drbd_info(connection, "Feature flags enabled on protocol level: 0x%x%s%s%s.\n", |
---|
| 5376 | + drbd_info(connection, "Feature flags enabled on protocol level: 0x%x%s%s%s%s.\n", |
---|
5247 | 5377 | connection->agreed_features, |
---|
5248 | 5378 | connection->agreed_features & DRBD_FF_TRIM ? " TRIM" : "", |
---|
5249 | 5379 | connection->agreed_features & DRBD_FF_THIN_RESYNC ? " THIN_RESYNC" : "", |
---|
5250 | | - connection->agreed_features & DRBD_FF_WSAME ? " WRITE_SAME" : |
---|
| 5380 | + connection->agreed_features & DRBD_FF_WSAME ? " WRITE_SAME" : "", |
---|
| 5381 | + connection->agreed_features & DRBD_FF_WZEROES ? " WRITE_ZEROES" : |
---|
5251 | 5382 | connection->agreed_features ? "" : " none"); |
---|
5252 | 5383 | |
---|
5253 | 5384 | return 1; |
---|
.. | .. |
---|
5307 | 5438 | goto fail; |
---|
5308 | 5439 | } |
---|
5309 | 5440 | desc->tfm = connection->cram_hmac_tfm; |
---|
5310 | | - desc->flags = 0; |
---|
5311 | 5441 | |
---|
5312 | 5442 | rv = crypto_shash_setkey(connection->cram_hmac_tfm, (u8 *)secret, key_len); |
---|
5313 | 5443 | if (rv) { |
---|
.. | .. |
---|
5337 | 5467 | if (pi.cmd != P_AUTH_CHALLENGE) { |
---|
5338 | 5468 | drbd_err(connection, "expected AuthChallenge packet, received: %s (0x%04x)\n", |
---|
5339 | 5469 | cmdname(pi.cmd), pi.cmd); |
---|
5340 | | - rv = 0; |
---|
| 5470 | + rv = -1; |
---|
5341 | 5471 | goto fail; |
---|
5342 | 5472 | } |
---|
5343 | 5473 | |
---|
.. | .. |
---|
5889 | 6019 | unsigned int header_size = drbd_header_size(connection); |
---|
5890 | 6020 | int expect = header_size; |
---|
5891 | 6021 | bool ping_timeout_active = false; |
---|
5892 | | - struct sched_param param = { .sched_priority = 2 }; |
---|
5893 | 6022 | |
---|
5894 | | - rv = sched_setscheduler(current, SCHED_RR, ¶m); |
---|
5895 | | - if (rv < 0) |
---|
5896 | | - drbd_err(connection, "drbd_ack_receiver: ERROR set priority, ret=%d\n", rv); |
---|
| 6023 | + sched_set_fifo_low(current); |
---|
5897 | 6024 | |
---|
5898 | 6025 | while (get_t_state(thi) == RUNNING) { |
---|
5899 | 6026 | drbd_thread_current_set_cpu(thi); |
---|
.. | .. |
---|
5983 | 6110 | |
---|
5984 | 6111 | err = cmd->fn(connection, &pi); |
---|
5985 | 6112 | if (err) { |
---|
5986 | | - drbd_err(connection, "%pf failed\n", cmd->fn); |
---|
| 6113 | + drbd_err(connection, "%ps failed\n", cmd->fn); |
---|
5987 | 6114 | goto reconnect; |
---|
5988 | 6115 | } |
---|
5989 | 6116 | |
---|
.. | .. |
---|
6031 | 6158 | rcu_read_unlock(); |
---|
6032 | 6159 | |
---|
6033 | 6160 | if (tcp_cork) |
---|
6034 | | - drbd_tcp_cork(connection->meta.socket); |
---|
| 6161 | + tcp_sock_set_cork(connection->meta.socket->sk, true); |
---|
6035 | 6162 | |
---|
6036 | 6163 | err = drbd_finish_peer_reqs(device); |
---|
6037 | 6164 | kref_put(&device->kref, drbd_destroy_device); |
---|
.. | .. |
---|
6044 | 6171 | } |
---|
6045 | 6172 | |
---|
6046 | 6173 | if (tcp_cork) |
---|
6047 | | - drbd_tcp_uncork(connection->meta.socket); |
---|
| 6174 | + tcp_sock_set_cork(connection->meta.socket->sk, false); |
---|
6048 | 6175 | |
---|
6049 | 6176 | return; |
---|
6050 | 6177 | } |
---|