blob: eff716c27b1fdf53caa7440ac5bad755c271ad43 [file] [log] [blame]
Philipp Reisnerb411b362009-09-25 16:07:19 -07001/*
2 drbd_worker.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
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +020024*/
Philipp Reisnerb411b362009-09-25 16:07:19 -070025
Philipp Reisnerb411b362009-09-25 16:07:19 -070026#include <linux/module.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070027#include <linux/drbd.h>
28#include <linux/sched.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070029#include <linux/wait.h>
30#include <linux/mm.h>
31#include <linux/memcontrol.h>
32#include <linux/mm_inline.h>
33#include <linux/slab.h>
34#include <linux/random.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070035#include <linux/string.h>
36#include <linux/scatterlist.h>
37
38#include "drbd_int.h"
Andreas Gruenbachera3603a62011-05-30 11:47:37 +020039#include "drbd_protocol.h"
Philipp Reisnerb411b362009-09-25 16:07:19 -070040#include "drbd_req.h"
Philipp Reisnerb411b362009-09-25 16:07:19 -070041
Andreas Gruenbacherd448a2e2011-08-25 16:59:58 +020042static int make_ov_request(struct drbd_device *, int);
43static int make_resync_request(struct drbd_device *, int);
Philipp Reisnerb411b362009-09-25 16:07:19 -070044
Andreas Gruenbacherc5a91612011-01-25 17:33:38 +010045/* endio handlers:
Andreas Gruenbachered15b792014-09-11 14:29:06 +020046 * drbd_md_endio (defined here)
Andreas Gruenbacherfcefa622011-02-17 16:46:59 +010047 * drbd_request_endio (defined here)
48 * drbd_peer_request_endio (defined here)
Andreas Gruenbachered15b792014-09-11 14:29:06 +020049 * drbd_bm_endio (defined in drbd_bitmap.c)
Andreas Gruenbacherc5a91612011-01-25 17:33:38 +010050 *
Philipp Reisnerb411b362009-09-25 16:07:19 -070051 * For all these callbacks, note the following:
52 * The callbacks will be called in irq context by the IDE drivers,
53 * and in Softirqs/Tasklets/BH context by the SCSI drivers.
54 * Try to get the locking right :)
55 *
56 */
57
Philipp Reisnerb411b362009-09-25 16:07:19 -070058/* used for synchronous meta data and bitmap IO
59 * submitted by drbd_md_sync_page_io()
60 */
Christoph Hellwig4246a0b2015-07-20 15:29:37 +020061void drbd_md_endio(struct bio *bio)
Philipp Reisnerb411b362009-09-25 16:07:19 -070062{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020063 struct drbd_device *device;
Philipp Reisnerb411b362009-09-25 16:07:19 -070064
Lars Ellenberge37d2432014-04-01 23:53:30 +020065 device = bio->bi_private;
Christoph Hellwig4246a0b2015-07-20 15:29:37 +020066 device->md_io.error = bio->bi_error;
Philipp Reisnerb411b362009-09-25 16:07:19 -070067
Philipp Reisner0cfac5d2011-11-10 12:12:52 +010068 /* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
69 * to timeout on the lower level device, and eventually detach from it.
70 * If this io completion runs after that timeout expired, this
71 * drbd_md_put_buffer() may allow us to finally try and re-attach.
72 * During normal operation, this only puts that extra reference
73 * down to 1 again.
74 * Make sure we first drop the reference, and only then signal
75 * completion, or we may (in drbd_al_read_log()) cycle so fast into the
76 * next drbd_md_sync_page_io(), that we trigger the
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020077 * ASSERT(atomic_read(&device->md_io_in_use) == 1) there.
Philipp Reisner0cfac5d2011-11-10 12:12:52 +010078 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020079 drbd_md_put_buffer(device);
Lars Ellenberge37d2432014-04-01 23:53:30 +020080 device->md_io.done = 1;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020081 wake_up(&device->misc_wait);
Philipp Reisnercdfda632011-07-05 15:38:59 +020082 bio_put(bio);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020083 if (device->ldev) /* special case: drbd_md_read() during drbd_adm_attach() */
84 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -070085}
86
87/* reads on behalf of the partner,
88 * "submitted" by the receiver
89 */
Rashika Kheriaa186e472013-12-19 15:06:10 +053090static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -070091{
92 unsigned long flags = 0;
Andreas Gruenbacher67801392011-09-13 10:39:41 +020093 struct drbd_peer_device *peer_device = peer_req->peer_device;
94 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -070095
Andreas Gruenbacher05008132011-07-07 14:19:42 +020096 spin_lock_irqsave(&device->resource->req_lock, flags);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020097 device->read_cnt += peer_req->i.size >> 9;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +020098 list_del(&peer_req->w.list);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +020099 if (list_empty(&device->read_ee))
100 wake_up(&device->ee_wait);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100101 if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200102 __drbd_chk_io_error(device, DRBD_READ_ERROR);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200103 spin_unlock_irqrestore(&device->resource->req_lock, flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700104
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200105 drbd_queue_work(&peer_device->connection->sender_work, &peer_req->w);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200106 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700107}
108
109/* writes on behalf of the partner, or resync writes,
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200110 * "submitted" by the receiver, final stage. */
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200111void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700112{
113 unsigned long flags = 0;
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200114 struct drbd_peer_device *peer_device = peer_req->peer_device;
115 struct drbd_device *device = peer_device->device;
Philipp Reisner668700b2015-03-16 16:08:29 +0100116 struct drbd_connection *connection = peer_device->connection;
Lars Ellenberg181286a2011-03-31 15:18:56 +0200117 struct drbd_interval i;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700118 int do_wake;
Andreas Gruenbacher579b57e2011-01-13 18:40:57 +0100119 u64 block_id;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700120 int do_al_complete_io;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700121
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100122 /* after we moved peer_req to done_ee,
Philipp Reisnerb411b362009-09-25 16:07:19 -0700123 * we may no longer access it,
124 * it may be freed/reused already!
125 * (as soon as we release the req_lock) */
Lars Ellenberg181286a2011-03-31 15:18:56 +0200126 i = peer_req->i;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100127 do_al_complete_io = peer_req->flags & EE_CALL_AL_COMPLETE_IO;
128 block_id = peer_req->block_id;
Lars Ellenberg21ae5d72014-05-05 23:42:24 +0200129 peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700130
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200131 spin_lock_irqsave(&device->resource->req_lock, flags);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200132 device->writ_cnt += peer_req->i.size >> 9;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200133 list_move_tail(&peer_req->w.list, &device->done_ee);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700134
Andreas Gruenbacherbb3bfe92011-01-21 15:59:23 +0100135 /*
Andreas Gruenbacher5e472262011-01-27 14:42:51 +0100136 * Do not remove from the write_requests tree here: we did not send the
Andreas Gruenbacherbb3bfe92011-01-21 15:59:23 +0100137 * Ack yet and did not wake possibly waiting conflicting requests.
138 * Removed from the tree from "drbd_process_done_ee" within the
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200139 * appropriate dw.cb (e_end_block/e_end_resync_block) or from
Andreas Gruenbacherbb3bfe92011-01-21 15:59:23 +0100140 * _drbd_clear_done_ee.
141 */
Philipp Reisnerb411b362009-09-25 16:07:19 -0700142
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200143 do_wake = list_empty(block_id == ID_SYNCER ? &device->sync_ee : &device->active_ee);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700144
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200145 /* FIXME do we want to detach for failed REQ_DISCARD?
146 * ((peer_req->flags & (EE_WAS_ERROR|EE_IS_TRIM)) == EE_WAS_ERROR) */
147 if (peer_req->flags & EE_WAS_ERROR)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200148 __drbd_chk_io_error(device, DRBD_WRITE_ERROR);
Philipp Reisner668700b2015-03-16 16:08:29 +0100149
150 if (connection->cstate >= C_WF_REPORT_PARAMS) {
151 kref_get(&device->kref); /* put is in drbd_send_acks_wf() */
152 if (!queue_work(connection->ack_sender, &peer_device->send_acks_work))
153 kref_put(&device->kref, drbd_destroy_device);
154 }
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200155 spin_unlock_irqrestore(&device->resource->req_lock, flags);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700156
Andreas Gruenbacher579b57e2011-01-13 18:40:57 +0100157 if (block_id == ID_SYNCER)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200158 drbd_rs_complete_io(device, i.sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700159
160 if (do_wake)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200161 wake_up(&device->ee_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700162
163 if (do_al_complete_io)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200164 drbd_al_complete_io(device, &i);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700165
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200166 put_ldev(device);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200167}
Philipp Reisnerb411b362009-09-25 16:07:19 -0700168
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200169/* writes on behalf of the partner, or resync writes,
170 * "submitted" by the receiver.
171 */
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200172void drbd_peer_request_endio(struct bio *bio)
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200173{
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100174 struct drbd_peer_request *peer_req = bio->bi_private;
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200175 struct drbd_device *device = peer_req->peer_device->device;
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200176 int is_write = bio_data_dir(bio) == WRITE;
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200177 int is_discard = !!(bio->bi_rw & REQ_DISCARD);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200178
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200179 if (bio->bi_error && __ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200180 drbd_warn(device, "%s: error=%d s=%llus\n",
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200181 is_write ? (is_discard ? "discard" : "write")
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200182 : "read", bio->bi_error,
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100183 (unsigned long long)peer_req->i.sector);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200184
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200185 if (bio->bi_error)
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100186 set_bit(__EE_WAS_ERROR, &peer_req->flags);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200187
188 bio_put(bio); /* no need for the bio anymore */
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100189 if (atomic_dec_and_test(&peer_req->pending_bios)) {
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200190 if (is_write)
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100191 drbd_endio_write_sec_final(peer_req);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200192 else
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100193 drbd_endio_read_sec_final(peer_req);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200194 }
Philipp Reisnerb411b362009-09-25 16:07:19 -0700195}
196
Lars Ellenberg142207f2015-02-19 13:48:59 +0100197void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
198{
199 panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n",
200 device->minor, device->resource->name, device->vnr);
201}
202
Philipp Reisnerb411b362009-09-25 16:07:19 -0700203/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
204 */
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200205void drbd_request_endio(struct bio *bio)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700206{
Lars Ellenberga1154132010-11-13 20:42:29 +0100207 unsigned long flags;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700208 struct drbd_request *req = bio->bi_private;
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200209 struct drbd_device *device = req->device;
Lars Ellenberga1154132010-11-13 20:42:29 +0100210 struct bio_and_error m;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700211 enum drbd_req_event what;
Philipp Reisner1b6dd252012-09-04 15:16:20 +0200212
213 /* If this request was aborted locally before,
214 * but now was completed "successfully",
215 * chances are that this caused arbitrary data corruption.
216 *
217 * "aborting" requests, or force-detaching the disk, is intended for
218 * completely blocked/hung local backing devices which do no longer
219 * complete requests at all, not even do error completions. In this
220 * situation, usually a hard-reset and failover is the only way out.
221 *
222 * By "aborting", basically faking a local error-completion,
223 * we allow for a more graceful swichover by cleanly migrating services.
224 * Still the affected node has to be rebooted "soon".
225 *
226 * By completing these requests, we allow the upper layers to re-use
227 * the associated data pages.
228 *
229 * If later the local backing device "recovers", and now DMAs some data
230 * from disk into the original request pages, in the best case it will
231 * just put random data into unused pages; but typically it will corrupt
232 * meanwhile completely unrelated data, causing all sorts of damage.
233 *
234 * Which means delayed successful completion,
235 * especially for READ requests,
236 * is a reason to panic().
237 *
238 * We assume that a delayed *error* completion is OK,
239 * though we still will complain noisily about it.
240 */
241 if (unlikely(req->rq_state & RQ_LOCAL_ABORTED)) {
242 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200243 drbd_emerg(device, "delayed completion of aborted local request; disk-timeout may be too aggressive\n");
Philipp Reisner1b6dd252012-09-04 15:16:20 +0200244
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200245 if (!bio->bi_error)
Lars Ellenberg142207f2015-02-19 13:48:59 +0100246 drbd_panic_after_delayed_completion_of_aborted_request(device);
Philipp Reisner1b6dd252012-09-04 15:16:20 +0200247 }
248
Philipp Reisnerb411b362009-09-25 16:07:19 -0700249 /* to avoid recursion in __req_mod */
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200250 if (unlikely(bio->bi_error)) {
Lars Ellenberg2f632ae2014-04-28 18:43:24 +0200251 if (bio->bi_rw & REQ_DISCARD)
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200252 what = (bio->bi_error == -EOPNOTSUPP)
Lars Ellenberg2f632ae2014-04-28 18:43:24 +0200253 ? DISCARD_COMPLETED_NOTSUPP
254 : DISCARD_COMPLETED_WITH_ERROR;
255 else
256 what = (bio_data_dir(bio) == WRITE)
Andreas Gruenbacher8554df12011-01-25 15:37:43 +0100257 ? WRITE_COMPLETED_WITH_ERROR
Lars Ellenberg5c3c7e62010-04-10 02:10:09 +0200258 : (bio_rw(bio) == READ)
Andreas Gruenbacher8554df12011-01-25 15:37:43 +0100259 ? READ_COMPLETED_WITH_ERROR
260 : READ_AHEAD_COMPLETED_WITH_ERROR;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700261 } else
Andreas Gruenbacher8554df12011-01-25 15:37:43 +0100262 what = COMPLETED_OK;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700263
264 bio_put(req->private_bio);
Christoph Hellwig4246a0b2015-07-20 15:29:37 +0200265 req->private_bio = ERR_PTR(bio->bi_error);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700266
Lars Ellenberga1154132010-11-13 20:42:29 +0100267 /* not req_mod(), we need irqsave here! */
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200268 spin_lock_irqsave(&device->resource->req_lock, flags);
Lars Ellenberga1154132010-11-13 20:42:29 +0100269 __req_mod(req, what, &m);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200270 spin_unlock_irqrestore(&device->resource->req_lock, flags);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200271 put_ldev(device);
Lars Ellenberga1154132010-11-13 20:42:29 +0100272
273 if (m.bio)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200274 complete_master_bio(device, &m);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700275}
276
Andreas Gruenbacher79a3c8d2011-08-09 02:49:01 +0200277void drbd_csum_ee(struct crypto_hash *tfm, struct drbd_peer_request *peer_req, void *digest)
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200278{
279 struct hash_desc desc;
280 struct scatterlist sg;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100281 struct page *page = peer_req->pages;
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200282 struct page *tmp;
283 unsigned len;
284
285 desc.tfm = tfm;
286 desc.flags = 0;
287
288 sg_init_table(&sg, 1);
289 crypto_hash_init(&desc);
290
291 while ((tmp = page_chain_next(page))) {
292 /* all but the last page will be fully used */
293 sg_set_page(&sg, page, PAGE_SIZE, 0);
294 crypto_hash_update(&desc, &sg, sg.length);
295 page = tmp;
296 }
297 /* and now the last, possibly only partially used page */
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100298 len = peer_req->i.size & (PAGE_SIZE - 1);
Lars Ellenberg45bb9122010-05-14 17:10:48 +0200299 sg_set_page(&sg, page, len ?: PAGE_SIZE, 0);
300 crypto_hash_update(&desc, &sg, sg.length);
301 crypto_hash_final(&desc, digest);
302}
303
Andreas Gruenbacher79a3c8d2011-08-09 02:49:01 +0200304void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700305{
306 struct hash_desc desc;
307 struct scatterlist sg;
Kent Overstreet79886132013-11-23 17:19:00 -0800308 struct bio_vec bvec;
309 struct bvec_iter iter;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700310
311 desc.tfm = tfm;
312 desc.flags = 0;
313
314 sg_init_table(&sg, 1);
315 crypto_hash_init(&desc);
316
Kent Overstreet79886132013-11-23 17:19:00 -0800317 bio_for_each_segment(bvec, bio, iter) {
318 sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700319 crypto_hash_update(&desc, &sg, sg.length);
320 }
321 crypto_hash_final(&desc, digest);
322}
323
Lars Ellenberg9676c762011-02-22 14:02:31 +0100324/* MAYBE merge common code with w_e_end_ov_req */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100325static int w_e_send_csum(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700326{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200327 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200328 struct drbd_peer_device *peer_device = peer_req->peer_device;
329 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700330 int digest_size;
331 void *digest;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100332 int err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700333
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100334 if (unlikely(cancel))
335 goto out;
336
Lars Ellenberg9676c762011-02-22 14:02:31 +0100337 if (unlikely((peer_req->flags & EE_WAS_ERROR) != 0))
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100338 goto out;
339
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200340 digest_size = crypto_hash_digestsize(peer_device->connection->csums_tfm);
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100341 digest = kmalloc(digest_size, GFP_NOIO);
342 if (digest) {
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100343 sector_t sector = peer_req->i.sector;
344 unsigned int size = peer_req->i.size;
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200345 drbd_csum_ee(peer_device->connection->csums_tfm, peer_req, digest);
Lars Ellenberg9676c762011-02-22 14:02:31 +0100346 /* Free peer_req and pages before send.
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100347 * In case we block on congestion, we could otherwise run into
348 * some distributed deadlock, if the other side blocks on
349 * congestion as well, because our receiver blocks in
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +0200350 * drbd_alloc_pages due to pp_in_use > max_buffers. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200351 drbd_free_peer_req(device, peer_req);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100352 peer_req = NULL;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200353 inc_rs_pending(device);
Andreas Gruenbacher67801392011-09-13 10:39:41 +0200354 err = drbd_send_drequest_csum(peer_device, sector, size,
Andreas Gruenbacherdb1b0b72011-03-16 01:37:21 +0100355 digest, digest_size,
356 P_CSUM_RS_REQUEST);
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100357 kfree(digest);
358 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200359 drbd_err(device, "kmalloc() of digest failed.\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100360 err = -ENOMEM;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700361 }
362
Lars Ellenberg53ea4332011-03-08 17:11:40 +0100363out:
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100364 if (peer_req)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200365 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700366
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100367 if (unlikely(err))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200368 drbd_err(device, "drbd_send_drequest(..., csum) failed\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100369 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700370}
371
372#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN)
373
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200374static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, int size)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700375{
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200376 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100377 struct drbd_peer_request *peer_req;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700378
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200379 if (!get_ldev(device))
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200380 return -EIO;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700381
382 /* GFP_TRY, because if there is no memory available right now, this may
383 * be rescheduled for later. It is "only" background resync, after all. */
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200384 peer_req = drbd_alloc_peer_req(peer_device, ID_SYNCER /* unused */, sector,
Lars Ellenberga0fb3c42014-04-28 18:43:23 +0200385 size, true /* has real payload */, GFP_TRY);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100386 if (!peer_req)
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200387 goto defer;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700388
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200389 peer_req->w.cb = w_e_send_csum;
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200390 spin_lock_irq(&device->resource->req_lock);
Lars Ellenbergb9ed7082014-04-23 12:15:35 +0200391 list_add_tail(&peer_req->w.list, &device->read_ee);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200392 spin_unlock_irq(&device->resource->req_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700393
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200394 atomic_add(size >> 9, &device->rs_sect_ev);
395 if (drbd_submit_peer_request(device, peer_req, READ, DRBD_FAULT_RS_RD) == 0)
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200396 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700397
Lars Ellenberg10f6d9922011-01-24 14:47:09 +0100398 /* If it failed because of ENOMEM, retry should help. If it failed
399 * because bio_add_page failed (probably broken lower level driver),
400 * retry may or may not help.
401 * If it does not, you may need to force disconnect. */
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200402 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200403 list_del(&peer_req->w.list);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200404 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberg22cc37a2010-09-14 20:40:41 +0200405
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200406 drbd_free_peer_req(device, peer_req);
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200407defer:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200408 put_ldev(device);
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200409 return -EAGAIN;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700410}
411
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100412int w_resync_timer(struct drbd_work *w, int cancel)
Philipp Reisner794abb72010-12-27 11:51:23 +0100413{
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200414 struct drbd_device *device =
415 container_of(w, struct drbd_device, resync_work);
416
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200417 switch (device->state.conn) {
Philipp Reisner794abb72010-12-27 11:51:23 +0100418 case C_VERIFY_S:
Andreas Gruenbacherd448a2e2011-08-25 16:59:58 +0200419 make_ov_request(device, cancel);
Philipp Reisner794abb72010-12-27 11:51:23 +0100420 break;
421 case C_SYNC_TARGET:
Andreas Gruenbacherd448a2e2011-08-25 16:59:58 +0200422 make_resync_request(device, cancel);
Philipp Reisner794abb72010-12-27 11:51:23 +0100423 break;
424 }
425
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100426 return 0;
Philipp Reisner794abb72010-12-27 11:51:23 +0100427}
428
Philipp Reisnerb411b362009-09-25 16:07:19 -0700429void resync_timer_fn(unsigned long data)
430{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200431 struct drbd_device *device = (struct drbd_device *) data;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700432
Lars Ellenberg15e26f62014-04-28 11:43:21 +0200433 drbd_queue_work_if_unqueued(
434 &first_peer_device(device)->connection->sender_work,
435 &device->resync_work);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700436}
437
Philipp Reisner778f2712010-07-06 11:14:00 +0200438static void fifo_set(struct fifo_buffer *fb, int value)
439{
440 int i;
441
442 for (i = 0; i < fb->size; i++)
Philipp Reisnerf10f2622010-10-05 16:50:17 +0200443 fb->values[i] = value;
Philipp Reisner778f2712010-07-06 11:14:00 +0200444}
445
446static int fifo_push(struct fifo_buffer *fb, int value)
447{
448 int ov;
449
450 ov = fb->values[fb->head_index];
451 fb->values[fb->head_index++] = value;
452
453 if (fb->head_index >= fb->size)
454 fb->head_index = 0;
455
456 return ov;
457}
458
459static void fifo_add_val(struct fifo_buffer *fb, int value)
460{
461 int i;
462
463 for (i = 0; i < fb->size; i++)
464 fb->values[i] += value;
465}
466
Philipp Reisner9958c852011-05-03 16:19:31 +0200467struct fifo_buffer *fifo_alloc(int fifo_size)
468{
469 struct fifo_buffer *fb;
470
Lars Ellenberg8747d302012-09-26 14:22:40 +0200471 fb = kzalloc(sizeof(struct fifo_buffer) + sizeof(int) * fifo_size, GFP_NOIO);
Philipp Reisner9958c852011-05-03 16:19:31 +0200472 if (!fb)
473 return NULL;
474
475 fb->head_index = 0;
476 fb->size = fifo_size;
477 fb->total = 0;
478
479 return fb;
480}
481
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200482static int drbd_rs_controller(struct drbd_device *device, unsigned int sect_in)
Philipp Reisner778f2712010-07-06 11:14:00 +0200483{
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +0200484 struct disk_conf *dc;
Lars Ellenberg7f34f612014-04-22 16:37:16 +0200485 unsigned int want; /* The number of sectors we want in-flight */
Philipp Reisner778f2712010-07-06 11:14:00 +0200486 int req_sect; /* Number of sectors to request in this turn */
Lars Ellenberg7f34f612014-04-22 16:37:16 +0200487 int correction; /* Number of sectors more we need in-flight */
Philipp Reisner778f2712010-07-06 11:14:00 +0200488 int cps; /* correction per invocation of drbd_rs_controller() */
489 int steps; /* Number of time steps to plan ahead */
490 int curr_corr;
491 int max_sect;
Philipp Reisner813472c2011-05-03 16:47:02 +0200492 struct fifo_buffer *plan;
Philipp Reisner778f2712010-07-06 11:14:00 +0200493
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200494 dc = rcu_dereference(device->ldev->disk_conf);
495 plan = rcu_dereference(device->rs_plan_s);
Philipp Reisner778f2712010-07-06 11:14:00 +0200496
Philipp Reisner813472c2011-05-03 16:47:02 +0200497 steps = plan->size; /* (dc->c_plan_ahead * 10 * SLEEP_TIME) / HZ; */
Philipp Reisner778f2712010-07-06 11:14:00 +0200498
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200499 if (device->rs_in_flight + sect_in == 0) { /* At start of resync */
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +0200500 want = ((dc->resync_rate * 2 * SLEEP_TIME) / HZ) * steps;
Philipp Reisner778f2712010-07-06 11:14:00 +0200501 } else { /* normal path */
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +0200502 want = dc->c_fill_target ? dc->c_fill_target :
503 sect_in * dc->c_delay_target * HZ / (SLEEP_TIME * 10);
Philipp Reisner778f2712010-07-06 11:14:00 +0200504 }
505
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200506 correction = want - device->rs_in_flight - plan->total;
Philipp Reisner778f2712010-07-06 11:14:00 +0200507
508 /* Plan ahead */
509 cps = correction / steps;
Philipp Reisner813472c2011-05-03 16:47:02 +0200510 fifo_add_val(plan, cps);
511 plan->total += cps * steps;
Philipp Reisner778f2712010-07-06 11:14:00 +0200512
513 /* What we do in this step */
Philipp Reisner813472c2011-05-03 16:47:02 +0200514 curr_corr = fifo_push(plan, 0);
515 plan->total -= curr_corr;
Philipp Reisner778f2712010-07-06 11:14:00 +0200516
517 req_sect = sect_in + curr_corr;
518 if (req_sect < 0)
519 req_sect = 0;
520
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +0200521 max_sect = (dc->c_max_rate * 2 * SLEEP_TIME) / HZ;
Philipp Reisner778f2712010-07-06 11:14:00 +0200522 if (req_sect > max_sect)
523 req_sect = max_sect;
524
525 /*
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200526 drbd_warn(device, "si=%u if=%d wa=%u co=%d st=%d cps=%d pl=%d cc=%d rs=%d\n",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200527 sect_in, device->rs_in_flight, want, correction,
528 steps, cps, device->rs_planed, curr_corr, req_sect);
Philipp Reisner778f2712010-07-06 11:14:00 +0200529 */
530
531 return req_sect;
532}
533
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200534static int drbd_rs_number_requests(struct drbd_device *device)
Lars Ellenberge65f4402010-11-05 10:04:07 +0100535{
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200536 unsigned int sect_in; /* Number of sectors that came in since the last turn */
537 int number, mxb;
538
539 sect_in = atomic_xchg(&device->rs_sect_in, 0);
540 device->rs_in_flight -= sect_in;
Philipp Reisner813472c2011-05-03 16:47:02 +0200541
542 rcu_read_lock();
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200543 mxb = drbd_get_max_buffers(device) / 2;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200544 if (rcu_dereference(device->rs_plan_s)->size) {
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200545 number = drbd_rs_controller(device, sect_in) >> (BM_BLOCK_SHIFT - 9);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200546 device->c_sync_rate = number * HZ * (BM_BLOCK_SIZE / 1024) / SLEEP_TIME;
Lars Ellenberge65f4402010-11-05 10:04:07 +0100547 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200548 device->c_sync_rate = rcu_dereference(device->ldev->disk_conf)->resync_rate;
549 number = SLEEP_TIME * device->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ);
Lars Ellenberge65f4402010-11-05 10:04:07 +0100550 }
Philipp Reisner813472c2011-05-03 16:47:02 +0200551 rcu_read_unlock();
Lars Ellenberge65f4402010-11-05 10:04:07 +0100552
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200553 /* Don't have more than "max-buffers"/2 in-flight.
554 * Otherwise we may cause the remote site to stall on drbd_alloc_pages(),
555 * potentially causing a distributed deadlock on congestion during
556 * online-verify or (checksum-based) resync, if max-buffers,
557 * socket buffer sizes and resync rate settings are mis-configured. */
Lars Ellenberg7f34f612014-04-22 16:37:16 +0200558
559 /* note that "number" is in units of "BM_BLOCK_SIZE" (which is 4k),
560 * mxb (as used here, and in drbd_alloc_pages on the peer) is
561 * "number of pages" (typically also 4k),
562 * but "rs_in_flight" is in "sectors" (512 Byte). */
563 if (mxb - device->rs_in_flight/8 < number)
564 number = mxb - device->rs_in_flight/8;
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200565
Lars Ellenberge65f4402010-11-05 10:04:07 +0100566 return number;
567}
568
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100569static int make_resync_request(struct drbd_device *const device, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700570{
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100571 struct drbd_peer_device *const peer_device = first_peer_device(device);
572 struct drbd_connection *const connection = peer_device ? peer_device->connection : NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700573 unsigned long bit;
574 sector_t sector;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200575 const sector_t capacity = drbd_get_capacity(device->this_bdev);
Lars Ellenberg1816a2b2010-11-11 15:19:07 +0100576 int max_bio_size;
Lars Ellenberge65f4402010-11-05 10:04:07 +0100577 int number, rollback_i, size;
Lars Ellenberg506afb62014-01-31 14:55:12 +0100578 int align, requeue = 0;
Lars Ellenberg0f0601f2010-08-11 23:40:24 +0200579 int i = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700580
581 if (unlikely(cancel))
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100582 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700583
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200584 if (device->rs_total == 0) {
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +0200585 /* empty resync? */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200586 drbd_resync_finished(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100587 return 0;
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +0200588 }
589
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200590 if (!get_ldev(device)) {
591 /* Since we only need to access device->rsync a
592 get_ldev_if_state(device,D_FAILED) would be sufficient, but
Philipp Reisnerb411b362009-09-25 16:07:19 -0700593 to continue resync with a broken disk makes no sense at
594 all */
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200595 drbd_err(device, "Disk broke down during resync!\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100596 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700597 }
598
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200599 max_bio_size = queue_max_hw_sectors(device->rq_queue) << 9;
600 number = drbd_rs_number_requests(device);
Lars Ellenberg0e49d7b2014-04-28 18:43:18 +0200601 if (number <= 0)
Lars Ellenberg0f0601f2010-08-11 23:40:24 +0200602 goto requeue;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700603
Philipp Reisnerb411b362009-09-25 16:07:19 -0700604 for (i = 0; i < number; i++) {
Lars Ellenberg506afb62014-01-31 14:55:12 +0100605 /* Stop generating RS requests when half of the send buffer is filled,
606 * but notify TCP that we'd like to have more space. */
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100607 mutex_lock(&connection->data.mutex);
608 if (connection->data.socket) {
Lars Ellenberg506afb62014-01-31 14:55:12 +0100609 struct sock *sk = connection->data.socket->sk;
610 int queued = sk->sk_wmem_queued;
611 int sndbuf = sk->sk_sndbuf;
612 if (queued > sndbuf / 2) {
613 requeue = 1;
614 if (sk->sk_socket)
615 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
616 }
617 } else
618 requeue = 1;
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100619 mutex_unlock(&connection->data.mutex);
Lars Ellenberg506afb62014-01-31 14:55:12 +0100620 if (requeue)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700621 goto requeue;
622
623next_sector:
624 size = BM_BLOCK_SIZE;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200625 bit = drbd_bm_find_next(device, device->bm_resync_fo);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700626
Lars Ellenberg4b0715f2010-12-14 15:13:04 +0100627 if (bit == DRBD_END_OF_BITMAP) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200628 device->bm_resync_fo = drbd_bm_bits(device);
629 put_ldev(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100630 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700631 }
632
633 sector = BM_BIT_TO_SECT(bit);
634
Lars Ellenbergad3fee72013-12-20 11:22:13 +0100635 if (drbd_try_rs_begin_io(device, sector)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200636 device->bm_resync_fo = bit;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700637 goto requeue;
638 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200639 device->bm_resync_fo = bit + 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700640
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200641 if (unlikely(drbd_bm_test_bit(device, bit) == 0)) {
642 drbd_rs_complete_io(device, sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700643 goto next_sector;
644 }
645
Lars Ellenberg1816a2b2010-11-11 15:19:07 +0100646#if DRBD_MAX_BIO_SIZE > BM_BLOCK_SIZE
Philipp Reisnerb411b362009-09-25 16:07:19 -0700647 /* try to find some adjacent bits.
648 * we stop if we have already the maximum req size.
649 *
650 * Additionally always align bigger requests, in order to
651 * be prepared for all stripe sizes of software RAIDs.
Philipp Reisnerb411b362009-09-25 16:07:19 -0700652 */
653 align = 1;
Philipp Reisnerd2074502010-07-22 15:27:27 +0200654 rollback_i = i;
Lars Ellenberg6377b922014-04-28 18:43:17 +0200655 while (i < number) {
Lars Ellenberg1816a2b2010-11-11 15:19:07 +0100656 if (size + BM_BLOCK_SIZE > max_bio_size)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700657 break;
658
659 /* Be always aligned */
660 if (sector & ((1<<(align+3))-1))
661 break;
662
663 /* do not cross extent boundaries */
664 if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0)
665 break;
666 /* now, is it actually dirty, after all?
667 * caution, drbd_bm_test_bit is tri-state for some
668 * obscure reason; ( b == 0 ) would get the out-of-band
669 * only accidentally right because of the "oddly sized"
670 * adjustment below */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200671 if (drbd_bm_test_bit(device, bit+1) != 1)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700672 break;
673 bit++;
674 size += BM_BLOCK_SIZE;
675 if ((BM_BLOCK_SIZE << align) <= size)
676 align++;
677 i++;
678 }
679 /* if we merged some,
680 * reset the offset to start the next drbd_bm_find_next from */
681 if (size > BM_BLOCK_SIZE)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200682 device->bm_resync_fo = bit + 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700683#endif
684
685 /* adjust very last sectors, in case we are oddly sized */
686 if (sector + (size>>9) > capacity)
687 size = (capacity-sector)<<9;
Lars Ellenbergaaaba342014-03-18 12:30:09 +0100688
689 if (device->use_csums) {
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100690 switch (read_for_csum(peer_device, sector, size)) {
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200691 case -EIO: /* Disk failure */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200692 put_ldev(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100693 return -EIO;
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200694 case -EAGAIN: /* allocation failed, or ldev busy */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200695 drbd_rs_complete_io(device, sector);
696 device->bm_resync_fo = BM_SECT_TO_BIT(sector);
Philipp Reisnerd2074502010-07-22 15:27:27 +0200697 i = rollback_i;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700698 goto requeue;
Lars Ellenberg80a40e42010-08-11 23:28:00 +0200699 case 0:
700 /* everything ok */
701 break;
702 default:
703 BUG();
Philipp Reisnerb411b362009-09-25 16:07:19 -0700704 }
705 } else {
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100706 int err;
707
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200708 inc_rs_pending(device);
Lars Ellenberg44a4d552013-11-22 12:40:58 +0100709 err = drbd_send_drequest(peer_device, P_RS_DATA_REQUEST,
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100710 sector, size, ID_SYNCER);
711 if (err) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200712 drbd_err(device, "drbd_send_drequest() failed, aborting...\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200713 dec_rs_pending(device);
714 put_ldev(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100715 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700716 }
717 }
718 }
719
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200720 if (device->bm_resync_fo >= drbd_bm_bits(device)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700721 /* last syncer _request_ was sent,
722 * but the P_RS_DATA_REPLY not yet received. sync will end (and
723 * next sync group will resume), as soon as we receive the last
724 * resync data block, and the last bit is cleared.
725 * until then resync "work" is "inactive" ...
726 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200727 put_ldev(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100728 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700729 }
730
731 requeue:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200732 device->rs_in_flight += (i << (BM_BLOCK_SHIFT - 9));
733 mod_timer(&device->resync_timer, jiffies + SLEEP_TIME);
734 put_ldev(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100735 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700736}
737
Andreas Gruenbacherd448a2e2011-08-25 16:59:58 +0200738static int make_ov_request(struct drbd_device *device, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700739{
740 int number, i, size;
741 sector_t sector;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200742 const sector_t capacity = drbd_get_capacity(device->this_bdev);
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200743 bool stop_sector_reached = false;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700744
745 if (unlikely(cancel))
746 return 1;
747
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200748 number = drbd_rs_number_requests(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700749
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200750 sector = device->ov_position;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700751 for (i = 0; i < number; i++) {
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200752 if (sector >= capacity)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700753 return 1;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200754
755 /* We check for "finished" only in the reply path:
756 * w_e_end_ov_reply().
757 * We need to send at least one request out. */
758 stop_sector_reached = i > 0
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200759 && verify_can_do_stop_sector(device)
760 && sector >= device->ov_stop_sector;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200761 if (stop_sector_reached)
762 break;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700763
764 size = BM_BLOCK_SIZE;
765
Lars Ellenbergad3fee72013-12-20 11:22:13 +0100766 if (drbd_try_rs_begin_io(device, sector)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200767 device->ov_position = sector;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700768 goto requeue;
769 }
770
771 if (sector + (size>>9) > capacity)
772 size = (capacity-sector)<<9;
773
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200774 inc_rs_pending(device);
Andreas Gruenbacher69a22772011-08-09 00:47:13 +0200775 if (drbd_send_ov_request(first_peer_device(device), sector, size)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200776 dec_rs_pending(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700777 return 0;
778 }
779 sector += BM_SECT_PER_BIT;
780 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200781 device->ov_position = sector;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700782
783 requeue:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200784 device->rs_in_flight += (i << (BM_BLOCK_SHIFT - 9));
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200785 if (i == 0 || !stop_sector_reached)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200786 mod_timer(&device->resync_timer, jiffies + SLEEP_TIME);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700787 return 1;
788}
789
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100790int w_ov_finished(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700791{
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200792 struct drbd_device_work *dw =
793 container_of(w, struct drbd_device_work, w);
794 struct drbd_device *device = dw->device;
795 kfree(dw);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200796 ov_out_of_sync_print(device);
797 drbd_resync_finished(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700798
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100799 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700800}
801
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100802static int w_resync_finished(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700803{
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200804 struct drbd_device_work *dw =
805 container_of(w, struct drbd_device_work, w);
806 struct drbd_device *device = dw->device;
807 kfree(dw);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700808
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200809 drbd_resync_finished(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700810
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +0100811 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700812}
813
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200814static void ping_peer(struct drbd_device *device)
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +0200815{
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +0200816 struct drbd_connection *connection = first_peer_device(device)->connection;
Philipp Reisner2a67d8b2011-02-09 14:10:32 +0100817
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +0200818 clear_bit(GOT_PING_ACK, &connection->flags);
819 request_ping(connection);
820 wait_event(connection->ping_wait,
821 test_bit(GOT_PING_ACK, &connection->flags) || device->state.conn < C_CONNECTED);
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +0200822}
823
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200824int drbd_resync_finished(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700825{
826 unsigned long db, dt, dbdt;
827 unsigned long n_oos;
828 union drbd_state os, ns;
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200829 struct drbd_device_work *dw;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700830 char *khelper_cmd = NULL;
Lars Ellenberg26525612010-11-05 09:56:33 +0100831 int verify_done = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700832
833 /* Remove all elements from the resync LRU. Since future actions
834 * might set bits in the (main) bitmap, then the entries in the
835 * resync LRU would be wrong. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200836 if (drbd_rs_del_all(device)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700837 /* In case this is not possible now, most probably because
838 * there are P_RS_DATA_REPLY Packets lingering on the worker's
839 * queue (or even the read operations for those packets
840 * is not finished by now). Retry in 100ms. */
841
Philipp Reisner20ee6392011-01-18 15:28:59 +0100842 schedule_timeout_interruptible(HZ / 10);
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200843 dw = kmalloc(sizeof(struct drbd_device_work), GFP_ATOMIC);
844 if (dw) {
845 dw->w.cb = w_resync_finished;
846 dw->device = device;
847 drbd_queue_work(&first_peer_device(device)->connection->sender_work,
848 &dw->w);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700849 return 1;
850 }
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200851 drbd_err(device, "Warn failed to drbd_rs_del_all() and to kmalloc(dw).\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700852 }
853
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200854 dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700855 if (dt <= 0)
856 dt = 1;
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +0200857
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200858 db = device->rs_total;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200859 /* adjust for verify start and stop sectors, respective reached position */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200860 if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
861 db -= device->ov_left;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200862
Philipp Reisnerb411b362009-09-25 16:07:19 -0700863 dbdt = Bit2KB(db/dt);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200864 device->rs_paused /= HZ;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700865
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200866 if (!get_ldev(device))
Philipp Reisnerb411b362009-09-25 16:07:19 -0700867 goto out;
868
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200869 ping_peer(device);
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +0200870
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200871 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200872 os = drbd_read_state(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700873
Lars Ellenberg26525612010-11-05 09:56:33 +0100874 verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T);
875
Philipp Reisnerb411b362009-09-25 16:07:19 -0700876 /* This protects us against multiple calls (that can happen in the presence
877 of application IO), and against connectivity loss just before we arrive here. */
878 if (os.conn <= C_CONNECTED)
879 goto out_unlock;
880
881 ns = os;
882 ns.conn = C_CONNECTED;
883
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200884 drbd_info(device, "%s done (total %lu sec; paused %lu sec; %lu K/sec)\n",
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200885 verify_done ? "Online verify" : "Resync",
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200886 dt + device->rs_paused, device->rs_paused, dbdt);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700887
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200888 n_oos = drbd_bm_total_weight(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700889
890 if (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) {
891 if (n_oos) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200892 drbd_alert(device, "Online verify found %lu %dk block out of sync!\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -0700893 n_oos, Bit2KB(1));
894 khelper_cmd = "out-of-sync";
895 }
896 } else {
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +0200897 D_ASSERT(device, (n_oos - device->rs_failed) == 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700898
899 if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T)
900 khelper_cmd = "after-resync-target";
901
Lars Ellenbergaaaba342014-03-18 12:30:09 +0100902 if (device->use_csums && device->rs_total) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200903 const unsigned long s = device->rs_same_csum;
904 const unsigned long t = device->rs_total;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700905 const int ratio =
906 (t == 0) ? 0 :
907 (t < 100000) ? ((s*100)/t) : (s/(t/100));
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200908 drbd_info(device, "%u %% had equal checksums, eliminated: %luK; "
Philipp Reisnerb411b362009-09-25 16:07:19 -0700909 "transferred %luK total %luK\n",
910 ratio,
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200911 Bit2KB(device->rs_same_csum),
912 Bit2KB(device->rs_total - device->rs_same_csum),
913 Bit2KB(device->rs_total));
Philipp Reisnerb411b362009-09-25 16:07:19 -0700914 }
915 }
916
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200917 if (device->rs_failed) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200918 drbd_info(device, " %lu failed blocks\n", device->rs_failed);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700919
920 if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T) {
921 ns.disk = D_INCONSISTENT;
922 ns.pdsk = D_UP_TO_DATE;
923 } else {
924 ns.disk = D_UP_TO_DATE;
925 ns.pdsk = D_INCONSISTENT;
926 }
927 } else {
928 ns.disk = D_UP_TO_DATE;
929 ns.pdsk = D_UP_TO_DATE;
930
931 if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200932 if (device->p_uuid) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700933 int i;
934 for (i = UI_BITMAP ; i <= UI_HISTORY_END ; i++)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200935 _drbd_uuid_set(device, i, device->p_uuid[i]);
936 drbd_uuid_set(device, UI_BITMAP, device->ldev->md.uuid[UI_CURRENT]);
937 _drbd_uuid_set(device, UI_CURRENT, device->p_uuid[UI_CURRENT]);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700938 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +0200939 drbd_err(device, "device->p_uuid is NULL! BUG\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700940 }
941 }
942
Lars Ellenberg62b0da32011-01-20 13:25:21 +0100943 if (!(os.conn == C_VERIFY_S || os.conn == C_VERIFY_T)) {
944 /* for verify runs, we don't update uuids here,
945 * so there would be nothing to report. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200946 drbd_uuid_set_bm(device, 0UL);
947 drbd_print_uuids(device, "updated UUIDs");
948 if (device->p_uuid) {
Lars Ellenberg62b0da32011-01-20 13:25:21 +0100949 /* Now the two UUID sets are equal, update what we
950 * know of the peer. */
951 int i;
952 for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200953 device->p_uuid[i] = device->ldev->md.uuid[i];
Lars Ellenberg62b0da32011-01-20 13:25:21 +0100954 }
Philipp Reisnerb411b362009-09-25 16:07:19 -0700955 }
956 }
957
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200958 _drbd_set_state(device, ns, CS_VERBOSE, NULL);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700959out_unlock:
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200960 spin_unlock_irq(&device->resource->req_lock);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200961 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700962out:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200963 device->rs_total = 0;
964 device->rs_failed = 0;
965 device->rs_paused = 0;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200966
967 /* reset start sector, if we reached end of device */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200968 if (verify_done && device->ov_left == 0)
969 device->ov_start_sector = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700970
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200971 drbd_md_sync(device);
Lars Ellenberg13d42682010-10-13 17:37:54 +0200972
Philipp Reisnerb411b362009-09-25 16:07:19 -0700973 if (khelper_cmd)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200974 drbd_khelper(device, khelper_cmd);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700975
976 return 1;
977}
978
979/* helper */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200980static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_request *peer_req)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700981{
Andreas Gruenbacher045417f2011-04-07 21:34:24 +0200982 if (drbd_peer_req_has_active_page(peer_req)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700983 /* This might happen if sendpage() has not finished */
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +0100984 int i = (peer_req->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200985 atomic_add(i, &device->pp_in_use_by_net);
986 atomic_sub(i, &device->pp_in_use);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200987 spin_lock_irq(&device->resource->req_lock);
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +0200988 list_add_tail(&peer_req->w.list, &device->net_ee);
Andreas Gruenbacher05008132011-07-07 14:19:42 +0200989 spin_unlock_irq(&device->resource->req_lock);
Lars Ellenberg435f0742010-09-06 12:30:25 +0200990 wake_up(&drbd_pp_wait);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700991 } else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200992 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700993}
994
995/**
996 * w_e_end_data_req() - Worker callback, to send a P_DATA_REPLY packet in response to a P_DATA_REQUEST
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200997 * @device: DRBD device.
Philipp Reisnerb411b362009-09-25 16:07:19 -0700998 * @w: work object.
999 * @cancel: The connection will be closed anyways
1000 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001001int w_e_end_data_req(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001002{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001003 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001004 struct drbd_peer_device *peer_device = peer_req->peer_device;
1005 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001006 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001007
1008 if (unlikely(cancel)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001009 drbd_free_peer_req(device, peer_req);
1010 dec_unacked(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001011 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001012 }
1013
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001014 if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001015 err = drbd_send_block(peer_device, P_DATA_REPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001016 } else {
1017 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001018 drbd_err(device, "Sending NegDReply. sector=%llus.\n",
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001019 (unsigned long long)peer_req->i.sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001020
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001021 err = drbd_send_ack(peer_device, P_NEG_DREPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001022 }
1023
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001024 dec_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001025
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001026 move_to_net_ee_or_free(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001027
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001028 if (unlikely(err))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001029 drbd_err(device, "drbd_send_block() failed\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001030 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001031}
1032
1033/**
Andreas Gruenbachera209b4a2011-08-17 12:43:25 +02001034 * w_e_end_rsdata_req() - Worker callback to send a P_RS_DATA_REPLY packet in response to a P_RS_DATA_REQUEST
Philipp Reisnerb411b362009-09-25 16:07:19 -07001035 * @w: work object.
1036 * @cancel: The connection will be closed anyways
1037 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001038int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001039{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001040 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001041 struct drbd_peer_device *peer_device = peer_req->peer_device;
1042 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001043 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001044
1045 if (unlikely(cancel)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001046 drbd_free_peer_req(device, peer_req);
1047 dec_unacked(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001048 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001049 }
1050
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001051 if (get_ldev_if_state(device, D_FAILED)) {
1052 drbd_rs_complete_io(device, peer_req->i.sector);
1053 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001054 }
1055
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001056 if (device->state.conn == C_AHEAD) {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001057 err = drbd_send_ack(peer_device, P_RS_CANCEL, peer_req);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001058 } else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001059 if (likely(device->state.pdsk >= D_INCONSISTENT)) {
1060 inc_rs_pending(device);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001061 err = drbd_send_block(peer_device, P_RS_DATA_REPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001062 } else {
1063 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001064 drbd_err(device, "Not sending RSDataReply, "
Philipp Reisnerb411b362009-09-25 16:07:19 -07001065 "partner DISKLESS!\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001066 err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001067 }
1068 } else {
1069 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001070 drbd_err(device, "Sending NegRSDReply. sector %llus.\n",
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001071 (unsigned long long)peer_req->i.sector);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001072
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001073 err = drbd_send_ack(peer_device, P_NEG_RS_DREPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001074
1075 /* update resync data with failure */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001076 drbd_rs_failed_io(device, peer_req->i.sector, peer_req->i.size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001077 }
1078
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001079 dec_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001080
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001081 move_to_net_ee_or_free(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001082
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001083 if (unlikely(err))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001084 drbd_err(device, "drbd_send_block() failed\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001085 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001086}
1087
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001088int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001089{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001090 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001091 struct drbd_peer_device *peer_device = peer_req->peer_device;
1092 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001093 struct digest_info *di;
1094 int digest_size;
1095 void *digest = NULL;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001096 int err, eq = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001097
1098 if (unlikely(cancel)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001099 drbd_free_peer_req(device, peer_req);
1100 dec_unacked(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001101 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001102 }
1103
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001104 if (get_ldev(device)) {
1105 drbd_rs_complete_io(device, peer_req->i.sector);
1106 put_ldev(device);
Lars Ellenberg1d53f092010-09-05 01:13:24 +02001107 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001108
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001109 di = peer_req->digest;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001110
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001111 if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001112 /* quick hack to try to avoid a race against reconfiguration.
1113 * a real fix would be much more involved,
1114 * introducing more locking mechanisms */
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001115 if (peer_device->connection->csums_tfm) {
1116 digest_size = crypto_hash_digestsize(peer_device->connection->csums_tfm);
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001117 D_ASSERT(device, digest_size == di->digest_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001118 digest = kmalloc(digest_size, GFP_NOIO);
1119 }
1120 if (digest) {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001121 drbd_csum_ee(peer_device->connection->csums_tfm, peer_req, digest);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001122 eq = !memcmp(digest, di->digest, digest_size);
1123 kfree(digest);
1124 }
1125
1126 if (eq) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001127 drbd_set_in_sync(device, peer_req->i.sector, peer_req->i.size);
Lars Ellenberg676396d2010-03-03 02:08:22 +01001128 /* rs_same_csums unit is BM_BLOCK_SIZE */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001129 device->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT;
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001130 err = drbd_send_ack(peer_device, P_RS_IS_IN_SYNC, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001131 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001132 inc_rs_pending(device);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001133 peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
1134 peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */
Philipp Reisner204bba92010-08-23 16:17:13 +02001135 kfree(di);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001136 err = drbd_send_block(peer_device, P_RS_DATA_REPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001137 }
1138 } else {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001139 err = drbd_send_ack(peer_device, P_NEG_RS_DREPLY, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001140 if (__ratelimit(&drbd_ratelimit_state))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001141 drbd_err(device, "Sending NegDReply. I guess it gets messy.\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07001142 }
1143
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001144 dec_unacked(device);
1145 move_to_net_ee_or_free(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001146
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001147 if (unlikely(err))
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001148 drbd_err(device, "drbd_send_block/ack() failed\n");
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001149 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001150}
1151
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001152int w_e_end_ov_req(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001153{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001154 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001155 struct drbd_peer_device *peer_device = peer_req->peer_device;
1156 struct drbd_device *device = peer_device->device;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001157 sector_t sector = peer_req->i.sector;
1158 unsigned int size = peer_req->i.size;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001159 int digest_size;
1160 void *digest;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001161 int err = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001162
1163 if (unlikely(cancel))
1164 goto out;
1165
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001166 digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001167 digest = kmalloc(digest_size, GFP_NOIO);
Philipp Reisner8f214202011-03-01 15:52:35 +01001168 if (!digest) {
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001169 err = 1; /* terminate the connection in case the allocation failed */
Philipp Reisner8f214202011-03-01 15:52:35 +01001170 goto out;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001171 }
1172
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001173 if (likely(!(peer_req->flags & EE_WAS_ERROR)))
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001174 drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest);
Philipp Reisner8f214202011-03-01 15:52:35 +01001175 else
1176 memset(digest, 0, digest_size);
1177
Lars Ellenberg53ea4332011-03-08 17:11:40 +01001178 /* Free e and pages before send.
1179 * In case we block on congestion, we could otherwise run into
1180 * some distributed deadlock, if the other side blocks on
1181 * congestion as well, because our receiver blocks in
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +02001182 * drbd_alloc_pages due to pp_in_use > max_buffers. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001183 drbd_free_peer_req(device, peer_req);
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001184 peer_req = NULL;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001185 inc_rs_pending(device);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001186 err = drbd_send_drequest_csum(peer_device, sector, size, digest, digest_size, P_OV_REPLY);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001187 if (err)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001188 dec_rs_pending(device);
Philipp Reisner8f214202011-03-01 15:52:35 +01001189 kfree(digest);
1190
Philipp Reisnerb411b362009-09-25 16:07:19 -07001191out:
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001192 if (peer_req)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001193 drbd_free_peer_req(device, peer_req);
1194 dec_unacked(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001195 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001196}
1197
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001198void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int size)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001199{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001200 if (device->ov_last_oos_start + device->ov_last_oos_size == sector) {
1201 device->ov_last_oos_size += size>>9;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001202 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001203 device->ov_last_oos_start = sector;
1204 device->ov_last_oos_size = size>>9;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001205 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001206 drbd_set_out_of_sync(device, sector, size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001207}
1208
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001209int w_e_end_ov_reply(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001210{
Andreas Gruenbachera8cd15b2011-08-25 15:49:40 +02001211 struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001212 struct drbd_peer_device *peer_device = peer_req->peer_device;
1213 struct drbd_device *device = peer_device->device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001214 struct digest_info *di;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001215 void *digest;
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001216 sector_t sector = peer_req->i.sector;
1217 unsigned int size = peer_req->i.size;
Lars Ellenberg53ea4332011-03-08 17:11:40 +01001218 int digest_size;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001219 int err, eq = 0;
Lars Ellenberg58ffa582012-07-26 14:09:49 +02001220 bool stop_sector_reached = false;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001221
1222 if (unlikely(cancel)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001223 drbd_free_peer_req(device, peer_req);
1224 dec_unacked(device);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001225 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001226 }
1227
1228 /* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all
1229 * the resync lru has been cleaned up already */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001230 if (get_ldev(device)) {
1231 drbd_rs_complete_io(device, peer_req->i.sector);
1232 put_ldev(device);
Lars Ellenberg1d53f092010-09-05 01:13:24 +02001233 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001234
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001235 di = peer_req->digest;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001236
Andreas Gruenbacherdb830c42011-02-04 15:57:48 +01001237 if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001238 digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001239 digest = kmalloc(digest_size, GFP_NOIO);
1240 if (digest) {
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001241 drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001242
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02001243 D_ASSERT(device, digest_size == di->digest_size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001244 eq = !memcmp(digest, di->digest, digest_size);
1245 kfree(digest);
1246 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001247 }
1248
Lars Ellenberg9676c762011-02-22 14:02:31 +01001249 /* Free peer_req and pages before send.
1250 * In case we block on congestion, we could otherwise run into
1251 * some distributed deadlock, if the other side blocks on
1252 * congestion as well, because our receiver blocks in
Andreas Gruenbacherc37c8ec2011-04-07 21:02:09 +02001253 * drbd_alloc_pages due to pp_in_use > max_buffers. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001254 drbd_free_peer_req(device, peer_req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001255 if (!eq)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001256 drbd_ov_out_of_sync_found(device, sector, size);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001257 else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001258 ov_out_of_sync_print(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001259
Andreas Gruenbacher67801392011-09-13 10:39:41 +02001260 err = drbd_send_ack_ex(peer_device, P_OV_RESULT, sector, size,
Andreas Gruenbacherfa79abd2011-03-16 01:31:39 +01001261 eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001262
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001263 dec_unacked(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001264
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001265 --device->ov_left;
Lars Ellenbergea5442a2010-11-05 09:48:01 +01001266
1267 /* let's advance progress step marks only for every other megabyte */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001268 if ((device->ov_left & 0x200) == 0x200)
1269 drbd_advance_rs_marks(device, device->ov_left);
Lars Ellenbergea5442a2010-11-05 09:48:01 +01001270
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001271 stop_sector_reached = verify_can_do_stop_sector(device) &&
1272 (sector + (size>>9)) >= device->ov_stop_sector;
Lars Ellenberg58ffa582012-07-26 14:09:49 +02001273
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001274 if (device->ov_left == 0 || stop_sector_reached) {
1275 ov_out_of_sync_print(device);
1276 drbd_resync_finished(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001277 }
1278
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001279 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001280}
1281
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001282/* FIXME
1283 * We need to track the number of pending barrier acks,
1284 * and to be able to wait for them.
1285 * See also comment in drbd_adm_attach before drbd_suspend_io.
1286 */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001287static int drbd_send_barrier(struct drbd_connection *connection)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001288{
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02001289 struct p_barrier *p;
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001290 struct drbd_socket *sock;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001291
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001292 sock = &connection->data;
1293 p = conn_prepare_command(connection, sock);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02001294 if (!p)
1295 return -EIO;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001296 p->barrier = connection->send.current_epoch_nr;
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001297 p->pad = 0;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001298 connection->send.current_epoch_writes = 0;
Lars Ellenberg84d34f22015-02-19 13:54:11 +01001299 connection->send.last_sent_barrier_jif = jiffies;
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001300
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001301 return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001302}
1303
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001304int w_send_write_hint(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001305{
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02001306 struct drbd_device *device =
1307 container_of(w, struct drbd_device, unplug_work);
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02001308 struct drbd_socket *sock;
1309
Philipp Reisnerb411b362009-09-25 16:07:19 -07001310 if (cancel)
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001311 return 0;
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +02001312 sock = &first_peer_device(device)->connection->data;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001313 if (!drbd_prepare_command(first_peer_device(device), sock))
Andreas Gruenbacher9f5bdc32011-03-28 14:23:08 +02001314 return -EIO;
Andreas Gruenbacher69a22772011-08-09 00:47:13 +02001315 return drbd_send_command(first_peer_device(device), sock, P_UNPLUG_REMOTE, 0, NULL, 0);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001316}
1317
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001318static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
Lars Ellenberg4eb9b3c2012-08-20 11:05:23 +02001319{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001320 if (!connection->send.seen_any_write_yet) {
1321 connection->send.seen_any_write_yet = true;
1322 connection->send.current_epoch_nr = epoch;
1323 connection->send.current_epoch_writes = 0;
Lars Ellenberg84d34f22015-02-19 13:54:11 +01001324 connection->send.last_sent_barrier_jif = jiffies;
Lars Ellenberg4eb9b3c2012-08-20 11:05:23 +02001325 }
1326}
1327
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001328static void maybe_send_barrier(struct drbd_connection *connection, unsigned int epoch)
Lars Ellenberg4eb9b3c2012-08-20 11:05:23 +02001329{
1330 /* re-init if first write on this connection */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001331 if (!connection->send.seen_any_write_yet)
Lars Ellenberg4eb9b3c2012-08-20 11:05:23 +02001332 return;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001333 if (connection->send.current_epoch_nr != epoch) {
1334 if (connection->send.current_epoch_writes)
1335 drbd_send_barrier(connection);
1336 connection->send.current_epoch_nr = epoch;
Lars Ellenberg4eb9b3c2012-08-20 11:05:23 +02001337 }
1338}
1339
Andreas Gruenbacher8f7bed72010-12-19 23:53:14 +01001340int w_send_out_of_sync(struct drbd_work *w, int cancel)
Philipp Reisner73a01a12010-10-27 14:33:00 +02001341{
1342 struct drbd_request *req = container_of(w, struct drbd_request, w);
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02001343 struct drbd_device *device = req->device;
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001344 struct drbd_peer_device *const peer_device = first_peer_device(device);
1345 struct drbd_connection *const connection = peer_device->connection;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001346 int err;
Philipp Reisner73a01a12010-10-27 14:33:00 +02001347
1348 if (unlikely(cancel)) {
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01001349 req_mod(req, SEND_CANCELED);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001350 return 0;
Philipp Reisner73a01a12010-10-27 14:33:00 +02001351 }
Lars Ellenberge5f891b2013-11-22 12:32:01 +01001352 req->pre_send_jif = jiffies;
Philipp Reisner73a01a12010-10-27 14:33:00 +02001353
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001354 /* this time, no connection->send.current_epoch_writes++;
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001355 * If it was sent, it was the closing barrier for the last
1356 * replicated epoch, before we went into AHEAD mode.
1357 * No more barriers will be sent, until we leave AHEAD mode again. */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001358 maybe_send_barrier(connection, req->epoch);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001359
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001360 err = drbd_send_out_of_sync(peer_device, req);
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01001361 req_mod(req, OOS_HANDED_TO_NETWORK);
Philipp Reisner73a01a12010-10-27 14:33:00 +02001362
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001363 return err;
Philipp Reisner73a01a12010-10-27 14:33:00 +02001364}
1365
Philipp Reisnerb411b362009-09-25 16:07:19 -07001366/**
1367 * w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request
Philipp Reisnerb411b362009-09-25 16:07:19 -07001368 * @w: work object.
1369 * @cancel: The connection will be closed anyways
1370 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001371int w_send_dblock(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001372{
1373 struct drbd_request *req = container_of(w, struct drbd_request, w);
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02001374 struct drbd_device *device = req->device;
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001375 struct drbd_peer_device *const peer_device = first_peer_device(device);
1376 struct drbd_connection *connection = peer_device->connection;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001377 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001378
1379 if (unlikely(cancel)) {
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01001380 req_mod(req, SEND_CANCELED);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001381 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001382 }
Lars Ellenberge5f891b2013-11-22 12:32:01 +01001383 req->pre_send_jif = jiffies;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001384
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001385 re_init_if_first_write(connection, req->epoch);
1386 maybe_send_barrier(connection, req->epoch);
1387 connection->send.current_epoch_writes++;
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001388
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001389 err = drbd_send_dblock(peer_device, req);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001390 req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001391
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001392 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001393}
1394
1395/**
1396 * w_send_read_req() - Worker callback to send a read request (P_DATA_REQUEST) packet
Philipp Reisnerb411b362009-09-25 16:07:19 -07001397 * @w: work object.
1398 * @cancel: The connection will be closed anyways
1399 */
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001400int w_send_read_req(struct drbd_work *w, int cancel)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001401{
1402 struct drbd_request *req = container_of(w, struct drbd_request, w);
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02001403 struct drbd_device *device = req->device;
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001404 struct drbd_peer_device *const peer_device = first_peer_device(device);
1405 struct drbd_connection *connection = peer_device->connection;
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001406 int err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001407
1408 if (unlikely(cancel)) {
Andreas Gruenbacher8554df12011-01-25 15:37:43 +01001409 req_mod(req, SEND_CANCELED);
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001410 return 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001411 }
Lars Ellenberge5f891b2013-11-22 12:32:01 +01001412 req->pre_send_jif = jiffies;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001413
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001414 /* Even read requests may close a write epoch,
1415 * if there was any yet. */
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001416 maybe_send_barrier(connection, req->epoch);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001417
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001418 err = drbd_send_drequest(peer_device, P_DATA_REQUEST, req->i.sector, req->i.size,
Andreas Gruenbacher6c1005e2011-03-16 01:34:24 +01001419 (unsigned long)req);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001420
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001421 req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001422
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001423 return err;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001424}
1425
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001426int w_restart_disk_io(struct drbd_work *w, int cancel)
Philipp Reisner265be2d2010-05-31 10:14:17 +02001427{
1428 struct drbd_request *req = container_of(w, struct drbd_request, w);
Andreas Gruenbacher84b8c062011-07-28 15:27:51 +02001429 struct drbd_device *device = req->device;
Philipp Reisner265be2d2010-05-31 10:14:17 +02001430
Philipp Reisner07782862010-08-31 12:00:50 +02001431 if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
Lars Ellenberg4dd726f2014-02-11 11:15:36 +01001432 drbd_al_begin_io(device, &req->i);
Philipp Reisner265be2d2010-05-31 10:14:17 +02001433
1434 drbd_req_make_private_bio(req, req->master_bio);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001435 req->private_bio->bi_bdev = device->ldev->backing_bdev;
Philipp Reisner265be2d2010-05-31 10:14:17 +02001436 generic_make_request(req->private_bio);
1437
Andreas Gruenbacher99920dc2011-03-16 15:31:39 +01001438 return 0;
Philipp Reisner265be2d2010-05-31 10:14:17 +02001439}
1440
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001441static int _drbd_may_sync_now(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001442{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001443 struct drbd_device *odev = device;
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001444 int resync_after;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001445
1446 while (1) {
Lars Ellenberga3f8f7d2013-03-27 14:08:43 +01001447 if (!odev->ldev || odev->state.disk == D_DISKLESS)
Philipp Reisner438c8372011-03-28 14:48:01 +02001448 return 1;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02001449 rcu_read_lock();
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001450 resync_after = rcu_dereference(odev->ldev->disk_conf)->resync_after;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02001451 rcu_read_unlock();
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001452 if (resync_after == -1)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001453 return 1;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001454 odev = minor_to_device(resync_after);
Lars Ellenberga3f8f7d2013-03-27 14:08:43 +01001455 if (!odev)
Andreas Gruenbacher841ce242010-12-15 19:31:20 +01001456 return 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001457 if ((odev->state.conn >= C_SYNC_SOURCE &&
1458 odev->state.conn <= C_PAUSED_SYNC_T) ||
1459 odev->state.aftr_isp || odev->state.peer_isp ||
1460 odev->state.user_isp)
1461 return 0;
1462 }
1463}
1464
1465/**
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001466 * drbd_pause_after() - Pause resync on all devices that may not resync now
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001467 * @device: DRBD device.
Philipp Reisnerb411b362009-09-25 16:07:19 -07001468 *
1469 * Called from process context only (admin command and after_state_ch).
1470 */
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001471static bool drbd_pause_after(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001472{
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001473 bool changed = false;
Andreas Gruenbacher54761692011-05-30 16:15:21 +02001474 struct drbd_device *odev;
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001475 int i;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001476
Philipp Reisner695d08f2011-04-11 22:53:32 -07001477 rcu_read_lock();
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02001478 idr_for_each_entry(&drbd_devices, odev, i) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001479 if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
1480 continue;
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001481 if (!_drbd_may_sync_now(odev) &&
1482 _drbd_set_state(_NS(odev, aftr_isp, 1),
1483 CS_HARD, NULL) != SS_NOTHING_TO_DO)
1484 changed = true;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001485 }
Philipp Reisner695d08f2011-04-11 22:53:32 -07001486 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07001487
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001488 return changed;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001489}
1490
1491/**
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001492 * drbd_resume_next() - Resume resync on all devices that may resync now
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001493 * @device: DRBD device.
Philipp Reisnerb411b362009-09-25 16:07:19 -07001494 *
1495 * Called from process context only (admin command and worker).
1496 */
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001497static bool drbd_resume_next(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001498{
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001499 bool changed = false;
Andreas Gruenbacher54761692011-05-30 16:15:21 +02001500 struct drbd_device *odev;
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001501 int i;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001502
Philipp Reisner695d08f2011-04-11 22:53:32 -07001503 rcu_read_lock();
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02001504 idr_for_each_entry(&drbd_devices, odev, i) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07001505 if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
1506 continue;
1507 if (odev->state.aftr_isp) {
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001508 if (_drbd_may_sync_now(odev) &&
1509 _drbd_set_state(_NS(odev, aftr_isp, 0),
1510 CS_HARD, NULL) != SS_NOTHING_TO_DO)
1511 changed = true;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001512 }
1513 }
Philipp Reisner695d08f2011-04-11 22:53:32 -07001514 rcu_read_unlock();
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001515 return changed;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001516}
1517
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001518void resume_next_sg(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001519{
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001520 lock_all_resources();
1521 drbd_resume_next(device);
1522 unlock_all_resources();
Philipp Reisnerb411b362009-09-25 16:07:19 -07001523}
1524
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001525void suspend_other_sg(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001526{
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001527 lock_all_resources();
1528 drbd_pause_after(device);
1529 unlock_all_resources();
Philipp Reisnerb411b362009-09-25 16:07:19 -07001530}
1531
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001532/* caller must lock_all_resources() */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001533enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001534{
Andreas Gruenbacher54761692011-05-30 16:15:21 +02001535 struct drbd_device *odev;
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001536 int resync_after;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001537
1538 if (o_minor == -1)
1539 return NO_ERROR;
Lars Ellenberga3f8f7d2013-03-27 14:08:43 +01001540 if (o_minor < -1 || o_minor > MINORMASK)
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001541 return ERR_RESYNC_AFTER;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001542
1543 /* check for loops */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001544 odev = minor_to_device(o_minor);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001545 while (1) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001546 if (odev == device)
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001547 return ERR_RESYNC_AFTER_CYCLE;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001548
Lars Ellenberga3f8f7d2013-03-27 14:08:43 +01001549 /* You are free to depend on diskless, non-existing,
1550 * or not yet/no longer existing minors.
1551 * We only reject dependency loops.
1552 * We cannot follow the dependency chain beyond a detached or
1553 * missing minor.
1554 */
1555 if (!odev || !odev->ldev || odev->state.disk == D_DISKLESS)
1556 return NO_ERROR;
1557
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02001558 rcu_read_lock();
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001559 resync_after = rcu_dereference(odev->ldev->disk_conf)->resync_after;
Philipp Reisnerdaeda1c2011-05-03 15:00:55 +02001560 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07001561 /* dependency chain ends here, no cycles. */
Andreas Gruenbacher95f8efd2011-05-12 11:15:34 +02001562 if (resync_after == -1)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001563 return NO_ERROR;
1564
1565 /* follow the dependency chain */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001566 odev = minor_to_device(resync_after);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001567 }
1568}
1569
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001570/* caller must lock_all_resources() */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001571void drbd_resync_after_changed(struct drbd_device *device)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001572{
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001573 int changed;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001574
Philipp Reisnerdc97b702011-05-03 14:27:15 +02001575 do {
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001576 changed = drbd_pause_after(device);
1577 changed |= drbd_resume_next(device);
1578 } while (changed);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001579}
1580
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001581void drbd_rs_controller_reset(struct drbd_device *device)
Lars Ellenberg9bd28d32010-11-05 09:55:18 +01001582{
Lars Ellenbergff8bd882014-11-10 17:21:12 +01001583 struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk;
Philipp Reisner813472c2011-05-03 16:47:02 +02001584 struct fifo_buffer *plan;
1585
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001586 atomic_set(&device->rs_sect_in, 0);
1587 atomic_set(&device->rs_sect_ev, 0);
1588 device->rs_in_flight = 0;
Lars Ellenbergff8bd882014-11-10 17:21:12 +01001589 device->rs_last_events =
1590 (int)part_stat_read(&disk->part0, sectors[0]) +
1591 (int)part_stat_read(&disk->part0, sectors[1]);
Philipp Reisner813472c2011-05-03 16:47:02 +02001592
1593 /* Updating the RCU protected object in place is necessary since
1594 this function gets called from atomic context.
1595 It is valid since all other updates also lead to an completely
1596 empty fifo */
1597 rcu_read_lock();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001598 plan = rcu_dereference(device->rs_plan_s);
Philipp Reisner813472c2011-05-03 16:47:02 +02001599 plan->total = 0;
1600 fifo_set(plan, 0);
1601 rcu_read_unlock();
Lars Ellenberg9bd28d32010-11-05 09:55:18 +01001602}
1603
Philipp Reisner1f04af32011-02-07 11:33:59 +01001604void start_resync_timer_fn(unsigned long data)
1605{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001606 struct drbd_device *device = (struct drbd_device *) data;
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001607 drbd_device_post_work(device, RS_START);
Philipp Reisner1f04af32011-02-07 11:33:59 +01001608}
1609
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001610static void do_start_resync(struct drbd_device *device)
Philipp Reisner1f04af32011-02-07 11:33:59 +01001611{
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001612 if (atomic_read(&device->unacked_cnt) || atomic_read(&device->rs_pending_cnt)) {
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001613 drbd_warn(device, "postponing start_resync ...\n");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001614 device->start_resync_timer.expires = jiffies + HZ/10;
1615 add_timer(&device->start_resync_timer);
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001616 return;
Philipp Reisner1f04af32011-02-07 11:33:59 +01001617 }
1618
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001619 drbd_start_resync(device, C_SYNC_SOURCE);
1620 clear_bit(AHEAD_TO_SYNC_SOURCE, &device->flags);
Philipp Reisner1f04af32011-02-07 11:33:59 +01001621}
1622
Lars Ellenbergaaaba342014-03-18 12:30:09 +01001623static bool use_checksum_based_resync(struct drbd_connection *connection, struct drbd_device *device)
1624{
1625 bool csums_after_crash_only;
1626 rcu_read_lock();
1627 csums_after_crash_only = rcu_dereference(connection->net_conf)->csums_after_crash_only;
1628 rcu_read_unlock();
1629 return connection->agreed_pro_version >= 89 && /* supported? */
1630 connection->csums_tfm && /* configured? */
1631 (csums_after_crash_only == 0 /* use for each resync? */
1632 || test_bit(CRASHED_PRIMARY, &device->flags)); /* or only after Primary crash? */
1633}
1634
Philipp Reisnerb411b362009-09-25 16:07:19 -07001635/**
1636 * drbd_start_resync() - Start the resync process
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001637 * @device: DRBD device.
Philipp Reisnerb411b362009-09-25 16:07:19 -07001638 * @side: Either C_SYNC_SOURCE or C_SYNC_TARGET
1639 *
1640 * This function might bring you directly into one of the
1641 * C_PAUSED_SYNC_* states.
1642 */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001643void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
Philipp Reisnerb411b362009-09-25 16:07:19 -07001644{
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001645 struct drbd_peer_device *peer_device = first_peer_device(device);
1646 struct drbd_connection *connection = peer_device ? peer_device->connection : NULL;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001647 union drbd_state ns;
1648 int r;
1649
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001650 if (device->state.conn >= C_SYNC_SOURCE && device->state.conn < C_AHEAD) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001651 drbd_err(device, "Resync already running!\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07001652 return;
1653 }
1654
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001655 if (!test_bit(B_RS_H_DONE, &device->flags)) {
Philipp Reisnere64a3292011-02-05 17:34:11 +01001656 if (side == C_SYNC_TARGET) {
1657 /* Since application IO was locked out during C_WF_BITMAP_T and
1658 C_WF_SYNC_UUID we are still unmodified. Before going to C_SYNC_TARGET
1659 we check that we might make the data inconsistent. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001660 r = drbd_khelper(device, "before-resync-target");
Philipp Reisnere64a3292011-02-05 17:34:11 +01001661 r = (r >> 8) & 0xff;
1662 if (r > 0) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001663 drbd_info(device, "before-resync-target handler returned %d, "
Philipp Reisner09b9e792010-12-03 16:04:24 +01001664 "dropping connection.\n", r);
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001665 conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisner09b9e792010-12-03 16:04:24 +01001666 return;
1667 }
Philipp Reisnere64a3292011-02-05 17:34:11 +01001668 } else /* C_SYNC_SOURCE */ {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001669 r = drbd_khelper(device, "before-resync-source");
Philipp Reisnere64a3292011-02-05 17:34:11 +01001670 r = (r >> 8) & 0xff;
1671 if (r > 0) {
1672 if (r == 3) {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001673 drbd_info(device, "before-resync-source handler returned %d, "
Philipp Reisnere64a3292011-02-05 17:34:11 +01001674 "ignoring. Old userland tools?", r);
1675 } else {
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001676 drbd_info(device, "before-resync-source handler returned %d, "
Philipp Reisnere64a3292011-02-05 17:34:11 +01001677 "dropping connection.\n", r);
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001678 conn_request_state(connection,
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +02001679 NS(conn, C_DISCONNECTING), CS_HARD);
Philipp Reisnere64a3292011-02-05 17:34:11 +01001680 return;
1681 }
1682 }
Philipp Reisner09b9e792010-12-03 16:04:24 +01001683 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001684 }
1685
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001686 if (current == connection->worker.task) {
Philipp Reisnerdad20552011-02-11 19:43:55 +01001687 /* The worker should not sleep waiting for state_mutex,
Philipp Reisnere64a3292011-02-05 17:34:11 +01001688 that can take long */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001689 if (!mutex_trylock(device->state_mutex)) {
1690 set_bit(B_RS_H_DONE, &device->flags);
1691 device->start_resync_timer.expires = jiffies + HZ/5;
1692 add_timer(&device->start_resync_timer);
Philipp Reisnere64a3292011-02-05 17:34:11 +01001693 return;
1694 }
1695 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001696 mutex_lock(device->state_mutex);
Philipp Reisnere64a3292011-02-05 17:34:11 +01001697 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07001698
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001699 lock_all_resources();
1700 clear_bit(B_RS_H_DONE, &device->flags);
Philipp Reisnera7004712013-03-27 14:08:35 +01001701 /* Did some connection breakage or IO error race with us? */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001702 if (device->state.conn < C_CONNECTED
1703 || !get_ldev_if_state(device, D_NEGOTIATING)) {
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001704 unlock_all_resources();
1705 goto out;
Philipp Reisnerb411b362009-09-25 16:07:19 -07001706 }
1707
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001708 ns = drbd_read_state(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001709
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001710 ns.aftr_isp = !_drbd_may_sync_now(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001711
1712 ns.conn = side;
1713
1714 if (side == C_SYNC_TARGET)
1715 ns.disk = D_INCONSISTENT;
1716 else /* side == C_SYNC_SOURCE */
1717 ns.pdsk = D_INCONSISTENT;
1718
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001719 r = _drbd_set_state(device, ns, CS_VERBOSE, NULL);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001720 ns = drbd_read_state(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001721
1722 if (ns.conn < C_CONNECTED)
1723 r = SS_UNKNOWN_ERROR;
1724
1725 if (r == SS_SUCCESS) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001726 unsigned long tw = drbd_bm_total_weight(device);
Lars Ellenberg1d7734a2010-08-11 21:21:50 +02001727 unsigned long now = jiffies;
1728 int i;
1729
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001730 device->rs_failed = 0;
1731 device->rs_paused = 0;
1732 device->rs_same_csum = 0;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001733 device->rs_last_sect_ev = 0;
1734 device->rs_total = tw;
1735 device->rs_start = now;
Lars Ellenberg1d7734a2010-08-11 21:21:50 +02001736 for (i = 0; i < DRBD_SYNC_MARKS; i++) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001737 device->rs_mark_left[i] = tw;
1738 device->rs_mark_time[i] = now;
Lars Ellenberg1d7734a2010-08-11 21:21:50 +02001739 }
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001740 drbd_pause_after(device);
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01001741 /* Forget potentially stale cached per resync extent bit-counts.
1742 * Open coded drbd_rs_cancel_all(device), we already have IRQs
1743 * disabled, and know the disk state is ok. */
1744 spin_lock(&device->al_lock);
1745 lc_reset(device->resync);
1746 device->resync_locked = 0;
1747 device->resync_wenr = LC_FREE;
1748 spin_unlock(&device->al_lock);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001749 }
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001750 unlock_all_resources();
Lars Ellenberg5a22db82010-12-17 21:14:23 +01001751
Philipp Reisnerb411b362009-09-25 16:07:19 -07001752 if (r == SS_SUCCESS) {
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01001753 wake_up(&device->al_wait); /* for lc_reset() above */
Philipp Reisner328e0f122012-10-19 14:37:47 +02001754 /* reset rs_last_bcast when a resync or verify is started,
1755 * to deal with potential jiffies wrap. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001756 device->rs_last_bcast = jiffies - HZ;
Philipp Reisner328e0f122012-10-19 14:37:47 +02001757
Andreas Gruenbacherd0180172011-07-03 17:53:52 +02001758 drbd_info(device, "Began resync as %s (will sync %lu KB [%lu bits set]).\n",
Philipp Reisnerb411b362009-09-25 16:07:19 -07001759 drbd_conn_str(ns.conn),
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001760 (unsigned long) device->rs_total << (BM_BLOCK_SHIFT-10),
1761 (unsigned long) device->rs_total);
Lars Ellenbergaaaba342014-03-18 12:30:09 +01001762 if (side == C_SYNC_TARGET) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001763 device->bm_resync_fo = 0;
Lars Ellenbergaaaba342014-03-18 12:30:09 +01001764 device->use_csums = use_checksum_based_resync(connection, device);
1765 } else {
1766 device->use_csums = 0;
1767 }
Lars Ellenberg6c922ed2011-01-12 11:51:13 +01001768
1769 /* Since protocol 96, we must serialize drbd_gen_and_send_sync_uuid
1770 * with w_send_oos, or the sync target will get confused as to
1771 * how much bits to resync. We cannot do that always, because for an
1772 * empty resync and protocol < 95, we need to do it here, as we call
1773 * drbd_resync_finished from here in that case.
1774 * We drbd_gen_and_send_sync_uuid here for protocol < 96,
1775 * and from after_state_ch otherwise. */
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001776 if (side == C_SYNC_SOURCE && connection->agreed_pro_version < 96)
1777 drbd_gen_and_send_sync_uuid(peer_device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001778
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001779 if (connection->agreed_pro_version < 95 && device->rs_total == 0) {
Lars Ellenbergaf85e8e2010-10-07 16:07:55 +02001780 /* This still has a race (about when exactly the peers
1781 * detect connection loss) that can lead to a full sync
1782 * on next handshake. In 8.3.9 we fixed this with explicit
1783 * resync-finished notifications, but the fix
1784 * introduces a protocol change. Sleeping for some
1785 * time longer than the ping interval + timeout on the
1786 * SyncSource, to give the SyncTarget the chance to
1787 * detect connection loss, then waiting for a ping
1788 * response (implicit in drbd_resync_finished) reduces
1789 * the race considerably, but does not solve it. */
Philipp Reisner44ed1672011-04-19 17:10:19 +02001790 if (side == C_SYNC_SOURCE) {
1791 struct net_conf *nc;
1792 int timeo;
1793
1794 rcu_read_lock();
Lars Ellenberg44a4d552013-11-22 12:40:58 +01001795 nc = rcu_dereference(connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +02001796 timeo = nc->ping_int * HZ + nc->ping_timeo * HZ / 9;
1797 rcu_read_unlock();
1798 schedule_timeout_interruptible(timeo);
1799 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001800 drbd_resync_finished(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001801 }
1802
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001803 drbd_rs_controller_reset(device);
1804 /* ns.conn may already be != device->state.conn,
Philipp Reisnerb411b362009-09-25 16:07:19 -07001805 * we may have been paused in between, or become paused until
1806 * the timer triggers.
1807 * No matter, that is handled in resync_timer_fn() */
1808 if (ns.conn == C_SYNC_TARGET)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001809 mod_timer(&device->resync_timer, jiffies);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001810
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001811 drbd_md_sync(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001812 }
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001813 put_ldev(device);
Andreas Gruenbacher28bc3b82014-08-14 18:33:30 +02001814out:
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02001815 mutex_unlock(device->state_mutex);
Philipp Reisnerb411b362009-09-25 16:07:19 -07001816}
1817
Lars Ellenberge334f552014-02-11 09:30:49 +01001818static void update_on_disk_bitmap(struct drbd_device *device, bool resync_done)
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001819{
1820 struct sib_info sib = { .sib_reason = SIB_SYNC_PROGRESS, };
1821 device->rs_last_bcast = jiffies;
1822
1823 if (!get_ldev(device))
1824 return;
1825
1826 drbd_bm_write_lazy(device, 0);
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01001827 if (resync_done && is_sync_state(device->state.conn))
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001828 drbd_resync_finished(device);
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01001829
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001830 drbd_bcast_event(device, &sib);
1831 /* update timestamp, in case it took a while to write out stuff */
1832 device->rs_last_bcast = jiffies;
1833 put_ldev(device);
1834}
1835
Lars Ellenberge334f552014-02-11 09:30:49 +01001836static void drbd_ldev_destroy(struct drbd_device *device)
1837{
1838 lc_destroy(device->resync);
1839 device->resync = NULL;
1840 lc_destroy(device->act_log);
1841 device->act_log = NULL;
Andreas Gruenbacherd1b80852014-09-11 14:29:09 +02001842
1843 __acquire(local);
Lars Ellenberg63a7c8a2015-03-26 20:53:55 +01001844 drbd_backing_dev_free(device, device->ldev);
Andreas Gruenbacherd1b80852014-09-11 14:29:09 +02001845 device->ldev = NULL;
1846 __release(local);
1847
Lars Ellenberge334f552014-02-11 09:30:49 +01001848 clear_bit(GOING_DISKLESS, &device->flags);
1849 wake_up(&device->misc_wait);
1850}
1851
1852static void go_diskless(struct drbd_device *device)
1853{
1854 D_ASSERT(device, device->state.disk == D_FAILED);
1855 /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
1856 * inc/dec it frequently. Once we are D_DISKLESS, no one will touch
1857 * the protected members anymore, though, so once put_ldev reaches zero
1858 * again, it will be safe to free them. */
1859
1860 /* Try to write changed bitmap pages, read errors may have just
1861 * set some bits outside the area covered by the activity log.
1862 *
1863 * If we have an IO error during the bitmap writeout,
1864 * we will want a full sync next time, just in case.
1865 * (Do we want a specific meta data flag for this?)
1866 *
1867 * If that does not make it to stable storage either,
1868 * we cannot do anything about that anymore.
1869 *
1870 * We still need to check if both bitmap and ldev are present, we may
1871 * end up here after a failed attach, before ldev was even assigned.
1872 */
1873 if (device->bitmap && device->ldev) {
1874 /* An interrupted resync or similar is allowed to recounts bits
1875 * while we detach.
1876 * Any modifications would not be expected anymore, though.
1877 */
1878 if (drbd_bitmap_io_from_worker(device, drbd_bm_write,
1879 "detach", BM_LOCKED_TEST_ALLOWED)) {
1880 if (test_bit(WAS_READ_ERROR, &device->flags)) {
1881 drbd_md_set_flag(device, MDF_FULL_SYNC);
1882 drbd_md_sync(device);
1883 }
1884 }
1885 }
1886
1887 drbd_force_state(device, NS(disk, D_DISKLESS));
1888}
1889
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001890static int do_md_sync(struct drbd_device *device)
1891{
1892 drbd_warn(device, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
1893 drbd_md_sync(device);
1894 return 0;
1895}
1896
Lars Ellenberg944410e2014-05-06 15:02:05 +02001897/* only called from drbd_worker thread, no locking */
1898void __update_timing_details(
1899 struct drbd_thread_timing_details *tdp,
1900 unsigned int *cb_nr,
1901 void *cb,
1902 const char *fn, const unsigned int line)
1903{
1904 unsigned int i = *cb_nr % DRBD_THREAD_DETAILS_HIST;
1905 struct drbd_thread_timing_details *td = tdp + i;
1906
1907 td->start_jif = jiffies;
1908 td->cb_addr = cb;
1909 td->caller_fn = fn;
1910 td->line = line;
1911 td->cb_nr = *cb_nr;
1912
1913 i = (i+1) % DRBD_THREAD_DETAILS_HIST;
1914 td = tdp + i;
1915 memset(td, 0, sizeof(*td));
1916
1917 ++(*cb_nr);
1918}
1919
Lars Ellenberge334f552014-02-11 09:30:49 +01001920static void do_device_work(struct drbd_device *device, const unsigned long todo)
1921{
Andreas Gruenbacherb47a06d2014-09-11 14:29:10 +02001922 if (test_bit(MD_SYNC, &todo))
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001923 do_md_sync(device);
Andreas Gruenbacherb47a06d2014-09-11 14:29:10 +02001924 if (test_bit(RS_DONE, &todo) ||
1925 test_bit(RS_PROGRESS, &todo))
1926 update_on_disk_bitmap(device, test_bit(RS_DONE, &todo));
1927 if (test_bit(GO_DISKLESS, &todo))
Lars Ellenberge334f552014-02-11 09:30:49 +01001928 go_diskless(device);
Andreas Gruenbacherb47a06d2014-09-11 14:29:10 +02001929 if (test_bit(DESTROY_DISK, &todo))
Lars Ellenberge334f552014-02-11 09:30:49 +01001930 drbd_ldev_destroy(device);
Andreas Gruenbacherb47a06d2014-09-11 14:29:10 +02001931 if (test_bit(RS_START, &todo))
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001932 do_start_resync(device);
Lars Ellenberge334f552014-02-11 09:30:49 +01001933}
1934
1935#define DRBD_DEVICE_WORK_MASK \
1936 ((1UL << GO_DISKLESS) \
1937 |(1UL << DESTROY_DISK) \
Lars Ellenbergac0acb92014-02-11 09:47:58 +01001938 |(1UL << MD_SYNC) \
1939 |(1UL << RS_START) \
Lars Ellenberge334f552014-02-11 09:30:49 +01001940 |(1UL << RS_PROGRESS) \
1941 |(1UL << RS_DONE) \
1942 )
1943
1944static unsigned long get_work_bits(unsigned long *flags)
1945{
1946 unsigned long old, new;
1947 do {
1948 old = *flags;
1949 new = old & ~DRBD_DEVICE_WORK_MASK;
1950 } while (cmpxchg(flags, old, new) != old);
1951 return old & DRBD_DEVICE_WORK_MASK;
1952}
1953
1954static void do_unqueued_work(struct drbd_connection *connection)
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001955{
1956 struct drbd_peer_device *peer_device;
1957 int vnr;
1958
1959 rcu_read_lock();
1960 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
1961 struct drbd_device *device = peer_device->device;
Lars Ellenberge334f552014-02-11 09:30:49 +01001962 unsigned long todo = get_work_bits(&device->flags);
1963 if (!todo)
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001964 continue;
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01001965
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001966 kref_get(&device->kref);
1967 rcu_read_unlock();
Lars Ellenberge334f552014-02-11 09:30:49 +01001968 do_device_work(device, todo);
Lars Ellenbergc7a58db2013-12-20 11:39:48 +01001969 kref_put(&device->kref, drbd_destroy_device);
1970 rcu_read_lock();
1971 }
1972 rcu_read_unlock();
1973}
1974
Rashika Kheriaa186e472013-12-19 15:06:10 +05301975static bool dequeue_work_batch(struct drbd_work_queue *queue, struct list_head *work_list)
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02001976{
1977 spin_lock_irq(&queue->q_lock);
Lars Ellenberg15e26f62014-04-28 11:43:21 +02001978 list_splice_tail_init(&queue->q, work_list);
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02001979 spin_unlock_irq(&queue->q_lock);
1980 return !list_empty(work_list);
1981}
1982
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02001983static void wait_for_work(struct drbd_connection *connection, struct list_head *work_list)
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001984{
1985 DEFINE_WAIT(wait);
1986 struct net_conf *nc;
1987 int uncork, cork;
1988
Lars Ellenbergabde9cc2014-09-11 14:29:11 +02001989 dequeue_work_batch(&connection->sender_work, work_list);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01001990 if (!list_empty(work_list))
1991 return;
1992
1993 /* Still nothing to do?
1994 * Maybe we still need to close the current epoch,
1995 * even if no new requests are queued yet.
1996 *
1997 * Also, poke TCP, just in case.
1998 * Then wait for new work (or signal). */
1999 rcu_read_lock();
2000 nc = rcu_dereference(connection->net_conf);
2001 uncork = nc ? nc->tcp_cork : 0;
2002 rcu_read_unlock();
2003 if (uncork) {
2004 mutex_lock(&connection->data.mutex);
2005 if (connection->data.socket)
2006 drbd_tcp_uncork(connection->data.socket);
2007 mutex_unlock(&connection->data.mutex);
2008 }
2009
2010 for (;;) {
2011 int send_barrier;
2012 prepare_to_wait(&connection->sender_work.q_wait, &wait, TASK_INTERRUPTIBLE);
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002013 spin_lock_irq(&connection->resource->req_lock);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01002014 spin_lock(&connection->sender_work.q_lock); /* FIXME get rid of this one? */
Lars Ellenbergbc317a92012-08-22 11:47:14 +02002015 if (!list_empty(&connection->sender_work.q))
Lars Ellenberg4dd726f2014-02-11 11:15:36 +01002016 list_splice_tail_init(&connection->sender_work.q, work_list);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01002017 spin_unlock(&connection->sender_work.q_lock); /* FIXME get rid of this one? */
2018 if (!list_empty(work_list) || signal_pending(current)) {
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002019 spin_unlock_irq(&connection->resource->req_lock);
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01002020 break;
2021 }
Lars Ellenbergf9c78122014-04-28 18:43:29 +02002022
2023 /* We found nothing new to do, no to-be-communicated request,
2024 * no other work item. We may still need to close the last
2025 * epoch. Next incoming request epoch will be connection ->
2026 * current transfer log epoch number. If that is different
2027 * from the epoch of the last request we communicated, it is
2028 * safe to send the epoch separating barrier now.
2029 */
2030 send_barrier =
2031 atomic_read(&connection->current_tle_nr) !=
2032 connection->send.current_epoch_nr;
Andreas Gruenbacher05008132011-07-07 14:19:42 +02002033 spin_unlock_irq(&connection->resource->req_lock);
Lars Ellenbergf9c78122014-04-28 18:43:29 +02002034
2035 if (send_barrier)
2036 maybe_send_barrier(connection,
2037 connection->send.current_epoch_nr + 1);
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01002038
Lars Ellenberge334f552014-02-11 09:30:49 +01002039 if (test_bit(DEVICE_WORK_PENDING, &connection->flags))
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01002040 break;
2041
Lars Ellenberga80ca1a2013-12-27 17:17:25 +01002042 /* drbd_send() may have called flush_signals() */
2043 if (get_t_state(&connection->worker) != RUNNING)
2044 break;
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01002045
Lars Ellenbergb6dd1a82011-11-28 15:04:49 +01002046 schedule();
2047 /* may be woken up for other things but new work, too,
2048 * e.g. if the current epoch got closed.
2049 * In which case we send the barrier above. */
2050 }
2051 finish_wait(&connection->sender_work.q_wait, &wait);
2052
2053 /* someone may have changed the config while we have been waiting above. */
2054 rcu_read_lock();
2055 nc = rcu_dereference(connection->net_conf);
2056 cork = nc ? nc->tcp_cork : 0;
2057 rcu_read_unlock();
2058 mutex_lock(&connection->data.mutex);
2059 if (connection->data.socket) {
2060 if (cork)
2061 drbd_tcp_cork(connection->data.socket);
2062 else if (!uncork)
2063 drbd_tcp_uncork(connection->data.socket);
2064 }
2065 mutex_unlock(&connection->data.mutex);
2066}
2067
Philipp Reisnerb411b362009-09-25 16:07:19 -07002068int drbd_worker(struct drbd_thread *thi)
2069{
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002070 struct drbd_connection *connection = thi->connection;
Andreas Gruenbacher6db7e502011-08-26 23:50:08 +02002071 struct drbd_work *w = NULL;
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02002072 struct drbd_peer_device *peer_device;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002073 LIST_HEAD(work_list);
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02002074 int vnr;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002075
Andreas Gruenbachere77a0a52011-01-25 15:43:39 +01002076 while (get_t_state(thi) == RUNNING) {
Philipp Reisner80822282011-02-08 12:46:30 +01002077 drbd_thread_current_set_cpu(thi);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002078
Lars Ellenberg944410e2014-05-06 15:02:05 +02002079 if (list_empty(&work_list)) {
2080 update_worker_timing_details(connection, wait_for_work);
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002081 wait_for_work(connection, &work_list);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002082 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07002083
Lars Ellenberg944410e2014-05-06 15:02:05 +02002084 if (test_and_clear_bit(DEVICE_WORK_PENDING, &connection->flags)) {
2085 update_worker_timing_details(connection, do_unqueued_work);
Lars Ellenberge334f552014-02-11 09:30:49 +01002086 do_unqueued_work(connection);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002087 }
Lars Ellenberg5ab7d2c2014-01-27 15:58:22 +01002088
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02002089 if (signal_pending(current)) {
Philipp Reisnerb411b362009-09-25 16:07:19 -07002090 flush_signals(current);
Philipp Reisner19393e12011-02-09 10:09:07 +01002091 if (get_t_state(thi) == RUNNING) {
Andreas Gruenbacher1ec861e2011-07-06 11:01:44 +02002092 drbd_warn(connection, "Worker got an unexpected signal\n");
Philipp Reisnerb411b362009-09-25 16:07:19 -07002093 continue;
Philipp Reisner19393e12011-02-09 10:09:07 +01002094 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07002095 break;
2096 }
2097
Andreas Gruenbachere77a0a52011-01-25 15:43:39 +01002098 if (get_t_state(thi) != RUNNING)
Philipp Reisnerb411b362009-09-25 16:07:19 -07002099 break;
Philipp Reisnerb411b362009-09-25 16:07:19 -07002100
Lars Ellenberg729e8b82014-09-11 14:29:12 +02002101 if (!list_empty(&work_list)) {
Andreas Gruenbacher6db7e502011-08-26 23:50:08 +02002102 w = list_first_entry(&work_list, struct drbd_work, list);
2103 list_del_init(&w->list);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002104 update_worker_timing_details(connection, w->cb);
Andreas Gruenbacher6db7e502011-08-26 23:50:08 +02002105 if (w->cb(w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02002106 continue;
Andreas Gruenbacherbde89a92011-05-30 16:32:41 +02002107 if (connection->cstate >= C_WF_REPORT_PARAMS)
2108 conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
Philipp Reisnerb411b362009-09-25 16:07:19 -07002109 }
2110 }
Philipp Reisnerb411b362009-09-25 16:07:19 -07002111
Lars Ellenberg8c0785a2011-10-19 11:50:57 +02002112 do {
Lars Ellenberg944410e2014-05-06 15:02:05 +02002113 if (test_and_clear_bit(DEVICE_WORK_PENDING, &connection->flags)) {
2114 update_worker_timing_details(connection, do_unqueued_work);
Lars Ellenberge334f552014-02-11 09:30:49 +01002115 do_unqueued_work(connection);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002116 }
Lars Ellenberg729e8b82014-09-11 14:29:12 +02002117 if (!list_empty(&work_list)) {
Andreas Gruenbacher6db7e502011-08-26 23:50:08 +02002118 w = list_first_entry(&work_list, struct drbd_work, list);
2119 list_del_init(&w->list);
Lars Ellenberg944410e2014-05-06 15:02:05 +02002120 update_worker_timing_details(connection, w->cb);
Andreas Gruenbacher6db7e502011-08-26 23:50:08 +02002121 w->cb(w, 1);
Lars Ellenberg729e8b82014-09-11 14:29:12 +02002122 } else
2123 dequeue_work_batch(&connection->sender_work, &work_list);
Lars Ellenberge334f552014-02-11 09:30:49 +01002124 } while (!list_empty(&work_list) || test_bit(DEVICE_WORK_PENDING, &connection->flags));
Philipp Reisnerb411b362009-09-25 16:07:19 -07002125
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02002126 rcu_read_lock();
Andreas Gruenbacherc06ece62011-06-21 17:23:59 +02002127 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
2128 struct drbd_device *device = peer_device->device;
Andreas Gruenbacher0b0ba1e2011-06-27 16:23:33 +02002129 D_ASSERT(device, device->state.disk == D_DISKLESS && device->state.conn == C_STANDALONE);
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002130 kref_get(&device->kref);
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02002131 rcu_read_unlock();
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +02002132 drbd_device_cleanup(device);
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +02002133 kref_put(&device->kref, drbd_destroy_device);
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02002134 rcu_read_lock();
Philipp Reisner0e29d162011-02-18 14:23:11 +01002135 }
Philipp Reisnerc141ebd2011-05-05 16:13:10 +02002136 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -07002137
2138 return 0;
2139}