xref: /linux/drivers/block/drbd/drbd_int.h (revision e5f891b2234dbab8c8797111a61519d0728ef855)
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 */
320*e5f891b2SLars Ellenberg 
321*e5f891b2SLars Ellenberg 	/* for generic IO accounting */
322*e5f891b2SLars Ellenberg 	unsigned long start_jif;
323*e5f891b2SLars Ellenberg 
324*e5f891b2SLars Ellenberg 	/* for DRBD internal statistics */
325*e5f891b2SLars Ellenberg 
326*e5f891b2SLars Ellenberg 	/* Minimal set of time stamps to determine if we wait for activity log
327*e5f891b2SLars Ellenberg 	 * transactions, local disk or peer.  32 bit "jiffies" are good enough,
328*e5f891b2SLars Ellenberg 	 * we don't expect a DRBD request to be stalled for several month.
329*e5f891b2SLars Ellenberg 	 */
330*e5f891b2SLars Ellenberg 
331*e5f891b2SLars Ellenberg 	/* before actual request processing */
332*e5f891b2SLars Ellenberg 	unsigned long in_actlog_jif;
333*e5f891b2SLars Ellenberg 
334*e5f891b2SLars Ellenberg 	/* local disk */
335*e5f891b2SLars Ellenberg 	unsigned long pre_submit_jif;
336*e5f891b2SLars Ellenberg 
337*e5f891b2SLars Ellenberg 	/* per connection */
338*e5f891b2SLars Ellenberg 	unsigned long pre_send_jif;
339*e5f891b2SLars Ellenberg 	unsigned long acked_jif;
340*e5f891b2SLars Ellenberg 	unsigned long net_done_jif;
341*e5f891b2SLars Ellenberg 
342*e5f891b2SLars Ellenberg 	/* Possibly even more detail to track each phase:
343*e5f891b2SLars Ellenberg 	 *  master_completion_jif
344*e5f891b2SLars Ellenberg 	 *      how long did it take to complete the master bio
345*e5f891b2SLars Ellenberg 	 *      (application visible latency)
346*e5f891b2SLars Ellenberg 	 *  allocated_jif
347*e5f891b2SLars Ellenberg 	 *      how long the master bio was blocked until we finally allocated
348*e5f891b2SLars Ellenberg 	 *      a tracking struct
349*e5f891b2SLars Ellenberg 	 *  in_actlog_jif
350*e5f891b2SLars Ellenberg 	 *      how long did we wait for activity log transactions
351*e5f891b2SLars Ellenberg 	 *
352*e5f891b2SLars Ellenberg 	 *  net_queued_jif
353*e5f891b2SLars Ellenberg 	 *      when did we finally queue it for sending
354*e5f891b2SLars Ellenberg 	 *  pre_send_jif
355*e5f891b2SLars Ellenberg 	 *      when did we start sending it
356*e5f891b2SLars Ellenberg 	 *  post_send_jif
357*e5f891b2SLars Ellenberg 	 *      how long did we block in the network stack trying to send it
358*e5f891b2SLars Ellenberg 	 *  acked_jif
359*e5f891b2SLars Ellenberg 	 *      when did we receive (or fake, in protocol A) a remote ACK
360*e5f891b2SLars Ellenberg 	 *  net_done_jif
361*e5f891b2SLars Ellenberg 	 *      when did we receive final acknowledgement (P_BARRIER_ACK),
362*e5f891b2SLars Ellenberg 	 *      or decide, e.g. on connection loss, that we do no longer expect
363*e5f891b2SLars Ellenberg 	 *      anything from this peer for this request.
364*e5f891b2SLars Ellenberg 	 *
365*e5f891b2SLars Ellenberg 	 *  pre_submit_jif
366*e5f891b2SLars Ellenberg 	 *  post_sub_jif
367*e5f891b2SLars Ellenberg 	 *      when did we start submiting to the lower level device,
368*e5f891b2SLars Ellenberg 	 *      and how long did we block in that submit function
369*e5f891b2SLars Ellenberg 	 *  local_completion_jif
370*e5f891b2SLars Ellenberg 	 *      how long did it take the lower level device to complete this request
371*e5f891b2SLars Ellenberg 	 */
372*e5f891b2SLars Ellenberg 
373b406777eSLars Ellenberg 
374b406777eSLars Ellenberg 	/* once it hits 0, we may complete the master_bio */
375b406777eSLars Ellenberg 	atomic_t completion_ref;
376b406777eSLars Ellenberg 	/* once it hits 0, we may destroy this drbd_request object */
377b406777eSLars Ellenberg 	struct kref kref;
378a0d856dfSLars Ellenberg 
379a0d856dfSLars Ellenberg 	unsigned rq_state; /* see comments above _req_mod() */
380b411b363SPhilipp Reisner };
381b411b363SPhilipp Reisner 
382b411b363SPhilipp Reisner struct drbd_epoch {
383bde89a9eSAndreas Gruenbacher 	struct drbd_connection *connection;
384b411b363SPhilipp Reisner 	struct list_head list;
385b411b363SPhilipp Reisner 	unsigned int barrier_nr;
386b411b363SPhilipp Reisner 	atomic_t epoch_size; /* increased on every request added. */
387b411b363SPhilipp Reisner 	atomic_t active;     /* increased on every req. added, and dec on every finished. */
388b411b363SPhilipp Reisner 	unsigned long flags;
389b411b363SPhilipp Reisner };
390b411b363SPhilipp Reisner 
391de0b2e69SRashika Kheria /* Prototype declaration of function defined in drbd_receiver.c */
392de0b2e69SRashika Kheria int drbdd_init(struct drbd_thread *);
393de0b2e69SRashika Kheria int drbd_asender(struct drbd_thread *);
394de0b2e69SRashika Kheria 
395b411b363SPhilipp Reisner /* drbd_epoch flag bits */
396b411b363SPhilipp Reisner enum {
397b411b363SPhilipp Reisner 	DE_HAVE_BARRIER_NUMBER,
398b411b363SPhilipp Reisner };
399b411b363SPhilipp Reisner 
400b411b363SPhilipp Reisner enum epoch_event {
401b411b363SPhilipp Reisner 	EV_PUT,
402b411b363SPhilipp Reisner 	EV_GOT_BARRIER_NR,
403b411b363SPhilipp Reisner 	EV_BECAME_LAST,
404b411b363SPhilipp Reisner 	EV_CLEANUP = 32, /* used as flag */
405b411b363SPhilipp Reisner };
406b411b363SPhilipp Reisner 
407b411b363SPhilipp Reisner struct digest_info {
408b411b363SPhilipp Reisner 	int digest_size;
409b411b363SPhilipp Reisner 	void *digest;
410b411b363SPhilipp Reisner };
411b411b363SPhilipp Reisner 
412f6ffca9fSAndreas Gruenbacher struct drbd_peer_request {
413a8cd15baSAndreas Gruenbacher 	struct drbd_work w;
414a8cd15baSAndreas Gruenbacher 	struct drbd_peer_device *peer_device;
41585719573SPhilipp Reisner 	struct drbd_epoch *epoch; /* for writes */
41645bb912bSLars Ellenberg 	struct page *pages;
41745bb912bSLars Ellenberg 	atomic_t pending_bios;
418010f6e67SAndreas Gruenbacher 	struct drbd_interval i;
41945bb912bSLars Ellenberg 	/* see comments on ee flag bits below */
42045bb912bSLars Ellenberg 	unsigned long flags;
42185719573SPhilipp Reisner 	union {
42245bb912bSLars Ellenberg 		u64 block_id;
42385719573SPhilipp Reisner 		struct digest_info *digest;
42485719573SPhilipp Reisner 	};
42545bb912bSLars Ellenberg };
42645bb912bSLars Ellenberg 
42745bb912bSLars Ellenberg /* ee flag bits.
42845bb912bSLars Ellenberg  * While corresponding bios are in flight, the only modification will be
42945bb912bSLars Ellenberg  * set_bit WAS_ERROR, which has to be atomic.
43045bb912bSLars Ellenberg  * If no bios are in flight yet, or all have been completed,
43145bb912bSLars Ellenberg  * non-atomic modification to ee->flags is ok.
43245bb912bSLars Ellenberg  */
433b411b363SPhilipp Reisner enum {
434b411b363SPhilipp Reisner 	__EE_CALL_AL_COMPLETE_IO,
435b411b363SPhilipp Reisner 	__EE_MAY_SET_IN_SYNC,
43645bb912bSLars Ellenberg 
437a0fb3c47SLars Ellenberg 	/* is this a TRIM aka REQ_DISCARD? */
438a0fb3c47SLars Ellenberg 	__EE_IS_TRIM,
439a0fb3c47SLars Ellenberg 	/* our lower level cannot handle trim,
440a0fb3c47SLars Ellenberg 	 * and we want to fall back to zeroout instead */
441a0fb3c47SLars Ellenberg 	__EE_IS_TRIM_USE_ZEROOUT,
442a0fb3c47SLars Ellenberg 
44345bb912bSLars Ellenberg 	/* In case a barrier failed,
44445bb912bSLars Ellenberg 	 * we need to resubmit without the barrier flag. */
44545bb912bSLars Ellenberg 	__EE_RESUBMITTED,
44645bb912bSLars Ellenberg 
4476c852becSAndreas Gruenbacher 	/* we may have several bios per peer request.
44845bb912bSLars Ellenberg 	 * if any of those fail, we set this flag atomically
44945bb912bSLars Ellenberg 	 * from the endio callback */
45045bb912bSLars Ellenberg 	__EE_WAS_ERROR,
451c36c3cedSLars Ellenberg 
452c36c3cedSLars Ellenberg 	/* This ee has a pointer to a digest instead of a block id */
453c36c3cedSLars Ellenberg 	__EE_HAS_DIGEST,
4547be8da07SAndreas Gruenbacher 
4557be8da07SAndreas Gruenbacher 	/* Conflicting local requests need to be restarted after this request */
4567be8da07SAndreas Gruenbacher 	__EE_RESTART_REQUESTS,
457303d1448SPhilipp Reisner 
458303d1448SPhilipp Reisner 	/* The peer wants a write ACK for this (wire proto C) */
459303d1448SPhilipp Reisner 	__EE_SEND_WRITE_ACK,
460302bdeaeSPhilipp Reisner 
461302bdeaeSPhilipp Reisner 	/* Is set when net_conf had two_primaries set while creating this peer_req */
462302bdeaeSPhilipp Reisner 	__EE_IN_INTERVAL_TREE,
463b411b363SPhilipp Reisner };
464b411b363SPhilipp Reisner #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
465b411b363SPhilipp Reisner #define EE_MAY_SET_IN_SYNC     (1<<__EE_MAY_SET_IN_SYNC)
466a0fb3c47SLars Ellenberg #define EE_IS_TRIM             (1<<__EE_IS_TRIM)
467a0fb3c47SLars Ellenberg #define EE_IS_TRIM_USE_ZEROOUT (1<<__EE_IS_TRIM_USE_ZEROOUT)
46845bb912bSLars Ellenberg #define EE_RESUBMITTED         (1<<__EE_RESUBMITTED)
46945bb912bSLars Ellenberg #define EE_WAS_ERROR           (1<<__EE_WAS_ERROR)
470c36c3cedSLars Ellenberg #define EE_HAS_DIGEST          (1<<__EE_HAS_DIGEST)
4717be8da07SAndreas Gruenbacher #define EE_RESTART_REQUESTS	(1<<__EE_RESTART_REQUESTS)
472303d1448SPhilipp Reisner #define EE_SEND_WRITE_ACK	(1<<__EE_SEND_WRITE_ACK)
473302bdeaeSPhilipp Reisner #define EE_IN_INTERVAL_TREE	(1<<__EE_IN_INTERVAL_TREE)
474b411b363SPhilipp Reisner 
475b30ab791SAndreas Gruenbacher /* flag bits per device */
476b411b363SPhilipp Reisner enum {
477b411b363SPhilipp Reisner 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
478b411b363SPhilipp Reisner 	MD_DIRTY,		/* current uuids and flags not yet on disk */
479b411b363SPhilipp Reisner 	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
480b411b363SPhilipp Reisner 	CL_ST_CHG_SUCCESS,
481b411b363SPhilipp Reisner 	CL_ST_CHG_FAIL,
482b411b363SPhilipp Reisner 	CRASHED_PRIMARY,	/* This node was a crashed primary.
483b411b363SPhilipp Reisner 				 * Gets cleared when the state.conn
484b411b363SPhilipp Reisner 				 * goes into C_CONNECTED state. */
485b411b363SPhilipp Reisner 	CONSIDER_RESYNC,
486b411b363SPhilipp Reisner 
487a8a4e51eSPhilipp Reisner 	MD_NO_FUA,		/* Users wants us to not use FUA/FLUSH on meta data dev */
4885ab7d2c0SLars Ellenberg 
489b411b363SPhilipp Reisner 	SUSPEND_IO,		/* suspend application io */
490b411b363SPhilipp Reisner 	BITMAP_IO,		/* suspend application io;
491b411b363SPhilipp Reisner 				   once no more io in flight, start bitmap io */
492b411b363SPhilipp Reisner 	BITMAP_IO_QUEUED,       /* Started bitmap IO */
493a2a3c74fSLars Ellenberg 	WAS_IO_ERROR,		/* Local disk failed, returned IO error */
494a2a3c74fSLars Ellenberg 	WAS_READ_ERROR,		/* Local disk READ failed (set additionally to the above) */
495383606e0SLars Ellenberg 	FORCE_DETACH,		/* Force-detach from local disk, aborting any pending local IO */
496b411b363SPhilipp Reisner 	RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
497b411b363SPhilipp Reisner 	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
498b411b363SPhilipp Reisner 				 * the peer, if it changed there as well. */
49943a5182cSPhilipp Reisner 	NEW_CUR_UUID,		/* Create new current UUID when thawing IO */
5000778286aSPhilipp Reisner 	AL_SUSPENDED,		/* Activity logging is currently suspended. */
501370a43e7SPhilipp Reisner 	AHEAD_TO_SYNC_SOURCE,   /* Ahead -> SyncSource queued */
502e64a3294SPhilipp Reisner 	B_RS_H_DONE,		/* Before resync handler done (already executed) */
50308b165baSPhilipp Reisner 	DISCARD_MY_DATA,	/* discard_my_data flag per volume */
504380207d0SPhilipp Reisner 	READ_BALANCE_RR,
505e334f550SLars Ellenberg 
506e334f550SLars Ellenberg 	/* cleared only after backing device related structures have been destroyed. */
507e334f550SLars Ellenberg 	GOING_DISKLESS,		/* Disk is being detached, because of io-error, or admin request. */
508e334f550SLars Ellenberg 
509e334f550SLars Ellenberg 	/* to be used in drbd_device_post_work() */
510e334f550SLars Ellenberg 	GO_DISKLESS,		/* tell worker to schedule cleanup before detach */
511e334f550SLars Ellenberg 	DESTROY_DISK,		/* tell worker to close backing devices and destroy related structures. */
512ac0acb9eSLars Ellenberg 	MD_SYNC,		/* tell worker to call drbd_md_sync() */
513ac0acb9eSLars Ellenberg 	RS_START,		/* tell worker to start resync/OV */
514e334f550SLars Ellenberg 	RS_PROGRESS,		/* tell worker that resync made significant progress */
515e334f550SLars Ellenberg 	RS_DONE,		/* tell worker that resync is done */
516b411b363SPhilipp Reisner };
517b411b363SPhilipp Reisner 
51854761697SAndreas Gruenbacher struct drbd_bitmap; /* opaque for drbd_device */
519b411b363SPhilipp Reisner 
52020ceb2b2SLars Ellenberg /* definition of bits in bm_flags to be used in drbd_bm_lock
52120ceb2b2SLars Ellenberg  * and drbd_bitmap_io and friends. */
52220ceb2b2SLars Ellenberg enum bm_flag {
52320ceb2b2SLars Ellenberg 	/* do we need to kfree, or vfree bm_pages? */
52420ceb2b2SLars Ellenberg 	BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */
52520ceb2b2SLars Ellenberg 
52620ceb2b2SLars Ellenberg 	/* currently locked for bulk operation */
5270e8488adSLars Ellenberg 	BM_LOCKED_MASK = 0xf,
52820ceb2b2SLars Ellenberg 
52920ceb2b2SLars Ellenberg 	/* in detail, that is: */
53020ceb2b2SLars Ellenberg 	BM_DONT_CLEAR = 0x1,
53120ceb2b2SLars Ellenberg 	BM_DONT_SET   = 0x2,
53220ceb2b2SLars Ellenberg 	BM_DONT_TEST  = 0x4,
53320ceb2b2SLars Ellenberg 
5340e8488adSLars Ellenberg 	/* so we can mark it locked for bulk operation,
5350e8488adSLars Ellenberg 	 * and still allow all non-bulk operations */
5360e8488adSLars Ellenberg 	BM_IS_LOCKED  = 0x8,
5370e8488adSLars Ellenberg 
53820ceb2b2SLars Ellenberg 	/* (test bit, count bit) allowed (common case) */
5390e8488adSLars Ellenberg 	BM_LOCKED_TEST_ALLOWED = BM_DONT_CLEAR | BM_DONT_SET | BM_IS_LOCKED,
54020ceb2b2SLars Ellenberg 
54120ceb2b2SLars Ellenberg 	/* testing bits, as well as setting new bits allowed, but clearing bits
54220ceb2b2SLars Ellenberg 	 * would be unexpected.  Used during bitmap receive.  Setting new bits
54320ceb2b2SLars Ellenberg 	 * requires sending of "out-of-sync" information, though. */
5440e8488adSLars Ellenberg 	BM_LOCKED_SET_ALLOWED = BM_DONT_CLEAR | BM_IS_LOCKED,
54520ceb2b2SLars Ellenberg 
5460e8488adSLars Ellenberg 	/* for drbd_bm_write_copy_pages, everything is allowed,
5470e8488adSLars Ellenberg 	 * only concurrent bulk operations are locked out. */
5480e8488adSLars Ellenberg 	BM_LOCKED_CHANGE_ALLOWED = BM_IS_LOCKED,
54920ceb2b2SLars Ellenberg };
55020ceb2b2SLars Ellenberg 
551b411b363SPhilipp Reisner struct drbd_work_queue {
552b411b363SPhilipp Reisner 	struct list_head q;
553b411b363SPhilipp Reisner 	spinlock_t q_lock;  /* to protect the list. */
5548c0785a5SLars Ellenberg 	wait_queue_head_t q_wait;
555b411b363SPhilipp Reisner };
556b411b363SPhilipp Reisner 
557b411b363SPhilipp Reisner struct drbd_socket {
558b411b363SPhilipp Reisner 	struct mutex mutex;
559b411b363SPhilipp Reisner 	struct socket    *socket;
560b411b363SPhilipp Reisner 	/* this way we get our
561b411b363SPhilipp Reisner 	 * send/receive buffers off the stack */
5625a87d920SAndreas Gruenbacher 	void *sbuf;
563e6ef8a5cSAndreas Gruenbacher 	void *rbuf;
564b411b363SPhilipp Reisner };
565b411b363SPhilipp Reisner 
566b411b363SPhilipp Reisner struct drbd_md {
567b411b363SPhilipp Reisner 	u64 md_offset;		/* sector offset to 'super' block */
568b411b363SPhilipp Reisner 
569b411b363SPhilipp Reisner 	u64 la_size_sect;	/* last agreed size, unit sectors */
5709f2247bbSPhilipp Reisner 	spinlock_t uuid_lock;
571b411b363SPhilipp Reisner 	u64 uuid[UI_SIZE];
572b411b363SPhilipp Reisner 	u64 device_uuid;
573b411b363SPhilipp Reisner 	u32 flags;
574b411b363SPhilipp Reisner 	u32 md_size_sect;
575b411b363SPhilipp Reisner 
576ae8bf312SLars Ellenberg 	s32 al_offset;	/* signed relative sector offset to activity log */
577b411b363SPhilipp Reisner 	s32 bm_offset;	/* signed relative sector offset to bitmap */
5783a4d4eb3SLars Ellenberg 
5793a4d4eb3SLars Ellenberg 	/* cached value of bdev->disk_conf->meta_dev_idx (see below) */
5803a4d4eb3SLars Ellenberg 	s32 meta_dev_idx;
5813a4d4eb3SLars Ellenberg 
5823a4d4eb3SLars Ellenberg 	/* see al_tr_number_to_on_disk_sector() */
5833a4d4eb3SLars Ellenberg 	u32 al_stripes;
5843a4d4eb3SLars Ellenberg 	u32 al_stripe_size_4k;
5853a4d4eb3SLars Ellenberg 	u32 al_size_4k; /* cached product of the above */
586b411b363SPhilipp Reisner };
587b411b363SPhilipp Reisner 
588b411b363SPhilipp Reisner struct drbd_backing_dev {
589b411b363SPhilipp Reisner 	struct block_device *backing_bdev;
590b411b363SPhilipp Reisner 	struct block_device *md_bdev;
591b411b363SPhilipp Reisner 	struct drbd_md md;
5920500813fSAndreas Gruenbacher 	struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
593b411b363SPhilipp Reisner 	sector_t known_size; /* last known size of that backing device */
594b411b363SPhilipp Reisner };
595b411b363SPhilipp Reisner 
596b411b363SPhilipp Reisner struct drbd_md_io {
597e37d2438SLars Ellenberg 	struct page *page;
598e37d2438SLars Ellenberg 	unsigned long start_jif;	/* last call to drbd_md_get_buffer */
599e37d2438SLars Ellenberg 	unsigned long submit_jif;	/* last _drbd_md_sync_page_io() submit */
600e37d2438SLars Ellenberg 	const char *current_use;
601e37d2438SLars Ellenberg 	atomic_t in_use;
6020c464425SPhilipp Reisner 	unsigned int done;
603b411b363SPhilipp Reisner 	int error;
604b411b363SPhilipp Reisner };
605b411b363SPhilipp Reisner 
606b411b363SPhilipp Reisner struct bm_io_work {
607b411b363SPhilipp Reisner 	struct drbd_work w;
608b411b363SPhilipp Reisner 	char *why;
60920ceb2b2SLars Ellenberg 	enum bm_flag flags;
610b30ab791SAndreas Gruenbacher 	int (*io_fn)(struct drbd_device *device);
611b30ab791SAndreas Gruenbacher 	void (*done)(struct drbd_device *device, int rv);
612b411b363SPhilipp Reisner };
613b411b363SPhilipp Reisner 
614b411b363SPhilipp Reisner enum write_ordering_e {
615b411b363SPhilipp Reisner 	WO_none,
616b411b363SPhilipp Reisner 	WO_drain_io,
617b411b363SPhilipp Reisner 	WO_bdev_flush,
618b411b363SPhilipp Reisner };
619b411b363SPhilipp Reisner 
620778f271dSPhilipp Reisner struct fifo_buffer {
621778f271dSPhilipp Reisner 	unsigned int head_index;
622778f271dSPhilipp Reisner 	unsigned int size;
6239958c857SPhilipp Reisner 	int total; /* sum of all values */
6249958c857SPhilipp Reisner 	int values[0];
625778f271dSPhilipp Reisner };
6269958c857SPhilipp Reisner extern struct fifo_buffer *fifo_alloc(int fifo_size);
627778f271dSPhilipp Reisner 
628bde89a9eSAndreas Gruenbacher /* flag bits per connection */
62901a311a5SPhilipp Reisner enum {
63001a311a5SPhilipp Reisner 	NET_CONGESTED,		/* The data socket is congested */
631427c0434SLars Ellenberg 	RESOLVE_CONFLICTS,	/* Set on one node, cleared on the peer! */
632e43ef195SPhilipp Reisner 	SEND_PING,		/* whether asender should send a ping asap */
633808e37b8SPhilipp Reisner 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
6342a67d8b9SPhilipp Reisner 	GOT_PING_ACK,		/* set when we receive a ping_ack packet, ping_wait gets woken */
6354d0fc3fdSPhilipp Reisner 	CONN_WD_ST_CHG_REQ,	/* A cluster wide state change on the connection is active */
636fc3b10a4SPhilipp Reisner 	CONN_WD_ST_CHG_OKAY,
637fc3b10a4SPhilipp Reisner 	CONN_WD_ST_CHG_FAIL,
6388169e41bSPhilipp Reisner 	CONN_DRY_RUN,		/* Expect disconnect after resync handshake. */
6396936fcb4SPhilipp Reisner 	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
640a1096a6eSPhilipp Reisner 	STATE_SENT,		/* Do not change state/UUIDs while this is set */
6416f3465edSLars Ellenberg 	CALLBACK_PENDING,	/* Whether we have a call_usermodehelper(, UMH_WAIT_PROC)
6426f3465edSLars Ellenberg 				 * pending, from drbd worker context.
6436f3465edSLars Ellenberg 				 * If set, bdi_write_congested() returns true,
6446f3465edSLars Ellenberg 				 * so shrink_page_list() would not recurse into,
6456f3465edSLars Ellenberg 				 * and potentially deadlock on, this drbd worker.
6466f3465edSLars Ellenberg 				 */
647b66623e3SPhilipp Reisner 	DISCONNECT_SENT,
648e334f550SLars Ellenberg 
649e334f550SLars Ellenberg 	DEVICE_WORK_PENDING,	/* tell worker that some device has pending work */
65001a311a5SPhilipp Reisner };
65101a311a5SPhilipp Reisner 
65277c556f6SAndreas Gruenbacher struct drbd_resource {
65377c556f6SAndreas Gruenbacher 	char *name;
65477c556f6SAndreas Gruenbacher 	struct kref kref;
655803ea134SAndreas Gruenbacher 	struct idr devices;		/* volume number to device mapping */
65677c556f6SAndreas Gruenbacher 	struct list_head connections;
65777c556f6SAndreas Gruenbacher 	struct list_head resources;
658eb6bea67SAndreas Gruenbacher 	struct res_opts res_opts;
6590500813fSAndreas Gruenbacher 	struct mutex conf_update;	/* mutex for ready-copy-update of net_conf and disk_conf */
6609e276872SLars Ellenberg 	struct mutex adm_mutex;		/* mutex to serialize administrative requests */
6610500813fSAndreas Gruenbacher 	spinlock_t req_lock;
6626bbf53caSAndreas Gruenbacher 
6636bbf53caSAndreas Gruenbacher 	unsigned susp:1;		/* IO suspended by user */
6646bbf53caSAndreas Gruenbacher 	unsigned susp_nod:1;		/* IO suspended because no data */
6656bbf53caSAndreas Gruenbacher 	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
666625a6ba2SAndreas Gruenbacher 
667e9526580SPhilipp Reisner 	enum write_ordering_e write_ordering;
668e9526580SPhilipp Reisner 
669625a6ba2SAndreas Gruenbacher 	cpumask_var_t cpu_mask;
67077c556f6SAndreas Gruenbacher };
67177c556f6SAndreas Gruenbacher 
67277c556f6SAndreas Gruenbacher struct drbd_connection {
67377c556f6SAndreas Gruenbacher 	struct list_head connections;
67477c556f6SAndreas Gruenbacher 	struct drbd_resource *resource;
6759dc9fbb3SPhilipp Reisner 	struct kref kref;
676c06ece6bSAndreas Gruenbacher 	struct idr peer_devices;	/* volume number to peer device mapping */
677bbeb641cSPhilipp Reisner 	enum drbd_conns cstate;		/* Only C_STANDALONE to C_WF_REPORT_PARAMS */
6788410da8fSPhilipp Reisner 	struct mutex cstate_mutex;	/* Protects graceful disconnects */
67928e448bbSPhilipp Reisner 	unsigned int connect_cnt;	/* Inc each time a connection is established */
6802111438bSPhilipp Reisner 
681062e879cSPhilipp Reisner 	unsigned long flags;
68244ed167dSPhilipp Reisner 	struct net_conf *net_conf;	/* content protected by rcu */
6832a67d8b9SPhilipp Reisner 	wait_queue_head_t ping_wait;	/* Woken upon reception of a ping, and a state change */
684e42325a5SPhilipp Reisner 
685089c075dSAndreas Gruenbacher 	struct sockaddr_storage my_addr;
686089c075dSAndreas Gruenbacher 	int my_addr_len;
687089c075dSAndreas Gruenbacher 	struct sockaddr_storage peer_addr;
688089c075dSAndreas Gruenbacher 	int peer_addr_len;
689089c075dSAndreas Gruenbacher 
690e42325a5SPhilipp Reisner 	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
691e42325a5SPhilipp Reisner 	struct drbd_socket meta;	/* ping/ack (metadata) packets */
69231890f4aSPhilipp Reisner 	int agreed_pro_version;		/* actually used protocol version */
69320c68fdeSLars Ellenberg 	u32 agreed_features;
69431890f4aSPhilipp Reisner 	unsigned long last_received;	/* in jiffies, either socket */
69531890f4aSPhilipp Reisner 	unsigned int ko_count;
696e6b3ea83SPhilipp Reisner 
697b6dd1a89SLars Ellenberg 	struct list_head transfer_log;	/* all requests not yet fully processed */
69887eeee41SPhilipp Reisner 
699a0638456SPhilipp Reisner 	struct crypto_hash *cram_hmac_tfm;
700bde89a9eSAndreas Gruenbacher 	struct crypto_hash *integrity_tfm;  /* checksums we compute, updates protected by connection->data->mutex */
701036b17eaSPhilipp Reisner 	struct crypto_hash *peer_integrity_tfm;  /* checksums we verify, only accessed from receiver thread  */
702f399002eSLars Ellenberg 	struct crypto_hash *csums_tfm;
703f399002eSLars Ellenberg 	struct crypto_hash *verify_tfm;
704a0638456SPhilipp Reisner 	void *int_dig_in;
705a0638456SPhilipp Reisner 	void *int_dig_vv;
706a0638456SPhilipp Reisner 
707b6dd1a89SLars Ellenberg 	/* receiver side */
70812038a3aSPhilipp Reisner 	struct drbd_epoch *current_epoch;
70912038a3aSPhilipp Reisner 	spinlock_t epoch_lock;
71012038a3aSPhilipp Reisner 	unsigned int epochs;
711b379c41eSLars Ellenberg 	atomic_t current_tle_nr;	/* transfer log epoch number */
712b6dd1a89SLars Ellenberg 	unsigned current_tle_writes;	/* writes seen within this tl epoch */
7134b0007c0SPhilipp Reisner 
71407be15b1SLars Ellenberg 	unsigned long last_reconnect_jif;
715e6b3ea83SPhilipp Reisner 	struct drbd_thread receiver;
716e6b3ea83SPhilipp Reisner 	struct drbd_thread worker;
717e6b3ea83SPhilipp Reisner 	struct drbd_thread asender;
718b6dd1a89SLars Ellenberg 
719b6dd1a89SLars Ellenberg 	/* sender side */
720d5b27b01SLars Ellenberg 	struct drbd_work_queue sender_work;
721b6dd1a89SLars Ellenberg 
722b6dd1a89SLars Ellenberg 	struct {
723b6dd1a89SLars Ellenberg 		/* whether this sender thread
724b6dd1a89SLars Ellenberg 		 * has processed a single write yet. */
725b6dd1a89SLars Ellenberg 		bool seen_any_write_yet;
726b6dd1a89SLars Ellenberg 
727b6dd1a89SLars Ellenberg 		/* Which barrier number to send with the next P_BARRIER */
728b6dd1a89SLars Ellenberg 		int current_epoch_nr;
729b6dd1a89SLars Ellenberg 
730b6dd1a89SLars Ellenberg 		/* how many write requests have been sent
731b6dd1a89SLars Ellenberg 		 * with req->epoch == current_epoch_nr.
732b6dd1a89SLars Ellenberg 		 * If none, no P_BARRIER will be sent. */
733b6dd1a89SLars Ellenberg 		unsigned current_epoch_writes;
734b6dd1a89SLars Ellenberg 	} send;
735b411b363SPhilipp Reisner };
736b411b363SPhilipp Reisner 
737113fef9eSLars Ellenberg struct submit_worker {
738113fef9eSLars Ellenberg 	struct workqueue_struct *wq;
739113fef9eSLars Ellenberg 	struct work_struct worker;
740113fef9eSLars Ellenberg 
741113fef9eSLars Ellenberg 	spinlock_t lock;
742113fef9eSLars Ellenberg 	struct list_head writes;
743113fef9eSLars Ellenberg };
744113fef9eSLars Ellenberg 
745a6b32bc3SAndreas Gruenbacher struct drbd_peer_device {
746a6b32bc3SAndreas Gruenbacher 	struct list_head peer_devices;
747a6b32bc3SAndreas Gruenbacher 	struct drbd_device *device;
748bde89a9eSAndreas Gruenbacher 	struct drbd_connection *connection;
749a6b32bc3SAndreas Gruenbacher };
750a6b32bc3SAndreas Gruenbacher 
751a6b32bc3SAndreas Gruenbacher struct drbd_device {
752d8628a86SAndreas Gruenbacher 	struct drbd_resource *resource;
753a6b32bc3SAndreas Gruenbacher 	struct list_head peer_devices;
7542111438bSPhilipp Reisner 	int vnr;			/* volume number within the connection */
75581fa2e67SPhilipp Reisner 	struct kref kref;
7562111438bSPhilipp Reisner 
757b411b363SPhilipp Reisner 	/* things that are stored as / read from meta data on disk */
758b411b363SPhilipp Reisner 	unsigned long flags;
759b411b363SPhilipp Reisner 
760b411b363SPhilipp Reisner 	/* configured by drbdsetup */
761b411b363SPhilipp Reisner 	struct drbd_backing_dev *ldev __protected_by(local);
762b411b363SPhilipp Reisner 
763b411b363SPhilipp Reisner 	sector_t p_size;     /* partner's disk size */
764b411b363SPhilipp Reisner 	struct request_queue *rq_queue;
765b411b363SPhilipp Reisner 	struct block_device *this_bdev;
766b411b363SPhilipp Reisner 	struct gendisk	    *vdisk;
767b411b363SPhilipp Reisner 
76807be15b1SLars Ellenberg 	unsigned long last_reattach_jif;
76984b8c06bSAndreas Gruenbacher 	struct drbd_work resync_work;
77084b8c06bSAndreas Gruenbacher 	struct drbd_work unplug_work;
771b411b363SPhilipp Reisner 	struct timer_list resync_timer;
772b411b363SPhilipp Reisner 	struct timer_list md_sync_timer;
773370a43e7SPhilipp Reisner 	struct timer_list start_resync_timer;
7747fde2be9SPhilipp Reisner 	struct timer_list request_timer;
775b411b363SPhilipp Reisner 
776b411b363SPhilipp Reisner 	/* Used after attach while negotiating new disk state. */
777b411b363SPhilipp Reisner 	union drbd_state new_state_tmp;
778b411b363SPhilipp Reisner 
779da9fbc27SPhilipp Reisner 	union drbd_dev_state state;
780b411b363SPhilipp Reisner 	wait_queue_head_t misc_wait;
781b411b363SPhilipp Reisner 	wait_queue_head_t state_wait;  /* upon each state change. */
782b411b363SPhilipp Reisner 	unsigned int send_cnt;
783b411b363SPhilipp Reisner 	unsigned int recv_cnt;
784b411b363SPhilipp Reisner 	unsigned int read_cnt;
785b411b363SPhilipp Reisner 	unsigned int writ_cnt;
786b411b363SPhilipp Reisner 	unsigned int al_writ_cnt;
787b411b363SPhilipp Reisner 	unsigned int bm_writ_cnt;
788b411b363SPhilipp Reisner 	atomic_t ap_bio_cnt;	 /* Requests we need to complete */
789b411b363SPhilipp Reisner 	atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */
790b411b363SPhilipp Reisner 	atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
791d942ae44SPhilipp Reisner 	atomic_t unacked_cnt;	 /* Need to send replies for */
792b411b363SPhilipp Reisner 	atomic_t local_cnt;	 /* Waiting for local completion */
793b2fb6dbeSPhilipp Reisner 
794dac1389cSAndreas Gruenbacher 	/* Interval tree of pending local requests */
795dac1389cSAndreas Gruenbacher 	struct rb_root read_requests;
796de696716SAndreas Gruenbacher 	struct rb_root write_requests;
797b411b363SPhilipp Reisner 
798aaaba345SLars Ellenberg 	/* use checksums for *this* resync */
799aaaba345SLars Ellenberg 	bool use_csums;
8004b0715f0SLars Ellenberg 	/* blocks to resync in this run [unit BM_BLOCK_SIZE] */
801b411b363SPhilipp Reisner 	unsigned long rs_total;
8024b0715f0SLars Ellenberg 	/* number of resync blocks that failed in this run */
803b411b363SPhilipp Reisner 	unsigned long rs_failed;
804b411b363SPhilipp Reisner 	/* Syncer's start time [unit jiffies] */
805b411b363SPhilipp Reisner 	unsigned long rs_start;
806b411b363SPhilipp Reisner 	/* cumulated time in PausedSyncX state [unit jiffies] */
807b411b363SPhilipp Reisner 	unsigned long rs_paused;
8081d7734a0SLars Ellenberg 	/* skipped because csum was equal [unit BM_BLOCK_SIZE] */
809b411b363SPhilipp Reisner 	unsigned long rs_same_csum;
8101d7734a0SLars Ellenberg #define DRBD_SYNC_MARKS 8
8111d7734a0SLars Ellenberg #define DRBD_SYNC_MARK_STEP (3*HZ)
8121d7734a0SLars Ellenberg 	/* block not up-to-date at mark [unit BM_BLOCK_SIZE] */
8131d7734a0SLars Ellenberg 	unsigned long rs_mark_left[DRBD_SYNC_MARKS];
8141d7734a0SLars Ellenberg 	/* marks's time [unit jiffies] */
8151d7734a0SLars Ellenberg 	unsigned long rs_mark_time[DRBD_SYNC_MARKS];
8161d7734a0SLars Ellenberg 	/* current index into rs_mark_{left,time} */
8171d7734a0SLars Ellenberg 	int rs_last_mark;
818328e0f12SPhilipp Reisner 	unsigned long rs_last_bcast; /* [unit jiffies] */
819b411b363SPhilipp Reisner 
820b411b363SPhilipp Reisner 	/* where does the admin want us to start? (sector) */
821b411b363SPhilipp Reisner 	sector_t ov_start_sector;
82202b91b55SLars Ellenberg 	sector_t ov_stop_sector;
823b411b363SPhilipp Reisner 	/* where are we now? (sector) */
824b411b363SPhilipp Reisner 	sector_t ov_position;
825b411b363SPhilipp Reisner 	/* Start sector of out of sync range (to merge printk reporting). */
826b411b363SPhilipp Reisner 	sector_t ov_last_oos_start;
827b411b363SPhilipp Reisner 	/* size of out-of-sync range in sectors. */
828b411b363SPhilipp Reisner 	sector_t ov_last_oos_size;
829b411b363SPhilipp Reisner 	unsigned long ov_left; /* in bits */
830b411b363SPhilipp Reisner 
831b411b363SPhilipp Reisner 	struct drbd_bitmap *bitmap;
832b411b363SPhilipp Reisner 	unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */
833b411b363SPhilipp Reisner 
834b411b363SPhilipp Reisner 	/* Used to track operations of resync... */
835b411b363SPhilipp Reisner 	struct lru_cache *resync;
836b411b363SPhilipp Reisner 	/* Number of locked elements in resync LRU */
837b411b363SPhilipp Reisner 	unsigned int resync_locked;
838b411b363SPhilipp Reisner 	/* resync extent number waiting for application requests */
839b411b363SPhilipp Reisner 	unsigned int resync_wenr;
840b411b363SPhilipp Reisner 
841b411b363SPhilipp Reisner 	int open_cnt;
842b411b363SPhilipp Reisner 	u64 *p_uuid;
8434b0007c0SPhilipp Reisner 
84485719573SPhilipp Reisner 	struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */
84585719573SPhilipp Reisner 	struct list_head sync_ee;   /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
84618b75d75SAndreas Gruenbacher 	struct list_head done_ee;   /* need to send P_WRITE_ACK */
84718b75d75SAndreas Gruenbacher 	struct list_head read_ee;   /* [RS]P_DATA_REQUEST being read */
848b411b363SPhilipp Reisner 	struct list_head net_ee;    /* zero-copy network send in progress */
849b411b363SPhilipp Reisner 
850b411b363SPhilipp Reisner 	int next_barrier_nr;
851b411b363SPhilipp Reisner 	struct list_head resync_reads;
852435f0740SLars Ellenberg 	atomic_t pp_in_use;		/* allocated from page pool */
853435f0740SLars Ellenberg 	atomic_t pp_in_use_by_net;	/* sendpage()d, still referenced by tcp */
854b411b363SPhilipp Reisner 	wait_queue_head_t ee_wait;
855cc94c650SPhilipp Reisner 	struct drbd_md_io md_io;
856b411b363SPhilipp Reisner 	spinlock_t al_lock;
857b411b363SPhilipp Reisner 	wait_queue_head_t al_wait;
858b411b363SPhilipp Reisner 	struct lru_cache *act_log;	/* activity log */
859b411b363SPhilipp Reisner 	unsigned int al_tr_number;
860b411b363SPhilipp Reisner 	int al_tr_cycle;
861b411b363SPhilipp Reisner 	wait_queue_head_t seq_wait;
862b411b363SPhilipp Reisner 	atomic_t packet_seq;
863b411b363SPhilipp Reisner 	unsigned int peer_seq;
864b411b363SPhilipp Reisner 	spinlock_t peer_seq_lock;
865b411b363SPhilipp Reisner 	unsigned int minor;
866b411b363SPhilipp Reisner 	unsigned long comm_bm_set; /* communicated number of set bits. */
867b411b363SPhilipp Reisner 	struct bm_io_work bm_io_work;
868b411b363SPhilipp Reisner 	u64 ed_uuid; /* UUID of the exposed data */
8698410da8fSPhilipp Reisner 	struct mutex own_state_mutex;
870a6b32bc3SAndreas Gruenbacher 	struct mutex *state_mutex; /* either own_state_mutex or first_peer_device(device)->connection->cstate_mutex */
871b411b363SPhilipp Reisner 	char congestion_reason;  /* Why we where congested... */
8721d7734a0SLars Ellenberg 	atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
8731d7734a0SLars Ellenberg 	atomic_t rs_sect_ev; /* for submitted resync data rate, both */
8741d7734a0SLars Ellenberg 	int rs_last_sect_ev; /* counter to compare with */
8751d7734a0SLars Ellenberg 	int rs_last_events;  /* counter of read or write "events" (unit sectors)
8761d7734a0SLars Ellenberg 			      * on the lower level device when we last looked. */
8771d7734a0SLars Ellenberg 	int c_sync_rate; /* current resync rate after syncer throttle magic */
878bde89a9eSAndreas Gruenbacher 	struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
879778f271dSPhilipp Reisner 	int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
880759fbdfbSPhilipp Reisner 	atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
881db141b2fSLars Ellenberg 	unsigned int peer_max_bio_size;
882db141b2fSLars Ellenberg 	unsigned int local_max_bio_size;
883113fef9eSLars Ellenberg 
884113fef9eSLars Ellenberg 	/* any requests that would block in drbd_make_request()
885113fef9eSLars Ellenberg 	 * are deferred to this single-threaded work queue */
886113fef9eSLars Ellenberg 	struct submit_worker submit;
887b411b363SPhilipp Reisner };
888b411b363SPhilipp Reisner 
889a910b123SLars Ellenberg struct drbd_config_context {
890a910b123SLars Ellenberg 	/* assigned from drbd_genlmsghdr */
891a910b123SLars Ellenberg 	unsigned int minor;
892a910b123SLars Ellenberg 	/* assigned from request attributes, if present */
893a910b123SLars Ellenberg 	unsigned int volume;
894a910b123SLars Ellenberg #define VOLUME_UNSPECIFIED		(-1U)
895a910b123SLars Ellenberg 	/* pointer into the request skb,
896a910b123SLars Ellenberg 	 * limited lifetime! */
897a910b123SLars Ellenberg 	char *resource_name;
898a910b123SLars Ellenberg 	struct nlattr *my_addr;
899a910b123SLars Ellenberg 	struct nlattr *peer_addr;
900a910b123SLars Ellenberg 
901a910b123SLars Ellenberg 	/* reply buffer */
902a910b123SLars Ellenberg 	struct sk_buff *reply_skb;
903a910b123SLars Ellenberg 	/* pointer into reply buffer */
904a910b123SLars Ellenberg 	struct drbd_genlmsghdr *reply_dh;
905a910b123SLars Ellenberg 	/* resolved from attributes, if possible */
906a910b123SLars Ellenberg 	struct drbd_device *device;
907a910b123SLars Ellenberg 	struct drbd_resource *resource;
908a910b123SLars Ellenberg 	struct drbd_connection *connection;
909a910b123SLars Ellenberg };
910a910b123SLars Ellenberg 
911b30ab791SAndreas Gruenbacher static inline struct drbd_device *minor_to_device(unsigned int minor)
912b411b363SPhilipp Reisner {
91305a10ec7SAndreas Gruenbacher 	return (struct drbd_device *)idr_find(&drbd_devices, minor);
914b411b363SPhilipp Reisner }
915b411b363SPhilipp Reisner 
916a6b32bc3SAndreas Gruenbacher static inline struct drbd_peer_device *first_peer_device(struct drbd_device *device)
917a6b32bc3SAndreas Gruenbacher {
918ec4a3407SLars Ellenberg 	return list_first_entry_or_null(&device->peer_devices, struct drbd_peer_device, peer_devices);
919a6b32bc3SAndreas Gruenbacher }
920a6b32bc3SAndreas Gruenbacher 
92177c556f6SAndreas Gruenbacher #define for_each_resource(resource, _resources) \
92277c556f6SAndreas Gruenbacher 	list_for_each_entry(resource, _resources, resources)
92377c556f6SAndreas Gruenbacher 
92477c556f6SAndreas Gruenbacher #define for_each_resource_rcu(resource, _resources) \
92577c556f6SAndreas Gruenbacher 	list_for_each_entry_rcu(resource, _resources, resources)
92677c556f6SAndreas Gruenbacher 
92777c556f6SAndreas Gruenbacher #define for_each_resource_safe(resource, tmp, _resources) \
92877c556f6SAndreas Gruenbacher 	list_for_each_entry_safe(resource, tmp, _resources, resources)
92977c556f6SAndreas Gruenbacher 
93077c556f6SAndreas Gruenbacher #define for_each_connection(connection, resource) \
93177c556f6SAndreas Gruenbacher 	list_for_each_entry(connection, &resource->connections, connections)
93277c556f6SAndreas Gruenbacher 
93377c556f6SAndreas Gruenbacher #define for_each_connection_rcu(connection, resource) \
93477c556f6SAndreas Gruenbacher 	list_for_each_entry_rcu(connection, &resource->connections, connections)
93577c556f6SAndreas Gruenbacher 
93677c556f6SAndreas Gruenbacher #define for_each_connection_safe(connection, tmp, resource) \
93777c556f6SAndreas Gruenbacher 	list_for_each_entry_safe(connection, tmp, &resource->connections, connections)
93877c556f6SAndreas Gruenbacher 
939a6b32bc3SAndreas Gruenbacher #define for_each_peer_device(peer_device, device) \
940a6b32bc3SAndreas Gruenbacher 	list_for_each_entry(peer_device, &device->peer_devices, peer_devices)
941a6b32bc3SAndreas Gruenbacher 
942a6b32bc3SAndreas Gruenbacher #define for_each_peer_device_rcu(peer_device, device) \
943a6b32bc3SAndreas Gruenbacher 	list_for_each_entry_rcu(peer_device, &device->peer_devices, peer_devices)
944a6b32bc3SAndreas Gruenbacher 
945a6b32bc3SAndreas Gruenbacher #define for_each_peer_device_safe(peer_device, tmp, device) \
946a6b32bc3SAndreas Gruenbacher 	list_for_each_entry_safe(peer_device, tmp, &device->peer_devices, peer_devices)
947a6b32bc3SAndreas Gruenbacher 
948b30ab791SAndreas Gruenbacher static inline unsigned int device_to_minor(struct drbd_device *device)
949b411b363SPhilipp Reisner {
950b30ab791SAndreas Gruenbacher 	return device->minor;
951b411b363SPhilipp Reisner }
952b411b363SPhilipp Reisner 
953b411b363SPhilipp Reisner /*
954b411b363SPhilipp Reisner  * function declarations
955b411b363SPhilipp Reisner  *************************/
956b411b363SPhilipp Reisner 
957b411b363SPhilipp Reisner /* drbd_main.c */
958b411b363SPhilipp Reisner 
959e89b591cSPhilipp Reisner enum dds_flags {
960e89b591cSPhilipp Reisner 	DDSF_FORCED    = 1,
961e89b591cSPhilipp Reisner 	DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */
962e89b591cSPhilipp Reisner };
963e89b591cSPhilipp Reisner 
964b30ab791SAndreas Gruenbacher extern void drbd_init_set_defaults(struct drbd_device *device);
965b411b363SPhilipp Reisner extern int  drbd_thread_start(struct drbd_thread *thi);
966b411b363SPhilipp Reisner extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
967b411b363SPhilipp Reisner #ifdef CONFIG_SMP
96880822284SPhilipp Reisner extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
969b411b363SPhilipp Reisner #else
970b411b363SPhilipp Reisner #define drbd_thread_current_set_cpu(A) ({})
971b411b363SPhilipp Reisner #endif
972bde89a9eSAndreas Gruenbacher extern void tl_release(struct drbd_connection *, unsigned int barrier_nr,
973b411b363SPhilipp Reisner 		       unsigned int set_size);
974bde89a9eSAndreas Gruenbacher extern void tl_clear(struct drbd_connection *);
975bde89a9eSAndreas Gruenbacher extern void drbd_free_sock(struct drbd_connection *connection);
976bde89a9eSAndreas Gruenbacher extern int drbd_send(struct drbd_connection *connection, struct socket *sock,
977b411b363SPhilipp Reisner 		     void *buf, size_t size, unsigned msg_flags);
978bde89a9eSAndreas Gruenbacher extern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size_t,
979fb708e40SAndreas Gruenbacher 			 unsigned);
980fb708e40SAndreas Gruenbacher 
981bde89a9eSAndreas Gruenbacher extern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd);
982bde89a9eSAndreas Gruenbacher extern int drbd_send_protocol(struct drbd_connection *connection);
98369a22773SAndreas Gruenbacher extern int drbd_send_uuids(struct drbd_peer_device *);
98469a22773SAndreas Gruenbacher extern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
98569a22773SAndreas Gruenbacher extern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
98669a22773SAndreas Gruenbacher extern int drbd_send_sizes(struct drbd_peer_device *, int trigger_reply, enum dds_flags flags);
98769a22773SAndreas Gruenbacher extern int drbd_send_state(struct drbd_peer_device *, union drbd_state s);
98869a22773SAndreas Gruenbacher extern int drbd_send_current_state(struct drbd_peer_device *);
98969a22773SAndreas Gruenbacher extern int drbd_send_sync_param(struct drbd_peer_device *);
990bde89a9eSAndreas Gruenbacher extern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr,
991b411b363SPhilipp Reisner 			    u32 set_size);
99269a22773SAndreas Gruenbacher extern int drbd_send_ack(struct drbd_peer_device *, enum drbd_packet,
993f6ffca9fSAndreas Gruenbacher 			 struct drbd_peer_request *);
99469a22773SAndreas Gruenbacher extern void drbd_send_ack_rp(struct drbd_peer_device *, enum drbd_packet,
995b411b363SPhilipp Reisner 			     struct p_block_req *rp);
99669a22773SAndreas Gruenbacher extern void drbd_send_ack_dp(struct drbd_peer_device *, enum drbd_packet,
9972b2bf214SLars Ellenberg 			     struct p_data *dp, int data_size);
99869a22773SAndreas Gruenbacher extern int drbd_send_ack_ex(struct drbd_peer_device *, enum drbd_packet,
999b411b363SPhilipp Reisner 			    sector_t sector, int blksize, u64 block_id);
100069a22773SAndreas Gruenbacher extern int drbd_send_out_of_sync(struct drbd_peer_device *, struct drbd_request *);
100169a22773SAndreas Gruenbacher extern int drbd_send_block(struct drbd_peer_device *, enum drbd_packet,
1002f6ffca9fSAndreas Gruenbacher 			   struct drbd_peer_request *);
100369a22773SAndreas Gruenbacher extern int drbd_send_dblock(struct drbd_peer_device *, struct drbd_request *req);
100469a22773SAndreas Gruenbacher extern int drbd_send_drequest(struct drbd_peer_device *, int cmd,
1005b411b363SPhilipp Reisner 			      sector_t sector, int size, u64 block_id);
100669a22773SAndreas Gruenbacher extern int drbd_send_drequest_csum(struct drbd_peer_device *, sector_t sector,
1007d8763023SAndreas Gruenbacher 				   int size, void *digest, int digest_size,
1008d8763023SAndreas Gruenbacher 				   enum drbd_packet cmd);
100969a22773SAndreas Gruenbacher extern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int size);
1010b411b363SPhilipp Reisner 
1011b30ab791SAndreas Gruenbacher extern int drbd_send_bitmap(struct drbd_device *device);
101269a22773SAndreas Gruenbacher extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
1013bde89a9eSAndreas Gruenbacher extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
101428995af5SPhilipp Reisner extern void drbd_free_ldev(struct drbd_backing_dev *ldev);
1015b30ab791SAndreas Gruenbacher extern void drbd_device_cleanup(struct drbd_device *device);
1016b30ab791SAndreas Gruenbacher void drbd_print_uuids(struct drbd_device *device, const char *text);
1017b411b363SPhilipp Reisner 
1018bde89a9eSAndreas Gruenbacher extern void conn_md_sync(struct drbd_connection *connection);
1019b30ab791SAndreas Gruenbacher extern void drbd_md_write(struct drbd_device *device, void *buffer);
1020b30ab791SAndreas Gruenbacher extern void drbd_md_sync(struct drbd_device *device);
1021b30ab791SAndreas Gruenbacher extern int  drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev);
1022b30ab791SAndreas Gruenbacher extern void drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
1023b30ab791SAndreas Gruenbacher extern void _drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
1024b30ab791SAndreas Gruenbacher extern void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local);
1025b30ab791SAndreas Gruenbacher extern void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local);
1026b30ab791SAndreas Gruenbacher extern void drbd_uuid_move_history(struct drbd_device *device) __must_hold(local);
1027b30ab791SAndreas Gruenbacher extern void __drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
1028b30ab791SAndreas Gruenbacher extern void drbd_md_set_flag(struct drbd_device *device, int flags) __must_hold(local);
1029b30ab791SAndreas Gruenbacher extern void drbd_md_clear_flag(struct drbd_device *device, int flags)__must_hold(local);
1030b411b363SPhilipp Reisner extern int drbd_md_test_flag(struct drbd_backing_dev *, int);
1031b30ab791SAndreas Gruenbacher extern void drbd_md_mark_dirty(struct drbd_device *device);
1032b30ab791SAndreas Gruenbacher extern void drbd_queue_bitmap_io(struct drbd_device *device,
103354761697SAndreas Gruenbacher 				 int (*io_fn)(struct drbd_device *),
103454761697SAndreas Gruenbacher 				 void (*done)(struct drbd_device *, int),
103520ceb2b2SLars Ellenberg 				 char *why, enum bm_flag flags);
1036b30ab791SAndreas Gruenbacher extern int drbd_bitmap_io(struct drbd_device *device,
103754761697SAndreas Gruenbacher 		int (*io_fn)(struct drbd_device *),
103820ceb2b2SLars Ellenberg 		char *why, enum bm_flag flags);
1039b30ab791SAndreas Gruenbacher extern int drbd_bitmap_io_from_worker(struct drbd_device *device,
104054761697SAndreas Gruenbacher 		int (*io_fn)(struct drbd_device *),
1041edc9f5ebSLars Ellenberg 		char *why, enum bm_flag flags);
10428fe39aacSPhilipp Reisner extern int drbd_bmio_set_n_write(struct drbd_device *device) __must_hold(local);
10438fe39aacSPhilipp Reisner extern int drbd_bmio_clear_n_write(struct drbd_device *device) __must_hold(local);
1044b411b363SPhilipp Reisner 
1045b411b363SPhilipp Reisner /* Meta data layout
1046ae8bf312SLars Ellenberg  *
1047ae8bf312SLars Ellenberg  * We currently have two possible layouts.
1048ae8bf312SLars Ellenberg  * Offsets in (512 byte) sectors.
1049ae8bf312SLars Ellenberg  * external:
1050ae8bf312SLars Ellenberg  *   |----------- md_size_sect ------------------|
1051ae8bf312SLars Ellenberg  *   [ 4k superblock ][ activity log ][  Bitmap  ]
1052ae8bf312SLars Ellenberg  *   | al_offset == 8 |
1053ae8bf312SLars Ellenberg  *   | bm_offset = al_offset + X      |
1054ae8bf312SLars Ellenberg  *  ==> bitmap sectors = md_size_sect - bm_offset
1055ae8bf312SLars Ellenberg  *
1056ae8bf312SLars Ellenberg  *  Variants:
1057ae8bf312SLars Ellenberg  *     old, indexed fixed size meta data:
1058ae8bf312SLars Ellenberg  *
1059ae8bf312SLars Ellenberg  * internal:
1060ae8bf312SLars Ellenberg  *            |----------- md_size_sect ------------------|
1061ae8bf312SLars Ellenberg  * [data.....][  Bitmap  ][ activity log ][ 4k superblock ][padding*]
1062ae8bf312SLars Ellenberg  *                        | al_offset < 0 |
1063ae8bf312SLars Ellenberg  *            | bm_offset = al_offset - Y |
1064ae8bf312SLars Ellenberg  *  ==> bitmap sectors = Y = al_offset - bm_offset
1065ae8bf312SLars Ellenberg  *
1066ae8bf312SLars Ellenberg  *  [padding*] are zero or up to 7 unused 512 Byte sectors to the
1067ae8bf312SLars Ellenberg  *  end of the device, so that the [4k superblock] will be 4k aligned.
1068ae8bf312SLars Ellenberg  *
1069ae8bf312SLars Ellenberg  *  The activity log consists of 4k transaction blocks,
1070ae8bf312SLars Ellenberg  *  which are written in a ring-buffer, or striped ring-buffer like fashion,
1071ae8bf312SLars Ellenberg  *  which are writtensize used to be fixed 32kB,
1072ae8bf312SLars Ellenberg  *  but is about to become configurable.
1073ae8bf312SLars Ellenberg  */
1074b411b363SPhilipp Reisner 
1075ae8bf312SLars Ellenberg /* Our old fixed size meta data layout
1076ae8bf312SLars Ellenberg  * allows up to about 3.8TB, so if you want more,
10777ad651b5SLars Ellenberg  * you need to use the "flexible" meta data format. */
1078ae8bf312SLars Ellenberg #define MD_128MB_SECT (128LLU << 11)  /* 128 MB, unit sectors */
1079ae8bf312SLars Ellenberg #define MD_4kB_SECT	 8
1080ae8bf312SLars Ellenberg #define MD_32kB_SECT	64
1081b411b363SPhilipp Reisner 
10827ad651b5SLars Ellenberg /* One activity log extent represents 4M of storage */
10837ad651b5SLars Ellenberg #define AL_EXTENT_SHIFT 22
1084b411b363SPhilipp Reisner #define AL_EXTENT_SIZE (1<<AL_EXTENT_SHIFT)
1085b411b363SPhilipp Reisner 
10867ad651b5SLars Ellenberg /* We could make these currently hardcoded constants configurable
10877ad651b5SLars Ellenberg  * variables at create-md time (or even re-configurable at runtime?).
10887ad651b5SLars Ellenberg  * Which will require some more changes to the DRBD "super block"
10897ad651b5SLars Ellenberg  * and attach code.
10907ad651b5SLars Ellenberg  *
10917ad651b5SLars Ellenberg  * updates per transaction:
10927ad651b5SLars Ellenberg  *   This many changes to the active set can be logged with one transaction.
10937ad651b5SLars Ellenberg  *   This number is arbitrary.
10947ad651b5SLars Ellenberg  * context per transaction:
10957ad651b5SLars Ellenberg  *   This many context extent numbers are logged with each transaction.
10967ad651b5SLars Ellenberg  *   This number is resulting from the transaction block size (4k), the layout
10977ad651b5SLars Ellenberg  *   of the transaction header, and the number of updates per transaction.
10987ad651b5SLars Ellenberg  *   See drbd_actlog.c:struct al_transaction_on_disk
10997ad651b5SLars Ellenberg  * */
11007ad651b5SLars Ellenberg #define AL_UPDATES_PER_TRANSACTION	 64	// arbitrary
11017ad651b5SLars Ellenberg #define AL_CONTEXT_PER_TRANSACTION	919	// (4096 - 36 - 6*64)/4
11027ad651b5SLars Ellenberg 
1103b411b363SPhilipp Reisner #if BITS_PER_LONG == 32
1104b411b363SPhilipp Reisner #define LN2_BPL 5
1105b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le32(A)
1106b411b363SPhilipp Reisner #define lel_to_cpu(A) le32_to_cpu(A)
1107b411b363SPhilipp Reisner #elif BITS_PER_LONG == 64
1108b411b363SPhilipp Reisner #define LN2_BPL 6
1109b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le64(A)
1110b411b363SPhilipp Reisner #define lel_to_cpu(A) le64_to_cpu(A)
1111b411b363SPhilipp Reisner #else
1112b411b363SPhilipp Reisner #error "LN2 of BITS_PER_LONG unknown!"
1113b411b363SPhilipp Reisner #endif
1114b411b363SPhilipp Reisner 
1115b411b363SPhilipp Reisner /* resync bitmap */
1116b411b363SPhilipp Reisner /* 16MB sized 'bitmap extent' to track syncer usage */
1117b411b363SPhilipp Reisner struct bm_extent {
1118b411b363SPhilipp Reisner 	int rs_left; /* number of bits set (out of sync) in this extent. */
1119b411b363SPhilipp Reisner 	int rs_failed; /* number of failed resync requests in this extent. */
1120b411b363SPhilipp Reisner 	unsigned long flags;
1121b411b363SPhilipp Reisner 	struct lc_element lce;
1122b411b363SPhilipp Reisner };
1123b411b363SPhilipp Reisner 
1124b411b363SPhilipp Reisner #define BME_NO_WRITES  0  /* bm_extent.flags: no more requests on this one! */
1125b411b363SPhilipp Reisner #define BME_LOCKED     1  /* bm_extent.flags: syncer active on this one. */
1126e3555d85SPhilipp Reisner #define BME_PRIORITY   2  /* finish resync IO on this extent ASAP! App IO waiting! */
1127b411b363SPhilipp Reisner 
1128b411b363SPhilipp Reisner /* drbd_bitmap.c */
1129b411b363SPhilipp Reisner /*
1130b411b363SPhilipp Reisner  * We need to store one bit for a block.
1131b411b363SPhilipp Reisner  * Example: 1GB disk @ 4096 byte blocks ==> we need 32 KB bitmap.
1132b411b363SPhilipp Reisner  * Bit 0 ==> local node thinks this block is binary identical on both nodes
1133b411b363SPhilipp Reisner  * Bit 1 ==> local node thinks this block needs to be synced.
1134b411b363SPhilipp Reisner  */
1135b411b363SPhilipp Reisner 
11368e26f9ccSPhilipp Reisner #define SLEEP_TIME (HZ/10)
11378e26f9ccSPhilipp Reisner 
113845dfffebSLars Ellenberg /* We do bitmap IO in units of 4k blocks.
113945dfffebSLars Ellenberg  * We also still have a hardcoded 4k per bit relation. */
1140b411b363SPhilipp Reisner #define BM_BLOCK_SHIFT	12			 /* 4k per bit */
1141b411b363SPhilipp Reisner #define BM_BLOCK_SIZE	 (1<<BM_BLOCK_SHIFT)
114245dfffebSLars Ellenberg /* mostly arbitrarily set the represented size of one bitmap extent,
114345dfffebSLars Ellenberg  * aka resync extent, to 16 MiB (which is also 512 Byte worth of bitmap
114445dfffebSLars Ellenberg  * at 4k per bit resolution) */
114545dfffebSLars Ellenberg #define BM_EXT_SHIFT	 24	/* 16 MiB per resync extent */
1146b411b363SPhilipp Reisner #define BM_EXT_SIZE	 (1<<BM_EXT_SHIFT)
1147b411b363SPhilipp Reisner 
1148b411b363SPhilipp Reisner #if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12)
1149b411b363SPhilipp Reisner #error "HAVE YOU FIXED drbdmeta AS WELL??"
1150b411b363SPhilipp Reisner #endif
1151b411b363SPhilipp Reisner 
1152b411b363SPhilipp Reisner /* thus many _storage_ sectors are described by one bit */
1153b411b363SPhilipp Reisner #define BM_SECT_TO_BIT(x)   ((x)>>(BM_BLOCK_SHIFT-9))
1154b411b363SPhilipp Reisner #define BM_BIT_TO_SECT(x)   ((sector_t)(x)<<(BM_BLOCK_SHIFT-9))
1155b411b363SPhilipp Reisner #define BM_SECT_PER_BIT     BM_BIT_TO_SECT(1)
1156b411b363SPhilipp Reisner 
1157b411b363SPhilipp Reisner /* bit to represented kilo byte conversion */
1158b411b363SPhilipp Reisner #define Bit2KB(bits) ((bits)<<(BM_BLOCK_SHIFT-10))
1159b411b363SPhilipp Reisner 
1160b411b363SPhilipp Reisner /* in which _bitmap_ extent (resp. sector) the bit for a certain
1161b411b363SPhilipp Reisner  * _storage_ sector is located in */
1162b411b363SPhilipp Reisner #define BM_SECT_TO_EXT(x)   ((x)>>(BM_EXT_SHIFT-9))
11635ab7d2c0SLars Ellenberg #define BM_BIT_TO_EXT(x)    ((x) >> (BM_EXT_SHIFT - BM_BLOCK_SHIFT))
1164b411b363SPhilipp Reisner 
11655ab7d2c0SLars Ellenberg /* first storage sector a bitmap extent corresponds to */
1166b411b363SPhilipp Reisner #define BM_EXT_TO_SECT(x)   ((sector_t)(x) << (BM_EXT_SHIFT-9))
11675ab7d2c0SLars Ellenberg /* how much _storage_ sectors we have per bitmap extent */
1168b411b363SPhilipp Reisner #define BM_SECT_PER_EXT     BM_EXT_TO_SECT(1)
11695ab7d2c0SLars Ellenberg /* how many bits are covered by one bitmap extent (resync extent) */
11705ab7d2c0SLars Ellenberg #define BM_BITS_PER_EXT     (1UL << (BM_EXT_SHIFT - BM_BLOCK_SHIFT))
11715ab7d2c0SLars Ellenberg 
11725ab7d2c0SLars Ellenberg #define BM_BLOCKS_PER_BM_EXT_MASK  (BM_BITS_PER_EXT - 1)
11735ab7d2c0SLars Ellenberg 
1174b411b363SPhilipp Reisner 
1175b411b363SPhilipp Reisner /* in one sector of the bitmap, we have this many activity_log extents. */
1176b411b363SPhilipp Reisner #define AL_EXT_PER_BM_SECT  (1 << (BM_EXT_SHIFT - AL_EXTENT_SHIFT))
1177b411b363SPhilipp Reisner 
1178b411b363SPhilipp Reisner /* the extent in "PER_EXTENT" below is an activity log extent
1179b411b363SPhilipp Reisner  * we need that many (long words/bytes) to store the bitmap
1180b411b363SPhilipp Reisner  *		     of one AL_EXTENT_SIZE chunk of storage.
1181b411b363SPhilipp Reisner  * we can store the bitmap for that many AL_EXTENTS within
1182b411b363SPhilipp Reisner  * one sector of the _on_disk_ bitmap:
1183b411b363SPhilipp Reisner  * bit	 0	  bit 37   bit 38	     bit (512*8)-1
1184b411b363SPhilipp Reisner  *	     ...|........|........|.. // ..|........|
1185b411b363SPhilipp Reisner  * sect. 0	 `296	  `304			   ^(512*8*8)-1
1186b411b363SPhilipp Reisner  *
1187b411b363SPhilipp Reisner #define BM_WORDS_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / BITS_PER_LONG )
1188b411b363SPhilipp Reisner #define BM_BYTES_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / 8 )  // 128
1189b411b363SPhilipp Reisner #define BM_EXT_PER_SECT	    ( 512 / BM_BYTES_PER_EXTENT )	 //   4
1190b411b363SPhilipp Reisner  */
1191b411b363SPhilipp Reisner 
1192b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_32 (0xffffffffLU)
1193ae8bf312SLars Ellenberg /* we have a certain meta data variant that has a fixed on-disk size of 128
1194ae8bf312SLars Ellenberg  * MiB, of which 4k are our "superblock", and 32k are the fixed size activity
1195ae8bf312SLars Ellenberg  * log, leaving this many sectors for the bitmap.
1196ae8bf312SLars Ellenberg  */
1197ae8bf312SLars Ellenberg 
1198ae8bf312SLars Ellenberg #define DRBD_MAX_SECTORS_FIXED_BM \
1199ae8bf312SLars Ellenberg 	  ((MD_128MB_SECT - MD_32kB_SECT - MD_4kB_SECT) * (1LL<<(BM_EXT_SHIFT-9)))
1200ae8bf312SLars Ellenberg #if !defined(CONFIG_LBDAF) && BITS_PER_LONG == 32
1201b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_32
1202b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_32
1203b411b363SPhilipp Reisner #else
1204ae8bf312SLars Ellenberg #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_FIXED_BM
1205b411b363SPhilipp Reisner /* 16 TB in units of sectors */
1206b411b363SPhilipp Reisner #if BITS_PER_LONG == 32
1207b411b363SPhilipp Reisner /* adjust by one page worth of bitmap,
1208b411b363SPhilipp Reisner  * so we won't wrap around in drbd_bm_find_next_bit.
1209b411b363SPhilipp Reisner  * you should use 64bit OS for that much storage, anyways. */
1210b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff)
1211b411b363SPhilipp Reisner #else
12124b0715f0SLars Ellenberg /* we allow up to 1 PiB now on 64bit architecture with "flexible" meta data */
12134b0715f0SLars Ellenberg #define DRBD_MAX_SECTORS_FLEX (1UL << 51)
12144b0715f0SLars Ellenberg /* corresponds to (1UL << 38) bits right now. */
1215b411b363SPhilipp Reisner #endif
1216b411b363SPhilipp Reisner #endif
1217b411b363SPhilipp Reisner 
121823361cf3SLars Ellenberg /* BIO_MAX_SIZE is 256 * PAGE_CACHE_SIZE,
121923361cf3SLars Ellenberg  * so for typical PAGE_CACHE_SIZE of 4k, that is (1<<20) Byte.
122023361cf3SLars Ellenberg  * Since we may live in a mixed-platform cluster,
122123361cf3SLars Ellenberg  * we limit us to a platform agnostic constant here for now.
122223361cf3SLars Ellenberg  * A followup commit may allow even bigger BIO sizes,
122323361cf3SLars Ellenberg  * once we thought that through. */
122498683650SPhilipp Reisner #define DRBD_MAX_BIO_SIZE (1U << 20)
122523361cf3SLars Ellenberg #if DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE
122623361cf3SLars Ellenberg #error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE
122723361cf3SLars Ellenberg #endif
1228db141b2fSLars Ellenberg #define DRBD_MAX_BIO_SIZE_SAFE (1U << 12)       /* Works always = 4k */
1229b411b363SPhilipp Reisner 
123098683650SPhilipp Reisner #define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* Header 80 only allows packets up to 32KiB data */
123198683650SPhilipp Reisner #define DRBD_MAX_BIO_SIZE_P95    (1U << 17) /* Protocol 95 to 99 allows bios up to 128KiB */
1232b411b363SPhilipp Reisner 
1233a0fb3c47SLars Ellenberg /* For now, don't allow more than one activity log extent worth of data
1234a0fb3c47SLars Ellenberg  * to be discarded in one go. We may need to rework drbd_al_begin_io()
1235a0fb3c47SLars Ellenberg  * to allow for even larger discard ranges */
1236a0fb3c47SLars Ellenberg #define DRBD_MAX_DISCARD_SIZE	AL_EXTENT_SIZE
1237a0fb3c47SLars Ellenberg #define DRBD_MAX_DISCARD_SECTORS (DRBD_MAX_DISCARD_SIZE >> 9)
1238a0fb3c47SLars Ellenberg 
1239b30ab791SAndreas Gruenbacher extern int  drbd_bm_init(struct drbd_device *device);
1240b30ab791SAndreas Gruenbacher extern int  drbd_bm_resize(struct drbd_device *device, sector_t sectors, int set_new_bits);
1241b30ab791SAndreas Gruenbacher extern void drbd_bm_cleanup(struct drbd_device *device);
1242b30ab791SAndreas Gruenbacher extern void drbd_bm_set_all(struct drbd_device *device);
1243b30ab791SAndreas Gruenbacher extern void drbd_bm_clear_all(struct drbd_device *device);
12444b0715f0SLars Ellenberg /* set/clear/test only a few bits at a time */
1245b411b363SPhilipp Reisner extern int  drbd_bm_set_bits(
1246b30ab791SAndreas Gruenbacher 		struct drbd_device *device, unsigned long s, unsigned long e);
1247b411b363SPhilipp Reisner extern int  drbd_bm_clear_bits(
1248b30ab791SAndreas Gruenbacher 		struct drbd_device *device, unsigned long s, unsigned long e);
12494b0715f0SLars Ellenberg extern int drbd_bm_count_bits(
1250b30ab791SAndreas Gruenbacher 	struct drbd_device *device, const unsigned long s, const unsigned long e);
12514b0715f0SLars Ellenberg /* bm_set_bits variant for use while holding drbd_bm_lock,
12524b0715f0SLars Ellenberg  * may process the whole bitmap in one go */
1253b30ab791SAndreas Gruenbacher extern void _drbd_bm_set_bits(struct drbd_device *device,
1254b411b363SPhilipp Reisner 		const unsigned long s, const unsigned long e);
1255b30ab791SAndreas Gruenbacher extern int  drbd_bm_test_bit(struct drbd_device *device, unsigned long bitnr);
1256b30ab791SAndreas Gruenbacher extern int  drbd_bm_e_weight(struct drbd_device *device, unsigned long enr);
1257b30ab791SAndreas Gruenbacher extern int  drbd_bm_read(struct drbd_device *device) __must_hold(local);
1258b30ab791SAndreas Gruenbacher extern void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr);
1259b30ab791SAndreas Gruenbacher extern int  drbd_bm_write(struct drbd_device *device) __must_hold(local);
1260b30ab791SAndreas Gruenbacher extern int  drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local);
1261c7a58db4SLars Ellenberg extern int  drbd_bm_write_lazy(struct drbd_device *device, unsigned upper_idx) __must_hold(local);
1262b30ab791SAndreas Gruenbacher extern int drbd_bm_write_all(struct drbd_device *device) __must_hold(local);
1263b30ab791SAndreas Gruenbacher extern int  drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local);
1264b30ab791SAndreas Gruenbacher extern size_t	     drbd_bm_words(struct drbd_device *device);
1265b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_bits(struct drbd_device *device);
1266b30ab791SAndreas Gruenbacher extern sector_t      drbd_bm_capacity(struct drbd_device *device);
12674b0715f0SLars Ellenberg 
12684b0715f0SLars Ellenberg #define DRBD_END_OF_BITMAP	(~(unsigned long)0)
1269b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
1270b411b363SPhilipp Reisner /* bm_find_next variants for use while you hold drbd_bm_lock() */
1271b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
1272b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_find_next_zero(struct drbd_device *device, unsigned long bm_fo);
1273b30ab791SAndreas Gruenbacher extern unsigned long _drbd_bm_total_weight(struct drbd_device *device);
1274b30ab791SAndreas Gruenbacher extern unsigned long drbd_bm_total_weight(struct drbd_device *device);
1275b411b363SPhilipp Reisner /* for receive_bitmap */
1276b30ab791SAndreas Gruenbacher extern void drbd_bm_merge_lel(struct drbd_device *device, size_t offset,
1277b411b363SPhilipp Reisner 		size_t number, unsigned long *buffer);
127819f843aaSLars Ellenberg /* for _drbd_send_bitmap */
1279b30ab791SAndreas Gruenbacher extern void drbd_bm_get_lel(struct drbd_device *device, size_t offset,
1280b411b363SPhilipp Reisner 		size_t number, unsigned long *buffer);
1281b411b363SPhilipp Reisner 
1282b30ab791SAndreas Gruenbacher extern void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags);
1283b30ab791SAndreas Gruenbacher extern void drbd_bm_unlock(struct drbd_device *device);
1284b411b363SPhilipp Reisner /* drbd_main.c */
1285b411b363SPhilipp Reisner 
1286b411b363SPhilipp Reisner extern struct kmem_cache *drbd_request_cache;
12876c852becSAndreas Gruenbacher extern struct kmem_cache *drbd_ee_cache;	/* peer requests */
1288b411b363SPhilipp Reisner extern struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
1289b411b363SPhilipp Reisner extern struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
1290b411b363SPhilipp Reisner extern mempool_t *drbd_request_mempool;
1291b411b363SPhilipp Reisner extern mempool_t *drbd_ee_mempool;
1292b411b363SPhilipp Reisner 
12934281808fSLars Ellenberg /* drbd's page pool, used to buffer data received from the peer,
12944281808fSLars Ellenberg  * or data requested by the peer.
12954281808fSLars Ellenberg  *
12964281808fSLars Ellenberg  * This does not have an emergency reserve.
12974281808fSLars Ellenberg  *
12984281808fSLars Ellenberg  * When allocating from this pool, it first takes pages from the pool.
12994281808fSLars Ellenberg  * Only if the pool is depleted will try to allocate from the system.
13004281808fSLars Ellenberg  *
13014281808fSLars Ellenberg  * The assumption is that pages taken from this pool will be processed,
13024281808fSLars Ellenberg  * and given back, "quickly", and then can be recycled, so we can avoid
13034281808fSLars Ellenberg  * frequent calls to alloc_page(), and still will be able to make progress even
13044281808fSLars Ellenberg  * under memory pressure.
13054281808fSLars Ellenberg  */
13064281808fSLars Ellenberg extern struct page *drbd_pp_pool;
1307b411b363SPhilipp Reisner extern spinlock_t   drbd_pp_lock;
1308b411b363SPhilipp Reisner extern int	    drbd_pp_vacant;
1309b411b363SPhilipp Reisner extern wait_queue_head_t drbd_pp_wait;
1310b411b363SPhilipp Reisner 
13114281808fSLars Ellenberg /* We also need a standard (emergency-reserve backed) page pool
13124281808fSLars Ellenberg  * for meta data IO (activity log, bitmap).
13134281808fSLars Ellenberg  * We can keep it global, as long as it is used as "N pages at a time".
13144281808fSLars Ellenberg  * 128 should be plenty, currently we probably can get away with as few as 1.
13154281808fSLars Ellenberg  */
13164281808fSLars Ellenberg #define DRBD_MIN_POOL_PAGES	128
13174281808fSLars Ellenberg extern mempool_t *drbd_md_io_page_pool;
13184281808fSLars Ellenberg 
13199476f39dSLars Ellenberg /* We also need to make sure we get a bio
13209476f39dSLars Ellenberg  * when we need it for housekeeping purposes */
13219476f39dSLars Ellenberg extern struct bio_set *drbd_md_io_bio_set;
13229476f39dSLars Ellenberg /* to allocate from that set */
13239476f39dSLars Ellenberg extern struct bio *bio_alloc_drbd(gfp_t gfp_mask);
13249476f39dSLars Ellenberg 
1325b411b363SPhilipp Reisner extern rwlock_t global_state_lock;
1326b411b363SPhilipp Reisner 
1327bde89a9eSAndreas Gruenbacher extern int conn_lowest_minor(struct drbd_connection *connection);
1328a910b123SLars Ellenberg extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor);
132905a10ec7SAndreas Gruenbacher extern void drbd_destroy_device(struct kref *kref);
1330a910b123SLars Ellenberg extern void drbd_delete_device(struct drbd_device *device);
1331b411b363SPhilipp Reisner 
133277c556f6SAndreas Gruenbacher extern struct drbd_resource *drbd_create_resource(const char *name);
133377c556f6SAndreas Gruenbacher extern void drbd_free_resource(struct drbd_resource *resource);
133477c556f6SAndreas Gruenbacher 
1335eb6bea67SAndreas Gruenbacher extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts);
1336bde89a9eSAndreas Gruenbacher extern struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts);
133705a10ec7SAndreas Gruenbacher extern void drbd_destroy_connection(struct kref *kref);
1338bde89a9eSAndreas Gruenbacher extern struct drbd_connection *conn_get_by_addrs(void *my_addr, int my_addr_len,
1339089c075dSAndreas Gruenbacher 					    void *peer_addr, int peer_addr_len);
13404bc76048SAndreas Gruenbacher extern struct drbd_resource *drbd_find_resource(const char *name);
134177c556f6SAndreas Gruenbacher extern void drbd_destroy_resource(struct kref *kref);
1342bde89a9eSAndreas Gruenbacher extern void conn_free_crypto(struct drbd_connection *connection);
1343b411b363SPhilipp Reisner 
1344b411b363SPhilipp Reisner extern int proc_details;
1345b411b363SPhilipp Reisner 
1346b411b363SPhilipp Reisner /* drbd_req */
1347113fef9eSLars Ellenberg extern void do_submit(struct work_struct *ws);
134854761697SAndreas Gruenbacher extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
13495a7bbad2SChristoph Hellwig extern void drbd_make_request(struct request_queue *q, struct bio *bio);
1350b30ab791SAndreas Gruenbacher extern int drbd_read_remote(struct drbd_device *device, struct drbd_request *req);
1351b411b363SPhilipp Reisner extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec);
1352b411b363SPhilipp Reisner extern int is_valid_ar_handle(struct drbd_request *, sector_t);
1353b411b363SPhilipp Reisner 
1354b411b363SPhilipp Reisner 
1355b411b363SPhilipp Reisner /* drbd_nl.c */
1356a910b123SLars Ellenberg extern int drbd_msg_put_info(struct sk_buff *skb, const char *info);
1357b30ab791SAndreas Gruenbacher extern void drbd_suspend_io(struct drbd_device *device);
1358b30ab791SAndreas Gruenbacher extern void drbd_resume_io(struct drbd_device *device);
1359b411b363SPhilipp Reisner extern char *ppsize(char *buf, unsigned long long size);
136054761697SAndreas Gruenbacher extern sector_t drbd_new_dev_size(struct drbd_device *, struct drbd_backing_dev *, sector_t, int);
1361e96c9633SPhilipp Reisner enum determine_dev_size {
1362d752b269SPhilipp Reisner 	DS_ERROR_SHRINK = -3,
1363d752b269SPhilipp Reisner 	DS_ERROR_SPACE_MD = -2,
1364e96c9633SPhilipp Reisner 	DS_ERROR = -1,
1365e96c9633SPhilipp Reisner 	DS_UNCHANGED = 0,
1366e96c9633SPhilipp Reisner 	DS_SHRUNK = 1,
136757737adcSPhilipp Reisner 	DS_GREW = 2,
136857737adcSPhilipp Reisner 	DS_GREW_FROM_ZERO = 3,
1369e96c9633SPhilipp Reisner };
1370d752b269SPhilipp Reisner extern enum determine_dev_size
137154761697SAndreas Gruenbacher drbd_determine_dev_size(struct drbd_device *, enum dds_flags, struct resize_parms *) __must_hold(local);
137254761697SAndreas Gruenbacher extern void resync_after_online_grow(struct drbd_device *);
13738fe39aacSPhilipp Reisner extern void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev);
1374b30ab791SAndreas Gruenbacher extern enum drbd_state_rv drbd_set_role(struct drbd_device *device,
1375bf885f8aSAndreas Gruenbacher 					enum drbd_role new_role,
1376b411b363SPhilipp Reisner 					int force);
1377bde89a9eSAndreas Gruenbacher extern bool conn_try_outdate_peer(struct drbd_connection *connection);
1378bde89a9eSAndreas Gruenbacher extern void conn_try_outdate_peer_async(struct drbd_connection *connection);
1379b30ab791SAndreas Gruenbacher extern int drbd_khelper(struct drbd_device *device, char *cmd);
1380b411b363SPhilipp Reisner 
1381b411b363SPhilipp Reisner /* drbd_worker.c */
1382d40e5671SPhilipp Reisner /* bi_end_io handlers */
1383d40e5671SPhilipp Reisner extern void drbd_md_io_complete(struct bio *bio, int error);
1384d40e5671SPhilipp Reisner extern void drbd_peer_request_endio(struct bio *bio, int error);
1385d40e5671SPhilipp Reisner extern void drbd_request_endio(struct bio *bio, int error);
1386b411b363SPhilipp Reisner extern int drbd_worker(struct drbd_thread *thi);
1387b30ab791SAndreas Gruenbacher enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
1388b30ab791SAndreas Gruenbacher void drbd_resync_after_changed(struct drbd_device *device);
1389b30ab791SAndreas Gruenbacher extern void drbd_start_resync(struct drbd_device *device, enum drbd_conns side);
1390b30ab791SAndreas Gruenbacher extern void resume_next_sg(struct drbd_device *device);
1391b30ab791SAndreas Gruenbacher extern void suspend_other_sg(struct drbd_device *device);
1392b30ab791SAndreas Gruenbacher extern int drbd_resync_finished(struct drbd_device *device);
1393b411b363SPhilipp Reisner /* maybe rather drbd_main.c ? */
1394e37d2438SLars Ellenberg extern void *drbd_md_get_buffer(struct drbd_device *device, const char *intent);
1395b30ab791SAndreas Gruenbacher extern void drbd_md_put_buffer(struct drbd_device *device);
1396b30ab791SAndreas Gruenbacher extern int drbd_md_sync_page_io(struct drbd_device *device,
1397b411b363SPhilipp Reisner 		struct drbd_backing_dev *bdev, sector_t sector, int rw);
139854761697SAndreas Gruenbacher extern void drbd_ov_out_of_sync_found(struct drbd_device *, sector_t, int);
1399b30ab791SAndreas Gruenbacher extern void wait_until_done_or_force_detached(struct drbd_device *device,
140044edfb0dSLars Ellenberg 		struct drbd_backing_dev *bdev, unsigned int *done);
1401b30ab791SAndreas Gruenbacher extern void drbd_rs_controller_reset(struct drbd_device *device);
1402b411b363SPhilipp Reisner 
1403b30ab791SAndreas Gruenbacher static inline void ov_out_of_sync_print(struct drbd_device *device)
1404b411b363SPhilipp Reisner {
1405b30ab791SAndreas Gruenbacher 	if (device->ov_last_oos_size) {
1406d0180171SAndreas Gruenbacher 		drbd_err(device, "Out of sync: start=%llu, size=%lu (sectors)\n",
1407b30ab791SAndreas Gruenbacher 		     (unsigned long long)device->ov_last_oos_start,
1408b30ab791SAndreas Gruenbacher 		     (unsigned long)device->ov_last_oos_size);
1409b411b363SPhilipp Reisner 	}
1410b30ab791SAndreas Gruenbacher 	device->ov_last_oos_size = 0;
1411b411b363SPhilipp Reisner }
1412b411b363SPhilipp Reisner 
1413b411b363SPhilipp Reisner 
141479a3c8d3SAndreas Gruenbacher extern void drbd_csum_bio(struct crypto_hash *, struct bio *, void *);
141579a3c8d3SAndreas Gruenbacher extern void drbd_csum_ee(struct crypto_hash *, struct drbd_peer_request *, void *);
1416b411b363SPhilipp Reisner /* worker callbacks */
141799920dc5SAndreas Gruenbacher extern int w_e_end_data_req(struct drbd_work *, int);
141899920dc5SAndreas Gruenbacher extern int w_e_end_rsdata_req(struct drbd_work *, int);
141999920dc5SAndreas Gruenbacher extern int w_e_end_csum_rs_req(struct drbd_work *, int);
142099920dc5SAndreas Gruenbacher extern int w_e_end_ov_reply(struct drbd_work *, int);
142199920dc5SAndreas Gruenbacher extern int w_e_end_ov_req(struct drbd_work *, int);
142299920dc5SAndreas Gruenbacher extern int w_ov_finished(struct drbd_work *, int);
142399920dc5SAndreas Gruenbacher extern int w_resync_timer(struct drbd_work *, int);
142499920dc5SAndreas Gruenbacher extern int w_send_write_hint(struct drbd_work *, int);
142599920dc5SAndreas Gruenbacher extern int w_send_dblock(struct drbd_work *, int);
142699920dc5SAndreas Gruenbacher extern int w_send_read_req(struct drbd_work *, int);
142799920dc5SAndreas Gruenbacher extern int w_e_reissue(struct drbd_work *, int);
142899920dc5SAndreas Gruenbacher extern int w_restart_disk_io(struct drbd_work *, int);
14298f7bed77SAndreas Gruenbacher extern int w_send_out_of_sync(struct drbd_work *, int);
143099920dc5SAndreas Gruenbacher extern int w_start_resync(struct drbd_work *, int);
1431b411b363SPhilipp Reisner 
1432b411b363SPhilipp Reisner extern void resync_timer_fn(unsigned long data);
1433370a43e7SPhilipp Reisner extern void start_resync_timer_fn(unsigned long data);
1434b411b363SPhilipp Reisner 
1435a0fb3c47SLars Ellenberg extern void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req);
1436a0fb3c47SLars Ellenberg 
1437b411b363SPhilipp Reisner /* drbd_receiver.c */
1438753c6191SAndreas Gruenbacher extern int drbd_receiver(struct drbd_thread *thi);
1439753c6191SAndreas Gruenbacher extern int drbd_asender(struct drbd_thread *thi);
1440e8299874SLars Ellenberg extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device);
1441e8299874SLars Ellenberg extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector);
144254761697SAndreas Gruenbacher extern int drbd_submit_peer_request(struct drbd_device *,
1443fbe29decSAndreas Gruenbacher 				    struct drbd_peer_request *, const unsigned,
1444fbe29decSAndreas Gruenbacher 				    const int);
144554761697SAndreas Gruenbacher extern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
144669a22773SAndreas Gruenbacher extern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
14470db55363SAndreas Gruenbacher 						     sector_t, unsigned int,
1448a0fb3c47SLars Ellenberg 						     bool,
1449f6ffca9fSAndreas Gruenbacher 						     gfp_t) __must_hold(local);
145054761697SAndreas Gruenbacher extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *,
1451f6ffca9fSAndreas Gruenbacher 				 int);
14523967deb1SAndreas Gruenbacher #define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0)
14533967deb1SAndreas Gruenbacher #define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1)
145469a22773SAndreas Gruenbacher extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
1455b30ab791SAndreas Gruenbacher extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
1456b30ab791SAndreas Gruenbacher extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
145769a22773SAndreas Gruenbacher extern int drbd_connected(struct drbd_peer_device *);
1458b411b363SPhilipp Reisner 
1459ed439848SLars Ellenberg /* Yes, there is kernel_setsockopt, but only since 2.6.18.
1460ed439848SLars Ellenberg  * So we have our own copy of it here. */
1461b411b363SPhilipp Reisner static inline int drbd_setsockopt(struct socket *sock, int level, int optname,
1462ed439848SLars Ellenberg 				  char *optval, int optlen)
1463b411b363SPhilipp Reisner {
1464ed439848SLars Ellenberg 	mm_segment_t oldfs = get_fs();
1465ed439848SLars Ellenberg 	char __user *uoptval;
1466b411b363SPhilipp Reisner 	int err;
1467ed439848SLars Ellenberg 
1468ed439848SLars Ellenberg 	uoptval = (char __user __force *)optval;
1469ed439848SLars Ellenberg 
1470ed439848SLars Ellenberg 	set_fs(KERNEL_DS);
1471b411b363SPhilipp Reisner 	if (level == SOL_SOCKET)
1472ed439848SLars Ellenberg 		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
1473b411b363SPhilipp Reisner 	else
1474ed439848SLars Ellenberg 		err = sock->ops->setsockopt(sock, level, optname, uoptval,
1475b411b363SPhilipp Reisner 					    optlen);
1476ed439848SLars Ellenberg 	set_fs(oldfs);
1477b411b363SPhilipp Reisner 	return err;
1478b411b363SPhilipp Reisner }
1479b411b363SPhilipp Reisner 
1480b411b363SPhilipp Reisner static inline void drbd_tcp_cork(struct socket *sock)
1481b411b363SPhilipp Reisner {
1482ed439848SLars Ellenberg 	int val = 1;
1483b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
1484ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1485b411b363SPhilipp Reisner }
1486b411b363SPhilipp Reisner 
1487b411b363SPhilipp Reisner static inline void drbd_tcp_uncork(struct socket *sock)
1488b411b363SPhilipp Reisner {
1489ed439848SLars Ellenberg 	int val = 0;
1490b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
1491ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1492b411b363SPhilipp Reisner }
1493b411b363SPhilipp Reisner 
1494b411b363SPhilipp Reisner static inline void drbd_tcp_nodelay(struct socket *sock)
1495b411b363SPhilipp Reisner {
1496ed439848SLars Ellenberg 	int val = 1;
1497b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY,
1498ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1499b411b363SPhilipp Reisner }
1500b411b363SPhilipp Reisner 
1501b411b363SPhilipp Reisner static inline void drbd_tcp_quickack(struct socket *sock)
1502b411b363SPhilipp Reisner {
1503ed439848SLars Ellenberg 	int val = 2;
1504b411b363SPhilipp Reisner 	(void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
1505ed439848SLars Ellenberg 			(char*)&val, sizeof(val));
1506b411b363SPhilipp Reisner }
1507b411b363SPhilipp Reisner 
1508d40e5671SPhilipp Reisner /* sets the number of 512 byte sectors of our virtual device */
1509d40e5671SPhilipp Reisner static inline void drbd_set_my_capacity(struct drbd_device *device,
1510d40e5671SPhilipp Reisner 					sector_t size)
1511d40e5671SPhilipp Reisner {
1512d40e5671SPhilipp Reisner 	/* set_capacity(device->this_bdev->bd_disk, size); */
1513d40e5671SPhilipp Reisner 	set_capacity(device->vdisk, size);
1514d40e5671SPhilipp Reisner 	device->this_bdev->bd_inode->i_size = (loff_t)size << 9;
1515d40e5671SPhilipp Reisner }
1516d40e5671SPhilipp Reisner 
1517d40e5671SPhilipp Reisner /*
1518d40e5671SPhilipp Reisner  * used to submit our private bio
1519d40e5671SPhilipp Reisner  */
1520d40e5671SPhilipp Reisner static inline void drbd_generic_make_request(struct drbd_device *device,
1521d40e5671SPhilipp Reisner 					     int fault_type, struct bio *bio)
1522d40e5671SPhilipp Reisner {
1523d40e5671SPhilipp Reisner 	__release(local);
1524d40e5671SPhilipp Reisner 	if (!bio->bi_bdev) {
1525f88c5d90SLars Ellenberg 		drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n");
1526d40e5671SPhilipp Reisner 		bio_endio(bio, -ENODEV);
1527d40e5671SPhilipp Reisner 		return;
1528d40e5671SPhilipp Reisner 	}
1529d40e5671SPhilipp Reisner 
1530d40e5671SPhilipp Reisner 	if (drbd_insert_fault(device, fault_type))
1531d40e5671SPhilipp Reisner 		bio_endio(bio, -EIO);
1532d40e5671SPhilipp Reisner 	else
1533d40e5671SPhilipp Reisner 		generic_make_request(bio);
1534d40e5671SPhilipp Reisner }
1535d40e5671SPhilipp Reisner 
15368fe39aacSPhilipp Reisner void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backing_dev *bdev,
15378fe39aacSPhilipp Reisner 			      enum write_ordering_e wo);
1538b411b363SPhilipp Reisner 
1539b411b363SPhilipp Reisner /* drbd_proc.c */
1540b411b363SPhilipp Reisner extern struct proc_dir_entry *drbd_proc;
15417d4e9d09SEmese Revfy extern const struct file_operations drbd_proc_fops;
1542b411b363SPhilipp Reisner extern const char *drbd_conn_str(enum drbd_conns s);
1543b411b363SPhilipp Reisner extern const char *drbd_role_str(enum drbd_role s);
1544b411b363SPhilipp Reisner 
1545b411b363SPhilipp Reisner /* drbd_actlog.c */
1546e4d7d6f4SLars Ellenberg extern bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *i);
1547b30ab791SAndreas Gruenbacher extern int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i);
15484dd726f0SLars Ellenberg extern void drbd_al_begin_io_commit(struct drbd_device *device);
1549b30ab791SAndreas Gruenbacher extern bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i);
15504dd726f0SLars Ellenberg extern void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i);
1551b30ab791SAndreas Gruenbacher extern void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i);
1552b30ab791SAndreas Gruenbacher extern void drbd_rs_complete_io(struct drbd_device *device, sector_t sector);
1553b30ab791SAndreas Gruenbacher extern int drbd_rs_begin_io(struct drbd_device *device, sector_t sector);
1554b30ab791SAndreas Gruenbacher extern int drbd_try_rs_begin_io(struct drbd_device *device, sector_t sector);
1555b30ab791SAndreas Gruenbacher extern void drbd_rs_cancel_all(struct drbd_device *device);
1556b30ab791SAndreas Gruenbacher extern int drbd_rs_del_all(struct drbd_device *device);
1557b30ab791SAndreas Gruenbacher extern void drbd_rs_failed_io(struct drbd_device *device,
1558b411b363SPhilipp Reisner 		sector_t sector, int size);
1559b30ab791SAndreas Gruenbacher extern void drbd_advance_rs_marks(struct drbd_device *device, unsigned long still_to_go);
15605ab7d2c0SLars Ellenberg 
15615ab7d2c0SLars Ellenberg enum update_sync_bits_mode { RECORD_RS_FAILED, SET_OUT_OF_SYNC, SET_IN_SYNC };
15625ab7d2c0SLars Ellenberg extern int __drbd_change_sync(struct drbd_device *device, sector_t sector, int size,
15635ab7d2c0SLars Ellenberg 		enum update_sync_bits_mode mode,
15645ab7d2c0SLars Ellenberg 		const char *file, const unsigned int line);
1565b30ab791SAndreas Gruenbacher #define drbd_set_in_sync(device, sector, size) \
15665ab7d2c0SLars Ellenberg 	__drbd_change_sync(device, sector, size, SET_IN_SYNC, __FILE__, __LINE__)
1567b30ab791SAndreas Gruenbacher #define drbd_set_out_of_sync(device, sector, size) \
15685ab7d2c0SLars Ellenberg 	__drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC, __FILE__, __LINE__)
15695ab7d2c0SLars Ellenberg #define drbd_rs_failed_io(device, sector, size) \
15705ab7d2c0SLars Ellenberg 	__drbd_change_sync(device, sector, size, RECORD_RS_FAILED, __FILE__, __LINE__)
1571b30ab791SAndreas Gruenbacher extern void drbd_al_shrink(struct drbd_device *device);
157254761697SAndreas Gruenbacher extern int drbd_initialize_al(struct drbd_device *, void *);
1573b411b363SPhilipp Reisner 
1574b411b363SPhilipp Reisner /* drbd_nl.c */
15753b98c0c2SLars Ellenberg /* state info broadcast */
15763b98c0c2SLars Ellenberg struct sib_info {
15773b98c0c2SLars Ellenberg 	enum drbd_state_info_bcast_reason sib_reason;
15783b98c0c2SLars Ellenberg 	union {
15793b98c0c2SLars Ellenberg 		struct {
15803b98c0c2SLars Ellenberg 			char *helper_name;
15813b98c0c2SLars Ellenberg 			unsigned helper_exit_code;
15823b98c0c2SLars Ellenberg 		};
15833b98c0c2SLars Ellenberg 		struct {
15843b98c0c2SLars Ellenberg 			union drbd_state os;
15853b98c0c2SLars Ellenberg 			union drbd_state ns;
15863b98c0c2SLars Ellenberg 		};
15873b98c0c2SLars Ellenberg 	};
15883b98c0c2SLars Ellenberg };
1589b30ab791SAndreas Gruenbacher void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
1590b411b363SPhilipp Reisner 
1591b411b363SPhilipp Reisner /*
1592b411b363SPhilipp Reisner  * inline helper functions
1593b411b363SPhilipp Reisner  *************************/
1594b411b363SPhilipp Reisner 
159545bb912bSLars Ellenberg /* see also page_chain_add and friends in drbd_receiver.c */
159645bb912bSLars Ellenberg static inline struct page *page_chain_next(struct page *page)
159745bb912bSLars Ellenberg {
159845bb912bSLars Ellenberg 	return (struct page *)page_private(page);
159945bb912bSLars Ellenberg }
160045bb912bSLars Ellenberg #define page_chain_for_each(page) \
160145bb912bSLars Ellenberg 	for (; page && ({ prefetch(page_chain_next(page)); 1; }); \
160245bb912bSLars Ellenberg 			page = page_chain_next(page))
160345bb912bSLars Ellenberg #define page_chain_for_each_safe(page, n) \
160445bb912bSLars Ellenberg 	for (; page && ({ n = page_chain_next(page); 1; }); page = n)
160545bb912bSLars Ellenberg 
160645bb912bSLars Ellenberg 
1607045417f7SAndreas Gruenbacher static inline int drbd_peer_req_has_active_page(struct drbd_peer_request *peer_req)
160845bb912bSLars Ellenberg {
1609db830c46SAndreas Gruenbacher 	struct page *page = peer_req->pages;
161045bb912bSLars Ellenberg 	page_chain_for_each(page) {
161145bb912bSLars Ellenberg 		if (page_count(page) > 1)
161245bb912bSLars Ellenberg 			return 1;
161345bb912bSLars Ellenberg 	}
161445bb912bSLars Ellenberg 	return 0;
161545bb912bSLars Ellenberg }
161645bb912bSLars Ellenberg 
1617bf885f8aSAndreas Gruenbacher static inline enum drbd_state_rv
1618b30ab791SAndreas Gruenbacher _drbd_set_state(struct drbd_device *device, union drbd_state ns,
1619bf885f8aSAndreas Gruenbacher 		enum chg_state_flags flags, struct completion *done)
1620b411b363SPhilipp Reisner {
1621bf885f8aSAndreas Gruenbacher 	enum drbd_state_rv rv;
1622b411b363SPhilipp Reisner 
1623b411b363SPhilipp Reisner 	read_lock(&global_state_lock);
1624b30ab791SAndreas Gruenbacher 	rv = __drbd_set_state(device, ns, flags, done);
1625b411b363SPhilipp Reisner 	read_unlock(&global_state_lock);
1626b411b363SPhilipp Reisner 
1627b411b363SPhilipp Reisner 	return rv;
1628b411b363SPhilipp Reisner }
1629b411b363SPhilipp Reisner 
1630b30ab791SAndreas Gruenbacher static inline union drbd_state drbd_read_state(struct drbd_device *device)
1631b411b363SPhilipp Reisner {
16326bbf53caSAndreas Gruenbacher 	struct drbd_resource *resource = device->resource;
163378bae59bSPhilipp Reisner 	union drbd_state rv;
163478bae59bSPhilipp Reisner 
1635b30ab791SAndreas Gruenbacher 	rv.i = device->state.i;
16366bbf53caSAndreas Gruenbacher 	rv.susp = resource->susp;
16376bbf53caSAndreas Gruenbacher 	rv.susp_nod = resource->susp_nod;
16386bbf53caSAndreas Gruenbacher 	rv.susp_fen = resource->susp_fen;
163978bae59bSPhilipp Reisner 
164078bae59bSPhilipp Reisner 	return rv;
1641b411b363SPhilipp Reisner }
1642b411b363SPhilipp Reisner 
1643383606e0SLars Ellenberg enum drbd_force_detach_flags {
1644a2a3c74fSLars Ellenberg 	DRBD_READ_ERROR,
1645a2a3c74fSLars Ellenberg 	DRBD_WRITE_ERROR,
1646383606e0SLars Ellenberg 	DRBD_META_IO_ERROR,
1647383606e0SLars Ellenberg 	DRBD_FORCE_DETACH,
1648383606e0SLars Ellenberg };
1649383606e0SLars Ellenberg 
1650b411b363SPhilipp Reisner #define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
1651b30ab791SAndreas Gruenbacher static inline void __drbd_chk_io_error_(struct drbd_device *device,
1652a2a3c74fSLars Ellenberg 		enum drbd_force_detach_flags df,
1653383606e0SLars Ellenberg 		const char *where)
1654b411b363SPhilipp Reisner {
1655daeda1ccSPhilipp Reisner 	enum drbd_io_error_p ep;
1656daeda1ccSPhilipp Reisner 
1657daeda1ccSPhilipp Reisner 	rcu_read_lock();
1658b30ab791SAndreas Gruenbacher 	ep = rcu_dereference(device->ldev->disk_conf)->on_io_error;
1659daeda1ccSPhilipp Reisner 	rcu_read_unlock();
1660daeda1ccSPhilipp Reisner 	switch (ep) {
1661daeda1ccSPhilipp Reisner 	case EP_PASS_ON: /* FIXME would this be better named "Ignore"? */
1662a2a3c74fSLars Ellenberg 		if (df == DRBD_READ_ERROR || df == DRBD_WRITE_ERROR) {
16637383506cSLars Ellenberg 			if (__ratelimit(&drbd_ratelimit_state))
1664d0180171SAndreas Gruenbacher 				drbd_err(device, "Local IO failed in %s.\n", where);
1665b30ab791SAndreas Gruenbacher 			if (device->state.disk > D_INCONSISTENT)
1666b30ab791SAndreas Gruenbacher 				_drbd_set_state(_NS(device, disk, D_INCONSISTENT), CS_HARD, NULL);
1667b411b363SPhilipp Reisner 			break;
1668b411b363SPhilipp Reisner 		}
1669a2a3c74fSLars Ellenberg 		/* NOTE fall through for DRBD_META_IO_ERROR or DRBD_FORCE_DETACH */
1670b411b363SPhilipp Reisner 	case EP_DETACH:
1671b411b363SPhilipp Reisner 	case EP_CALL_HELPER:
1672a2a3c74fSLars Ellenberg 		/* Remember whether we saw a READ or WRITE error.
1673a2a3c74fSLars Ellenberg 		 *
1674a2a3c74fSLars Ellenberg 		 * Recovery of the affected area for WRITE failure is covered
1675a2a3c74fSLars Ellenberg 		 * by the activity log.
1676a2a3c74fSLars Ellenberg 		 * READ errors may fall outside that area though. Certain READ
1677a2a3c74fSLars Ellenberg 		 * errors can be "healed" by writing good data to the affected
1678a2a3c74fSLars Ellenberg 		 * blocks, which triggers block re-allocation in lower layers.
1679a2a3c74fSLars Ellenberg 		 *
1680a2a3c74fSLars Ellenberg 		 * If we can not write the bitmap after a READ error,
1681a2a3c74fSLars Ellenberg 		 * we may need to trigger a full sync (see w_go_diskless()).
1682a2a3c74fSLars Ellenberg 		 *
1683a2a3c74fSLars Ellenberg 		 * Force-detach is not really an IO error, but rather a
1684a2a3c74fSLars Ellenberg 		 * desperate measure to try to deal with a completely
1685a2a3c74fSLars Ellenberg 		 * unresponsive lower level IO stack.
1686a2a3c74fSLars Ellenberg 		 * Still it should be treated as a WRITE error.
1687a2a3c74fSLars Ellenberg 		 *
1688a2a3c74fSLars Ellenberg 		 * Meta IO error is always WRITE error:
1689a2a3c74fSLars Ellenberg 		 * we read meta data only once during attach,
1690a2a3c74fSLars Ellenberg 		 * which will fail in case of errors.
1691a2a3c74fSLars Ellenberg 		 */
1692b30ab791SAndreas Gruenbacher 		set_bit(WAS_IO_ERROR, &device->flags);
1693a2a3c74fSLars Ellenberg 		if (df == DRBD_READ_ERROR)
1694b30ab791SAndreas Gruenbacher 			set_bit(WAS_READ_ERROR, &device->flags);
1695a2a3c74fSLars Ellenberg 		if (df == DRBD_FORCE_DETACH)
1696b30ab791SAndreas Gruenbacher 			set_bit(FORCE_DETACH, &device->flags);
1697b30ab791SAndreas Gruenbacher 		if (device->state.disk > D_FAILED) {
1698b30ab791SAndreas Gruenbacher 			_drbd_set_state(_NS(device, disk, D_FAILED), CS_HARD, NULL);
1699d0180171SAndreas Gruenbacher 			drbd_err(device,
170082f59cc6SLars Ellenberg 				"Local IO failed in %s. Detaching...\n", where);
1701b411b363SPhilipp Reisner 		}
1702b411b363SPhilipp Reisner 		break;
1703b411b363SPhilipp Reisner 	}
1704b411b363SPhilipp Reisner }
1705b411b363SPhilipp Reisner 
1706b411b363SPhilipp Reisner /**
1707b411b363SPhilipp Reisner  * drbd_chk_io_error: Handle the on_io_error setting, should be called from all io completion handlers
1708b30ab791SAndreas Gruenbacher  * @device:	 DRBD device.
1709b411b363SPhilipp Reisner  * @error:	 Error code passed to the IO completion callback
1710b411b363SPhilipp Reisner  * @forcedetach: Force detach. I.e. the error happened while accessing the meta data
1711b411b363SPhilipp Reisner  *
1712b411b363SPhilipp Reisner  * See also drbd_main.c:after_state_ch() if (os.disk > D_FAILED && ns.disk == D_FAILED)
1713b411b363SPhilipp Reisner  */
1714b411b363SPhilipp Reisner #define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__)
1715b30ab791SAndreas Gruenbacher static inline void drbd_chk_io_error_(struct drbd_device *device,
1716383606e0SLars Ellenberg 	int error, enum drbd_force_detach_flags forcedetach, const char *where)
1717b411b363SPhilipp Reisner {
1718b411b363SPhilipp Reisner 	if (error) {
1719b411b363SPhilipp Reisner 		unsigned long flags;
17200500813fSAndreas Gruenbacher 		spin_lock_irqsave(&device->resource->req_lock, flags);
1721b30ab791SAndreas Gruenbacher 		__drbd_chk_io_error_(device, forcedetach, where);
17220500813fSAndreas Gruenbacher 		spin_unlock_irqrestore(&device->resource->req_lock, flags);
1723b411b363SPhilipp Reisner 	}
1724b411b363SPhilipp Reisner }
1725b411b363SPhilipp Reisner 
1726b411b363SPhilipp Reisner 
1727b411b363SPhilipp Reisner /**
1728b411b363SPhilipp Reisner  * drbd_md_first_sector() - Returns the first sector number of the meta data area
1729b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1730b411b363SPhilipp Reisner  *
1731b411b363SPhilipp Reisner  * BTW, for internal meta data, this happens to be the maximum capacity
1732b411b363SPhilipp Reisner  * we could agree upon with our peer node.
1733b411b363SPhilipp Reisner  */
173468e41a43SLars Ellenberg static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
1735b411b363SPhilipp Reisner {
173668e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1737b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1738b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1739b411b363SPhilipp Reisner 		return bdev->md.md_offset + bdev->md.bm_offset;
1740b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1741b411b363SPhilipp Reisner 	default:
1742b411b363SPhilipp Reisner 		return bdev->md.md_offset;
1743b411b363SPhilipp Reisner 	}
1744b411b363SPhilipp Reisner }
1745b411b363SPhilipp Reisner 
1746b411b363SPhilipp Reisner /**
1747b411b363SPhilipp Reisner  * drbd_md_last_sector() - Return the last sector number of the meta data area
1748b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1749b411b363SPhilipp Reisner  */
1750b411b363SPhilipp Reisner static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
1751b411b363SPhilipp Reisner {
175268e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1753b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1754b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1755ae8bf312SLars Ellenberg 		return bdev->md.md_offset + MD_4kB_SECT -1;
1756b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1757b411b363SPhilipp Reisner 	default:
1758ae8bf312SLars Ellenberg 		return bdev->md.md_offset + bdev->md.md_size_sect -1;
1759b411b363SPhilipp Reisner 	}
1760b411b363SPhilipp Reisner }
1761b411b363SPhilipp Reisner 
1762b411b363SPhilipp Reisner /* Returns the number of 512 byte sectors of the device */
1763b411b363SPhilipp Reisner static inline sector_t drbd_get_capacity(struct block_device *bdev)
1764b411b363SPhilipp Reisner {
1765b411b363SPhilipp Reisner 	/* return bdev ? get_capacity(bdev->bd_disk) : 0; */
176677304d2aSMike Snitzer 	return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0;
1767b411b363SPhilipp Reisner }
1768b411b363SPhilipp Reisner 
1769b411b363SPhilipp Reisner /**
1770b411b363SPhilipp Reisner  * drbd_get_max_capacity() - Returns the capacity we announce to out peer
1771b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1772b411b363SPhilipp Reisner  *
1773b411b363SPhilipp Reisner  * returns the capacity we announce to out peer.  we clip ourselves at the
1774b411b363SPhilipp Reisner  * various MAX_SECTORS, because if we don't, current implementation will
1775b411b363SPhilipp Reisner  * oops sooner or later
1776b411b363SPhilipp Reisner  */
1777b411b363SPhilipp Reisner static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
1778b411b363SPhilipp Reisner {
1779b411b363SPhilipp Reisner 	sector_t s;
1780daeda1ccSPhilipp Reisner 
178168e41a43SLars Ellenberg 	switch (bdev->md.meta_dev_idx) {
1782b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_INTERNAL:
1783b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_INT:
1784b411b363SPhilipp Reisner 		s = drbd_get_capacity(bdev->backing_bdev)
1785b411b363SPhilipp Reisner 			? min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
178668e41a43SLars Ellenberg 				drbd_md_first_sector(bdev))
1787b411b363SPhilipp Reisner 			: 0;
1788b411b363SPhilipp Reisner 		break;
1789b411b363SPhilipp Reisner 	case DRBD_MD_INDEX_FLEX_EXT:
1790b411b363SPhilipp Reisner 		s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
1791b411b363SPhilipp Reisner 				drbd_get_capacity(bdev->backing_bdev));
1792b411b363SPhilipp Reisner 		/* clip at maximum size the meta device can support */
1793b411b363SPhilipp Reisner 		s = min_t(sector_t, s,
1794b411b363SPhilipp Reisner 			BM_EXT_TO_SECT(bdev->md.md_size_sect
1795b411b363SPhilipp Reisner 				     - bdev->md.bm_offset));
1796b411b363SPhilipp Reisner 		break;
1797b411b363SPhilipp Reisner 	default:
1798b411b363SPhilipp Reisner 		s = min_t(sector_t, DRBD_MAX_SECTORS,
1799b411b363SPhilipp Reisner 				drbd_get_capacity(bdev->backing_bdev));
1800b411b363SPhilipp Reisner 	}
1801b411b363SPhilipp Reisner 	return s;
1802b411b363SPhilipp Reisner }
1803b411b363SPhilipp Reisner 
1804b411b363SPhilipp Reisner /**
18053a4d4eb3SLars Ellenberg  * drbd_md_ss() - Return the sector number of our meta data super block
1806b411b363SPhilipp Reisner  * @bdev:	Meta data block device.
1807b411b363SPhilipp Reisner  */
18083a4d4eb3SLars Ellenberg static inline sector_t drbd_md_ss(struct drbd_backing_dev *bdev)
1809b411b363SPhilipp Reisner {
18103a4d4eb3SLars Ellenberg 	const int meta_dev_idx = bdev->md.meta_dev_idx;
1811daeda1ccSPhilipp Reisner 
18123a4d4eb3SLars Ellenberg 	if (meta_dev_idx == DRBD_MD_INDEX_FLEX_EXT)
1813b411b363SPhilipp Reisner 		return 0;
18143a4d4eb3SLars Ellenberg 
18153a4d4eb3SLars Ellenberg 	/* Since drbd08, internal meta data is always "flexible".
1816ae8bf312SLars Ellenberg 	 * position: last 4k aligned block of 4k size */
18173a4d4eb3SLars Ellenberg 	if (meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
18183a4d4eb3SLars Ellenberg 	    meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)
1819ae8bf312SLars Ellenberg 		return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) - 8;
18203a4d4eb3SLars Ellenberg 
18213a4d4eb3SLars Ellenberg 	/* external, some index; this is the old fixed size layout */
18223a4d4eb3SLars Ellenberg 	return MD_128MB_SECT * bdev->md.meta_dev_idx;
1823b411b363SPhilipp Reisner }
1824b411b363SPhilipp Reisner 
1825b411b363SPhilipp Reisner static inline void
1826b411b363SPhilipp Reisner drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
1827b411b363SPhilipp Reisner {
1828b411b363SPhilipp Reisner 	unsigned long flags;
1829b411b363SPhilipp Reisner 	spin_lock_irqsave(&q->q_lock, flags);
1830b411b363SPhilipp Reisner 	list_add_tail(&w->list, &q->q);
1831b411b363SPhilipp Reisner 	spin_unlock_irqrestore(&q->q_lock, flags);
18328c0785a5SLars Ellenberg 	wake_up(&q->q_wait);
1833b411b363SPhilipp Reisner }
1834b411b363SPhilipp Reisner 
1835e334f550SLars Ellenberg static inline void
183615e26f6aSLars Ellenberg drbd_queue_work_if_unqueued(struct drbd_work_queue *q, struct drbd_work *w)
183715e26f6aSLars Ellenberg {
183815e26f6aSLars Ellenberg 	unsigned long flags;
183915e26f6aSLars Ellenberg 	spin_lock_irqsave(&q->q_lock, flags);
184015e26f6aSLars Ellenberg 	if (list_empty_careful(&w->list))
184115e26f6aSLars Ellenberg 		list_add_tail(&w->list, &q->q);
184215e26f6aSLars Ellenberg 	spin_unlock_irqrestore(&q->q_lock, flags);
184315e26f6aSLars Ellenberg 	wake_up(&q->q_wait);
184415e26f6aSLars Ellenberg }
184515e26f6aSLars Ellenberg 
184615e26f6aSLars Ellenberg static inline void
1847e334f550SLars Ellenberg drbd_device_post_work(struct drbd_device *device, int work_bit)
1848e334f550SLars Ellenberg {
1849e334f550SLars Ellenberg 	if (!test_and_set_bit(work_bit, &device->flags)) {
1850e334f550SLars Ellenberg 		struct drbd_connection *connection =
1851e334f550SLars Ellenberg 			first_peer_device(device)->connection;
1852e334f550SLars Ellenberg 		struct drbd_work_queue *q = &connection->sender_work;
1853e334f550SLars Ellenberg 		if (!test_and_set_bit(DEVICE_WORK_PENDING, &connection->flags))
1854e334f550SLars Ellenberg 			wake_up(&q->q_wait);
1855e334f550SLars Ellenberg 	}
1856e334f550SLars Ellenberg }
1857e334f550SLars Ellenberg 
1858b5043c5eSAndreas Gruenbacher extern void drbd_flush_workqueue(struct drbd_work_queue *work_queue);
1859b5043c5eSAndreas Gruenbacher 
1860bde89a9eSAndreas Gruenbacher static inline void wake_asender(struct drbd_connection *connection)
1861b411b363SPhilipp Reisner {
1862bde89a9eSAndreas Gruenbacher 	if (test_bit(SIGNAL_ASENDER, &connection->flags))
1863bde89a9eSAndreas Gruenbacher 		force_sig(DRBD_SIG, connection->asender.task);
1864b411b363SPhilipp Reisner }
1865b411b363SPhilipp Reisner 
1866bde89a9eSAndreas Gruenbacher static inline void request_ping(struct drbd_connection *connection)
1867b411b363SPhilipp Reisner {
1868bde89a9eSAndreas Gruenbacher 	set_bit(SEND_PING, &connection->flags);
1869bde89a9eSAndreas Gruenbacher 	wake_asender(connection);
1870b411b363SPhilipp Reisner }
1871b411b363SPhilipp Reisner 
1872bde89a9eSAndreas Gruenbacher extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
187369a22773SAndreas Gruenbacher extern void *drbd_prepare_command(struct drbd_peer_device *, struct drbd_socket *);
1874bde89a9eSAndreas Gruenbacher extern int conn_send_command(struct drbd_connection *, struct drbd_socket *,
1875dba58587SAndreas Gruenbacher 			     enum drbd_packet, unsigned int, void *,
1876dba58587SAndreas Gruenbacher 			     unsigned int);
187769a22773SAndreas Gruenbacher extern int drbd_send_command(struct drbd_peer_device *, struct drbd_socket *,
1878dba58587SAndreas Gruenbacher 			     enum drbd_packet, unsigned int, void *,
1879dba58587SAndreas Gruenbacher 			     unsigned int);
1880b411b363SPhilipp Reisner 
1881bde89a9eSAndreas Gruenbacher extern int drbd_send_ping(struct drbd_connection *connection);
1882bde89a9eSAndreas Gruenbacher extern int drbd_send_ping_ack(struct drbd_connection *connection);
188369a22773SAndreas Gruenbacher extern int drbd_send_state_req(struct drbd_peer_device *, union drbd_state, union drbd_state);
1884bde89a9eSAndreas Gruenbacher extern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state);
1885b411b363SPhilipp Reisner 
1886b411b363SPhilipp Reisner static inline void drbd_thread_stop(struct drbd_thread *thi)
1887b411b363SPhilipp Reisner {
188881e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, false, true);
1889b411b363SPhilipp Reisner }
1890b411b363SPhilipp Reisner 
1891b411b363SPhilipp Reisner static inline void drbd_thread_stop_nowait(struct drbd_thread *thi)
1892b411b363SPhilipp Reisner {
189381e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, false, false);
1894b411b363SPhilipp Reisner }
1895b411b363SPhilipp Reisner 
1896b411b363SPhilipp Reisner static inline void drbd_thread_restart_nowait(struct drbd_thread *thi)
1897b411b363SPhilipp Reisner {
189881e84650SAndreas Gruenbacher 	_drbd_thread_stop(thi, true, false);
1899b411b363SPhilipp Reisner }
1900b411b363SPhilipp Reisner 
1901b411b363SPhilipp Reisner /* counts how many answer packets packets we expect from our peer,
1902b411b363SPhilipp Reisner  * for either explicit application requests,
1903b411b363SPhilipp Reisner  * or implicit barrier packets as necessary.
1904b411b363SPhilipp Reisner  * increased:
1905b411b363SPhilipp Reisner  *  w_send_barrier
19068554df1cSAndreas Gruenbacher  *  _req_mod(req, QUEUE_FOR_NET_WRITE or QUEUE_FOR_NET_READ);
1907b411b363SPhilipp Reisner  *    it is much easier and equally valid to count what we queue for the
1908b411b363SPhilipp Reisner  *    worker, even before it actually was queued or send.
1909b411b363SPhilipp Reisner  *    (drbd_make_request_common; recovery path on read io-error)
1910b411b363SPhilipp Reisner  * decreased:
1911b411b363SPhilipp Reisner  *  got_BarrierAck (respective tl_clear, tl_clear_barrier)
19128554df1cSAndreas Gruenbacher  *  _req_mod(req, DATA_RECEIVED)
1913b411b363SPhilipp Reisner  *     [from receive_DataReply]
19148554df1cSAndreas Gruenbacher  *  _req_mod(req, WRITE_ACKED_BY_PEER or RECV_ACKED_BY_PEER or NEG_ACKED)
1915b411b363SPhilipp Reisner  *     [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)]
1916b411b363SPhilipp Reisner  *     for some reason it is NOT decreased in got_NegAck,
1917b411b363SPhilipp Reisner  *     but in the resulting cleanup code from report_params.
1918b411b363SPhilipp Reisner  *     we should try to remember the reason for that...
19198554df1cSAndreas Gruenbacher  *  _req_mod(req, SEND_FAILED or SEND_CANCELED)
19208554df1cSAndreas Gruenbacher  *  _req_mod(req, CONNECTION_LOST_WHILE_PENDING)
1921b411b363SPhilipp Reisner  *     [from tl_clear_barrier]
1922b411b363SPhilipp Reisner  */
1923b30ab791SAndreas Gruenbacher static inline void inc_ap_pending(struct drbd_device *device)
1924b411b363SPhilipp Reisner {
1925b30ab791SAndreas Gruenbacher 	atomic_inc(&device->ap_pending_cnt);
1926b411b363SPhilipp Reisner }
1927b411b363SPhilipp Reisner 
192849559d87SPhilipp Reisner #define ERR_IF_CNT_IS_NEGATIVE(which, func, line)			\
1929b30ab791SAndreas Gruenbacher 	if (atomic_read(&device->which) < 0)				\
1930d0180171SAndreas Gruenbacher 		drbd_err(device, "in %s:%d: " #which " = %d < 0 !\n",	\
193149559d87SPhilipp Reisner 			func, line,					\
1932b30ab791SAndreas Gruenbacher 			atomic_read(&device->which))
1933b411b363SPhilipp Reisner 
1934659b2e3bSJoe Perches #define dec_ap_pending(device) _dec_ap_pending(device, __func__, __LINE__)
1935b30ab791SAndreas Gruenbacher static inline void _dec_ap_pending(struct drbd_device *device, const char *func, int line)
193649559d87SPhilipp Reisner {
1937b30ab791SAndreas Gruenbacher 	if (atomic_dec_and_test(&device->ap_pending_cnt))
1938b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
193949559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt, func, line);
194049559d87SPhilipp Reisner }
1941b411b363SPhilipp Reisner 
1942b411b363SPhilipp Reisner /* counts how many resync-related answers we still expect from the peer
1943b411b363SPhilipp Reisner  *		     increase			decrease
1944b411b363SPhilipp Reisner  * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY)
194525985edcSLucas De Marchi  * C_SYNC_SOURCE sends P_RS_DATA_REPLY   (and expects P_WRITE_ACK with ID_SYNCER)
1946b411b363SPhilipp Reisner  *					   (or P_NEG_ACK with ID_SYNCER)
1947b411b363SPhilipp Reisner  */
1948b30ab791SAndreas Gruenbacher static inline void inc_rs_pending(struct drbd_device *device)
1949b411b363SPhilipp Reisner {
1950b30ab791SAndreas Gruenbacher 	atomic_inc(&device->rs_pending_cnt);
1951b411b363SPhilipp Reisner }
1952b411b363SPhilipp Reisner 
1953659b2e3bSJoe Perches #define dec_rs_pending(device) _dec_rs_pending(device, __func__, __LINE__)
1954b30ab791SAndreas Gruenbacher static inline void _dec_rs_pending(struct drbd_device *device, const char *func, int line)
195549559d87SPhilipp Reisner {
1956b30ab791SAndreas Gruenbacher 	atomic_dec(&device->rs_pending_cnt);
195749559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt, func, line);
195849559d87SPhilipp Reisner }
1959b411b363SPhilipp Reisner 
1960b411b363SPhilipp Reisner /* counts how many answers we still need to send to the peer.
1961b411b363SPhilipp Reisner  * increased on
1962b411b363SPhilipp Reisner  *  receive_Data	unless protocol A;
1963b411b363SPhilipp Reisner  *			we need to send a P_RECV_ACK (proto B)
1964b411b363SPhilipp Reisner  *			or P_WRITE_ACK (proto C)
1965b411b363SPhilipp Reisner  *  receive_RSDataReply (recv_resync_read) we need to send a P_WRITE_ACK
1966b411b363SPhilipp Reisner  *  receive_DataRequest (receive_RSDataRequest) we need to send back P_DATA
1967b411b363SPhilipp Reisner  *  receive_Barrier_*	we need to send a P_BARRIER_ACK
1968b411b363SPhilipp Reisner  */
1969b30ab791SAndreas Gruenbacher static inline void inc_unacked(struct drbd_device *device)
1970b411b363SPhilipp Reisner {
1971b30ab791SAndreas Gruenbacher 	atomic_inc(&device->unacked_cnt);
1972b411b363SPhilipp Reisner }
1973b411b363SPhilipp Reisner 
1974659b2e3bSJoe Perches #define dec_unacked(device) _dec_unacked(device, __func__, __LINE__)
1975b30ab791SAndreas Gruenbacher static inline void _dec_unacked(struct drbd_device *device, const char *func, int line)
1976b411b363SPhilipp Reisner {
1977b30ab791SAndreas Gruenbacher 	atomic_dec(&device->unacked_cnt);
197849559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
1979b411b363SPhilipp Reisner }
1980b411b363SPhilipp Reisner 
1981659b2e3bSJoe Perches #define sub_unacked(device, n) _sub_unacked(device, n, __func__, __LINE__)
1982b30ab791SAndreas Gruenbacher static inline void _sub_unacked(struct drbd_device *device, int n, const char *func, int line)
1983b411b363SPhilipp Reisner {
1984b30ab791SAndreas Gruenbacher 	atomic_sub(n, &device->unacked_cnt);
198549559d87SPhilipp Reisner 	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
1986b411b363SPhilipp Reisner }
1987b411b363SPhilipp Reisner 
19885ab7d2c0SLars Ellenberg static inline bool is_sync_state(enum drbd_conns connection_state)
19895ab7d2c0SLars Ellenberg {
19905ab7d2c0SLars Ellenberg 	return
19915ab7d2c0SLars Ellenberg 	   (connection_state == C_SYNC_SOURCE
19925ab7d2c0SLars Ellenberg 	||  connection_state == C_SYNC_TARGET
19935ab7d2c0SLars Ellenberg 	||  connection_state == C_PAUSED_SYNC_S
19945ab7d2c0SLars Ellenberg 	||  connection_state == C_PAUSED_SYNC_T);
19955ab7d2c0SLars Ellenberg }
19965ab7d2c0SLars Ellenberg 
1997b411b363SPhilipp Reisner /**
1998b30ab791SAndreas Gruenbacher  * get_ldev() - Increase the ref count on device->ldev. Returns 0 if there is no ldev
1999b411b363SPhilipp Reisner  * @M:		DRBD device.
2000b411b363SPhilipp Reisner  *
2001b30ab791SAndreas Gruenbacher  * You have to call put_ldev() when finished working with device->ldev.
2002b411b363SPhilipp Reisner  */
2003b411b363SPhilipp Reisner #define get_ldev(M) __cond_lock(local, _get_ldev_if_state(M,D_INCONSISTENT))
2004b411b363SPhilipp Reisner #define get_ldev_if_state(M,MINS) __cond_lock(local, _get_ldev_if_state(M,MINS))
2005b411b363SPhilipp Reisner 
2006b30ab791SAndreas Gruenbacher static inline void put_ldev(struct drbd_device *device)
2007b411b363SPhilipp Reisner {
2008ba3c6fb8SLars Ellenberg 	enum drbd_disk_state ds = device->state.disk;
2009ba3c6fb8SLars Ellenberg 	/* We must check the state *before* the atomic_dec becomes visible,
2010ba3c6fb8SLars Ellenberg 	 * or we have a theoretical race where someone hitting zero,
2011ba3c6fb8SLars Ellenberg 	 * while state still D_FAILED, will then see D_DISKLESS in the
2012ba3c6fb8SLars Ellenberg 	 * condition below and calling into destroy, where he must not, yet. */
2013b30ab791SAndreas Gruenbacher 	int i = atomic_dec_return(&device->local_cnt);
20149a0d9d03SLars Ellenberg 
20159a0d9d03SLars Ellenberg 	/* This may be called from some endio handler,
20169a0d9d03SLars Ellenberg 	 * so we must not sleep here. */
20179a0d9d03SLars Ellenberg 
2018b411b363SPhilipp Reisner 	__release(local);
20190b0ba1efSAndreas Gruenbacher 	D_ASSERT(device, i >= 0);
2020e9e6f3ecSLars Ellenberg 	if (i == 0) {
2021ba3c6fb8SLars Ellenberg 		if (ds == D_DISKLESS)
202282f59cc6SLars Ellenberg 			/* even internal references gone, safe to destroy */
2023e334f550SLars Ellenberg 			drbd_device_post_work(device, DESTROY_DISK);
2024e334f550SLars Ellenberg 		if (ds == D_FAILED)
202582f59cc6SLars Ellenberg 			/* all application IO references gone. */
2026e334f550SLars Ellenberg 			if (!test_and_set_bit(GOING_DISKLESS, &device->flags))
2027e334f550SLars Ellenberg 				drbd_device_post_work(device, GO_DISKLESS);
2028b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
2029b411b363SPhilipp Reisner 	}
2030e9e6f3ecSLars Ellenberg }
2031b411b363SPhilipp Reisner 
2032b411b363SPhilipp Reisner #ifndef __CHECKER__
2033b30ab791SAndreas Gruenbacher static inline int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins)
2034b411b363SPhilipp Reisner {
2035b411b363SPhilipp Reisner 	int io_allowed;
2036b411b363SPhilipp Reisner 
203782f59cc6SLars Ellenberg 	/* never get a reference while D_DISKLESS */
2038b30ab791SAndreas Gruenbacher 	if (device->state.disk == D_DISKLESS)
203982f59cc6SLars Ellenberg 		return 0;
204082f59cc6SLars Ellenberg 
2041b30ab791SAndreas Gruenbacher 	atomic_inc(&device->local_cnt);
2042b30ab791SAndreas Gruenbacher 	io_allowed = (device->state.disk >= mins);
2043b411b363SPhilipp Reisner 	if (!io_allowed)
2044b30ab791SAndreas Gruenbacher 		put_ldev(device);
2045b411b363SPhilipp Reisner 	return io_allowed;
2046b411b363SPhilipp Reisner }
2047b411b363SPhilipp Reisner #else
2048b30ab791SAndreas Gruenbacher extern int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins);
2049b411b363SPhilipp Reisner #endif
2050b411b363SPhilipp Reisner 
2051b411b363SPhilipp Reisner /* this throttles on-the-fly application requests
2052b411b363SPhilipp Reisner  * according to max_buffers settings;
2053b411b363SPhilipp Reisner  * maybe re-implement using semaphores? */
2054b30ab791SAndreas Gruenbacher static inline int drbd_get_max_buffers(struct drbd_device *device)
2055b411b363SPhilipp Reisner {
205644ed167dSPhilipp Reisner 	struct net_conf *nc;
205744ed167dSPhilipp Reisner 	int mxb;
205844ed167dSPhilipp Reisner 
205944ed167dSPhilipp Reisner 	rcu_read_lock();
2060a6b32bc3SAndreas Gruenbacher 	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
206144ed167dSPhilipp Reisner 	mxb = nc ? nc->max_buffers : 1000000;  /* arbitrary limit on open requests */
206244ed167dSPhilipp Reisner 	rcu_read_unlock();
206344ed167dSPhilipp Reisner 
2064b411b363SPhilipp Reisner 	return mxb;
2065b411b363SPhilipp Reisner }
2066b411b363SPhilipp Reisner 
2067b30ab791SAndreas Gruenbacher static inline int drbd_state_is_stable(struct drbd_device *device)
2068b411b363SPhilipp Reisner {
2069b30ab791SAndreas Gruenbacher 	union drbd_dev_state s = device->state;
2070b411b363SPhilipp Reisner 
2071b411b363SPhilipp Reisner 	/* DO NOT add a default clause, we want the compiler to warn us
2072b411b363SPhilipp Reisner 	 * for any newly introduced state we may have forgotten to add here */
2073b411b363SPhilipp Reisner 
2074b411b363SPhilipp Reisner 	switch ((enum drbd_conns)s.conn) {
2075b411b363SPhilipp Reisner 	/* new io only accepted when there is no connection, ... */
2076b411b363SPhilipp Reisner 	case C_STANDALONE:
2077b411b363SPhilipp Reisner 	case C_WF_CONNECTION:
2078b411b363SPhilipp Reisner 	/* ... or there is a well established connection. */
2079b411b363SPhilipp Reisner 	case C_CONNECTED:
2080b411b363SPhilipp Reisner 	case C_SYNC_SOURCE:
2081b411b363SPhilipp Reisner 	case C_SYNC_TARGET:
2082b411b363SPhilipp Reisner 	case C_VERIFY_S:
2083b411b363SPhilipp Reisner 	case C_VERIFY_T:
2084b411b363SPhilipp Reisner 	case C_PAUSED_SYNC_S:
2085b411b363SPhilipp Reisner 	case C_PAUSED_SYNC_T:
208667531718SPhilipp Reisner 	case C_AHEAD:
208767531718SPhilipp Reisner 	case C_BEHIND:
20883719094eSPhilipp Reisner 		/* transitional states, IO allowed */
2089b411b363SPhilipp Reisner 	case C_DISCONNECTING:
2090b411b363SPhilipp Reisner 	case C_UNCONNECTED:
2091b411b363SPhilipp Reisner 	case C_TIMEOUT:
2092b411b363SPhilipp Reisner 	case C_BROKEN_PIPE:
2093b411b363SPhilipp Reisner 	case C_NETWORK_FAILURE:
2094b411b363SPhilipp Reisner 	case C_PROTOCOL_ERROR:
2095b411b363SPhilipp Reisner 	case C_TEAR_DOWN:
2096b411b363SPhilipp Reisner 	case C_WF_REPORT_PARAMS:
2097b411b363SPhilipp Reisner 	case C_STARTING_SYNC_S:
2098b411b363SPhilipp Reisner 	case C_STARTING_SYNC_T:
20993719094eSPhilipp Reisner 		break;
21003719094eSPhilipp Reisner 
21013719094eSPhilipp Reisner 		/* Allow IO in BM exchange states with new protocols */
2102b411b363SPhilipp Reisner 	case C_WF_BITMAP_S:
2103a6b32bc3SAndreas Gruenbacher 		if (first_peer_device(device)->connection->agreed_pro_version < 96)
21043719094eSPhilipp Reisner 			return 0;
21053719094eSPhilipp Reisner 		break;
21063719094eSPhilipp Reisner 
21073719094eSPhilipp Reisner 		/* no new io accepted in these states */
2108b411b363SPhilipp Reisner 	case C_WF_BITMAP_T:
2109b411b363SPhilipp Reisner 	case C_WF_SYNC_UUID:
2110b411b363SPhilipp Reisner 	case C_MASK:
2111b411b363SPhilipp Reisner 		/* not "stable" */
2112b411b363SPhilipp Reisner 		return 0;
2113b411b363SPhilipp Reisner 	}
2114b411b363SPhilipp Reisner 
2115b411b363SPhilipp Reisner 	switch ((enum drbd_disk_state)s.disk) {
2116b411b363SPhilipp Reisner 	case D_DISKLESS:
2117b411b363SPhilipp Reisner 	case D_INCONSISTENT:
2118b411b363SPhilipp Reisner 	case D_OUTDATED:
2119b411b363SPhilipp Reisner 	case D_CONSISTENT:
2120b411b363SPhilipp Reisner 	case D_UP_TO_DATE:
21215ca1de03SPhilipp Reisner 	case D_FAILED:
2122b411b363SPhilipp Reisner 		/* disk state is stable as well. */
2123b411b363SPhilipp Reisner 		break;
2124b411b363SPhilipp Reisner 
2125d942ae44SPhilipp Reisner 	/* no new io accepted during transitional states */
2126b411b363SPhilipp Reisner 	case D_ATTACHING:
2127b411b363SPhilipp Reisner 	case D_NEGOTIATING:
2128b411b363SPhilipp Reisner 	case D_UNKNOWN:
2129b411b363SPhilipp Reisner 	case D_MASK:
2130b411b363SPhilipp Reisner 		/* not "stable" */
2131b411b363SPhilipp Reisner 		return 0;
2132b411b363SPhilipp Reisner 	}
2133b411b363SPhilipp Reisner 
2134b411b363SPhilipp Reisner 	return 1;
2135b411b363SPhilipp Reisner }
2136b411b363SPhilipp Reisner 
2137b30ab791SAndreas Gruenbacher static inline int drbd_suspended(struct drbd_device *device)
2138fb22c402SPhilipp Reisner {
21396bbf53caSAndreas Gruenbacher 	struct drbd_resource *resource = device->resource;
21408e0af25fSPhilipp Reisner 
21416bbf53caSAndreas Gruenbacher 	return resource->susp || resource->susp_fen || resource->susp_nod;
2142fb22c402SPhilipp Reisner }
2143fb22c402SPhilipp Reisner 
2144b30ab791SAndreas Gruenbacher static inline bool may_inc_ap_bio(struct drbd_device *device)
2145b411b363SPhilipp Reisner {
2146b30ab791SAndreas Gruenbacher 	int mxb = drbd_get_max_buffers(device);
2147b411b363SPhilipp Reisner 
2148b30ab791SAndreas Gruenbacher 	if (drbd_suspended(device))
21491b881ef7SAndreas Gruenbacher 		return false;
2150b30ab791SAndreas Gruenbacher 	if (test_bit(SUSPEND_IO, &device->flags))
21511b881ef7SAndreas Gruenbacher 		return false;
2152b411b363SPhilipp Reisner 
2153b411b363SPhilipp Reisner 	/* to avoid potential deadlock or bitmap corruption,
2154b411b363SPhilipp Reisner 	 * in various places, we only allow new application io
2155b411b363SPhilipp Reisner 	 * to start during "stable" states. */
2156b411b363SPhilipp Reisner 
2157b411b363SPhilipp Reisner 	/* no new io accepted when attaching or detaching the disk */
2158b30ab791SAndreas Gruenbacher 	if (!drbd_state_is_stable(device))
21591b881ef7SAndreas Gruenbacher 		return false;
2160b411b363SPhilipp Reisner 
2161b411b363SPhilipp Reisner 	/* since some older kernels don't have atomic_add_unless,
2162b411b363SPhilipp Reisner 	 * and we are within the spinlock anyways, we have this workaround.  */
2163b30ab791SAndreas Gruenbacher 	if (atomic_read(&device->ap_bio_cnt) > mxb)
21641b881ef7SAndreas Gruenbacher 		return false;
2165b30ab791SAndreas Gruenbacher 	if (test_bit(BITMAP_IO, &device->flags))
21661b881ef7SAndreas Gruenbacher 		return false;
21671b881ef7SAndreas Gruenbacher 	return true;
2168b411b363SPhilipp Reisner }
2169b411b363SPhilipp Reisner 
2170b30ab791SAndreas Gruenbacher static inline bool inc_ap_bio_cond(struct drbd_device *device)
21718869d683SPhilipp Reisner {
21721b881ef7SAndreas Gruenbacher 	bool rv = false;
21738869d683SPhilipp Reisner 
21740500813fSAndreas Gruenbacher 	spin_lock_irq(&device->resource->req_lock);
2175b30ab791SAndreas Gruenbacher 	rv = may_inc_ap_bio(device);
21768869d683SPhilipp Reisner 	if (rv)
2177b30ab791SAndreas Gruenbacher 		atomic_inc(&device->ap_bio_cnt);
21780500813fSAndreas Gruenbacher 	spin_unlock_irq(&device->resource->req_lock);
21798869d683SPhilipp Reisner 
21808869d683SPhilipp Reisner 	return rv;
21818869d683SPhilipp Reisner }
21828869d683SPhilipp Reisner 
2183b30ab791SAndreas Gruenbacher static inline void inc_ap_bio(struct drbd_device *device)
2184b411b363SPhilipp Reisner {
2185b411b363SPhilipp Reisner 	/* we wait here
2186b411b363SPhilipp Reisner 	 *    as long as the device is suspended
2187b411b363SPhilipp Reisner 	 *    until the bitmap is no longer on the fly during connection
2188d942ae44SPhilipp Reisner 	 *    handshake as long as we would exceed the max_buffer limit.
2189b411b363SPhilipp Reisner 	 *
2190b411b363SPhilipp Reisner 	 * to avoid races with the reconnect code,
2191b411b363SPhilipp Reisner 	 * we need to atomic_inc within the spinlock. */
2192b411b363SPhilipp Reisner 
2193b30ab791SAndreas Gruenbacher 	wait_event(device->misc_wait, inc_ap_bio_cond(device));
2194b411b363SPhilipp Reisner }
2195b411b363SPhilipp Reisner 
2196b30ab791SAndreas Gruenbacher static inline void dec_ap_bio(struct drbd_device *device)
2197b411b363SPhilipp Reisner {
2198b30ab791SAndreas Gruenbacher 	int mxb = drbd_get_max_buffers(device);
2199b30ab791SAndreas Gruenbacher 	int ap_bio = atomic_dec_return(&device->ap_bio_cnt);
2200b411b363SPhilipp Reisner 
22010b0ba1efSAndreas Gruenbacher 	D_ASSERT(device, ap_bio >= 0);
22027ee1fb93SLars Ellenberg 
2203b30ab791SAndreas Gruenbacher 	if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) {
2204b30ab791SAndreas Gruenbacher 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
220584b8c06bSAndreas Gruenbacher 			drbd_queue_work(&first_peer_device(device)->
220684b8c06bSAndreas Gruenbacher 				connection->sender_work,
220784b8c06bSAndreas Gruenbacher 				&device->bm_io_work.w);
22087ee1fb93SLars Ellenberg 	}
22097ee1fb93SLars Ellenberg 
2210b411b363SPhilipp Reisner 	/* this currently does wake_up for every dec_ap_bio!
2211b411b363SPhilipp Reisner 	 * maybe rather introduce some type of hysteresis?
2212b411b363SPhilipp Reisner 	 * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */
2213b411b363SPhilipp Reisner 	if (ap_bio < mxb)
2214b30ab791SAndreas Gruenbacher 		wake_up(&device->misc_wait);
2215b411b363SPhilipp Reisner }
2216b411b363SPhilipp Reisner 
2217b30ab791SAndreas Gruenbacher static inline bool verify_can_do_stop_sector(struct drbd_device *device)
221858ffa580SLars Ellenberg {
2219a6b32bc3SAndreas Gruenbacher 	return first_peer_device(device)->connection->agreed_pro_version >= 97 &&
2220a6b32bc3SAndreas Gruenbacher 		first_peer_device(device)->connection->agreed_pro_version != 100;
222158ffa580SLars Ellenberg }
222258ffa580SLars Ellenberg 
2223b30ab791SAndreas Gruenbacher static inline int drbd_set_ed_uuid(struct drbd_device *device, u64 val)
2224b411b363SPhilipp Reisner {
2225b30ab791SAndreas Gruenbacher 	int changed = device->ed_uuid != val;
2226b30ab791SAndreas Gruenbacher 	device->ed_uuid = val;
222762b0da3aSLars Ellenberg 	return changed;
2228b411b363SPhilipp Reisner }
2229b411b363SPhilipp Reisner 
2230b30ab791SAndreas Gruenbacher static inline int drbd_queue_order_type(struct drbd_device *device)
2231b411b363SPhilipp Reisner {
2232b411b363SPhilipp Reisner 	/* sorry, we currently have no working implementation
2233b411b363SPhilipp Reisner 	 * of distributed TCQ stuff */
2234b411b363SPhilipp Reisner #ifndef QUEUE_ORDERED_NONE
2235b411b363SPhilipp Reisner #define QUEUE_ORDERED_NONE 0
2236b411b363SPhilipp Reisner #endif
2237b411b363SPhilipp Reisner 	return QUEUE_ORDERED_NONE;
2238b411b363SPhilipp Reisner }
2239b411b363SPhilipp Reisner 
224077c556f6SAndreas Gruenbacher static inline struct drbd_connection *first_connection(struct drbd_resource *resource)
224177c556f6SAndreas Gruenbacher {
2242ec4a3407SLars Ellenberg 	return list_first_entry_or_null(&resource->connections,
224377c556f6SAndreas Gruenbacher 				struct drbd_connection, connections);
224477c556f6SAndreas Gruenbacher }
224577c556f6SAndreas Gruenbacher 
2246b411b363SPhilipp Reisner #endif
2247