Hello community, here is the log from the commit of package drbd for openSUSE:Factory checked in at 2018-05-03 12:34:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/drbd (Old) and /work/SRC/openSUSE:Factory/.drbd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "drbd" Thu May 3 12:34:44 2018 rev:68 rq:603419 version:9.0.14+git.62f906cf Changes: -------- --- /work/SRC/openSUSE:Factory/drbd/drbd.changes 2018-04-19 15:32:53.630661326 +0200 +++ /work/SRC/openSUSE:Factory/.drbd.new/drbd.changes 2018-05-03 12:34:46.599162887 +0200 @@ -1,0 +2,24 @@ +Thu May 3 01:04:29 UTC 2018 - [email protected] + +- Update to 9.0.14-1 +* fix regression in 9.0.13: call after-split-brain-recovery + handlers no auto-recovery strategies (not even the default: + disconnect) would be applied, nodes would stay connected + and all nodes would try to become the source of the resync. +* fix spurious temporary promotion failure: if after Primary + loss failover happened too quickly, transparently retry internally. +* fixup recently introduced P_ZEROES to actually work as intended +* fix online-verify to account for skipped blocks; otherwise, + it won't notice that it has finished, apparently being stuck + near "100% done" +* expose more resync and online-verify statistics and details +* improve accounting of "in-flight" data and resync requests +* allow taking down an already useless minor device during "down", + even if it is (temporarily) opened by for example udev scanning +* fix for a node staying "only" Consistent and not returning + to UpToDate in certain scenarios when fencing is enabled +* fix data generation UUID propagate during resync +* compat for upstream kernels up to v4.17 + + +------------------------------------------------------------------- Old: ---- drbd-9.0.13+git.b83ade31.tar.bz2 New: ---- drbd-9.0.14+git.62f906cf.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ drbd.spec ++++++ --- /var/tmp/diff_new_pack.ldUjR8/_old 2018-05-03 12:34:47.423133530 +0200 +++ /var/tmp/diff_new_pack.ldUjR8/_new 2018-05-03 12:34:47.427133388 +0200 @@ -24,7 +24,7 @@ %endif Name: drbd -Version: 9.0.13+git.b83ade31 +Version: 9.0.14+git.62f906cf Release: 0 Summary: DRBD driver for Linux License: GPL-2.0+ ++++++ _service ++++++ --- /var/tmp/diff_new_pack.ldUjR8/_old 2018-05-03 12:34:47.479131535 +0200 +++ /var/tmp/diff_new_pack.ldUjR8/_new 2018-05-03 12:34:47.479131535 +0200 @@ -7,10 +7,10 @@ To update to a new release, change "revision" to the desired git commit hash and bump "version" if necessary - <param name="version">9.0.13</param> + <param name="version">9.0.14</param> --> - <param name="versionformat">9.0.13+git.%h</param> - <param name="revision">b83ade31e10925030206854027021eb4fc9f2563</param> + <param name="versionformat">9.0.14+git.%h</param> + <param name="revision">62f906cf44ef02a30ce0c148fec223b40c51c533</param> </service> <service name="recompress" mode="disabled"> ++++++ drbd-9.0.13+git.b83ade31.tar.bz2 -> drbd-9.0.14+git.62f906cf.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/ChangeLog new/drbd-9.0.14+git.62f906cf/ChangeLog --- old/drbd-9.0.13+git.b83ade31/ChangeLog 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/ChangeLog 2018-05-01 00:15:21.000000000 +0200 @@ -2,6 +2,25 @@ ------ For even more detail, use "git log" or visit http://git.drbd.org/. +9.0.14-1 (api:genl2/proto:86-113/transport:14) + * fix regression in 9.0.13: call after-split-brain-recovery handlers + no auto-recovery strategies (not even the default: disconnect) would be + applied, nodes would stay connected and all nodes would try to become the + source of the resync. + * fix spurious temporary promotion failure: if after Primary loss + failover happened too quickly, transparently retry internally. + * fixup recently introduced P_ZEROES to actually work as intended + * fix online-verify to account for skipped blocks; otherwise, it won't + notice that it has finished, apparently being stuck near "100% done" + * expose more resync and online-verify statistics and details + * improve accounting of "in-flight" data and resync requests + * allow taking down an already useless minor device during "down", + even if it is (temporarily) opened by for example udev scanning + * fix for a node staying "only" Consistent and not returning to UpToDate + in certain scenarios when fencing is enabled + * fix data generation UUID propagate during resync + * compat for upstream kernels up to v4.17 + 9.0.13-1 (api:genl2/proto:86-113/transport:14) -------- * abort a resync if a resync source becomes weakly connected and the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/Makefile new/drbd-9.0.14+git.62f906cf/Makefile --- old/drbd-9.0.13+git.b83ade31/Makefile 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/Makefile 2018-05-01 00:15:21.000000000 +0200 @@ -32,7 +32,12 @@ KVER = `uname -r` KDIR = /lib/modules/$(KVER)/build else -KVER := $(shell (make -s -C $(KDIR) kernelversion || make -s -C $(KDIR) kernelrelease) | tail -n1) +# Aand sles is more special than rhel this time. +# Others may be even more special than those two :-/ +# Try "kernelrelease" first, then try "kernelversion". +# If the magic does not work out for you, +# explicitly set both KVER and KDIR to matching values. +KVER := $(shell (make -s -C $(KDIR) kernelrelease || make -s -C $(KDIR) kernelversion) | tail -n1) ifeq ($(KVER),) $(error could not guess kernel version string from kernel sources at "$(KDIR)") endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/README.drbd-utils new/drbd-9.0.14+git.62f906cf/README.drbd-utils --- old/drbd-9.0.13+git.b83ade31/README.drbd-utils 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/README.drbd-utils 2018-05-01 00:15:21.000000000 +0200 @@ -4,9 +4,10 @@ (tarball at http://links.linbit.com/drbd-download) That started out as "drbd-utils version 8.9.0", + has a different release cycle, and provides compatible drbdadm, drbdsetup and drbdmeta tools for DRBD module versions 8.3, 8.4 and 9. Again: to manage DRBD 9 kernel modules and above, - you want drbd-utils >= 8.9.11 from above url. + you want drbd-utils >= 9.3 from above url. ======================================================================= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/debian/changelog new/drbd-9.0.14+git.62f906cf/debian/changelog --- old/drbd-9.0.13+git.b83ade31/debian/changelog 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/debian/changelog 2018-05-01 00:15:21.000000000 +0200 @@ -1,3 +1,9 @@ +drbd (9.0.14-1) unstable; urgency=medium + + * New upstream release. + + -- Lars Ellenberg <[email protected]> Tue, 01 May 2018 00:12:39 +0200 + drbd (9.0.13-1) unstable; urgency=medium * New upstream release. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/drbd_wrappers.h new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/drbd_wrappers.h --- old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/drbd_wrappers.h 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/drbd_wrappers.h 2018-05-01 00:15:21.000000000 +0200 @@ -60,6 +60,17 @@ } #endif +static inline int drbd_always_getpeername(struct socket *sock, struct sockaddr *uaddr) +{ +#ifdef COMPAT_SOCK_OPS_RETURNS_ADDR_LEN + return sock->ops->getname(sock, uaddr, 2); +#else + int len = 0; + int err = sock->ops->getname(sock, uaddr, &len, 2); + return err ?: len; +#endif +} + #ifdef COMPAT_HAVE_BLK_QC_T_MAKE_REQUEST /* in Commit dece16353ef47d8d33f5302bc158072a9d65e26f * make_request() becomes type blk_qc_t. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/tests/have_blk_queue_flag_set.c new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/tests/have_blk_queue_flag_set.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/tests/have_blk_queue_flag_set.c 1970-01-01 01:00:00.000000000 +0100 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/tests/have_blk_queue_flag_set.c 2018-05-01 00:15:21.000000000 +0200 @@ -0,0 +1,6 @@ +#include <linux/blkdev.h> + +void dummy(struct request_queue *q) +{ + blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/tests/sock_ops_returns_addr_len.c new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/tests/sock_ops_returns_addr_len.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd-kernel-compat/tests/sock_ops_returns_addr_len.c 1970-01-01 01:00:00.000000000 +0100 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd-kernel-compat/tests/sock_ops_returns_addr_len.c 2018-05-01 00:15:21.000000000 +0200 @@ -0,0 +1,5 @@ +#include <linux/net.h> +int always_getpeername(struct socket *sock, struct sockaddr *addr) +{ + return sock->ops->getname(sock, addr, 2); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_debugfs.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_debugfs.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_debugfs.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_debugfs.c 2018-05-01 00:15:21.000000000 +0200 @@ -829,6 +829,8 @@ pretty_print_bit(C_UNREGISTERED); pretty_print_bit(RECONNECT); pretty_print_bit(CONN_DISCARD_MY_DATA); + pretty_print_bit(SEND_STATE_AFTER_AHEAD_C); + pretty_print_bit(NOTIFY_PEERS_LOST_PRIMARY); #undef pretty_print_bit seq_putc(m, '\n'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_int.h new/drbd-9.0.14+git.62f906cf/drbd/drbd_int.h --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_int.h 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_int.h 2018-05-01 00:15:21.000000000 +0200 @@ -550,6 +550,7 @@ STABLE_RESYNC, /* One peer_device finished the resync stable! */ READ_BALANCE_RR, PRIMARY_LOST_QUORUM, + DESTROYING_DEV, }; /* flag bits per peer device */ @@ -1143,6 +1144,10 @@ sector_t ov_last_oos_start; /* size of out-of-sync range in sectors. */ sector_t ov_last_oos_size; + /* Start sector of skipped range (to merge printk reporting). */ + sector_t ov_last_skipped_start; + /* size of skipped range in sectors. */ + sector_t ov_last_skipped_size; int c_sync_rate; /* current resync rate after syncer throttle magic */ struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */ atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */ @@ -1151,6 +1156,7 @@ * on the lower level device when we last looked. */ int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ unsigned long ov_left; /* in bits */ + unsigned long ov_skipped; /* in bits */ u64 current_uuid; u64 bitmap_uuids[DRBD_PEERS_MAX]; @@ -1849,6 +1855,8 @@ extern void resume_next_sg(struct drbd_device *device); extern void suspend_other_sg(struct drbd_device *device); extern int drbd_resync_finished(struct drbd_peer_device *, enum drbd_disk_state); +extern void verify_progress(struct drbd_peer_device *peer_device, + const sector_t sector, const unsigned int size); /* maybe rather drbd_main.c ? */ extern void *drbd_md_get_buffer(struct drbd_device *device, const char *intent); extern void drbd_md_put_buffer(struct drbd_device *device); @@ -1872,6 +1880,15 @@ peer_device->ov_last_oos_size = 0; } +static inline void ov_skipped_print(struct drbd_peer_device *peer_device) +{ + if (peer_device->ov_last_skipped_size) { + drbd_info(peer_device, "Skipped verify, too busy: start=%llu, size=%lu (sectors)\n", + (unsigned long long)peer_device->ov_last_skipped_start, + (unsigned long)peer_device->ov_last_skipped_size); + } + peer_device->ov_last_skipped_size = 0; +} extern void drbd_csum_bio(struct crypto_ahash *, struct bio *, void *); extern void drbd_csum_pages(struct crypto_ahash *, struct page *, void *); @@ -1881,7 +1898,6 @@ extern int w_e_end_csum_rs_req(struct drbd_work *, int); extern int w_e_end_ov_reply(struct drbd_work *, int); extern int w_e_end_ov_req(struct drbd_work *, int); -extern int w_ov_finished(struct drbd_work *, int); extern int w_resync_timer(struct drbd_work *, int); extern int w_send_dblock(struct drbd_work *, int); extern int w_send_read_req(struct drbd_work *, int); @@ -2491,6 +2507,13 @@ is_sync_target_state(peer_device, which); } +static inline bool is_verify_state(struct drbd_peer_device *peer_device, + enum which_state which) +{ + enum drbd_repl_state repl_state = peer_device->repl_state[which]; + return repl_state == L_VERIFY_S || repl_state == L_VERIFY_T; +} + /** * get_ldev() - Increase the ref count on device->ldev. Returns 0 if there is no ldev * @_device: DRBD device. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_main.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_main.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_main.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_main.c 2018-05-01 00:15:21.000000000 +0200 @@ -2511,7 +2511,9 @@ return IOC_ABORT; spin_lock_irq(&resource->req_lock); - if (!resource->remote_state_change) { + if (test_bit(UNREGISTERED, &device->flags)) + r = IOC_ABORT; + else if (!resource->remote_state_change) { r = IOC_OK; if (mode & FMODE_WRITE) device->open_rw_cnt++; @@ -2620,6 +2622,11 @@ if (open_ro_cnt == 0) wake_up_all(&resource->state_wait); + if (test_bit(UNREGISTERED, &device->flags) && + device->open_rw_cnt == 0 && device->open_ro_cnt == 0 && + !test_and_set_bit(DESTROYING_DEV, &device->flags)) + call_rcu(&device->rcu, drbd_reclaim_device); + if (resource->res_opts.auto_promote) { enum drbd_state_rv rv; @@ -4654,7 +4661,7 @@ { struct drbd_device *device = peer_device->device; u64 dagtag = peer_device->connection->last_dagtag_sector; - u64 got_new_bitmap_uuid = 0; + u64 receipients = 0; bool set_current = true; spin_lock_irq(&device->ldev->md.uuid_lock); @@ -4665,16 +4672,21 @@ peer_device->current_uuid = val; set_current = false; } + if (peer_device->repl_state[NOW] == L_SYNC_SOURCE || + peer_device->repl_state[NOW] == L_PAUSED_SYNC_S) + receipients |= NODE_MASK(peer_device->node_id); + } if (set_current) { if (device->disk_state[NOW] == D_UP_TO_DATE) - got_new_bitmap_uuid = rotate_current_into_bitmap(device, weak_nodes, dagtag); + receipients |= rotate_current_into_bitmap(device, weak_nodes, dagtag); __drbd_uuid_set_current(device, val); } spin_unlock_irq(&device->ldev->md.uuid_lock); - drbd_propagate_uuids(device, got_new_bitmap_uuid); + if (set_current) + drbd_propagate_uuids(device, receipients); } static u64 __set_bitmap_slots(struct drbd_device *device, u64 bitmap_uuid, u64 do_nodes) __must_hold(local) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_nl.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_nl.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_nl.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_nl.c 2018-05-01 00:15:21.000000000 +0200 @@ -928,6 +928,29 @@ rcu_read_unlock(); } +static bool wait_up_to_date(struct drbd_resource *resource) +{ + long timeout = resource->res_opts.auto_promote_timeout * HZ / 10; + struct drbd_device *device; + int vnr; + + rcu_read_lock(); + idr_for_each_entry(&resource->devices, device, vnr) { + if (device->disk_state[NOW] == D_CONSISTENT) + break; + } + rcu_read_unlock(); + + if (!device) + return false; + + timeout = wait_event_interruptible_timeout(resource->state_wait, + device->disk_state[NOW] != D_CONSISTENT, + timeout); + return device->disk_state[NOW] == D_UP_TO_DATE; +} + + enum drbd_state_rv drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, struct sk_buff *reply_skb) { @@ -936,6 +959,7 @@ const int max_tries = 4; enum drbd_state_rv rv = SS_UNKNOWN_ERROR; int try = 0; + bool retried_ss_two_primaries = false; int forced = 0; bool with_force = false; const char *err_str = NULL; @@ -1017,6 +1041,19 @@ continue; } + if (rv == SS_NO_UP_TO_DATE_DISK) { + bool a_disk_became_up_to_date; + + /* need to give up state_sem, see try_become_up_to_date(); */ + up(&resource->state_sem); + drbd_flush_workqueue(&resource->work); + a_disk_became_up_to_date = wait_up_to_date(resource); + down(&resource->state_sem); + if (a_disk_became_up_to_date) + continue; + /* fall through into possible fence-peer or even force cases */ + } + if (rv == SS_NO_UP_TO_DATE_DISK && !with_force) { struct drbd_connection *connection; u64 im; @@ -1067,6 +1104,10 @@ struct net_conf *nc; int timeout = 0; + if (try >= max_tries || retried_ss_two_primaries) + break; + retried_ss_two_primaries = true; + /* * Catch the case where we discover that the other * primary has died soon after the state change @@ -1085,8 +1126,6 @@ timeout = 1; schedule_timeout_interruptible(timeout); - if (try < max_tries) - try = max_tries - 1; continue; } @@ -1819,6 +1858,26 @@ return s; } +#ifndef COMPAT_HAVE_BLK_QUEUE_FLAG_SET +static void blk_queue_flag_set(unsigned int flag, struct request_queue *q) +{ + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + queue_flag_set(flag, q); + spin_unlock_irqrestore(q->queue_lock, flags); +} + +static void blk_queue_flag_clear(unsigned int flag, struct request_queue *q) +{ + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + queue_flag_clear(flag, q); + spin_unlock_irqrestore(q->queue_lock, flags); +} +#endif + static void decide_on_discard_support(struct drbd_device *device, struct request_queue *q, struct request_queue *b, @@ -1847,17 +1906,11 @@ * topology on all peers. */ blk_queue_discard_granularity(q, 512); q->limits.max_discard_sectors = drbd_max_discard_sectors(device->resource); - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); -#ifdef COMPAT_HAVE_REQ_OP_WRITE_ZEROES - q->limits.max_write_zeroes_sectors = drbd_max_discard_sectors(device->resource); -#endif + blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } else { - queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); + blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); blk_queue_discard_granularity(q, 0); q->limits.max_discard_sectors = 0; -#ifdef COMPAT_HAVE_REQ_OP_WRITE_ZEROES - q->limits.max_write_zeroes_sectors = 0; -#endif } } @@ -1873,6 +1926,23 @@ } } +static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q) +{ +#ifdef COMPAT_HAVE_REQ_OP_WRITE_ZEROES + /* Fixup max_write_zeroes_sectors after blk_queue_stack_limits(): + * if we can handle "zeroes" efficiently on the protocol, + * we want to do that, even if our backend does not announce + * max_write_zeroes_sectors itself. */ + + /* If all peers announce WZEROES support, use it. Otherwise, rather + * send explicit zeroes than rely on some discard-zeroes-data magic. */ + if (common_connection_features(device->resource) & DRBD_FF_WZEROES) + q->limits.max_write_zeroes_sectors = DRBD_MAX_BBIO_SECTORS; + else + q->limits.max_write_zeroes_sectors = 0; +#endif +} + static void decide_on_write_same_support(struct drbd_device *device, struct request_queue *q, struct request_queue *b, struct o_qlim *o, @@ -1974,6 +2044,7 @@ adjust_ra_pages(q, b); } fixup_discard_if_not_supported(q); + fixup_write_zeroes(device, q); } void drbd_reconsider_queue_parameters(struct drbd_device *device, struct drbd_backing_dev *bdev, struct o_qlim *o) @@ -4949,6 +5020,13 @@ return -EMSGSIZE; } +static void connection_to_statistics(struct connection_statistics *s, struct drbd_connection *connection) +{ + s->conn_congested = test_bit(NET_CONGESTED, &connection->transport.flags); + s->ap_in_flight = atomic_read(&connection->ap_in_flight); + s->rs_in_flight = atomic_read(&connection->rs_in_flight); +} + enum { SINGLE_RESOURCE, ITERATE_RESOURCES }; int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb) @@ -5054,7 +5132,7 @@ err = connection_info_to_skb(skb, &connection_info, !capable(CAP_SYS_ADMIN)); if (err) goto out; - connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->transport.flags); + connection_to_statistics(&connection_statistics, connection); err = connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN)); if (err) goto out; @@ -5073,21 +5151,65 @@ } static void peer_device_to_statistics(struct peer_device_statistics *s, - struct drbd_peer_device *peer_device) + struct drbd_peer_device *pd) { - struct drbd_device *device = peer_device->device; + struct drbd_device *device = pd->device; + unsigned long now = jiffies; + unsigned long rs_left = 0; + int i; + + /* userspace should get "future proof" units, + * convert to sectors or milli seconds as appropriate */ memset(s, 0, sizeof(*s)); - s->peer_dev_received = peer_device->recv_cnt; - s->peer_dev_sent = peer_device->send_cnt; - s->peer_dev_pending = atomic_read(&peer_device->ap_pending_cnt) + - atomic_read(&peer_device->rs_pending_cnt); - s->peer_dev_unacked = atomic_read(&peer_device->unacked_cnt); - s->peer_dev_out_of_sync = drbd_bm_total_weight(peer_device) << (BM_BLOCK_SHIFT - 9); - s->peer_dev_resync_failed = peer_device->rs_failed << (BM_BLOCK_SHIFT - 9); + s->peer_dev_received = pd->recv_cnt; + s->peer_dev_sent = pd->send_cnt; + s->peer_dev_pending = atomic_read(&pd->ap_pending_cnt) + + atomic_read(&pd->rs_pending_cnt); + s->peer_dev_unacked = atomic_read(&pd->unacked_cnt); + s->peer_dev_out_of_sync = BM_BIT_TO_SECT(drbd_bm_total_weight(pd)); + + if (is_verify_state(pd, NOW)) { + rs_left = BM_BIT_TO_SECT(pd->ov_left); + s->peer_dev_ov_start_sector = pd->ov_start_sector; + s->peer_dev_ov_stop_sector = pd->ov_stop_sector; + s->peer_dev_ov_position = pd->ov_position; + s->peer_dev_ov_left = BM_BIT_TO_SECT(pd->ov_left); + s->peer_dev_ov_skipped = BM_BIT_TO_SECT(pd->ov_skipped); + } else if (is_sync_state(pd, NOW)) { + rs_left = s->peer_dev_out_of_sync - BM_BIT_TO_SECT(pd->rs_failed); + s->peer_dev_resync_failed = BM_BIT_TO_SECT(pd->rs_failed); + s->peer_dev_rs_same_csum = BM_BIT_TO_SECT(pd->rs_same_csum); + } + + if (rs_left) { + enum drbd_repl_state repl_state = pd->repl_state[NOW]; + if (repl_state == L_SYNC_TARGET || repl_state == L_VERIFY_S) + s->peer_dev_rs_c_sync_rate = pd->c_sync_rate; + + s->peer_dev_rs_total = BM_BIT_TO_SECT(pd->rs_total); + + s->peer_dev_rs_dt_start_ms = jiffies_to_msecs(now - pd->rs_start); + s->peer_dev_rs_paused_ms = jiffies_to_msecs(pd->rs_paused); + + i = (pd->rs_last_mark + 2) % DRBD_SYNC_MARKS; + s->peer_dev_rs_dt0_ms = jiffies_to_msecs(now - pd->rs_mark_time[i]); + s->peer_dev_rs_db0_sectors = BM_BIT_TO_SECT(pd->rs_mark_left[i]) - rs_left; + + i = (pd->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; + s->peer_dev_rs_dt1_ms = jiffies_to_msecs(now - pd->rs_mark_time[i]); + s->peer_dev_rs_db1_sectors = BM_BIT_TO_SECT(pd->rs_mark_left[i]) - rs_left; + + /* long term average: + * dt = rs_dt_start_ms - rs_paused_ms; + * db = rs_total - rs_left, which is + * rs_total - (ov_left? ov_left : out_of_sync - rs_failed) + */ + } + if (get_ldev(device)) { struct drbd_md *md = &device->ldev->md; - struct drbd_peer_md *peer_md = &md->peers[peer_device->node_id]; + struct drbd_peer_md *peer_md = &md->peers[pd->node_id]; spin_lock_irq(&md->uuid_lock); s->peer_dev_bitmap_uuid = peer_md->bitmap_uuid; @@ -5556,8 +5678,7 @@ return ERR_MINOR_INVALID; spin_lock_irq(&resource->req_lock); - if (device->disk_state[NOW] == D_DISKLESS && - device->open_ro_cnt == 0 && device->open_rw_cnt == 0) { + if (device->disk_state[NOW] == D_DISKLESS) { set_bit(UNREGISTERED, &device->flags); ret = NO_ERROR; } else { @@ -5587,7 +5708,10 @@ NOTIFY_DESTROY | NOTIFY_CONTINUES); notify_device_state(NULL, 0, device, NULL, NOTIFY_DESTROY); mutex_unlock(¬ification_mutex); - call_rcu(&device->rcu, drbd_reclaim_device); + + if (device->open_ro_cnt == 0 && device->open_rw_cnt == 0 && + !test_and_set_bit(DESTROYING_DEV, &device->flags)) + call_rcu(&device->rcu, drbd_reclaim_device); return ret; } @@ -5888,7 +6012,7 @@ connection_info_to_skb(skb, connection_info, true))) goto nla_put_failure; connection_paths_to_skb(skb, connection); - connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->transport.flags); + connection_to_statistics(&connection_statistics, connection); connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN)); genlmsg_end(skb, dh); if (multicast) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_receiver.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_receiver.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_receiver.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_receiver.c 2018-05-01 00:15:21.000000000 +0200 @@ -1786,7 +1786,7 @@ struct drbd_peer_request_details *d, struct packet_info *pi) { struct p_trim *p = pi->data; - bool is_trim_or_wsame = pi->cmd == P_TRIM || pi->cmd == P_WSAME; + bool is_trim_or_wsame = pi->cmd == P_TRIM || pi->cmd == P_WSAME || pi->cmd == P_ZEROES; unsigned int digest_size = pi->cmd != P_TRIM && connection->peer_integrity_tfm ? crypto_ahash_digestsize(connection->peer_integrity_tfm) : 0; @@ -2944,6 +2944,20 @@ return false; } +static void verify_skipped_block(struct drbd_peer_device *peer_device, + const sector_t sector, const unsigned int size) +{ + ++peer_device->ov_skipped; + if (peer_device->ov_last_skipped_start + peer_device->ov_last_skipped_size == sector) { + peer_device->ov_last_skipped_size += size>>9; + } else { + ov_skipped_print(peer_device); + peer_device->ov_last_skipped_start = sector; + peer_device->ov_last_skipped_size = size>>9; + } + verify_progress(peer_device, sector, size); +} + static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi) { struct drbd_peer_device *peer_device; @@ -2985,10 +2999,11 @@ case P_DATA_REQUEST: drbd_send_ack_rp(peer_device, P_NEG_DREPLY, p); break; + case P_OV_REQUEST: + verify_skipped_block(peer_device, sector, size); case P_RS_THIN_REQ: case P_RS_DATA_REQUEST: case P_CSUM_RS_REQUEST: - case P_OV_REQUEST: drbd_send_ack_rp(peer_device, P_NEG_RS_DREPLY , p); break; case P_OV_REPLY: @@ -3084,6 +3099,7 @@ peer_device->ov_start_sector = sector; peer_device->ov_position = sector; peer_device->ov_left = drbd_bm_bits(device) - BM_SECT_TO_BIT(sector); + peer_device->ov_skipped = 0; peer_device->rs_total = peer_device->ov_left; for (i = 0; i < DRBD_SYNC_MARKS; i++) { peer_device->rs_mark_left[i] = peer_device->ov_left; @@ -3141,6 +3157,8 @@ Instruct the SyncSource to retry */ err = drbd_try_rs_begin_io(peer_device, sector, false); if (err) { + if (pi->cmd == P_OV_REQUEST) + verify_skipped_block(peer_device, sector, size); err = drbd_send_ack(peer_device, P_RS_CANCEL, peer_req); /* If err is set, we will drop the connection... */ goto fail3; @@ -3963,7 +3981,7 @@ else if (!device->have_quorum[NOW] && peer_state.quorum) hg = -2; } - if (hg > 2 && hg < -2) { + if (abs(hg) > 2) { switch (pcount) { case 0: hg = drbd_asb_recover_0p(peer_device); @@ -6580,7 +6598,7 @@ new_disk_state = D_CONSISTENT; /* This is a "safety net"; it can only happen if fencing and quorum are both disabled. This alone would be racy, look for - "Do not trust this guy!" */ + "Do not trust this guy!" (see also may_return_to_up_to_date()) */ } } } else if (resource->role[NOW] == R_PRIMARY && device->disk_state[NOW] == D_DISKLESS && @@ -7334,8 +7352,10 @@ [P_CURRENT_UUID] = { 0, sizeof(struct p_current_uuid), receive_current_uuid }, [P_TWOPC_COMMIT] = { 0, sizeof(struct p_twopc_request), receive_twopc }, [P_TRIM] = { 0, sizeof(struct p_trim), receive_Data }, + [P_ZEROES] = { 0, sizeof(struct p_trim), receive_Data }, [P_RS_DEALLOCATED] = { 0, sizeof(struct p_block_desc), receive_rs_deallocated }, [P_WSAME] = { 1, sizeof(struct p_wsame), receive_Data }, + [P_ZEROES] = { 0, sizeof(struct p_trim), receive_Data }, }; static void drbdd(struct drbd_connection *connection) @@ -7715,11 +7735,11 @@ connection->peer_node_id, connection->agreed_pro_version); - drbd_info(connection, "Feature flags enabled on protocol level: 0x%x%s%s%s.\n", + drbd_info(connection, "Feature flags enabled on protocol level: 0x%x%s%s%s%s.\n", connection->agreed_features, connection->agreed_features & DRBD_FF_TRIM ? " TRIM" : "", connection->agreed_features & DRBD_FF_THIN_RESYNC ? " THIN_RESYNC" : "", - connection->agreed_features & DRBD_FF_WSAME ? " WRITE_SAME" : + connection->agreed_features & DRBD_FF_WSAME ? " WRITE_SAME" : "", connection->agreed_features & DRBD_FF_WZEROES ? " WRITE_ZEROES" : connection->agreed_features ? "" : " none"); @@ -7800,7 +7820,7 @@ if (pi.cmd != P_AUTH_CHALLENGE) { drbd_err(connection, "expected AuthChallenge packet, received: %s (0x%04x)\n", drbd_packet_name(pi.cmd), pi.cmd); - rv = 0; + rv = -1; goto fail; } @@ -8318,10 +8338,14 @@ drbd_rs_failed_io(peer_device, sector, size); break; case P_RS_CANCEL: - bit = BM_SECT_TO_BIT(sector); - mutex_lock(&device->bm_resync_fo_mutex); - device->bm_resync_fo = min(device->bm_resync_fo, bit); - mutex_unlock(&device->bm_resync_fo_mutex); + if (peer_device->repl_state[NOW] == L_VERIFY_S) { + verify_skipped_block(peer_device, sector, size); + } else { + bit = BM_SECT_TO_BIT(sector); + mutex_lock(&device->bm_resync_fo_mutex); + device->bm_resync_fo = min(device->bm_resync_fo, bit); + mutex_unlock(&device->bm_resync_fo_mutex); + } atomic_add(size >> 9, &peer_device->rs_sect_in); mod_timer(&peer_device->resync_timer, jiffies + SLEEP_TIME); @@ -8373,24 +8397,8 @@ drbd_rs_complete_io(peer_device, sector); dec_rs_pending(peer_device); - --peer_device->ov_left; + verify_progress(peer_device, sector, size); - /* let's advance progress step marks only for every other megabyte */ - if ((peer_device->ov_left & 0x200) == 0x200) - drbd_advance_rs_marks(peer_device, peer_device->ov_left); - - if (peer_device->ov_left == 0) { - struct drbd_peer_device_work *dw = kmalloc(sizeof(*dw), GFP_NOIO); - if (dw) { - dw->w.cb = w_ov_finished; - dw->peer_device = peer_device; - drbd_queue_work(&connection->sender_work, &dw->w); - } else { - drbd_err(device, "kmalloc(dw) failed."); - ov_out_of_sync_print(peer_device); - drbd_resync_finished(peer_device, D_MASK); - } - } put_ldev(device); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_req.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_req.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_req.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_req.c 2018-05-01 00:15:21.000000000 +0200 @@ -623,6 +623,21 @@ connection->req_not_net_done = req; } +/* for wsame, discard, and zero-out requests, the payload (amount of data we + * need to send) is much smaller than the number of storage sectors affected */ +static unsigned int req_payload_sectors(struct drbd_request *req) +{ + /* actually: physical_block_size, + * but lets just hardcode 4k in sectors: */ + if (unlikely(req->local_rq_state & RQ_WSAME)) + return 8; + /* really only a few bytes, but let's pretend one sector */ + if (unlikely(req->local_rq_state & (RQ_UNMAP|RQ_ZEROES))) + return 1; + /* other have all the data as payload on the wire */ + return req->i.size >> 9; +} + /* I'd like this to be the only place that manipulates * req->completion_ref and req->kref. */ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, @@ -689,7 +704,7 @@ if (!(old_net & RQ_NET_SENT) && (set & RQ_NET_SENT)) { /* potentially already completed in the ack_receiver thread */ if (!(old_net & RQ_NET_DONE)) { - atomic_add(req->i.size >> 9, &peer_device->connection->ap_in_flight); + atomic_add(req_payload_sectors(req), &peer_device->connection->ap_in_flight); set_if_null_req_not_net_done(peer_device, req); } if (req->net_rq_state[idx] & RQ_NET_PENDING) @@ -733,7 +748,7 @@ atomic_t *ap_in_flight = &peer_device->connection->ap_in_flight; if (old_net & RQ_NET_SENT) - atomic_sub(req->i.size >> 9, ap_in_flight); + atomic_sub(req_payload_sectors(req), ap_in_flight); if (old_net & RQ_EXP_BARR_ACK) kref_put(&req->kref, drbd_req_destroy); req->net_done_kt[peer_device->node_id] = ktime_get(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_sender.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_sender.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_sender.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_sender.c 2018-05-01 00:15:21.000000000 +0200 @@ -873,18 +873,6 @@ return 1; } -int w_ov_finished(struct drbd_work *w, int cancel) -{ - struct drbd_peer_device_work *dw = - container_of(w, struct drbd_peer_device_work, w); - struct drbd_peer_device *peer_device = dw->peer_device; - kfree(dw); - ov_out_of_sync_print(peer_device); - drbd_resync_finished(peer_device, D_MASK); - - return 0; -} - struct resync_finished_work { struct drbd_peer_device_work pdw; enum drbd_disk_state new_peer_disk_state; @@ -1091,17 +1079,22 @@ __change_repl_state(peer_device, L_ESTABLISHED); aborted = device->disk_state[NOW] == D_OUTDATED && new_peer_disk_state == D_INCONSISTENT; - - drbd_info(peer_device, "%s %s (total %lu sec; paused %lu sec; %lu K/sec)\n", + { + char tmp[sizeof(" but 01234567890123456789 4k blocks skipped")] = ""; + if (verify_done && peer_device->ov_skipped) + snprintf(tmp, sizeof(tmp), " but %lu %dk blocks skipped", + peer_device->ov_skipped, Bit2KB(1)); + drbd_info(peer_device, "%s %s%s (total %lu sec; paused %lu sec; %lu K/sec)\n", verify_done ? "Online verify" : "Resync", - aborted ? "aborted" : "done", + aborted ? "aborted" : "done", tmp, dt + peer_device->rs_paused, peer_device->rs_paused, dbdt); + } n_oos = drbd_bm_total_weight(peer_device); if (repl_state[NOW] == L_VERIFY_S || repl_state[NOW] == L_VERIFY_T) { if (n_oos) { - drbd_alert(peer_device, "Online verify found %lu %dk block out of sync!\n", + drbd_alert(peer_device, "Online verify found %lu %dk blocks out of sync!\n", n_oos, Bit2KB(1)); khelper_cmd = "out-of-sync"; } @@ -1340,10 +1333,15 @@ } else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { if (likely(peer_device->disk_state[NOW] >= D_INCONSISTENT)) { inc_rs_pending(peer_device); + /* If we send back as P_RS_DATA_REPLY, + * this is overestimating "in-flight" accounting. + * But needed to be properly balanced with + * the atomic_sub() in got_BlockAck. + * TODO: to fix that, we'd need a protocol bump. */ + atomic_add(peer_req->i.size >> 9, &connection->rs_in_flight); if (peer_req->flags & EE_RS_THIN_REQ && all_zero(peer_req)) { err = drbd_send_rs_deallocated(peer_device, peer_req); } else { - atomic_add(peer_req->i.size >> 9, &connection->rs_in_flight); err = drbd_send_block(peer_device, P_RS_DATA_REPLY, peer_req); } } else { @@ -1485,12 +1483,31 @@ if (peer_device->ov_last_oos_start + peer_device->ov_last_oos_size == sector) { peer_device->ov_last_oos_size += size>>9; } else { + ov_out_of_sync_print(peer_device); peer_device->ov_last_oos_start = sector; peer_device->ov_last_oos_size = size>>9; } drbd_set_out_of_sync(peer_device, sector, size); } +void verify_progress(struct drbd_peer_device *peer_device, + const sector_t sector, const unsigned int size) +{ + bool stop_sector_reached = + (peer_device->repl_state[NOW] == L_VERIFY_S) && + verify_can_do_stop_sector(peer_device) && + (sector + (size>>9)) >= peer_device->ov_stop_sector; + + --peer_device->ov_left; + + /* let's advance progress step marks only for every other megabyte */ + if ((peer_device->ov_left & 0x1ff) == 0) + drbd_advance_rs_marks(peer_device, peer_device->ov_left); + + if (peer_device->ov_left == 0 || stop_sector_reached) + drbd_peer_device_post_work(peer_device, RS_DONE); +} + int w_e_end_ov_reply(struct drbd_work *w, int cancel) { struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); @@ -1502,7 +1519,6 @@ unsigned int size = peer_req->i.size; int digest_size; int err, eq = 0; - bool stop_sector_reached = false; if (unlikely(cancel)) { drbd_free_peer_req(peer_req); @@ -1547,19 +1563,7 @@ dec_unacked(peer_device); - --peer_device->ov_left; - - /* let's advance progress step marks only for every other megabyte */ - if ((peer_device->ov_left & 0x200) == 0x200) - drbd_advance_rs_marks(peer_device, peer_device->ov_left); - - stop_sector_reached = verify_can_do_stop_sector(peer_device) && - (sector + (size>>9)) >= peer_device->ov_stop_sector; - - if (peer_device->ov_left == 0 || stop_sector_reached) { - ov_out_of_sync_print(peer_device); - drbd_resync_finished(peer_device, D_MASK); - } + verify_progress(peer_device, sector, size); return err; } @@ -2080,7 +2084,15 @@ drbd_bm_write_lazy(device, 0); - if (resync_done && is_sync_state(peer_device, NOW)) + if (resync_done) { + if (is_verify_state(peer_device, NOW)) { + ov_out_of_sync_print(peer_device); + ov_skipped_print(peer_device); + } else + resync_done = is_sync_state(peer_device, NOW); + } + + if (resync_done) drbd_resync_finished(peer_device, D_MASK); /* update timestamp, in case it took a while to write out stuff */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_state.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_state.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_state.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_state.c 2018-05-01 00:15:21.000000000 +0200 @@ -91,30 +91,27 @@ static enum drbd_state_rv change_peer_state(struct drbd_connection *, int, union drbd_state, union drbd_state, unsigned long *); -static bool only_diskless_peers(struct drbd_device *device, enum which_state which) +/* We need to stay consistent if we are neighbour of a diskless primary with + different UUID. This function should be used if the device was D_UP_TO_DATE + before. + */ +static bool may_return_to_up_to_date(struct drbd_device *device, enum which_state which) { struct drbd_peer_device *peer_device; + bool rv = true; - for_each_peer_device(peer_device, device) { - enum drbd_disk_state peer_disk_state = peer_device->disk_state[which]; - - if (peer_disk_state >= D_INCONSISTENT && peer_disk_state != D_UNKNOWN) - return false; - } - - for_each_peer_device(peer_device, device) { - if (peer_device->disk_state[which] != D_DISKLESS || - peer_device->connection->peer_role[which] != R_PRIMARY) - continue; - - if (peer_device->current_uuid != device->ldev->md.current_uuid) { - /* Limit disk state get to D_CONSISTENT at max. - That has the effect that the diskless peer can - not read/write from/to this node. */ - return true; + rcu_read_lock(); + for_each_peer_device_rcu(peer_device, device) { + if (peer_device->disk_state[which] == D_DISKLESS && + peer_device->connection->peer_role[which] == R_PRIMARY && + peer_device->current_uuid != drbd_current_uuid(device)) { + rv = false; + break; } } - return false; + rcu_read_unlock(); + + return rv; } /** @@ -128,7 +125,7 @@ bool all_peers_outdated = true; int node_id; - if (only_diskless_peers(device, which)) /* and one primary peer */ + if (!may_return_to_up_to_date(device, which)) return false; rcu_read_lock(); @@ -2040,6 +2037,7 @@ peer_device->ov_position = peer_device->ov_start_sector; } peer_device->ov_left = peer_device->rs_total; + peer_device->ov_skipped = 0; } static void queue_after_state_change_work(struct drbd_resource *resource, @@ -2252,6 +2250,8 @@ peer_device->rs_last_sect_ev = 0; peer_device->ov_last_oos_size = 0; peer_device->ov_last_oos_start = 0; + peer_device->ov_last_skipped_size = 0; + peer_device->ov_last_skipped_start = 0; for (i = 0; i < DRBD_SYNC_MARKS; i++) { peer_device->rs_mark_left[i] = peer_device->ov_left; @@ -3406,7 +3406,7 @@ send_new_state_to_all_peer_devices(state_change, n_device); if (disk_state[OLD] == D_UP_TO_DATE && disk_state[NEW] == D_CONSISTENT && - may_be_up_to_date(device, NOW)) + may_return_to_up_to_date(device, NOW)) try_become_up_to_date = true; drbd_md_sync_if_dirty(device); @@ -4566,7 +4566,8 @@ int vnr; idr_for_each_entry(&resource->devices, device, vnr) { - if (device->disk_state[NOW] == D_CONSISTENT) + if (device->disk_state[NOW] == D_CONSISTENT && + may_return_to_up_to_date(device, NOW)) __change_disk_state(device, D_UP_TO_DATE); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/drbd_transport_tcp.c new/drbd-9.0.14+git.62f906cf/drbd/drbd_transport_tcp.c --- old/drbd-9.0.13+git.b83ade31/drbd/drbd_transport_tcp.c 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/drbd_transport_tcp.c 2018-05-01 00:15:21.000000000 +0200 @@ -607,7 +607,7 @@ { struct dtt_socket_container *socket_c; struct sockaddr_storage peer_addr; - int connect_int, peer_addr_len, err = 0; + int connect_int, err = 0; long timeo; struct socket *s_estab = NULL; struct net_conf *nc; @@ -653,7 +653,8 @@ from the listening socket. */ unregister_state_change(s_estab->sk, listener); - s_estab->ops->getname(s_estab, (struct sockaddr *)&peer_addr, &peer_addr_len, 2); + + drbd_always_getpeername(s_estab, (struct sockaddr *)&peer_addr); spin_lock_bh(&listener->listener.waiters_lock); drbd_path2 = drbd_find_path_by_addr(&listener->listener, &peer_addr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd/linux/drbd_config.h new/drbd-9.0.14+git.62f906cf/drbd/linux/drbd_config.h --- old/drbd-9.0.13+git.b83ade31/drbd/linux/drbd_config.h 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd/linux/drbd_config.h 2018-05-01 00:15:21.000000000 +0200 @@ -32,7 +32,7 @@ /* End of external module for 2.6.33 stuff */ -#define REL_VERSION "9.0.13-1" +#define REL_VERSION "9.0.14-1" #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 113 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd-headers/linux/drbd_genl.h new/drbd-9.0.14+git.62f906cf/drbd-headers/linux/drbd_genl.h --- old/drbd-9.0.13+git.b83ade31/drbd-headers/linux/drbd_genl.h 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd-headers/linux/drbd_genl.h 2018-05-01 00:15:21.000000000 +0200 @@ -272,6 +272,8 @@ GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, connection_statistics, __flg_field(1, 0, conn_congested) + __u64_field(2, 0, ap_in_flight) /* sectors */ + __u64_field(3, 0, rs_in_flight) /* sectors */ ) GENL_struct(DRBD_NLA_PEER_DEVICE_STATISTICS, 22, peer_device_statistics, @@ -283,6 +285,24 @@ __u64_field(6, 0, peer_dev_resync_failed) /* sectors */ __u64_field(7, 0, peer_dev_bitmap_uuid) __u32_field(9, 0, peer_dev_flags) + /* you need the peer_repl_state from peer_device_info + * to properly interpret these stats for "progress" + * of syncer/verify */ + __u64_field(10,0, peer_dev_rs_total) /* sectors */ + __u64_field(11,0, peer_dev_ov_start_sector) + __u64_field(12,0, peer_dev_ov_stop_sector) + __u64_field(13,0, peer_dev_ov_position) /* sectors */ + __u64_field(14,0, peer_dev_ov_left) /* sectors */ + __u64_field(15,0, peer_dev_ov_skipped) /* sectors */ + __u64_field(16,0, peer_dev_rs_same_csum) + __u64_field(17,0, peer_dev_rs_dt_start_ms) + __u64_field(18,0, peer_dev_rs_paused_ms) + /* resync progress marks for "resync speed" guestimation */ + __u64_field(19,0, peer_dev_rs_dt0_ms) + __u64_field(20,0, peer_dev_rs_db0_sectors) + __u64_field(21,0, peer_dev_rs_dt1_ms) + __u64_field(22,0, peer_dev_rs_db1_sectors) + __u32_field(23,0, peer_dev_rs_c_sync_rate) ) GENL_struct(DRBD_NLA_NOTIFICATION_HEADER, 23, drbd_notification_header, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/drbd-9.0.13+git.b83ade31/drbd-kernel.spec new/drbd-9.0.14+git.62f906cf/drbd-kernel.spec --- old/drbd-9.0.13+git.b83ade31/drbd-kernel.spec 2018-04-17 12:04:10.000000000 +0200 +++ new/drbd-9.0.14+git.62f906cf/drbd-kernel.spec 2018-05-01 00:15:21.000000000 +0200 @@ -1,6 +1,6 @@ Name: drbd-kernel Summary: Kernel driver for DRBD -Version: 9.0.13 +Version: 9.0.14 Release: 1%{?dist} # always require a suitable userland @@ -103,6 +103,9 @@ rm -rf %{buildroot} %changelog +* Tue May 01 2018 Lars Ellenberg <[email protected]> - 9.0.14-1 +- New upstream release. + * Tue Apr 17 2018 Philipp Reisner <[email protected]> - 9.0.13-1 - New upstream release. ++++++ drbd_git_revision ++++++ --- /var/tmp/diff_new_pack.ldUjR8/_old 2018-05-03 12:34:47.759121560 +0200 +++ /var/tmp/diff_new_pack.ldUjR8/_new 2018-05-03 12:34:47.759121560 +0200 @@ -1 +1 @@ -GIT-hash: b83ade31e10925030206854027021eb4fc9f2563 +GIT-hash: 62f906cf44ef02a30ce0c148fec223b40c51c533
