blob: 6c59978944759a40b25adbd6c26abcbde02b2011 [file] [log] [blame]
Philipp Reisnerb411b362009-09-25 16:07:19 -07001/*
2 drbd_receiver.c
3
4 This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
5
6 Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
7 Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
8 Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
9
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 */
24
25
Philipp Reisnerb411b362009-09-25 16:07:19 -070026#include <linux/module.h>
27
28#include <asm/uaccess.h>
29#include <net/sock.h>
30
Philipp Reisnerb411b362009-09-25 16:07:19 -070031#include <linux/drbd.h>
32#include <linux/fs.h>
33#include <linux/file.h>
34#include <linux/in.h>
35#include <linux/mm.h>
36#include <linux/memcontrol.h>
37#include <linux/mm_inline.h>
38#include <linux/slab.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070039#include <linux/pkt_sched.h>
40#define __KERNEL_SYSCALLS__
41#include <linux/unistd.h>
42#include <linux/vmalloc.h>
43#include <linux/random.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070044#include <linux/string.h>
45#include <linux/scatterlist.h>
46#include "drbd_int.h"
Andreas Gruenbachera3603a62011-05-30 11:47:37 +020047#include "drbd_protocol.h"
Philipp Reisnerb411b362009-09-25 16:07:19 -070048#include "drbd_req.h"
Philipp Reisnerb411b362009-09-25 16:07:19 -070049#include "drbd_vli.h"
50
Lars Ellenberg20c68fd2014-04-28 18:43:25 +020051#define PRO_FEATURES (FF_TRIM)
52
Philipp Reisner77351055b2011-02-07 17:24:26 +010053struct packet_info {
54 enum drbd_packet cmd;
Andreas Gruenbachere2857212011-03-25 00:57:38 +010055 unsigned int size;
56 unsigned int vnr;
Andreas Gruenbachere6589832011-03-30 12:54:42 +020057 void *data;
Philipp Reisner77351055b2011-02-07 17:24:26 +010058};
59
Philipp Reisnerb411b362009-09-25 16:07:19 -070060enum finish_epoch {
61 FE_STILL_LIVE,
62 FE_DESTROYED,
63 FE_RECYCLED,
64};
65
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +020066static int drbd_do_features(struct drbd_connection *connection);
67static int drbd_do_auth(struct drbd_connection *connection);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +020068static int drbd_disconnected(struct drbd_peer_device *);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +020069static void conn_wait_active_ee_empty(struct drbd_connection *connection);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +020070static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +010071static int e_end_block(struct drbd_work *, int);
Philipp Reisnerb411b362009-09-25 16:07:19 -070072
Philipp Reisnerb411b362009-09-25 16:07:19 -070073
74#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN)
75
Lars Ellenberg45bb9122010-05-14 17:10:48 +020076/*
77 * some helper functions to deal with single linked page lists,
78 * page->private being our "next" pointer.
79 */
80
81/* If at least n pages are linked at head, get n pages off.
82 * Otherwise, don't modify head, and return NULL.
83 * Locking is the responsibility of the caller.
84 */
85static struct page *page_chain_del(struct page **head, int n)
86{
87 struct page *page;
88 struct page *tmp;
89
90 BUG_ON(!n);
91 BUG_ON(!head);
92
93 page = *head;
Philipp Reisner23ce4222010-05-20 13:35:31 +020094
95 if (!page)
96 return NULL;
97
Lars Ellenberg45bb9122010-05-14 17:10:48 +020098 while (page) {
99 tmp = page_chain_next(page);
100 if (--n == 0)
101 break; /* found sufficient pages */
102 if (tmp == NULL)
103 /* insufficient pages, don't use any of them. */
104 return NULL;
105 page = tmp;
106 }
107
108 /* add end of list marker for the returned list */
109 set_page_private(page, 0);
110 /* actual return value, and adjustment of head */
111 page = *head;
112 *head = tmp;
113 return page;
114}
115
116/* may be used outside of locks to find the tail of a (usually short)
117 * "private" page chain, before adding it back to a global chain head
118 * with page_chain_add() under a spinlock. */
119static struct page *page_chain_tail(struct page *page, int *len)
120{
121 struct page *tmp;
122 int i = 1;
123 while ((tmp = page_chain_next(page)))
124 ++i, page = tmp;
125 if (len)
126 *len = i;
127 return page;
128}
129
130static int page_chain_free(struct page *page)
131{
132 struct page *tmp;
133 int i = 0;
134 page_chain_for_each_safe(page, tmp) {
135 put_page(page);
136 ++i;
137 }
138 return i;
139}
140
141static void page_chain_add(struct page **head,
142 struct page *chain_first, struct page *chain_last)
143{
144#if 1
145 struct page *tmp;
146 tmp = page_chain_tail(chain_first, NULL);
147 BUG_ON(tmp != chain_last);
148#endif
149
150 /* add chain to head */
151 set_page_private(chain_last, (unsigned long)*head);
152 *head = chain_first;
153}
154
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200155static struct page *__drbd_alloc_pages(struct drbd_device *device,
Andreas Gruenbacher18c2d522011-04-07 21:08:50 +0200156 unsigned int number)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700157{
158 struct page *page = NULL;
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200159 struct page *tmp = NULL;
Andreas Gruenbacher18c2d522011-04-07 21:08:50 +0200160 unsigned int i = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700161
162 /* Yes, testing drbd_pp_vacant outside the lock is racy.
163 * So what. It saves a spin_lock. */
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200164 if (drbd_pp_vacant >= number) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700165 spin_lock(&drbd_pp_lock);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200166 page = page_chain_del(&drbd_pp_pool, number);
167 if (page)
168 drbd_pp_vacant -= number;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700169 spin_unlock(&drbd_pp_lock);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200170 if (page)
171 return page;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700172 }
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200173
Philipp Reisnerb411b362009-09-25 16:07:19 -0700174 /* GFP_TRY, because we must not cause arbitrary write-out: in a DRBD
175 * "criss-cross" setup, that might cause write-out on some other DRBD,
176 * which in turn might block on the other node at this very place. */
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200177 for (i = 0; i < number; i++) {
178 tmp = alloc_page(GFP_TRY);
179 if (!tmp)
180 break;
181 set_page_private(tmp, (unsigned long)page);
182 page = tmp;
183 }
184
185 if (i == number)
186 return page;
187
188 /* Not enough pages immediately available this time.
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +0200189 * No need to jump around here, drbd_alloc_pages will retry this
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200190 * function "soon". */
191 if (page) {
192 tmp = page_chain_tail(page, NULL);
193 spin_lock(&drbd_pp_lock);
194 page_chain_add(&drbd_pp_pool, page, tmp);
195 drbd_pp_vacant += i;
196 spin_unlock(&drbd_pp_lock);
197 }
198 return NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700199}
200
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200201static void reclaim_finished_net_peer_reqs(struct drbd_device *device,
Andreas Gruenbachera990be42011-04-06 17:56:48 +0200202 struct list_head *to_be_freed)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700203{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200204 struct drbd_peer_request *peer_req, *tmp;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700205
206 /* The EEs are always appended to the end of the list. Since
207 they are sent in order over the wire, they have to finish
208 in order. As soon as we see the first not finished we can
209 stop to examine the list... */
210
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200211 list_for_each_entry_safe(peer_req, tmp, &device->net_ee, w.list) {
Andreas Gruenbacher045417f2011-04-07 21:34:24 +0200212 if (drbd_peer_req_has_active_page(peer_req))
Philipp Reisnerb411b362009-09-25 16:07:19 -0700213 break;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200214 list_move(&peer_req->w.list, to_be_freed);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700215 }
216}
217
Philipp Reisner668700b2015-03-16 16:08:29 +0100218static void drbd_reclaim_net_peer_reqs(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700219{
220 LIST_HEAD(reclaimed);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100221 struct drbd_peer_request *peer_req, *t;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700222
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200223 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200224 reclaim_finished_net_peer_reqs(device, &reclaimed);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200225 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200226 list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200227 drbd_free_net_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700228}
229
Philipp Reisner668700b2015-03-16 16:08:29 +0100230static void conn_reclaim_net_peer_reqs(struct drbd_connection *connection)
231{
232 struct drbd_peer_device *peer_device;
233 int vnr;
234
235 rcu_read_lock();
236 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
237 struct drbd_device *device = peer_device->device;
238 if (!atomic_read(&device->pp_in_use_by_net))
239 continue;
240
241 kref_get(&device->kref);
242 rcu_read_unlock();
243 drbd_reclaim_net_peer_reqs(device);
244 kref_put(&device->kref, drbd_destroy_device);
245 rcu_read_lock();
246 }
247 rcu_read_unlock();
248}
249
Philipp Reisnerb411b362009-09-25 16:07:19 -0700250/**
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +0200251 * drbd_alloc_pages() - Returns @number pages, retries forever (or until signalled)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200252 * @device: DRBD device.
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200253 * @number: number of pages requested
254 * @retry: whether to retry, if not enough pages are available right now
Philipp Reisnerb411b362009-09-25 16:07:19 -0700255 *
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200256 * Tries to allocate number pages, first from our own page pool, then from
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200257 * the kernel.
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200258 * Possibly retry until DRBD frees sufficient pages somewhere else.
259 *
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200260 * If this allocation would exceed the max_buffers setting, we throttle
261 * allocation (schedule_timeout) to give the system some room to breathe.
262 *
263 * We do not use max-buffers as hard limit, because it could lead to
264 * congestion and further to a distributed deadlock during online-verify or
265 * (checksum based) resync, if the max-buffers, socket buffer sizes and
266 * resync-rate settings are mis-configured.
267 *
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200268 * Returns a page chain linked via page->private.
Philipp Reisnerb411b362009-09-25 16:07:19 -0700269 */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200270struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number,
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +0200271 bool retry)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700272{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200273 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700274 struct page *page = NULL;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200275 struct net_conf *nc;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700276 DEFINE_WAIT(wait);
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200277 unsigned int mxb;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700278
Philipp Reisner44ed1672011-04-19 17:10:19 +0200279 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200280 nc = rcu_dereference(peer_device->connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +0200281 mxb = nc ? nc->max_buffers : 1000000;
282 rcu_read_unlock();
283
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200284 if (atomic_read(&device->pp_in_use) < mxb)
285 page = __drbd_alloc_pages(device, number);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700286
Philipp Reisner668700b2015-03-16 16:08:29 +0100287 /* Try to keep the fast path fast, but occasionally we need
288 * to reclaim the pages we lended to the network stack. */
289 if (page && atomic_read(&device->pp_in_use_by_net) > 512)
290 drbd_reclaim_net_peer_reqs(device);
291
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200292 while (page == NULL) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700293 prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE);
294
Philipp Reisner668700b2015-03-16 16:08:29 +0100295 drbd_reclaim_net_peer_reqs(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700296
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200297 if (atomic_read(&device->pp_in_use) < mxb) {
298 page = __drbd_alloc_pages(device, number);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700299 if (page)
300 break;
301 }
302
303 if (!retry)
304 break;
305
306 if (signal_pending(current)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200307 drbd_warn(device, "drbd_alloc_pages interrupted!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700308 break;
309 }
310
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200311 if (schedule_timeout(HZ/10) == 0)
312 mxb = UINT_MAX;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700313 }
314 finish_wait(&drbd_pp_wait, &wait);
315
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200316 if (page)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200317 atomic_add(number, &device->pp_in_use);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700318 return page;
319}
320
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +0200321/* Must not be used from irq, as that may deadlock: see drbd_alloc_pages.
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200322 * Is also used from inside an other spin_lock_irq(&resource->req_lock);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200323 * Either links the page chain back to the global pool,
324 * or returns all pages to the system. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200325static void drbd_free_pages(struct drbd_device *device, struct page *page, int is_net)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700326{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200327 atomic_t *a = is_net ? &device->pp_in_use_by_net : &device->pp_in_use;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700328 int i;
Lars Ellenberg435f0742010-09-06 12:30:25 +0200329
Lars Ellenberga73ff322012-06-25 19:15:38 +0200330 if (page == NULL)
331 return;
332
Philipp Reisner81a5d602011-02-22 19:53:16 -0500333 if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count)
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200334 i = page_chain_free(page);
335 else {
336 struct page *tmp;
337 tmp = page_chain_tail(page, &i);
338 spin_lock(&drbd_pp_lock);
339 page_chain_add(&drbd_pp_pool, page, tmp);
340 drbd_pp_vacant += i;
341 spin_unlock(&drbd_pp_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700342 }
Lars Ellenberg435f0742010-09-06 12:30:25 +0200343 i = atomic_sub_return(i, a);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200344 if (i < 0)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200345 drbd_warn(device, "ASSERTION FAILED: %s: %d < 0\n",
Lars Ellenberg435f0742010-09-06 12:30:25 +0200346 is_net ? "pp_in_use_by_net" : "pp_in_use", i);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700347 wake_up(&drbd_pp_wait);
348}
349
350/*
351You need to hold the req_lock:
352 _drbd_wait_ee_list_empty()
353
354You must not have the req_lock:
Andreas Gruenbacher3967deb2011-04-06 16:16:56 +0200355 drbd_free_peer_req()
Andreas Gruenbacher0db55362011-04-06 16:09:15 +0200356 drbd_alloc_peer_req()
Andreas Gruenbacher7721f562011-04-06 17:14:02 +0200357 drbd_free_peer_reqs()
Philipp Reisnerb411b362009-09-25 16:07:19 -0700358 drbd_ee_fix_bhs()
Andreas Gruenbachera990be42011-04-06 17:56:48 +0200359 drbd_finish_peer_reqs()
Philipp Reisnerb411b362009-09-25 16:07:19 -0700360 drbd_clear_done_ee()
361 drbd_wait_ee_list_empty()
362*/
363
Andreas Gruenbacherf6ffca92011-02-04 15:30:34 +0100364struct drbd_peer_request *
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200365drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200366 unsigned int data_size, bool has_payload, gfp_t gfp_mask) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700367{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200368 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100369 struct drbd_peer_request *peer_req;
Lars Ellenberga73ff322012-06-25 19:15:38 +0200370 struct page *page = NULL;
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200371 unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700372
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200373 if (drbd_insert_fault(device, DRBD_FAULT_AL_EE))
Philipp Reisnerb411b362009-09-25 16:07:19 -0700374 return NULL;
375
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100376 peer_req = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM);
377 if (!peer_req) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700378 if (!(gfp_mask & __GFP_NOWARN))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200379 drbd_err(device, "%s: allocation failed\n", __func__);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700380 return NULL;
381 }
382
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200383 if (has_payload && data_size) {
Mel Gormand0164ad2015-11-06 16:28:21 -0800384 page = drbd_alloc_pages(peer_device, nr_pages,
385 gfpflags_allow_blocking(gfp_mask));
Lars Ellenberga73ff322012-06-25 19:15:38 +0200386 if (!page)
387 goto fail;
388 }
Philipp Reisnerb411b362009-09-25 16:07:19 -0700389
Lars Ellenbergc5a2c152014-05-08 10:08:05 +0200390 memset(peer_req, 0, sizeof(*peer_req));
391 INIT_LIST_HEAD(&peer_req->w.list);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100392 drbd_clear_interval(&peer_req->i);
393 peer_req->i.size = data_size;
394 peer_req->i.sector = sector;
Lars Ellenbergc5a2c152014-05-08 10:08:05 +0200395 peer_req->submit_jif = jiffies;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200396 peer_req->peer_device = peer_device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100397 peer_req->pages = page;
Andreas Gruenbacher9a8e7752011-01-11 14:04:09 +0100398 /*
399 * The block_id is opaque to the receiver. It is not endianness
400 * converted, and sent back to the sender unchanged.
401 */
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100402 peer_req->block_id = id;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700403
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100404 return peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700405
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200406 fail:
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100407 mempool_free(peer_req, drbd_ee_mempool);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700408 return NULL;
409}
410
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200411void __drbd_free_peer_req(struct drbd_device *device, struct drbd_peer_request *peer_req,
Andreas Gruenbacherf6ffca92011-02-04 15:30:34 +0100412 int is_net)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700413{
Lars Ellenberg21ae5d72014-05-05 23:42:24 +0200414 might_sleep();
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100415 if (peer_req->flags & EE_HAS_DIGEST)
416 kfree(peer_req->digest);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200417 drbd_free_pages(device, peer_req->pages, is_net);
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +0200418 D_ASSERT(device, atomic_read(&peer_req->pending_bios) == 0);
419 D_ASSERT(device, drbd_interval_empty(&peer_req->i));
Lars Ellenberg21ae5d72014-05-05 23:42:24 +0200420 if (!expect(!(peer_req->flags & EE_CALL_AL_COMPLETE_IO))) {
421 peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
422 drbd_al_complete_io(device, &peer_req->i);
423 }
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100424 mempool_free(peer_req, drbd_ee_mempool);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700425}
426
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200427int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700428{
429 LIST_HEAD(work_list);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100430 struct drbd_peer_request *peer_req, *t;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700431 int count = 0;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200432 int is_net = list == &device->net_ee;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700433
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200434 spin_lock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700435 list_splice_init(list, &work_list);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200436 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700437
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200438 list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200439 __drbd_free_peer_req(device, peer_req, is_net);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700440 count++;
441 }
442 return count;
443}
444
Philipp Reisnerb411b362009-09-25 16:07:19 -0700445/*
Andreas Gruenbachera990be42011-04-06 17:56:48 +0200446 * See also comments in _req_mod(,BARRIER_ACKED) and receive_Barrier.
Philipp Reisnerb411b362009-09-25 16:07:19 -0700447 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200448static int drbd_finish_peer_reqs(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700449{
450 LIST_HEAD(work_list);
451 LIST_HEAD(reclaimed);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100452 struct drbd_peer_request *peer_req, *t;
Andreas Gruenbachere2b30322011-03-16 17:16:12 +0100453 int err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700454
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200455 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200456 reclaim_finished_net_peer_reqs(device, &reclaimed);
457 list_splice_init(&device->done_ee, &work_list);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200458 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700459
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200460 list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200461 drbd_free_net_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700462
463 /* possible callbacks here:
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +0200464 * e_end_block, and e_end_resync_block, e_send_superseded.
Philipp Reisnerb411b362009-09-25 16:07:19 -0700465 * all ignore the last argument.
466 */
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200467 list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
Andreas Gruenbachere2b30322011-03-16 17:16:12 +0100468 int err2;
469
Philipp Reisnerb411b362009-09-25 16:07:19 -0700470 /* list_del not necessary, next/prev members not touched */
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200471 err2 = peer_req->w.cb(&peer_req->w, !!err);
Andreas Gruenbachere2b30322011-03-16 17:16:12 +0100472 if (!err)
473 err = err2;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200474 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700475 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200476 wake_up(&device->ee_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700477
Andreas Gruenbachere2b30322011-03-16 17:16:12 +0100478 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700479}
480
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200481static void _drbd_wait_ee_list_empty(struct drbd_device *device,
Andreas Gruenbacherd4da1532011-04-07 00:06:56 +0200482 struct list_head *head)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700483{
484 DEFINE_WAIT(wait);
485
486 /* avoids spin_lock/unlock
487 * and calling prepare_to_wait in the fast path */
488 while (!list_empty(head)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200489 prepare_to_wait(&device->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200490 spin_unlock_irq(&device->resource->req_lock);
Jens Axboe7eaceac2011-03-10 08:52:07 +0100491 io_schedule();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200492 finish_wait(&device->ee_wait, &wait);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200493 spin_lock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700494 }
495}
496
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200497static void drbd_wait_ee_list_empty(struct drbd_device *device,
Andreas Gruenbacherd4da1532011-04-07 00:06:56 +0200498 struct list_head *head)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700499{
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200500 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200501 _drbd_wait_ee_list_empty(device, head);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200502 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700503}
504
Philipp Reisnerdbd9eea2011-02-07 15:34:16 +0100505static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flags)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700506{
Philipp Reisnerb411b362009-09-25 16:07:19 -0700507 struct kvec iov = {
508 .iov_base = buf,
509 .iov_len = size,
510 };
511 struct msghdr msg = {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700512 .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL)
513 };
Al Virof730c842014-02-08 21:07:38 -0500514 return kernel_recvmsg(sock, &msg, &iov, 1, size, msg.msg_flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700515}
516
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200517static int drbd_recv(struct drbd_connection *connection, void *buf, size_t size)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700518{
Philipp Reisnerb411b362009-09-25 16:07:19 -0700519 int rv;
520
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200521 rv = drbd_recv_short(connection->data.socket, buf, size, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700522
Philipp Reisnerdbd08202012-08-17 16:55:47 +0200523 if (rv < 0) {
524 if (rv == -ECONNRESET)
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200525 drbd_info(connection, "sock was reset by peer\n");
Philipp Reisnerdbd08202012-08-17 16:55:47 +0200526 else if (rv != -ERESTARTSYS)
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200527 drbd_err(connection, "sock_recvmsg returned %d\n", rv);
Philipp Reisnerdbd08202012-08-17 16:55:47 +0200528 } else if (rv == 0) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200529 if (test_bit(DISCONNECT_SENT, &connection->flags)) {
Philipp Reisnerb66623e2012-08-08 21:19:09 +0200530 long t;
531 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200532 t = rcu_dereference(connection->net_conf)->ping_timeo * HZ/10;
Philipp Reisnerb66623e2012-08-08 21:19:09 +0200533 rcu_read_unlock();
534
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200535 t = wait_event_timeout(connection->ping_wait, connection->cstate < C_WF_REPORT_PARAMS, t);
Philipp Reisnerb66623e2012-08-08 21:19:09 +0200536
Philipp Reisner599377a2012-08-17 14:50:22 +0200537 if (t)
538 goto out;
539 }
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200540 drbd_info(connection, "sock was shut down by peer\n");
Philipp Reisner599377a2012-08-17 14:50:22 +0200541 }
542
Philipp Reisnerb411b362009-09-25 16:07:19 -0700543 if (rv != size)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200544 conn_request_state(connection, NS(conn, C_BROKEN_PIPE), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700545
Philipp Reisner599377a2012-08-17 14:50:22 +0200546out:
Philipp Reisnerb411b362009-09-25 16:07:19 -0700547 return rv;
548}
549
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200550static int drbd_recv_all(struct drbd_connection *connection, void *buf, size_t size)
Andreas Gruenbacherc6967742011-03-17 17:15:20 +0100551{
552 int err;
553
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200554 err = drbd_recv(connection, buf, size);
Andreas Gruenbacherc6967742011-03-17 17:15:20 +0100555 if (err != size) {
556 if (err >= 0)
557 err = -EIO;
558 } else
559 err = 0;
560 return err;
561}
562
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200563static int drbd_recv_all_warn(struct drbd_connection *connection, void *buf, size_t size)
Andreas Gruenbachera5c31902011-03-24 03:28:04 +0100564{
565 int err;
566
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200567 err = drbd_recv_all(connection, buf, size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +0100568 if (err && !signal_pending(current))
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200569 drbd_warn(connection, "short read (expected size %d)\n", (int)size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +0100570 return err;
571}
572
Lars Ellenberg5dbf1672010-05-25 16:18:01 +0200573/* quoting tcp(7):
574 * On individual connections, the socket buffer size must be set prior to the
575 * listen(2) or connect(2) calls in order to have it take effect.
576 * This is our wrapper to do so.
577 */
578static void drbd_setbufsize(struct socket *sock, unsigned int snd,
579 unsigned int rcv)
580{
581 /* open coded SO_SNDBUF, SO_RCVBUF */
582 if (snd) {
583 sock->sk->sk_sndbuf = snd;
584 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
585 }
586 if (rcv) {
587 sock->sk->sk_rcvbuf = rcv;
588 sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
589 }
590}
591
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200592static struct socket *drbd_try_connect(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700593{
594 const char *what;
595 struct socket *sock;
596 struct sockaddr_in6 src_in6;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200597 struct sockaddr_in6 peer_in6;
598 struct net_conf *nc;
599 int err, peer_addr_len, my_addr_len;
Andreas Gruenbacher69ef82d2011-05-11 14:34:35 +0200600 int sndbuf_size, rcvbuf_size, connect_int;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700601 int disconnect_on_error = 1;
602
Philipp Reisner44ed1672011-04-19 17:10:19 +0200603 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200604 nc = rcu_dereference(connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +0200605 if (!nc) {
606 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -0700607 return NULL;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200608 }
Philipp Reisner44ed1672011-04-19 17:10:19 +0200609 sndbuf_size = nc->sndbuf_size;
610 rcvbuf_size = nc->rcvbuf_size;
Andreas Gruenbacher69ef82d2011-05-11 14:34:35 +0200611 connect_int = nc->connect_int;
Andreas Gruenbacher089c0752011-06-14 18:28:09 +0200612 rcu_read_unlock();
Philipp Reisner44ed1672011-04-19 17:10:19 +0200613
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200614 my_addr_len = min_t(int, connection->my_addr_len, sizeof(src_in6));
615 memcpy(&src_in6, &connection->my_addr, my_addr_len);
Philipp Reisner44ed1672011-04-19 17:10:19 +0200616
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200617 if (((struct sockaddr *)&connection->my_addr)->sa_family == AF_INET6)
Philipp Reisner44ed1672011-04-19 17:10:19 +0200618 src_in6.sin6_port = 0;
619 else
620 ((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */
621
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200622 peer_addr_len = min_t(int, connection->peer_addr_len, sizeof(src_in6));
623 memcpy(&peer_in6, &connection->peer_addr, peer_addr_len);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700624
625 what = "sock_create_kern";
Eric W. Biedermaneeb1bd52015-05-08 21:08:05 -0500626 err = sock_create_kern(&init_net, ((struct sockaddr *)&src_in6)->sa_family,
Philipp Reisner44ed1672011-04-19 17:10:19 +0200627 SOCK_STREAM, IPPROTO_TCP, &sock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700628 if (err < 0) {
629 sock = NULL;
630 goto out;
631 }
632
633 sock->sk->sk_rcvtimeo =
Andreas Gruenbacher69ef82d2011-05-11 14:34:35 +0200634 sock->sk->sk_sndtimeo = connect_int * HZ;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200635 drbd_setbufsize(sock, sndbuf_size, rcvbuf_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700636
637 /* explicitly bind to the configured IP as source IP
638 * for the outgoing connections.
639 * This is needed for multihomed hosts and to be
640 * able to use lo: interfaces for drbd.
641 * Make sure to use 0 as port number, so linux selects
642 * a free one dynamically.
643 */
Philipp Reisnerb411b362009-09-25 16:07:19 -0700644 what = "bind before connect";
Philipp Reisner44ed1672011-04-19 17:10:19 +0200645 err = sock->ops->bind(sock, (struct sockaddr *) &src_in6, my_addr_len);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700646 if (err < 0)
647 goto out;
648
649 /* connect may fail, peer not yet available.
650 * stay C_WF_CONNECTION, don't go Disconnecting! */
651 disconnect_on_error = 0;
652 what = "connect";
Philipp Reisner44ed1672011-04-19 17:10:19 +0200653 err = sock->ops->connect(sock, (struct sockaddr *) &peer_in6, peer_addr_len, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700654
655out:
656 if (err < 0) {
657 if (sock) {
658 sock_release(sock);
659 sock = NULL;
660 }
661 switch (-err) {
662 /* timeout, busy, signal pending */
663 case ETIMEDOUT: case EAGAIN: case EINPROGRESS:
664 case EINTR: case ERESTARTSYS:
665 /* peer not (yet) available, network problem */
666 case ECONNREFUSED: case ENETUNREACH:
667 case EHOSTDOWN: case EHOSTUNREACH:
668 disconnect_on_error = 0;
669 break;
670 default:
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200671 drbd_err(connection, "%s failed, err = %d\n", what, err);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700672 }
673 if (disconnect_on_error)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200674 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700675 }
Philipp Reisner44ed1672011-04-19 17:10:19 +0200676
Philipp Reisnerb411b362009-09-25 16:07:19 -0700677 return sock;
678}
679
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200680struct accept_wait_data {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200681 struct drbd_connection *connection;
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200682 struct socket *s_listen;
683 struct completion door_bell;
684 void (*original_sk_state_change)(struct sock *sk);
685
686};
687
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200688static void drbd_incoming_connection(struct sock *sk)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700689{
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200690 struct accept_wait_data *ad = sk->sk_user_data;
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200691 void (*state_change)(struct sock *sk);
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200692
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200693 state_change = ad->original_sk_state_change;
694 if (sk->sk_state == TCP_ESTABLISHED)
695 complete(&ad->door_bell);
696 state_change(sk);
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200697}
698
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200699static int prepare_listen_socket(struct drbd_connection *connection, struct accept_wait_data *ad)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700700{
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200701 int err, sndbuf_size, rcvbuf_size, my_addr_len;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200702 struct sockaddr_in6 my_addr;
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200703 struct socket *s_listen;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200704 struct net_conf *nc;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700705 const char *what;
706
Philipp Reisner44ed1672011-04-19 17:10:19 +0200707 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200708 nc = rcu_dereference(connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +0200709 if (!nc) {
710 rcu_read_unlock();
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200711 return -EIO;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200712 }
Philipp Reisner44ed1672011-04-19 17:10:19 +0200713 sndbuf_size = nc->sndbuf_size;
714 rcvbuf_size = nc->rcvbuf_size;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200715 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -0700716
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200717 my_addr_len = min_t(int, connection->my_addr_len, sizeof(struct sockaddr_in6));
718 memcpy(&my_addr, &connection->my_addr, my_addr_len);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700719
720 what = "sock_create_kern";
Eric W. Biedermaneeb1bd52015-05-08 21:08:05 -0500721 err = sock_create_kern(&init_net, ((struct sockaddr *)&my_addr)->sa_family,
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200722 SOCK_STREAM, IPPROTO_TCP, &s_listen);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700723 if (err) {
724 s_listen = NULL;
725 goto out;
726 }
727
Philipp Reisner98683652012-11-09 14:18:43 +0100728 s_listen->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
Philipp Reisner44ed1672011-04-19 17:10:19 +0200729 drbd_setbufsize(s_listen, sndbuf_size, rcvbuf_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700730
731 what = "bind before listen";
Philipp Reisner44ed1672011-04-19 17:10:19 +0200732 err = s_listen->ops->bind(s_listen, (struct sockaddr *)&my_addr, my_addr_len);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700733 if (err < 0)
734 goto out;
735
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200736 ad->s_listen = s_listen;
737 write_lock_bh(&s_listen->sk->sk_callback_lock);
738 ad->original_sk_state_change = s_listen->sk->sk_state_change;
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200739 s_listen->sk->sk_state_change = drbd_incoming_connection;
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200740 s_listen->sk->sk_user_data = ad;
741 write_unlock_bh(&s_listen->sk->sk_callback_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700742
Philipp Reisner2820fd32012-07-12 10:22:48 +0200743 what = "listen";
744 err = s_listen->ops->listen(s_listen, 5);
745 if (err < 0)
746 goto out;
747
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200748 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700749out:
750 if (s_listen)
751 sock_release(s_listen);
752 if (err < 0) {
753 if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200754 drbd_err(connection, "%s failed, err = %d\n", what, err);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200755 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700756 }
757 }
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200758
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200759 return -EIO;
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200760}
761
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200762static void unregister_state_change(struct sock *sk, struct accept_wait_data *ad)
763{
764 write_lock_bh(&sk->sk_callback_lock);
765 sk->sk_state_change = ad->original_sk_state_change;
766 sk->sk_user_data = NULL;
767 write_unlock_bh(&sk->sk_callback_lock);
768}
769
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200770static struct socket *drbd_wait_for_connect(struct drbd_connection *connection, struct accept_wait_data *ad)
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200771{
772 int timeo, connect_int, err = 0;
773 struct socket *s_estab = NULL;
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200774 struct net_conf *nc;
775
776 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200777 nc = rcu_dereference(connection->net_conf);
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200778 if (!nc) {
779 rcu_read_unlock();
780 return NULL;
781 }
782 connect_int = nc->connect_int;
783 rcu_read_unlock();
784
785 timeo = connect_int * HZ;
Akinobu Mita38b682b22013-04-29 16:21:31 -0700786 /* 28.5% random jitter */
787 timeo += (prandom_u32() & 1) ? timeo / 7 : -timeo / 7;
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200788
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200789 err = wait_for_completion_interruptible_timeout(&ad->door_bell, timeo);
790 if (err <= 0)
791 return NULL;
Philipp Reisner1f3e5092012-07-12 11:08:34 +0200792
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200793 err = kernel_accept(ad->s_listen, &s_estab, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700794 if (err < 0) {
795 if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200796 drbd_err(connection, "accept failed, err = %d\n", err);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200797 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700798 }
799 }
Philipp Reisnerb411b362009-09-25 16:07:19 -0700800
Andreas Gruenbacher715306f2012-08-10 17:00:30 +0200801 if (s_estab)
802 unregister_state_change(s_estab->sk, ad);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700803
804 return s_estab;
805}
806
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200807static int decode_header(struct drbd_connection *, void *, struct packet_info *);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700808
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200809static int send_first_packet(struct drbd_connection *connection, struct drbd_socket *sock,
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200810 enum drbd_packet cmd)
811{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200812 if (!conn_prepare_command(connection, sock))
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200813 return -EIO;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200814 return conn_send_command(connection, sock, cmd, 0, NULL, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700815}
816
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200817static int receive_first_packet(struct drbd_connection *connection, struct socket *sock)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700818{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200819 unsigned int header_size = drbd_header_size(connection);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200820 struct packet_info pi;
Philipp Reisner4920e372014-03-18 14:40:13 +0100821 struct net_conf *nc;
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200822 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700823
Philipp Reisner4920e372014-03-18 14:40:13 +0100824 rcu_read_lock();
825 nc = rcu_dereference(connection->net_conf);
826 if (!nc) {
827 rcu_read_unlock();
828 return -EIO;
829 }
830 sock->sk->sk_rcvtimeo = nc->ping_timeo * 4 * HZ / 10;
831 rcu_read_unlock();
832
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200833 err = drbd_recv_short(sock, connection->data.rbuf, header_size, 0);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200834 if (err != header_size) {
835 if (err >= 0)
836 err = -EIO;
837 return err;
838 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200839 err = decode_header(connection, connection->data.rbuf, &pi);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +0200840 if (err)
841 return err;
842 return pi.cmd;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700843}
844
845/**
846 * drbd_socket_okay() - Free the socket if its connection is not okay
Philipp Reisnerb411b362009-09-25 16:07:19 -0700847 * @sock: pointer to the pointer to the socket.
848 */
Philipp Reisner5d0b17f2014-03-18 14:24:35 +0100849static bool drbd_socket_okay(struct socket **sock)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700850{
851 int rr;
852 char tb[4];
853
854 if (!*sock)
Andreas Gruenbacher81e84652010-12-09 15:03:57 +0100855 return false;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700856
Philipp Reisnerdbd9eea2011-02-07 15:34:16 +0100857 rr = drbd_recv_short(*sock, tb, 4, MSG_DONTWAIT | MSG_PEEK);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700858
859 if (rr > 0 || rr == -EAGAIN) {
Andreas Gruenbacher81e84652010-12-09 15:03:57 +0100860 return true;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700861 } else {
862 sock_release(*sock);
863 *sock = NULL;
Andreas Gruenbacher81e84652010-12-09 15:03:57 +0100864 return false;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700865 }
866}
Philipp Reisner5d0b17f2014-03-18 14:24:35 +0100867
868static bool connection_established(struct drbd_connection *connection,
869 struct socket **sock1,
870 struct socket **sock2)
871{
872 struct net_conf *nc;
873 int timeout;
874 bool ok;
875
876 if (!*sock1 || !*sock2)
877 return false;
878
879 rcu_read_lock();
880 nc = rcu_dereference(connection->net_conf);
881 timeout = (nc->sock_check_timeo ?: nc->ping_timeo) * HZ / 10;
882 rcu_read_unlock();
883 schedule_timeout_interruptible(timeout);
884
885 ok = drbd_socket_okay(sock1);
886 ok = drbd_socket_okay(sock2) && ok;
887
888 return ok;
889}
890
Philipp Reisner2325eb62011-03-15 16:56:18 +0100891/* Gets called if a connection is established, or if a new minor gets created
892 in a connection */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200893int drbd_connected(struct drbd_peer_device *peer_device)
Philipp Reisner907599e2011-02-08 11:25:37 +0100894{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200895 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher0829f5e2011-03-24 14:31:22 +0100896 int err;
Philipp Reisner907599e2011-02-08 11:25:37 +0100897
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200898 atomic_set(&device->packet_seq, 0);
899 device->peer_seq = 0;
Philipp Reisner907599e2011-02-08 11:25:37 +0100900
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200901 device->state_mutex = peer_device->connection->agreed_pro_version < 100 ?
902 &peer_device->connection->cstate_mutex :
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200903 &device->own_state_mutex;
Philipp Reisner8410da82011-02-11 20:11:10 +0100904
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200905 err = drbd_send_sync_param(peer_device);
Andreas Gruenbacher0829f5e2011-03-24 14:31:22 +0100906 if (!err)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200907 err = drbd_send_sizes(peer_device, 0, 0);
Andreas Gruenbacher0829f5e2011-03-24 14:31:22 +0100908 if (!err)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200909 err = drbd_send_uuids(peer_device);
Andreas Gruenbacher0829f5e2011-03-24 14:31:22 +0100910 if (!err)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200911 err = drbd_send_current_state(peer_device);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200912 clear_bit(USE_DEGR_WFC_T, &device->flags);
913 clear_bit(RESIZE_PENDING, &device->flags);
914 atomic_set(&device->ap_in_flight, 0);
915 mod_timer(&device->request_timer, jiffies + HZ); /* just start it here. */
Andreas Gruenbacher0829f5e2011-03-24 14:31:22 +0100916 return err;
Philipp Reisner907599e2011-02-08 11:25:37 +0100917}
Philipp Reisnerb411b362009-09-25 16:07:19 -0700918
919/*
920 * return values:
921 * 1 yes, we have a valid connection
922 * 0 oops, did not work out, please try again
923 * -1 peer talks different language,
924 * no point in trying again, please go standalone.
925 * -2 We do not have a network config...
926 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200927static int conn_connect(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700928{
Philipp Reisner7da35862011-12-19 22:42:56 +0100929 struct drbd_socket sock, msock;
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +0200930 struct drbd_peer_device *peer_device;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200931 struct net_conf *nc;
Philipp Reisner5d0b17f2014-03-18 14:24:35 +0100932 int vnr, timeout, h;
933 bool discard_my_data, ok;
Philipp Reisner197296f2012-03-26 16:47:11 +0200934 enum drbd_state_rv rv;
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200935 struct accept_wait_data ad = {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200936 .connection = connection,
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200937 .door_bell = COMPLETION_INITIALIZER_ONSTACK(ad.door_bell),
938 };
Philipp Reisnerb411b362009-09-25 16:07:19 -0700939
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200940 clear_bit(DISCONNECT_SENT, &connection->flags);
941 if (conn_request_state(connection, NS(conn, C_WF_CONNECTION), CS_VERBOSE) < SS_SUCCESS)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700942 return -2;
943
Philipp Reisner7da35862011-12-19 22:42:56 +0100944 mutex_init(&sock.mutex);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200945 sock.sbuf = connection->data.sbuf;
946 sock.rbuf = connection->data.rbuf;
Philipp Reisner7da35862011-12-19 22:42:56 +0100947 sock.socket = NULL;
948 mutex_init(&msock.mutex);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200949 msock.sbuf = connection->meta.sbuf;
950 msock.rbuf = connection->meta.rbuf;
Philipp Reisner7da35862011-12-19 22:42:56 +0100951 msock.socket = NULL;
952
Andreas Gruenbacher0916e0e2011-03-21 14:10:15 +0100953 /* Assume that the peer only understands protocol 80 until we know better. */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200954 connection->agreed_pro_version = 80;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700955
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200956 if (prepare_listen_socket(connection, &ad))
Philipp Reisner7a426fd2012-07-12 14:22:37 +0200957 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700958
959 do {
Andreas Gruenbacher2bf89622011-03-28 16:33:12 +0200960 struct socket *s;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700961
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200962 s = drbd_try_connect(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700963 if (s) {
Philipp Reisner7da35862011-12-19 22:42:56 +0100964 if (!sock.socket) {
965 sock.socket = s;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200966 send_first_packet(connection, &sock, P_INITIAL_DATA);
Philipp Reisner7da35862011-12-19 22:42:56 +0100967 } else if (!msock.socket) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200968 clear_bit(RESOLVE_CONFLICTS, &connection->flags);
Philipp Reisner7da35862011-12-19 22:42:56 +0100969 msock.socket = s;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200970 send_first_packet(connection, &msock, P_INITIAL_META);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700971 } else {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200972 drbd_err(connection, "Logic error in conn_connect()\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700973 goto out_release_sockets;
974 }
975 }
976
Philipp Reisner5d0b17f2014-03-18 14:24:35 +0100977 if (connection_established(connection, &sock.socket, &msock.socket))
978 break;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700979
980retry:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200981 s = drbd_wait_for_connect(connection, &ad);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700982 if (s) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200983 int fp = receive_first_packet(connection, s);
Philipp Reisner7da35862011-12-19 22:42:56 +0100984 drbd_socket_okay(&sock.socket);
985 drbd_socket_okay(&msock.socket);
Philipp Reisner92f14952012-08-01 11:41:01 +0200986 switch (fp) {
Andreas Gruenbachere5d6f332011-03-28 16:44:40 +0200987 case P_INITIAL_DATA:
Philipp Reisner7da35862011-12-19 22:42:56 +0100988 if (sock.socket) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200989 drbd_warn(connection, "initial packet S crossed\n");
Philipp Reisner7da35862011-12-19 22:42:56 +0100990 sock_release(sock.socket);
Philipp Reisner80c6eed2012-08-01 14:53:39 +0200991 sock.socket = s;
992 goto randomize;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700993 }
Philipp Reisner7da35862011-12-19 22:42:56 +0100994 sock.socket = s;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700995 break;
Andreas Gruenbachere5d6f332011-03-28 16:44:40 +0200996 case P_INITIAL_META:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200997 set_bit(RESOLVE_CONFLICTS, &connection->flags);
Philipp Reisner7da35862011-12-19 22:42:56 +0100998 if (msock.socket) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +0200999 drbd_warn(connection, "initial packet M crossed\n");
Philipp Reisner7da35862011-12-19 22:42:56 +01001000 sock_release(msock.socket);
Philipp Reisner80c6eed2012-08-01 14:53:39 +02001001 msock.socket = s;
1002 goto randomize;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001003 }
Philipp Reisner7da35862011-12-19 22:42:56 +01001004 msock.socket = s;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001005 break;
1006 default:
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001007 drbd_warn(connection, "Error receiving initial packet\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07001008 sock_release(s);
Philipp Reisner80c6eed2012-08-01 14:53:39 +02001009randomize:
Akinobu Mita38b682b22013-04-29 16:21:31 -07001010 if (prandom_u32() & 1)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001011 goto retry;
1012 }
1013 }
1014
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001015 if (connection->cstate <= C_DISCONNECTING)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001016 goto out_release_sockets;
1017 if (signal_pending(current)) {
1018 flush_signals(current);
1019 smp_rmb();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001020 if (get_t_state(&connection->receiver) == EXITING)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001021 goto out_release_sockets;
1022 }
1023
Philipp Reisner5d0b17f2014-03-18 14:24:35 +01001024 ok = connection_established(connection, &sock.socket, &msock.socket);
Philipp Reisnerb666dbf2012-07-26 14:12:59 +02001025 } while (!ok);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001026
Philipp Reisner7a426fd2012-07-12 14:22:37 +02001027 if (ad.s_listen)
1028 sock_release(ad.s_listen);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001029
Philipp Reisner98683652012-11-09 14:18:43 +01001030 sock.socket->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
1031 msock.socket->sk->sk_reuse = SK_CAN_REUSE; /* SO_REUSEADDR */
Philipp Reisnerb411b362009-09-25 16:07:19 -07001032
Philipp Reisner7da35862011-12-19 22:42:56 +01001033 sock.socket->sk->sk_allocation = GFP_NOIO;
1034 msock.socket->sk->sk_allocation = GFP_NOIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001035
Philipp Reisner7da35862011-12-19 22:42:56 +01001036 sock.socket->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
1037 msock.socket->sk->sk_priority = TC_PRIO_INTERACTIVE;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001038
Philipp Reisnerb411b362009-09-25 16:07:19 -07001039 /* NOT YET ...
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001040 * sock.socket->sk->sk_sndtimeo = connection->net_conf->timeout*HZ/10;
Philipp Reisner7da35862011-12-19 22:42:56 +01001041 * sock.socket->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
Andreas Gruenbacher60381782011-03-28 17:05:50 +02001042 * first set it to the P_CONNECTION_FEATURES timeout,
Philipp Reisnerb411b362009-09-25 16:07:19 -07001043 * which we set to 4x the configured ping_timeout. */
Philipp Reisner44ed1672011-04-19 17:10:19 +02001044 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001045 nc = rcu_dereference(connection->net_conf);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001046
Philipp Reisner7da35862011-12-19 22:42:56 +01001047 sock.socket->sk->sk_sndtimeo =
1048 sock.socket->sk->sk_rcvtimeo = nc->ping_timeo*4*HZ/10;
Philipp Reisner44ed1672011-04-19 17:10:19 +02001049
Philipp Reisner7da35862011-12-19 22:42:56 +01001050 msock.socket->sk->sk_rcvtimeo = nc->ping_int*HZ;
Philipp Reisner44ed1672011-04-19 17:10:19 +02001051 timeout = nc->timeout * HZ / 10;
Philipp Reisner08b165b2011-09-05 16:22:33 +02001052 discard_my_data = nc->discard_my_data;
Philipp Reisner44ed1672011-04-19 17:10:19 +02001053 rcu_read_unlock();
1054
Philipp Reisner7da35862011-12-19 22:42:56 +01001055 msock.socket->sk->sk_sndtimeo = timeout;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001056
1057 /* we don't want delays.
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001058 * we use TCP_CORK where appropriate, though */
Philipp Reisner7da35862011-12-19 22:42:56 +01001059 drbd_tcp_nodelay(sock.socket);
1060 drbd_tcp_nodelay(msock.socket);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001061
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001062 connection->data.socket = sock.socket;
1063 connection->meta.socket = msock.socket;
1064 connection->last_received = jiffies;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001065
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001066 h = drbd_do_features(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001067 if (h <= 0)
1068 return h;
1069
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001070 if (connection->cram_hmac_tfm) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001071 /* drbd_request_state(device, NS(conn, WFAuth)); */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001072 switch (drbd_do_auth(connection)) {
Johannes Thomab10d96c2010-01-07 16:02:50 +01001073 case -1:
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001074 drbd_err(connection, "Authentication of peer failed\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07001075 return -1;
Johannes Thomab10d96c2010-01-07 16:02:50 +01001076 case 0:
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001077 drbd_err(connection, "Authentication of peer failed, trying again.\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01001078 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001079 }
1080 }
1081
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001082 connection->data.socket->sk->sk_sndtimeo = timeout;
1083 connection->data.socket->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001084
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001085 if (drbd_send_protocol(connection) == -EOPNOTSUPP)
Philipp Reisner7e2455c2010-04-22 14:50:23 +02001086 return -1;
Philipp Reisner1e86ac42011-08-04 10:33:08 +02001087
Philipp Reisner31007742014-04-28 18:43:12 +02001088 /* Prevent a race between resync-handshake and
1089 * being promoted to Primary.
1090 *
1091 * Grab and release the state mutex, so we know that any current
1092 * drbd_set_role() is finished, and any incoming drbd_set_role
1093 * will see the STATE_SENT flag, and wait for it to be cleared.
1094 */
1095 idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
1096 mutex_lock(peer_device->device->state_mutex);
1097
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001098 set_bit(STATE_SENT, &connection->flags);
Philipp Reisner197296f2012-03-26 16:47:11 +02001099
Philipp Reisner31007742014-04-28 18:43:12 +02001100 idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
1101 mutex_unlock(peer_device->device->state_mutex);
1102
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02001103 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02001104 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
1105 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001106 kref_get(&device->kref);
Andreas Gruenbacher26ea8f92013-06-25 16:50:03 +02001107 rcu_read_unlock();
1108
Philipp Reisner08b165b2011-09-05 16:22:33 +02001109 if (discard_my_data)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001110 set_bit(DISCARD_MY_DATA, &device->flags);
Philipp Reisner08b165b2011-09-05 16:22:33 +02001111 else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001112 clear_bit(DISCARD_MY_DATA, &device->flags);
Philipp Reisner08b165b2011-09-05 16:22:33 +02001113
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001114 drbd_connected(peer_device);
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02001115 kref_put(&device->kref, drbd_destroy_device);
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02001116 rcu_read_lock();
1117 }
1118 rcu_read_unlock();
1119
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001120 rv = conn_request_state(connection, NS(conn, C_WF_REPORT_PARAMS), CS_VERBOSE);
1121 if (rv < SS_SUCCESS || connection->cstate != C_WF_REPORT_PARAMS) {
1122 clear_bit(STATE_SENT, &connection->flags);
Philipp Reisner1e86ac42011-08-04 10:33:08 +02001123 return 0;
Philipp Reisnera1096a62012-04-06 12:07:34 +02001124 }
Philipp Reisner1e86ac42011-08-04 10:33:08 +02001125
Philipp Reisner1c03e522015-03-16 15:01:00 +01001126 drbd_thread_start(&connection->ack_receiver);
Lars Ellenberg39e91a62015-03-24 10:40:26 +01001127 /* opencoded create_singlethread_workqueue(),
1128 * to be able to use format string arguments */
1129 connection->ack_sender =
1130 alloc_ordered_workqueue("drbd_as_%s", WQ_MEM_RECLAIM, connection->resource->name);
Philipp Reisner668700b2015-03-16 16:08:29 +01001131 if (!connection->ack_sender) {
1132 drbd_err(connection, "Failed to create workqueue ack_sender\n");
1133 return 0;
1134 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001135
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001136 mutex_lock(&connection->resource->conf_update);
Philipp Reisner08b165b2011-09-05 16:22:33 +02001137 /* The discard_my_data flag is a single-shot modifier to the next
1138 * connection attempt, the handshake of which is now well underway.
1139 * No need for rcu style copying of the whole struct
1140 * just to clear a single value. */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001141 connection->net_conf->discard_my_data = 0;
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001142 mutex_unlock(&connection->resource->conf_update);
Philipp Reisner08b165b2011-09-05 16:22:33 +02001143
Philipp Reisnerd3fcb492011-04-13 14:46:05 -07001144 return h;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001145
1146out_release_sockets:
Philipp Reisner7a426fd2012-07-12 14:22:37 +02001147 if (ad.s_listen)
1148 sock_release(ad.s_listen);
Philipp Reisner7da35862011-12-19 22:42:56 +01001149 if (sock.socket)
1150 sock_release(sock.socket);
1151 if (msock.socket)
1152 sock_release(msock.socket);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001153 return -1;
1154}
1155
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001156static int decode_header(struct drbd_connection *connection, void *header, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001157{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001158 unsigned int header_size = drbd_header_size(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001159
Andreas Gruenbacher0c8e36d2011-03-30 16:00:17 +02001160 if (header_size == sizeof(struct p_header100) &&
1161 *(__be32 *)header == cpu_to_be32(DRBD_MAGIC_100)) {
1162 struct p_header100 *h = header;
1163 if (h->pad != 0) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001164 drbd_err(connection, "Header padding is not zero\n");
Andreas Gruenbacher0c8e36d2011-03-30 16:00:17 +02001165 return -EINVAL;
1166 }
1167 pi->vnr = be16_to_cpu(h->volume);
1168 pi->cmd = be16_to_cpu(h->command);
1169 pi->size = be32_to_cpu(h->length);
1170 } else if (header_size == sizeof(struct p_header95) &&
1171 *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001172 struct p_header95 *h = header;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001173 pi->cmd = be16_to_cpu(h->command);
Andreas Gruenbacherb55d84b2011-03-22 13:17:47 +01001174 pi->size = be32_to_cpu(h->length);
1175 pi->vnr = 0;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001176 } else if (header_size == sizeof(struct p_header80) &&
1177 *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) {
1178 struct p_header80 *h = header;
1179 pi->cmd = be16_to_cpu(h->command);
1180 pi->size = be16_to_cpu(h->length);
Philipp Reisner77351055b2011-02-07 17:24:26 +01001181 pi->vnr = 0;
Philipp Reisner02918be2010-08-20 14:35:10 +02001182 } else {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001183 drbd_err(connection, "Wrong magic value 0x%08x in protocol version %d\n",
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001184 be32_to_cpu(*(__be32 *)header),
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001185 connection->agreed_pro_version);
Andreas Gruenbacher8172f3e2011-03-16 17:22:39 +01001186 return -EINVAL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001187 }
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001188 pi->data = header + header_size;
Andreas Gruenbacher8172f3e2011-03-16 17:22:39 +01001189 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001190}
1191
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001192static int drbd_recv_header(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisner257d0af2011-01-26 12:15:29 +01001193{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001194 void *buffer = connection->data.rbuf;
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01001195 int err;
Philipp Reisner257d0af2011-01-26 12:15:29 +01001196
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001197 err = drbd_recv_all_warn(connection, buffer, drbd_header_size(connection));
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001198 if (err)
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01001199 return err;
Philipp Reisner257d0af2011-01-26 12:15:29 +01001200
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001201 err = decode_header(connection, buffer, pi);
1202 connection->last_received = jiffies;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001203
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01001204 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001205}
1206
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001207static void drbd_flush(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001208{
1209 int rv;
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02001210 struct drbd_peer_device *peer_device;
Philipp Reisner4b0007c2011-11-09 20:12:34 +01001211 int vnr;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001212
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001213 if (connection->resource->write_ordering >= WO_BDEV_FLUSH) {
Lars Ellenberg615e0872011-11-17 14:32:12 +01001214 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02001215 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
1216 struct drbd_device *device = peer_device->device;
1217
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001218 if (!get_ldev(device))
Lars Ellenberg615e0872011-11-17 14:32:12 +01001219 continue;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001220 kref_get(&device->kref);
Lars Ellenberg615e0872011-11-17 14:32:12 +01001221 rcu_read_unlock();
Philipp Reisner4b0007c2011-11-09 20:12:34 +01001222
Lars Ellenbergf4188152014-05-05 23:05:47 +02001223 /* Right now, we have only this one synchronous code path
1224 * for flushes between request epochs.
1225 * We may want to make those asynchronous,
1226 * or at least parallelize the flushes to the volume devices.
1227 */
1228 device->flush_jif = jiffies;
1229 set_bit(FLUSH_PENDING, &device->flags);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001230 rv = blkdev_issue_flush(device->ldev->backing_bdev,
Lars Ellenberg615e0872011-11-17 14:32:12 +01001231 GFP_NOIO, NULL);
Lars Ellenbergf4188152014-05-05 23:05:47 +02001232 clear_bit(FLUSH_PENDING, &device->flags);
Lars Ellenberg615e0872011-11-17 14:32:12 +01001233 if (rv) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001234 drbd_info(device, "local disk flush failed with status %d\n", rv);
Lars Ellenberg615e0872011-11-17 14:32:12 +01001235 /* would rather check on EOPNOTSUPP, but that is not reliable.
1236 * don't try again for ANY return value != 0
1237 * if (rv == -EOPNOTSUPP) */
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001238 drbd_bump_write_ordering(connection->resource, NULL, WO_DRAIN_IO);
Philipp Reisner4b0007c2011-11-09 20:12:34 +01001239 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001240 put_ldev(device);
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02001241 kref_put(&device->kref, drbd_destroy_device);
Lars Ellenberg615e0872011-11-17 14:32:12 +01001242
1243 rcu_read_lock();
1244 if (rv)
1245 break;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001246 }
Lars Ellenberg615e0872011-11-17 14:32:12 +01001247 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07001248 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001249}
1250
1251/**
1252 * drbd_may_finish_epoch() - Applies an epoch_event to the epoch's state, eventually finishes it.
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001253 * @device: DRBD device.
Philipp Reisnerb411b362009-09-25 16:07:19 -07001254 * @epoch: Epoch object.
1255 * @ev: Epoch event.
1256 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001257static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *connection,
Philipp Reisnerb411b362009-09-25 16:07:19 -07001258 struct drbd_epoch *epoch,
1259 enum epoch_event ev)
1260{
Philipp Reisner2451fc32010-08-24 13:43:11 +02001261 int epoch_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001262 struct drbd_epoch *next_epoch;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001263 enum finish_epoch rv = FE_STILL_LIVE;
1264
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001265 spin_lock(&connection->epoch_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001266 do {
1267 next_epoch = NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001268
1269 epoch_size = atomic_read(&epoch->epoch_size);
1270
1271 switch (ev & ~EV_CLEANUP) {
1272 case EV_PUT:
1273 atomic_dec(&epoch->active);
1274 break;
1275 case EV_GOT_BARRIER_NR:
1276 set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001277 break;
1278 case EV_BECAME_LAST:
1279 /* nothing to do*/
1280 break;
1281 }
1282
Philipp Reisnerb411b362009-09-25 16:07:19 -07001283 if (epoch_size != 0 &&
1284 atomic_read(&epoch->active) == 0 &&
Philipp Reisner80f9fd52011-07-18 15:45:15 +02001285 (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) || ev & EV_CLEANUP)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001286 if (!(ev & EV_CLEANUP)) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001287 spin_unlock(&connection->epoch_lock);
1288 drbd_send_b_ack(epoch->connection, epoch->barrier_nr, epoch_size);
1289 spin_lock(&connection->epoch_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001290 }
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02001291#if 0
1292 /* FIXME: dec unacked on connection, once we have
1293 * something to count pending connection packets in. */
Philipp Reisner80f9fd52011-07-18 15:45:15 +02001294 if (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags))
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001295 dec_unacked(epoch->connection);
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02001296#endif
Philipp Reisnerb411b362009-09-25 16:07:19 -07001297
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001298 if (connection->current_epoch != epoch) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001299 next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list);
1300 list_del(&epoch->list);
1301 ev = EV_BECAME_LAST | (ev & EV_CLEANUP);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001302 connection->epochs--;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001303 kfree(epoch);
1304
1305 if (rv == FE_STILL_LIVE)
1306 rv = FE_DESTROYED;
1307 } else {
1308 epoch->flags = 0;
1309 atomic_set(&epoch->epoch_size, 0);
Uwe Kleine-König698f9312010-07-02 20:41:51 +02001310 /* atomic_set(&epoch->active, 0); is already zero */
Philipp Reisnerb411b362009-09-25 16:07:19 -07001311 if (rv == FE_STILL_LIVE)
1312 rv = FE_RECYCLED;
1313 }
1314 }
1315
1316 if (!next_epoch)
1317 break;
1318
1319 epoch = next_epoch;
1320 } while (1);
1321
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001322 spin_unlock(&connection->epoch_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001323
Philipp Reisnerb411b362009-09-25 16:07:19 -07001324 return rv;
1325}
1326
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01001327static enum write_ordering_e
1328max_allowed_wo(struct drbd_backing_dev *bdev, enum write_ordering_e wo)
1329{
1330 struct disk_conf *dc;
1331
1332 dc = rcu_dereference(bdev->disk_conf);
1333
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001334 if (wo == WO_BDEV_FLUSH && !dc->disk_flushes)
1335 wo = WO_DRAIN_IO;
1336 if (wo == WO_DRAIN_IO && !dc->disk_drain)
1337 wo = WO_NONE;
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01001338
1339 return wo;
1340}
1341
Philipp Reisnerb411b362009-09-25 16:07:19 -07001342/**
1343 * drbd_bump_write_ordering() - Fall back to an other write ordering method
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001344 * @connection: DRBD connection.
Philipp Reisnerb411b362009-09-25 16:07:19 -07001345 * @wo: Write ordering method to try.
1346 */
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01001347void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backing_dev *bdev,
1348 enum write_ordering_e wo)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001349{
Philipp Reisnere9526582013-11-22 15:53:41 +01001350 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001351 enum write_ordering_e pwo;
Philipp Reisner4b0007c2011-11-09 20:12:34 +01001352 int vnr;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001353 static char *write_ordering_str[] = {
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001354 [WO_NONE] = "none",
1355 [WO_DRAIN_IO] = "drain",
1356 [WO_BDEV_FLUSH] = "flush",
Philipp Reisnerb411b362009-09-25 16:07:19 -07001357 };
1358
Philipp Reisnere9526582013-11-22 15:53:41 +01001359 pwo = resource->write_ordering;
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001360 if (wo != WO_BDEV_FLUSH)
Lars Ellenberg70df7092013-12-20 11:17:02 +01001361 wo = min(pwo, wo);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02001362 rcu_read_lock();
Philipp Reisnere9526582013-11-22 15:53:41 +01001363 idr_for_each_entry(&resource->devices, device, vnr) {
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01001364 if (get_ldev(device)) {
1365 wo = max_allowed_wo(device->ldev, wo);
1366 if (device->ldev == bdev)
1367 bdev = NULL;
1368 put_ldev(device);
1369 }
Philipp Reisner4b0007c2011-11-09 20:12:34 +01001370 }
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01001371
1372 if (bdev)
1373 wo = max_allowed_wo(bdev, wo);
1374
Lars Ellenberg70df7092013-12-20 11:17:02 +01001375 rcu_read_unlock();
1376
Philipp Reisnere9526582013-11-22 15:53:41 +01001377 resource->write_ordering = wo;
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001378 if (pwo != resource->write_ordering || wo == WO_BDEV_FLUSH)
Philipp Reisnere9526582013-11-22 15:53:41 +01001379 drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001380}
1381
1382/**
Andreas Gruenbacherfbe29de2011-02-17 16:38:35 +01001383 * drbd_submit_peer_request()
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001384 * @device: DRBD device.
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001385 * @peer_req: peer request
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001386 * @rw: flag field, see bio->bi_rw
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001387 *
1388 * May spread the pages to multiple bios,
1389 * depending on bio_add_page restrictions.
1390 *
1391 * Returns 0 if all bios have been submitted,
1392 * -ENOMEM if we could not allocate enough bios,
1393 * -ENOSPC (any better suggestion?) if we have not been able to bio_add_page a
1394 * single page to an empty bio (which should never happen and likely indicates
1395 * that the lower level IO stack is in some way broken). This has been observed
1396 * on certain Xen deployments.
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001397 */
1398/* TODO allocate from our own bio_set. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001399int drbd_submit_peer_request(struct drbd_device *device,
Andreas Gruenbacherfbe29de2011-02-17 16:38:35 +01001400 struct drbd_peer_request *peer_req,
Mike Christiebb3cc852016-06-05 14:32:06 -05001401 const unsigned op, const unsigned op_flags,
1402 const int fault_type)
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001403{
1404 struct bio *bios = NULL;
1405 struct bio *bio;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001406 struct page *page = peer_req->pages;
1407 sector_t sector = peer_req->i.sector;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001408 unsigned data_size = peer_req->i.size;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001409 unsigned n_bios = 0;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001410 unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001411 int err = -ENOMEM;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001412
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001413 if (peer_req->flags & EE_IS_TRIM_USE_ZEROOUT) {
1414 /* wait for all pending IO completions, before we start
1415 * zeroing things out. */
Andreas Gruenbacher5dd2ca12014-08-11 16:59:23 +02001416 conn_wait_active_ee_empty(peer_req->peer_device->connection);
Lars Ellenberg45d29332014-04-23 12:25:23 +02001417 /* add it to the active list now,
1418 * so we can find it to present it in debugfs */
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02001419 peer_req->submit_jif = jiffies;
1420 peer_req->flags |= EE_SUBMITTED;
Lars Ellenberg45d29332014-04-23 12:25:23 +02001421 spin_lock_irq(&device->resource->req_lock);
1422 list_add_tail(&peer_req->w.list, &device->active_ee);
1423 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001424 if (blkdev_issue_zeroout(device->ldev->backing_bdev,
Martin K. Petersend93ba7a2015-01-20 20:06:30 -05001425 sector, data_size >> 9, GFP_NOIO, false))
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001426 peer_req->flags |= EE_WAS_ERROR;
1427 drbd_endio_write_sec_final(peer_req);
1428 return 0;
1429 }
1430
Lars Ellenberg54ed4ed2014-06-25 17:52:38 +02001431 /* Discards don't have any payload.
1432 * But the scsi layer still expects a bio_vec it can use internally,
1433 * see sd_setup_discard_cmnd() and blk_add_request_payload(). */
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001434 if (peer_req->flags & EE_IS_TRIM)
Lars Ellenberg54ed4ed2014-06-25 17:52:38 +02001435 nr_pages = 1;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001436
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001437 /* In most cases, we will only need one bio. But in case the lower
1438 * level restrictions happen to be different at this offset on this
1439 * side than those of the sending peer, we may need to submit the
Lars Ellenberg9476f392011-02-23 17:02:01 +01001440 * request in more than one bio.
1441 *
1442 * Plain bio_alloc is good enough here, this is no DRBD internally
1443 * generated bio, but a bio allocated on behalf of the peer.
1444 */
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001445next_bio:
1446 bio = bio_alloc(GFP_NOIO, nr_pages);
1447 if (!bio) {
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001448 drbd_err(device, "submit_ee: Allocation of a bio failed (nr_pages=%u)\n", nr_pages);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001449 goto fail;
1450 }
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001451 /* > peer_req->i.sector, unless this is the first bio */
Kent Overstreet4f024f32013-10-11 15:44:27 -07001452 bio->bi_iter.bi_sector = sector;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001453 bio->bi_bdev = device->ldev->backing_bdev;
Mike Christiebb3cc852016-06-05 14:32:06 -05001454 bio_set_op_attrs(bio, op, op_flags);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001455 bio->bi_private = peer_req;
Andreas Gruenbacherfcefa622011-02-17 16:46:59 +01001456 bio->bi_end_io = drbd_peer_request_endio;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001457
1458 bio->bi_next = bios;
1459 bios = bio;
1460 ++n_bios;
1461
Mike Christiebb3cc852016-06-05 14:32:06 -05001462 if (op == REQ_OP_DISCARD) {
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001463 bio->bi_iter.bi_size = data_size;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001464 goto submit;
1465 }
1466
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001467 page_chain_for_each(page) {
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001468 unsigned len = min_t(unsigned, data_size, PAGE_SIZE);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001469 if (!bio_add_page(bio, page, len, 0)) {
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001470 /* A single page must always be possible!
1471 * But in case it fails anyways,
1472 * we deal with it, and complain (below). */
1473 if (bio->bi_vcnt == 0) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001474 drbd_err(device,
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001475 "bio_add_page failed for len=%u, "
1476 "bi_vcnt=0 (bi_sector=%llu)\n",
Kent Overstreet4f024f32013-10-11 15:44:27 -07001477 len, (uint64_t)bio->bi_iter.bi_sector);
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001478 err = -ENOSPC;
1479 goto fail;
1480 }
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001481 goto next_bio;
1482 }
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001483 data_size -= len;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001484 sector += len >> 9;
1485 --nr_pages;
1486 }
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001487 D_ASSERT(device, data_size == 0);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001488submit:
1489 D_ASSERT(device, page == NULL);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001490
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001491 atomic_set(&peer_req->pending_bios, n_bios);
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02001492 /* for debugfs: update timestamp, mark as submitted */
1493 peer_req->submit_jif = jiffies;
1494 peer_req->flags |= EE_SUBMITTED;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001495 do {
1496 bio = bios;
1497 bios = bios->bi_next;
1498 bio->bi_next = NULL;
1499
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001500 drbd_generic_make_request(device, fault_type, bio);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001501 } while (bios);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001502 return 0;
1503
1504fail:
1505 while (bios) {
1506 bio = bios;
1507 bios = bios->bi_next;
1508 bio_put(bio);
1509 }
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001510 return err;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001511}
1512
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001513static void drbd_remove_epoch_entry_interval(struct drbd_device *device,
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001514 struct drbd_peer_request *peer_req)
Andreas Gruenbacher53840642011-01-28 10:31:04 +01001515{
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001516 struct drbd_interval *i = &peer_req->i;
Andreas Gruenbacher53840642011-01-28 10:31:04 +01001517
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001518 drbd_remove_interval(&device->write_requests, i);
Andreas Gruenbacher53840642011-01-28 10:31:04 +01001519 drbd_clear_interval(i);
1520
Andreas Gruenbacher6c852be2011-02-04 15:38:52 +01001521 /* Wake up any processes waiting for this peer request to complete. */
Andreas Gruenbacher53840642011-01-28 10:31:04 +01001522 if (i->waiting)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001523 wake_up(&device->misc_wait);
Andreas Gruenbacher53840642011-01-28 10:31:04 +01001524}
1525
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001526static void conn_wait_active_ee_empty(struct drbd_connection *connection)
Philipp Reisner77fede52011-11-10 21:19:11 +01001527{
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02001528 struct drbd_peer_device *peer_device;
Philipp Reisner77fede52011-11-10 21:19:11 +01001529 int vnr;
1530
1531 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02001532 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
1533 struct drbd_device *device = peer_device->device;
1534
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001535 kref_get(&device->kref);
Philipp Reisner77fede52011-11-10 21:19:11 +01001536 rcu_read_unlock();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001537 drbd_wait_ee_list_empty(device, &device->active_ee);
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02001538 kref_put(&device->kref, drbd_destroy_device);
Philipp Reisner77fede52011-11-10 21:19:11 +01001539 rcu_read_lock();
1540 }
1541 rcu_read_unlock();
1542}
1543
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001544static int receive_Barrier(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001545{
Philipp Reisner2451fc32010-08-24 13:43:11 +02001546 int rv;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001547 struct p_barrier *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001548 struct drbd_epoch *epoch;
1549
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02001550 /* FIXME these are unacked on connection,
1551 * not a specific (peer)device.
1552 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001553 connection->current_epoch->barrier_nr = p->barrier;
1554 connection->current_epoch->connection = connection;
1555 rv = drbd_may_finish_epoch(connection, connection->current_epoch, EV_GOT_BARRIER_NR);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001556
1557 /* P_BARRIER_ACK may imply that the corresponding extent is dropped from
1558 * the activity log, which means it would not be resynced in case the
1559 * R_PRIMARY crashes now.
1560 * Therefore we must send the barrier_ack after the barrier request was
1561 * completed. */
Philipp Reisnere9526582013-11-22 15:53:41 +01001562 switch (connection->resource->write_ordering) {
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001563 case WO_NONE:
Philipp Reisnerb411b362009-09-25 16:07:19 -07001564 if (rv == FE_RECYCLED)
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001565 return 0;
Philipp Reisner2451fc32010-08-24 13:43:11 +02001566
1567 /* receiver context, in the writeout path of the other node.
1568 * avoid potential distributed deadlock */
1569 epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
1570 if (epoch)
1571 break;
1572 else
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02001573 drbd_warn(connection, "Allocation of an epoch failed, slowing down\n");
Philipp Reisner2451fc32010-08-24 13:43:11 +02001574 /* Fall through */
Philipp Reisnerb411b362009-09-25 16:07:19 -07001575
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +02001576 case WO_BDEV_FLUSH:
1577 case WO_DRAIN_IO:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001578 conn_wait_active_ee_empty(connection);
1579 drbd_flush(connection);
Philipp Reisner2451fc32010-08-24 13:43:11 +02001580
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001581 if (atomic_read(&connection->current_epoch->epoch_size)) {
Philipp Reisner2451fc32010-08-24 13:43:11 +02001582 epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
1583 if (epoch)
1584 break;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001585 }
1586
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001587 return 0;
Philipp Reisner2451fc32010-08-24 13:43:11 +02001588 default:
Philipp Reisnere9526582013-11-22 15:53:41 +01001589 drbd_err(connection, "Strangeness in connection->write_ordering %d\n",
1590 connection->resource->write_ordering);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001591 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001592 }
1593
1594 epoch->flags = 0;
1595 atomic_set(&epoch->epoch_size, 0);
1596 atomic_set(&epoch->active, 0);
1597
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001598 spin_lock(&connection->epoch_lock);
1599 if (atomic_read(&connection->current_epoch->epoch_size)) {
1600 list_add(&epoch->list, &connection->current_epoch->list);
1601 connection->current_epoch = epoch;
1602 connection->epochs++;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001603 } else {
1604 /* The current_epoch got recycled while we allocated this one... */
1605 kfree(epoch);
1606 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001607 spin_unlock(&connection->epoch_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001608
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001609 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001610}
1611
1612/* used from receive_RSDataReply (recv_resync_read)
1613 * and from receive_Data */
Andreas Gruenbacherf6ffca92011-02-04 15:30:34 +01001614static struct drbd_peer_request *
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001615read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001616 struct packet_info *pi) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001617{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001618 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001619 const sector_t capacity = drbd_get_capacity(device->this_bdev);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001620 struct drbd_peer_request *peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001621 struct page *page;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001622 int digest_size, err;
1623 unsigned int data_size = pi->size, ds;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001624 void *dig_in = peer_device->connection->int_dig_in;
1625 void *dig_vv = peer_device->connection->int_dig_vv;
Philipp Reisner6b4388a2010-04-26 14:11:45 +02001626 unsigned long *data;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001627 struct p_trim *trim = (pi->cmd == P_TRIM) ? pi->data : NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001628
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001629 digest_size = 0;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001630 if (!trim && peer_device->connection->peer_integrity_tfm) {
Herbert Xu9534d672016-01-24 21:19:21 +08001631 digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02001632 /*
1633 * FIXME: Receive the incoming digest into the receive buffer
1634 * here, together with its struct p_data?
1635 */
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001636 err = drbd_recv_all_warn(peer_device->connection, dig_in, digest_size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001637 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001638 return NULL;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001639 data_size -= digest_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001640 }
1641
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001642 if (trim) {
1643 D_ASSERT(peer_device, data_size == 0);
1644 data_size = be32_to_cpu(trim->size);
1645 }
1646
Andreas Gruenbacher841ce242010-12-15 19:31:20 +01001647 if (!expect(IS_ALIGNED(data_size, 512)))
1648 return NULL;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001649 /* prepare for larger trim requests. */
1650 if (!trim && !expect(data_size <= DRBD_MAX_BIO_SIZE))
Andreas Gruenbacher841ce242010-12-15 19:31:20 +01001651 return NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001652
Lars Ellenberg66660322010-04-06 12:15:04 +02001653 /* even though we trust out peer,
1654 * we sometimes have to double check. */
1655 if (sector + (data_size>>9) > capacity) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001656 drbd_err(device, "request from peer beyond end of local disk: "
Lars Ellenbergfdda6542011-01-24 15:11:01 +01001657 "capacity: %llus < sector: %llus + size: %u\n",
Lars Ellenberg66660322010-04-06 12:15:04 +02001658 (unsigned long long)capacity,
1659 (unsigned long long)sector, data_size);
1660 return NULL;
1661 }
1662
Philipp Reisnerb411b362009-09-25 16:07:19 -07001663 /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
1664 * "criss-cross" setup, that might cause write-out on some other DRBD,
1665 * which in turn might block on the other node at this very place. */
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001666 peer_req = drbd_alloc_peer_req(peer_device, id, sector, data_size, trim == NULL, GFP_NOIO);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001667 if (!peer_req)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001668 return NULL;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001669
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02001670 peer_req->flags |= EE_WRITE;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001671 if (trim)
Lars Ellenberg81a35372012-07-30 09:00:54 +02001672 return peer_req;
Lars Ellenberga73ff322012-06-25 19:15:38 +02001673
Philipp Reisnerb411b362009-09-25 16:07:19 -07001674 ds = data_size;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001675 page = peer_req->pages;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001676 page_chain_for_each(page) {
1677 unsigned len = min_t(int, ds, PAGE_SIZE);
Philipp Reisner6b4388a2010-04-26 14:11:45 +02001678 data = kmap(page);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001679 err = drbd_recv_all_warn(peer_device->connection, data, len);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001680 if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001681 drbd_err(device, "Fault injection: Corrupting data on receive\n");
Philipp Reisner6b4388a2010-04-26 14:11:45 +02001682 data[0] = data[0] ^ (unsigned long)-1;
1683 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001684 kunmap(page);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001685 if (err) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001686 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001687 return NULL;
1688 }
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001689 ds -= len;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001690 }
1691
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001692 if (digest_size) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001693 drbd_csum_ee(peer_device->connection->peer_integrity_tfm, peer_req, dig_vv);
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001694 if (memcmp(dig_in, dig_vv, digest_size)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001695 drbd_err(device, "Digest integrity check FAILED: %llus +%u\n",
Lars Ellenberg470be442010-11-10 10:36:52 +01001696 (unsigned long long)sector, data_size);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001697 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001698 return NULL;
1699 }
1700 }
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001701 device->recv_cnt += data_size >> 9;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001702 return peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001703}
1704
1705/* drbd_drain_block() just takes a data block
1706 * out of the socket input buffer, and discards it.
1707 */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001708static int drbd_drain_block(struct drbd_peer_device *peer_device, int data_size)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001709{
1710 struct page *page;
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001711 int err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001712 void *data;
1713
Lars Ellenbergc3470cd2010-04-01 16:57:19 +02001714 if (!data_size)
Andreas Gruenbacherfc5be832011-03-16 17:50:50 +01001715 return 0;
Lars Ellenbergc3470cd2010-04-01 16:57:19 +02001716
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001717 page = drbd_alloc_pages(peer_device, 1, 1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001718
1719 data = kmap(page);
1720 while (data_size) {
Andreas Gruenbacherfc5be832011-03-16 17:50:50 +01001721 unsigned int len = min_t(int, data_size, PAGE_SIZE);
1722
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001723 err = drbd_recv_all_warn(peer_device->connection, data, len);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001724 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001725 break;
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001726 data_size -= len;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001727 }
1728 kunmap(page);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001729 drbd_free_pages(peer_device->device, page, 0);
Andreas Gruenbacherfc5be832011-03-16 17:50:50 +01001730 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001731}
1732
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001733static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_request *req,
Philipp Reisnerb411b362009-09-25 16:07:19 -07001734 sector_t sector, int data_size)
1735{
Kent Overstreet79886132013-11-23 17:19:00 -08001736 struct bio_vec bvec;
1737 struct bvec_iter iter;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001738 struct bio *bio;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001739 int digest_size, err, expect;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001740 void *dig_in = peer_device->connection->int_dig_in;
1741 void *dig_vv = peer_device->connection->int_dig_vv;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001742
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001743 digest_size = 0;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001744 if (peer_device->connection->peer_integrity_tfm) {
Herbert Xu9534d672016-01-24 21:19:21 +08001745 digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm);
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001746 err = drbd_recv_all_warn(peer_device->connection, dig_in, digest_size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001747 if (err)
1748 return err;
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001749 data_size -= digest_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001750 }
1751
Philipp Reisnerb411b362009-09-25 16:07:19 -07001752 /* optimistically update recv_cnt. if receiving fails below,
1753 * we disconnect anyways, and counters will be reset. */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001754 peer_device->device->recv_cnt += data_size>>9;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001755
1756 bio = req->master_bio;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001757 D_ASSERT(peer_device->device, sector == bio->bi_iter.bi_sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001758
Kent Overstreet79886132013-11-23 17:19:00 -08001759 bio_for_each_segment(bvec, bio, iter) {
1760 void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
1761 expect = min_t(int, data_size, bvec.bv_len);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001762 err = drbd_recv_all_warn(peer_device->connection, mapped, expect);
Kent Overstreet79886132013-11-23 17:19:00 -08001763 kunmap(bvec.bv_page);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01001764 if (err)
1765 return err;
1766 data_size -= expect;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001767 }
1768
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001769 if (digest_size) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001770 drbd_csum_bio(peer_device->connection->peer_integrity_tfm, bio, dig_vv);
Andreas Gruenbacher11f8b2b2014-09-11 14:29:05 +02001771 if (memcmp(dig_in, dig_vv, digest_size)) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001772 drbd_err(peer_device, "Digest integrity check FAILED. Broken NICs?\n");
Andreas Gruenbacher28284ce2011-03-16 17:54:02 +01001773 return -EINVAL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001774 }
1775 }
1776
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001777 D_ASSERT(peer_device->device, data_size == 0);
Andreas Gruenbacher28284ce2011-03-16 17:54:02 +01001778 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001779}
1780
Andreas Gruenbachera990be42011-04-06 17:56:48 +02001781/*
Philipp Reisner668700b2015-03-16 16:08:29 +01001782 * e_end_resync_block() is called in ack_sender context via
Andreas Gruenbachera990be42011-04-06 17:56:48 +02001783 * drbd_finish_peer_reqs().
1784 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001785static int e_end_resync_block(struct drbd_work *w, int unused)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001786{
Andreas Gruenbacher8050e6d2011-02-18 16:12:48 +01001787 struct drbd_peer_request *peer_req =
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001788 container_of(w, struct drbd_peer_request, w);
1789 struct drbd_peer_device *peer_device = peer_req->peer_device;
1790 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001791 sector_t sector = peer_req->i.sector;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001792 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001793
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001794 D_ASSERT(device, drbd_interval_empty(&peer_req->i));
Philipp Reisnerb411b362009-09-25 16:07:19 -07001795
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001796 if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001797 drbd_set_in_sync(device, sector, peer_req->i.size);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001798 err = drbd_send_ack(peer_device, P_RS_WRITE_ACK, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001799 } else {
1800 /* Record failure to sync */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001801 drbd_rs_failed_io(device, sector, peer_req->i.size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001802
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001803 err = drbd_send_ack(peer_device, P_NEG_ACK, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001804 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001805 dec_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001806
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001807 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001808}
1809
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001810static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t sector,
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001811 struct packet_info *pi) __releases(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001812{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001813 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001814 struct drbd_peer_request *peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001815
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001816 peer_req = read_in_block(peer_device, ID_SYNCER, sector, pi);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001817 if (!peer_req)
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001818 goto fail;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001819
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001820 dec_rs_pending(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001821
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001822 inc_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001823 /* corresponding dec_unacked() in e_end_resync_block()
1824 * respective _drbd_clear_done_ee */
1825
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001826 peer_req->w.cb = e_end_resync_block;
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02001827 peer_req->submit_jif = jiffies;
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001828
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001829 spin_lock_irq(&device->resource->req_lock);
Lars Ellenbergb9ed7082014-04-23 12:15:35 +02001830 list_add_tail(&peer_req->w.list, &device->sync_ee);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001831 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001832
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001833 atomic_add(pi->size >> 9, &device->rs_sect_ev);
Mike Christiebb3cc852016-06-05 14:32:06 -05001834 if (drbd_submit_peer_request(device, peer_req, REQ_OP_WRITE, 0,
1835 DRBD_FAULT_RS_WR) == 0)
Andreas Gruenbachere1c1b0f2011-03-16 17:58:27 +01001836 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001837
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01001838 /* don't care for the reason here */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001839 drbd_err(device, "submit failed, triggering re-connect\n");
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001840 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001841 list_del(&peer_req->w.list);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001842 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberg22cc37a2010-09-14 20:40:41 +02001843
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001844 drbd_free_peer_req(device, peer_req);
Lars Ellenberg45bb9122010-05-14 17:10:48 +02001845fail:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001846 put_ldev(device);
Andreas Gruenbachere1c1b0f2011-03-16 17:58:27 +01001847 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001848}
1849
Andreas Gruenbacher668eebc2011-01-20 17:14:26 +01001850static struct drbd_request *
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001851find_request(struct drbd_device *device, struct rb_root *root, u64 id,
Andreas Gruenbacherbc9c5c42011-01-21 18:00:55 +01001852 sector_t sector, bool missing_ok, const char *func)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001853{
1854 struct drbd_request *req;
Andreas Gruenbacher668eebc2011-01-20 17:14:26 +01001855
Andreas Gruenbacherbc9c5c42011-01-21 18:00:55 +01001856 /* Request object according to our peer */
1857 req = (struct drbd_request *)(unsigned long)id;
Andreas Gruenbacher5e472262011-01-27 14:42:51 +01001858 if (drbd_contains_interval(root, sector, &req->i) && req->i.local)
Andreas Gruenbacher668eebc2011-01-20 17:14:26 +01001859 return req;
Andreas Gruenbacherc3afd8f2011-01-20 22:25:40 +01001860 if (!missing_ok) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001861 drbd_err(device, "%s: failed to find request 0x%lx, sector %llus\n", func,
Andreas Gruenbacherc3afd8f2011-01-20 22:25:40 +01001862 (unsigned long)id, (unsigned long long)sector);
1863 }
Andreas Gruenbacher668eebc2011-01-20 17:14:26 +01001864 return NULL;
1865}
1866
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001867static int receive_DataReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001868{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001869 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001870 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001871 struct drbd_request *req;
1872 sector_t sector;
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001873 int err;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001874 struct p_data *p = pi->data;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01001875
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001876 peer_device = conn_peer_device(connection, pi->vnr);
1877 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01001878 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001879 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001880
1881 sector = be64_to_cpu(p->sector);
1882
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001883 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001884 req = find_request(device, &device->read_requests, p->block_id, sector, false, __func__);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001885 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacherc3afd8f2011-01-20 22:25:40 +01001886 if (unlikely(!req))
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001887 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001888
Bart Van Assche24c48302011-05-21 18:32:29 +02001889 /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
Philipp Reisnerb411b362009-09-25 16:07:19 -07001890 * special casing it there for the various failure cases.
1891 * still no race with drbd_fail_pending_reads */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001892 err = recv_dless_read(peer_device, req, sector, pi->size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001893 if (!err)
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01001894 req_mod(req, DATA_RECEIVED);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001895 /* else: nothing. handled from drbd_disconnect...
1896 * I don't think we may complete this just yet
1897 * in case we are "on-disconnect: freeze" */
1898
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001899 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001900}
1901
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001902static int receive_RSDataReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001903{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001904 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001905 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001906 sector_t sector;
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001907 int err;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02001908 struct p_data *p = pi->data;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01001909
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001910 peer_device = conn_peer_device(connection, pi->vnr);
1911 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01001912 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02001913 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001914
1915 sector = be64_to_cpu(p->sector);
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001916 D_ASSERT(device, p->block_id == ID_SYNCER);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001917
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001918 if (get_ldev(device)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001919 /* data is submitted to disk within recv_resync_read.
1920 * corresponding put_ldev done below on error,
Andreas Gruenbacherfcefa622011-02-17 16:46:59 +01001921 * or in drbd_peer_request_endio. */
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02001922 err = recv_resync_read(peer_device, sector, pi);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001923 } else {
1924 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001925 drbd_err(device, "Can not write resync data to local disk.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07001926
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001927 err = drbd_drain_block(peer_device, pi->size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001928
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001929 drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001930 }
1931
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001932 atomic_add(pi->size >> 9, &device->rs_sect_in);
Philipp Reisner778f2712010-07-06 11:14:00 +02001933
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01001934 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001935}
1936
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001937static void restart_conflicting_writes(struct drbd_device *device,
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01001938 sector_t sector, int size)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001939{
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01001940 struct drbd_interval *i;
1941 struct drbd_request *req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001942
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001943 drbd_for_each_overlap(i, &device->write_requests, sector, size) {
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01001944 if (!i->local)
1945 continue;
1946 req = container_of(i, struct drbd_request, i);
1947 if (req->rq_state & RQ_LOCAL_PENDING ||
1948 !(req->rq_state & RQ_POSTPONED))
1949 continue;
Lars Ellenberg2312f0b32011-11-24 10:36:25 +01001950 /* as it is RQ_POSTPONED, this will cause it to
1951 * be queued on the retry workqueue. */
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02001952 __req_mod(req, CONFLICT_RESOLVED, NULL);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01001953 }
1954}
1955
Andreas Gruenbachera990be42011-04-06 17:56:48 +02001956/*
Philipp Reisner668700b2015-03-16 16:08:29 +01001957 * e_end_block() is called in ack_sender context via drbd_finish_peer_reqs().
Philipp Reisnerb411b362009-09-25 16:07:19 -07001958 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001959static int e_end_block(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001960{
Andreas Gruenbacher8050e6d2011-02-18 16:12:48 +01001961 struct drbd_peer_request *peer_req =
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001962 container_of(w, struct drbd_peer_request, w);
1963 struct drbd_peer_device *peer_device = peer_req->peer_device;
1964 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001965 sector_t sector = peer_req->i.sector;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001966 int err = 0, pcmd;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001967
Philipp Reisner303d1442011-04-13 16:24:47 -07001968 if (peer_req->flags & EE_SEND_WRITE_ACK) {
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001969 if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001970 pcmd = (device->state.conn >= C_SYNC_SOURCE &&
1971 device->state.conn <= C_PAUSED_SYNC_T &&
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001972 peer_req->flags & EE_MAY_SET_IN_SYNC) ?
Philipp Reisnerb411b362009-09-25 16:07:19 -07001973 P_RS_WRITE_ACK : P_WRITE_ACK;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001974 err = drbd_send_ack(peer_device, pcmd, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001975 if (pcmd == P_RS_WRITE_ACK)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001976 drbd_set_in_sync(device, sector, peer_req->i.size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001977 } else {
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001978 err = drbd_send_ack(peer_device, P_NEG_ACK, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001979 /* we expect it to be marked out of sync anyways...
1980 * maybe assert this? */
1981 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001982 dec_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001983 }
Lars Ellenberg08d0dab2014-03-20 11:19:22 +01001984
Philipp Reisnerb411b362009-09-25 16:07:19 -07001985 /* we delete from the conflict detection hash _after_ we sent out the
1986 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right. */
Philipp Reisner302bdea2011-04-21 11:36:49 +02001987 if (peer_req->flags & EE_IN_INTERVAL_TREE) {
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001988 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001989 D_ASSERT(device, !drbd_interval_empty(&peer_req->i));
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001990 drbd_remove_epoch_entry_interval(device, peer_req);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01001991 if (peer_req->flags & EE_RESTART_REQUESTS)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001992 restart_conflicting_writes(device, sector, peer_req->i.size);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02001993 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacherbb3bfe92011-01-21 15:59:23 +01001994 } else
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001995 D_ASSERT(device, drbd_interval_empty(&peer_req->i));
Philipp Reisnerb411b362009-09-25 16:07:19 -07001996
Andreas Gruenbacher5dd2ca12014-08-11 16:59:23 +02001997 drbd_may_finish_epoch(peer_device->connection, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
Philipp Reisnerb411b362009-09-25 16:07:19 -07001998
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001999 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002000}
2001
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002002static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002003{
Andreas Gruenbacher8050e6d2011-02-18 16:12:48 +01002004 struct drbd_peer_request *peer_req =
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002005 container_of(w, struct drbd_peer_request, w);
2006 struct drbd_peer_device *peer_device = peer_req->peer_device;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01002007 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002008
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002009 err = drbd_send_ack(peer_device, ack, peer_req);
2010 dec_unacked(peer_device->device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002011
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01002012 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002013}
2014
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002015static int e_send_superseded(struct drbd_work *w, int unused)
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002016{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002017 return e_send_ack(w, P_SUPERSEDED);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002018}
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002019
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01002020static int e_send_retry_write(struct drbd_work *w, int unused)
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002021{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002022 struct drbd_peer_request *peer_req =
2023 container_of(w, struct drbd_peer_request, w);
2024 struct drbd_connection *connection = peer_req->peer_device->connection;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002025
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002026 return e_send_ack(w, connection->agreed_pro_version >= 100 ?
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002027 P_RETRY_WRITE : P_SUPERSEDED);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002028}
2029
Andreas Gruenbacher3e394da2011-01-26 18:36:55 +01002030static bool seq_greater(u32 a, u32 b)
2031{
2032 /*
2033 * We assume 32-bit wrap-around here.
2034 * For 24-bit wrap-around, we would have to shift:
2035 * a <<= 8; b <<= 8;
2036 */
2037 return (s32)a - (s32)b > 0;
2038}
2039
2040static u32 seq_max(u32 a, u32 b)
2041{
2042 return seq_greater(a, b) ? a : b;
2043}
2044
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002045static void update_peer_seq(struct drbd_peer_device *peer_device, unsigned int peer_seq)
Andreas Gruenbacher3e394da2011-01-26 18:36:55 +01002046{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002047 struct drbd_device *device = peer_device->device;
Lars Ellenberg3c13b682011-02-23 16:10:01 +01002048 unsigned int newest_peer_seq;
Andreas Gruenbacher3e394da2011-01-26 18:36:55 +01002049
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002050 if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002051 spin_lock(&device->peer_seq_lock);
2052 newest_peer_seq = seq_max(device->peer_seq, peer_seq);
2053 device->peer_seq = newest_peer_seq;
2054 spin_unlock(&device->peer_seq_lock);
2055 /* wake up only if we actually changed device->peer_seq */
Lars Ellenberg3c13b682011-02-23 16:10:01 +01002056 if (peer_seq == newest_peer_seq)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002057 wake_up(&device->seq_wait);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002058 }
Andreas Gruenbacher3e394da2011-01-26 18:36:55 +01002059}
2060
Lars Ellenbergd93f6302012-03-26 15:49:13 +02002061static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2)
2062{
2063 return !((s1 + (l1>>9) <= s2) || (s1 >= s2 + (l2>>9)));
2064}
2065
2066/* maybe change sync_ee into interval trees as well? */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002067static bool overlapping_resync_write(struct drbd_device *device, struct drbd_peer_request *peer_req)
Lars Ellenbergd93f6302012-03-26 15:49:13 +02002068{
2069 struct drbd_peer_request *rs_req;
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002070 bool rv = 0;
2071
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002072 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002073 list_for_each_entry(rs_req, &device->sync_ee, w.list) {
Lars Ellenbergd93f6302012-03-26 15:49:13 +02002074 if (overlaps(peer_req->i.sector, peer_req->i.size,
2075 rs_req->i.sector, rs_req->i.size)) {
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002076 rv = 1;
2077 break;
2078 }
2079 }
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002080 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002081
2082 return rv;
2083}
2084
Philipp Reisnerb411b362009-09-25 16:07:19 -07002085/* Called from receive_Data.
2086 * Synchronize packets on sock with packets on msock.
2087 *
2088 * This is here so even when a P_DATA packet traveling via sock overtook an Ack
2089 * packet traveling on msock, they are still processed in the order they have
2090 * been sent.
2091 *
2092 * Note: we don't care for Ack packets overtaking P_DATA packets.
2093 *
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002094 * In case packet_seq is larger than device->peer_seq number, there are
Philipp Reisnerb411b362009-09-25 16:07:19 -07002095 * outstanding packets on the msock. We wait for them to arrive.
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002096 * In case we are the logically next packet, we update device->peer_seq
Philipp Reisnerb411b362009-09-25 16:07:19 -07002097 * ourselves. Correctly handles 32bit wrap around.
2098 *
2099 * Assume we have a 10 GBit connection, that is about 1<<30 byte per second,
2100 * about 1<<21 sectors per second. So "worst" case, we have 1<<3 == 8 seconds
2101 * for the 24bit wrap (historical atomic_t guarantee on some archs), and we have
2102 * 1<<9 == 512 seconds aka ages for the 32bit wrap around...
2103 *
2104 * returns 0 if we may process the packet,
2105 * -ERESTARTSYS if we were interrupted (by disconnect signal). */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002106static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, const u32 peer_seq)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002107{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002108 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002109 DEFINE_WAIT(wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002110 long timeout;
Philipp Reisnerb874d232013-10-23 10:59:16 +02002111 int ret = 0, tp;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002112
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002113 if (!test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags))
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002114 return 0;
2115
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002116 spin_lock(&device->peer_seq_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002117 for (;;) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002118 if (!seq_greater(peer_seq - 1, device->peer_seq)) {
2119 device->peer_seq = seq_max(device->peer_seq, peer_seq);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002120 break;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002121 }
Philipp Reisnerb874d232013-10-23 10:59:16 +02002122
Philipp Reisnerb411b362009-09-25 16:07:19 -07002123 if (signal_pending(current)) {
2124 ret = -ERESTARTSYS;
2125 break;
2126 }
Philipp Reisnerb874d232013-10-23 10:59:16 +02002127
2128 rcu_read_lock();
Andreas Gruenbacher5dd2ca12014-08-11 16:59:23 +02002129 tp = rcu_dereference(peer_device->connection->net_conf)->two_primaries;
Philipp Reisnerb874d232013-10-23 10:59:16 +02002130 rcu_read_unlock();
2131
2132 if (!tp)
2133 break;
2134
2135 /* Only need to wait if two_primaries is enabled */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002136 prepare_to_wait(&device->seq_wait, &wait, TASK_INTERRUPTIBLE);
2137 spin_unlock(&device->peer_seq_lock);
Philipp Reisner44ed1672011-04-19 17:10:19 +02002138 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002139 timeout = rcu_dereference(peer_device->connection->net_conf)->ping_timeo*HZ/10;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002140 rcu_read_unlock();
Andreas Gruenbacher71b1c1e2011-03-01 15:40:43 +01002141 timeout = schedule_timeout(timeout);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002142 spin_lock(&device->peer_seq_lock);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002143 if (!timeout) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002144 ret = -ETIMEDOUT;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002145 drbd_err(device, "Timed out waiting for missing ack packets; disconnecting\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002146 break;
2147 }
2148 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002149 spin_unlock(&device->peer_seq_lock);
2150 finish_wait(&device->seq_wait, &wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002151 return ret;
2152}
2153
Lars Ellenberg688593c2010-11-17 22:25:03 +01002154/* see also bio_flags_to_wire()
2155 * DRBD_REQ_*, because we need to semantically map the flags to data packet
2156 * flags and back. We may replicate to other kernel versions. */
Mike Christiebb3cc852016-06-05 14:32:06 -05002157static unsigned long wire_flags_to_bio_flags(u32 dpf)
Philipp Reisner76d2e7e2010-08-25 11:58:05 +02002158{
Lars Ellenberg688593c2010-11-17 22:25:03 +01002159 return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
2160 (dpf & DP_FUA ? REQ_FUA : 0) |
Mike Christiebb3cc852016-06-05 14:32:06 -05002161 (dpf & DP_FLUSH ? REQ_FLUSH : 0);
2162}
2163
2164static unsigned long wire_flags_to_bio_op(u32 dpf)
2165{
2166 if (dpf & DP_DISCARD)
2167 return REQ_OP_DISCARD;
2168 else
2169 return REQ_OP_WRITE;
Philipp Reisner76d2e7e2010-08-25 11:58:05 +02002170}
2171
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002172static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002173 unsigned int size)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002174{
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002175 struct drbd_interval *i;
2176
2177 repeat:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002178 drbd_for_each_overlap(i, &device->write_requests, sector, size) {
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002179 struct drbd_request *req;
2180 struct bio_and_error m;
2181
2182 if (!i->local)
2183 continue;
2184 req = container_of(i, struct drbd_request, i);
2185 if (!(req->rq_state & RQ_POSTPONED))
2186 continue;
2187 req->rq_state &= ~RQ_POSTPONED;
2188 __req_mod(req, NEG_ACKED, &m);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002189 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002190 if (m.bio)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002191 complete_master_bio(device, &m);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002192 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002193 goto repeat;
2194 }
2195}
2196
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002197static int handle_write_conflicts(struct drbd_device *device,
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002198 struct drbd_peer_request *peer_req)
2199{
Andreas Gruenbachere33b32d2011-08-30 15:38:04 +02002200 struct drbd_connection *connection = peer_req->peer_device->connection;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002201 bool resolve_conflicts = test_bit(RESOLVE_CONFLICTS, &connection->flags);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002202 sector_t sector = peer_req->i.sector;
2203 const unsigned int size = peer_req->i.size;
2204 struct drbd_interval *i;
2205 bool equal;
2206 int err;
2207
2208 /*
2209 * Inserting the peer request into the write_requests tree will prevent
2210 * new conflicting local requests from being added.
2211 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002212 drbd_insert_interval(&device->write_requests, &peer_req->i);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002213
2214 repeat:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002215 drbd_for_each_overlap(i, &device->write_requests, sector, size) {
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002216 if (i == &peer_req->i)
2217 continue;
Lars Ellenberg08d0dab2014-03-20 11:19:22 +01002218 if (i->completed)
2219 continue;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002220
2221 if (!i->local) {
2222 /*
2223 * Our peer has sent a conflicting remote request; this
2224 * should not happen in a two-node setup. Wait for the
2225 * earlier peer request to complete.
2226 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002227 err = drbd_wait_misc(device, i);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002228 if (err)
2229 goto out;
2230 goto repeat;
2231 }
2232
2233 equal = i->sector == sector && i->size == size;
2234 if (resolve_conflicts) {
2235 /*
2236 * If the peer request is fully contained within the
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002237 * overlapping request, it can be considered overwritten
2238 * and thus superseded; otherwise, it will be retried
2239 * once all overlapping requests have completed.
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002240 */
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002241 bool superseded = i->sector <= sector && i->sector +
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002242 (i->size >> 9) >= sector + (size >> 9);
2243
2244 if (!equal)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002245 drbd_alert(device, "Concurrent writes detected: "
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002246 "local=%llus +%u, remote=%llus +%u, "
2247 "assuming %s came first\n",
2248 (unsigned long long)i->sector, i->size,
2249 (unsigned long long)sector, size,
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002250 superseded ? "local" : "remote");
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002251
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002252 peer_req->w.cb = superseded ? e_send_superseded :
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002253 e_send_retry_write;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002254 list_add_tail(&peer_req->w.list, &device->done_ee);
Philipp Reisner668700b2015-03-16 16:08:29 +01002255 queue_work(connection->ack_sender, &peer_req->peer_device->send_acks_work);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002256
2257 err = -ENOENT;
2258 goto out;
2259 } else {
2260 struct drbd_request *req =
2261 container_of(i, struct drbd_request, i);
2262
2263 if (!equal)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002264 drbd_alert(device, "Concurrent writes detected: "
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002265 "local=%llus +%u, remote=%llus +%u\n",
2266 (unsigned long long)i->sector, i->size,
2267 (unsigned long long)sector, size);
2268
2269 if (req->rq_state & RQ_LOCAL_PENDING ||
2270 !(req->rq_state & RQ_POSTPONED)) {
2271 /*
2272 * Wait for the node with the discard flag to
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02002273 * decide if this request has been superseded
2274 * or needs to be retried.
2275 * Requests that have been superseded will
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002276 * disappear from the write_requests tree.
2277 *
2278 * In addition, wait for the conflicting
2279 * request to finish locally before submitting
2280 * the conflicting peer request.
2281 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002282 err = drbd_wait_misc(device, &req->i);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002283 if (err) {
Andreas Gruenbachere33b32d2011-08-30 15:38:04 +02002284 _conn_request_state(connection, NS(conn, C_TIMEOUT), CS_HARD);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002285 fail_postponed_requests(device, sector, size);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002286 goto out;
2287 }
2288 goto repeat;
2289 }
2290 /*
2291 * Remember to restart the conflicting requests after
2292 * the new peer request has completed.
2293 */
2294 peer_req->flags |= EE_RESTART_REQUESTS;
2295 }
2296 }
2297 err = 0;
2298
2299 out:
2300 if (err)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002301 drbd_remove_epoch_entry_interval(device, peer_req);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002302 return err;
2303}
2304
Philipp Reisnerb411b362009-09-25 16:07:19 -07002305/* mirrored write */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002306static int receive_Data(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002307{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002308 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002309 struct drbd_device *device;
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002310 struct net_conf *nc;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002311 sector_t sector;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002312 struct drbd_peer_request *peer_req;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02002313 struct p_data *p = pi->data;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002314 u32 peer_seq = be32_to_cpu(p->seq_num);
Mike Christiebb3cc852016-06-05 14:32:06 -05002315 int op, op_flags;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002316 u32 dp_flags;
Philipp Reisner302bdea2011-04-21 11:36:49 +02002317 int err, tp;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002318
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002319 peer_device = conn_peer_device(connection, pi->vnr);
2320 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01002321 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002322 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002323
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002324 if (!get_ldev(device)) {
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002325 int err2;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002326
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002327 err = wait_for_and_update_peer_seq(peer_device, peer_seq);
2328 drbd_send_ack_dp(peer_device, P_NEG_ACK, p, pi->size);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002329 atomic_inc(&connection->current_epoch->epoch_size);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002330 err2 = drbd_drain_block(peer_device, pi->size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002331 if (!err)
2332 err = err2;
2333 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002334 }
2335
Andreas Gruenbacherfcefa622011-02-17 16:46:59 +01002336 /*
2337 * Corresponding put_ldev done either below (on various errors), or in
2338 * drbd_peer_request_endio, if we successfully submit the data at the
2339 * end of this function.
2340 */
Philipp Reisnerb411b362009-09-25 16:07:19 -07002341
2342 sector = be64_to_cpu(p->sector);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02002343 peer_req = read_in_block(peer_device, p->block_id, sector, pi);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002344 if (!peer_req) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002345 put_ldev(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002346 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002347 }
2348
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002349 peer_req->w.cb = e_end_block;
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002350 peer_req->submit_jif = jiffies;
2351 peer_req->flags |= EE_APPLICATION;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002352
Lars Ellenberg688593c2010-11-17 22:25:03 +01002353 dp_flags = be32_to_cpu(p->dp_flags);
Mike Christiebb3cc852016-06-05 14:32:06 -05002354 op = wire_flags_to_bio_op(dp_flags);
2355 op_flags = wire_flags_to_bio_flags(dp_flags);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02002356 if (pi->cmd == P_TRIM) {
2357 struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev);
2358 peer_req->flags |= EE_IS_TRIM;
2359 if (!blk_queue_discard(q))
2360 peer_req->flags |= EE_IS_TRIM_USE_ZEROOUT;
2361 D_ASSERT(peer_device, peer_req->i.size > 0);
Mike Christiebb3cc852016-06-05 14:32:06 -05002362 D_ASSERT(peer_device, op == REQ_OP_DISCARD);
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02002363 D_ASSERT(peer_device, peer_req->pages == NULL);
2364 } else if (peer_req->pages == NULL) {
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02002365 D_ASSERT(device, peer_req->i.size == 0);
2366 D_ASSERT(device, dp_flags & DP_FLUSH);
Lars Ellenberga73ff322012-06-25 19:15:38 +02002367 }
Lars Ellenberg688593c2010-11-17 22:25:03 +01002368
2369 if (dp_flags & DP_MAY_SET_IN_SYNC)
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002370 peer_req->flags |= EE_MAY_SET_IN_SYNC;
Lars Ellenberg688593c2010-11-17 22:25:03 +01002371
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002372 spin_lock(&connection->epoch_lock);
2373 peer_req->epoch = connection->current_epoch;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002374 atomic_inc(&peer_req->epoch->epoch_size);
2375 atomic_inc(&peer_req->epoch->active);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002376 spin_unlock(&connection->epoch_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002377
Philipp Reisner302bdea2011-04-21 11:36:49 +02002378 rcu_read_lock();
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002379 nc = rcu_dereference(peer_device->connection->net_conf);
2380 tp = nc->two_primaries;
2381 if (peer_device->connection->agreed_pro_version < 100) {
2382 switch (nc->wire_protocol) {
2383 case DRBD_PROT_C:
2384 dp_flags |= DP_SEND_WRITE_ACK;
2385 break;
2386 case DRBD_PROT_B:
2387 dp_flags |= DP_SEND_RECEIVE_ACK;
2388 break;
2389 }
2390 }
Philipp Reisner302bdea2011-04-21 11:36:49 +02002391 rcu_read_unlock();
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002392
2393 if (dp_flags & DP_SEND_WRITE_ACK) {
2394 peer_req->flags |= EE_SEND_WRITE_ACK;
2395 inc_unacked(device);
2396 /* corresponding dec_unacked() in e_end_block()
2397 * respective _drbd_clear_done_ee */
2398 }
2399
2400 if (dp_flags & DP_SEND_RECEIVE_ACK) {
2401 /* I really don't like it that the receiver thread
2402 * sends on the msock, but anyways */
Andreas Gruenbacher5dd2ca12014-08-11 16:59:23 +02002403 drbd_send_ack(peer_device, P_RECV_ACK, peer_req);
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002404 }
2405
Philipp Reisner302bdea2011-04-21 11:36:49 +02002406 if (tp) {
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002407 /* two primaries implies protocol C */
2408 D_ASSERT(device, dp_flags & DP_SEND_WRITE_ACK);
Philipp Reisner302bdea2011-04-21 11:36:49 +02002409 peer_req->flags |= EE_IN_INTERVAL_TREE;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002410 err = wait_for_and_update_peer_seq(peer_device, peer_seq);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002411 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002412 goto out_interrupted;
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002413 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002414 err = handle_write_conflicts(device, peer_req);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002415 if (err) {
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002416 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002417 if (err == -ENOENT) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002418 put_ldev(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002419 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002420 }
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01002421 goto out_interrupted;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002422 }
Philipp Reisnerb874d232013-10-23 10:59:16 +02002423 } else {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002424 update_peer_seq(peer_device, peer_seq);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002425 spin_lock_irq(&device->resource->req_lock);
Philipp Reisnerb874d232013-10-23 10:59:16 +02002426 }
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02002427 /* if we use the zeroout fallback code, we process synchronously
2428 * and we wait for all pending requests, respectively wait for
2429 * active_ee to become empty in drbd_submit_peer_request();
2430 * better not add ourselves here. */
2431 if ((peer_req->flags & EE_IS_TRIM_USE_ZEROOUT) == 0)
Lars Ellenbergb9ed7082014-04-23 12:15:35 +02002432 list_add_tail(&peer_req->w.list, &device->active_ee);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002433 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002434
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002435 if (device->state.conn == C_SYNC_TARGET)
2436 wait_event(device->ee_wait, !overlapping_resync_write(device, peer_req));
Philipp Reisnerb6a370ba2012-02-19 01:27:53 +01002437
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002438 if (device->state.pdsk < D_INCONSISTENT) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002439 /* In case we have the only disk of the cluster, */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002440 drbd_set_out_of_sync(device, peer_req->i.sector, peer_req->i.size);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002441 peer_req->flags &= ~EE_MAY_SET_IN_SYNC;
Lars Ellenberg4dd726f2014-02-11 11:15:36 +01002442 drbd_al_begin_io(device, &peer_req->i);
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002443 peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002444 }
2445
Mike Christiebb3cc852016-06-05 14:32:06 -05002446 err = drbd_submit_peer_request(device, peer_req, op, op_flags,
2447 DRBD_FAULT_DT_WR);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002448 if (!err)
2449 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002450
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01002451 /* don't care for the reason here */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002452 drbd_err(device, "submit failed, triggering re-connect\n");
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002453 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002454 list_del(&peer_req->w.list);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002455 drbd_remove_epoch_entry_interval(device, peer_req);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002456 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002457 if (peer_req->flags & EE_CALL_AL_COMPLETE_IO) {
2458 peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002459 drbd_al_complete_io(device, &peer_req->i);
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002460 }
Lars Ellenberg22cc37a2010-09-14 20:40:41 +02002461
Philipp Reisnerb411b362009-09-25 16:07:19 -07002462out_interrupted:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002463 drbd_may_finish_epoch(connection, peer_req->epoch, EV_PUT + EV_CLEANUP);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002464 put_ldev(device);
2465 drbd_free_peer_req(device, peer_req);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002466 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002467}
2468
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002469/* We may throttle resync, if the lower device seems to be busy,
2470 * and current sync rate is above c_min_rate.
2471 *
2472 * To decide whether or not the lower device is busy, we use a scheme similar
2473 * to MD RAID is_mddev_idle(): if the partition stats reveal "significant"
2474 * (more than 64 sectors) of activity we cannot account for with our own resync
2475 * activity, it obviously is "busy".
2476 *
2477 * The current sync rate used here uses only the most recent two step marks,
2478 * to have a short time average so we can react faster.
2479 */
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002480bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector,
2481 bool throttle_if_app_is_waiting)
Lars Ellenberge8299872014-04-28 18:43:19 +02002482{
2483 struct lc_element *tmp;
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002484 bool throttle = drbd_rs_c_min_rate_throttle(device);
Lars Ellenberge8299872014-04-28 18:43:19 +02002485
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002486 if (!throttle || throttle_if_app_is_waiting)
2487 return throttle;
Lars Ellenberge8299872014-04-28 18:43:19 +02002488
2489 spin_lock_irq(&device->al_lock);
2490 tmp = lc_find(device->resync, BM_SECT_TO_EXT(sector));
2491 if (tmp) {
2492 struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce);
2493 if (test_bit(BME_PRIORITY, &bm_ext->flags))
2494 throttle = false;
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002495 /* Do not slow down if app IO is already waiting for this extent,
2496 * and our progress is necessary for application IO to complete. */
Lars Ellenberge8299872014-04-28 18:43:19 +02002497 }
2498 spin_unlock_irq(&device->al_lock);
2499
2500 return throttle;
2501}
2502
2503bool drbd_rs_c_min_rate_throttle(struct drbd_device *device)
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002504{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002505 struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002506 unsigned long db, dt, dbdt;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02002507 unsigned int c_min_rate;
Lars Ellenberge8299872014-04-28 18:43:19 +02002508 int curr_events;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02002509
2510 rcu_read_lock();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002511 c_min_rate = rcu_dereference(device->ldev->disk_conf)->c_min_rate;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02002512 rcu_read_unlock();
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002513
2514 /* feature disabled? */
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02002515 if (c_min_rate == 0)
Lars Ellenberge8299872014-04-28 18:43:19 +02002516 return false;
Philipp Reisnere3555d82010-11-07 15:56:29 +01002517
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002518 curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
2519 (int)part_stat_read(&disk->part0, sectors[1]) -
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002520 atomic_read(&device->rs_sect_ev);
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002521
2522 if (atomic_read(&device->ap_actlog_cnt)
Lars Ellenbergff8bd882014-11-10 17:21:12 +01002523 || curr_events - device->rs_last_events > 64) {
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002524 unsigned long rs_left;
2525 int i;
2526
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002527 device->rs_last_events = curr_events;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002528
2529 /* sync speed average over the last 2*DRBD_SYNC_MARK_STEP,
2530 * approx. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002531 i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
Lars Ellenberg2649f082010-11-05 10:05:47 +01002532
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002533 if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
2534 rs_left = device->ov_left;
Lars Ellenberg2649f082010-11-05 10:05:47 +01002535 else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002536 rs_left = drbd_bm_total_weight(device) - device->rs_failed;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002537
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002538 dt = ((long)jiffies - (long)device->rs_mark_time[i]) / HZ;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002539 if (!dt)
2540 dt++;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002541 db = device->rs_mark_left[i] - rs_left;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002542 dbdt = Bit2KB(db/dt);
2543
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02002544 if (dbdt > c_min_rate)
Lars Ellenberge8299872014-04-28 18:43:19 +02002545 return true;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002546 }
Lars Ellenberge8299872014-04-28 18:43:19 +02002547 return false;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002548}
2549
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002550static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002551{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002552 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002553 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002554 sector_t sector;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01002555 sector_t capacity;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002556 struct drbd_peer_request *peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002557 struct digest_info *di = NULL;
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002558 int size, verb;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002559 unsigned int fault_type;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02002560 struct p_block_req *p = pi->data;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01002561
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002562 peer_device = conn_peer_device(connection, pi->vnr);
2563 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01002564 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002565 device = peer_device->device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002566 capacity = drbd_get_capacity(device->this_bdev);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002567
2568 sector = be64_to_cpu(p->sector);
2569 size = be32_to_cpu(p->blksize);
2570
Andreas Gruenbacherc670a392011-02-21 12:41:39 +01002571 if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002572 drbd_err(device, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
Philipp Reisnerb411b362009-09-25 16:07:19 -07002573 (unsigned long long)sector, size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002574 return -EINVAL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002575 }
2576 if (sector + (size>>9) > capacity) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002577 drbd_err(device, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
Philipp Reisnerb411b362009-09-25 16:07:19 -07002578 (unsigned long long)sector, size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002579 return -EINVAL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002580 }
2581
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002582 if (!get_ldev_if_state(device, D_UP_TO_DATE)) {
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002583 verb = 1;
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002584 switch (pi->cmd) {
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002585 case P_DATA_REQUEST:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002586 drbd_send_ack_rp(peer_device, P_NEG_DREPLY, p);
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002587 break;
2588 case P_RS_DATA_REQUEST:
2589 case P_CSUM_RS_REQUEST:
2590 case P_OV_REQUEST:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002591 drbd_send_ack_rp(peer_device, P_NEG_RS_DREPLY , p);
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002592 break;
2593 case P_OV_REPLY:
2594 verb = 0;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002595 dec_rs_pending(device);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002596 drbd_send_ack_ex(peer_device, P_OV_RESULT, sector, size, ID_IN_SYNC);
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002597 break;
2598 default:
Andreas Gruenbacher49ba9b12011-03-25 00:35:45 +01002599 BUG();
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002600 }
2601 if (verb && __ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002602 drbd_err(device, "Can not satisfy peer's read request, "
Philipp Reisnerb411b362009-09-25 16:07:19 -07002603 "no local data.\n");
Philipp Reisnerb18b37b2010-10-13 15:32:44 +02002604
Lars Ellenberga821cc42010-09-06 12:31:37 +02002605 /* drain possibly payload */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002606 return drbd_drain_block(peer_device, pi->size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002607 }
2608
2609 /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
2610 * "criss-cross" setup, that might cause write-out on some other DRBD,
2611 * which in turn might block on the other node at this very place. */
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02002612 peer_req = drbd_alloc_peer_req(peer_device, p->block_id, sector, size,
2613 true /* has real payload */, GFP_NOIO);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002614 if (!peer_req) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002615 put_ldev(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002616 return -ENOMEM;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002617 }
2618
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002619 switch (pi->cmd) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002620 case P_DATA_REQUEST:
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002621 peer_req->w.cb = w_e_end_data_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002622 fault_type = DRBD_FAULT_DT_RD;
Lars Ellenberg80a40e42010-08-11 23:28:00 +02002623 /* application IO, don't drbd_rs_begin_io */
Lars Ellenberg21ae5d72014-05-05 23:42:24 +02002624 peer_req->flags |= EE_APPLICATION;
Lars Ellenberg80a40e42010-08-11 23:28:00 +02002625 goto submit;
2626
Philipp Reisnerb411b362009-09-25 16:07:19 -07002627 case P_RS_DATA_REQUEST:
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002628 peer_req->w.cb = w_e_end_rsdata_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002629 fault_type = DRBD_FAULT_RS_RD;
Lars Ellenberg5f9915b2010-11-09 14:15:24 +01002630 /* used in the sector offset progress display */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002631 device->bm_resync_fo = BM_SECT_TO_BIT(sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002632 break;
2633
2634 case P_OV_REPLY:
2635 case P_CSUM_RS_REQUEST:
2636 fault_type = DRBD_FAULT_RS_RD;
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002637 di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002638 if (!di)
2639 goto out_free_e;
2640
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002641 di->digest_size = pi->size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002642 di->digest = (((char *)di)+sizeof(struct digest_info));
2643
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01002644 peer_req->digest = di;
2645 peer_req->flags |= EE_HAS_DIGEST;
Lars Ellenbergc36c3ce2010-08-11 20:42:55 +02002646
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002647 if (drbd_recv_all(peer_device->connection, di->digest, pi->size))
Philipp Reisnerb411b362009-09-25 16:07:19 -07002648 goto out_free_e;
2649
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002650 if (pi->cmd == P_CSUM_RS_REQUEST) {
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002651 D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002652 peer_req->w.cb = w_e_end_csum_rs_req;
Lars Ellenberg5f9915b2010-11-09 14:15:24 +01002653 /* used in the sector offset progress display */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002654 device->bm_resync_fo = BM_SECT_TO_BIT(sector);
Lars Ellenbergaaaba342014-03-18 12:30:09 +01002655 /* remember to report stats in drbd_resync_finished */
2656 device->use_csums = true;
Andreas Gruenbachere2857212011-03-25 00:57:38 +01002657 } else if (pi->cmd == P_OV_REPLY) {
Lars Ellenberg2649f082010-11-05 10:05:47 +01002658 /* track progress, we may need to throttle */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002659 atomic_add(size >> 9, &device->rs_sect_in);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002660 peer_req->w.cb = w_e_end_ov_reply;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002661 dec_rs_pending(device);
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002662 /* drbd_rs_begin_io done when we sent this request,
2663 * but accounting still needs to be done. */
2664 goto submit_for_resync;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002665 }
2666 break;
2667
2668 case P_OV_REQUEST:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002669 if (device->ov_start_sector == ~(sector_t)0 &&
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02002670 peer_device->connection->agreed_pro_version >= 90) {
Lars Ellenbergde228bb2010-11-05 09:43:15 +01002671 unsigned long now = jiffies;
2672 int i;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002673 device->ov_start_sector = sector;
2674 device->ov_position = sector;
2675 device->ov_left = drbd_bm_bits(device) - BM_SECT_TO_BIT(sector);
2676 device->rs_total = device->ov_left;
Lars Ellenbergde228bb2010-11-05 09:43:15 +01002677 for (i = 0; i < DRBD_SYNC_MARKS; i++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002678 device->rs_mark_left[i] = device->ov_left;
2679 device->rs_mark_time[i] = now;
Lars Ellenbergde228bb2010-11-05 09:43:15 +01002680 }
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002681 drbd_info(device, "Online Verify start sector: %llu\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07002682 (unsigned long long)sector);
2683 }
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002684 peer_req->w.cb = w_e_end_ov_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002685 fault_type = DRBD_FAULT_RS_RD;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002686 break;
2687
Philipp Reisnerb411b362009-09-25 16:07:19 -07002688 default:
Andreas Gruenbacher49ba9b12011-03-25 00:35:45 +01002689 BUG();
Philipp Reisnerb411b362009-09-25 16:07:19 -07002690 }
2691
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002692 /* Throttle, drbd_rs_begin_io and submit should become asynchronous
2693 * wrt the receiver, but it is not as straightforward as it may seem.
2694 * Various places in the resync start and stop logic assume resync
2695 * requests are processed in order, requeuing this on the worker thread
2696 * introduces a bunch of new code for synchronization between threads.
2697 *
2698 * Unlimited throttling before drbd_rs_begin_io may stall the resync
2699 * "forever", throttling after drbd_rs_begin_io will lock that extent
2700 * for application writes for the same time. For now, just throttle
2701 * here, where the rest of the code expects the receiver to sleep for
2702 * a while, anyways.
2703 */
Philipp Reisnerb411b362009-09-25 16:07:19 -07002704
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002705 /* Throttle before drbd_rs_begin_io, as that locks out application IO;
2706 * this defers syncer requests for some time, before letting at least
2707 * on request through. The resync controller on the receiving side
2708 * will adapt to the incoming rate accordingly.
2709 *
2710 * We cannot throttle here if remote is Primary/SyncTarget:
2711 * we would also throttle its application reads.
2712 * In that case, throttling is done on the SyncTarget only.
2713 */
Lars Ellenbergc5a2c152014-05-08 10:08:05 +02002714
2715 /* Even though this may be a resync request, we do add to "read_ee";
2716 * "sync_ee" is only used for resync WRITEs.
2717 * Add to list early, so debugfs can find this request
2718 * even if we have to sleep below. */
2719 spin_lock_irq(&device->resource->req_lock);
2720 list_add_tail(&peer_req->w.list, &device->read_ee);
2721 spin_unlock_irq(&device->resource->req_lock);
2722
Lars Ellenberg944410e2014-05-06 15:02:05 +02002723 update_receiver_timing_details(connection, drbd_rs_should_slow_down);
Lars Ellenbergad3fee72013-12-20 11:22:13 +01002724 if (device->state.peer != R_PRIMARY
2725 && drbd_rs_should_slow_down(device, sector, false))
Philipp Reisnere3555d82010-11-07 15:56:29 +01002726 schedule_timeout_uninterruptible(HZ/10);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002727 update_receiver_timing_details(connection, drbd_rs_begin_io);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002728 if (drbd_rs_begin_io(device, sector))
Lars Ellenberg80a40e42010-08-11 23:28:00 +02002729 goto out_free_e;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002730
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002731submit_for_resync:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002732 atomic_add(size >> 9, &device->rs_sect_ev);
Lars Ellenberg0f0601f2010-08-11 23:40:24 +02002733
Lars Ellenberg80a40e42010-08-11 23:28:00 +02002734submit:
Lars Ellenberg944410e2014-05-06 15:02:05 +02002735 update_receiver_timing_details(connection, drbd_submit_peer_request);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002736 inc_unacked(device);
Mike Christiebb3cc852016-06-05 14:32:06 -05002737 if (drbd_submit_peer_request(device, peer_req, REQ_OP_READ, 0,
2738 fault_type) == 0)
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002739 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002740
Lars Ellenberg10f6d9922011-01-24 14:47:09 +01002741 /* don't care for the reason here */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002742 drbd_err(device, "submit failed, triggering re-connect\n");
Lars Ellenbergc5a2c152014-05-08 10:08:05 +02002743
2744out_free_e:
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002745 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02002746 list_del(&peer_req->w.list);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002747 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberg22cc37a2010-09-14 20:40:41 +02002748 /* no drbd_rs_complete_io(), we are dropping the connection anyways */
2749
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002750 put_ldev(device);
2751 drbd_free_peer_req(device, peer_req);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01002752 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002753}
2754
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002755/**
2756 * drbd_asb_recover_0p - Recover after split-brain with no remaining primaries
2757 */
2758static int drbd_asb_recover_0p(struct drbd_peer_device *peer_device) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002759{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002760 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002761 int self, peer, rv = -100;
2762 unsigned long ch_self, ch_peer;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002763 enum drbd_after_sb_p after_sb_0p;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002764
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002765 self = device->ldev->md.uuid[UI_BITMAP] & 1;
2766 peer = device->p_uuid[UI_BITMAP] & 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002767
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002768 ch_peer = device->p_uuid[UI_SIZE];
2769 ch_self = device->comm_bm_set;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002770
Philipp Reisner44ed1672011-04-19 17:10:19 +02002771 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002772 after_sb_0p = rcu_dereference(peer_device->connection->net_conf)->after_sb_0p;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002773 rcu_read_unlock();
2774 switch (after_sb_0p) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002775 case ASB_CONSENSUS:
2776 case ASB_DISCARD_SECONDARY:
2777 case ASB_CALL_HELPER:
Philipp Reisner44ed1672011-04-19 17:10:19 +02002778 case ASB_VIOLENTLY:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002779 drbd_err(device, "Configuration error.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002780 break;
2781 case ASB_DISCONNECT:
2782 break;
2783 case ASB_DISCARD_YOUNGER_PRI:
2784 if (self == 0 && peer == 1) {
2785 rv = -1;
2786 break;
2787 }
2788 if (self == 1 && peer == 0) {
2789 rv = 1;
2790 break;
2791 }
2792 /* Else fall through to one of the other strategies... */
2793 case ASB_DISCARD_OLDER_PRI:
2794 if (self == 0 && peer == 1) {
2795 rv = 1;
2796 break;
2797 }
2798 if (self == 1 && peer == 0) {
2799 rv = -1;
2800 break;
2801 }
2802 /* Else fall through to one of the other strategies... */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002803 drbd_warn(device, "Discard younger/older primary did not find a decision\n"
Philipp Reisnerb411b362009-09-25 16:07:19 -07002804 "Using discard-least-changes instead\n");
2805 case ASB_DISCARD_ZERO_CHG:
2806 if (ch_peer == 0 && ch_self == 0) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002807 rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002808 ? -1 : 1;
2809 break;
2810 } else {
2811 if (ch_peer == 0) { rv = 1; break; }
2812 if (ch_self == 0) { rv = -1; break; }
2813 }
Philipp Reisner44ed1672011-04-19 17:10:19 +02002814 if (after_sb_0p == ASB_DISCARD_ZERO_CHG)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002815 break;
2816 case ASB_DISCARD_LEAST_CHG:
2817 if (ch_self < ch_peer)
2818 rv = -1;
2819 else if (ch_self > ch_peer)
2820 rv = 1;
2821 else /* ( ch_self == ch_peer ) */
2822 /* Well, then use something else. */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002823 rv = test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002824 ? -1 : 1;
2825 break;
2826 case ASB_DISCARD_LOCAL:
2827 rv = -1;
2828 break;
2829 case ASB_DISCARD_REMOTE:
2830 rv = 1;
2831 }
2832
2833 return rv;
2834}
2835
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002836/**
2837 * drbd_asb_recover_1p - Recover after split-brain with one remaining primary
2838 */
2839static int drbd_asb_recover_1p(struct drbd_peer_device *peer_device) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002840{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002841 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher6184ea22010-12-09 14:23:27 +01002842 int hg, rv = -100;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002843 enum drbd_after_sb_p after_sb_1p;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002844
Philipp Reisner44ed1672011-04-19 17:10:19 +02002845 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002846 after_sb_1p = rcu_dereference(peer_device->connection->net_conf)->after_sb_1p;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002847 rcu_read_unlock();
2848 switch (after_sb_1p) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002849 case ASB_DISCARD_YOUNGER_PRI:
2850 case ASB_DISCARD_OLDER_PRI:
2851 case ASB_DISCARD_LEAST_CHG:
2852 case ASB_DISCARD_LOCAL:
2853 case ASB_DISCARD_REMOTE:
Philipp Reisner44ed1672011-04-19 17:10:19 +02002854 case ASB_DISCARD_ZERO_CHG:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002855 drbd_err(device, "Configuration error.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002856 break;
2857 case ASB_DISCONNECT:
2858 break;
2859 case ASB_CONSENSUS:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002860 hg = drbd_asb_recover_0p(peer_device);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002861 if (hg == -1 && device->state.role == R_SECONDARY)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002862 rv = hg;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002863 if (hg == 1 && device->state.role == R_PRIMARY)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002864 rv = hg;
2865 break;
2866 case ASB_VIOLENTLY:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002867 rv = drbd_asb_recover_0p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002868 break;
2869 case ASB_DISCARD_SECONDARY:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002870 return device->state.role == R_PRIMARY ? 1 : -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002871 case ASB_CALL_HELPER:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002872 hg = drbd_asb_recover_0p(peer_device);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002873 if (hg == -1 && device->state.role == R_PRIMARY) {
Andreas Gruenbacherbb437942010-12-09 14:02:35 +01002874 enum drbd_state_rv rv2;
2875
Philipp Reisnerb411b362009-09-25 16:07:19 -07002876 /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
2877 * we might be here in C_WF_REPORT_PARAMS which is transient.
2878 * we do not need to wait for the after state change work either. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002879 rv2 = drbd_change_state(device, CS_VERBOSE, NS(role, R_SECONDARY));
Andreas Gruenbacherbb437942010-12-09 14:02:35 +01002880 if (rv2 != SS_SUCCESS) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002881 drbd_khelper(device, "pri-lost-after-sb");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002882 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002883 drbd_warn(device, "Successfully gave up primary role.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002884 rv = hg;
2885 }
2886 } else
2887 rv = hg;
2888 }
2889
2890 return rv;
2891}
2892
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002893/**
2894 * drbd_asb_recover_2p - Recover after split-brain with two remaining primaries
2895 */
2896static int drbd_asb_recover_2p(struct drbd_peer_device *peer_device) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002897{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002898 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher6184ea22010-12-09 14:23:27 +01002899 int hg, rv = -100;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002900 enum drbd_after_sb_p after_sb_2p;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002901
Philipp Reisner44ed1672011-04-19 17:10:19 +02002902 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002903 after_sb_2p = rcu_dereference(peer_device->connection->net_conf)->after_sb_2p;
Philipp Reisner44ed1672011-04-19 17:10:19 +02002904 rcu_read_unlock();
2905 switch (after_sb_2p) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002906 case ASB_DISCARD_YOUNGER_PRI:
2907 case ASB_DISCARD_OLDER_PRI:
2908 case ASB_DISCARD_LEAST_CHG:
2909 case ASB_DISCARD_LOCAL:
2910 case ASB_DISCARD_REMOTE:
2911 case ASB_CONSENSUS:
2912 case ASB_DISCARD_SECONDARY:
Philipp Reisner44ed1672011-04-19 17:10:19 +02002913 case ASB_DISCARD_ZERO_CHG:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002914 drbd_err(device, "Configuration error.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002915 break;
2916 case ASB_VIOLENTLY:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002917 rv = drbd_asb_recover_0p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002918 break;
2919 case ASB_DISCONNECT:
2920 break;
2921 case ASB_CALL_HELPER:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02002922 hg = drbd_asb_recover_0p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002923 if (hg == -1) {
Andreas Gruenbacherbb437942010-12-09 14:02:35 +01002924 enum drbd_state_rv rv2;
2925
Philipp Reisnerb411b362009-09-25 16:07:19 -07002926 /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
2927 * we might be here in C_WF_REPORT_PARAMS which is transient.
2928 * we do not need to wait for the after state change work either. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002929 rv2 = drbd_change_state(device, CS_VERBOSE, NS(role, R_SECONDARY));
Andreas Gruenbacherbb437942010-12-09 14:02:35 +01002930 if (rv2 != SS_SUCCESS) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002931 drbd_khelper(device, "pri-lost-after-sb");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002932 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002933 drbd_warn(device, "Successfully gave up primary role.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002934 rv = hg;
2935 }
2936 } else
2937 rv = hg;
2938 }
2939
2940 return rv;
2941}
2942
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002943static void drbd_uuid_dump(struct drbd_device *device, char *text, u64 *uuid,
Philipp Reisnerb411b362009-09-25 16:07:19 -07002944 u64 bits, u64 flags)
2945{
2946 if (!uuid) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002947 drbd_info(device, "%s uuid info vanished while I was looking!\n", text);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002948 return;
2949 }
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02002950 drbd_info(device, "%s %016llX:%016llX:%016llX:%016llX bits:%llu flags:%llX\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07002951 text,
2952 (unsigned long long)uuid[UI_CURRENT],
2953 (unsigned long long)uuid[UI_BITMAP],
2954 (unsigned long long)uuid[UI_HISTORY_START],
2955 (unsigned long long)uuid[UI_HISTORY_END],
2956 (unsigned long long)bits,
2957 (unsigned long long)flags);
2958}
2959
2960/*
2961 100 after split brain try auto recover
2962 2 C_SYNC_SOURCE set BitMap
2963 1 C_SYNC_SOURCE use BitMap
2964 0 no Sync
2965 -1 C_SYNC_TARGET use BitMap
2966 -2 C_SYNC_TARGET set BitMap
2967 -100 after split brain, disconnect
2968-1000 unrelated data
Philipp Reisner4a23f262011-01-11 17:42:17 +01002969-1091 requires proto 91
2970-1096 requires proto 96
Philipp Reisnerb411b362009-09-25 16:07:19 -07002971 */
Lars Ellenberg44a4d552013-11-22 12:40:58 +01002972static int drbd_uuid_compare(struct drbd_device *const device, int *rule_nr) __must_hold(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002973{
Lars Ellenberg44a4d552013-11-22 12:40:58 +01002974 struct drbd_peer_device *const peer_device = first_peer_device(device);
2975 struct drbd_connection *const connection = peer_device ? peer_device->connection : NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002976 u64 self, peer;
2977 int i, j;
2978
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002979 self = device->ldev->md.uuid[UI_CURRENT] & ~((u64)1);
2980 peer = device->p_uuid[UI_CURRENT] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002981
2982 *rule_nr = 10;
2983 if (self == UUID_JUST_CREATED && peer == UUID_JUST_CREATED)
2984 return 0;
2985
2986 *rule_nr = 20;
2987 if ((self == UUID_JUST_CREATED || self == (u64)0) &&
2988 peer != UUID_JUST_CREATED)
2989 return -2;
2990
2991 *rule_nr = 30;
2992 if (self != UUID_JUST_CREATED &&
2993 (peer == UUID_JUST_CREATED || peer == (u64)0))
2994 return 2;
2995
2996 if (self == peer) {
2997 int rct, dc; /* roles at crash time */
2998
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002999 if (device->p_uuid[UI_BITMAP] == (u64)0 && device->ldev->md.uuid[UI_BITMAP] != (u64)0) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003000
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003001 if (connection->agreed_pro_version < 91)
Philipp Reisner4a23f262011-01-11 17:42:17 +01003002 return -1091;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003003
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003004 if ((device->ldev->md.uuid[UI_BITMAP] & ~((u64)1)) == (device->p_uuid[UI_HISTORY_START] & ~((u64)1)) &&
3005 (device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (device->p_uuid[UI_HISTORY_START + 1] & ~((u64)1))) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003006 drbd_info(device, "was SyncSource, missed the resync finished event, corrected myself:\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003007 drbd_uuid_move_history(device);
3008 device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];
3009 device->ldev->md.uuid[UI_BITMAP] = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003010
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003011 drbd_uuid_dump(device, "self", device->ldev->md.uuid,
3012 device->state.disk >= D_NEGOTIATING ? drbd_bm_total_weight(device) : 0, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003013 *rule_nr = 34;
3014 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003015 drbd_info(device, "was SyncSource (peer failed to write sync_uuid)\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003016 *rule_nr = 36;
3017 }
3018
3019 return 1;
3020 }
3021
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003022 if (device->ldev->md.uuid[UI_BITMAP] == (u64)0 && device->p_uuid[UI_BITMAP] != (u64)0) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003023
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003024 if (connection->agreed_pro_version < 91)
Philipp Reisner4a23f262011-01-11 17:42:17 +01003025 return -1091;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003026
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003027 if ((device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (device->p_uuid[UI_BITMAP] & ~((u64)1)) &&
3028 (device->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) == (device->p_uuid[UI_HISTORY_START] & ~((u64)1))) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003029 drbd_info(device, "was SyncTarget, peer missed the resync finished event, corrected peer:\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003030
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003031 device->p_uuid[UI_HISTORY_START + 1] = device->p_uuid[UI_HISTORY_START];
3032 device->p_uuid[UI_HISTORY_START] = device->p_uuid[UI_BITMAP];
3033 device->p_uuid[UI_BITMAP] = 0UL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003034
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003035 drbd_uuid_dump(device, "peer", device->p_uuid, device->p_uuid[UI_SIZE], device->p_uuid[UI_FLAGS]);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003036 *rule_nr = 35;
3037 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003038 drbd_info(device, "was SyncTarget (failed to write sync_uuid)\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003039 *rule_nr = 37;
3040 }
3041
3042 return -1;
3043 }
3044
3045 /* Common power [off|failure] */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003046 rct = (test_bit(CRASHED_PRIMARY, &device->flags) ? 1 : 0) +
3047 (device->p_uuid[UI_FLAGS] & 2);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003048 /* lowest bit is set when we were primary,
3049 * next bit (weight 2) is set when peer was primary */
3050 *rule_nr = 40;
3051
3052 switch (rct) {
3053 case 0: /* !self_pri && !peer_pri */ return 0;
3054 case 1: /* self_pri && !peer_pri */ return 1;
3055 case 2: /* !self_pri && peer_pri */ return -1;
3056 case 3: /* self_pri && peer_pri */
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003057 dc = test_bit(RESOLVE_CONFLICTS, &connection->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003058 return dc ? -1 : 1;
3059 }
3060 }
3061
3062 *rule_nr = 50;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003063 peer = device->p_uuid[UI_BITMAP] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003064 if (self == peer)
3065 return -1;
3066
3067 *rule_nr = 51;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003068 peer = device->p_uuid[UI_HISTORY_START] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003069 if (self == peer) {
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003070 if (connection->agreed_pro_version < 96 ?
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003071 (device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) ==
3072 (device->p_uuid[UI_HISTORY_START + 1] & ~((u64)1)) :
3073 peer + UUID_NEW_BM_OFFSET == (device->p_uuid[UI_BITMAP] & ~((u64)1))) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003074 /* The last P_SYNC_UUID did not get though. Undo the last start of
3075 resync as sync source modifications of the peer's UUIDs. */
3076
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003077 if (connection->agreed_pro_version < 91)
Philipp Reisner4a23f262011-01-11 17:42:17 +01003078 return -1091;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003079
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003080 device->p_uuid[UI_BITMAP] = device->p_uuid[UI_HISTORY_START];
3081 device->p_uuid[UI_HISTORY_START] = device->p_uuid[UI_HISTORY_START + 1];
Philipp Reisner4a23f262011-01-11 17:42:17 +01003082
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003083 drbd_info(device, "Lost last syncUUID packet, corrected:\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003084 drbd_uuid_dump(device, "peer", device->p_uuid, device->p_uuid[UI_SIZE], device->p_uuid[UI_FLAGS]);
Philipp Reisner4a23f262011-01-11 17:42:17 +01003085
Philipp Reisnerb411b362009-09-25 16:07:19 -07003086 return -1;
3087 }
3088 }
3089
3090 *rule_nr = 60;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003091 self = device->ldev->md.uuid[UI_CURRENT] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003092 for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003093 peer = device->p_uuid[i] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003094 if (self == peer)
3095 return -2;
3096 }
3097
3098 *rule_nr = 70;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003099 self = device->ldev->md.uuid[UI_BITMAP] & ~((u64)1);
3100 peer = device->p_uuid[UI_CURRENT] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003101 if (self == peer)
3102 return 1;
3103
3104 *rule_nr = 71;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003105 self = device->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003106 if (self == peer) {
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003107 if (connection->agreed_pro_version < 96 ?
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003108 (device->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) ==
3109 (device->p_uuid[UI_HISTORY_START] & ~((u64)1)) :
3110 self + UUID_NEW_BM_OFFSET == (device->ldev->md.uuid[UI_BITMAP] & ~((u64)1))) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003111 /* The last P_SYNC_UUID did not get though. Undo the last start of
3112 resync as sync source modifications of our UUIDs. */
3113
Lars Ellenberg44a4d552013-11-22 12:40:58 +01003114 if (connection->agreed_pro_version < 91)
Philipp Reisner4a23f262011-01-11 17:42:17 +01003115 return -1091;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003116
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003117 __drbd_uuid_set(device, UI_BITMAP, device->ldev->md.uuid[UI_HISTORY_START]);
3118 __drbd_uuid_set(device, UI_HISTORY_START, device->ldev->md.uuid[UI_HISTORY_START + 1]);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003119
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003120 drbd_info(device, "Last syncUUID did not get through, corrected:\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003121 drbd_uuid_dump(device, "self", device->ldev->md.uuid,
3122 device->state.disk >= D_NEGOTIATING ? drbd_bm_total_weight(device) : 0, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003123
3124 return 1;
3125 }
3126 }
3127
3128
3129 *rule_nr = 80;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003130 peer = device->p_uuid[UI_CURRENT] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003131 for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003132 self = device->ldev->md.uuid[i] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003133 if (self == peer)
3134 return 2;
3135 }
3136
3137 *rule_nr = 90;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003138 self = device->ldev->md.uuid[UI_BITMAP] & ~((u64)1);
3139 peer = device->p_uuid[UI_BITMAP] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003140 if (self == peer && self != ((u64)0))
3141 return 100;
3142
3143 *rule_nr = 100;
3144 for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003145 self = device->ldev->md.uuid[i] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003146 for (j = UI_HISTORY_START; j <= UI_HISTORY_END; j++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003147 peer = device->p_uuid[j] & ~((u64)1);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003148 if (self == peer)
3149 return -100;
3150 }
3151 }
3152
3153 return -1000;
3154}
3155
3156/* drbd_sync_handshake() returns the new conn state on success, or
3157 CONN_MASK (-1) on failure.
3158 */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003159static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,
3160 enum drbd_role peer_role,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003161 enum drbd_disk_state peer_disk) __must_hold(local)
3162{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003163 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003164 enum drbd_conns rv = C_MASK;
3165 enum drbd_disk_state mydisk;
Philipp Reisner44ed1672011-04-19 17:10:19 +02003166 struct net_conf *nc;
Andreas Gruenbacher6dff2902011-06-28 14:18:12 +02003167 int hg, rule_nr, rr_conflict, tentative;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003168
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003169 mydisk = device->state.disk;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003170 if (mydisk == D_NEGOTIATING)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003171 mydisk = device->new_state_tmp.disk;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003172
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003173 drbd_info(device, "drbd_sync_handshake:\n");
Philipp Reisner9f2247b2012-08-16 14:25:58 +02003174
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003175 spin_lock_irq(&device->ldev->md.uuid_lock);
3176 drbd_uuid_dump(device, "self", device->ldev->md.uuid, device->comm_bm_set, 0);
3177 drbd_uuid_dump(device, "peer", device->p_uuid,
3178 device->p_uuid[UI_SIZE], device->p_uuid[UI_FLAGS]);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003179
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003180 hg = drbd_uuid_compare(device, &rule_nr);
3181 spin_unlock_irq(&device->ldev->md.uuid_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003182
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003183 drbd_info(device, "uuid_compare()=%d by rule %d\n", hg, rule_nr);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003184
3185 if (hg == -1000) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003186 drbd_alert(device, "Unrelated data, aborting!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003187 return C_MASK;
3188 }
Philipp Reisner4a23f262011-01-11 17:42:17 +01003189 if (hg < -1000) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003190 drbd_alert(device, "To resolve this both sides have to support at least protocol %d\n", -hg - 1000);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003191 return C_MASK;
3192 }
3193
3194 if ((mydisk == D_INCONSISTENT && peer_disk > D_INCONSISTENT) ||
3195 (peer_disk == D_INCONSISTENT && mydisk > D_INCONSISTENT)) {
3196 int f = (hg == -100) || abs(hg) == 2;
3197 hg = mydisk > D_INCONSISTENT ? 1 : -1;
3198 if (f)
3199 hg = hg*2;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003200 drbd_info(device, "Becoming sync %s due to disk states.\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07003201 hg > 0 ? "source" : "target");
3202 }
3203
Adam Gandelman3a11a482010-04-08 16:48:23 -07003204 if (abs(hg) == 100)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003205 drbd_khelper(device, "initial-split-brain");
Adam Gandelman3a11a482010-04-08 16:48:23 -07003206
Philipp Reisner44ed1672011-04-19 17:10:19 +02003207 rcu_read_lock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003208 nc = rcu_dereference(peer_device->connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +02003209
3210 if (hg == 100 || (hg == -100 && nc->always_asbp)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003211 int pcount = (device->state.role == R_PRIMARY)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003212 + (peer_role == R_PRIMARY);
3213 int forced = (hg == -100);
3214
3215 switch (pcount) {
3216 case 0:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003217 hg = drbd_asb_recover_0p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003218 break;
3219 case 1:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003220 hg = drbd_asb_recover_1p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003221 break;
3222 case 2:
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003223 hg = drbd_asb_recover_2p(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003224 break;
3225 }
3226 if (abs(hg) < 100) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003227 drbd_warn(device, "Split-Brain detected, %d primaries, "
Philipp Reisnerb411b362009-09-25 16:07:19 -07003228 "automatically solved. Sync from %s node\n",
3229 pcount, (hg < 0) ? "peer" : "this");
3230 if (forced) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003231 drbd_warn(device, "Doing a full sync, since"
Philipp Reisnerb411b362009-09-25 16:07:19 -07003232 " UUIDs where ambiguous.\n");
3233 hg = hg*2;
3234 }
3235 }
3236 }
3237
3238 if (hg == -100) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003239 if (test_bit(DISCARD_MY_DATA, &device->flags) && !(device->p_uuid[UI_FLAGS]&1))
Philipp Reisnerb411b362009-09-25 16:07:19 -07003240 hg = -1;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003241 if (!test_bit(DISCARD_MY_DATA, &device->flags) && (device->p_uuid[UI_FLAGS]&1))
Philipp Reisnerb411b362009-09-25 16:07:19 -07003242 hg = 1;
3243
3244 if (abs(hg) < 100)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003245 drbd_warn(device, "Split-Brain detected, manually solved. "
Philipp Reisnerb411b362009-09-25 16:07:19 -07003246 "Sync from %s node\n",
3247 (hg < 0) ? "peer" : "this");
3248 }
Philipp Reisner44ed1672011-04-19 17:10:19 +02003249 rr_conflict = nc->rr_conflict;
Andreas Gruenbacher6dff2902011-06-28 14:18:12 +02003250 tentative = nc->tentative;
Philipp Reisner44ed1672011-04-19 17:10:19 +02003251 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07003252
3253 if (hg == -100) {
Lars Ellenberg580b9762010-02-26 23:15:23 +01003254 /* FIXME this log message is not correct if we end up here
3255 * after an attempted attach on a diskless node.
3256 * We just refuse to attach -- well, we drop the "connection"
3257 * to that disk, in a way... */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003258 drbd_alert(device, "Split-Brain detected but unresolved, dropping connection!\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003259 drbd_khelper(device, "split-brain");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003260 return C_MASK;
3261 }
3262
3263 if (hg > 0 && mydisk <= D_INCONSISTENT) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003264 drbd_err(device, "I shall become SyncSource, but I am inconsistent!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003265 return C_MASK;
3266 }
3267
3268 if (hg < 0 && /* by intention we do not use mydisk here. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003269 device->state.role == R_PRIMARY && device->state.disk >= D_CONSISTENT) {
Philipp Reisner44ed1672011-04-19 17:10:19 +02003270 switch (rr_conflict) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003271 case ASB_CALL_HELPER:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003272 drbd_khelper(device, "pri-lost");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003273 /* fall through */
3274 case ASB_DISCONNECT:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003275 drbd_err(device, "I shall become SyncTarget, but I am primary!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003276 return C_MASK;
3277 case ASB_VIOLENTLY:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003278 drbd_warn(device, "Becoming SyncTarget, violating the stable-data"
Philipp Reisnerb411b362009-09-25 16:07:19 -07003279 "assumption\n");
3280 }
3281 }
3282
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003283 if (tentative || test_bit(CONN_DRY_RUN, &peer_device->connection->flags)) {
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003284 if (hg == 0)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003285 drbd_info(device, "dry-run connect: No resync, would become Connected immediately.\n");
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003286 else
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003287 drbd_info(device, "dry-run connect: Would become %s, doing a %s resync.",
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003288 drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET),
3289 abs(hg) >= 2 ? "full" : "bit-map based");
3290 return C_MASK;
3291 }
3292
Philipp Reisnerb411b362009-09-25 16:07:19 -07003293 if (abs(hg) >= 2) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003294 drbd_info(device, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003295 if (drbd_bitmap_io(device, &drbd_bmio_set_n_write, "set_n_write from sync_handshake",
Lars Ellenberg20ceb2b2011-01-21 10:56:44 +01003296 BM_LOCKED_SET_ALLOWED))
Philipp Reisnerb411b362009-09-25 16:07:19 -07003297 return C_MASK;
3298 }
3299
3300 if (hg > 0) { /* become sync source. */
3301 rv = C_WF_BITMAP_S;
3302 } else if (hg < 0) { /* become sync target */
3303 rv = C_WF_BITMAP_T;
3304 } else {
3305 rv = C_CONNECTED;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003306 if (drbd_bm_total_weight(device)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003307 drbd_info(device, "No resync, but %lu bits in bitmap!\n",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003308 drbd_bm_total_weight(device));
Philipp Reisnerb411b362009-09-25 16:07:19 -07003309 }
3310 }
3311
3312 return rv;
3313}
3314
Philipp Reisnerf179d762011-05-16 17:31:47 +02003315static enum drbd_after_sb_p convert_after_sb(enum drbd_after_sb_p peer)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003316{
3317 /* ASB_DISCARD_REMOTE - ASB_DISCARD_LOCAL is valid */
Philipp Reisnerf179d762011-05-16 17:31:47 +02003318 if (peer == ASB_DISCARD_REMOTE)
3319 return ASB_DISCARD_LOCAL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003320
3321 /* any other things with ASB_DISCARD_REMOTE or ASB_DISCARD_LOCAL are invalid */
Philipp Reisnerf179d762011-05-16 17:31:47 +02003322 if (peer == ASB_DISCARD_LOCAL)
3323 return ASB_DISCARD_REMOTE;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003324
3325 /* everything else is valid if they are equal on both sides. */
Philipp Reisnerf179d762011-05-16 17:31:47 +02003326 return peer;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003327}
3328
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003329static int receive_protocol(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003330{
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003331 struct p_protocol *p = pi->data;
Philipp Reisner036b17e2011-05-16 17:38:11 +02003332 enum drbd_after_sb_p p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
3333 int p_proto, p_discard_my_data, p_two_primaries, cf;
3334 struct net_conf *nc, *old_net_conf, *new_net_conf = NULL;
3335 char integrity_alg[SHARED_SECRET_MAX] = "";
Herbert Xu9534d672016-01-24 21:19:21 +08003336 struct crypto_ahash *peer_integrity_tfm = NULL;
Philipp Reisner7aca6c72011-05-17 10:12:56 +02003337 void *int_dig_in = NULL, *int_dig_vv = NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003338
Philipp Reisnerb411b362009-09-25 16:07:19 -07003339 p_proto = be32_to_cpu(p->protocol);
3340 p_after_sb_0p = be32_to_cpu(p->after_sb_0p);
3341 p_after_sb_1p = be32_to_cpu(p->after_sb_1p);
3342 p_after_sb_2p = be32_to_cpu(p->after_sb_2p);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003343 p_two_primaries = be32_to_cpu(p->two_primaries);
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003344 cf = be32_to_cpu(p->conn_flags);
Andreas Gruenbacher6139f602011-05-06 20:00:02 +02003345 p_discard_my_data = cf & CF_DISCARD_MY_DATA;
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003346
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003347 if (connection->agreed_pro_version >= 87) {
Andreas Gruenbacher86db0612011-04-28 15:24:18 +02003348 int err;
Philipp Reisnercf14c2e2010-02-02 21:03:50 +01003349
Andreas Gruenbacher88104ca2011-04-28 21:47:21 +02003350 if (pi->size > sizeof(integrity_alg))
Andreas Gruenbacher86db0612011-04-28 15:24:18 +02003351 return -EIO;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003352 err = drbd_recv_all(connection, integrity_alg, pi->size);
Andreas Gruenbacher86db0612011-04-28 15:24:18 +02003353 if (err)
3354 return err;
Philipp Reisner036b17e2011-05-16 17:38:11 +02003355 integrity_alg[SHARED_SECRET_MAX - 1] = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003356 }
3357
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003358 if (pi->cmd != P_PROTOCOL_UPDATE) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003359 clear_bit(CONN_DRY_RUN, &connection->flags);
Philipp Reisner036b17e2011-05-16 17:38:11 +02003360
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003361 if (cf & CF_DRY_RUN)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003362 set_bit(CONN_DRY_RUN, &connection->flags);
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003363
3364 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003365 nc = rcu_dereference(connection->net_conf);
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003366
3367 if (p_proto != nc->wire_protocol) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003368 drbd_err(connection, "incompatible %s settings\n", "protocol");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003369 goto disconnect_rcu_unlock;
3370 }
3371
3372 if (convert_after_sb(p_after_sb_0p) != nc->after_sb_0p) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003373 drbd_err(connection, "incompatible %s settings\n", "after-sb-0pri");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003374 goto disconnect_rcu_unlock;
3375 }
3376
3377 if (convert_after_sb(p_after_sb_1p) != nc->after_sb_1p) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003378 drbd_err(connection, "incompatible %s settings\n", "after-sb-1pri");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003379 goto disconnect_rcu_unlock;
3380 }
3381
3382 if (convert_after_sb(p_after_sb_2p) != nc->after_sb_2p) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003383 drbd_err(connection, "incompatible %s settings\n", "after-sb-2pri");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003384 goto disconnect_rcu_unlock;
3385 }
3386
3387 if (p_discard_my_data && nc->discard_my_data) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003388 drbd_err(connection, "incompatible %s settings\n", "discard-my-data");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003389 goto disconnect_rcu_unlock;
3390 }
3391
3392 if (p_two_primaries != nc->two_primaries) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003393 drbd_err(connection, "incompatible %s settings\n", "allow-two-primaries");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003394 goto disconnect_rcu_unlock;
3395 }
3396
3397 if (strcmp(integrity_alg, nc->integrity_alg)) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003398 drbd_err(connection, "incompatible %s settings\n", "data-integrity-alg");
Andreas Gruenbacherfbc12f42011-07-15 17:04:26 +02003399 goto disconnect_rcu_unlock;
3400 }
3401
3402 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07003403 }
3404
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003405 if (integrity_alg[0]) {
3406 int hash_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003407
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003408 /*
3409 * We can only change the peer data integrity algorithm
3410 * here. Changing our own data integrity algorithm
3411 * requires that we send a P_PROTOCOL_UPDATE packet at
3412 * the same time; otherwise, the peer has no way to
3413 * tell between which packets the algorithm should
3414 * change.
3415 */
Philipp Reisnerb411b362009-09-25 16:07:19 -07003416
Herbert Xu9534d672016-01-24 21:19:21 +08003417 peer_integrity_tfm = crypto_alloc_ahash(integrity_alg, 0, CRYPTO_ALG_ASYNC);
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003418 if (!peer_integrity_tfm) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003419 drbd_err(connection, "peer data-integrity-alg %s not supported\n",
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003420 integrity_alg);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003421 goto disconnect;
3422 }
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003423
Herbert Xu9534d672016-01-24 21:19:21 +08003424 hash_size = crypto_ahash_digestsize(peer_integrity_tfm);
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003425 int_dig_in = kmalloc(hash_size, GFP_KERNEL);
3426 int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
3427 if (!(int_dig_in && int_dig_vv)) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003428 drbd_err(connection, "Allocation of buffers for data integrity checking failed\n");
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003429 goto disconnect;
3430 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003431 }
3432
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003433 new_net_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL);
3434 if (!new_net_conf) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003435 drbd_err(connection, "Allocation of new net_conf failed\n");
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003436 goto disconnect;
3437 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003438
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003439 mutex_lock(&connection->data.mutex);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003440 mutex_lock(&connection->resource->conf_update);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003441 old_net_conf = connection->net_conf;
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003442 *new_net_conf = *old_net_conf;
3443
3444 new_net_conf->wire_protocol = p_proto;
3445 new_net_conf->after_sb_0p = convert_after_sb(p_after_sb_0p);
3446 new_net_conf->after_sb_1p = convert_after_sb(p_after_sb_1p);
3447 new_net_conf->after_sb_2p = convert_after_sb(p_after_sb_2p);
3448 new_net_conf->two_primaries = p_two_primaries;
3449
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003450 rcu_assign_pointer(connection->net_conf, new_net_conf);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003451 mutex_unlock(&connection->resource->conf_update);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003452 mutex_unlock(&connection->data.mutex);
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003453
Herbert Xu9534d672016-01-24 21:19:21 +08003454 crypto_free_ahash(connection->peer_integrity_tfm);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003455 kfree(connection->int_dig_in);
3456 kfree(connection->int_dig_vv);
3457 connection->peer_integrity_tfm = peer_integrity_tfm;
3458 connection->int_dig_in = int_dig_in;
3459 connection->int_dig_vv = int_dig_vv;
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003460
3461 if (strcmp(old_net_conf->integrity_alg, integrity_alg))
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003462 drbd_info(connection, "peer data-integrity-alg: %s\n",
Andreas Gruenbacher7d4c7822011-07-17 23:06:12 +02003463 integrity_alg[0] ? integrity_alg : "(none)");
3464
3465 synchronize_rcu();
3466 kfree(old_net_conf);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003467 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003468
Philipp Reisner44ed1672011-04-19 17:10:19 +02003469disconnect_rcu_unlock:
3470 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07003471disconnect:
Herbert Xu9534d672016-01-24 21:19:21 +08003472 crypto_free_ahash(peer_integrity_tfm);
Philipp Reisner036b17e2011-05-16 17:38:11 +02003473 kfree(int_dig_in);
3474 kfree(int_dig_vv);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003475 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003476 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003477}
3478
3479/* helper function
3480 * input: alg name, feature name
3481 * return: NULL (alg name was "")
3482 * ERR_PTR(error) if something goes wrong
3483 * or the crypto hash ptr, if it worked out ok. */
Herbert Xu9534d672016-01-24 21:19:21 +08003484static struct crypto_ahash *drbd_crypto_alloc_digest_safe(const struct drbd_device *device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003485 const char *alg, const char *name)
3486{
Herbert Xu9534d672016-01-24 21:19:21 +08003487 struct crypto_ahash *tfm;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003488
3489 if (!alg[0])
3490 return NULL;
3491
Herbert Xu9534d672016-01-24 21:19:21 +08003492 tfm = crypto_alloc_ahash(alg, 0, CRYPTO_ALG_ASYNC);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003493 if (IS_ERR(tfm)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003494 drbd_err(device, "Can not allocate \"%s\" as %s (reason: %ld)\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07003495 alg, name, PTR_ERR(tfm));
3496 return tfm;
3497 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003498 return tfm;
3499}
3500
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003501static int ignore_remaining_packet(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003502{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003503 void *buffer = connection->data.rbuf;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003504 int size = pi->size;
3505
3506 while (size) {
3507 int s = min_t(int, size, DRBD_SOCKET_BUFFER_SIZE);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003508 s = drbd_recv(connection, buffer, s);
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003509 if (s <= 0) {
3510 if (s < 0)
3511 return s;
3512 break;
3513 }
3514 size -= s;
3515 }
3516 if (size)
3517 return -EIO;
3518 return 0;
3519}
3520
3521/*
3522 * config_unknown_volume - device configuration command for unknown volume
3523 *
3524 * When a device is added to an existing connection, the node on which the
3525 * device is added first will send configuration commands to its peer but the
3526 * peer will not know about the device yet. It will warn and ignore these
3527 * commands. Once the device is added on the second node, the second node will
3528 * send the same device configuration commands, but in the other direction.
3529 *
3530 * (We can also end up here if drbd is misconfigured.)
3531 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003532static int config_unknown_volume(struct drbd_connection *connection, struct packet_info *pi)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003533{
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02003534 drbd_warn(connection, "%s packet received for volume %u, which is not configured locally\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02003535 cmdname(pi->cmd), pi->vnr);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003536 return ignore_remaining_packet(connection, pi);
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003537}
3538
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003539static int receive_SyncParam(struct drbd_connection *connection, struct packet_info *pi)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003540{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003541 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003542 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003543 struct p_rs_param_95 *p;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003544 unsigned int header_size, data_size, exp_max_sz;
Herbert Xu9534d672016-01-24 21:19:21 +08003545 struct crypto_ahash *verify_tfm = NULL;
3546 struct crypto_ahash *csums_tfm = NULL;
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003547 struct net_conf *old_net_conf, *new_net_conf = NULL;
Philipp Reisner813472c2011-05-03 16:47:02 +02003548 struct disk_conf *old_disk_conf = NULL, *new_disk_conf = NULL;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003549 const int apv = connection->agreed_pro_version;
Philipp Reisner813472c2011-05-03 16:47:02 +02003550 struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
Philipp Reisner778f2712010-07-06 11:14:00 +02003551 int fifo_size = 0;
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003552 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003553
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003554 peer_device = conn_peer_device(connection, pi->vnr);
3555 if (!peer_device)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003556 return config_unknown_volume(connection, pi);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003557 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003558
3559 exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param)
3560 : apv == 88 ? sizeof(struct p_rs_param)
3561 + SHARED_SECRET_MAX
Philipp Reisner8e26f9c2010-07-06 17:25:54 +02003562 : apv <= 94 ? sizeof(struct p_rs_param_89)
3563 : /* apv >= 95 */ sizeof(struct p_rs_param_95);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003564
Andreas Gruenbachere2857212011-03-25 00:57:38 +01003565 if (pi->size > exp_max_sz) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003566 drbd_err(device, "SyncParam packet too long: received %u, expected <= %u bytes\n",
Andreas Gruenbachere2857212011-03-25 00:57:38 +01003567 pi->size, exp_max_sz);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003568 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003569 }
3570
3571 if (apv <= 88) {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003572 header_size = sizeof(struct p_rs_param);
Andreas Gruenbachere2857212011-03-25 00:57:38 +01003573 data_size = pi->size - header_size;
Philipp Reisner8e26f9c2010-07-06 17:25:54 +02003574 } else if (apv <= 94) {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003575 header_size = sizeof(struct p_rs_param_89);
Andreas Gruenbachere2857212011-03-25 00:57:38 +01003576 data_size = pi->size - header_size;
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02003577 D_ASSERT(device, data_size == 0);
Philipp Reisner8e26f9c2010-07-06 17:25:54 +02003578 } else {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003579 header_size = sizeof(struct p_rs_param_95);
Andreas Gruenbachere2857212011-03-25 00:57:38 +01003580 data_size = pi->size - header_size;
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02003581 D_ASSERT(device, data_size == 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003582 }
3583
3584 /* initialize verify_alg and csums_alg */
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003585 p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003586 memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
3587
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003588 err = drbd_recv_all(peer_device->connection, p, header_size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003589 if (err)
3590 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003591
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003592 mutex_lock(&connection->resource->conf_update);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003593 old_net_conf = peer_device->connection->net_conf;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003594 if (get_ldev(device)) {
Philipp Reisner813472c2011-05-03 16:47:02 +02003595 new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
3596 if (!new_disk_conf) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003597 put_ldev(device);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003598 mutex_unlock(&connection->resource->conf_update);
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003599 drbd_err(device, "Allocation of new disk_conf failed\n");
Philipp Reisner813472c2011-05-03 16:47:02 +02003600 return -ENOMEM;
3601 }
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003602
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003603 old_disk_conf = device->ldev->disk_conf;
Philipp Reisner813472c2011-05-03 16:47:02 +02003604 *new_disk_conf = *old_disk_conf;
3605
Andreas Gruenbacher6394b932011-05-11 14:29:52 +02003606 new_disk_conf->resync_rate = be32_to_cpu(p->resync_rate);
Philipp Reisner813472c2011-05-03 16:47:02 +02003607 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003608
3609 if (apv >= 88) {
3610 if (apv == 88) {
Philipp Reisner5de73822012-03-28 10:17:32 +02003611 if (data_size > SHARED_SECRET_MAX || data_size == 0) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003612 drbd_err(device, "verify-alg of wrong size, "
Philipp Reisner5de73822012-03-28 10:17:32 +02003613 "peer wants %u, accepting only up to %u byte\n",
3614 data_size, SHARED_SECRET_MAX);
Philipp Reisner813472c2011-05-03 16:47:02 +02003615 err = -EIO;
3616 goto reconnect;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003617 }
3618
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003619 err = drbd_recv_all(peer_device->connection, p->verify_alg, data_size);
Philipp Reisner813472c2011-05-03 16:47:02 +02003620 if (err)
3621 goto reconnect;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003622 /* we expect NUL terminated string */
3623 /* but just in case someone tries to be evil */
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02003624 D_ASSERT(device, p->verify_alg[data_size-1] == 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003625 p->verify_alg[data_size-1] = 0;
3626
3627 } else /* apv >= 89 */ {
3628 /* we still expect NUL terminated strings */
3629 /* but just in case someone tries to be evil */
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02003630 D_ASSERT(device, p->verify_alg[SHARED_SECRET_MAX-1] == 0);
3631 D_ASSERT(device, p->csums_alg[SHARED_SECRET_MAX-1] == 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003632 p->verify_alg[SHARED_SECRET_MAX-1] = 0;
3633 p->csums_alg[SHARED_SECRET_MAX-1] = 0;
3634 }
3635
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003636 if (strcmp(old_net_conf->verify_alg, p->verify_alg)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003637 if (device->state.conn == C_WF_REPORT_PARAMS) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003638 drbd_err(device, "Different verify-alg settings. me=\"%s\" peer=\"%s\"\n",
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003639 old_net_conf->verify_alg, p->verify_alg);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003640 goto disconnect;
3641 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003642 verify_tfm = drbd_crypto_alloc_digest_safe(device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003643 p->verify_alg, "verify-alg");
3644 if (IS_ERR(verify_tfm)) {
3645 verify_tfm = NULL;
3646 goto disconnect;
3647 }
3648 }
3649
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003650 if (apv >= 89 && strcmp(old_net_conf->csums_alg, p->csums_alg)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003651 if (device->state.conn == C_WF_REPORT_PARAMS) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003652 drbd_err(device, "Different csums-alg settings. me=\"%s\" peer=\"%s\"\n",
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003653 old_net_conf->csums_alg, p->csums_alg);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003654 goto disconnect;
3655 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003656 csums_tfm = drbd_crypto_alloc_digest_safe(device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003657 p->csums_alg, "csums-alg");
3658 if (IS_ERR(csums_tfm)) {
3659 csums_tfm = NULL;
3660 goto disconnect;
3661 }
3662 }
3663
Philipp Reisner813472c2011-05-03 16:47:02 +02003664 if (apv > 94 && new_disk_conf) {
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003665 new_disk_conf->c_plan_ahead = be32_to_cpu(p->c_plan_ahead);
3666 new_disk_conf->c_delay_target = be32_to_cpu(p->c_delay_target);
3667 new_disk_conf->c_fill_target = be32_to_cpu(p->c_fill_target);
3668 new_disk_conf->c_max_rate = be32_to_cpu(p->c_max_rate);
Philipp Reisner778f2712010-07-06 11:14:00 +02003669
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003670 fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003671 if (fifo_size != device->rs_plan_s->size) {
Philipp Reisner813472c2011-05-03 16:47:02 +02003672 new_plan = fifo_alloc(fifo_size);
3673 if (!new_plan) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003674 drbd_err(device, "kmalloc of fifo_buffer failed");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003675 put_ldev(device);
Philipp Reisner778f2712010-07-06 11:14:00 +02003676 goto disconnect;
3677 }
3678 }
Philipp Reisner8e26f9c2010-07-06 17:25:54 +02003679 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003680
Philipp Reisner91fd4da2011-04-20 17:47:29 +02003681 if (verify_tfm || csums_tfm) {
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003682 new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
3683 if (!new_net_conf) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003684 drbd_err(device, "Allocation of new net_conf failed\n");
Philipp Reisner91fd4da2011-04-20 17:47:29 +02003685 goto disconnect;
3686 }
3687
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003688 *new_net_conf = *old_net_conf;
Philipp Reisner91fd4da2011-04-20 17:47:29 +02003689
3690 if (verify_tfm) {
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003691 strcpy(new_net_conf->verify_alg, p->verify_alg);
3692 new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1;
Herbert Xu9534d672016-01-24 21:19:21 +08003693 crypto_free_ahash(peer_device->connection->verify_tfm);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003694 peer_device->connection->verify_tfm = verify_tfm;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003695 drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg);
Philipp Reisner91fd4da2011-04-20 17:47:29 +02003696 }
3697 if (csums_tfm) {
Philipp Reisner2ec91e02011-05-03 14:58:00 +02003698 strcpy(new_net_conf->csums_alg, p->csums_alg);
3699 new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1;
Herbert Xu9534d672016-01-24 21:19:21 +08003700 crypto_free_ahash(peer_device->connection->csums_tfm);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003701 peer_device->connection->csums_tfm = csums_tfm;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003702 drbd_info(device, "using csums-alg: \"%s\"\n", p->csums_alg);
Philipp Reisner91fd4da2011-04-20 17:47:29 +02003703 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003704 rcu_assign_pointer(connection->net_conf, new_net_conf);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003705 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003706 }
3707
Philipp Reisner813472c2011-05-03 16:47:02 +02003708 if (new_disk_conf) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003709 rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
3710 put_ldev(device);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003711 }
Philipp Reisner813472c2011-05-03 16:47:02 +02003712
3713 if (new_plan) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003714 old_plan = device->rs_plan_s;
3715 rcu_assign_pointer(device->rs_plan_s, new_plan);
Philipp Reisner813472c2011-05-03 16:47:02 +02003716 }
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003717
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003718 mutex_unlock(&connection->resource->conf_update);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003719 synchronize_rcu();
3720 if (new_net_conf)
3721 kfree(old_net_conf);
3722 kfree(old_disk_conf);
Philipp Reisner813472c2011-05-03 16:47:02 +02003723 kfree(old_plan);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003724
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003725 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003726
Philipp Reisner813472c2011-05-03 16:47:02 +02003727reconnect:
3728 if (new_disk_conf) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003729 put_ldev(device);
Philipp Reisner813472c2011-05-03 16:47:02 +02003730 kfree(new_disk_conf);
3731 }
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003732 mutex_unlock(&connection->resource->conf_update);
Philipp Reisner813472c2011-05-03 16:47:02 +02003733 return -EIO;
3734
Philipp Reisnerb411b362009-09-25 16:07:19 -07003735disconnect:
Philipp Reisner813472c2011-05-03 16:47:02 +02003736 kfree(new_plan);
3737 if (new_disk_conf) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003738 put_ldev(device);
Philipp Reisner813472c2011-05-03 16:47:02 +02003739 kfree(new_disk_conf);
3740 }
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003741 mutex_unlock(&connection->resource->conf_update);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003742 /* just for completeness: actually not needed,
3743 * as this is not reached if csums_tfm was ok. */
Herbert Xu9534d672016-01-24 21:19:21 +08003744 crypto_free_ahash(csums_tfm);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003745 /* but free the verify_tfm again, if csums_tfm did not work out */
Herbert Xu9534d672016-01-24 21:19:21 +08003746 crypto_free_ahash(verify_tfm);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003747 conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003748 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003749}
3750
Philipp Reisnerb411b362009-09-25 16:07:19 -07003751/* warn if the arguments differ by more than 12.5% */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003752static void warn_if_differ_considerably(struct drbd_device *device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003753 const char *s, sector_t a, sector_t b)
3754{
3755 sector_t d;
3756 if (a == 0 || b == 0)
3757 return;
3758 d = (a > b) ? (a - b) : (b - a);
3759 if (d > (a>>3) || d > (b>>3))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003760 drbd_warn(device, "Considerable difference in %s: %llus vs. %llus\n", s,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003761 (unsigned long long)a, (unsigned long long)b);
3762}
3763
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003764static int receive_sizes(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003765{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003766 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003767 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003768 struct p_sizes *p = pi->data;
Philipp Reisnere96c9632013-06-25 16:50:07 +02003769 enum determine_dev_size dd = DS_UNCHANGED;
Lars Ellenberg6a8d68b2014-03-18 12:22:14 +01003770 sector_t p_size, p_usize, p_csize, my_usize;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003771 int ldsc = 0; /* local disk size changed */
Philipp Reisnere89b5912010-03-24 17:11:33 +01003772 enum dds_flags ddsf;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003773
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003774 peer_device = conn_peer_device(connection, pi->vnr);
3775 if (!peer_device)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003776 return config_unknown_volume(connection, pi);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003777 device = peer_device->device;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003778
Philipp Reisnerb411b362009-09-25 16:07:19 -07003779 p_size = be64_to_cpu(p->d_size);
3780 p_usize = be64_to_cpu(p->u_size);
Lars Ellenberg6a8d68b2014-03-18 12:22:14 +01003781 p_csize = be64_to_cpu(p->c_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003782
Philipp Reisnerb411b362009-09-25 16:07:19 -07003783 /* just store the peer's disk size for now.
3784 * we still need to figure out whether we accept that. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003785 device->p_size = p_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003786
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003787 if (get_ldev(device)) {
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003788 rcu_read_lock();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003789 my_usize = rcu_dereference(device->ldev->disk_conf)->disk_size;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003790 rcu_read_unlock();
3791
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003792 warn_if_differ_considerably(device, "lower level device sizes",
3793 p_size, drbd_get_max_capacity(device->ldev));
3794 warn_if_differ_considerably(device, "user requested size",
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003795 p_usize, my_usize);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003796
3797 /* if this is the first connect, or an otherwise expected
3798 * param exchange, choose the minimum */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003799 if (device->state.conn == C_WF_REPORT_PARAMS)
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003800 p_usize = min_not_zero(my_usize, p_usize);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003801
3802 /* Never shrink a device with usable data during connect.
3803 But allow online shrinking if we are connected. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003804 if (drbd_new_dev_size(device, device->ldev, p_usize, 0) <
3805 drbd_get_capacity(device->this_bdev) &&
3806 device->state.disk >= D_OUTDATED &&
3807 device->state.conn < C_CONNECTED) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003808 drbd_err(device, "The peer's disk size is too small!\n");
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003809 conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003810 put_ldev(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003811 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003812 }
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003813
3814 if (my_usize != p_usize) {
3815 struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
3816
3817 new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
3818 if (!new_disk_conf) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003819 drbd_err(device, "Allocation of new disk_conf failed\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003820 put_ldev(device);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003821 return -ENOMEM;
3822 }
3823
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003824 mutex_lock(&connection->resource->conf_update);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003825 old_disk_conf = device->ldev->disk_conf;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003826 *new_disk_conf = *old_disk_conf;
3827 new_disk_conf->disk_size = p_usize;
3828
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003829 rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02003830 mutex_unlock(&connection->resource->conf_update);
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003831 synchronize_rcu();
3832 kfree(old_disk_conf);
3833
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003834 drbd_info(device, "Peer sets u_size to %lu sectors\n",
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02003835 (unsigned long)my_usize);
3836 }
3837
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003838 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003839 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003840
Lars Ellenberg20c68fd2014-04-28 18:43:25 +02003841 device->peer_max_bio_size = be32_to_cpu(p->max_bio_size);
Lars Ellenberg20c68fd2014-04-28 18:43:25 +02003842 /* Leave drbd_reconsider_max_bio_size() before drbd_determine_dev_size().
3843 In case we cleared the QUEUE_FLAG_DISCARD from our queue in
3844 drbd_reconsider_max_bio_size(), we can be sure that after
3845 drbd_determine_dev_size() no REQ_DISCARDs are in the queue. */
3846
Philipp Reisnere89b5912010-03-24 17:11:33 +01003847 ddsf = be16_to_cpu(p->dds_flags);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003848 if (get_ldev(device)) {
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01003849 drbd_reconsider_max_bio_size(device, device->ldev);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003850 dd = drbd_determine_dev_size(device, ddsf, NULL);
3851 put_ldev(device);
Philipp Reisnere96c9632013-06-25 16:50:07 +02003852 if (dd == DS_ERROR)
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003853 return -EIO;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003854 drbd_md_sync(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003855 } else {
Lars Ellenberg6a8d68b2014-03-18 12:22:14 +01003856 /*
3857 * I am diskless, need to accept the peer's *current* size.
3858 * I must NOT accept the peers backing disk size,
3859 * it may have been larger than mine all along...
3860 *
3861 * At this point, the peer knows more about my disk, or at
3862 * least about what we last agreed upon, than myself.
3863 * So if his c_size is less than his d_size, the most likely
3864 * reason is that *my* d_size was smaller last time we checked.
3865 *
3866 * However, if he sends a zero current size,
3867 * take his (user-capped or) backing disk size anyways.
3868 */
Philipp Reisner8fe39aa2013-11-22 13:22:13 +01003869 drbd_reconsider_max_bio_size(device, NULL);
Lars Ellenberg6a8d68b2014-03-18 12:22:14 +01003870 drbd_set_my_capacity(device, p_csize ?: p_usize ?: p_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003871 }
3872
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003873 if (get_ldev(device)) {
3874 if (device->ldev->known_size != drbd_get_capacity(device->ldev->backing_bdev)) {
3875 device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003876 ldsc = 1;
3877 }
3878
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003879 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003880 }
3881
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003882 if (device->state.conn > C_WF_REPORT_PARAMS) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003883 if (be64_to_cpu(p->c_size) !=
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003884 drbd_get_capacity(device->this_bdev) || ldsc) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003885 /* we have different sizes, probably peer
3886 * needs to know my new size... */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02003887 drbd_send_sizes(peer_device, 0, ddsf);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003888 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003889 if (test_and_clear_bit(RESIZE_PENDING, &device->flags) ||
3890 (dd == DS_GREW && device->state.conn == C_CONNECTED)) {
3891 if (device->state.pdsk >= D_INCONSISTENT &&
3892 device->state.disk >= D_INCONSISTENT) {
Philipp Reisnere89b5912010-03-24 17:11:33 +01003893 if (ddsf & DDSF_NO_RESYNC)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003894 drbd_info(device, "Resync of new storage suppressed with --assume-clean\n");
Philipp Reisnere89b5912010-03-24 17:11:33 +01003895 else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003896 resync_after_online_grow(device);
Philipp Reisnere89b5912010-03-24 17:11:33 +01003897 } else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003898 set_bit(RESYNC_AFTER_NEG, &device->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003899 }
3900 }
3901
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003902 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003903}
3904
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003905static int receive_uuids(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07003906{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003907 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003908 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02003909 struct p_uuids *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003910 u64 *p_uuid;
Lars Ellenberg62b0da32011-01-20 13:25:21 +01003911 int i, updated_uuids = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003912
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003913 peer_device = conn_peer_device(connection, pi->vnr);
3914 if (!peer_device)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02003915 return config_unknown_volume(connection, pi);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003916 device = peer_device->device;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01003917
Philipp Reisnerb411b362009-09-25 16:07:19 -07003918 p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO);
Jing Wang063eacf2012-10-25 15:00:56 +08003919 if (!p_uuid) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003920 drbd_err(device, "kmalloc of p_uuid failed\n");
Jing Wang063eacf2012-10-25 15:00:56 +08003921 return false;
3922 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07003923
3924 for (i = UI_CURRENT; i < UI_EXTENDED_SIZE; i++)
3925 p_uuid[i] = be64_to_cpu(p->uuid[i]);
3926
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003927 kfree(device->p_uuid);
3928 device->p_uuid = p_uuid;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003929
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003930 if (device->state.conn < C_CONNECTED &&
3931 device->state.disk < D_INCONSISTENT &&
3932 device->state.role == R_PRIMARY &&
3933 (device->ed_uuid & ~((u64)1)) != (p_uuid[UI_CURRENT] & ~((u64)1))) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003934 drbd_err(device, "Can only connect to data with current UUID=%016llX\n",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003935 (unsigned long long)device->ed_uuid);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003936 conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003937 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003938 }
3939
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003940 if (get_ldev(device)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07003941 int skip_initial_sync =
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003942 device->state.conn == C_CONNECTED &&
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02003943 peer_device->connection->agreed_pro_version >= 90 &&
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003944 device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
Philipp Reisnerb411b362009-09-25 16:07:19 -07003945 (p_uuid[UI_FLAGS] & 8);
3946 if (skip_initial_sync) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02003947 drbd_info(device, "Accepted new current UUID, preparing to skip initial sync\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003948 drbd_bitmap_io(device, &drbd_bmio_clear_n_write,
Lars Ellenberg20ceb2b2011-01-21 10:56:44 +01003949 "clear_n_write from receive_uuids",
3950 BM_LOCKED_TEST_ALLOWED);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003951 _drbd_uuid_set(device, UI_CURRENT, p_uuid[UI_CURRENT]);
3952 _drbd_uuid_set(device, UI_BITMAP, 0);
3953 _drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
Philipp Reisnerb411b362009-09-25 16:07:19 -07003954 CS_VERBOSE, NULL);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003955 drbd_md_sync(device);
Lars Ellenberg62b0da32011-01-20 13:25:21 +01003956 updated_uuids = 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003957 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003958 put_ldev(device);
3959 } else if (device->state.disk < D_INCONSISTENT &&
3960 device->state.role == R_PRIMARY) {
Philipp Reisner18a50fa2010-06-21 14:14:15 +02003961 /* I am a diskless primary, the peer just created a new current UUID
3962 for me. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003963 updated_uuids = drbd_set_ed_uuid(device, p_uuid[UI_CURRENT]);
Philipp Reisnerb411b362009-09-25 16:07:19 -07003964 }
3965
3966 /* Before we test for the disk state, we should wait until an eventually
3967 ongoing cluster wide state change is finished. That is important if
3968 we are primary and are detaching from our disk. We need to see the
3969 new disk state... */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003970 mutex_lock(device->state_mutex);
3971 mutex_unlock(device->state_mutex);
3972 if (device->state.conn >= C_CONNECTED && device->state.disk < D_INCONSISTENT)
3973 updated_uuids |= drbd_set_ed_uuid(device, p_uuid[UI_CURRENT]);
Lars Ellenberg62b0da32011-01-20 13:25:21 +01003974
3975 if (updated_uuids)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02003976 drbd_print_uuids(device, "receiver updated UUIDs to");
Philipp Reisnerb411b362009-09-25 16:07:19 -07003977
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01003978 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07003979}
3980
3981/**
3982 * convert_state() - Converts the peer's view of the cluster state to our point of view
3983 * @ps: The state as seen by the peer.
3984 */
3985static union drbd_state convert_state(union drbd_state ps)
3986{
3987 union drbd_state ms;
3988
3989 static enum drbd_conns c_tab[] = {
Philipp Reisner369bea62011-07-06 23:04:44 +02003990 [C_WF_REPORT_PARAMS] = C_WF_REPORT_PARAMS,
Philipp Reisnerb411b362009-09-25 16:07:19 -07003991 [C_CONNECTED] = C_CONNECTED,
3992
3993 [C_STARTING_SYNC_S] = C_STARTING_SYNC_T,
3994 [C_STARTING_SYNC_T] = C_STARTING_SYNC_S,
3995 [C_DISCONNECTING] = C_TEAR_DOWN, /* C_NETWORK_FAILURE, */
3996 [C_VERIFY_S] = C_VERIFY_T,
3997 [C_MASK] = C_MASK,
3998 };
3999
4000 ms.i = ps.i;
4001
4002 ms.conn = c_tab[ps.conn];
4003 ms.peer = ps.role;
4004 ms.role = ps.peer;
4005 ms.pdsk = ps.disk;
4006 ms.disk = ps.pdsk;
4007 ms.peer_isp = (ps.aftr_isp | ps.user_isp);
4008
4009 return ms;
4010}
4011
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004012static int receive_req_state(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004013{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004014 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004015 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004016 struct p_req_state *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004017 union drbd_state mask, val;
Andreas Gruenbacherbf885f82010-12-08 00:39:32 +01004018 enum drbd_state_rv rv;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004019
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004020 peer_device = conn_peer_device(connection, pi->vnr);
4021 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004022 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004023 device = peer_device->device;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004024
Philipp Reisnerb411b362009-09-25 16:07:19 -07004025 mask.i = be32_to_cpu(p->mask);
4026 val.i = be32_to_cpu(p->val);
4027
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004028 if (test_bit(RESOLVE_CONFLICTS, &peer_device->connection->flags) &&
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004029 mutex_is_locked(device->state_mutex)) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004030 drbd_send_sr_reply(peer_device, SS_CONCURRENT_ST_CHG);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004031 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004032 }
4033
4034 mask = convert_state(mask);
4035 val = convert_state(val);
4036
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004037 rv = drbd_change_state(device, CS_VERBOSE, mask, val);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004038 drbd_send_sr_reply(peer_device, rv);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004039
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004040 drbd_md_sync(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004041
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004042 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004043}
4044
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004045static int receive_req_conn_state(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004046{
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004047 struct p_req_state *p = pi->data;
Philipp Reisnerdfafcc82011-03-16 10:55:07 +01004048 union drbd_state mask, val;
4049 enum drbd_state_rv rv;
4050
4051 mask.i = be32_to_cpu(p->mask);
4052 val.i = be32_to_cpu(p->val);
4053
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004054 if (test_bit(RESOLVE_CONFLICTS, &connection->flags) &&
4055 mutex_is_locked(&connection->cstate_mutex)) {
4056 conn_send_sr_reply(connection, SS_CONCURRENT_ST_CHG);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004057 return 0;
Philipp Reisnerdfafcc82011-03-16 10:55:07 +01004058 }
4059
4060 mask = convert_state(mask);
4061 val = convert_state(val);
4062
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004063 rv = conn_request_state(connection, mask, val, CS_VERBOSE | CS_LOCAL_ONLY | CS_IGN_OUTD_FAIL);
4064 conn_send_sr_reply(connection, rv);
Philipp Reisnerdfafcc82011-03-16 10:55:07 +01004065
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004066 return 0;
Philipp Reisnerdfafcc82011-03-16 10:55:07 +01004067}
4068
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004069static int receive_state(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004070{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004071 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004072 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004073 struct p_state *p = pi->data;
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004074 union drbd_state os, ns, peer_state;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004075 enum drbd_disk_state real_peer_disk;
Philipp Reisner65d922c2010-06-16 16:18:09 +02004076 enum chg_state_flags cs_flags;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004077 int rv;
4078
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004079 peer_device = conn_peer_device(connection, pi->vnr);
4080 if (!peer_device)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004081 return config_unknown_volume(connection, pi);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004082 device = peer_device->device;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004083
Philipp Reisnerb411b362009-09-25 16:07:19 -07004084 peer_state.i = be32_to_cpu(p->state);
4085
4086 real_peer_disk = peer_state.disk;
4087 if (peer_state.disk == D_NEGOTIATING) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004088 real_peer_disk = device->p_uuid[UI_FLAGS] & 4 ? D_INCONSISTENT : D_CONSISTENT;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004089 drbd_info(device, "real peer disk state = %s\n", drbd_disk_str(real_peer_disk));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004090 }
4091
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004092 spin_lock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004093 retry:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004094 os = ns = drbd_read_state(device);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004095 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004096
Philipp Reisner668700b2015-03-16 16:08:29 +01004097 /* If some other part of the code (ack_receiver thread, timeout)
Lars Ellenberg545752d2011-12-05 14:39:25 +01004098 * already decided to close the connection again,
4099 * we must not "re-establish" it here. */
4100 if (os.conn <= C_TEAR_DOWN)
Lars Ellenberg58ffa582012-07-26 14:09:49 +02004101 return -ECONNRESET;
Lars Ellenberg545752d2011-12-05 14:39:25 +01004102
Lars Ellenberg40424e42011-09-26 15:24:56 +02004103 /* If this is the "end of sync" confirmation, usually the peer disk
4104 * transitions from D_INCONSISTENT to D_UP_TO_DATE. For empty (0 bits
4105 * set) resync started in PausedSyncT, or if the timing of pause-/
4106 * unpause-sync events has been "just right", the peer disk may
4107 * transition from D_CONSISTENT to D_UP_TO_DATE as well.
4108 */
4109 if ((os.pdsk == D_INCONSISTENT || os.pdsk == D_CONSISTENT) &&
4110 real_peer_disk == D_UP_TO_DATE &&
Lars Ellenberge9ef7bb2010-10-07 15:55:39 +02004111 os.conn > C_CONNECTED && os.disk == D_UP_TO_DATE) {
4112 /* If we are (becoming) SyncSource, but peer is still in sync
4113 * preparation, ignore its uptodate-ness to avoid flapping, it
4114 * will change to inconsistent once the peer reaches active
4115 * syncing states.
4116 * It may have changed syncer-paused flags, however, so we
4117 * cannot ignore this completely. */
4118 if (peer_state.conn > C_CONNECTED &&
4119 peer_state.conn < C_SYNC_SOURCE)
4120 real_peer_disk = D_INCONSISTENT;
4121
4122 /* if peer_state changes to connected at the same time,
4123 * it explicitly notifies us that it finished resync.
4124 * Maybe we should finish it up, too? */
4125 else if (os.conn >= C_SYNC_SOURCE &&
4126 peer_state.conn == C_CONNECTED) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004127 if (drbd_bm_total_weight(device) <= device->rs_failed)
4128 drbd_resync_finished(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004129 return 0;
Lars Ellenberge9ef7bb2010-10-07 15:55:39 +02004130 }
4131 }
4132
Lars Ellenberg02b91b52012-06-28 18:26:52 +02004133 /* explicit verify finished notification, stop sector reached. */
4134 if (os.conn == C_VERIFY_T && os.disk == D_UP_TO_DATE &&
4135 peer_state.conn == C_CONNECTED && real_peer_disk == D_UP_TO_DATE) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004136 ov_out_of_sync_print(device);
4137 drbd_resync_finished(device);
Lars Ellenberg58ffa582012-07-26 14:09:49 +02004138 return 0;
Lars Ellenberg02b91b52012-06-28 18:26:52 +02004139 }
4140
Lars Ellenberge9ef7bb2010-10-07 15:55:39 +02004141 /* peer says his disk is inconsistent, while we think it is uptodate,
4142 * and this happens while the peer still thinks we have a sync going on,
4143 * but we think we are already done with the sync.
4144 * We ignore this to avoid flapping pdsk.
4145 * This should not happen, if the peer is a recent version of drbd. */
4146 if (os.pdsk == D_UP_TO_DATE && real_peer_disk == D_INCONSISTENT &&
4147 os.conn == C_CONNECTED && peer_state.conn > C_SYNC_SOURCE)
4148 real_peer_disk = D_UP_TO_DATE;
4149
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004150 if (ns.conn == C_WF_REPORT_PARAMS)
4151 ns.conn = C_CONNECTED;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004152
Philipp Reisner67531712010-10-27 12:21:30 +02004153 if (peer_state.conn == C_AHEAD)
4154 ns.conn = C_BEHIND;
4155
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004156 if (device->p_uuid && peer_state.disk >= D_NEGOTIATING &&
4157 get_ldev_if_state(device, D_NEGOTIATING)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07004158 int cr; /* consider resync */
4159
4160 /* if we established a new connection */
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004161 cr = (os.conn < C_CONNECTED);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004162 /* if we had an established connection
4163 * and one of the nodes newly attaches a disk */
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004164 cr |= (os.conn == C_CONNECTED &&
Philipp Reisnerb411b362009-09-25 16:07:19 -07004165 (peer_state.disk == D_NEGOTIATING ||
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004166 os.disk == D_NEGOTIATING));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004167 /* if we have both been inconsistent, and the peer has been
4168 * forced to be UpToDate with --overwrite-data */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004169 cr |= test_bit(CONSIDER_RESYNC, &device->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004170 /* if we had been plain connected, and the admin requested to
4171 * start a sync by "invalidate" or "invalidate-remote" */
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004172 cr |= (os.conn == C_CONNECTED &&
Philipp Reisnerb411b362009-09-25 16:07:19 -07004173 (peer_state.conn >= C_STARTING_SYNC_S &&
4174 peer_state.conn <= C_WF_BITMAP_T));
4175
4176 if (cr)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004177 ns.conn = drbd_sync_handshake(peer_device, peer_state.role, real_peer_disk);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004178
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004179 put_ldev(device);
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004180 if (ns.conn == C_MASK) {
4181 ns.conn = C_CONNECTED;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004182 if (device->state.disk == D_NEGOTIATING) {
4183 drbd_force_state(device, NS(disk, D_FAILED));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004184 } else if (peer_state.disk == D_NEGOTIATING) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004185 drbd_err(device, "Disk attach process on the peer node was aborted.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07004186 peer_state.disk = D_DISKLESS;
Lars Ellenberg580b9762010-02-26 23:15:23 +01004187 real_peer_disk = D_DISKLESS;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004188 } else {
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004189 if (test_and_clear_bit(CONN_DRY_RUN, &peer_device->connection->flags))
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004190 return -EIO;
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02004191 D_ASSERT(device, os.conn == C_WF_REPORT_PARAMS);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004192 conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004193 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004194 }
4195 }
4196 }
4197
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004198 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004199 if (os.i != drbd_read_state(device).i)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004200 goto retry;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004201 clear_bit(CONSIDER_RESYNC, &device->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004202 ns.peer = peer_state.role;
4203 ns.pdsk = real_peer_disk;
4204 ns.peer_isp = (peer_state.aftr_isp | peer_state.user_isp);
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004205 if ((ns.conn == C_CONNECTED || ns.conn == C_WF_BITMAP_S) && ns.disk == D_NEGOTIATING)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004206 ns.disk = device->new_state_tmp.disk;
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004207 cs_flags = CS_VERBOSE + (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED ? 0 : CS_HARD);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004208 if (ns.pdsk == D_CONSISTENT && drbd_suspended(device) && ns.conn == C_CONNECTED && os.conn < C_CONNECTED &&
4209 test_bit(NEW_CUR_UUID, &device->flags)) {
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01004210 /* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
Philipp Reisner481c6f52010-06-22 14:03:27 +02004211 for temporal network outages! */
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004212 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004213 drbd_err(device, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004214 tl_clear(peer_device->connection);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004215 drbd_uuid_new_current(device);
4216 clear_bit(NEW_CUR_UUID, &device->flags);
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004217 conn_request_state(peer_device->connection, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004218 return -EIO;
Philipp Reisner481c6f52010-06-22 14:03:27 +02004219 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004220 rv = _drbd_set_state(device, ns, cs_flags, NULL);
4221 ns = drbd_read_state(device);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004222 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004223
4224 if (rv < SS_SUCCESS) {
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004225 conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004226 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004227 }
4228
Lars Ellenberg4ac4aad2010-07-22 17:39:26 +02004229 if (os.conn > C_WF_REPORT_PARAMS) {
4230 if (ns.conn > C_CONNECTED && peer_state.conn <= C_CONNECTED &&
Philipp Reisnerb411b362009-09-25 16:07:19 -07004231 peer_state.disk != D_NEGOTIATING ) {
4232 /* we want resync, peer has not yet decided to sync... */
4233 /* Nowadays only used when forcing a node into primary role and
4234 setting its disk to UpToDate with that */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004235 drbd_send_uuids(peer_device);
4236 drbd_send_current_state(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004237 }
4238 }
4239
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004240 clear_bit(DISCARD_MY_DATA, &device->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004241
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004242 drbd_md_sync(device); /* update connected indicator, la_size_sect, ... */
Philipp Reisnerb411b362009-09-25 16:07:19 -07004243
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004244 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004245}
4246
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004247static int receive_sync_uuid(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004248{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004249 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004250 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004251 struct p_rs_uuid *p = pi->data;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004252
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004253 peer_device = conn_peer_device(connection, pi->vnr);
4254 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004255 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004256 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004257
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004258 wait_event(device->misc_wait,
4259 device->state.conn == C_WF_SYNC_UUID ||
4260 device->state.conn == C_BEHIND ||
4261 device->state.conn < C_CONNECTED ||
4262 device->state.disk < D_NEGOTIATING);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004263
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02004264 /* D_ASSERT(device, device->state.conn == C_WF_SYNC_UUID ); */
Philipp Reisnerb411b362009-09-25 16:07:19 -07004265
Philipp Reisnerb411b362009-09-25 16:07:19 -07004266 /* Here the _drbd_uuid_ functions are right, current should
4267 _not_ be rotated into the history */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004268 if (get_ldev_if_state(device, D_NEGOTIATING)) {
4269 _drbd_uuid_set(device, UI_CURRENT, be64_to_cpu(p->uuid));
4270 _drbd_uuid_set(device, UI_BITMAP, 0UL);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004271
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004272 drbd_print_uuids(device, "updated sync uuid");
4273 drbd_start_resync(device, C_SYNC_TARGET);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004274
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004275 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004276 } else
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004277 drbd_err(device, "Ignoring SyncUUID packet!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07004278
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004279 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004280}
4281
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004282/**
4283 * receive_bitmap_plain
4284 *
4285 * Return 0 when done, 1 when another iteration is needed, and a negative error
4286 * code upon failure.
4287 */
4288static int
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004289receive_bitmap_plain(struct drbd_peer_device *peer_device, unsigned int size,
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004290 unsigned long *p, struct bm_xfer_ctx *c)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004291{
Andreas Gruenbacher50d0b1a2011-03-30 11:53:51 +02004292 unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004293 drbd_header_size(peer_device->connection);
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004294 unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
Andreas Gruenbacher50d0b1a2011-03-30 11:53:51 +02004295 c->bm_words - c->word_offset);
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004296 unsigned int want = num_words * sizeof(*p);
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004297 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004298
Andreas Gruenbacher50d0b1a2011-03-30 11:53:51 +02004299 if (want != size) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004300 drbd_err(peer_device, "%s:want (%u) != size (%u)\n", __func__, want, size);
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004301 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004302 }
4303 if (want == 0)
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004304 return 0;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004305 err = drbd_recv_all(peer_device->connection, p, want);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004306 if (err)
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004307 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004308
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004309 drbd_bm_merge_lel(peer_device->device, c->word_offset, num_words, p);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004310
4311 c->word_offset += num_words;
4312 c->bit_offset = c->word_offset * BITS_PER_LONG;
4313 if (c->bit_offset > c->bm_bits)
4314 c->bit_offset = c->bm_bits;
4315
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004316 return 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004317}
4318
Andreas Gruenbachera02d1242011-03-22 17:20:45 +01004319static enum drbd_bitmap_code dcbp_get_code(struct p_compressed_bm *p)
4320{
4321 return (enum drbd_bitmap_code)(p->encoding & 0x0f);
4322}
4323
4324static int dcbp_get_start(struct p_compressed_bm *p)
4325{
4326 return (p->encoding & 0x80) != 0;
4327}
4328
4329static int dcbp_get_pad_bits(struct p_compressed_bm *p)
4330{
4331 return (p->encoding >> 4) & 0x7;
4332}
4333
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004334/**
4335 * recv_bm_rle_bits
4336 *
4337 * Return 0 when done, 1 when another iteration is needed, and a negative error
4338 * code upon failure.
4339 */
4340static int
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004341recv_bm_rle_bits(struct drbd_peer_device *peer_device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07004342 struct p_compressed_bm *p,
Philipp Reisnerc6d25cf2011-01-19 16:13:06 +01004343 struct bm_xfer_ctx *c,
4344 unsigned int len)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004345{
4346 struct bitstream bs;
4347 u64 look_ahead;
4348 u64 rl;
4349 u64 tmp;
4350 unsigned long s = c->bit_offset;
4351 unsigned long e;
Andreas Gruenbachera02d1242011-03-22 17:20:45 +01004352 int toggle = dcbp_get_start(p);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004353 int have;
4354 int bits;
4355
Andreas Gruenbachera02d1242011-03-22 17:20:45 +01004356 bitstream_init(&bs, p->code, len, dcbp_get_pad_bits(p));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004357
4358 bits = bitstream_get_bits(&bs, &look_ahead, 64);
4359 if (bits < 0)
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004360 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004361
4362 for (have = bits; have > 0; s += rl, toggle = !toggle) {
4363 bits = vli_decode_bits(&rl, look_ahead);
4364 if (bits <= 0)
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004365 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004366
4367 if (toggle) {
4368 e = s + rl -1;
4369 if (e >= c->bm_bits) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004370 drbd_err(peer_device, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e);
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004371 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004372 }
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004373 _drbd_bm_set_bits(peer_device->device, s, e);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004374 }
4375
4376 if (have < bits) {
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004377 drbd_err(peer_device, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07004378 have, bits, look_ahead,
4379 (unsigned int)(bs.cur.b - p->code),
4380 (unsigned int)bs.buf_len);
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004381 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004382 }
Lars Ellenbergd2da5b02013-10-23 10:59:18 +02004383 /* if we consumed all 64 bits, assign 0; >> 64 is "undefined"; */
4384 if (likely(bits < 64))
4385 look_ahead >>= bits;
4386 else
4387 look_ahead = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004388 have -= bits;
4389
4390 bits = bitstream_get_bits(&bs, &tmp, 64 - have);
4391 if (bits < 0)
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004392 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004393 look_ahead |= tmp << have;
4394 have += bits;
4395 }
4396
4397 c->bit_offset = s;
4398 bm_xfer_ctx_bit_to_word_offset(c);
4399
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004400 return (s != c->bm_bits);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004401}
4402
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004403/**
4404 * decode_bitmap_c
4405 *
4406 * Return 0 when done, 1 when another iteration is needed, and a negative error
4407 * code upon failure.
4408 */
4409static int
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004410decode_bitmap_c(struct drbd_peer_device *peer_device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07004411 struct p_compressed_bm *p,
Philipp Reisnerc6d25cf2011-01-19 16:13:06 +01004412 struct bm_xfer_ctx *c,
4413 unsigned int len)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004414{
Andreas Gruenbachera02d1242011-03-22 17:20:45 +01004415 if (dcbp_get_code(p) == RLE_VLI_Bits)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004416 return recv_bm_rle_bits(peer_device, p, c, len - sizeof(*p));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004417
4418 /* other variants had been implemented for evaluation,
4419 * but have been dropped as this one turned out to be "best"
4420 * during all our tests. */
4421
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004422 drbd_err(peer_device, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
4423 conn_request_state(peer_device->connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004424 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004425}
4426
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004427void INFO_bm_xfer_stats(struct drbd_device *device,
Philipp Reisnerb411b362009-09-25 16:07:19 -07004428 const char *direction, struct bm_xfer_ctx *c)
4429{
4430 /* what would it take to transfer it "plaintext" */
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +02004431 unsigned int header_size = drbd_header_size(first_peer_device(device)->connection);
Andreas Gruenbacher50d0b1a2011-03-30 11:53:51 +02004432 unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
4433 unsigned int plain =
4434 header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
4435 c->bm_words * sizeof(unsigned long);
4436 unsigned int total = c->bytes[0] + c->bytes[1];
4437 unsigned int r;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004438
4439 /* total can not be zero. but just in case: */
4440 if (total == 0)
4441 return;
4442
4443 /* don't report if not compressed */
4444 if (total >= plain)
4445 return;
4446
4447 /* total < plain. check for overflow, still */
4448 r = (total > UINT_MAX/1000) ? (total / (plain/1000))
4449 : (1000 * total / plain);
4450
4451 if (r > 1000)
4452 r = 1000;
4453
4454 r = 1000 - r;
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004455 drbd_info(device, "%s bitmap stats [Bytes(packets)]: plain %u(%u), RLE %u(%u), "
Philipp Reisnerb411b362009-09-25 16:07:19 -07004456 "total %u; compression: %u.%u%%\n",
4457 direction,
4458 c->bytes[1], c->packets[1],
4459 c->bytes[0], c->packets[0],
4460 total, r/10, r % 10);
4461}
4462
4463/* Since we are processing the bitfield from lower addresses to higher,
4464 it does not matter if the process it in 32 bit chunks or 64 bit
4465 chunks as long as it is little endian. (Understand it as byte stream,
4466 beginning with the lowest byte...) If we would use big endian
4467 we would need to process it from the highest address to the lowest,
4468 in order to be agnostic to the 32 vs 64 bits issue.
4469
4470 returns 0 on failure, 1 if we successfully received it. */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004471static int receive_bitmap(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004472{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004473 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004474 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004475 struct bm_xfer_ctx c;
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004476 int err;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004477
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004478 peer_device = conn_peer_device(connection, pi->vnr);
4479 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004480 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004481 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004482
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004483 drbd_bm_lock(device, "receive bitmap", BM_LOCKED_SET_ALLOWED);
Lars Ellenberg20ceb2b2011-01-21 10:56:44 +01004484 /* you are supposed to send additional out-of-sync information
4485 * if you actually set bits during this phase */
Philipp Reisnerb411b362009-09-25 16:07:19 -07004486
Philipp Reisnerb411b362009-09-25 16:07:19 -07004487 c = (struct bm_xfer_ctx) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004488 .bm_bits = drbd_bm_bits(device),
4489 .bm_words = drbd_bm_words(device),
Philipp Reisnerb411b362009-09-25 16:07:19 -07004490 };
4491
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004492 for(;;) {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004493 if (pi->cmd == P_BITMAP)
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004494 err = receive_bitmap_plain(peer_device, pi->size, pi->data, &c);
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004495 else if (pi->cmd == P_COMPRESSED_BITMAP) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07004496 /* MAYBE: sanity check that we speak proto >= 90,
4497 * and the feature is enabled! */
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004498 struct p_compressed_bm *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004499
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004500 if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(connection)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004501 drbd_err(device, "ReportCBitmap packet too large\n");
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004502 err = -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004503 goto out;
4504 }
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004505 if (pi->size <= sizeof(*p)) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004506 drbd_err(device, "ReportCBitmap packet too small (l:%u)\n", pi->size);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004507 err = -EIO;
Andreas Gruenbacher78fcbda2010-12-10 22:18:27 +01004508 goto out;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004509 }
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004510 err = drbd_recv_all(peer_device->connection, p, pi->size);
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004511 if (err)
4512 goto out;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004513 err = decode_bitmap_c(peer_device, p, &c, pi->size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004514 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004515 drbd_warn(device, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004516 err = -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004517 goto out;
4518 }
4519
Andreas Gruenbachere2857212011-03-25 00:57:38 +01004520 c.packets[pi->cmd == P_BITMAP]++;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004521 c.bytes[pi->cmd == P_BITMAP] += drbd_header_size(connection) + pi->size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004522
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004523 if (err <= 0) {
4524 if (err < 0)
4525 goto out;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004526 break;
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004527 }
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004528 err = drbd_recv_header(peer_device->connection, pi);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004529 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004530 goto out;
Andreas Gruenbacher2c464072010-12-11 21:53:12 +01004531 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07004532
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004533 INFO_bm_xfer_stats(device, "receive", &c);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004534
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004535 if (device->state.conn == C_WF_BITMAP_T) {
Andreas Gruenbacherde1f8e42010-12-10 21:04:00 +01004536 enum drbd_state_rv rv;
4537
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004538 err = drbd_send_bitmap(device);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004539 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004540 goto out;
4541 /* Omit CS_ORDERED with this state transition to avoid deadlocks. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004542 rv = _drbd_request_state(device, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02004543 D_ASSERT(device, rv == SS_SUCCESS);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004544 } else if (device->state.conn != C_WF_BITMAP_S) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07004545 /* admin may have requested C_DISCONNECTING,
4546 * other threads may have noticed network errors */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004547 drbd_info(device, "unexpected cstate (%s) in receive_bitmap\n",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004548 drbd_conn_str(device->state.conn));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004549 }
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004550 err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004551
Philipp Reisnerb411b362009-09-25 16:07:19 -07004552 out:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004553 drbd_bm_unlock(device);
4554 if (!err && device->state.conn == C_WF_BITMAP_S)
4555 drbd_start_resync(device, C_SYNC_SOURCE);
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004556 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004557}
4558
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004559static int receive_skip(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004560{
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004561 drbd_warn(connection, "skipping unknown optional packet type %d, l: %d!\n",
Andreas Gruenbachere2857212011-03-25 00:57:38 +01004562 pi->cmd, pi->size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004563
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004564 return ignore_remaining_packet(connection, pi);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004565}
4566
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004567static int receive_UnplugRemote(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004568{
Philipp Reisnerb411b362009-09-25 16:07:19 -07004569 /* Make sure we've acked all the TCP data associated
4570 * with the data requests being unplugged */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004571 drbd_tcp_quickack(connection->data.socket);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004572
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004573 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004574}
4575
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004576static int receive_out_of_sync(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisner73a01a12010-10-27 14:33:00 +02004577{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004578 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004579 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004580 struct p_block_desc *p = pi->data;
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004581
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004582 peer_device = conn_peer_device(connection, pi->vnr);
4583 if (!peer_device)
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004584 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02004585 device = peer_device->device;
Philipp Reisner73a01a12010-10-27 14:33:00 +02004586
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004587 switch (device->state.conn) {
Lars Ellenbergf735e3632010-12-17 21:06:18 +01004588 case C_WF_SYNC_UUID:
4589 case C_WF_BITMAP_T:
4590 case C_BEHIND:
4591 break;
4592 default:
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004593 drbd_err(device, "ASSERT FAILED cstate = %s, expected: WFSyncUUID|WFBitMapT|Behind\n",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004594 drbd_conn_str(device->state.conn));
Lars Ellenbergf735e3632010-12-17 21:06:18 +01004595 }
4596
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004597 drbd_set_out_of_sync(device, be64_to_cpu(p->sector), be32_to_cpu(p->blksize));
Philipp Reisner73a01a12010-10-27 14:33:00 +02004598
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004599 return 0;
Philipp Reisner73a01a12010-10-27 14:33:00 +02004600}
4601
Philipp Reisner02918be2010-08-20 14:35:10 +02004602struct data_cmd {
4603 int expect_payload;
4604 size_t pkt_size;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004605 int (*fn)(struct drbd_connection *, struct packet_info *);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004606};
4607
Philipp Reisner02918be2010-08-20 14:35:10 +02004608static struct data_cmd drbd_cmd_handler[] = {
4609 [P_DATA] = { 1, sizeof(struct p_data), receive_Data },
4610 [P_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply },
4611 [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } ,
4612 [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } ,
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004613 [P_BITMAP] = { 1, 0, receive_bitmap } ,
4614 [P_COMPRESSED_BITMAP] = { 1, 0, receive_bitmap } ,
4615 [P_UNPLUG_REMOTE] = { 0, 0, receive_UnplugRemote },
Philipp Reisner02918be2010-08-20 14:35:10 +02004616 [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
4617 [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004618 [P_SYNC_PARAM] = { 1, 0, receive_SyncParam },
4619 [P_SYNC_PARAM89] = { 1, 0, receive_SyncParam },
Philipp Reisner02918be2010-08-20 14:35:10 +02004620 [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol },
4621 [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids },
4622 [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes },
4623 [P_STATE] = { 0, sizeof(struct p_state), receive_state },
4624 [P_STATE_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_state },
4625 [P_SYNC_UUID] = { 0, sizeof(struct p_rs_uuid), receive_sync_uuid },
4626 [P_OV_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
4627 [P_OV_REPLY] = { 1, sizeof(struct p_block_req), receive_DataRequest },
4628 [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest },
4629 [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), receive_skip },
Philipp Reisner73a01a12010-10-27 14:33:00 +02004630 [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync },
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004631 [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state },
Philipp Reisner036b17e2011-05-16 17:38:11 +02004632 [P_PROTOCOL_UPDATE] = { 1, sizeof(struct p_protocol), receive_protocol },
Lars Ellenberga0fb3c42014-04-28 18:43:23 +02004633 [P_TRIM] = { 0, sizeof(struct p_trim), receive_Data },
Philipp Reisner02918be2010-08-20 14:35:10 +02004634};
4635
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004636static void drbdd(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004637{
Philipp Reisner77351055b2011-02-07 17:24:26 +01004638 struct packet_info pi;
Philipp Reisner02918be2010-08-20 14:35:10 +02004639 size_t shs; /* sub header size */
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004640 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004641
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004642 while (get_t_state(&connection->receiver) == RUNNING) {
Andreas Gruenbacherdeebe192011-03-25 00:01:04 +01004643 struct data_cmd *cmd;
4644
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004645 drbd_thread_current_set_cpu(&connection->receiver);
Lars Ellenberg944410e2014-05-06 15:02:05 +02004646 update_receiver_timing_details(connection, drbd_recv_header);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004647 if (drbd_recv_header(connection, &pi))
Philipp Reisner02918be2010-08-20 14:35:10 +02004648 goto err_out;
4649
Andreas Gruenbacherdeebe192011-03-25 00:01:04 +01004650 cmd = &drbd_cmd_handler[pi.cmd];
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004651 if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->fn)) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004652 drbd_err(connection, "Unexpected data packet %s (0x%04x)",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02004653 cmdname(pi.cmd), pi.cmd);
Philipp Reisner02918be2010-08-20 14:35:10 +02004654 goto err_out;
Lars Ellenberg0b33a912009-11-16 15:58:04 +01004655 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07004656
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004657 shs = cmd->pkt_size;
4658 if (pi.size > shs && !cmd->expect_payload) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004659 drbd_err(connection, "No payload expected %s l:%d\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02004660 cmdname(pi.cmd), pi.size);
Philipp Reisner02918be2010-08-20 14:35:10 +02004661 goto err_out;
4662 }
4663
Lars Ellenbergc13f7e12010-10-29 23:32:01 +02004664 if (shs) {
Lars Ellenberg944410e2014-05-06 15:02:05 +02004665 update_receiver_timing_details(connection, drbd_recv_all_warn);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004666 err = drbd_recv_all_warn(connection, pi.data, shs);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01004667 if (err)
Lars Ellenbergc13f7e12010-10-29 23:32:01 +02004668 goto err_out;
Andreas Gruenbachere2857212011-03-25 00:57:38 +01004669 pi.size -= shs;
Lars Ellenbergc13f7e12010-10-29 23:32:01 +02004670 }
4671
Lars Ellenberg944410e2014-05-06 15:02:05 +02004672 update_receiver_timing_details(connection, cmd->fn);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004673 err = cmd->fn(connection, &pi);
Andreas Gruenbacher4a76b162011-03-25 02:43:51 +01004674 if (err) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004675 drbd_err(connection, "error receiving %s, e: %d l: %d!\n",
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004676 cmdname(pi.cmd), err, pi.size);
Philipp Reisner02918be2010-08-20 14:35:10 +02004677 goto err_out;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004678 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07004679 }
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004680 return;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004681
Andreas Gruenbacher82bc0192011-03-17 12:10:19 +01004682 err_out:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004683 conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004684}
4685
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004686static void conn_disconnect(struct drbd_connection *connection)
Philipp Reisnerf70b35112010-06-24 14:34:40 +02004687{
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02004688 struct drbd_peer_device *peer_device;
Philipp Reisnerbbeb6412011-02-10 13:45:46 +01004689 enum drbd_conns oc;
Philipp Reisner376694a2011-11-07 10:54:28 +01004690 int vnr;
Philipp Reisnerf70b35112010-06-24 14:34:40 +02004691
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004692 if (connection->cstate == C_STANDALONE)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004693 return;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004694
Lars Ellenberg545752d2011-12-05 14:39:25 +01004695 /* We are about to start the cleanup after connection loss.
4696 * Make sure drbd_make_request knows about that.
4697 * Usually we should be in some network failure state already,
4698 * but just in case we are not, we fix it up here.
4699 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004700 conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
Lars Ellenberg545752d2011-12-05 14:39:25 +01004701
Philipp Reisner668700b2015-03-16 16:08:29 +01004702 /* ack_receiver does not clean up anything. it must not interfere, either */
Philipp Reisner1c03e522015-03-16 15:01:00 +01004703 drbd_thread_stop(&connection->ack_receiver);
Philipp Reisner668700b2015-03-16 16:08:29 +01004704 if (connection->ack_sender) {
4705 destroy_workqueue(connection->ack_sender);
4706 connection->ack_sender = NULL;
4707 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004708 drbd_free_sock(connection);
Philipp Reisner360cc742011-02-08 14:29:53 +01004709
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02004710 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02004711 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
4712 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004713 kref_get(&device->kref);
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02004714 rcu_read_unlock();
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004715 drbd_disconnected(peer_device);
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02004716 kref_put(&device->kref, drbd_destroy_device);
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02004717 rcu_read_lock();
4718 }
4719 rcu_read_unlock();
4720
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004721 if (!list_empty(&connection->current_epoch->list))
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004722 drbd_err(connection, "ASSERTION FAILED: connection->current_epoch->list not empty\n");
Philipp Reisner12038a32011-11-09 19:18:00 +01004723 /* ok, no more ee's on the fly, it is safe to reset the epoch_size */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004724 atomic_set(&connection->current_epoch->epoch_size, 0);
4725 connection->send.seen_any_write_yet = false;
Philipp Reisner12038a32011-11-09 19:18:00 +01004726
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004727 drbd_info(connection, "Connection closed\n");
Philipp Reisner360cc742011-02-08 14:29:53 +01004728
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004729 if (conn_highest_role(connection) == R_PRIMARY && conn_highest_pdsk(connection) >= D_UNKNOWN)
4730 conn_try_outdate_peer_async(connection);
Philipp Reisnercb703452011-03-24 11:03:07 +01004731
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004732 spin_lock_irq(&connection->resource->req_lock);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004733 oc = connection->cstate;
Philipp Reisnerbbeb6412011-02-10 13:45:46 +01004734 if (oc >= C_UNCONNECTED)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004735 _conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE);
Philipp Reisnerbbeb6412011-02-10 13:45:46 +01004736
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004737 spin_unlock_irq(&connection->resource->req_lock);
Philipp Reisner360cc742011-02-08 14:29:53 +01004738
Lars Ellenbergf3dfa402011-05-02 10:45:05 +02004739 if (oc == C_DISCONNECTING)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004740 conn_request_state(connection, NS(conn, C_STANDALONE), CS_VERBOSE | CS_HARD);
Philipp Reisner360cc742011-02-08 14:29:53 +01004741}
4742
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004743static int drbd_disconnected(struct drbd_peer_device *peer_device)
Philipp Reisner360cc742011-02-08 14:29:53 +01004744{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004745 struct drbd_device *device = peer_device->device;
Philipp Reisner360cc742011-02-08 14:29:53 +01004746 unsigned int i;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004747
Philipp Reisner85719572010-07-21 10:20:17 +02004748 /* wait for current activity to cease. */
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004749 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004750 _drbd_wait_ee_list_empty(device, &device->active_ee);
4751 _drbd_wait_ee_list_empty(device, &device->sync_ee);
4752 _drbd_wait_ee_list_empty(device, &device->read_ee);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02004753 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004754
4755 /* We do not have data structures that would allow us to
4756 * get the rs_pending_cnt down to 0 again.
4757 * * On C_SYNC_TARGET we do not have any data structures describing
4758 * the pending RSDataRequest's we have sent.
4759 * * On C_SYNC_SOURCE there is no data structure that tracks
4760 * the P_RS_DATA_REPLY blocks that we sent to the SyncTarget.
4761 * And no, it is not the sum of the reference counts in the
4762 * resync_LRU. The resync_LRU tracks the whole operation including
4763 * the disk-IO, while the rs_pending_cnt only tracks the blocks
4764 * on the fly. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004765 drbd_rs_cancel_all(device);
4766 device->rs_total = 0;
4767 device->rs_failed = 0;
4768 atomic_set(&device->rs_pending_cnt, 0);
4769 wake_up(&device->misc_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004770
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004771 del_timer_sync(&device->resync_timer);
4772 resync_timer_fn((unsigned long)device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004773
Philipp Reisnerb411b362009-09-25 16:07:19 -07004774 /* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
4775 * w_make_resync_request etc. which may still be on the worker queue
4776 * to be "canceled" */
Andreas Gruenbacherb5043c52011-07-28 15:56:02 +02004777 drbd_flush_workqueue(&peer_device->connection->sender_work);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004778
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004779 drbd_finish_peer_reqs(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004780
Philipp Reisnerd10b4ea2011-11-30 23:25:36 +01004781 /* This second workqueue flush is necessary, since drbd_finish_peer_reqs()
4782 might have issued a work again. The one before drbd_finish_peer_reqs() is
4783 necessary to reclain net_ee in drbd_finish_peer_reqs(). */
Andreas Gruenbacherb5043c52011-07-28 15:56:02 +02004784 drbd_flush_workqueue(&peer_device->connection->sender_work);
Philipp Reisnerd10b4ea2011-11-30 23:25:36 +01004785
Lars Ellenberg08332d72012-08-17 15:09:13 +02004786 /* need to do it again, drbd_finish_peer_reqs() may have populated it
4787 * again via drbd_try_clear_on_disk_bm(). */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004788 drbd_rs_cancel_all(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004789
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004790 kfree(device->p_uuid);
4791 device->p_uuid = NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004792
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004793 if (!drbd_suspended(device))
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02004794 tl_clear(peer_device->connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004795
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004796 drbd_md_sync(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004797
Lars Ellenberg20ceb2b2011-01-21 10:56:44 +01004798 /* serialize with bitmap writeout triggered by the state change,
4799 * if any. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004800 wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
Lars Ellenberg20ceb2b2011-01-21 10:56:44 +01004801
Philipp Reisnerb411b362009-09-25 16:07:19 -07004802 /* tcp_close and release of sendpage pages can be deferred. I don't
4803 * want to use SO_LINGER, because apparently it can be deferred for
4804 * more than 20 seconds (longest time I checked).
4805 *
4806 * Actually we don't care for exactly when the network stack does its
4807 * put_page(), but release our reference on these pages right here.
4808 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004809 i = drbd_free_peer_reqs(device, &device->net_ee);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004810 if (i)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004811 drbd_info(device, "net_ee not empty, killed %u entries\n", i);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004812 i = atomic_read(&device->pp_in_use_by_net);
Lars Ellenberg435f0742010-09-06 12:30:25 +02004813 if (i)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004814 drbd_info(device, "pp_in_use_by_net = %d, expected 0\n", i);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02004815 i = atomic_read(&device->pp_in_use);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004816 if (i)
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02004817 drbd_info(device, "pp_in_use = %d, expected 0\n", i);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004818
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02004819 D_ASSERT(device, list_empty(&device->read_ee));
4820 D_ASSERT(device, list_empty(&device->active_ee));
4821 D_ASSERT(device, list_empty(&device->sync_ee));
4822 D_ASSERT(device, list_empty(&device->done_ee));
Philipp Reisnerb411b362009-09-25 16:07:19 -07004823
Philipp Reisner360cc742011-02-08 14:29:53 +01004824 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004825}
4826
4827/*
4828 * We support PRO_VERSION_MIN to PRO_VERSION_MAX. The protocol version
4829 * we can agree on is stored in agreed_pro_version.
4830 *
4831 * feature flags and the reserved array should be enough room for future
4832 * enhancements of the handshake protocol, and possible plugins...
4833 *
4834 * for now, they are expected to be zero, but ignored.
4835 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004836static int drbd_send_features(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004837{
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004838 struct drbd_socket *sock;
4839 struct p_connection_features *p;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004840
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004841 sock = &connection->data;
4842 p = conn_prepare_command(connection, sock);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004843 if (!p)
Andreas Gruenbachere8d17b02011-03-16 00:54:19 +01004844 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004845 memset(p, 0, sizeof(*p));
4846 p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
4847 p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
Lars Ellenberg20c68fd2014-04-28 18:43:25 +02004848 p->feature_flags = cpu_to_be32(PRO_FEATURES);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004849 return conn_send_command(connection, sock, P_CONNECTION_FEATURES, sizeof(*p), NULL, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004850}
4851
4852/*
4853 * return values:
4854 * 1 yes, we have a valid connection
4855 * 0 oops, did not work out, please try again
4856 * -1 peer talks different language,
4857 * no point in trying again, please go standalone.
4858 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004859static int drbd_do_features(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004860{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004861 /* ASSERT current == connection->receiver ... */
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004862 struct p_connection_features *p;
4863 const int expect = sizeof(struct p_connection_features);
Philipp Reisner77351055b2011-02-07 17:24:26 +01004864 struct packet_info pi;
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01004865 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004866
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004867 err = drbd_send_features(connection);
Andreas Gruenbachere8d17b02011-03-16 00:54:19 +01004868 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004869 return 0;
4870
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004871 err = drbd_recv_header(connection, &pi);
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01004872 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004873 return 0;
4874
Andreas Gruenbacher60381782011-03-28 17:05:50 +02004875 if (pi.cmd != P_CONNECTION_FEATURES) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004876 drbd_err(connection, "expected ConnectionFeatures packet, received: %s (0x%04x)\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02004877 cmdname(pi.cmd), pi.cmd);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004878 return -1;
4879 }
4880
Philipp Reisner77351055b2011-02-07 17:24:26 +01004881 if (pi.size != expect) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004882 drbd_err(connection, "expected ConnectionFeatures length: %u, received: %u\n",
Philipp Reisner77351055b2011-02-07 17:24:26 +01004883 expect, pi.size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004884 return -1;
4885 }
4886
Andreas Gruenbachere6589832011-03-30 12:54:42 +02004887 p = pi.data;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004888 err = drbd_recv_all_warn(connection, p, expect);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01004889 if (err)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004890 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004891
Philipp Reisnerb411b362009-09-25 16:07:19 -07004892 p->protocol_min = be32_to_cpu(p->protocol_min);
4893 p->protocol_max = be32_to_cpu(p->protocol_max);
4894 if (p->protocol_max == 0)
4895 p->protocol_max = p->protocol_min;
4896
4897 if (PRO_VERSION_MAX < p->protocol_min ||
4898 PRO_VERSION_MIN > p->protocol_max)
4899 goto incompat;
4900
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004901 connection->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
Lars Ellenberg20c68fd2014-04-28 18:43:25 +02004902 connection->agreed_features = PRO_FEATURES & be32_to_cpu(p->feature_flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004903
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004904 drbd_info(connection, "Handshake successful: "
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004905 "Agreed network protocol version %d\n", connection->agreed_pro_version);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004906
Lars Ellenberg20c68fd2014-04-28 18:43:25 +02004907 drbd_info(connection, "Agreed to%ssupport TRIM on protocol level\n",
4908 connection->agreed_features & FF_TRIM ? " " : " not ");
4909
Philipp Reisnerb411b362009-09-25 16:07:19 -07004910 return 1;
4911
4912 incompat:
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004913 drbd_err(connection, "incompatible DRBD dialects: "
Philipp Reisnerb411b362009-09-25 16:07:19 -07004914 "I support %d-%d, peer supports %d-%d\n",
4915 PRO_VERSION_MIN, PRO_VERSION_MAX,
4916 p->protocol_min, p->protocol_max);
4917 return -1;
4918}
4919
4920#if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004921static int drbd_do_auth(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004922{
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004923 drbd_err(connection, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
4924 drbd_err(connection, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01004925 return -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004926}
4927#else
4928#define CHALLENGE_LEN 64
Johannes Thomab10d96c2010-01-07 16:02:50 +01004929
4930/* Return value:
4931 1 - auth succeeded,
4932 0 - failed, try again (network error),
4933 -1 - auth failed, don't try again.
4934*/
4935
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004936static int drbd_do_auth(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07004937{
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004938 struct drbd_socket *sock;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004939 char my_challenge[CHALLENGE_LEN]; /* 64 Bytes... */
Philipp Reisnerb411b362009-09-25 16:07:19 -07004940 char *response = NULL;
4941 char *right_response = NULL;
4942 char *peers_ch = NULL;
Philipp Reisner44ed1672011-04-19 17:10:19 +02004943 unsigned int key_len;
4944 char secret[SHARED_SECRET_MAX]; /* 64 byte */
Philipp Reisnerb411b362009-09-25 16:07:19 -07004945 unsigned int resp_size;
Herbert Xu9534d672016-01-24 21:19:21 +08004946 SHASH_DESC_ON_STACK(desc, connection->cram_hmac_tfm);
Philipp Reisner77351055b2011-02-07 17:24:26 +01004947 struct packet_info pi;
Philipp Reisner44ed1672011-04-19 17:10:19 +02004948 struct net_conf *nc;
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01004949 int err, rv;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004950
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004951 /* FIXME: Put the challenge/response into the preallocated socket buffer. */
4952
Philipp Reisner44ed1672011-04-19 17:10:19 +02004953 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004954 nc = rcu_dereference(connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +02004955 key_len = strlen(nc->shared_secret);
4956 memcpy(secret, nc->shared_secret, key_len);
4957 rcu_read_unlock();
4958
Herbert Xu9534d672016-01-24 21:19:21 +08004959 desc->tfm = connection->cram_hmac_tfm;
4960 desc->flags = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004961
Herbert Xu9534d672016-01-24 21:19:21 +08004962 rv = crypto_shash_setkey(connection->cram_hmac_tfm, (u8 *)secret, key_len);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004963 if (rv) {
Herbert Xu9534d672016-01-24 21:19:21 +08004964 drbd_err(connection, "crypto_shash_setkey() failed with %d\n", rv);
Johannes Thomab10d96c2010-01-07 16:02:50 +01004965 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004966 goto fail;
4967 }
4968
4969 get_random_bytes(my_challenge, CHALLENGE_LEN);
4970
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004971 sock = &connection->data;
4972 if (!conn_prepare_command(connection, sock)) {
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004973 rv = 0;
4974 goto fail;
4975 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004976 rv = !conn_send_command(connection, sock, P_AUTH_CHALLENGE, 0,
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02004977 my_challenge, CHALLENGE_LEN);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004978 if (!rv)
4979 goto fail;
4980
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02004981 err = drbd_recv_header(connection, &pi);
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01004982 if (err) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07004983 rv = 0;
4984 goto fail;
4985 }
4986
Philipp Reisner77351055b2011-02-07 17:24:26 +01004987 if (pi.cmd != P_AUTH_CHALLENGE) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004988 drbd_err(connection, "expected AuthChallenge packet, received: %s (0x%04x)\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02004989 cmdname(pi.cmd), pi.cmd);
Philipp Reisnerb411b362009-09-25 16:07:19 -07004990 rv = 0;
4991 goto fail;
4992 }
4993
Philipp Reisner77351055b2011-02-07 17:24:26 +01004994 if (pi.size > CHALLENGE_LEN * 2) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02004995 drbd_err(connection, "expected AuthChallenge payload too big.\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01004996 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07004997 goto fail;
4998 }
4999
Philipp Reisner67cca282014-04-28 18:43:30 +02005000 if (pi.size < CHALLENGE_LEN) {
5001 drbd_err(connection, "AuthChallenge payload too small.\n");
5002 rv = -1;
5003 goto fail;
5004 }
5005
Philipp Reisner77351055b2011-02-07 17:24:26 +01005006 peers_ch = kmalloc(pi.size, GFP_NOIO);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005007 if (peers_ch == NULL) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005008 drbd_err(connection, "kmalloc of peers_ch failed\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01005009 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005010 goto fail;
5011 }
5012
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005013 err = drbd_recv_all_warn(connection, peers_ch, pi.size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01005014 if (err) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07005015 rv = 0;
5016 goto fail;
5017 }
5018
Philipp Reisner67cca282014-04-28 18:43:30 +02005019 if (!memcmp(my_challenge, peers_ch, CHALLENGE_LEN)) {
5020 drbd_err(connection, "Peer presented the same challenge!\n");
5021 rv = -1;
5022 goto fail;
5023 }
5024
Herbert Xu9534d672016-01-24 21:19:21 +08005025 resp_size = crypto_shash_digestsize(connection->cram_hmac_tfm);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005026 response = kmalloc(resp_size, GFP_NOIO);
5027 if (response == NULL) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005028 drbd_err(connection, "kmalloc of response failed\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01005029 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005030 goto fail;
5031 }
5032
Herbert Xu9534d672016-01-24 21:19:21 +08005033 rv = crypto_shash_digest(desc, peers_ch, pi.size, response);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005034 if (rv) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005035 drbd_err(connection, "crypto_hash_digest() failed with %d\n", rv);
Johannes Thomab10d96c2010-01-07 16:02:50 +01005036 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005037 goto fail;
5038 }
5039
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005040 if (!conn_prepare_command(connection, sock)) {
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02005041 rv = 0;
5042 goto fail;
5043 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005044 rv = !conn_send_command(connection, sock, P_AUTH_RESPONSE, 0,
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02005045 response, resp_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005046 if (!rv)
5047 goto fail;
5048
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005049 err = drbd_recv_header(connection, &pi);
Andreas Gruenbacher69bc7bc2011-03-16 17:31:52 +01005050 if (err) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07005051 rv = 0;
5052 goto fail;
5053 }
5054
Philipp Reisner77351055b2011-02-07 17:24:26 +01005055 if (pi.cmd != P_AUTH_RESPONSE) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005056 drbd_err(connection, "expected AuthResponse packet, received: %s (0x%04x)\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02005057 cmdname(pi.cmd), pi.cmd);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005058 rv = 0;
5059 goto fail;
5060 }
5061
Philipp Reisner77351055b2011-02-07 17:24:26 +01005062 if (pi.size != resp_size) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005063 drbd_err(connection, "expected AuthResponse payload of wrong size\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005064 rv = 0;
5065 goto fail;
5066 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07005067
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005068 err = drbd_recv_all_warn(connection, response , resp_size);
Andreas Gruenbachera5c31902011-03-24 03:28:04 +01005069 if (err) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07005070 rv = 0;
5071 goto fail;
5072 }
5073
5074 right_response = kmalloc(resp_size, GFP_NOIO);
Julia Lawall2d1ee872009-12-27 22:27:11 +01005075 if (right_response == NULL) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005076 drbd_err(connection, "kmalloc of right_response failed\n");
Johannes Thomab10d96c2010-01-07 16:02:50 +01005077 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005078 goto fail;
5079 }
5080
Herbert Xu9534d672016-01-24 21:19:21 +08005081 rv = crypto_shash_digest(desc, my_challenge, CHALLENGE_LEN,
5082 right_response);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005083 if (rv) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005084 drbd_err(connection, "crypto_hash_digest() failed with %d\n", rv);
Johannes Thomab10d96c2010-01-07 16:02:50 +01005085 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005086 goto fail;
5087 }
5088
5089 rv = !memcmp(response, right_response, resp_size);
5090
5091 if (rv)
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005092 drbd_info(connection, "Peer authenticated using %d bytes HMAC\n",
Philipp Reisner44ed1672011-04-19 17:10:19 +02005093 resp_size);
Johannes Thomab10d96c2010-01-07 16:02:50 +01005094 else
5095 rv = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005096
5097 fail:
5098 kfree(peers_ch);
5099 kfree(response);
5100 kfree(right_response);
Herbert Xu9534d672016-01-24 21:19:21 +08005101 shash_desc_zero(desc);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005102
5103 return rv;
5104}
5105#endif
5106
Andreas Gruenbacher8fe60552011-07-22 11:04:36 +02005107int drbd_receiver(struct drbd_thread *thi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005108{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005109 struct drbd_connection *connection = thi->connection;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005110 int h;
5111
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005112 drbd_info(connection, "receiver (re)started\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005113
5114 do {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005115 h = conn_connect(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005116 if (h == 0) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005117 conn_disconnect(connection);
Philipp Reisner20ee6392011-01-18 15:28:59 +01005118 schedule_timeout_interruptible(HZ);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005119 }
5120 if (h == -1) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005121 drbd_warn(connection, "Discarding network configuration.\n");
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005122 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005123 }
5124 } while (h == 0);
5125
Philipp Reisner91fd4da2011-04-20 17:47:29 +02005126 if (h > 0)
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005127 drbdd(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005128
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005129 conn_disconnect(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005130
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005131 drbd_info(connection, "receiver terminated\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005132 return 0;
5133}
5134
5135/* ********* acknowledge sender ******** */
5136
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005137static int got_conn_RqSReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005138{
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005139 struct p_req_state_reply *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005140 int retcode = be32_to_cpu(p->retcode);
5141
5142 if (retcode >= SS_SUCCESS) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005143 set_bit(CONN_WD_ST_CHG_OKAY, &connection->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005144 } else {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005145 set_bit(CONN_WD_ST_CHG_FAIL, &connection->flags);
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005146 drbd_err(connection, "Requested state change failed by peer: %s (%d)\n",
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005147 drbd_set_st_err_str(retcode), retcode);
5148 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005149 wake_up(&connection->ping_wait);
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005150
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005151 return 0;
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005152}
5153
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005154static int got_RqSReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005155{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005156 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005157 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005158 struct p_req_state_reply *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005159 int retcode = be32_to_cpu(p->retcode);
5160
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005161 peer_device = conn_peer_device(connection, pi->vnr);
5162 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005163 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005164 device = peer_device->device;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005165
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005166 if (test_bit(CONN_WD_ST_CHG_REQ, &connection->flags)) {
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02005167 D_ASSERT(device, connection->agreed_pro_version < 100);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005168 return got_conn_RqSReply(connection, pi);
Philipp Reisner4d0fc3f2012-01-20 13:52:27 +01005169 }
5170
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005171 if (retcode >= SS_SUCCESS) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005172 set_bit(CL_ST_CHG_SUCCESS, &device->flags);
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005173 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005174 set_bit(CL_ST_CHG_FAIL, &device->flags);
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02005175 drbd_err(device, "Requested state change failed by peer: %s (%d)\n",
Philipp Reisnere4f78ed2011-03-16 11:27:48 +01005176 drbd_set_st_err_str(retcode), retcode);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005177 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005178 wake_up(&device->state_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005179
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005180 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005181}
5182
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005183static int got_Ping(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005184{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005185 return drbd_send_ping_ack(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005186
5187}
5188
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005189static int got_PingAck(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005190{
5191 /* restore idle timeout */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005192 connection->meta.socket->sk->sk_rcvtimeo = connection->net_conf->ping_int*HZ;
5193 if (!test_and_set_bit(GOT_PING_ACK, &connection->flags))
5194 wake_up(&connection->ping_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005195
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005196 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005197}
5198
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005199static int got_IsInSync(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005200{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005201 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005202 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005203 struct p_block_ack *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005204 sector_t sector = be64_to_cpu(p->sector);
5205 int blksize = be32_to_cpu(p->blksize);
5206
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005207 peer_device = conn_peer_device(connection, pi->vnr);
5208 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005209 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005210 device = peer_device->device;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005211
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005212 D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005213
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005214 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005215
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005216 if (get_ldev(device)) {
5217 drbd_rs_complete_io(device, sector);
5218 drbd_set_in_sync(device, sector, blksize);
Lars Ellenberg1d53f092010-09-05 01:13:24 +02005219 /* rs_same_csums is supposed to count in units of BM_BLOCK_SIZE */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005220 device->rs_same_csum += (blksize >> BM_BLOCK_SHIFT);
5221 put_ldev(device);
Lars Ellenberg1d53f092010-09-05 01:13:24 +02005222 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005223 dec_rs_pending(device);
5224 atomic_add(blksize >> 9, &device->rs_sect_in);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005225
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005226 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005227}
5228
Andreas Gruenbacherbc9c5c42011-01-21 18:00:55 +01005229static int
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005230validate_req_change_req_state(struct drbd_device *device, u64 id, sector_t sector,
Andreas Gruenbacherbc9c5c42011-01-21 18:00:55 +01005231 struct rb_root *root, const char *func,
5232 enum drbd_req_event what, bool missing_ok)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005233{
5234 struct drbd_request *req;
5235 struct bio_and_error m;
5236
Andreas Gruenbacher05008132011-07-07 14:19:42 +02005237 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005238 req = find_request(device, root, id, sector, missing_ok, func);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005239 if (unlikely(!req)) {
Andreas Gruenbacher05008132011-07-07 14:19:42 +02005240 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacher85997672011-04-04 13:09:15 +02005241 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005242 }
5243 __req_mod(req, what, &m);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02005244 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005245
5246 if (m.bio)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005247 complete_master_bio(device, &m);
Andreas Gruenbacher85997672011-04-04 13:09:15 +02005248 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005249}
5250
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005251static int got_BlockAck(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005252{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005253 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005254 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005255 struct p_block_ack *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005256 sector_t sector = be64_to_cpu(p->sector);
5257 int blksize = be32_to_cpu(p->blksize);
5258 enum drbd_req_event what;
5259
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005260 peer_device = conn_peer_device(connection, pi->vnr);
5261 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005262 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005263 device = peer_device->device;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005264
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005265 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005266
Andreas Gruenbacher579b57e2011-01-13 18:40:57 +01005267 if (p->block_id == ID_SYNCER) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005268 drbd_set_in_sync(device, sector, blksize);
5269 dec_rs_pending(device);
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005270 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005271 }
Andreas Gruenbachere05e1e52011-03-25 15:16:26 +01005272 switch (pi->cmd) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07005273 case P_RS_WRITE_ACK:
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01005274 what = WRITE_ACKED_BY_PEER_AND_SIS;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005275 break;
5276 case P_WRITE_ACK:
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01005277 what = WRITE_ACKED_BY_PEER;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005278 break;
5279 case P_RECV_ACK:
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01005280 what = RECV_ACKED_BY_PEER;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005281 break;
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02005282 case P_SUPERSEDED:
5283 what = CONFLICT_RESOLVED;
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01005284 break;
5285 case P_RETRY_WRITE:
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01005286 what = POSTPONE_WRITE;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005287 break;
5288 default:
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005289 BUG();
Philipp Reisnerb411b362009-09-25 16:07:19 -07005290 }
5291
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005292 return validate_req_change_req_state(device, p->block_id, sector,
5293 &device->write_requests, __func__,
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005294 what, false);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005295}
5296
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005297static int got_NegAck(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005298{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005299 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005300 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005301 struct p_block_ack *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005302 sector_t sector = be64_to_cpu(p->sector);
Philipp Reisner2deb8332011-01-17 18:39:18 +01005303 int size = be32_to_cpu(p->blksize);
Andreas Gruenbacher85997672011-04-04 13:09:15 +02005304 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005305
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005306 peer_device = conn_peer_device(connection, pi->vnr);
5307 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005308 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005309 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005310
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005311 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005312
Andreas Gruenbacher579b57e2011-01-13 18:40:57 +01005313 if (p->block_id == ID_SYNCER) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005314 dec_rs_pending(device);
5315 drbd_rs_failed_io(device, sector, size);
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005316 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005317 }
Philipp Reisner2deb8332011-01-17 18:39:18 +01005318
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005319 err = validate_req_change_req_state(device, p->block_id, sector,
5320 &device->write_requests, __func__,
Philipp Reisner303d1442011-04-13 16:24:47 -07005321 NEG_ACKED, true);
Andreas Gruenbacher85997672011-04-04 13:09:15 +02005322 if (err) {
Andreas Gruenbacherc3afd8f2011-01-20 22:25:40 +01005323 /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
5324 The master bio might already be completed, therefore the
5325 request is no longer in the collision hash. */
5326 /* In Protocol B we might already have got a P_RECV_ACK
5327 but then get a P_NEG_ACK afterwards. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005328 drbd_set_out_of_sync(device, sector, size);
Philipp Reisner2deb8332011-01-17 18:39:18 +01005329 }
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005330 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005331}
5332
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005333static int got_NegDReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005334{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005335 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005336 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005337 struct p_block_ack *p = pi->data;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005338 sector_t sector = be64_to_cpu(p->sector);
5339
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005340 peer_device = conn_peer_device(connection, pi->vnr);
5341 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005342 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005343 device = peer_device->device;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005344
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005345 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Andreas Gruenbacher7be8da02011-02-22 02:15:32 +01005346
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02005347 drbd_err(device, "Got NegDReply; Sector %llus, len %u.\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07005348 (unsigned long long)sector, be32_to_cpu(p->blksize));
5349
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005350 return validate_req_change_req_state(device, p->block_id, sector,
5351 &device->read_requests, __func__,
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005352 NEG_ACKED, false);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005353}
5354
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005355static int got_NegRSDReply(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005356{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005357 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005358 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005359 sector_t sector;
5360 int size;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005361 struct p_block_ack *p = pi->data;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005362
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005363 peer_device = conn_peer_device(connection, pi->vnr);
5364 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005365 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005366 device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005367
5368 sector = be64_to_cpu(p->sector);
5369 size = be32_to_cpu(p->blksize);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005370
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005371 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005372
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005373 dec_rs_pending(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005374
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005375 if (get_ldev_if_state(device, D_FAILED)) {
5376 drbd_rs_complete_io(device, sector);
Andreas Gruenbachere05e1e52011-03-25 15:16:26 +01005377 switch (pi->cmd) {
Philipp Reisnerd612d302010-12-27 10:53:28 +01005378 case P_NEG_RS_DREPLY:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005379 drbd_rs_failed_io(device, sector, size);
Philipp Reisnerd612d302010-12-27 10:53:28 +01005380 case P_RS_CANCEL:
5381 break;
5382 default:
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005383 BUG();
Philipp Reisnerd612d302010-12-27 10:53:28 +01005384 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005385 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005386 }
5387
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005388 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005389}
5390
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005391static int got_BarrierAck(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005392{
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005393 struct p_barrier_ack *p = pi->data;
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02005394 struct drbd_peer_device *peer_device;
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02005395 int vnr;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005396
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005397 tl_release(connection, p->barrier, be32_to_cpu(p->set_size));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005398
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02005399 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02005400 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
5401 struct drbd_device *device = peer_device->device;
5402
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005403 if (device->state.conn == C_AHEAD &&
5404 atomic_read(&device->ap_in_flight) == 0 &&
5405 !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &device->flags)) {
5406 device->start_resync_timer.expires = jiffies + HZ;
5407 add_timer(&device->start_resync_timer);
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02005408 }
Philipp Reisnerc4752ef2010-10-27 17:32:36 +02005409 }
Lars Ellenberg9ed57dc2012-03-26 20:55:17 +02005410 rcu_read_unlock();
Philipp Reisnerc4752ef2010-10-27 17:32:36 +02005411
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005412 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005413}
5414
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005415static int got_OVResult(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005416{
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005417 struct drbd_peer_device *peer_device;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005418 struct drbd_device *device;
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005419 struct p_block_ack *p = pi->data;
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02005420 struct drbd_device_work *dw;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005421 sector_t sector;
5422 int size;
5423
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005424 peer_device = conn_peer_device(connection, pi->vnr);
5425 if (!peer_device)
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005426 return -EIO;
Andreas Gruenbacher9f4fe9a2011-08-09 03:54:55 +02005427 device = peer_device->device;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005428
Philipp Reisnerb411b362009-09-25 16:07:19 -07005429 sector = be64_to_cpu(p->sector);
5430 size = be32_to_cpu(p->blksize);
5431
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02005432 update_peer_seq(peer_device, be32_to_cpu(p->seq_num));
Philipp Reisnerb411b362009-09-25 16:07:19 -07005433
5434 if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005435 drbd_ov_out_of_sync_found(device, sector, size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005436 else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005437 ov_out_of_sync_print(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005438
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005439 if (!get_ldev(device))
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005440 return 0;
Lars Ellenberg1d53f092010-09-05 01:13:24 +02005441
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005442 drbd_rs_complete_io(device, sector);
5443 dec_rs_pending(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005444
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005445 --device->ov_left;
Lars Ellenbergea5442a2010-11-05 09:48:01 +01005446
5447 /* let's advance progress step marks only for every other megabyte */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005448 if ((device->ov_left & 0x200) == 0x200)
5449 drbd_advance_rs_marks(device, device->ov_left);
Lars Ellenbergea5442a2010-11-05 09:48:01 +01005450
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005451 if (device->ov_left == 0) {
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02005452 dw = kmalloc(sizeof(*dw), GFP_NOIO);
5453 if (dw) {
5454 dw->w.cb = w_ov_finished;
5455 dw->device = device;
5456 drbd_queue_work(&peer_device->connection->sender_work, &dw->w);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005457 } else {
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02005458 drbd_err(device, "kmalloc(dw) failed.");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005459 ov_out_of_sync_print(device);
5460 drbd_resync_finished(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005461 }
5462 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02005463 put_ldev(device);
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005464 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005465}
5466
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005467static int got_skip(struct drbd_connection *connection, struct packet_info *pi)
Philipp Reisner0ced55a2010-04-30 15:26:20 +02005468{
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005469 return 0;
Philipp Reisner0ced55a2010-04-30 15:26:20 +02005470}
5471
Philipp Reisner668700b2015-03-16 16:08:29 +01005472struct meta_sock_cmd {
Philipp Reisnerb411b362009-09-25 16:07:19 -07005473 size_t pkt_size;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005474 int (*fn)(struct drbd_connection *connection, struct packet_info *);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005475};
5476
Philipp Reisner668700b2015-03-16 16:08:29 +01005477static void set_rcvtimeo(struct drbd_connection *connection, bool ping_timeout)
5478{
5479 long t;
5480 struct net_conf *nc;
5481
5482 rcu_read_lock();
5483 nc = rcu_dereference(connection->net_conf);
5484 t = ping_timeout ? nc->ping_timeo : nc->ping_int;
5485 rcu_read_unlock();
5486
5487 t *= HZ;
5488 if (ping_timeout)
5489 t /= 10;
5490
5491 connection->meta.socket->sk->sk_rcvtimeo = t;
5492}
5493
5494static void set_ping_timeout(struct drbd_connection *connection)
5495{
5496 set_rcvtimeo(connection, 1);
5497}
5498
5499static void set_idle_timeout(struct drbd_connection *connection)
5500{
5501 set_rcvtimeo(connection, 0);
5502}
5503
5504static struct meta_sock_cmd ack_receiver_tbl[] = {
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005505 [P_PING] = { 0, got_Ping },
5506 [P_PING_ACK] = { 0, got_PingAck },
Philipp Reisnerb411b362009-09-25 16:07:19 -07005507 [P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck },
5508 [P_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck },
5509 [P_RS_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck },
Lars Ellenbergd4dabbe2012-08-01 12:33:51 +02005510 [P_SUPERSEDED] = { sizeof(struct p_block_ack), got_BlockAck },
Philipp Reisnerb411b362009-09-25 16:07:19 -07005511 [P_NEG_ACK] = { sizeof(struct p_block_ack), got_NegAck },
5512 [P_NEG_DREPLY] = { sizeof(struct p_block_ack), got_NegDReply },
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005513 [P_NEG_RS_DREPLY] = { sizeof(struct p_block_ack), got_NegRSDReply },
Philipp Reisnerb411b362009-09-25 16:07:19 -07005514 [P_OV_RESULT] = { sizeof(struct p_block_ack), got_OVResult },
5515 [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck },
5516 [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply },
5517 [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync },
Philipp Reisner02918be2010-08-20 14:35:10 +02005518 [P_DELAY_PROBE] = { sizeof(struct p_delay_probe93), got_skip },
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005519 [P_RS_CANCEL] = { sizeof(struct p_block_ack), got_NegRSDReply },
5520 [P_CONN_ST_CHG_REPLY]={ sizeof(struct p_req_state_reply), got_conn_RqSReply },
5521 [P_RETRY_WRITE] = { sizeof(struct p_block_ack), got_BlockAck },
Andreas Gruenbacher7201b972011-03-14 18:23:00 +01005522};
Philipp Reisnerb411b362009-09-25 16:07:19 -07005523
Philipp Reisner1c03e522015-03-16 15:01:00 +01005524int drbd_ack_receiver(struct drbd_thread *thi)
Philipp Reisnerb411b362009-09-25 16:07:19 -07005525{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005526 struct drbd_connection *connection = thi->connection;
Philipp Reisner668700b2015-03-16 16:08:29 +01005527 struct meta_sock_cmd *cmd = NULL;
Philipp Reisner77351055b2011-02-07 17:24:26 +01005528 struct packet_info pi;
Philipp Reisner668700b2015-03-16 16:08:29 +01005529 unsigned long pre_recv_jif;
Philipp Reisner257d0af2011-01-26 12:15:29 +01005530 int rv;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005531 void *buf = connection->meta.rbuf;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005532 int received = 0;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005533 unsigned int header_size = drbd_header_size(connection);
Andreas Gruenbacher52b061a2011-03-30 11:38:49 +02005534 int expect = header_size;
Philipp Reisner44ed1672011-04-19 17:10:19 +02005535 bool ping_timeout_active = false;
Philipp Reisner3990e042013-03-27 14:08:48 +01005536 struct sched_param param = { .sched_priority = 2 };
Philipp Reisnerb411b362009-09-25 16:07:19 -07005537
Philipp Reisner3990e042013-03-27 14:08:48 +01005538 rv = sched_setscheduler(current, SCHED_RR, &param);
5539 if (rv < 0)
Philipp Reisner668700b2015-03-16 16:08:29 +01005540 drbd_err(connection, "drbd_ack_receiver: ERROR set priority, ret=%d\n", rv);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005541
Andreas Gruenbachere77a0a52011-01-25 15:43:39 +01005542 while (get_t_state(thi) == RUNNING) {
Philipp Reisner80822282011-02-08 12:46:30 +01005543 drbd_thread_current_set_cpu(thi);
Philipp Reisner44ed1672011-04-19 17:10:19 +02005544
Philipp Reisner668700b2015-03-16 16:08:29 +01005545 conn_reclaim_net_peer_reqs(connection);
Philipp Reisner44ed1672011-04-19 17:10:19 +02005546
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005547 if (test_and_clear_bit(SEND_PING, &connection->flags)) {
5548 if (drbd_send_ping(connection)) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005549 drbd_err(connection, "drbd_send_ping has failed\n");
Andreas Gruenbacher841ce242010-12-15 19:31:20 +01005550 goto reconnect;
5551 }
Philipp Reisner668700b2015-03-16 16:08:29 +01005552 set_ping_timeout(connection);
Philipp Reisner44ed1672011-04-19 17:10:19 +02005553 ping_timeout_active = true;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005554 }
5555
Philipp Reisner668700b2015-03-16 16:08:29 +01005556 pre_recv_jif = jiffies;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005557 rv = drbd_recv_short(connection->meta.socket, buf, expect-received, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005558
5559 /* Note:
5560 * -EINTR (on meta) we got a signal
5561 * -EAGAIN (on meta) rcvtimeo expired
5562 * -ECONNRESET other side closed the connection
5563 * -ERESTARTSYS (on data) we got a signal
5564 * rv < 0 other than above: unexpected error!
5565 * rv == expected: full header or command
5566 * rv < expected: "woken" by signal during receive
5567 * rv == 0 : "connection shut down by peer"
5568 */
5569 if (likely(rv > 0)) {
5570 received += rv;
5571 buf += rv;
5572 } else if (rv == 0) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005573 if (test_bit(DISCONNECT_SENT, &connection->flags)) {
Philipp Reisnerb66623e2012-08-08 21:19:09 +02005574 long t;
5575 rcu_read_lock();
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005576 t = rcu_dereference(connection->net_conf)->ping_timeo * HZ/10;
Philipp Reisnerb66623e2012-08-08 21:19:09 +02005577 rcu_read_unlock();
5578
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005579 t = wait_event_timeout(connection->ping_wait,
5580 connection->cstate < C_WF_REPORT_PARAMS,
Philipp Reisnerb66623e2012-08-08 21:19:09 +02005581 t);
Philipp Reisner599377a2012-08-17 14:50:22 +02005582 if (t)
5583 break;
5584 }
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005585 drbd_err(connection, "meta connection shut down by peer.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005586 goto reconnect;
5587 } else if (rv == -EAGAIN) {
Lars Ellenbergcb6518c2011-06-20 14:44:45 +02005588 /* If the data socket received something meanwhile,
5589 * that is good enough: peer is still alive. */
Philipp Reisner668700b2015-03-16 16:08:29 +01005590 if (time_after(connection->last_received, pre_recv_jif))
Lars Ellenbergcb6518c2011-06-20 14:44:45 +02005591 continue;
Lars Ellenbergf36af182011-03-09 22:44:55 +01005592 if (ping_timeout_active) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005593 drbd_err(connection, "PingAck did not arrive in time.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005594 goto reconnect;
5595 }
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005596 set_bit(SEND_PING, &connection->flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005597 continue;
5598 } else if (rv == -EINTR) {
Philipp Reisner668700b2015-03-16 16:08:29 +01005599 /* maybe drbd_thread_stop(): the while condition will notice.
5600 * maybe woken for send_ping: we'll send a ping above,
5601 * and change the rcvtimeo */
5602 flush_signals(current);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005603 continue;
5604 } else {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005605 drbd_err(connection, "sock_recvmsg returned %d\n", rv);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005606 goto reconnect;
5607 }
5608
5609 if (received == expect && cmd == NULL) {
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005610 if (decode_header(connection, connection->meta.rbuf, &pi))
Philipp Reisnerb411b362009-09-25 16:07:19 -07005611 goto reconnect;
Philipp Reisner668700b2015-03-16 16:08:29 +01005612 cmd = &ack_receiver_tbl[pi.cmd];
5613 if (pi.cmd >= ARRAY_SIZE(ack_receiver_tbl) || !cmd->fn) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005614 drbd_err(connection, "Unexpected meta packet %s (0x%04x)\n",
Andreas Gruenbacher2fcb8f32011-07-03 11:41:08 +02005615 cmdname(pi.cmd), pi.cmd);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005616 goto disconnect;
5617 }
Andreas Gruenbachere6589832011-03-30 12:54:42 +02005618 expect = header_size + cmd->pkt_size;
Andreas Gruenbacher52b061a2011-03-30 11:38:49 +02005619 if (pi.size != expect - header_size) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005620 drbd_err(connection, "Wrong packet size on meta (c: %d, l: %d)\n",
Philipp Reisner77351055b2011-02-07 17:24:26 +01005621 pi.cmd, pi.size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005622 goto reconnect;
Philipp Reisner257d0af2011-01-26 12:15:29 +01005623 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07005624 }
5625 if (received == expect) {
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005626 bool err;
Philipp Reisnera4fbda82011-03-16 11:13:17 +01005627
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005628 err = cmd->fn(connection, &pi);
Andreas Gruenbacher2735a592011-04-04 15:30:24 +02005629 if (err) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02005630 drbd_err(connection, "%pf failed\n", cmd->fn);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005631 goto reconnect;
Andreas Gruenbacher1952e912011-03-25 15:37:43 +01005632 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07005633
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005634 connection->last_received = jiffies;
Lars Ellenbergf36af182011-03-09 22:44:55 +01005635
Philipp Reisner668700b2015-03-16 16:08:29 +01005636 if (cmd == &ack_receiver_tbl[P_PING_ACK]) {
5637 set_idle_timeout(connection);
Philipp Reisner44ed1672011-04-19 17:10:19 +02005638 ping_timeout_active = false;
5639 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07005640
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005641 buf = connection->meta.rbuf;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005642 received = 0;
Andreas Gruenbacher52b061a2011-03-30 11:38:49 +02005643 expect = header_size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07005644 cmd = NULL;
5645 }
5646 }
5647
5648 if (0) {
5649reconnect:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005650 conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
5651 conn_md_sync(connection);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005652 }
5653 if (0) {
5654disconnect:
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02005655 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -07005656 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07005657
Philipp Reisner668700b2015-03-16 16:08:29 +01005658 drbd_info(connection, "ack_receiver terminated\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07005659
5660 return 0;
5661}
Philipp Reisner668700b2015-03-16 16:08:29 +01005662
5663void drbd_send_acks_wf(struct work_struct *ws)
5664{
5665 struct drbd_peer_device *peer_device =
5666 container_of(ws, struct drbd_peer_device, send_acks_work);
5667 struct drbd_connection *connection = peer_device->connection;
5668 struct drbd_device *device = peer_device->device;
5669 struct net_conf *nc;
5670 int tcp_cork, err;
5671
5672 rcu_read_lock();
5673 nc = rcu_dereference(connection->net_conf);
5674 tcp_cork = nc->tcp_cork;
5675 rcu_read_unlock();
5676
5677 if (tcp_cork)
5678 drbd_tcp_cork(connection->meta.socket);
5679
5680 err = drbd_finish_peer_reqs(device);
5681 kref_put(&device->kref, drbd_destroy_device);
5682 /* get is in drbd_endio_write_sec_final(). That is necessary to keep the
5683 struct work_struct send_acks_work alive, which is in the peer_device object */
5684
5685 if (err) {
5686 conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
5687 return;
5688 }
5689
5690 if (tcp_cork)
5691 drbd_tcp_uncork(connection->meta.socket);
5692
5693 return;
5694}