xref: /linux/drivers/block/drbd/drbd_int.h (revision d40e567149c7ac250344d1537261c87b2c3e852c)
1b411b363SPhilipp Reisner /*
2b411b363SPhilipp Reisner   drbd_int.h
3b411b363SPhilipp Reisner 
4b411b363SPhilipp Reisner   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
5b411b363SPhilipp Reisner 
6b411b363SPhilipp Reisner   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
7b411b363SPhilipp Reisner   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
8b411b363SPhilipp Reisner   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
9b411b363SPhilipp Reisner 
10b411b363SPhilipp Reisner   drbd is free software; you can redistribute it and/or modify
11b411b363SPhilipp Reisner   it under the terms of the GNU General Public License as published by
12b411b363SPhilipp Reisner   the Free Software Foundation; either version 2, or (at your option)
13b411b363SPhilipp Reisner   any later version.
14b411b363SPhilipp Reisner 
15b411b363SPhilipp Reisner   drbd is distributed in the hope that it will be useful,
16b411b363SPhilipp Reisner   but WITHOUT ANY WARRANTY; without even the implied warranty of
17b411b363SPhilipp Reisner   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
18b411b363SPhilipp Reisner   GNU General Public License for more details.
19b411b363SPhilipp Reisner 
20b411b363SPhilipp Reisner   You should have received a copy of the GNU General Public License
21b411b363SPhilipp Reisner   along with drbd; see the file COPYING.  If not, write to
22b411b363SPhilipp Reisner   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23b411b363SPhilipp Reisner 
24b411b363SPhilipp Reisner */
25b411b363SPhilipp Reisner 
26b411b363SPhilipp Reisner #ifndef _DRBD_INT_H
27b411b363SPhilipp Reisner #define _DRBD_INT_H
28b411b363SPhilipp Reisner 
29b411b363SPhilipp Reisner #include <linux/compiler.h>
30b411b363SPhilipp Reisner #include <linux/types.h>
31b411b363SPhilipp Reisner #include <linux/list.h>
32b411b363SPhilipp Reisner #include <linux/sched.h>
33b411b363SPhilipp Reisner #include <linux/bitops.h>
34b411b363SPhilipp Reisner #include <linux/slab.h>
35b411b363SPhilipp Reisner #include <linux/crypto.h>
36132cc538SRandy Dunlap #include <linux/ratelimit.h>
37b411b363SPhilipp Reisner #include <linux/tcp.h>
38b411b363SPhilipp Reisner #include <linux/mutex.h>
39b411b363SPhilipp Reisner #include <linux/major.h>
40b411b363SPhilipp Reisner #include <linux/blkdev.h>
41b411b363SPhilipp Reisner #include <linux/genhd.h>
42062e879cSPhilipp Reisner #include <linux/idr.h>
43b411b363SPhilipp Reisner #include <net/tcp.h>
44b411b363SPhilipp Reisner #include <linux/lru_cache.h>
4570c71606SPaul Gortmaker #include <linux/prefetch.h>
463b98c0c2SLars Ellenberg #include <linux/drbd_genl_api.h>
47b8907339SPhilipp Reisner #include <linux/drbd.h>
48d9f65229SAndreas Gruenbacher #include "drbd_strings.h"
49b8907339SPhilipp Reisner #include "drbd_state.h"
50a3603a6eSAndreas Gruenbacher #include "drbd_protocol.h"
51b411b363SPhilipp Reisner 
52b411b363SPhilipp Reisner #ifdef __CHECKER__
53b411b363SPhilipp Reisner # define __protected_by(x)       __attribute__((require_context(x,1,999,"rdwr")))
54b411b363SPhilipp Reisner # define __protected_read_by(x)  __attribute__((require_context(x,1,999,"read")))
55b411b363SPhilipp Reisner # define __protected_write_by(x) __attribute__((require_context(x,1,999,"write")))
56b411b363SPhilipp Reisner # define __must_hold(x)       __attribute__((context(x,1,1), require_context(x,1,999,"call")))
57b411b363SPhilipp Reisner #else
58b411b363SPhilipp Reisner # define __protected_by(x)
59b411b363SPhilipp Reisner # define __protected_read_by(x)
60b411b363SPhilipp Reisner # define __protected_write_by(x)
61b411b363SPhilipp Reisner # define __must_hold(x)
62b411b363SPhilipp Reisner #endif
63b411b363SPhilipp Reisner 
64b411b363SPhilipp Reisner #define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0)
65b411b363SPhilipp Reisner 
66b411b363SPhilipp Reisner /* module parameter, defined in drbd_main.c */
67b411b363SPhilipp Reisner extern unsigned int minor_count;
6890ab5ee9SRusty Russell extern bool disable_sendpage;
6990ab5ee9SRusty Russell extern bool allow_oos;
70b30ab791SAndreas Gruenbacher void tl_abort_disk_io(struct drbd_device *device);
71b411b363SPhilipp Reisner 
72b411b363SPhilipp Reisner #ifdef CONFIG_DRBD_FAULT_INJECTION
73b411b363SPhilipp Reisner extern int enable_faults;
74b411b363SPhilipp Reisner extern int fault_rate;
75b411b363SPhilipp Reisner extern int fault_devs;
76b411b363SPhilipp Reisner #endif
77b411b363SPhilipp Reisner 
78b411b363SPhilipp Reisner extern char usermode_helper[];
79b411b363SPhilipp Reisner 
80b411b363SPhilipp Reisner 
81b411b363SPhilipp Reisner /* I don't remember why XCPU ...
82b411b363SPhilipp Reisner  * This is used to wake the asender,
83b411b363SPhilipp Reisner  * and to interrupt sending the sending task
84b411b363SPhilipp Reisner  * on disconnect.
85b411b363SPhilipp Reisner  */
86b411b363SPhilipp Reisner #define DRBD_SIG SIGXCPU
87b411b363SPhilipp Reisner 
88b411b363SPhilipp Reisner /* This is used to stop/restart our threads.
89b411b363SPhilipp Reisner  * Cannot use SIGTERM nor SIGKILL, since these
90b411b363SPhilipp Reisner  * are sent out by init on runlevel changes
91b411b363SPhilipp Reisner  * I choose SIGHUP for now.
92b411b363SPhilipp Reisner  */
93b411b363SPhilipp Reisner #define DRBD_SIGKILL SIGHUP
94b411b363SPhilipp Reisner 
95b411b363SPhilipp Reisner #define ID_IN_SYNC      (4711ULL)
96b411b363SPhilipp Reisner #define ID_OUT_OF_SYNC  (4712ULL)
97b411b363SPhilipp Reisner #define ID_SYNCER (-1ULL)
98579b57edSAndreas Gruenbacher 
994a23f264SPhilipp Reisner #define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL)
100b411b363SPhilipp Reisner 
10154761697SAndreas Gruenbacher struct drbd_device;
102bde89a9eSAndreas Gruenbacher struct drbd_connection;
103b411b363SPhilipp Reisner 
1043b52beffSAndreas Gruenbacher #define __drbd_printk_device(level, device, fmt, args...) \
1053b52beffSAndreas Gruenbacher 	dev_printk(level, disk_to_dev((device)->vdisk), fmt, ## args)
1063b52beffSAndreas Gruenbacher #define __drbd_printk_peer_device(level, peer_device, fmt, args...) \
1073b52beffSAndreas Gruenbacher 	dev_printk(level, disk_to_dev((peer_device)->device->vdisk), fmt, ## args)
1083b52beffSAndreas Gruenbacher #define __drbd_printk_resource(level, resource, fmt, args...) \
1093b52beffSAndreas Gruenbacher 	printk(level "drbd %s: " fmt, (resource)->name, ## args)
1103b52beffSAndreas Gruenbacher #define __drbd_printk_connection(level, connection, fmt, args...) \
1113b52beffSAndreas Gruenbacher 	printk(level "drbd %s: " fmt, (connection)->resource->name, ## args)
112b411b363SPhilipp Reisner 
1133b52beffSAndreas Gruenbacher void drbd_printk_with_wrong_object_type(void);
1143b52beffSAndreas Gruenbacher 
1153b52beffSAndreas Gruenbacher #define __drbd_printk_if_same_type(obj, type, func, level, fmt, args...) \
1163b52beffSAndreas Gruenbacher 	(__builtin_types_compatible_p(typeof(obj), type) || \
1173b52beffSAndreas Gruenbacher 	 __builtin_types_compatible_p(typeof(obj), const type)), \
1183b52beffSAndreas Gruenbacher 	func(level, (const type)(obj), fmt, ## args)
1193b52beffSAndreas Gruenbacher 
1203b52beffSAndreas Gruenbacher #define drbd_printk(level, obj, fmt, args...) \
1213b52beffSAndreas Gruenbacher 	__builtin_choose_expr( \
1223b52beffSAndreas Gruenbacher 	  __drbd_printk_if_same_type(obj, struct drbd_device *, \
1233b52beffSAndreas Gruenbacher 			     __drbd_printk_device, level, fmt, ## args), \
1243b52beffSAndreas Gruenbacher 	  __builtin_choose_expr( \
1253b52beffSAndreas Gruenbacher 	    __drbd_printk_if_same_type(obj, struct drbd_resource *, \
1263b52beffSAndreas Gruenbacher 			       __drbd_printk_resource, level, fmt, ## args), \
1273b52beffSAndreas Gruenbacher 	    __builtin_choose_expr( \
1283b52beffSAndreas Gruenbacher 	      __drbd_printk_if_same_type(obj, struct drbd_connection *, \
1293b52beffSAndreas Gruenbacher 				 __drbd_printk_connection, level, fmt, ## args), \
1303b52beffSAndreas Gruenbacher 	      __builtin_choose_expr( \
1313b52beffSAndreas Gruenbacher 		__drbd_printk_if_same_type(obj, struct drbd_peer_device *, \
1323b52beffSAndreas Gruenbacher 				 __drbd_printk_peer_device, level, fmt, ## args), \
1333b52beffSAndreas Gruenbacher 		drbd_printk_with_wrong_object_type()))))
1343b52beffSAndreas Gruenbacher 
1353b52beffSAndreas Gruenbacher #define drbd_dbg(obj, fmt, args...) \
1363b52beffSAndreas Gruenbacher 	drbd_printk(KERN_DEBUG, obj, fmt, ## args)
1373b52beffSAndreas Gruenbacher #define drbd_alert(obj, fmt, args...) \
1383b52beffSAndreas Gruenbacher 	drbd_printk(KERN_ALERT, obj, fmt, ## args)
1393b52beffSAndreas Gruenbacher #define drbd_err(obj, fmt, args...) \
1403b52beffSAndreas Gruenbacher 	drbd_printk(KERN_ERR, obj, fmt, ## args)
1413b52beffSAndreas Gruenbacher #define drbd_warn(obj, fmt, args...) \
1423b52beffSAndreas Gruenbacher 	drbd_printk(KERN_WARNING, obj, fmt, ## args)
1433b52beffSAndreas Gruenbacher #define drbd_info(obj, fmt, args...) \
1443b52beffSAndreas Gruenbacher 	drbd_printk(KERN_INFO, obj, fmt, ## args)
1453b52beffSAndreas Gruenbacher #define drbd_emerg(obj, fmt, args...) \
1463b52beffSAndreas Gruenbacher 	drbd_printk(KERN_EMERG, obj, fmt, ## args)
147d0180171SAndreas Gruenbacher 
148d0180171SAndreas Gruenbacher #define dynamic_drbd_dbg(device, fmt, args...) \
149d0180171SAndreas Gruenbacher 	dynamic_dev_dbg(disk_to_dev(device->vdisk), fmt, ## args)
150b411b363SPhilipp Reisner 
1510b0ba1efSAndreas Gruenbacher #define D_ASSERT(device, exp)	do { \
1520b0ba1efSAndreas Gruenbacher 	if (!(exp)) \
1530b0ba1efSAndreas Gruenbacher 		drbd_err(device, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__); \
1540b0ba1efSAndreas Gruenbacher 	} while (0)
155b411b363SPhilipp Reisner 
156841ce241SAndreas Gruenbacher /**
157841ce241SAndreas Gruenbacher  * expect  -  Make an assertion
158841ce241SAndreas Gruenbacher  *
159841ce241SAndreas Gruenbacher  * Unlike the assert macro, this macro returns a boolean result.
160841ce241SAndreas Gruenbacher  */
161841ce241SAndreas Gruenbacher #define expect(exp) ({								\
162841ce241SAndreas Gruenbacher 		bool _bool = (exp);						\
163841ce241SAndreas Gruenbacher 		if (!_bool)							\
164d0180171SAndreas Gruenbacher 			drbd_err(device, "ASSERTION %s FAILED in %s\n",		\
165841ce241SAndreas Gruenbacher 			        #exp, __func__);				\
166841ce241SAndreas Gruenbacher 		_bool;								\
167841ce241SAndreas Gruenbacher 		})
168b411b363SPhilipp Reisner 
169b411b363SPhilipp Reisner /* Defines to control fault insertion */
170b411b363SPhilipp Reisner enum {
171b411b363SPhilipp Reisner 	DRBD_FAULT_MD_WR = 0,	/* meta data write */
172b411b363SPhilipp Reisner 	DRBD_FAULT_MD_RD = 1,	/*           read  */
173b411b363SPhilipp Reisner 	DRBD_FAULT_RS_WR = 2,	/* resync          */
174b411b363SPhilipp Reisner 	DRBD_FAULT_RS_RD = 3,
175b411b363SPhilipp Reisner 	DRBD_FAULT_DT_WR = 4,	/* data            */
176b411b363SPhilipp Reisner 	DRBD_FAULT_DT_RD = 5,
177b411b363SPhilipp Reisner 	DRBD_FAULT_DT_RA = 6,	/* data read ahead */
178b411b363SPhilipp Reisner 	DRBD_FAULT_BM_ALLOC = 7,	/* bitmap allocation */
179b411b363SPhilipp Reisner 	DRBD_FAULT_AL_EE = 8,	/* alloc ee */
1806b4388acSPhilipp Reisner 	DRBD_FAULT_RECEIVE = 9, /* Changes some bytes upon receiving a [rs]data block */
181b411b363SPhilipp Reisner 
182b411b363SPhilipp Reisner 	DRBD_FAULT_MAX,
183b411b363SPhilipp Reisner };
184b411b363SPhilipp Reisner 
185b411b363SPhilipp Reisner extern unsigned int
186b30ab791SAndreas Gruenbacher _drbd_insert_fault(struct drbd_device *device, unsigned int type);
1870cf9d27eSAndreas Gruenbacher 
188b411b363SPhilipp Reisner static inline int
189b30ab791SAndreas Gruenbacher drbd_insert_fault(struct drbd_device *device, unsigned int type) {
1900cf9d27eSAndreas Gruenbacher #ifdef CONFIG_DRBD_FAULT_INJECTION
191b411b363SPhilipp Reisner 	return fault_rate &&
192b411b363SPhilipp Reisner 		(enable_faults & (1<<type)) &&
193b30ab791SAndreas Gruenbacher 		_drbd_insert_fault(device, type);
194b411b363SPhilipp Reisner #else
1950cf9d27eSAndreas Gruenbacher 	return 0;
196b411b363SPhilipp Reisner #endif
1970cf9d27eSAndreas Gruenbacher }
198b411b363SPhilipp Reisner 
199b411b363SPhilipp Reisner /* integer division, round _UP_ to the next integer */
200b411b363SPhilipp Reisner #define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
201b411b363SPhilipp Reisner /* usual integer division */
202b411b363SPhilipp Reisner #define div_floor(A, B) ((A)/(B))
203b411b363SPhilipp Reisner 
204b411b363SPhilipp Reisner extern struct ratelimit_state drbd_ratelimit_state;
20505a10ec7SAndreas Gruenbacher extern struct idr drbd_devices; /* RCU, updates: genl_lock() */
20677c556f6SAndreas Gruenbacher extern struct list_head drbd_resources; /* RCU, updates: genl_lock() */
207b411b363SPhilipp Reisner 
208d8763023SAndreas Gruenbacher extern const char *cmdname(enum drbd_packet cmd);
209b411b363SPhilipp Reisner 
210b411b363SPhilipp Reisner /* for sending/receiving the bitmap,
211b411b363SPhilipp Reisner  * possibly in some encoding scheme */
212b411b363SPhilipp Reisner struct bm_xfer_ctx {
213b411b363SPhilipp Reisner 	/* "const"
214b411b363SPhilipp Reisner 	 * stores total bits and long words
215b411b363SPhilipp Reisner 	 * of the bitmap, so we don't need to
216b411b363SPhilipp Reisner 	 * call the accessor functions over and again. */
217b411b363SPhilipp Reisner 	unsigned long bm_bits;
218b411b363SPhilipp Reisner 	unsigned long bm_words;
219b411b363SPhilipp Reisner 	/* during xfer, current position within the bitmap */
220b411b363SPhilipp Reisner 	unsigned long bit_offset;
221b411b363SPhilipp Reisner 	unsigned long word_offset;
222b411b363SPhilipp Reisner 
223b411b363SPhilipp Reisner 	/* statistics; index: (h->command == P_BITMAP) */
224b411b363SPhilipp Reisner 	unsigned packets[2];
225b411b363SPhilipp Reisner 	unsigned bytes[2];
226b411b363SPhilipp Reisner };
227b411b363SPhilipp Reisner 
228b30ab791SAndreas Gruenbacher extern void INFO_bm_xfer_stats(struct drbd_device *device,
229b411b363SPhilipp Reisner 		const char *direction, struct bm_xfer_ctx *c);
230b411b363SPhilipp Reisner 
231b411b363SPhilipp Reisner static inline void bm_xfer_ctx_bit_to_word_offset(struct bm_xfer_ctx *c)
232b411b363SPhilipp Reisner {
233b411b363SPhilipp Reisner 	/* word_offset counts "native long words" (32 or 64 bit),
234b411b363SPhilipp Reisner 	 * aligned at 64 bit.
235b411b363SPhilipp Reisner 	 * Encoded packet may end at an unaligned bit offset.
236b411b363SPhilipp Reisner 	 * In case a fallback clear text packet is transmitted in
237b411b363SPhilipp Reisner 	 * between, we adjust this offset back to the last 64bit
238b411b363SPhilipp Reisner 	 * aligned "native long word", which makes coding and decoding
239b411b363SPhilipp Reisner 	 * the plain text bitmap much more convenient.  */
240b411b363SPhilipp Reisner #if BITS_PER_LONG == 64
241b411b363SPhilipp Reisner 	c->word_offset = c->bit_offset >> 6;
242b411b363SPhilipp Reisner #elif BITS_PER_LONG == 32
243b411b363SPhilipp Reisner 	c->word_offset = c->bit_offset >> 5;
244b411b363SPhilipp Reisner 	c->word_offset &= ~(1UL);
245b411b363SPhilipp Reisner #else
246b411b363SPhilipp Reisner # error "unsupported BITS_PER_LONG"
247b411b363SPhilipp Reisner #endif
248b411b363SPhilipp Reisner }
249b411b363SPhilipp Reisner 
250bde89a9eSAndreas Gruenbacher extern unsigned int drbd_header_size(struct drbd_connection *connection);
251b411b363SPhilipp Reisner 
252b411b363SPhilipp Reisner /**********************************************************************/
253b411b363SPhilipp Reisner enum drbd_thread_state {
254e77a0a5cSAndreas Gruenbacher 	NONE,
255e77a0a5cSAndreas Gruenbacher 	RUNNING,
256e77a0a5cSAndreas Gruenbacher 	EXITING,
257e77a0a5cSAndreas Gruenbacher 	RESTARTING
258b411b363SPhilipp Reisner };
259b411b363SPhilipp Reisner 
260b411b363SPhilipp Reisner struct drbd_thread {
261b411b363SPhilipp Reisner 	spinlock_t t_lock;
262b411b363SPhilipp Reisner 	struct task_struct *task;
263b411b363SPhilipp Reisner 	struct completion stop;
264b411b363SPhilipp Reisner 	enum drbd_thread_state t_state;
265b411b363SPhilipp Reisner 	int (*function) (struct drbd_thread *);
2662457b6d5SAndreas Gruenbacher 	struct drbd_resource *resource;
267bde89a9eSAndreas Gruenbacher 	struct drbd_connection *connection;
268b411b363SPhilipp Reisner 	int reset_cpu_mask;
269c60b0251SAndreas Gruenbacher 	const char *name;
270b411b363SPhilipp Reisner };
271b411b363SPhilipp Reisner 
272b411b363SPhilipp Reisner static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
273b411b363SPhilipp Reisner {
274b411b363SPhilipp Reisner 	/* THINK testing the t_state seems to be uncritical in all cases
275b411b363SPhilipp Reisner 	 * (but thread_{start,stop}), so we can read it *without* the lock.
276b411b363SPhilipp Reisner 	 *	--lge */
277b411b363SPhilipp Reisner 
278b411b363SPhilipp Reisner 	smp_rmb();
279b411b363SPhilipp Reisner 	return thi->t_state;
280b411b363SPhilipp Reisner }
281b411b363SPhilipp Reisner 
282b411b363SPhilipp Reisner struct drbd_work {
283b411b363SPhilipp Reisner 	struct list_head list;
284309a8348SAndreas Gruenbacher 	int (*cb)(struct drbd_work *, int cancel);
28500d56944SPhilipp Reisner };
28684b8c06bSAndreas Gruenbacher 
28784b8c06bSAndreas Gruenbacher struct drbd_device_work {
28884b8c06bSAndreas Gruenbacher 	struct drbd_work w;
28984b8c06bSAndreas Gruenbacher 	struct drbd_device *device;
290b411b363SPhilipp Reisner };
291b411b363SPhilipp Reisner 
292ace652acSAndreas Gruenbacher #include "drbd_interval.h"
293ace652acSAndreas Gruenbacher 
29454761697SAndreas Gruenbacher extern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *);
2957be8da07SAndreas Gruenbacher 
296b411b363SPhilipp Reisner struct drbd_request {
297b411b363SPhilipp Reisner 	struct drbd_work w;
29884b8c06bSAndreas Gruenbacher 	struct drbd_device *device;
299b411b363SPhilipp Reisner 
300b411b363SPhilipp Reisner 	/* if local IO is not allowed, will be NULL.
301b411b363SPhilipp Reisner 	 * if local IO _is_ allowed, holds the locally submitted bio clone,
302b411b363SPhilipp Reisner 	 * or, after local IO completion, the ERR_PTR(error).
303fcefa62eSAndreas Gruenbacher 	 * see drbd_request_endio(). */
304b411b363SPhilipp Reisner 	struct bio *private_bio;
305b411b363SPhilipp Reisner 
306ace652acSAndreas Gruenbacher 	struct drbd_interval i;
307b411b363SPhilipp Reisner 
308b6dd1a89SLars Ellenberg 	/* epoch: used to check on "completion" whether this req was in
309b411b363SPhilipp Reisner 	 * the current epoch, and we therefore have to close it,
310b6dd1a89SLars Ellenberg 	 * causing a p_barrier packet to be send, starting a new epoch.
311b6dd1a89SLars Ellenberg 	 *
312b6dd1a89SLars Ellenberg 	 * This corresponds to "barrier" in struct p_barrier[_ack],
313b6dd1a89SLars Ellenberg 	 * and to "barrier_nr" in struct drbd_epoch (and various
314b6dd1a89SLars Ellenberg 	 * comments/function parameters/local variable names).
315b411b363SPhilipp Reisner 	 */
316b6dd1a89SLars Ellenberg 	unsigned int epoch;
317b411b363SPhilipp Reisner 
318b411b363SPhilipp Reisner 	struct list_head tl_requests; /* ring list in the transfer log */
319b411b363SPhilipp Reisner 	struct bio *master_bio;       /* master bio pointer */
320b411b363SPhilipp Reisner 	unsigned long start_time;
321b406777eSLars Ellenberg 
322b406777eSLars Ellenberg 	/* once it hits 0, we may complete the master_bio */
323b406777eSLars Ellenberg 	atomic_t completion_ref;
324b406777eSLars Ellenberg 	/* once it hits 0, we may destroy this drbd_request object */
325b406777eSLars Ellenberg 	struct kref kref;
326a0d856dfSLars Ellenberg 
327a0d856dfSLars Ellenberg 	unsigned rq_state; /* see comments above _req_mod() */
328b411b363SPhilipp Reisner };
329b411b363SPhilipp Reisner 
330b411b363SPhilipp Reisner struct drbd_epoch {
331bde89a9eSAndreas Gruenbacher 	struct drbd_connection *connection;
332b411b363SPhilipp Reisner 	struct list_head list;
333b411b363SPhilipp Reisner 	unsigned int barrier_nr;
334b411b363SPhilipp Reisner 	atomic_t epoch_size; /* increased on every request added. */
335b411b363SPhilipp Reisner 	atomic_t active;     /* increased on every req. added, and dec on every finished. */
336b411b363SPhilipp Reisner 	unsigned long flags;
337b411b363SPhilipp Reisner };
338b411b363SPhilipp Reisner 
339de0b2e69SRashika Kheria /* Prototype declaration of function defined in drbd_receiver.c */
340de0b2e69SRashika Kheria int drbdd_init(struct drbd_thread *);
341de0b2e69SRashika Kheria int drbd_asender(struct drbd_thread *);
342de0b2e69SRashika Kheria 
343b411b363SPhilipp Reisner /* drbd_epoch flag bits */
344b411b363SPhilipp Reisner enum {
345b411b363SPhilipp Reisner 	DE_HAVE_BARRIER_NUMBER,
346b411b363SPhilipp Reisner };
347b411b363SPhilipp Reisner 
348b411b363SPhilipp Reisner enum epoch_event {
349b411b363SPhilipp Reisner 	EV_PUT,
350b411b363SPhilipp Reisner 	EV_GOT_BARRIER_NR,
351b411b363SPhilipp Reisner 	EV_BECAME_LAST,
352b411b363SPhilipp Reisner 	EV_CLEANUP = 32, /* used as flag */
353b411b363SPhilipp Reisner };
354b411b363SPhilipp Reisner 
355b411b363SPhilipp Reisner struct digest_info {
356b411b363SPhilipp Reisner 	int digest_size;
357b411b363SPhilipp Reisner 	void *digest;
358b411b363SPhilipp Reisner };
359b411b363SPhilipp Reisner 
360f6ffca9fSAndreas Gruenbacher struct drbd_peer_request {
361a8cd15baSAndreas Gruenbacher 	struct drbd_work w;
362a8cd15baSAndreas Gruenbacher 	struct drbd_peer_device *peer_device;
36385719573SPhilipp Reisner 	struct drbd_epoch *epoch; /* for writes */
36445bb912bSLars Ellenberg 	struct page *pages;
36545bb912bSLars Ellenberg 	atomic_t pending_bios;
366010f6e67SAndreas Gruenbacher 	struct drbd_interval i;
36745bb912bSLars Ellenberg 	/* see comments on ee flag bits below */
36845bb912bSLars Ellenberg 	unsigned long flags;
36985719573SPhilipp Reisner 	union {
37045bb912bSLars Ellenberg 		u64 block_id;
37185719573SPhilipp Reisner 		struct digest_info *digest;
37285719573SPhilipp Reisner 	};
37345bb912bSLars Ellenberg };
37445bb912bSLars Ellenberg 
37545bb912bSLars Ellenberg /* ee flag bits.
37645bb912bSLars Ellenberg  * While corresponding bios are in flight, the only modification will be
37745bb912bSLars Ellenberg  * set_bit WAS_ERROR, which has to be atomic.
37845bb912bSLars Ellenberg  * If no bios are in flight yet, or all have been completed,
37945bb912bSLars Ellenberg  * non-atomic modification to ee->flags is ok.
38045bb912bSLars Ellenberg  */
381b411b363SPhilipp Reisner enum {
382b411b363SPhilipp Reisner 	__EE_CALL_AL_COMPLETE_IO,
383b411b363SPhilipp Reisner 	__EE_MAY_SET_IN_SYNC,
38445bb912bSLars Ellenberg 
38545bb912bSLars Ellenberg 	/* In case a barrier failed,
38645bb912bSLars Ellenberg 	 * we need to resubmit without the barrier flag. */
38745bb912bSLars Ellenberg 	__EE_RESUBMITTED,
38845bb912bSLars Ellenberg 
3896c852becSAndreas Gruenbacher 	/* we may have several bios per peer request.
39045bb912bSLars Ellenberg 	 * if any of those fail, we set this flag atomically
39145bb912bSLars Ellenberg 	 * from the endio callback */
39245bb912bSLars Ellenberg 	__EE_WAS_ERROR,
393c36c3cedSLars Ellenberg 
394c36c3cedSLars Ellenberg 	/* This ee has a pointer to a digest instead of a block id */
395c36c3cedSLars Ellenberg 	__EE_HAS_DIGEST,
3967be8da07SAndreas Gruenbacher 
3977be8da07SAndreas Gruenbacher 	/* Conflicting local requests need to be restarted after this request */
3987be8da07SAndreas Gruenbacher 	__EE_RESTART_REQUESTS,
399303d1448SPhilipp Reisner 
400303d1448SPhilipp Reisner 	/* The peer wants a write ACK for this (wire proto C) */
401303d1448SPhilipp Reisner 	__EE_SEND_WRITE_ACK,
402302bdeaeSPhilipp Reisner 
403302bdeaeSPhilipp Reisner 	/* Is set when net_conf had two_primaries set while creating this peer_req */
404302bdeaeSPhilipp Reisner 	__EE_IN_INTERVAL_TREE,
405b411b363SPhilipp Reisner };
406b411b363SPhilipp Reisner #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
407b411b363SPhilipp Reisner #define EE_MAY_SET_IN_SYNC     (1<<__EE_MAY_SET_IN_SYNC)
40845bb912bSLars Ellenberg #define	EE_RESUBMITTED         (1<<__EE_RESUBMITTED)
40945bb912bSLars Ellenberg #define EE_WAS_ERROR           (1<<__EE_WAS_ERROR)
410c36c3cedSLars Ellenberg #define EE_HAS_DIGEST          (1<<__EE_HAS_DIGEST)
4117be8da07SAndreas Gruenbacher #define EE_RESTART_REQUESTS	(1<<__EE_RESTART_REQUESTS)
412303d1448SPhilipp Reisner #define EE_SEND_WRITE_ACK	(1<<__EE_SEND_WRITE_ACK)
413302bdeaeSPhilipp Reisner #define EE_IN_INTERVAL_TREE	(1<<__EE_IN_INTERVAL_TREE)
414b411b363SPhilipp Reisner 
415b30ab791SAndreas Gruenbacher /* flag bits per device */
416b411b363SPhilipp Reisner enum {
417b411b363SPhilipp Reisner 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
418b411b363SPhilipp Reisner 	MD_DIRTY,		/* current uuids and flags not yet on disk */
419b411b363SPhilipp Reisner 	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
420b411b363SPhilipp Reisner 	CL_ST_CHG_SUCCESS,
421b411b363SPhilipp Reisner 	CL_ST_CHG_FAIL,
422b411b363SPhilipp Reisner 	CRASHED_PRIMARY,	/* This node was a crashed primary.
423b411b363SPhilipp Reisner 				 * Gets cleared when the state.conn
424b411b363SPhilipp Reisner 				 * goes into C_CONNECTED state. */
425b411b363SPhilipp Reisner 	CONSIDER_RESYNC,
426b411b363SPhilipp Reisner 
427a8a4e51eSPhilipp Reisner 	MD_NO_FUA,		/* Users wants us to not use FUA/FLUSH on meta data dev */
428b411b363SPhilipp Reisner 	SUSPEND_IO,		/* suspend application io */
429b411b363SPhilipp Reisner 	BITMAP_IO,		/* suspend application io;
430b411b363SPhilipp Reisner 				   once no more io in flight, start bitmap io */
431b411b363SPhilipp Reisner 	BITMAP_IO_QUEUED,       /* Started bitmap IO */
43282f59cc6SLars Ellenberg 	GO_DISKLESS,		/* Disk is being detached, on io-error or admin request. */
433a2a3c74fSLars Ellenberg 	WAS_IO_ERROR,		/* Local disk failed, returned IO error */
434a2a3c74fSLars Ellenberg 	WAS_READ_ERROR,		/* Local disk READ failed (set additionally to the above) */
435383606e0SLars Ellenberg 	FORCE_DETACH,		/* Force-detach from local disk, aborting any pending local IO */
436b411b363SPhilipp Reisner 	RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
437b411b363SPhilipp Reisner 	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
438b411b363SPhilipp Reisner 				 * the peer, if it changed there as well. */
43943a5182cSPhilipp Reisner 	NEW_CUR_UUID,		/* Create new current UUID when thawing IO */
4400778286aSPhilipp Reisner 	AL_SUSPENDED,		/* Activity logging is currently suspended. */
441370a43e7SPhilipp Reisner 	AHEAD_TO_SYNC_SOURCE,   /* Ahead -> SyncSource queued */
442e64a3294SPhilipp Reisner 	B_RS_H_DONE,		/* Before resync handler done (already executed) */
44308b165baSPhilipp Reisner 	DISCARD_MY_DATA,	/* discard_my_data flag per volume */
444380207d0SPhilipp Reisner 	READ_BALANCE_RR,
445b411b363SPhilipp Reisner };
446b411b363SPhilipp Reisner 
44754761697SAndreas Gruenbacher struct drbd_bitmap; /* opaque for drbd_device */
448b411b363SPhilipp Reisner 
44920ceb2b2SLars Ellenberg /* definition of bits in bm_flags to be used in drbd_bm_lock
45020ceb2b2SLars Ellenberg  * and drbd_bitmap_io and friends. */
45120ceb2b2SLars Ellenberg enum bm_flag {
45220ceb2b2SLars Ellenberg 	/* do we need to kfree, or vfree bm_pages? */
45320ceb2b2SLars Ellenberg 	BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */
45420ceb2b2SLars Ellenberg 
45520ceb2b2SLars Ellenberg 	/* currently locked for bulk operation */
4560e8488adSLars Ellenberg 	BM_LOCKED_MASK = 0xf,
45720ceb2b2SLars Ellenberg 
45820ceb2b2SLars Ellenberg 	/* in detail, that is: */
45920ceb2b2SLars Ellenberg 	BM_DONT_CLEAR = 0x1,
46020ceb2b2SLars Ellenberg 	BM_DONT_SET   = 0x2,
46120ceb2b2SLars Ellenberg 	BM_DONT_TEST  = 0x4,
46220ceb2b2SLars Ellenberg 
4630e8488adSLars Ellenberg 	/* so we can mark it locked for bulk operation,
4640e8488adSLars Ellenberg 	 * and still allow all non-bulk operations */
4650e8488adSLars Ellenberg 	BM_IS_LOCKED  = 0x8,
4660e8488adSLars Ellenberg 
46720ceb2b2SLars Ellenberg 	/* (test bit, count bit) allowed (common case) */
4680e8488adSLars Ellenberg 	BM_LOCKED_TEST_ALLOWED = BM_DONT_CLEAR | BM_DONT_SET | BM_IS_LOCKED,
46920ceb2b2SLars Ellenberg 
47020ceb2b2SLars Ellenberg 	/* testing bits, as well as setting new bits allowed, but clearing bits
47120ceb2b2SLars Ellenberg 	 * would be unexpected.  Used during bitmap receive.  Setting new bits
47220ceb2b2SLars Ellenberg 	 * requires sending of "out-of-sync" information, though. */
4730e8488adSLars Ellenberg 	BM_LOCKED_SET_ALLOWED = BM_DONT_CLEAR | BM_IS_LOCKED,
47420ceb2b2SLars Ellenberg 
4750e8488adSLars Ellenberg 	/* for drbd_bm_write_copy_pages, everything is allowed,
4760e8488adSLars Ellenberg 	 * only concurrent bulk operations are locked out. */
4770e8488adSLars Ellenberg 	BM_LOCKED_CHANGE_ALLOWED = BM_IS_LOCKED,
47820ceb2b2SLars Ellenberg };
47920ceb2b2SLars Ellenberg 
480b411b363SPhilipp Reisner struct drbd_work_queue {
481b411b363SPhilipp Reisner 	struct list_head q;
482b411b363SPhilipp Reisner 	spinlock_t q_lock;  /* to protect the list. */
4838c0785a5SLars Ellenberg 	wait_queue_head_t q_wait;
484b411b363SPhilipp Reisner };
485b411b363SPhilipp Reisner 
486b411b363SPhilipp Reisner struct drbd_socket {
487b411b363SPhilipp Reisner 	struct mutex mutex;
488b411b363SPhilipp Reisner 	struct socket    *socket;
489b411b363SPhilipp Reisner 	/* this way we get our
490b411b363SPhilipp Reisner 	 * send/receive buffers off the stack */
4915a87d920SAndreas Gruenbacher 	void *sbuf;
492e6ef8a5cSAndreas Gruenbacher 	void *rbuf;
493b411b363SPhilipp Reisner };
494b411b363SPhilipp Reisner 
495b411b363SPhilipp Reisner struct drbd_md {
496b411b363SPhilipp Reisner 	u64 md_offset;		/* sector offset to 'super' block */
497b411b363SPhilipp Reisner 
498b411b363SPhilipp Reisner 	u64 la_size_sect;	/* last agreed size, unit sectors */
4999f2247bbSPhilipp Reisner 	spinlock_t uuid_lock;
500b411b363SPhilipp Reisner 	u64 uuid[UI_SIZE];
501b411b363SPhilipp Reisner 	u64 device_uuid;
502b411b363SPhilipp Reisner 	u32 flags;
503b411b363SPhilipp Reisner 	u32 md_size_sect;
504b411b363SPhilipp Reisner 
505ae8bf312SLars Ellenberg 	s32 al_offset;	/* signed relative sector offset to activity log */
506b411b363SPhilipp Reisner 	s32 bm_offset;	/* signed relative sector offset to bitmap */
5073a4d4eb3SLars Ellenberg 
5083a4d4eb3SLars Ellenberg 	/* cached value of bdev->disk_conf->meta_dev_idx (see below) */
5093a4d4eb3SLars Ellenberg 	s32 meta_dev_idx;
5103a4d4eb3SLars Ellenberg 
5113a4d4eb3SLars Ellenberg 	/* see al_tr_number_to_on_disk_sector() */
5123a4d4eb3SLars Ellenberg 	u32 al_stripes;
5133a4d4eb3SLars Ellenberg 	u32 al_stripe_size_4k;
5143a4d4eb3SLars Ellenberg 	u32 al_size_4k; /* cached product of the above */
515b411b363SPhilipp Reisner };
516b411b363SPhilipp Reisner 
517b411b363SPhilipp Reisner struct drbd_backing_dev {
518b411b363SPhilipp Reisner 	struct block_device *backing_bdev;
519b411b363SPhilipp Reisner 	struct block_device *md_bdev;
520b411b363SPhilipp Reisner 	struct drbd_md md;
5210500813fSAndreas Gruenbacher 	struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
522b411b363SPhilipp Reisner 	sector_t known_size; /* last known size of that backing device */
523b411b363SPhilipp Reisner };
524b411b363SPhilipp Reisner 
525b411b363SPhilipp Reisner struct drbd_md_io {
5260c464425SPhilipp Reisner 	unsigned int done;
527b411b363SPhilipp Reisner 	int error;
528b411b363SPhilipp Reisner };
529b411b363SPhilipp Reisner 
530b411b363SPhilipp Reisner struct bm_io_work {
531b411b363SPhilipp Reisner 	struct drbd_work w;
532b411b363SPhilipp Reisner 	char *why;
53320ceb2b2SLars Ellenberg 	enum bm_flag flags;
534b30ab791SAndreas Gruenbacher 	int (*io_fn)(struct drbd_device *device);
535b30ab791SAndreas Gruenbacher 	void (*done)(struct drbd_device *device, int rv);
536b411b363SPhilipp Reisner };
537b411b363SPhilipp Reisner 
538b411b363SPhilipp Reisner enum write_ordering_e {
539b411b363SPhilipp Reisner 	WO_none,
540b411b363SPhilipp Reisner 	WO_drain_io,
541b411b363SPhilipp Reisner 	WO_bdev_flush,
542b411b363SPhilipp Reisner };
543b411b363SPhilipp Reisner 
544778f271dSPhilipp Reisner struct fifo_buffer {
545778f271dSPhilipp Reisner 	unsigned int head_index;
546778f271dSPhilipp Reisner 	unsigned int size;
5479958c857SPhilipp Reisner 	int total; /* sum of all values */
5489958c857SPhilipp Reisner 	int values[0];
549778f271dSPhilipp Reisner };
5509958c857SPhilipp Reisner extern struct fifo_buffer *fifo_alloc(int fifo_size);
551778f271dSPhilipp Reisner 
552bde89a9eSAndreas Gruenbacher /* flag bits per connection */
55301a311a5SPhilipp Reisner enum {
55401a311a5SPhilipp Reisner 	NET_CONGESTED,		/* The data socket is congested */
555427c0434SLars Ellenberg 	RESOLVE_CONFLICTS,	/* Set on one node, cleared on the peer! */
556e43ef195SPhilipp Reisner 	SEND_PING,		/* whether asender should send a ping asap */
557808e37b8SPhilipp Reisner 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
5582a67d8b9SPhilipp Reisner 	GOT_PING_ACK,		/* set when we receive a ping_ack packet, ping_wait gets woken */
5594d0fc3fdSPhilipp Reisner 	CONN_WD_ST_CHG_REQ,	/* A cluster wide state change on the connection is active */
560fc3b10a4SPhilipp Reisner 	CONN_WD_ST_CHG_OKAY,
561fc3b10a4SPhilipp Reisner 	CONN_WD_ST_CHG_FAIL,
5628169e41bSPhilipp Reisner 	CONN_DRY_RUN,		/* Expect disconnect after resync handshake. */
5636936fcb4SPhilipp Reisner 	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
564a1096a6eSPhilipp Reisner 	STATE_SENT,		/* Do not change state/UUIDs while this is set */
5656f3465edSLars Ellenberg 	CALLBACK_PENDING,	/* Whether we have a call_usermodehelper(, UMH_WAIT_PROC)
5666f3465edSLars Ellenberg 				 * pending, from drbd worker context.
5676f3465edSLars Ellenberg 				 * If set, bdi_write_congested() returns true,
5686f3465edSLars Ellenberg 				 * so shrink_page_list() would not recurse into,
5696f3465edSLars Ellenberg 				 * and potentially deadlock on, this drbd worker.
5706f3465edSLars Ellenberg 				 */
571b66623e3SPhilipp Reisner 	DISCONNECT_SENT,
57201a311a5SPhilipp Reisner };
57301a311a5SPhilipp Reisner 
57477c556f6SAndreas Gruenbacher struct drbd_resource {
57577c556f6SAndreas Gruenbacher 	char *name;
57677c556f6SAndreas Gruenbacher 	struct kref kref;
577803ea134SAndreas Gruenbacher 	struct idr devices;		/* volume number to device mapping */
57877c556f6SAndreas Gruenbacher 	struct list_head connections;
57977c556f6SAndreas Gruenbacher 	struct list_head resources;
580eb6bea67SAndreas Gruenbacher 	struct res_opts res_opts;
5810500813fSAndreas Gruenbacher 	struct mutex conf_update;	/* mutex for ready-copy-update of net_conf and disk_conf */
5820500813fSAndreas Gruenbacher 	spinlock_t req_lock;
5836bbf53caSAndreas Gruenbacher 
5846bbf53caSAndreas Gruenbacher 	unsigned susp:1;		/* IO suspended by user */
5856bbf53caSAndreas Gruenbacher 	unsigned susp_nod:1;		/* IO suspended because no data */
5866bbf53caSAndreas Gruenbacher 	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
587625a6ba2SAndreas Gruenbacher 
588625a6ba2SAndreas Gruenbacher 	cpumask_var_t cpu_mask;
58977c556f6SAndreas Gruenbacher };
59077c556f6SAndreas Gruenbacher 
59177c556f6SAndreas Gruenbacher struct drbd_connection {
59277c556f6SAndreas Gruenbacher 	struct list_head connections;
59377c556f6SAndreas Gruenbacher 	struct drbd_resource *resource;
5949dc9fbb3SPhilipp Reisner 	struct kref kref;
595c06ece6bSAndreas Gruenbacher 	struct idr peer_devices;	/* volume number to peer device mapping */
596bbeb641cSPhilipp Reisner 	enum drbd_conns cstate;		/* Only C_STANDALONE to C_WF_REPORT_PARAMS */
5978410da8fSPhilipp Reisner 	struct mutex cstate_mutex;	/* Protects graceful disconnects */
59828e448bbSPhilipp Reisner 	unsigned int connect_cnt;	/* Inc each time a connection is established */
5992111438bSPhilipp Reisner 
600062e879cSPhilipp Reisner 	unsigned long flags;
60144ed167dSPhilipp Reisner 	struct net_conf *net_conf;	/* content protected by rcu */
6022a67d8b9SPhilipp Reisner 	wait_queue_head_t ping_wait;	/* Woken upon reception of a ping, and a state change */
603e42325a5SPhilipp Reisner 
604089c075dSAndreas Gruenbacher 	struct sockaddr_storage my_addr;
605089c075dSAndreas Gruenbacher 	int my_addr_len;
606089c075dSAndreas Gruenbacher 	struct sockaddr_storage peer_addr;
607089c075dSAndreas Gruenbacher 	int peer_addr_len;
608089c075dSAndreas Gruenbacher 
609e42325a5SPhilipp Reisner 	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
610e42325a5SPhilipp Reisner 	struct drbd_socket meta;	/* ping/ack (metadata) packets */
61131890f4aSPhilipp Reisner 	int agreed_pro_version;		/* actually used protocol version */
61231890f4aSPhilipp Reisner 	unsigned long last_received;	/* in jiffies, either socket */
61331890f4aSPhilipp Reisner 	unsigned int ko_count;
614e6b3ea83SPhilipp Reisner 
615b6dd1a89SLars Ellenberg 	struct list_head transfer_log;	/* all requests not yet fully processed */
61687eeee41SPhilipp Reisner 
617a0638456SPhilipp Reisner 	struct crypto_hash *cram_hmac_tfm;
618bde89a9eSAndreas Gruenbacher 	struct crypto_hash *integrity_tfm;  /* checksums we compute, updates protected by connection->data->mutex */
619036b17eaSPhilipp Reisner 	struct crypto_hash *peer_integrity_tfm;  /* checksums we verify, only accessed from receiver thread  */
620f399002eSLars Ellenberg 	struct crypto_hash *csums_tfm;
621f399002eSLars Ellenberg 	struct crypto_hash *verify_tfm;
622a0638456SPhilipp Reisner 	void *int_dig_in;
623a0638456SPhilipp Reisner 	void *int_dig_vv;
624a0638456SPhilipp Reisner 
625b6dd1a89SLars Ellenberg 	/* receiver side */
62612038a3aSPhilipp Reisner 	struct drbd_epoch *current_epoch;
62712038a3aSPhilipp Reisner 	spinlock_t epoch_lock;
62812038a3aSPhilipp Reisner 	unsigned int epochs;
6294b0007c0SPhilipp Reisner 	enum write_ordering_e write_ordering;
630b379c41eSLars Ellenberg 	atomic_t current_tle_nr;	/* transfer log epoch number */
631b6dd1a89SLars Ellenberg 	unsigned current_tle_writes;	/* writes seen within this tl epoch */
6324b0007c0SPhilipp Reisner 
63307be15b1SLars Ellenberg 	unsigned long last_reconnect_jif;
634e6b3ea83SPhilipp Reisner 	struct drbd_thread receiver;
635e6b3ea83SPhilipp Reisner 	struct drbd_thread worker;
636e6b3ea83SPhilipp Reisner 	struct drbd_thread asender;
637b6dd1a89SLars Ellenberg 
638b6dd1a89SLars Ellenberg 	/* sender side */
639d5b27b01SLars Ellenberg 	struct drbd_work_queue sender_work;
640b6dd1a89SLars Ellenberg 
641b6dd1a89SLars Ellenberg 	struct {
642b6dd1a89SLars Ellenberg 		/* whether this sender thread
643b6dd1a89SLars Ellenberg 		 * has processed a single write yet. */
644b6dd1a89SLars Ellenberg 		bool seen_any_write_yet;
645b6dd1a89SLars Ellenberg 
646b6dd1a89SLars Ellenberg 		/* Which barrier number to send with the next P_BARRIER */
647b6dd1a89SLars Ellenberg 		int current_epoch_nr;
648b6dd1a89SLars Ellenberg 
649b6dd1a89SLars Ellenberg 		/* how many write requests have been sent
650b6dd1a89SLars Ellenberg 		 * with req->epoch == current_epoch_nr.
651b6dd1a89SLars Ellenberg 		 * If none, no P_BARRIER will be sent. */
652b6dd1a89SLars Ellenberg 		unsigned current_epoch_writes;
653b6dd1a89SLars Ellenberg 	} send;
654b411b363SPhilipp Reisner };
655b411b363SPhilipp Reisner 
656113fef9eSLars Ellenberg struct submit_worker {
657113fef9eSLars Ellenberg 	struct workqueue_struct *wq;
658113fef9eSLars Ellenberg 	struct work_struct worker;
659113fef9eSLars Ellenberg 
660113fef9eSLars Ellenberg 	spinlock_t lock;
661113fef9eSLars Ellenberg 	struct list_head writes;
662113fef9eSLars Ellenberg };
663113fef9eSLars Ellenberg 
664a6b32bc3SAndreas Gruenbacher struct drbd_peer_device {
665a6b32bc3SAndreas Gruenbacher 	struct list_head peer_devices;
666a6b32bc3SAndreas Gruenbacher 	struct drbd_device *device;
667bde89a9eSAndreas Gruenbacher 	struct drbd_connection *connection;
668a6b32bc3SAndreas Gruenbacher };
669a6b32bc3SAndreas Gruenbacher 
670a6b32bc3SAndreas Gruenbacher struct drbd_device {
671d8628a86SAndreas Gruenbacher 	struct drbd_resource *resource;
672a6b32bc3SAndreas Gruenbacher 	struct list_head peer_devices;
6732111438bSPhilipp Reisner 	int vnr;			/* volume number within the connection */
67481fa2e67SPhilipp Reisner 	struct kref kref;
6752111438bSPhilipp Reisner 
676b411b363SPhilipp Reisner 	/* things that are stored as / read from meta data on disk */
677b411b363SPhilipp Reisner 	unsigned long flags;
678b411b363SPhilipp Reisner 
679b411b363SPhilipp Reisner 	/* configured by drbdsetup */
680b411b363SPhilipp Reisner 	struct drbd_backing_dev *ldev __protected_by(local);
681b411b363SPhilipp Reisner 
682b411b363SPhilipp Reisner 	sector_t p_size;     /* partner's disk size */
683b411b363SPhilipp Reisner 	struct request_queue *rq_queue;
684b411b363SPhilipp Reisner 	struct block_device *this_bdev;
685b411b363SPhilipp Reisner 	struct gendisk	    *vdisk;
686b411b363SPhilipp Reisner 
68707be15b1SLars Ellenberg 	unsigned long last_reattach_jif;
68884b8c06bSAndreas Gruenbacher 	struct drbd_work resync_work;
68984b8c06bSAndreas Gruenbacher 	struct drbd_work unplug_work;
69084b8c06bSAndreas Gruenbacher 	struct drbd_work go_diskless;
69184b8c06bSAndreas Gruenbacher 	struct drbd_work md_sync_work;
69284b8c06bSAndreas Gruenbacher 	struct drbd_work start_resync_work;
693b411b363SPhilipp Reisner 	struct timer_list resync_timer;
694b411b363SPhilipp Reisner 	struct timer_list md_sync_timer;
695370a43e7SPhilipp Reisner 	struct timer_list start_resync_timer;
6967fde2be9SPhilipp Reisner 	struct timer_list request_timer;
697ee15b038SLars Ellenberg #ifdef DRBD_DEBUG_MD_SYNC
698ee15b038SLars Ellenberg 	struct {
699ee15b038SLars Ellenberg 		unsigned int line;
700ee15b038SLars Ellenberg 		const char* func;
701ee15b038SLars Ellenberg 	} last_md_mark_dirty;
702ee15b038SLars Ellenberg #endif
703b411b363SPhilipp Reisner 
704b411b363SPhilipp Reisner 	/* Used after attach while negotiating new disk state. */
705b411b363SPhilipp Reisner 	union drbd_state new_state_tmp;
706b411b363SPhilipp Reisner 
707da9fbc27SPhilipp Reisner 	union drbd_dev_state state;
708b411b363SPhilipp Reisner 	wait_queue_head_t misc_wait;
709b411b363SPhilipp Reisner 	wait_queue_head_t state_wait;  /* upon each state change. */
710b411b363SPhilipp Reisner 	unsigned int send_cnt;
711b411b363SPhilipp Reisner 	unsigned int recv_cnt;
712b411b363SPhilipp Reisner 	unsigned int read_cnt;
713b411b363SPhilipp Reisner 	unsigned int writ_cnt;
714b411b363SPhilipp Reisner 	unsigned int al_writ_cnt;
715b411b363SPhilipp Reisner 	unsigned int bm_writ_cnt;
716b411b363SPhilipp Reisner 	atomic_t ap_bio_cnt;	 /* Requests we need to complete */
717b411b363SPhilipp Reisner 	atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */
718b411b363SPhilipp Reisner 	atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
719d942ae44SPhilipp Reisner 	atomic_t unacked_cnt;	 /* Need to send replies for */
720b411b363SPhilipp Reisner 	atomic_t local_cnt;	 /* Waiting for local completion */
721b2fb6dbeSPhilipp Reisner 
722dac1389cSAndreas Gruenbacher 	/* Interval tree of pending local requests */
723dac1389cSAndreas Gruenbacher 	struct rb_root read_requests;
724de696716SAndreas Gruenbacher 	struct rb_root write_requests;
725b411b363SPhilipp Reisner 
7264b0715f0SLars Ellenberg 	/* blocks to resync in this run [unit BM_BLOCK_SIZE] */
727b411b363SPhilipp Reisner 	unsigned long rs_total;
7284b0715f0SLars Ellenberg 	/* number of resync blocks that failed in this run */
729b411b363SPhilipp Reisner 	unsigned long rs_failed;
730b411b363SPhilipp Reisner 	/* Syncer's start time [unit jiffies] */
731b411b363SPhilipp Reisner 	unsigned long rs_start;
732b411b363SPhilipp Reisner 	/* cumulated time in PausedSyncX state [unit jiffies] */
733b411b363SPhilipp Reisner 	unsigned long rs_paused;
7341d7734a0SLars Ellenberg 	/* skipped because csum was equal [unit BM_BLOCK_SIZE] */
735b411b363SPhilipp Reisner 	unsigned long rs_same_csum;
7361d7734a0SLars Ellenberg #define DRBD_SYNC_MARKS 8
7371d7734a0SLars Ellenberg #define DRBD_SYNC_MARK_STEP (3*HZ)
7381d7734a0SLars Ellenberg 	/* block not up-to-date at mark [unit BM_BLOCK_SIZE] */
7391d7734a0SLars Ellenberg 	unsigned long rs_mark_left[DRBD_SYNC_MARKS];
7401d7734a0SLars Ellenberg 	/* marks's time [unit jiffies] */
7411d7734a0SLars Ellenberg 	unsigned long rs_mark_time[DRBD_SYNC_MARKS];
7421d7734a0SLars Ellenberg 	/* current index into rs_mark_{left,time} */
7431d7734a0SLars Ellenberg 	int rs_last_mark;
744328e0f12SPhilipp Reisner 	unsigned long rs_last_bcast; /* [unit jiffies] */
745b411b363SPhilipp Reisner 
746b411b363SPhilipp Reisner 	/* where does the admin want us to start? (sector) */
747b411b363SPhilipp Reisner 	sector_t ov_start_sector;
74802b91b55SLars Ellenberg 	sector_t ov_stop_sector;
749b411b363SPhilipp Reisner 	/* where are we now? (sector) */
750b411b363SPhilipp Reisner 	sector_t ov_position;
751b411b363SPhilipp Reisner 	/* Start sector of out of sync range (to merge printk reporting). */
752b411b363SPhilipp Reisner 	sector_t ov_last_oos_start;
753b411b363SPhilipp Reisner 	/* size of out-of-sync range in sectors. */
754b411b363SPhilipp Reisner 	sector_t ov_last_oos_size;
755b411b363SPhilipp Reisner 	unsigned long ov_left; /* in bits */
756b411b363SPhilipp Reisner 
757b411b363SPhilipp Reisner 	struct drbd_bitmap *bitmap;
758b411b363SPhilipp Reisner 	unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */
759b411b363SPhilipp Reisner 
760b411b363SPhilipp Reisner 	/* Used to track operations of resync... */
761b411b363SPhilipp Reisner 	struct lru_cache *resync;
762b411b363SPhilipp Reisner 	/* Number of locked elements in resync LRU */
763b411b363SPhilipp Reisner 	unsigned int resync_locked;
764b411b363SPhilipp Reisner 	/* resync extent number waiting for application requests */
765b411b363SPhilipp Reisner 	unsigned int resync_wenr;
766b411b363SPhilipp Reisner 
767b411b363SPhilipp Reisner 	int open_cnt;
768b411b363SPhilipp Reisner 	u64 *p_uuid;
7694b0007c0SPhilipp Reisner 
77085719573SPhilipp Reisner 	struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */
77185719573SPhilipp Reisner 	struct list_head sync_ee;   /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
77218b75d75SAndreas Gruenbacher 	struct list_head done_ee;   /* need to send P_WRITE_ACK */
77318b75d75SAndreas Gruenbacher 	struct list_head read_ee;   /* [RS]P_DATA_REQUEST being read */
774b411b363SPhilipp Reisner 	struct list_head net_ee;    /* zero-copy network send in progress */
775b411b363SPhilipp Reisner 
776b411b363SPhilipp Reisner 	int next_barrier_nr;
777b411b363SPhilipp Reisner 	struct list_head resync_reads;
778435f0740SLars Ellenberg 	atomic_t pp_in_use;		/* allocated from page pool */
779435f0740SLars Ellenberg 	atomic_t pp_in_use_by_net;	/* sendpage()d, still referenced by tcp */
780b411b363SPhilipp Reisner 	wait_queue_head_t ee_wait;
781b411b363SPhilipp Reisner 	struct page *md_io_page;	/* one page buffer for md_io */
782cc94c650SPhilipp Reisner 	struct drbd_md_io md_io;
783e1711731SPhilipp Reisner 	atomic_t md_io_in_use;		/* protects the md_io, md_io_page and md_io_tmpp */
784b411b363SPhilipp Reisner 	spinlock_t al_lock;
785b411b363SPhilipp Reisner 	wait_queue_head_t al_wait;
786b411b363SPhilipp Reisner 	struct lru_cache *act_log;	/* activity log */
787b411b363SPhilipp Reisner 	unsigned int al_tr_number;
788b411b363SPhilipp Reisner 	int al_tr_cycle;
789b411b363SPhilipp Reisner 	wait_queue_head_t seq_wait;
790b411b363SPhilipp Reisner 	atomic_t packet_seq;
791b411b363SPhilipp Reisner 	unsigned int peer_seq;
792b411b363SPhilipp Reisner 	spinlock_t peer_seq_lock;
793b411b363SPhilipp Reisner 	unsigned int minor;
794b411b363SPhilipp Reisner 	unsigned long comm_bm_set; /* communicated number of set bits. */
795b411b363SPhilipp Reisner 	struct bm_io_work bm_io_work;
796b411b363SPhilipp Reisner 	u64 ed_uuid; /* UUID of the exposed data */
7978410da8fSPhilipp Reisner 	struct mutex own_state_mutex;
798a6b32bc3SAndreas Gruenbacher 	struct mutex *state_mutex; /* either own_state_mutex or first_peer_device(device)->connection->cstate_mutex */
799b411b363SPhilipp Reisner 	char congestion_reason;  /* Why we where congested... */
8001d7734a0SLars Ellenberg 	atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
8011d7734a0SLars Ellenberg 	atomic_t rs_sect_ev; /* for submitted resync data rate, both */
8021d7734a0SLars Ellenberg 	int rs_last_sect_ev; /* counter to compare with */
8031d7734a0SLars Ellenberg 	int rs_last_events;  /* counter of read or write "events" (unit sectors)
8041d7734a0SLars Ellenberg 			      * on the lower level device when we last looked. */
8051d7734a0SLars Ellenberg 	int c_sync_rate; /* current resync rate after syncer throttle magic */
806bde89a9eSAndreas Gruenbacher 	struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
807778f271dSPhilipp Reisner 	int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
808759fbdfbSPhilipp Reisner 	atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
809db141b2fSLars Ellenberg 	unsigned int peer_max_bio_size;
810db141b2fSLars Ellenberg 	unsigned int local_max_bio_size;
811113fef9eSLars Ellenberg 
812113fef9eSLars Ellenberg 	/* any requests that would block in drbd_make_request()
813113fef9eSLars Ellenberg 	 * are deferred to this single-threaded work queue */
814113fef9eSLars Ellenberg 	struct submit_worker submit;
815b411b363SPhilipp Reisner };
816b411b363SPhilipp Reisner 
817b30ab791SAndreas Gruenbacher static inline struct drbd_device *minor_to_device(unsigned int minor)
818b411b363SPhilipp Reisner {
81905a10ec7SAndreas Gruenbacher 	return (struct drbd_device *)idr_find(&drbd_devices, minor);
820b411b363SPhilipp Reisner }
821b411b363SPhilipp Reisner 
822a6b32bc3SAndreas Gruenbacher static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device)
823a6b32bc3SAndreas Gruenbacher {
824a6b32bc3SAndreas Gruenbacher 	return list_first_entry(&device->peer_devices, struct drbd_peer_device, peer_devices);
825a6b32bc3SAndreas Gruenbacher }
826a6b32bc3SAndreas Gruenbacher 
82777c556f6SAndreas Gruenbacher #define for_each_resource(resource, _resources) \
82877c556f6SAndreas Gruenbacher 	list_for_each_entry(resource, _resources, resources)
82977c556f6SAndreas Gruenbacher 
83077c556f6SAndreas Gruenbacher #define for_each_resource_rcu(resource, _resources) \
83177c556f6SAndreas Gruenbacher 	list_for_each_entry_rcu(resource, _resources, resources)
83277c556f6SAndreas Gruenbacher 
83377c556f6SAndreas Gruenbacher #define for_each_resource_safe(resource, tmp, _resources) \
83477c556f6SAndreas Gruenbacher 	list_for_each_entry_safe(resource, tmp, _resources, resources)
83577c556f6SAndreas Gruenbacher 
83677c556f6SAndreas Gruenbacher #define for_each_connection(connection, resource) \
83777c556f6SAndreas Gruenbacher 	list_for_each_entry(connection, &resource->connections, connections)
83877c556f6SAndreas Gruenbacher 
83977c556f6SAndreas Gruenbacher #define for_each_connection_rcu(connection, resource) \
84077c556f6SAndreas Gruenbacher 	list_for_each_entry_rcu(connection, &resource->connections, connections)
84177c556f6SAndreas Gruenbacher 
84277c556f6SAndreas Gruenbacher #define for_each_connection_safe(connection, tmp, resource) \
84377c556f6SAndreas Gruenbacher 	list_for_each_entry_safe(connection, tmp, &resource->connections, connections)
84477c556f6SAndreas Gruenbacher 
845a6b32bc3SAndreas Gruenbacher #define for_each_peer_device(peer_device, device) \
846a6b32bc3SAndreas Gruenbacher 	list_for_each_entry(peer_device, &device->peer_devices, peer_devices)
847a6b32bc3SAndreas Gruenbacher 
848a6b32bc3SAndreas Gruenbacher #define for_each_peer_device_rcu(peer_device, device) \
849a6b32bc3SAndreas Gruenbacher 	list_for_each_entry_rcu(peer_device, &device->peer_devices, peer_devices)
850a6b32bc3SAndreas Gruenbacher 
851a6b32bc3SAndreas Gruenbacher #define for_each_peer_device_safe(peer_device, tmp, device) \
852a6b32bc3SAndreas Gruenbacher 	list_for_each_entry_safe(peer_device, tmp, &device->peer_devices, peer_devices)
853a6b32bc3SAndreas Gruenbacher 
854b30ab791SAndreas Gruenbacher static inline unsigned int device_to_minor(struct drbd_device *device)
855b411b363SPhilipp Reisner {
856b30ab791SAndreas Gruenbacher 	return device->minor;
857b411b363SPhilipp Reisner }
858b411b363SPhilipp Reisner 
859b411b363SPhilipp Reisner /*
860b411b363SPhilipp Reisner  * function declarations
861b411b363SPhilipp Reisner  *************************/
862b411b363SPhilipp Reisner 
863b411b363SPhilipp Reisner /* drbd_main.c */
864b411b363SPhilipp Reisner 
865e89b591cSPhilipp Reisner enum dds_flags {
866e89b591cSPhilipp Reisner 	DDSF_FORCED    = 1,
867e89b591cSPhilipp Reisner 	DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */
868e89b591cSPhilipp Reisner };
869e89b591cSPhilipp Reisner 
870b30ab791SAndreas Gruenbacher extern void drbd_init_set_defaults(struct drbd_device *device);
871b411b363SPhilipp Reisner extern int  drbd_thread_start(struct drbd_thread *thi);
872b411b363SPhilipp Reisner extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
873b411b363SPhilipp Reisner #ifdef CONFIG_SMP
87480822284SPhilipp Reisner extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
875b411b363SPhilipp Reisner #else
876b411b363SPhilipp Reisner #define drbd_thread_current_set_cpu(A) ({})
877b411b363SPhilipp Reisner #endif
878bde89a9eSAndreas Gruenbacher extern void tl_release(struct drbd_connection *, unsigned int barrier_nr,
879b411b363SPhilipp Reisner 		       unsigned int set_size);
880bde89a9eSAndreas Gruenbacher extern void tl_clear(struct drbd_connection *);
881bde89a9eSAndreas Gruenbacher extern void drbd_free_sock(struct drbd_connection *connection);
882bde89a9eSAndreas Gruenbacher extern int drbd_send(struct drbd_connection *connection, struct socket *sock,
883b411b363SPhilipp Reisner 		     void *buf, size_t size, unsigned msg_flags);
884bde89a9eSAndreas Gruenbacher extern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size_t,
885fb708e40SAndreas Gruenbacher 			 unsigned);
886fb708e40SAndreas Gruenbacher 
887bde89a9eSAndreas Gruenbacher extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd);
888bde89a9eSAndreas Gruenbacher extern int drbd_send_protocol(struct drbd_connection *connection);
88969a22773SAndreas Gruenbacher extern int drbd_send_uuids(struct drbd_peer_device *);
89069a22773SAndreas Gruenbacher extern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
89169a22773SAndreas Gruenbacher extern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
89269a22773SAndreas Gruenbacher extern int drbd_send_sizes(struct drbd_peer_device *, int trigger_reply, enum dds_flags flags);
89369a22773SAndreas Gruenbacher extern int drbd_send_state(struct drbd_peer_device *, union drbd_state s);
89469a22773SAndreas Gruenbacher extern int drbd_send_current_state(struct drbd_peer_device *);
89569a22773SAndreas Gruenbacher extern int drbd_send_sync_param(struct drbd_peer_device *);
896bde89a9eSAndreas Gruenbacher extern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr,
897b411b363SPhilipp Reisner 			    u32 set_size);
89869a22773SAndreas Gruenbacher extern int drbd_send_ack(struct drbd_peer_device *, enum drbd_packet,
899f6ffca9fSAndreas Gruenbacher 			 struct drbd_peer_request *);
90069a22773SAndreas Gruenbacher extern void drbd_send_ack_rp(struct drbd_peer_device *, enum drbd_packet,
901b411b363SPhilipp Reisner 			     struct p_block_req *rp);
90269a22773SAndreas Gruenbacher extern void drbd_send_ack_dp(struct drbd_peer_device *, enum drbd_packet,
9032b2bf214SLars Ellenberg 			     struct p_data *dp, int data_size);
90469a22773SAndreas Gruenbacher extern int drbd_send_ack_ex(struct drbd_peer_device *, enum drbd_packet,
905b411b363SPhilipp Reisner 			    sector_t sector, int blksize, u64 block_id);
90669a22773SAndreas Gruenbacher extern int drbd_send_out_of_sync(struct drbd_peer_device *, struct drbd_request *);
90769a22773SAndreas Gruenbacher extern int drbd_send_block(struct drbd_peer_device *, enum drbd_packet,
908f6ffca9fSAndreas Gruenbacher 			   struct drbd_peer_request *);
90969a22773SAndreas Gruenbacher extern int drbd_send_dblock(struct drbd_peer_device *, struct drbd_request *req);
91069a22773SAndreas Gruenbacher extern int drbd_send_drequest(struct drbd_peer_device *, int cmd,
911b411b363SPhilipp Reisner 			      sector_t sector, int size, u64 block_id);
91269a22773SAndreas Gruenbacher extern int drbd_send_drequest_csum(struct drbd_peer_device *, sector_t sector,
913d8763023SAndreas Gruenbacher 				   int size, void *digest, int digest_size,
914d8763023SAndreas Gruenbacher 				   enum drbd_packet cmd);
91569a22773SAndreas Gruenbacher extern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int size);
916b411b363SPhilipp Reisner 
917b30ab791SAndreas Gruenbacher extern int drbd_send_bitmap(struct drbd_device *device);
91869a22773SAndreas Gruenbacher extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
919bde89a9eSAndreas Gruenbacher extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
920b411b363SPhilipp Reisner extern void drbd_free_bc(struct drbd_backing_dev *ldev);
921b30ab791SAndreas Gruenbacher extern void drbd_device_cleanup(struct drbd_device *device);
922b30ab791SAndreas Gruenbacher void drbd_print_uuids(struct drbd_device *device, const char *text);
923b411b363SPhilipp Reisner 
924bde89a9eSAndreas Gruenbacher extern void conn_md_sync(struct drbd_connection *connection);
925b30ab791SAndreas Gruenbacher extern void drbd_md_write(struct drbd_device *device, void *buffer);
926b30ab791SAndreas Gruenbacher extern void drbd_md_sync(struct drbd_device *device);
927b30ab791SAndreas Gruenbacher extern int  drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev);
928b30ab791SAndreas Gruenbacher extern void drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
929b30ab791SAndreas Gruenbacher extern void _drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
930b30ab791SAndreas Gruenbacher extern void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local);
931b30ab791SAndreas Gruenbacher extern void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local);
932b30ab791SAndreas Gruenbacher extern void drbd_uuid_move_history(struct drbd_device *device) __must_hold(local);
933b30ab791SAndreas Gruenbacher extern void __drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
934b30ab791SAndreas Gruenbacher extern void drbd_md_set_flag(struct drbd_device *device, int flags) __must_hold(local);
935b30ab791SAndreas Gruenbacher extern void drbd_md_clear_flag(struct drbd_device *device, int flags)__must_hold(local);
936b411b363SPhilipp Reisner extern int drbd_md_test_flag(struct drbd_backing_dev *, int);
937ee15b038SLars Ellenberg #ifndef DRBD_DEBUG_MD_SYNC
938b30ab791SAndreas Gruenbacher extern void drbd_md_mark_dirty(struct drbd_device *device);
939ee15b038SLars Ellenberg #else
940ee15b038SLars Ellenberg #define drbd_md_mark_dirty(m)	drbd_md_mark_dirty_(m, __LINE__ , __func__ )
941b30ab791SAndreas Gruenbacher extern void drbd_md_mark_dirty_(struct drbd_device *device,
942ee15b038SLars Ellenberg 		unsigned int line, const char *func);
943ee15b038SLars Ellenberg #endif
944b30ab791SAndreas Gruenbacher extern void drbd_queue_bitmap_io(struct drbd_device *device,
94554761697SAndreas Gruenbacher 				 int (*io_fn)(struct drbd_device *),
94654761697SAndreas Gruenbacher 				 void (*done)(struct drbd_device *, int),
94720ceb2b2SLars Ellenberg 				 char *why, enum bm_flag flags);
948b30ab791SAndreas Gruenbacher extern int drbd_bitmap_io(struct drbd_device *device,
94954761697SAndreas Gruenbacher 		int (*io_fn)(struct drbd_device *),
95020ceb2b2SLars Ellenberg 		char *why, enum bm_flag flags);
951b30ab791SAndreas Gruenbacher extern int drbd_bitmap_io_from_worker(struct drbd_device *device,
95254761697SAndreas Gruenbacher 		int (*io_fn)(struct drbd_device *),
953edc9f5ebSLars Ellenberg 		char *why, enum bm_flag flags);
954b30ab791SAndreas Gruenbacher extern int drbd_bmio_set_n_write(struct drbd_device *device);
955b30ab791SAndreas Gruenbacher extern int drbd_bmio_clear_n_write(struct drbd_device *device);
956b30ab791SAndreas Gruenbacher extern void drbd_ldev_destroy(struct drbd_device *device);
957b411b363SPhilipp Reisner 
958b411b363SPhilipp Reisner /* Meta data layout
959ae8bf312SLars Ellenberg  *
960ae8bf312SLars Ellenberg  * We currently have two possible layouts.
961ae8bf312SLars Ellenberg  * Offsets in (512 byte) sectors.
962ae8bf312SLars Ellenberg  * external:
963ae8bf312SLars Ellenberg  *   |----------- md_size_sect ------------------|
964ae8bf312SLars Ellenberg  *   [ 4k superblock ][ activity log ][  Bitmap  ]
965ae8bf312SLars Ellenberg  *   | al_offset == 8 |
966ae8bf312SLars Ellenberg  *   | bm_offset = al_offset + X      |
967ae8bf312SLars Ellenberg  *  ==> bitmap sectors = md_size_sect - bm_offset
968ae8bf312SLars Ellenberg  *
969ae8bf312SLars Ellenberg  *  Variants:
970ae8bf312SLars Ellenberg  *     old, indexed fixed size meta data:
971ae8bf312SLars Ellenberg  *
972ae8bf312SLars Ellenberg  * internal:
973ae8bf312SLars Ellenberg  *            |----------- md_size_sect ------------------|
974ae8bf312SLars Ellenberg  * [data.....][  Bitmap  ][ activity log ][ 4k superblock ][padding*]
975ae8bf312SLars Ellenberg  *                        | al_offset < 0 |
976ae8bf312SLars Ellenberg  *            | bm_offset = al_offset - Y |
977ae8bf312SLars Ellenberg  *  ==> bitmap sectors = Y = al_offset - bm_offset
978ae8bf312SLars Ellenberg  *
979ae8bf312SLars Ellenberg  *  [padding*] are zero or up to 7 unused 512 Byte sectors to the
980ae8bf312SLars Ellenberg  *  end of the device, so that the [4k superblock] will be 4k aligned.
981ae8bf312SLars Ellenberg  *
982ae8bf312SLars Ellenberg  *  The activity log consists of 4k transaction blocks,
983ae8bf312SLars Ellenberg  *  which are written in a ring-buffer, or striped ring-buffer like fashion,
984ae8bf312SLars Ellenberg  *  which are writtensize used to be fixed 32kB,
985ae8bf312SLars Ellenberg  *  but is about to become configurable.
986ae8bf312SLars Ellenberg  */
987b411b363SPhilipp Reisner 
988ae8bf312SLars Ellenberg /* Our old fixed size meta data layout
989ae8bf312SLars Ellenberg  * allows up to about 3.8TB, so if you want more,
9907ad651b5SLars Ellenberg  * you need to use the "flexible" meta data format. */
991ae8bf312SLars Ellenberg #define MD_128MB_SECT (128LLU << 11)  /* 128 MB, unit sectors */
992ae8bf312SLars Ellenberg #define MD_4kB_SECT	 8
993ae8bf312SLars Ellenberg #define MD_32kB_SECT	64
994b411b363SPhilipp Reisner 
9957ad651b5SLars Ellenberg /* One activity log extent represents 4M of storage */
9967ad651b5SLars Ellenberg #define AL_EXTENT_SHIFT 22
997b411b363SPhilipp Reisner #define AL_EXTENT_SIZE (1<<AL_EXTENT_SHIFT)
998b411b363SPhilipp Reisner 
9997ad651b5SLars Ellenberg /* We could make these currently hardcoded constants configurable
10007ad651b5SLars Ellenberg  * variables at create-md time (or even re-configurable at runtime?).
10017ad651b5SLars Ellenberg  * Which will require some more changes to the DRBD "super block"
10027ad651b5SLars Ellenberg  * and attach code.
10037ad651b5SLars Ellenberg  *
10047ad651b5SLars Ellenberg  * updates per transaction:
10057ad651b5SLars Ellenberg  *   This many changes to the active set can be logged with one transaction.
10067ad651b5SLars Ellenberg  *   This number is arbitrary.
10077ad651b5SLars Ellenberg  * context per transaction:
10087ad651b5SLars Ellenberg  *   This many context extent numbers are logged with each transaction.
10097ad651b5SLars Ellenberg  *   This number is resulting from the transaction block size (4k), the layout
10107ad651b5SLars Ellenberg  *   of the transaction header, and the number of updates per transaction.
10117ad651b5SLars Ellenberg  *   See drbd_actlog.c:struct al_transaction_on_disk
10127ad651b5SLars Ellenberg  * */
10137ad651b5SLars Ellenberg #define AL_UPDATES_PER_TRANSACTION	 64	// arbitrary
10147ad651b5SLars Ellenberg #define AL_CONTEXT_PER_TRANSACTION	919	// (4096 - 36 - 6*64)/4
10157ad651b5SLars Ellenberg 
1016b411b363SPhilipp Reisner #if BITS_PER_LONG == 32
1017b411b363SPhilipp Reisner #define LN2_BPL 5
1018b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le32(A)
1019b411b363SPhilipp Reisner #define lel_to_cpu(A) le32_to_cpu(A)
1020b411b363SPhilipp Reisner #elif BITS_PER_LONG == 64
1021b411b363SPhilipp Reisner #define LN2_BPL 6
1022b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le64(A)
1023b411b363SPhilipp Reisner #define lel_to_cpu(A) le64_to_cpu(A)
1024b411b363SPhilipp Reisner #else
1025b411b363SPhilipp Reisner #error "LN2 of BITS_PER_LONG unknown!"
1026b411b363SPhilipp Reisner #endif
1027b411b363SPhilipp Reisner 
1028b411b363SPhilipp Reisner /* resync bitmap */
1029b411b363SPhilipp Reisner /* 16MB sized 'bitmap extent' to track syncer usage */
1030b411b363SPhilipp Reisner struct bm_extent {
1031b411b363SPhilipp Reisner 	int rs_left; /* number of bits set (out of sync) in this extent. */
1032b411b363SPhilipp Reisner 	int rs_failed; /* number of failed resync requests in this extent. */
1033b411b363SPhilipp Reisner 	unsigned long flags;
1034b411b363SPhilipp Reisner 	struct lc_element lce;
1035b411b363SPhilipp Reisner };
1036b411b363SPhilipp Reisner 
1037b411b363SPhilipp Reisner #define BME_NO_WRITES  0  /* bm_extent.flags: no more requests on this one! */
1038b411b363SPhilipp Reisner #define BME_LOCKED     1  /* bm_extent.flags: syncer active on this one. */
1039e3555d85SPhilipp Reisner #define BME_PRIORITY   2  /* finish resync IO on this extent ASAP! App IO waiting! */
1040b411b363SPhilipp Reisner 
1041b411b363SPhilipp Reisner /* drbd_bitmap.c */
1042b411b363SPhilipp Reisner /*
1043b411b363SPhilipp Reisner  * We need to store one bit for a block.
1044b411b363SPhilipp Reisner  * Example: 1GB disk @ 4096 byte blocks ==> we need 32 KB bitmap.
1045b411b363SPhilipp Reisner  * Bit 0 ==> local node thinks this block is binary identical on both nodes
1046b411b363SPhilipp Reisner  * Bit 1 ==> local node thinks this block needs to be synced.
1047b411b363SPhilipp Reisner  */
1048b411b363SPhilipp Reisner 
10498e26f9ccSPhilipp Reisner #define SLEEP_TIME (HZ/10)
10508e26f9ccSPhilipp Reisner 
105145dfffebSLars Ellenberg /* We do bitmap IO in units of 4k blocks.
105245dfffebSLars Ellenberg  * We also still have a hardcoded 4k per bit relation. */
1053b411b363SPhilipp Reisner #define BM_BLOCK_SHIFT	12			 /* 4k per bit */
1054b411b363SPhilipp Reisner #define BM_BLOCK_SIZE	 (1<<BM_BLOCK_SHIFT)
105545dfffebSLars Ellenberg /* mostly arbitrarily set the represented size of one bitmap extent,
105645dfffebSLars Ellenberg  * aka resync extent, to 16 MiB (which is also 512 Byte worth of bitmap
105745dfffebSLars Ellenberg  * at 4k per bit resolution) */
105845dfffebSLars Ellenberg #define BM_EXT_SHIFT	 24	/* 16 MiB per resync extent */
1059b411b363SPhilipp Reisner #define BM_EXT_SIZE	 (1<<BM_EXT_SHIFT)
1060b411b363SPhilipp Reisner 
1061b411b363SPhilipp Reisner #if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12)
1062b411b363SPhilipp Reisner #error "HAVE YOU FIXED drbdmeta AS WELL??"
1063b411b363SPhilipp Reisner #endif
1064b411b363SPhilipp Reisner 
1065b411b363SPhilipp Reisner /* thus many _storage_ sectors are described by one bit */
1066b411b363SPhilipp Reisner #define BM_SECT_TO_BIT(x)   ((x)>>(BM_BLOCK_SHIFT-9))
1067b411b363SPhilipp Reisner #define BM_BIT_TO_SECT(x)   ((sector_t)(x)<<(BM_BLOCK_SHIFT-9))
1068b411b363SPhilipp Reisner #define BM_SECT_PER_BIT     BM_BIT_TO_SECT(1)
1069b411b363SPhilipp Reisner 
1070b411b363SPhilipp Reisner /* bit to represented kilo byte conversion */
1071b411b363SPhilipp Reisner #define Bit2KB(bits) ((bits)<<(BM_BLOCK_SHIFT-10))
1072b411b363SPhilipp Reisner 
1073b411b363SPhilipp Reisner /* in which _bitmap_ extent (resp. sector) the bit for a certain
1074b411b363SPhilipp Reisner  * _storage_ sector is located in */
1075b411b363SPhilipp Reisner #define BM_SECT_TO_EXT(x)   ((x)>>(BM_EXT_SHIFT-9))
1076b411b363SPhilipp Reisner 
1077b411b363SPhilipp Reisner /* how much _storage_ sectors we have per bitmap sector */
1078b411b363SPhilipp Reisner #define BM_EXT_TO_SECT(x)   ((sector_t)(x) << (BM_EXT_SHIFT-9))
1079b411b363SPhilipp Reisner #define BM_SECT_PER_EXT     BM_EXT_TO_SECT(1)
1080b411b363SPhilipp Reisner 
1081b411b363SPhilipp Reisner /* in one sector of the bitmap, we have this many activity_log extents. */
1082b411b363SPhilipp Reisner #define AL_EXT_PER_BM_SECT  (1 << (BM_EXT_SHIFT - AL_EXTENT_SHIFT))
1083b411b363SPhilipp Reisner 
1084b411b363SPhilipp Reisner #define BM_BLOCKS_PER_BM_EXT_B (BM_EXT_SHIFT - BM_BLOCK_SHIFT)
1085b411b363SPhilipp Reisner #define BM_BLOCKS_PER_BM_EXT_MASK  ((1<<BM_BLOCKS_PER_BM_EXT_B) - 1)
1086b411b363SPhilipp Reisner 
1087b411b363SPhilipp Reisner /* the extent in "PER_EXTENT" below is an activity log extent
1088b411b363SPhilipp Reisner  * we need that many (long words/bytes) to store the bitmap
1089b411b363SPhilipp Reisner  *		     of one AL_EXTENT_SIZE chunk of storage.
1090b411b363SPhilipp Reisner  * we can store the bitmap for that many AL_EXTENTS within
1091b411b363SPhilipp Reisner  * one sector of the _on_disk_ bitmap:
1092b411b363SPhilipp Reisner  * bit	 0	  bit 37   bit 38	     bit (512*8)-1
1093b411b363SPhilipp Reisner  *	     ...|........|........|.. // ..|........|
1094b411b363SPhilipp Reisner  * sect. 0	 `296	  `304			   ^(512*8*8)-1
1095b411b363SPhilipp Reisner  *
1096b411b363SPhilipp Reisner #define BM_WORDS_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / BITS_PER_LONG )
1097b411b363SPhilipp Reisner #define BM_BYTES_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / 8 )  // 128
1098b411b363SPhilipp Reisner #define BM_EXT_PER_SECT	    ( 512 / BM_BYTES_PER_EXTENT )	 //   4
1099b411b363SPhilipp Reisner  */
1100b411b363SPhilipp Reisner 
1101b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_32 (0xffffffffLU)
1102ae8bf312SLars Ellenberg /* we have a certain meta data variant that has a fixed on-disk size of 128
1103ae8bf312SLars Ellenberg  * MiB, of which 4k are our "superblock", and 32k are the fixed size activity
1104ae8bf312SLars Ellenberg  * log, leaving this many sectors for the bitmap.
1105ae8bf312SLars Ellenberg  */
1106ae8bf312SLars Ellenberg 
1107ae8bf312SLars Ellenberg #define DRBD_MAX_SECTORS_FIXED_BM \
1108ae8bf312SLars Ellenberg 	  ((MD_128MB_SECT - MD_32kB_SECT - MD_4kB_SECT) * (1LL<<(BM_EXT_SHIFT-9)))
1109ae8bf312SLars Ellenberg #if !defined(CONFIG_LBDAF) && BITS_PER_LONG == 32
1110b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_32
1111b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_32
1112b411b363SPhilipp Reisner #else
1113ae8bf312SLars Ellenberg #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_FIXED_BM
1114b411b363SPhilipp Reisner /* 16 TB in units of sectors */
1115b411b363SPhilipp Reisner #if BITS_PER_LONG == 32
1116b411b363SPhilipp Reisner /* adjust by one page worth of bitmap,
1117b411b363SPhilipp Reisner  * so we won't wrap around in drbd_bm_find_next_bit.
1118b411b363SPhilipp Reisner  * you should use 64bit OS for that much storage, anyways. */
1119b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff)
1120b411b363SPhilipp Reisner #else
11214b0715f0SLars Ellenberg /* we allow up to 1 PiB now on 64bit architecture with "flexible" meta data */
11224b0715f0SLars Ellenberg #define DRBD_MAX_SECTORS_FLEX (1UL << 51)
11234b0715f0SLars Ellenberg /* corresponds to (1UL << 38) bits right now. */
1124b411b363SPhilipp Reisner #endif
1125b411b363SPhilipp Reisner #endif
1126b411b363SPhilipp Reisner 
112723361cf3SLars Ellenberg /* BIO_MAX_SIZE is 256 * PAGE_CACHE_SIZE,
112823361cf3SLars Ellenberg  * so for typical PAGE_CACHE_SIZE of 4k, that is (1<<20) Byte.
112923361cf3SLars Ellenberg  * Since we may live in a mixed-platform cluster,
113023361cf3SLars Ellenberg  * we limit us to a platform agnostic constant here for now.
113123361cf3SLars Ellenberg  * A followup commit may allow even bigger BIO sizes,
113223361cf3SLars Ellenberg  * once we thought that through. */
113398683650SPhilipp Reisner #define DRBD_MAX_BIO_SIZE (1U << 20)
113423361cf3SLars Ellenberg #if DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE
113523361cf3SLars Ellenberg #error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE
113623361cf3SLars Ellenberg #endif
1137db141b2fSLars Ellenberg #define DRBD_MAX_BIO_SIZE_SAFE (1U << 12)       /* Works always = 4k */
1138b411b363SPhilipp Reisner 
113998683650SPhilipp Reisner #define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* Header 80 only allows packets up to 32KiB data */
114098683650SPhilipp Reisner #define DRBD_MAX_BIO_SIZE_P95    (1U << 17) /* Protocol 95 to 99 allows bios up to 128KiB */
1141b411b363SPhilipp Reisner 
1142b30ab791SAndreas Gruenbacher extern int  drbd_bm_init(struct drbd_device *device);
1143b30ab791SAndreas Gruenbacher extern int  drbd_bm_resize(struct drbd_device *device, sector_t sectors, int set_new_bits);
1144b30ab791SAndreas Gruenbacher extern void drbd_bm_cleanup(struct drbd_device *device);
1145b30ab791SAndreas Gruenbacher extern void drbd_bm_set_all(struct drbd_device *device);
1146b30ab791SAndreas Gruenbacher extern void drbd_bm_clear_all(struct drbd_device *device);
11474b0715f0SLars Ellenberg /* set/clear/test only a few bits at a time */
1148b411b363SPhilipp Reisner extern int  drbd_bm_set_bits(
1149b30ab791SAndreas Gruenbacher 		struct drbd_device *device, unsigned long s, unsigned long e);
1150b411b363SPhilipp Reisner extern int  drbd_bm_clear_bits(
1151b30ab791SAndreas Gruenbacher 		struct drbd_device *device, unsigned long s, unsigned long e);
11524b0715f0SLars Ellenberg extern int drbd_bm_count_bits(
1153b30ab791SAndreas Gruenbacher 	struct drbd_device *device, const unsigned long s, const unsigned long e);
11544b0715f0SLars Ellenberg /* bm_set_bits variant for use while holding drbd_bm_lock,
11554b0715f0SLars Ellenberg  * may process the whole bitmap in one go */
1156b30ab791SAndreas Gruenbacher extern void _drbd_bm_set_bits(struct drbd_device *device,
1157b411b363SPhilipp Reisner 		const unsigned long s, const unsigned long e);
1158b30ab791SAndreas Gruenbacher extern int  drbd_bm_test_bit(struct drbd_device *device, unsigned long bitnr);
1159b30ab791SAndreas Gruenbacher extern int  drbd_bm_e_weight(struct drbd_device *device, unsigned long enr);
1160b30ab791SAndreas Gruenbacher extern int  drbd_bm_write_page(struct drbd_device *device, unsigned int idx) __must_hold(local);
1161b30ab791SAndreas Gruenbacher extern int  drbd_bm_read(struct drbd_device *device) __must_hold(local);
1162b30ab791SAndreas Gruenbacher extern void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr);
1163b30ab791SAndreas Gruenbacher extern int  drbd_bm_write(struct drbd_device *device) __must_hold(local);
1164b30ab791SAndreas Gruenbacher extern int  drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local);
1165b30ab791SAndreas Gruenbacher extern int drbd_bm_write_all(struct drbd_device *device) __must_hold(local);
1166b30ab791SAndreas Gruenbacher extern int  drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local);
1167b30ab791SAndreas Gruenbacher extern size_t	     drbd_bm_words(struct drbd_device *device);
1168b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_bits(struct drbd_device *device);
1169b30ab791SAndreas Gruenbacher extern sector_t      drbd_bm_capacity(struct drbd_device *device);
11704b0715f0SLars Ellenberg 
11714b0715f0SLars Ellenberg #define DRBD_END_OF_BITMAP	(~(unsigned long)0)
1172b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
1173b411b363SPhilipp Reisner /* bm_find_next variants for use while you hold drbd_bm_lock() */
1174b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
1175b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_find_next_zero(struct drbd_device *device, unsigned long bm_fo);
1176b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_total_weight(struct drbd_device *device);
1177b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_total_weight(struct drbd_device *device);
1178b30ab791SAndreas Gruenbacher extern int drbd_bm_rs_done(struct drbd_device *device);
1179b411b363SPhilipp Reisner /* for receive_bitmap */
1180b30ab791SAndreas Gruenbacher extern void drbd_bm_merge_lel(struct drbd_device *device, size_t offset,
1181b411b363SPhilipp Reisner 		size_t number, unsigned long *buffer);
118219f843aaSLars Ellenberg /* for _drbd_send_bitmap */
1183b30ab791SAndreas Gruenbacher extern void drbd_bm_get_lel(struct drbd_device *device, size_t offset,
1184b411b363SPhilipp Reisner 		size_t number, unsigned long *buffer);
1185b411b363SPhilipp Reisner 
1186b30ab791SAndreas Gruenbacher extern void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags);
1187b30ab791SAndreas Gruenbacher extern void drbd_bm_unlock(struct drbd_device *device);
1188b411b363SPhilipp Reisner /* drbd_main.c */
1189b411b363SPhilipp Reisner 
1190b411b363SPhilipp Reisner extern struct kmem_cache *drbd_request_cache;
11916c852becSAndreas Gruenbacher extern struct kmem_cache *drbd_ee_cache;	/* peer requests */
1192b411b363SPhilipp Reisner extern struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
1193b411b363SPhilipp Reisner extern struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
1194b411b363SPhilipp Reisner extern mempool_t *drbd_request_mempool;
1195b411b363SPhilipp Reisner extern mempool_t *drbd_ee_mempool;
1196b411b363SPhilipp Reisner 
11974281808fSLars Ellenberg /* drbd's page pool, used to buffer data received from the peer,
11984281808fSLars Ellenberg  * or data requested by the peer.
11994281808fSLars Ellenberg  *
12004281808fSLars Ellenberg  * This does not have an emergency reserve.
12014281808fSLars Ellenberg  *
12024281808fSLars Ellenberg  * When allocating from this pool, it first takes pages from the pool.
12034281808fSLars Ellenberg  * Only if the pool is depleted will try to allocate from the system.
12044281808fSLars Ellenberg  *
12054281808fSLars Ellenberg  * The assumption is that pages taken from this pool will be processed,
12064281808fSLars Ellenberg  * and given back, "quickly", and then can be recycled, so we can avoid
12074281808fSLars Ellenberg  * frequent calls to alloc_page(), and still will be able to make progress even
12084281808fSLars Ellenberg  * under memory pressure.
12094281808fSLars Ellenberg  */
12104281808fSLars Ellenberg extern struct page *drbd_pp_pool;
1211b411b363SPhilipp Reisner extern spinlock_t   drbd_pp_lock;
1212b411b363SPhilipp Reisner extern int	    drbd_pp_vacant;
1213b411b363SPhilipp Reisner extern wait_queue_head_t drbd_pp_wait;
1214b411b363SPhilipp Reisner 
12154281808fSLars Ellenberg /* We also need a standard (emergency-reserve backed) page pool
12164281808fSLars Ellenberg  * for meta data IO (activity log, bitmap).
12174281808fSLars Ellenberg  * We can keep it global, as long as it is used as "N pages at a time".
12184281808fSLars Ellenberg  * 128 should be plenty, currently we probably can get away with as few as 1.
12194281808fSLars Ellenberg  */
12204281808fSLars Ellenberg #define DRBD_MIN_POOL_PAGES	128
12214281808fSLars Ellenberg extern mempool_t *drbd_md_io_page_pool;
12224281808fSLars Ellenberg 
12239476f39dSLars Ellenberg /* We also need to make sure we get a bio
12249476f39dSLars Ellenberg  * when we need it for housekeeping purposes */
12259476f39dSLars Ellenberg extern struct bio_set *drbd_md_io_bio_set;
12269476f39dSLars Ellenberg /* to allocate from that set */
12279476f39dSLars Ellenberg extern struct bio *bio_alloc_drbd(gfp_t gfp_mask);
12289476f39dSLars Ellenberg 
1229b411b363SPhilipp Reisner extern rwlock_t global_state_lock;
1230b411b363SPhilipp Reisner 
1231bde89a9eSAndreas Gruenbacher extern int conn_lowest_minor(struct drbd_connection *connection);
123259515a2eSAndreas Gruenbacher enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr);
123305a10ec7SAndreas Gruenbacher extern void drbd_destroy_device(struct kref *kref);
1234f82795d6SAndreas Gruenbacher extern void drbd_delete_device(struct drbd_device *mdev);
1235b411b363SPhilipp Reisner 
123677c556f6SAndreas Gruenbacher extern struct drbd_resource *drbd_create_resource(const char *name);
123777c556f6SAndreas Gruenbacher extern void drbd_free_resource(struct drbd_resource *resource);
123877c556f6SAndreas Gruenbacher 
1239eb6bea67SAndreas Gruenbacher extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts);
1240bde89a9eSAndreas Gruenbacher extern struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts);
124105a10ec7SAndreas Gruenbacher extern void drbd_destroy_connection(struct kref *kref);
1242bde89a9eSAndreas Gruenbacher extern struct drbd_connection *conn_get_by_addrs(void *my_addr, int my_addr_len,
1243089c075dSAndreas Gruenbacher 					    void *peer_addr, int peer_addr_len);
12444bc76048SAndreas Gruenbacher extern struct drbd_resource *drbd_find_resource(const char *name);
124577c556f6SAndreas Gruenbacher extern void drbd_destroy_resource(struct kref *kref);
1246bde89a9eSAndreas Gruenbacher extern void conn_free_crypto(struct drbd_connection *connection);
1247b411b363SPhilipp Reisner 
1248b411b363SPhilipp Reisner extern int proc_details;
1249b411b363SPhilipp Reisner 
1250b411b363SPhilipp Reisner /* drbd_req */
1251113fef9eSLars Ellenberg extern void do_submit(struct work_struct *ws);
125254761697SAndreas Gruenbacher extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
12535a7bbad2SChristoph Hellwig extern void drbd_make_request(struct request_queue *q, struct bio *bio);
1254b30ab791SAndreas Gruenbacher extern int drbd_read_remote(struct drbd_device *device, struct drbd_request *req);
1255b411b363SPhilipp Reisner extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec);
1256b411b363SPhilipp Reisner extern int is_valid_ar_handle(struct drbd_request *, sector_t);
1257b411b363SPhilipp Reisner 
1258b411b363SPhilipp Reisner 
1259b411b363SPhilipp Reisner /* drbd_nl.c */
12608432b314SLars Ellenberg extern int drbd_msg_put_info(const char *info);
1261b30ab791SAndreas Gruenbacher extern void drbd_suspend_io(struct drbd_device *device);
1262b30ab791SAndreas Gruenbacher extern void drbd_resume_io(struct drbd_device *device);
1263b411b363SPhilipp Reisner extern char *ppsize(char *buf, unsigned long long size);
126454761697SAndreas Gruenbacher extern sector_t drbd_new_dev_size(struct drbd_device *, struct drbd_backing_dev *, sector_t, int);
1265e96c9633SPhilipp Reisner enum determine_dev_size {
1266d752b269SPhilipp Reisner 	DS_ERROR_SHRINK = -3,
1267d752b269SPhilipp Reisner 	DS_ERROR_SPACE_MD = -2,
1268e96c9633SPhilipp Reisner 	DS_ERROR = -1,
1269e96c9633SPhilipp Reisner 	DS_UNCHANGED = 0,
1270e96c9633SPhilipp Reisner 	DS_SHRUNK = 1,
127157737adcSPhilipp Reisner 	DS_GREW = 2,
127257737adcSPhilipp Reisner 	DS_GREW_FROM_ZERO = 3,
1273e96c9633SPhilipp Reisner };
1274d752b269SPhilipp Reisner extern enum determine_dev_size
127554761697SAndreas Gruenbacher drbd_determine_dev_size(struct drbd_device *, enum dds_flags, struct resize_parms *) __must_hold(local);
127654761697SAndreas Gruenbacher extern void resync_after_online_grow(struct drbd_device *);
1277b30ab791SAndreas Gruenbacher extern void drbd_reconsider_max_bio_size(struct drbd_device *device);
1278b30ab791SAndreas Gruenbacher extern enum drbd_state_rv drbd_set_role(struct drbd_device *device,
1279bf885f8aSAndreas Gruenbacher 					enum drbd_role new_role,
1280b411b363SPhilipp Reisner 					int force);
1281bde89a9eSAndreas Gruenbacher extern bool conn_try_outdate_peer(struct drbd_connection *connection);
1282bde89a9eSAndreas Gruenbacher extern void conn_try_outdate_peer_async(struct drbd_connection *connection);
1283b30ab791SAndreas Gruenbacher extern int drbd_khelper(struct drbd_device *device, char *cmd);
1284b411b363SPhilipp Reisner 
1285b411b363SPhilipp Reisner /* drbd_worker.c */
1286*d40e5671SPhilipp Reisner /* bi_end_io handlers */
1287*d40e5671SPhilipp Reisner extern void drbd_md_io_complete(struct bio *bio, int error);
1288*d40e5671SPhilipp Reisner extern void drbd_peer_request_endio(struct bio *bio, int error);
1289*d40e5671SPhilipp Reisner extern void drbd_request_endio(struct bio *bio, int error);
1290b411b363SPhilipp Reisner extern int drbd_worker(struct drbd_thread *thi);
1291b30ab791SAndreas Gruenbacher enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
1292b30ab791SAndreas Gruenbacher void drbd_resync_after_changed(struct drbd_device *device);
1293b30ab791SAndreas Gruenbacher extern void drbd_start_resync(struct drbd_device *device, enum drbd_conns side);
1294b30ab791SAndreas Gruenbacher extern void resume_next_sg(struct drbd_device *device);
1295b30ab791SAndreas Gruenbacher extern void suspend_other_sg(struct drbd_device *device);
1296b30ab791SAndreas Gruenbacher extern int drbd_resync_finished(struct drbd_device *device);
1297b411b363SPhilipp Reisner /* maybe rather drbd_main.c ? */
1298b30ab791SAndreas Gruenbacher extern void *drbd_md_get_buffer(struct drbd_device *device);
1299b30ab791SAndreas Gruenbacher extern void drbd_md_put_buffer(struct drbd_device *device);
1300b30ab791SAndreas Gruenbacher extern int drbd_md_sync_page_io(struct drbd_device *device,
1301b411b363SPhilipp Reisner 		struct drbd_backing_dev *bdev, sector_t sector, int rw);
130254761697SAndreas Gruenbacher extern void drbd_ov_out_of_sync_found(struct drbd_device *, sector_t, int);
1303b30ab791SAndreas Gruenbacher extern void wait_until_done_or_force_detached(struct drbd_device *device,
130444edfb0dSLars Ellenberg 		struct drbd_backing_dev *bdev, unsigned int *done);
1305b30ab791SAndreas Gruenbacher extern void drbd_rs_controller_reset(struct drbd_device *device);
1306b411b363SPhilipp Reisner 
1307b30ab791SAndreas Gruenbacher static inline void ov_out_of_sync_print(struct drbd_device *device)
1308b411b363SPhilipp Reisner {
1309b30ab791SAndreas Gruenbacher 	if (device->ov_last_oos_size) {
1310d0180171SAndreas Gruenbacher 		drbd_err(device, "Out of sync: start=%llu, size=%lu (sectors)\n",
1311b30ab791SAndreas Gruenbacher 		     (unsigned long long)device->ov_last_oos_start,
1312b30ab791SAndreas Gruenbacher 		     (unsigned long)device->ov_last_oos_size);
1313b411b363SPhilipp Reisner 	}
1314b30ab791SAndreas Gruenbacher 	device->ov_last_oos_size = 0;
1315b411b363SPhilipp Reisner }
1316b411b363SPhilipp Reisner 
1317b411b363SPhilipp Reisner 
131879a3c8d3SAndreas Gruenbacher extern void drbd_csum_bio(struct crypto_hash *, struct bio *, void *);
131979a3c8d3SAndreas Gruenbacher extern void drbd_csum_ee(struct crypto_hash *, struct drbd_peer_request *, void *);
1320b411b363SPhilipp Reisner /* worker callbacks */
132199920dc5SAndreas Gruenbacher extern int w_e_end_data_req(struct drbd_work *, int);
132299920dc5SAndreas Gruenbacher extern int w_e_end_rsdata_req(struct drbd_work *, int);
132399920dc5SAndreas Gruenbacher extern int w_e_end_csum_rs_req(struct drbd_work *, int);
132499920dc5SAndreas Gruenbacher extern int w_e_end_ov_reply(struct drbd_work *, int);
132599920dc5SAndreas Gruenbacher extern int w_e_end_ov_req(struct drbd_work *, int);
132699920dc5SAndreas Gruenbacher extern int w_ov_finished(struct drbd_work *, int);
132799920dc5SAndreas Gruenbacher extern int w_resync_timer(struct drbd_work *, int);
132899920dc5SAndreas Gruenbacher extern int w_send_write_hint(struct drbd_work *, int);
132999920dc5SAndreas Gruenbacher extern int w_send_dblock(struct drbd_work *, int);
133099920dc5SAndreas Gruenbacher extern int w_send_read_req(struct drbd_work *, int);
133199920dc5SAndreas Gruenbacher extern int w_e_reissue(struct drbd_work *, int);
133299920dc5SAndreas Gruenbacher extern int w_restart_disk_io(struct drbd_work *, int);
13338f7bed77SAndreas Gruenbacher extern int w_send_out_of_sync(struct drbd_work *, int);
133499920dc5SAndreas Gruenbacher extern int w_start_resync(struct drbd_work *, int);
1335b411b363SPhilipp Reisner 
1336b411b363SPhilipp Reisner extern void resync_timer_fn(unsigned long data);
1337370a43e7SPhilipp Reisner extern void start_resync_timer_fn(unsigned long data);
1338b411b363SPhilipp Reisner 
1339b411b363SPhilipp Reisner /* drbd_receiver.c */
1340753c6191SAndreas Gruenbacher extern int drbd_receiver(struct drbd_thread *thi);
1341753c6191SAndreas Gruenbacher extern int drbd_asender(struct drbd_thread *thi);
1342b30ab791SAndreas Gruenbacher extern int drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector);
134354761697SAndreas Gruenbacher extern int drbd_submit_peer_request(struct drbd_device *,
1344fbe29decSAndreas Gruenbacher 				    struct drbd_peer_request *, const unsigned,
1345fbe29decSAndreas Gruenbacher 				    const int);
134654761697SAndreas Gruenbacher extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
134769a22773SAndreas Gruenbacher extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
13480db55363SAndreas Gruenbacher 						     sector_t, unsigned int,
1349f6ffca9fSAndreas Gruenbacher 						     gfp_t) __must_hold(local);
135054761697SAndreas Gruenbacher extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *,
1351f6ffca9fSAndreas Gruenbacher 				 int);
13523967deb1SAndreas Gruenbacher #define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0)
13533967deb1SAndreas Gruenbacher #define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1)
135469a22773SAndreas Gruenbacher extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
1355b30ab791SAndreas Gruenbacher extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
1356b30ab791SAndreas Gruenbacher extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
135769a22773SAndreas Gruenbacher extern int drbd_connected(struct drbd_peer_device *);
1358b411b363SPhilipp Reisner 
1359ed439848SLars Ellenberg /* Yes, there is kernel_setsockopt, but only since 2.6.18.
1360ed439848SLars Ellenberg  * So we have our own copy of it here. */
1361b411b363SPhilipp Reisner static inline int drbd_setsockopt(struct socket *sock, int level, int optname,
1362ed439848SLars Ellenberg 				  char *optval, int optlen)
1363b411b363SPhilipp Reisner {
1364ed439848SLars Ellenberg 	mm_segment_t oldfs = get_fs();
1365ed439848SLars Ellenberg 	char __user *uoptval;
1366b411b363SPhilipp Reisner 	int err;
1367ed439848SLars Ellenberg 
1368ed439848SLars Ellenberg 	uoptval = (char __user __force *)optval;
1369ed439848SLars Ellenberg 
1370ed439848SLars Ellenberg 	set_fs(KERNEL_DS);
1371b411b363SPhilipp Reisner 	if (level == SOL_SOCKET)
1372ed439848SLars Ellenberg 		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
1373b411b363SPhilipp Reisner 	else
1374ed439848SLars Ellenberg 		err = sock->ops->setsockopt(sock, level, optname, uoptval,
1375b411b363SPhilipp Reisner 					    optlen);
1376ed439848SLars Ellenberg 	set_fs(oldfs);
1377b411b363SPhilipp Reisner 	return err;
1378b411b363SPhilipp Reisner }
1379b411b363SPhilipp Reisner 
1380b411b363SPhilipp Reisner static inline void drbd_tcp_cork(struct socket *sock)
1381b411b363SPhilipp Reisner {
1382ed439848SLars Ellenberg 	int val = 1;
1383b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
1384ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1385b411b363SPhilipp Reisner }
1386b411b363SPhilipp Reisner 
1387b411b363SPhilipp Reisner static inline void drbd_tcp_uncork(struct socket *sock)
1388b411b363SPhilipp Reisner {
1389ed439848SLars Ellenberg 	int val = 0;
1390b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
1391ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1392b411b363SPhilipp Reisner }
1393b411b363SPhilipp Reisner 
1394b411b363SPhilipp Reisner static inline void drbd_tcp_nodelay(struct socket *sock)
1395b411b363SPhilipp Reisner {
1396ed439848SLars Ellenberg 	int val = 1;
1397b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY,
1398ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1399b411b363SPhilipp Reisner }
1400b411b363SPhilipp Reisner 
1401b411b363SPhilipp Reisner static inline void drbd_tcp_quickack(struct socket *sock)
1402b411b363SPhilipp Reisner {
1403ed439848SLars Ellenberg 	int val = 2;
1404b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
1405ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1406b411b363SPhilipp Reisner }
1407b411b363SPhilipp Reisner 
1408*d40e5671SPhilipp Reisner /* sets the number of 512 byte sectors of our virtual device */
1409*d40e5671SPhilipp Reisner static inline void drbd_set_my_capacity(struct drbd_device *device,
1410*d40e5671SPhilipp Reisner 					sector_t size)
1411*d40e5671SPhilipp Reisner {
1412*d40e5671SPhilipp Reisner 	/* set_capacity(device->this_bdev->bd_disk, size); */
1413*d40e5671SPhilipp Reisner 	set_capacity(device->vdisk, size);
1414*d40e5671SPhilipp Reisner 	device->this_bdev->bd_inode->i_size = (loff_t)size << 9;
1415*d40e5671SPhilipp Reisner }
1416*d40e5671SPhilipp Reisner 
1417*d40e5671SPhilipp Reisner /*
1418*d40e5671SPhilipp Reisner  * used to submit our private bio
1419*d40e5671SPhilipp Reisner  */
1420*d40e5671SPhilipp Reisner static inline void drbd_generic_make_request(struct drbd_device *device,
1421*d40e5671SPhilipp Reisner 					     int fault_type, struct bio *bio)
1422*d40e5671SPhilipp Reisner {
1423*d40e5671SPhilipp Reisner 	__release(local);
1424*d40e5671SPhilipp Reisner 	if (!bio->bi_bdev) {
1425*d40e5671SPhilipp Reisner 		printk(KERN_ERR "drbd%d: drbd_generic_make_request: "
1426*d40e5671SPhilipp Reisner 				"bio->bi_bdev == NULL\n",
1427*d40e5671SPhilipp Reisner 		       device_to_minor(device));
1428*d40e5671SPhilipp Reisner 		dump_stack();
1429*d40e5671SPhilipp Reisner 		bio_endio(bio, -ENODEV);
1430*d40e5671SPhilipp Reisner 		return;
1431*d40e5671SPhilipp Reisner 	}
1432*d40e5671SPhilipp Reisner 
1433*d40e5671SPhilipp Reisner 	if (drbd_insert_fault(device, fault_type))
1434*d40e5671SPhilipp Reisner 		bio_endio(bio, -EIO);
1435*d40e5671SPhilipp Reisner 	else
1436*d40e5671SPhilipp Reisner 		generic_make_request(bio);
1437*d40e5671SPhilipp Reisner }
1438*d40e5671SPhilipp Reisner 
1439bde89a9eSAndreas Gruenbacher void drbd_bump_write_ordering(struct drbd_connection *connection, enum write_ordering_e wo);
1440b411b363SPhilipp Reisner 
1441b411b363SPhilipp Reisner /* drbd_proc.c */
1442b411b363SPhilipp Reisner extern struct proc_dir_entry *drbd_proc;
14437d4e9d09SEmese Revfy extern const struct file_operations drbd_proc_fops;
1444b411b363SPhilipp Reisner extern const char *drbd_conn_str(enum drbd_conns s);
1445b411b363SPhilipp Reisner extern const char *drbd_role_str(enum drbd_role s);
1446b411b363SPhilipp Reisner 
1447b411b363SPhilipp Reisner /* drbd_actlog.c */
1448b30ab791SAndreas Gruenbacher extern int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i);
1449b30ab791SAndreas Gruenbacher extern void drbd_al_begin_io_commit(struct drbd_device *device, bool delegate);
1450b30ab791SAndreas Gruenbacher extern bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i);
1451b30ab791SAndreas Gruenbacher extern void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i, bool delegate);
1452b30ab791SAndreas Gruenbacher extern void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i);
1453b30ab791SAndreas Gruenbacher extern void drbd_rs_complete_io(struct drbd_device *device, sector_t sector);
1454b30ab791SAndreas Gruenbacher extern int drbd_rs_begin_io(struct drbd_device *device, sector_t sector);
1455b30ab791SAndreas Gruenbacher extern int drbd_try_rs_begin_io(struct drbd_device *device, sector_t sector);
1456b30ab791SAndreas Gruenbacher extern void drbd_rs_cancel_all(struct drbd_device *device);
1457b30ab791SAndreas Gruenbacher extern int drbd_rs_del_all(struct drbd_device *device);
1458b30ab791SAndreas Gruenbacher extern void drbd_rs_failed_io(struct drbd_device *device,
1459b411b363SPhilipp Reisner 		sector_t sector, int size);
1460b30ab791SAndreas Gruenbacher extern void drbd_advance_rs_marks(struct drbd_device *device, unsigned long still_to_go);
1461b30ab791SAndreas Gruenbacher extern void __drbd_set_in_sync(struct drbd_device *device, sector_t sector,
1462b411b363SPhilipp Reisner 		int size, const char *file, const unsigned int line);
1463b30ab791SAndreas Gruenbacher #define drbd_set_in_sync(device, sector, size) \
1464b30ab791SAndreas Gruenbacher 	__drbd_set_in_sync(device, sector, size, __FILE__, __LINE__)
1465b30ab791SAndreas Gruenbacher extern int __drbd_set_out_of_sync(struct drbd_device *device, sector_t sector,
1466b411b363SPhilipp Reisner 		int size, const char *file, const unsigned int line);
1467b30ab791SAndreas Gruenbacher #define drbd_set_out_of_sync(device, sector, size) \
1468b30ab791SAndreas Gruenbacher 	__drbd_set_out_of_sync(device, sector, size, __FILE__, __LINE__)
1469b30ab791SAndreas Gruenbacher extern void drbd_al_shrink(struct drbd_device *device);
147054761697SAndreas Gruenbacher extern int drbd_initialize_al(struct drbd_device *, void *);
1471b411b363SPhilipp Reisner 
1472b411b363SPhilipp Reisner /* drbd_nl.c */
14733b98c0c2SLars Ellenberg /* state info broadcast */
14743b98c0c2SLars Ellenberg struct sib_info {
14753b98c0c2SLars Ellenberg 	enum drbd_state_info_bcast_reason sib_reason;
14763b98c0c2SLars Ellenberg 	union {
14773b98c0c2SLars Ellenberg 		struct {
14783b98c0c2SLars Ellenberg 			char *helper_name;
14793b98c0c2SLars Ellenberg 			unsigned helper_exit_code;
14803b98c0c2SLars Ellenberg 		};
14813b98c0c2SLars Ellenberg 		struct {
14823b98c0c2SLars Ellenberg 			union drbd_state os;
14833b98c0c2SLars Ellenberg 			union drbd_state ns;
14843b98c0c2SLars Ellenberg 		};
14853b98c0c2SLars Ellenberg 	};
14863b98c0c2SLars Ellenberg };
1487b30ab791SAndreas Gruenbacher void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
1488b411b363SPhilipp Reisner 
1489b411b363SPhilipp Reisner /*
1490b411b363SPhilipp Reisner  * inline helper functions
1491b411b363SPhilipp Reisner  *************************/
1492b411b363SPhilipp Reisner 
149345bb912bSLars Ellenberg /* see also page_chain_add and friends in drbd_receiver.c */
149445bb912bSLars Ellenberg static inline struct page *page_chain_next(struct page *page)
149545bb912bSLars Ellenberg {
149645bb912bSLars Ellenberg 	return (struct page *)page_private(page);
149745bb912bSLars Ellenberg }
149845bb912bSLars Ellenberg #define page_chain_for_each(page) \
149945bb912bSLars Ellenberg 	for (; page && ({ prefetch(page_chain_next(page)); 1; }); \
150045bb912bSLars Ellenberg 			page = page_chain_next(page))
150145bb912bSLars Ellenberg #define page_chain_for_each_safe(page, n) \
150245bb912bSLars Ellenberg 	for (; page && ({ n = page_chain_next(page); 1; }); page = n)
150345bb912bSLars Ellenberg 
150445bb912bSLars Ellenberg 
1505045417f7SAndreas Gruenbacher static inline int drbd_peer_req_has_active_page(struct drbd_peer_request *peer_req)
150645bb912bSLars Ellenberg {
1507db830c46SAndreas Gruenbacher 	struct page *page = peer_req->pages;
150845bb912bSLars Ellenberg 	page_chain_for_each(page) {
150945bb912bSLars Ellenberg 		if (page_count(page) > 1)
151045bb912bSLars Ellenberg 			return 1;
151145bb912bSLars Ellenberg 	}
151245bb912bSLars Ellenberg 	return 0;
151345bb912bSLars Ellenberg }
151445bb912bSLars Ellenberg 
1515bf885f8aSAndreas Gruenbacher static inline enum drbd_state_rv
1516b30ab791SAndreas Gruenbacher _drbd_set_state(struct drbd_device *device, union drbd_state ns,
1517bf885f8aSAndreas Gruenbacher 		enum chg_state_flags flags, struct completion *done)
1518b411b363SPhilipp Reisner {
1519bf885f8aSAndreas Gruenbacher 	enum drbd_state_rv rv;
1520b411b363SPhilipp Reisner 
1521b411b363SPhilipp Reisner 	read_lock(&global_state_lock);
1522b30ab791SAndreas Gruenbacher 	rv = __drbd_set_state(device, ns, flags, done);
1523b411b363SPhilipp Reisner 	read_unlock(&global_state_lock);
1524b411b363SPhilipp Reisner 
1525b411b363SPhilipp Reisner 	return rv;
1526b411b363SPhilipp Reisner }
1527b411b363SPhilipp Reisner 
1528b30ab791SAndreas Gruenbacher static inline union drbd_state drbd_read_state(struct drbd_device *device)
1529b411b363SPhilipp Reisner {
15306bbf53caSAndreas Gruenbacher 	struct drbd_resource *resource = device->resource;
153178bae59bSPhilipp Reisner 	union drbd_state rv;
153278bae59bSPhilipp Reisner 
1533b30ab791SAndreas Gruenbacher 	rv.i = device->state.i;
15346bbf53caSAndreas Gruenbacher 	rv.susp = resource->susp;
15356bbf53caSAndreas Gruenbacher 	rv.susp_nod = resource->susp_nod;
15366bbf53caSAndreas Gruenbacher 	rv.susp_fen = resource->susp_fen;
153778bae59bSPhilipp Reisner 
153878bae59bSPhilipp Reisner 	return rv;
1539b411b363SPhilipp Reisner }
1540b411b363SPhilipp Reisner 
1541383606e0SLars Ellenberg enum drbd_force_detach_flags {
1542a2a3c74fSLars Ellenberg 	DRBD_READ_ERROR,
1543a2a3c74fSLars Ellenberg 	DRBD_WRITE_ERROR,
1544383606e0SLars Ellenberg 	DRBD_META_IO_ERROR,
1545383606e0SLars Ellenberg 	DRBD_FORCE_DETACH,
1546383606e0SLars Ellenberg };
1547383606e0SLars Ellenberg 
1548b411b363SPhilipp Reisner #define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
1549b30ab791SAndreas Gruenbacher static inline void __drbd_chk_io_error_(struct drbd_device *device,
1550a2a3c74fSLars Ellenberg 		enum drbd_force_detach_flags df,
1551383606e0SLars Ellenberg 		const char *where)
1552b411b363SPhilipp Reisner {
1553daeda1ccSPhilipp Reisner 	enum drbd_io_error_p ep;
1554daeda1ccSPhilipp Reisner 
1555daeda1ccSPhilipp Reisner 	rcu_read_lock();
1556b30ab791SAndreas Gruenbacher 	ep = rcu_dereference(device->ldev->disk_conf)->on_io_error;
1557daeda1ccSPhilipp Reisner 	rcu_read_unlock();
1558daeda1ccSPhilipp Reisner 	switch (ep) {
1559daeda1ccSPhilipp Reisner 	case EP_PASS_ON: /* FIXME would this be better named "Ignore"? */
1560a2a3c74fSLars Ellenberg 		if (df == DRBD_READ_ERROR || df == DRBD_WRITE_ERROR) {
15617383506cSLars Ellenberg 			if (__ratelimit(&drbd_ratelimit_state))
1562d0180171SAndreas Gruenbacher 				drbd_err(device, "Local IO failed in %s.\n", where);
1563b30ab791SAndreas Gruenbacher 			if (device->state.disk > D_INCONSISTENT)
1564b30ab791SAndreas Gruenbacher 				_drbd_set_state(_NS(device, disk, D_INCONSISTENT), CS_HARD, NULL);
1565b411b363SPhilipp Reisner 			break;
1566b411b363SPhilipp Reisner 		}
1567a2a3c74fSLars Ellenberg 		/* NOTE fall through for DRBD_META_IO_ERROR or DRBD_FORCE_DETACH */
1568b411b363SPhilipp Reisner 	case EP_DETACH:
1569b411b363SPhilipp Reisner 	case EP_CALL_HELPER:
1570a2a3c74fSLars Ellenberg 		/* Remember whether we saw a READ or WRITE error.
1571a2a3c74fSLars Ellenberg 		 *
1572a2a3c74fSLars Ellenberg 		 * Recovery of the affected area for WRITE failure is covered
1573a2a3c74fSLars Ellenberg 		 * by the activity log.
1574a2a3c74fSLars Ellenberg 		 * READ errors may fall outside that area though. Certain READ
1575a2a3c74fSLars Ellenberg 		 * errors can be "healed" by writing good data to the affected
1576a2a3c74fSLars Ellenberg 		 * blocks, which triggers block re-allocation in lower layers.
1577a2a3c74fSLars Ellenberg 		 *
1578a2a3c74fSLars Ellenberg 		 * If we can not write the bitmap after a READ error,
1579a2a3c74fSLars Ellenberg 		 * we may need to trigger a full sync (see w_go_diskless()).
1580a2a3c74fSLars Ellenberg 		 *
1581a2a3c74fSLars Ellenberg 		 * Force-detach is not really an IO error, but rather a
1582a2a3c74fSLars Ellenberg 		 * desperate measure to try to deal with a completely
1583a2a3c74fSLars Ellenberg 		 * unresponsive lower level IO stack.
1584a2a3c74fSLars Ellenberg 		 * Still it should be treated as a WRITE error.
1585a2a3c74fSLars Ellenberg 		 *
1586a2a3c74fSLars Ellenberg 		 * Meta IO error is always WRITE error:
1587a2a3c74fSLars Ellenberg 		 * we read meta data only once during attach,
1588a2a3c74fSLars Ellenberg 		 * which will fail in case of errors.
1589a2a3c74fSLars Ellenberg 		 */
1590b30ab791SAndreas Gruenbacher 		set_bit(WAS_IO_ERROR, &device->flags);
1591a2a3c74fSLars Ellenberg 		if (df == DRBD_READ_ERROR)
1592b30ab791SAndreas Gruenbacher 			set_bit(WAS_READ_ERROR, &device->flags);
1593a2a3c74fSLars Ellenberg 		if (df == DRBD_FORCE_DETACH)
1594b30ab791SAndreas Gruenbacher 			set_bit(FORCE_DETACH, &device->flags);
1595b30ab791SAndreas Gruenbacher 		if (device->state.disk > D_FAILED) {
1596b30ab791SAndreas Gruenbacher 			_drbd_set_state(_NS(device, disk, D_FAILED), CS_HARD, NULL);
1597d0180171SAndreas Gruenbacher 			drbd_err(device,
159882f59cc6SLars Ellenberg 				"Local IO failed in %s. Detaching...\n", where);
1599b411b363SPhilipp Reisner 		}
1600b411b363SPhilipp Reisner 		break;
1601b411b363SPhilipp Reisner 	}
1602b411b363SPhilipp Reisner }
1603b411b363SPhilipp Reisner 
1604b411b363SPhilipp Reisner /**
1605b411b363SPhilipp Reisner  * drbd_chk_io_error: Handle the on_io_error setting, should be called from all io completion handlers
1606b30ab791SAndreas Gruenbacher  * @device:	 DRBD device.
1607b411b363SPhilipp Reisner  * @error:	 Error code passed to the IO completion callback
1608b411b363SPhilipp Reisner  * @forcedetach: Force detach. I.e. the error happened while accessing the meta data
1609b411b363SPhilipp Reisner  *
1610b411b363SPhilipp Reisner  * See also drbd_main.c:after_state_ch() if (os.disk > D_FAILED && ns.disk == D_FAILED)
1611b411b363SPhilipp Reisner  */
1612b411b363SPhilipp Reisner #define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__)
1613b30ab791SAndreas Gruenbacher static inline void drbd_chk_io_error_(struct drbd_device *device,
1614383606e0SLars Ellenberg 	int error, enum drbd_force_detach_flags forcedetach, const char *where)
1615b411b363SPhilipp Reisner {
1616b411b363SPhilipp Reisner 	if (error) {
1617b411b363SPhilipp Reisner 		unsigned long flags;
16180500813fSAndreas Gruenbacher 		spin_lock_irqsave(&device->resource->req_lock, flags);
1619b30ab791SAndreas Gruenbacher 		__drbd_chk_io_error_(device, forcedetach, where);
16200500813fSAndreas Gruenbacher 		spin_unlock_irqrestore(&device->resource->req_lock, flags);
1621b411b363SPhilipp Reisner 	}
1622b411b363SPhilipp Reisner }
1623b411b363SPhilipp Reisner 
1624b411b363SPhilipp Reisner 
1625b411b363SPhilipp Reisner /**
1626b411b363SPhilipp Reisner  * drbd_md_first_sector() - Returns the first sector number of the meta data area
1627b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1628b411b363SPhilipp Reisner  *
1629b411b363SPhilipp Reisner  * BTW, for internal meta data, this happens to be the maximum capacity
1630b411b363SPhilipp Reisner  * we could agree upon with our peer node.
1631b411b363SPhilipp Reisner  */
163268e41a43SLars Ellenberg static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
1633b411b363SPhilipp Reisner {
163468e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1635b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1636b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1637b411b363SPhilipp Reisner 		return bdev->md.md_offset + bdev->md.bm_offset;
1638b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1639b411b363SPhilipp Reisner 	default:
1640b411b363SPhilipp Reisner 		return bdev->md.md_offset;
1641b411b363SPhilipp Reisner 	}
1642b411b363SPhilipp Reisner }
1643b411b363SPhilipp Reisner 
1644b411b363SPhilipp Reisner /**
1645b411b363SPhilipp Reisner  * drbd_md_last_sector() - Return the last sector number of the meta data area
1646b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1647b411b363SPhilipp Reisner  */
1648b411b363SPhilipp Reisner static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
1649b411b363SPhilipp Reisner {
165068e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1651b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1652b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1653ae8bf312SLars Ellenberg 		return bdev->md.md_offset + MD_4kB_SECT -1;
1654b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1655b411b363SPhilipp Reisner 	default:
1656ae8bf312SLars Ellenberg 		return bdev->md.md_offset + bdev->md.md_size_sect -1;
1657b411b363SPhilipp Reisner 	}
1658b411b363SPhilipp Reisner }
1659b411b363SPhilipp Reisner 
1660b411b363SPhilipp Reisner /* Returns the number of 512 byte sectors of the device */
1661b411b363SPhilipp Reisner static inline sector_t drbd_get_capacity(struct block_device *bdev)
1662b411b363SPhilipp Reisner {
1663b411b363SPhilipp Reisner 	/* return bdev ? get_capacity(bdev->bd_disk) : 0; */
166477304d2aSMike Snitzer 	return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0;
1665b411b363SPhilipp Reisner }
1666b411b363SPhilipp Reisner 
1667b411b363SPhilipp Reisner /**
1668b411b363SPhilipp Reisner  * drbd_get_max_capacity() - Returns the capacity we announce to out peer
1669b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1670b411b363SPhilipp Reisner  *
1671b411b363SPhilipp Reisner  * returns the capacity we announce to out peer.  we clip ourselves at the
1672b411b363SPhilipp Reisner  * various MAX_SECTORS, because if we don't, current implementation will
1673b411b363SPhilipp Reisner  * oops sooner or later
1674b411b363SPhilipp Reisner  */
1675b411b363SPhilipp Reisner static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
1676b411b363SPhilipp Reisner {
1677b411b363SPhilipp Reisner 	sector_t s;
1678daeda1ccSPhilipp Reisner 
167968e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1680b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1681b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1682b411b363SPhilipp Reisner 		s = drbd_get_capacity(bdev->backing_bdev)
1683b411b363SPhilipp Reisner 			? min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
168468e41a43SLars Ellenberg 				drbd_md_first_sector(bdev))
1685b411b363SPhilipp Reisner 			: 0;
1686b411b363SPhilipp Reisner 		break;
1687b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1688b411b363SPhilipp Reisner 		s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
1689b411b363SPhilipp Reisner 				drbd_get_capacity(bdev->backing_bdev));
1690b411b363SPhilipp Reisner 		/* clip at maximum size the meta device can support */
1691b411b363SPhilipp Reisner 		s = min_t(sector_t, s,
1692b411b363SPhilipp Reisner 			BM_EXT_TO_SECT(bdev->md.md_size_sect
1693b411b363SPhilipp Reisner 				     - bdev->md.bm_offset));
1694b411b363SPhilipp Reisner 		break;
1695b411b363SPhilipp Reisner 	default:
1696b411b363SPhilipp Reisner 		s = min_t(sector_t, DRBD_MAX_SECTORS,
1697b411b363SPhilipp Reisner 				drbd_get_capacity(bdev->backing_bdev));
1698b411b363SPhilipp Reisner 	}
1699b411b363SPhilipp Reisner 	return s;
1700b411b363SPhilipp Reisner }
1701b411b363SPhilipp Reisner 
1702b411b363SPhilipp Reisner /**
17033a4d4eb3SLars Ellenberg  * drbd_md_ss() - Return the sector number of our meta data super block
1704b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1705b411b363SPhilipp Reisner  */
17063a4d4eb3SLars Ellenberg static inline sector_t drbd_md_ss(struct drbd_backing_dev *bdev)
1707b411b363SPhilipp Reisner {
17083a4d4eb3SLars Ellenberg 	const int meta_dev_idx = bdev->md.meta_dev_idx;
1709daeda1ccSPhilipp Reisner 
17103a4d4eb3SLars Ellenberg 	if (meta_dev_idx == DRBD_MD_INDEX_FLEX_EXT)
1711b411b363SPhilipp Reisner 		return 0;
17123a4d4eb3SLars Ellenberg 
17133a4d4eb3SLars Ellenberg 	/* Since drbd08, internal meta data is always "flexible".
1714ae8bf312SLars Ellenberg 	 * position: last 4k aligned block of 4k size */
17153a4d4eb3SLars Ellenberg 	if (meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
17163a4d4eb3SLars Ellenberg 	    meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)
1717ae8bf312SLars Ellenberg 		return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) - 8;
17183a4d4eb3SLars Ellenberg 
17193a4d4eb3SLars Ellenberg 	/* external, some index; this is the old fixed size layout */
17203a4d4eb3SLars Ellenberg 	return MD_128MB_SECT * bdev->md.meta_dev_idx;
1721b411b363SPhilipp Reisner }
1722b411b363SPhilipp Reisner 
1723b411b363SPhilipp Reisner static inline void
1724b411b363SPhilipp Reisner drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w)
1725b411b363SPhilipp Reisner {
1726b411b363SPhilipp Reisner 	unsigned long flags;
1727b411b363SPhilipp Reisner 	spin_lock_irqsave(&q->q_lock, flags);
1728b411b363SPhilipp Reisner 	list_add(&w->list, &q->q);
1729b411b363SPhilipp Reisner 	spin_unlock_irqrestore(&q->q_lock, flags);
17308c0785a5SLars Ellenberg 	wake_up(&q->q_wait);
1731b411b363SPhilipp Reisner }
1732b411b363SPhilipp Reisner 
1733b411b363SPhilipp Reisner static inline void
1734b411b363SPhilipp Reisner drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
1735b411b363SPhilipp Reisner {
1736b411b363SPhilipp Reisner 	unsigned long flags;
1737b411b363SPhilipp Reisner 	spin_lock_irqsave(&q->q_lock, flags);
1738b411b363SPhilipp Reisner 	list_add_tail(&w->list, &q->q);
1739b411b363SPhilipp Reisner 	spin_unlock_irqrestore(&q->q_lock, flags);
17408c0785a5SLars Ellenberg 	wake_up(&q->q_wait);
1741b411b363SPhilipp Reisner }
1742b411b363SPhilipp Reisner 
1743b5043c5eSAndreas Gruenbacher extern void drbd_flush_workqueue(struct drbd_work_queue *work_queue);
1744b5043c5eSAndreas Gruenbacher 
1745bde89a9eSAndreas Gruenbacher static inline void wake_asender(struct drbd_connection *connection)
1746b411b363SPhilipp Reisner {
1747bde89a9eSAndreas Gruenbacher 	if (test_bit(SIGNAL_ASENDER, &connection->flags))
1748bde89a9eSAndreas Gruenbacher 		force_sig(DRBD_SIG, connection->asender.task);
1749b411b363SPhilipp Reisner }
1750b411b363SPhilipp Reisner 
1751bde89a9eSAndreas Gruenbacher static inline void request_ping(struct drbd_connection *connection)
1752b411b363SPhilipp Reisner {
1753bde89a9eSAndreas Gruenbacher 	set_bit(SEND_PING, &connection->flags);
1754bde89a9eSAndreas Gruenbacher 	wake_asender(connection);
1755b411b363SPhilipp Reisner }
1756b411b363SPhilipp Reisner 
1757bde89a9eSAndreas Gruenbacher extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
175869a22773SAndreas Gruenbacher extern void *drbd_prepare_command(struct drbd_peer_device *, struct drbd_socket *);
1759bde89a9eSAndreas Gruenbacher extern int conn_send_command(struct drbd_connection *, struct drbd_socket *,
1760dba58587SAndreas Gruenbacher 			     enum drbd_packet, unsigned int, void *,
1761dba58587SAndreas Gruenbacher 			     unsigned int);
176269a22773SAndreas Gruenbacher extern int drbd_send_command(struct drbd_peer_device *, struct drbd_socket *,
1763dba58587SAndreas Gruenbacher 			     enum drbd_packet, unsigned int, void *,
1764dba58587SAndreas Gruenbacher 			     unsigned int);
1765b411b363SPhilipp Reisner 
1766bde89a9eSAndreas Gruenbacher extern int drbd_send_ping(struct drbd_connection *connection);
1767bde89a9eSAndreas Gruenbacher extern int drbd_send_ping_ack(struct drbd_connection *connection);
176869a22773SAndreas Gruenbacher extern int drbd_send_state_req(struct drbd_peer_device *, union drbd_state, union drbd_state);
1769bde89a9eSAndreas Gruenbacher extern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state);
1770b411b363SPhilipp Reisner 
1771b411b363SPhilipp Reisner static inline void drbd_thread_stop(struct drbd_thread *thi)
1772b411b363SPhilipp Reisner {
177381e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, false, true);
1774b411b363SPhilipp Reisner }
1775b411b363SPhilipp Reisner 
1776b411b363SPhilipp Reisner static inline void drbd_thread_stop_nowait(struct drbd_thread *thi)
1777b411b363SPhilipp Reisner {
177881e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, false, false);
1779b411b363SPhilipp Reisner }
1780b411b363SPhilipp Reisner 
1781b411b363SPhilipp Reisner static inline void drbd_thread_restart_nowait(struct drbd_thread *thi)
1782b411b363SPhilipp Reisner {
178381e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, true, false);
1784b411b363SPhilipp Reisner }
1785b411b363SPhilipp Reisner 
1786b411b363SPhilipp Reisner /* counts how many answer packets packets we expect from our peer,
1787b411b363SPhilipp Reisner  * for either explicit application requests,
1788b411b363SPhilipp Reisner  * or implicit barrier packets as necessary.
1789b411b363SPhilipp Reisner  * increased:
1790b411b363SPhilipp Reisner  *  w_send_barrier
17918554df1cSAndreas Gruenbacher  *  _req_mod(req, QUEUE_FOR_NET_WRITE or QUEUE_FOR_NET_READ);
1792b411b363SPhilipp Reisner  *    it is much easier and equally valid to count what we queue for the
1793b411b363SPhilipp Reisner  *    worker, even before it actually was queued or send.
1794b411b363SPhilipp Reisner  *    (drbd_make_request_common; recovery path on read io-error)
1795b411b363SPhilipp Reisner  * decreased:
1796b411b363SPhilipp Reisner  *  got_BarrierAck (respective tl_clear, tl_clear_barrier)
17978554df1cSAndreas Gruenbacher  *  _req_mod(req, DATA_RECEIVED)
1798b411b363SPhilipp Reisner  *     [from receive_DataReply]
17998554df1cSAndreas Gruenbacher  *  _req_mod(req, WRITE_ACKED_BY_PEER or RECV_ACKED_BY_PEER or NEG_ACKED)
1800b411b363SPhilipp Reisner  *     [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)]
1801b411b363SPhilipp Reisner  *     for some reason it is NOT decreased in got_NegAck,
1802b411b363SPhilipp Reisner  *     but in the resulting cleanup code from report_params.
1803b411b363SPhilipp Reisner  *     we should try to remember the reason for that...
18048554df1cSAndreas Gruenbacher  *  _req_mod(req, SEND_FAILED or SEND_CANCELED)
18058554df1cSAndreas Gruenbacher  *  _req_mod(req, CONNECTION_LOST_WHILE_PENDING)
1806b411b363SPhilipp Reisner  *     [from tl_clear_barrier]
1807b411b363SPhilipp Reisner  */
1808b30ab791SAndreas Gruenbacher static inline void inc_ap_pending(struct drbd_device *device)
1809b411b363SPhilipp Reisner {
1810b30ab791SAndreas Gruenbacher 	atomic_inc(&device->ap_pending_cnt);
1811b411b363SPhilipp Reisner }
1812b411b363SPhilipp Reisner 
181349559d87SPhilipp Reisner #define ERR_IF_CNT_IS_NEGATIVE(which, func, line)			\
1814b30ab791SAndreas Gruenbacher 	if (atomic_read(&device->which) < 0)				\
1815d0180171SAndreas Gruenbacher 		drbd_err(device, "in %s:%d: " #which " = %d < 0 !\n",	\
181649559d87SPhilipp Reisner 			func, line,					\
1817b30ab791SAndreas Gruenbacher 			atomic_read(&device->which))
1818b411b363SPhilipp Reisner 
1819b30ab791SAndreas Gruenbacher #define dec_ap_pending(device) _dec_ap_pending(device, __FUNCTION__, __LINE__)
1820b30ab791SAndreas Gruenbacher static inline void _dec_ap_pending(struct drbd_device *device, const char *func, int line)
182149559d87SPhilipp Reisner {
1822b30ab791SAndreas Gruenbacher 	if (atomic_dec_and_test(&device->ap_pending_cnt))
1823b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
182449559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt, func, line);
182549559d87SPhilipp Reisner }
1826b411b363SPhilipp Reisner 
1827b411b363SPhilipp Reisner /* counts how many resync-related answers we still expect from the peer
1828b411b363SPhilipp Reisner  *		     increase			decrease
1829b411b363SPhilipp Reisner  * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY)
183025985edcSLucas De Marchi  * C_SYNC_SOURCE sends P_RS_DATA_REPLY   (and expects P_WRITE_ACK with ID_SYNCER)
1831b411b363SPhilipp Reisner  *					   (or P_NEG_ACK with ID_SYNCER)
1832b411b363SPhilipp Reisner  */
1833b30ab791SAndreas Gruenbacher static inline void inc_rs_pending(struct drbd_device *device)
1834b411b363SPhilipp Reisner {
1835b30ab791SAndreas Gruenbacher 	atomic_inc(&device->rs_pending_cnt);
1836b411b363SPhilipp Reisner }
1837b411b363SPhilipp Reisner 
1838b30ab791SAndreas Gruenbacher #define dec_rs_pending(device) _dec_rs_pending(device, __FUNCTION__, __LINE__)
1839b30ab791SAndreas Gruenbacher static inline void _dec_rs_pending(struct drbd_device *device, const char *func, int line)
184049559d87SPhilipp Reisner {
1841b30ab791SAndreas Gruenbacher 	atomic_dec(&device->rs_pending_cnt);
184249559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt, func, line);
184349559d87SPhilipp Reisner }
1844b411b363SPhilipp Reisner 
1845b411b363SPhilipp Reisner /* counts how many answers we still need to send to the peer.
1846b411b363SPhilipp Reisner  * increased on
1847b411b363SPhilipp Reisner  *  receive_Data	unless protocol A;
1848b411b363SPhilipp Reisner  *			we need to send a P_RECV_ACK (proto B)
1849b411b363SPhilipp Reisner  *			or P_WRITE_ACK (proto C)
1850b411b363SPhilipp Reisner  *  receive_RSDataReply (recv_resync_read) we need to send a P_WRITE_ACK
1851b411b363SPhilipp Reisner  *  receive_DataRequest (receive_RSDataRequest) we need to send back P_DATA
1852b411b363SPhilipp Reisner  *  receive_Barrier_*	we need to send a P_BARRIER_ACK
1853b411b363SPhilipp Reisner  */
1854b30ab791SAndreas Gruenbacher static inline void inc_unacked(struct drbd_device *device)
1855b411b363SPhilipp Reisner {
1856b30ab791SAndreas Gruenbacher 	atomic_inc(&device->unacked_cnt);
1857b411b363SPhilipp Reisner }
1858b411b363SPhilipp Reisner 
1859b30ab791SAndreas Gruenbacher #define dec_unacked(device) _dec_unacked(device, __FUNCTION__, __LINE__)
1860b30ab791SAndreas Gruenbacher static inline void _dec_unacked(struct drbd_device *device, const char *func, int line)
1861b411b363SPhilipp Reisner {
1862b30ab791SAndreas Gruenbacher 	atomic_dec(&device->unacked_cnt);
186349559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
1864b411b363SPhilipp Reisner }
1865b411b363SPhilipp Reisner 
1866b30ab791SAndreas Gruenbacher #define sub_unacked(device, n) _sub_unacked(device, n, __FUNCTION__, __LINE__)
1867b30ab791SAndreas Gruenbacher static inline void _sub_unacked(struct drbd_device *device, int n, const char *func, int line)
1868b411b363SPhilipp Reisner {
1869b30ab791SAndreas Gruenbacher 	atomic_sub(n, &device->unacked_cnt);
187049559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
1871b411b363SPhilipp Reisner }
1872b411b363SPhilipp Reisner 
1873b411b363SPhilipp Reisner /**
1874b30ab791SAndreas Gruenbacher  * get_ldev() - Increase the ref count on device->ldev. Returns 0 if there is no ldev
1875b411b363SPhilipp Reisner  * @M:		DRBD device.
1876b411b363SPhilipp Reisner  *
1877b30ab791SAndreas Gruenbacher  * You have to call put_ldev() when finished working with device->ldev.
1878b411b363SPhilipp Reisner  */
1879b411b363SPhilipp Reisner #define get_ldev(M) __cond_lock(local, _get_ldev_if_state(M,D_INCONSISTENT))
1880b411b363SPhilipp Reisner #define get_ldev_if_state(M,MINS) __cond_lock(local, _get_ldev_if_state(M,MINS))
1881b411b363SPhilipp Reisner 
1882b30ab791SAndreas Gruenbacher static inline void put_ldev(struct drbd_device *device)
1883b411b363SPhilipp Reisner {
1884b30ab791SAndreas Gruenbacher 	int i = atomic_dec_return(&device->local_cnt);
18859a0d9d03SLars Ellenberg 
18869a0d9d03SLars Ellenberg 	/* This may be called from some endio handler,
18879a0d9d03SLars Ellenberg 	 * so we must not sleep here. */
18889a0d9d03SLars Ellenberg 
1889b411b363SPhilipp Reisner 	__release(local);
18900b0ba1efSAndreas Gruenbacher 	D_ASSERT(device, i >= 0);
1891e9e6f3ecSLars Ellenberg 	if (i == 0) {
1892b30ab791SAndreas Gruenbacher 		if (device->state.disk == D_DISKLESS)
189382f59cc6SLars Ellenberg 			/* even internal references gone, safe to destroy */
1894b30ab791SAndreas Gruenbacher 			drbd_ldev_destroy(device);
1895b30ab791SAndreas Gruenbacher 		if (device->state.disk == D_FAILED) {
189682f59cc6SLars Ellenberg 			/* all application IO references gone. */
1897b30ab791SAndreas Gruenbacher 			if (!test_and_set_bit(GO_DISKLESS, &device->flags))
189884b8c06bSAndreas Gruenbacher 				drbd_queue_work(&first_peer_device(device)->connection->sender_work,
189984b8c06bSAndreas Gruenbacher 						&device->go_diskless);
19009114d795SLars Ellenberg 		}
1901b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
1902b411b363SPhilipp Reisner 	}
1903e9e6f3ecSLars Ellenberg }
1904b411b363SPhilipp Reisner 
1905b411b363SPhilipp Reisner #ifndef __CHECKER__
1906b30ab791SAndreas Gruenbacher static inline int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins)
1907b411b363SPhilipp Reisner {
1908b411b363SPhilipp Reisner 	int io_allowed;
1909b411b363SPhilipp Reisner 
191082f59cc6SLars Ellenberg 	/* never get a reference while D_DISKLESS */
1911b30ab791SAndreas Gruenbacher 	if (device->state.disk == D_DISKLESS)
191282f59cc6SLars Ellenberg 		return 0;
191382f59cc6SLars Ellenberg 
1914b30ab791SAndreas Gruenbacher 	atomic_inc(&device->local_cnt);
1915b30ab791SAndreas Gruenbacher 	io_allowed = (device->state.disk >= mins);
1916b411b363SPhilipp Reisner 	if (!io_allowed)
1917b30ab791SAndreas Gruenbacher 		put_ldev(device);
1918b411b363SPhilipp Reisner 	return io_allowed;
1919b411b363SPhilipp Reisner }
1920b411b363SPhilipp Reisner #else
1921b30ab791SAndreas Gruenbacher extern int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins);
1922b411b363SPhilipp Reisner #endif
1923b411b363SPhilipp Reisner 
1924b411b363SPhilipp Reisner /* you must have an "get_ldev" reference */
1925b30ab791SAndreas Gruenbacher static inline void drbd_get_syncer_progress(struct drbd_device *device,
1926b411b363SPhilipp Reisner 		unsigned long *bits_left, unsigned int *per_mil_done)
1927b411b363SPhilipp Reisner {
19284b0715f0SLars Ellenberg 	/* this is to break it at compile time when we change that, in case we
19294b0715f0SLars Ellenberg 	 * want to support more than (1<<32) bits on a 32bit arch. */
1930b30ab791SAndreas Gruenbacher 	typecheck(unsigned long, device->rs_total);
1931b411b363SPhilipp Reisner 
1932b411b363SPhilipp Reisner 	/* note: both rs_total and rs_left are in bits, i.e. in
1933b411b363SPhilipp Reisner 	 * units of BM_BLOCK_SIZE.
1934b411b363SPhilipp Reisner 	 * for the percentage, we don't care. */
1935b411b363SPhilipp Reisner 
1936b30ab791SAndreas Gruenbacher 	if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
1937b30ab791SAndreas Gruenbacher 		*bits_left = device->ov_left;
1938439d5953SLars Ellenberg 	else
1939b30ab791SAndreas Gruenbacher 		*bits_left = drbd_bm_total_weight(device) - device->rs_failed;
1940b411b363SPhilipp Reisner 	/* >> 10 to prevent overflow,
1941b411b363SPhilipp Reisner 	 * +1 to prevent division by zero */
1942b30ab791SAndreas Gruenbacher 	if (*bits_left > device->rs_total) {
1943b411b363SPhilipp Reisner 		/* doh. maybe a logic bug somewhere.
1944b411b363SPhilipp Reisner 		 * may also be just a race condition
1945b411b363SPhilipp Reisner 		 * between this and a disconnect during sync.
1946b411b363SPhilipp Reisner 		 * for now, just prevent in-kernel buffer overflow.
1947b411b363SPhilipp Reisner 		 */
1948b411b363SPhilipp Reisner 		smp_rmb();
1949d0180171SAndreas Gruenbacher 		drbd_warn(device, "cs:%s rs_left=%lu > rs_total=%lu (rs_failed %lu)\n",
1950b30ab791SAndreas Gruenbacher 				drbd_conn_str(device->state.conn),
1951b30ab791SAndreas Gruenbacher 				*bits_left, device->rs_total, device->rs_failed);
1952b411b363SPhilipp Reisner 		*per_mil_done = 0;
1953b411b363SPhilipp Reisner 	} else {
19544b0715f0SLars Ellenberg 		/* Make sure the division happens in long context.
19554b0715f0SLars Ellenberg 		 * We allow up to one petabyte storage right now,
19564b0715f0SLars Ellenberg 		 * at a granularity of 4k per bit that is 2**38 bits.
19574b0715f0SLars Ellenberg 		 * After shift right and multiplication by 1000,
19584b0715f0SLars Ellenberg 		 * this should still fit easily into a 32bit long,
19594b0715f0SLars Ellenberg 		 * so we don't need a 64bit division on 32bit arch.
19604b0715f0SLars Ellenberg 		 * Note: currently we don't support such large bitmaps on 32bit
19614b0715f0SLars Ellenberg 		 * arch anyways, but no harm done to be prepared for it here.
19624b0715f0SLars Ellenberg 		 */
1963b30ab791SAndreas Gruenbacher 		unsigned int shift = device->rs_total > UINT_MAX ? 16 : 10;
19644b0715f0SLars Ellenberg 		unsigned long left = *bits_left >> shift;
1965b30ab791SAndreas Gruenbacher 		unsigned long total = 1UL + (device->rs_total >> shift);
19664b0715f0SLars Ellenberg 		unsigned long tmp = 1000UL - left * 1000UL/total;
1967b411b363SPhilipp Reisner 		*per_mil_done = tmp;
1968b411b363SPhilipp Reisner 	}
1969b411b363SPhilipp Reisner }
1970b411b363SPhilipp Reisner 
1971b411b363SPhilipp Reisner 
1972b411b363SPhilipp Reisner /* this throttles on-the-fly application requests
1973b411b363SPhilipp Reisner  * according to max_buffers settings;
1974b411b363SPhilipp Reisner  * maybe re-implement using semaphores? */
1975b30ab791SAndreas Gruenbacher static inline int drbd_get_max_buffers(struct drbd_device *device)
1976b411b363SPhilipp Reisner {
197744ed167dSPhilipp Reisner 	struct net_conf *nc;
197844ed167dSPhilipp Reisner 	int mxb;
197944ed167dSPhilipp Reisner 
198044ed167dSPhilipp Reisner 	rcu_read_lock();
1981a6b32bc3SAndreas Gruenbacher 	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
198244ed167dSPhilipp Reisner 	mxb = nc ? nc->max_buffers : 1000000;  /* arbitrary limit on open requests */
198344ed167dSPhilipp Reisner 	rcu_read_unlock();
198444ed167dSPhilipp Reisner 
1985b411b363SPhilipp Reisner 	return mxb;
1986b411b363SPhilipp Reisner }
1987b411b363SPhilipp Reisner 
1988b30ab791SAndreas Gruenbacher static inline int drbd_state_is_stable(struct drbd_device *device)
1989b411b363SPhilipp Reisner {
1990b30ab791SAndreas Gruenbacher 	union drbd_dev_state s = device->state;
1991b411b363SPhilipp Reisner 
1992b411b363SPhilipp Reisner 	/* DO NOT add a default clause, we want the compiler to warn us
1993b411b363SPhilipp Reisner 	 * for any newly introduced state we may have forgotten to add here */
1994b411b363SPhilipp Reisner 
1995b411b363SPhilipp Reisner 	switch ((enum drbd_conns)s.conn) {
1996b411b363SPhilipp Reisner 	/* new io only accepted when there is no connection, ... */
1997b411b363SPhilipp Reisner 	case C_STANDALONE:
1998b411b363SPhilipp Reisner 	case C_WF_CONNECTION:
1999b411b363SPhilipp Reisner 	/* ... or there is a well established connection. */
2000b411b363SPhilipp Reisner 	case C_CONNECTED:
2001b411b363SPhilipp Reisner 	case C_SYNC_SOURCE:
2002b411b363SPhilipp Reisner 	case C_SYNC_TARGET:
2003b411b363SPhilipp Reisner 	case C_VERIFY_S:
2004b411b363SPhilipp Reisner 	case C_VERIFY_T:
2005b411b363SPhilipp Reisner 	case C_PAUSED_SYNC_S:
2006b411b363SPhilipp Reisner 	case C_PAUSED_SYNC_T:
200767531718SPhilipp Reisner 	case C_AHEAD:
200867531718SPhilipp Reisner 	case C_BEHIND:
20093719094eSPhilipp Reisner 		/* transitional states, IO allowed */
2010b411b363SPhilipp Reisner 	case C_DISCONNECTING:
2011b411b363SPhilipp Reisner 	case C_UNCONNECTED:
2012b411b363SPhilipp Reisner 	case C_TIMEOUT:
2013b411b363SPhilipp Reisner 	case C_BROKEN_PIPE:
2014b411b363SPhilipp Reisner 	case C_NETWORK_FAILURE:
2015b411b363SPhilipp Reisner 	case C_PROTOCOL_ERROR:
2016b411b363SPhilipp Reisner 	case C_TEAR_DOWN:
2017b411b363SPhilipp Reisner 	case C_WF_REPORT_PARAMS:
2018b411b363SPhilipp Reisner 	case C_STARTING_SYNC_S:
2019b411b363SPhilipp Reisner 	case C_STARTING_SYNC_T:
20203719094eSPhilipp Reisner 		break;
20213719094eSPhilipp Reisner 
20223719094eSPhilipp Reisner 		/* Allow IO in BM exchange states with new protocols */
2023b411b363SPhilipp Reisner 	case C_WF_BITMAP_S:
2024a6b32bc3SAndreas Gruenbacher 		if (first_peer_device(device)->connection->agreed_pro_version < 96)
20253719094eSPhilipp Reisner 			return 0;
20263719094eSPhilipp Reisner 		break;
20273719094eSPhilipp Reisner 
20283719094eSPhilipp Reisner 		/* no new io accepted in these states */
2029b411b363SPhilipp Reisner 	case C_WF_BITMAP_T:
2030b411b363SPhilipp Reisner 	case C_WF_SYNC_UUID:
2031b411b363SPhilipp Reisner 	case C_MASK:
2032b411b363SPhilipp Reisner 		/* not "stable" */
2033b411b363SPhilipp Reisner 		return 0;
2034b411b363SPhilipp Reisner 	}
2035b411b363SPhilipp Reisner 
2036b411b363SPhilipp Reisner 	switch ((enum drbd_disk_state)s.disk) {
2037b411b363SPhilipp Reisner 	case D_DISKLESS:
2038b411b363SPhilipp Reisner 	case D_INCONSISTENT:
2039b411b363SPhilipp Reisner 	case D_OUTDATED:
2040b411b363SPhilipp Reisner 	case D_CONSISTENT:
2041b411b363SPhilipp Reisner 	case D_UP_TO_DATE:
20425ca1de03SPhilipp Reisner 	case D_FAILED:
2043b411b363SPhilipp Reisner 		/* disk state is stable as well. */
2044b411b363SPhilipp Reisner 		break;
2045b411b363SPhilipp Reisner 
2046d942ae44SPhilipp Reisner 	/* no new io accepted during transitional states */
2047b411b363SPhilipp Reisner 	case D_ATTACHING:
2048b411b363SPhilipp Reisner 	case D_NEGOTIATING:
2049b411b363SPhilipp Reisner 	case D_UNKNOWN:
2050b411b363SPhilipp Reisner 	case D_MASK:
2051b411b363SPhilipp Reisner 		/* not "stable" */
2052b411b363SPhilipp Reisner 		return 0;
2053b411b363SPhilipp Reisner 	}
2054b411b363SPhilipp Reisner 
2055b411b363SPhilipp Reisner 	return 1;
2056b411b363SPhilipp Reisner }
2057b411b363SPhilipp Reisner 
2058b30ab791SAndreas Gruenbacher static inline int drbd_suspended(struct drbd_device *device)
2059fb22c402SPhilipp Reisner {
20606bbf53caSAndreas Gruenbacher 	struct drbd_resource *resource = device->resource;
20618e0af25fSPhilipp Reisner 
20626bbf53caSAndreas Gruenbacher 	return resource->susp || resource->susp_fen || resource->susp_nod;
2063fb22c402SPhilipp Reisner }
2064fb22c402SPhilipp Reisner 
2065b30ab791SAndreas Gruenbacher static inline bool may_inc_ap_bio(struct drbd_device *device)
2066b411b363SPhilipp Reisner {
2067b30ab791SAndreas Gruenbacher 	int mxb = drbd_get_max_buffers(device);
2068b411b363SPhilipp Reisner 
2069b30ab791SAndreas Gruenbacher 	if (drbd_suspended(device))
20701b881ef7SAndreas Gruenbacher 		return false;
2071b30ab791SAndreas Gruenbacher 	if (test_bit(SUSPEND_IO, &device->flags))
20721b881ef7SAndreas Gruenbacher 		return false;
2073b411b363SPhilipp Reisner 
2074b411b363SPhilipp Reisner 	/* to avoid potential deadlock or bitmap corruption,
2075b411b363SPhilipp Reisner 	 * in various places, we only allow new application io
2076b411b363SPhilipp Reisner 	 * to start during "stable" states. */
2077b411b363SPhilipp Reisner 
2078b411b363SPhilipp Reisner 	/* no new io accepted when attaching or detaching the disk */
2079b30ab791SAndreas Gruenbacher 	if (!drbd_state_is_stable(device))
20801b881ef7SAndreas Gruenbacher 		return false;
2081b411b363SPhilipp Reisner 
2082b411b363SPhilipp Reisner 	/* since some older kernels don't have atomic_add_unless,
2083b411b363SPhilipp Reisner 	 * and we are within the spinlock anyways, we have this workaround.  */
2084b30ab791SAndreas Gruenbacher 	if (atomic_read(&device->ap_bio_cnt) > mxb)
20851b881ef7SAndreas Gruenbacher 		return false;
2086b30ab791SAndreas Gruenbacher 	if (test_bit(BITMAP_IO, &device->flags))
20871b881ef7SAndreas Gruenbacher 		return false;
20881b881ef7SAndreas Gruenbacher 	return true;
2089b411b363SPhilipp Reisner }
2090b411b363SPhilipp Reisner 
2091b30ab791SAndreas Gruenbacher static inline bool inc_ap_bio_cond(struct drbd_device *device)
20928869d683SPhilipp Reisner {
20931b881ef7SAndreas Gruenbacher 	bool rv = false;
20948869d683SPhilipp Reisner 
20950500813fSAndreas Gruenbacher 	spin_lock_irq(&device->resource->req_lock);
2096b30ab791SAndreas Gruenbacher 	rv = may_inc_ap_bio(device);
20978869d683SPhilipp Reisner 	if (rv)
2098b30ab791SAndreas Gruenbacher 		atomic_inc(&device->ap_bio_cnt);
20990500813fSAndreas Gruenbacher 	spin_unlock_irq(&device->resource->req_lock);
21008869d683SPhilipp Reisner 
21018869d683SPhilipp Reisner 	return rv;
21028869d683SPhilipp Reisner }
21038869d683SPhilipp Reisner 
2104b30ab791SAndreas Gruenbacher static inline void inc_ap_bio(struct drbd_device *device)
2105b411b363SPhilipp Reisner {
2106b411b363SPhilipp Reisner 	/* we wait here
2107b411b363SPhilipp Reisner 	 *    as long as the device is suspended
2108b411b363SPhilipp Reisner 	 *    until the bitmap is no longer on the fly during connection
2109d942ae44SPhilipp Reisner 	 *    handshake as long as we would exceed the max_buffer limit.
2110b411b363SPhilipp Reisner 	 *
2111b411b363SPhilipp Reisner 	 * to avoid races with the reconnect code,
2112b411b363SPhilipp Reisner 	 * we need to atomic_inc within the spinlock. */
2113b411b363SPhilipp Reisner 
2114b30ab791SAndreas Gruenbacher 	wait_event(device->misc_wait, inc_ap_bio_cond(device));
2115b411b363SPhilipp Reisner }
2116b411b363SPhilipp Reisner 
2117b30ab791SAndreas Gruenbacher static inline void dec_ap_bio(struct drbd_device *device)
2118b411b363SPhilipp Reisner {
2119b30ab791SAndreas Gruenbacher 	int mxb = drbd_get_max_buffers(device);
2120b30ab791SAndreas Gruenbacher 	int ap_bio = atomic_dec_return(&device->ap_bio_cnt);
2121b411b363SPhilipp Reisner 
21220b0ba1efSAndreas Gruenbacher 	D_ASSERT(device, ap_bio >= 0);
21237ee1fb93SLars Ellenberg 
2124b30ab791SAndreas Gruenbacher 	if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) {
2125b30ab791SAndreas Gruenbacher 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
212684b8c06bSAndreas Gruenbacher 			drbd_queue_work(&first_peer_device(device)->
212784b8c06bSAndreas Gruenbacher 				connection->sender_work,
212884b8c06bSAndreas Gruenbacher 				&device->bm_io_work.w);
21297ee1fb93SLars Ellenberg 	}
21307ee1fb93SLars Ellenberg 
2131b411b363SPhilipp Reisner 	/* this currently does wake_up for every dec_ap_bio!
2132b411b363SPhilipp Reisner 	 * maybe rather introduce some type of hysteresis?
2133b411b363SPhilipp Reisner 	 * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */
2134b411b363SPhilipp Reisner 	if (ap_bio < mxb)
2135b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
2136b411b363SPhilipp Reisner }
2137b411b363SPhilipp Reisner 
2138b30ab791SAndreas Gruenbacher static inline bool verify_can_do_stop_sector(struct drbd_device *device)
213958ffa580SLars Ellenberg {
2140a6b32bc3SAndreas Gruenbacher 	return first_peer_device(device)->connection->agreed_pro_version >= 97 &&
2141a6b32bc3SAndreas Gruenbacher 		first_peer_device(device)->connection->agreed_pro_version != 100;
214258ffa580SLars Ellenberg }
214358ffa580SLars Ellenberg 
2144b30ab791SAndreas Gruenbacher static inline int drbd_set_ed_uuid(struct drbd_device *device, u64 val)
2145b411b363SPhilipp Reisner {
2146b30ab791SAndreas Gruenbacher 	int changed = device->ed_uuid != val;
2147b30ab791SAndreas Gruenbacher 	device->ed_uuid = val;
214862b0da3aSLars Ellenberg 	return changed;
2149b411b363SPhilipp Reisner }
2150b411b363SPhilipp Reisner 
2151b30ab791SAndreas Gruenbacher static inline int drbd_queue_order_type(struct drbd_device *device)
2152b411b363SPhilipp Reisner {
2153b411b363SPhilipp Reisner 	/* sorry, we currently have no working implementation
2154b411b363SPhilipp Reisner 	 * of distributed TCQ stuff */
2155b411b363SPhilipp Reisner #ifndef QUEUE_ORDERED_NONE
2156b411b363SPhilipp Reisner #define QUEUE_ORDERED_NONE 0
2157b411b363SPhilipp Reisner #endif
2158b411b363SPhilipp Reisner 	return QUEUE_ORDERED_NONE;
2159b411b363SPhilipp Reisner }
2160b411b363SPhilipp Reisner 
2161b30ab791SAndreas Gruenbacher static inline void drbd_md_flush(struct drbd_device *device)
2162b411b363SPhilipp Reisner {
2163b411b363SPhilipp Reisner 	int r;
2164b411b363SPhilipp Reisner 
2165b30ab791SAndreas Gruenbacher 	if (device->ldev == NULL) {
2166d0180171SAndreas Gruenbacher 		drbd_warn(device, "device->ldev == NULL in drbd_md_flush\n");
2167fd0017c1SPhilipp Reisner 		return;
2168fd0017c1SPhilipp Reisner 	}
2169fd0017c1SPhilipp Reisner 
2170b30ab791SAndreas Gruenbacher 	if (test_bit(MD_NO_FUA, &device->flags))
2171b411b363SPhilipp Reisner 		return;
2172b411b363SPhilipp Reisner 
2173b30ab791SAndreas Gruenbacher 	r = blkdev_issue_flush(device->ldev->md_bdev, GFP_NOIO, NULL);
2174b411b363SPhilipp Reisner 	if (r) {
2175b30ab791SAndreas Gruenbacher 		set_bit(MD_NO_FUA, &device->flags);
2176d0180171SAndreas Gruenbacher 		drbd_err(device, "meta data flush failed with status %d, disabling md-flushes\n", r);
2177b411b363SPhilipp Reisner 	}
2178b411b363SPhilipp Reisner }
2179b411b363SPhilipp Reisner 
218077c556f6SAndreas Gruenbacher static inline struct drbd_connection *first_connection(struct drbd_resource *resource)
218177c556f6SAndreas Gruenbacher {
218277c556f6SAndreas Gruenbacher 	return list_first_entry(&resource->connections,
218377c556f6SAndreas Gruenbacher 				struct drbd_connection, connections);
218477c556f6SAndreas Gruenbacher }
218577c556f6SAndreas Gruenbacher 
2186b411b363SPhilipp Reisner #endif
2187