18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci  drbd_int.h
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci  This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci  Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
88c2ecf20Sopenharmony_ci  Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
98c2ecf20Sopenharmony_ci  Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci*/
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef _DRBD_INT_H
158c2ecf20Sopenharmony_ci#define _DRBD_INT_H
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <crypto/hash.h>
188c2ecf20Sopenharmony_ci#include <linux/compiler.h>
198c2ecf20Sopenharmony_ci#include <linux/types.h>
208c2ecf20Sopenharmony_ci#include <linux/list.h>
218c2ecf20Sopenharmony_ci#include <linux/sched/signal.h>
228c2ecf20Sopenharmony_ci#include <linux/bitops.h>
238c2ecf20Sopenharmony_ci#include <linux/slab.h>
248c2ecf20Sopenharmony_ci#include <linux/ratelimit.h>
258c2ecf20Sopenharmony_ci#include <linux/tcp.h>
268c2ecf20Sopenharmony_ci#include <linux/mutex.h>
278c2ecf20Sopenharmony_ci#include <linux/major.h>
288c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
298c2ecf20Sopenharmony_ci#include <linux/backing-dev.h>
308c2ecf20Sopenharmony_ci#include <linux/genhd.h>
318c2ecf20Sopenharmony_ci#include <linux/idr.h>
328c2ecf20Sopenharmony_ci#include <linux/dynamic_debug.h>
338c2ecf20Sopenharmony_ci#include <net/tcp.h>
348c2ecf20Sopenharmony_ci#include <linux/lru_cache.h>
358c2ecf20Sopenharmony_ci#include <linux/prefetch.h>
368c2ecf20Sopenharmony_ci#include <linux/drbd_genl_api.h>
378c2ecf20Sopenharmony_ci#include <linux/drbd.h>
388c2ecf20Sopenharmony_ci#include "drbd_strings.h"
398c2ecf20Sopenharmony_ci#include "drbd_state.h"
408c2ecf20Sopenharmony_ci#include "drbd_protocol.h"
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#ifdef __CHECKER__
438c2ecf20Sopenharmony_ci# define __protected_by(x)       __attribute__((require_context(x,1,999,"rdwr")))
448c2ecf20Sopenharmony_ci# define __protected_read_by(x)  __attribute__((require_context(x,1,999,"read")))
458c2ecf20Sopenharmony_ci# define __protected_write_by(x) __attribute__((require_context(x,1,999,"write")))
468c2ecf20Sopenharmony_ci#else
478c2ecf20Sopenharmony_ci# define __protected_by(x)
488c2ecf20Sopenharmony_ci# define __protected_read_by(x)
498c2ecf20Sopenharmony_ci# define __protected_write_by(x)
508c2ecf20Sopenharmony_ci#endif
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/* shared module parameters, defined in drbd_main.c */
538c2ecf20Sopenharmony_ci#ifdef CONFIG_DRBD_FAULT_INJECTION
548c2ecf20Sopenharmony_ciextern int drbd_enable_faults;
558c2ecf20Sopenharmony_ciextern int drbd_fault_rate;
568c2ecf20Sopenharmony_ci#endif
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciextern unsigned int drbd_minor_count;
598c2ecf20Sopenharmony_ciextern char drbd_usermode_helper[];
608c2ecf20Sopenharmony_ciextern int drbd_proc_details;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/* This is used to stop/restart our threads.
648c2ecf20Sopenharmony_ci * Cannot use SIGTERM nor SIGKILL, since these
658c2ecf20Sopenharmony_ci * are sent out by init on runlevel changes
668c2ecf20Sopenharmony_ci * I choose SIGHUP for now.
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_ci#define DRBD_SIGKILL SIGHUP
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define ID_IN_SYNC      (4711ULL)
718c2ecf20Sopenharmony_ci#define ID_OUT_OF_SYNC  (4712ULL)
728c2ecf20Sopenharmony_ci#define ID_SYNCER (-1ULL)
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL)
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistruct drbd_device;
778c2ecf20Sopenharmony_cistruct drbd_connection;
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci#define __drbd_printk_device(level, device, fmt, args...) \
808c2ecf20Sopenharmony_ci	dev_printk(level, disk_to_dev((device)->vdisk), fmt, ## args)
818c2ecf20Sopenharmony_ci#define __drbd_printk_peer_device(level, peer_device, fmt, args...) \
828c2ecf20Sopenharmony_ci	dev_printk(level, disk_to_dev((peer_device)->device->vdisk), fmt, ## args)
838c2ecf20Sopenharmony_ci#define __drbd_printk_resource(level, resource, fmt, args...) \
848c2ecf20Sopenharmony_ci	printk(level "drbd %s: " fmt, (resource)->name, ## args)
858c2ecf20Sopenharmony_ci#define __drbd_printk_connection(level, connection, fmt, args...) \
868c2ecf20Sopenharmony_ci	printk(level "drbd %s: " fmt, (connection)->resource->name, ## args)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_civoid drbd_printk_with_wrong_object_type(void);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#define __drbd_printk_if_same_type(obj, type, func, level, fmt, args...) \
918c2ecf20Sopenharmony_ci	(__builtin_types_compatible_p(typeof(obj), type) || \
928c2ecf20Sopenharmony_ci	 __builtin_types_compatible_p(typeof(obj), const type)), \
938c2ecf20Sopenharmony_ci	func(level, (const type)(obj), fmt, ## args)
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci#define drbd_printk(level, obj, fmt, args...) \
968c2ecf20Sopenharmony_ci	__builtin_choose_expr( \
978c2ecf20Sopenharmony_ci	  __drbd_printk_if_same_type(obj, struct drbd_device *, \
988c2ecf20Sopenharmony_ci			     __drbd_printk_device, level, fmt, ## args), \
998c2ecf20Sopenharmony_ci	  __builtin_choose_expr( \
1008c2ecf20Sopenharmony_ci	    __drbd_printk_if_same_type(obj, struct drbd_resource *, \
1018c2ecf20Sopenharmony_ci			       __drbd_printk_resource, level, fmt, ## args), \
1028c2ecf20Sopenharmony_ci	    __builtin_choose_expr( \
1038c2ecf20Sopenharmony_ci	      __drbd_printk_if_same_type(obj, struct drbd_connection *, \
1048c2ecf20Sopenharmony_ci				 __drbd_printk_connection, level, fmt, ## args), \
1058c2ecf20Sopenharmony_ci	      __builtin_choose_expr( \
1068c2ecf20Sopenharmony_ci		__drbd_printk_if_same_type(obj, struct drbd_peer_device *, \
1078c2ecf20Sopenharmony_ci				 __drbd_printk_peer_device, level, fmt, ## args), \
1088c2ecf20Sopenharmony_ci		drbd_printk_with_wrong_object_type()))))
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci#define drbd_dbg(obj, fmt, args...) \
1118c2ecf20Sopenharmony_ci	drbd_printk(KERN_DEBUG, obj, fmt, ## args)
1128c2ecf20Sopenharmony_ci#define drbd_alert(obj, fmt, args...) \
1138c2ecf20Sopenharmony_ci	drbd_printk(KERN_ALERT, obj, fmt, ## args)
1148c2ecf20Sopenharmony_ci#define drbd_err(obj, fmt, args...) \
1158c2ecf20Sopenharmony_ci	drbd_printk(KERN_ERR, obj, fmt, ## args)
1168c2ecf20Sopenharmony_ci#define drbd_warn(obj, fmt, args...) \
1178c2ecf20Sopenharmony_ci	drbd_printk(KERN_WARNING, obj, fmt, ## args)
1188c2ecf20Sopenharmony_ci#define drbd_info(obj, fmt, args...) \
1198c2ecf20Sopenharmony_ci	drbd_printk(KERN_INFO, obj, fmt, ## args)
1208c2ecf20Sopenharmony_ci#define drbd_emerg(obj, fmt, args...) \
1218c2ecf20Sopenharmony_ci	drbd_printk(KERN_EMERG, obj, fmt, ## args)
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci#define dynamic_drbd_dbg(device, fmt, args...) \
1248c2ecf20Sopenharmony_ci	dynamic_dev_dbg(disk_to_dev(device->vdisk), fmt, ## args)
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci#define D_ASSERT(device, exp)	do { \
1278c2ecf20Sopenharmony_ci	if (!(exp)) \
1288c2ecf20Sopenharmony_ci		drbd_err(device, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__); \
1298c2ecf20Sopenharmony_ci	} while (0)
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/**
1328c2ecf20Sopenharmony_ci * expect  -  Make an assertion
1338c2ecf20Sopenharmony_ci *
1348c2ecf20Sopenharmony_ci * Unlike the assert macro, this macro returns a boolean result.
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_ci#define expect(exp) ({								\
1378c2ecf20Sopenharmony_ci		bool _bool = (exp);						\
1388c2ecf20Sopenharmony_ci		if (!_bool)							\
1398c2ecf20Sopenharmony_ci			drbd_err(device, "ASSERTION %s FAILED in %s\n",		\
1408c2ecf20Sopenharmony_ci			        #exp, __func__);				\
1418c2ecf20Sopenharmony_ci		_bool;								\
1428c2ecf20Sopenharmony_ci		})
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci/* Defines to control fault insertion */
1458c2ecf20Sopenharmony_cienum {
1468c2ecf20Sopenharmony_ci	DRBD_FAULT_MD_WR = 0,	/* meta data write */
1478c2ecf20Sopenharmony_ci	DRBD_FAULT_MD_RD = 1,	/*           read  */
1488c2ecf20Sopenharmony_ci	DRBD_FAULT_RS_WR = 2,	/* resync          */
1498c2ecf20Sopenharmony_ci	DRBD_FAULT_RS_RD = 3,
1508c2ecf20Sopenharmony_ci	DRBD_FAULT_DT_WR = 4,	/* data            */
1518c2ecf20Sopenharmony_ci	DRBD_FAULT_DT_RD = 5,
1528c2ecf20Sopenharmony_ci	DRBD_FAULT_DT_RA = 6,	/* data read ahead */
1538c2ecf20Sopenharmony_ci	DRBD_FAULT_BM_ALLOC = 7,	/* bitmap allocation */
1548c2ecf20Sopenharmony_ci	DRBD_FAULT_AL_EE = 8,	/* alloc ee */
1558c2ecf20Sopenharmony_ci	DRBD_FAULT_RECEIVE = 9, /* Changes some bytes upon receiving a [rs]data block */
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	DRBD_FAULT_MAX,
1588c2ecf20Sopenharmony_ci};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ciextern unsigned int
1618c2ecf20Sopenharmony_ci_drbd_insert_fault(struct drbd_device *device, unsigned int type);
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic inline int
1648c2ecf20Sopenharmony_cidrbd_insert_fault(struct drbd_device *device, unsigned int type) {
1658c2ecf20Sopenharmony_ci#ifdef CONFIG_DRBD_FAULT_INJECTION
1668c2ecf20Sopenharmony_ci	return drbd_fault_rate &&
1678c2ecf20Sopenharmony_ci		(drbd_enable_faults & (1<<type)) &&
1688c2ecf20Sopenharmony_ci		_drbd_insert_fault(device, type);
1698c2ecf20Sopenharmony_ci#else
1708c2ecf20Sopenharmony_ci	return 0;
1718c2ecf20Sopenharmony_ci#endif
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/* integer division, round _UP_ to the next integer */
1758c2ecf20Sopenharmony_ci#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
1768c2ecf20Sopenharmony_ci/* usual integer division */
1778c2ecf20Sopenharmony_ci#define div_floor(A, B) ((A)/(B))
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ciextern struct ratelimit_state drbd_ratelimit_state;
1808c2ecf20Sopenharmony_ciextern struct idr drbd_devices; /* RCU, updates: genl_lock() */
1818c2ecf20Sopenharmony_ciextern struct list_head drbd_resources; /* RCU, updates: genl_lock() */
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ciextern const char *cmdname(enum drbd_packet cmd);
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci/* for sending/receiving the bitmap,
1868c2ecf20Sopenharmony_ci * possibly in some encoding scheme */
1878c2ecf20Sopenharmony_cistruct bm_xfer_ctx {
1888c2ecf20Sopenharmony_ci	/* "const"
1898c2ecf20Sopenharmony_ci	 * stores total bits and long words
1908c2ecf20Sopenharmony_ci	 * of the bitmap, so we don't need to
1918c2ecf20Sopenharmony_ci	 * call the accessor functions over and again. */
1928c2ecf20Sopenharmony_ci	unsigned long bm_bits;
1938c2ecf20Sopenharmony_ci	unsigned long bm_words;
1948c2ecf20Sopenharmony_ci	/* during xfer, current position within the bitmap */
1958c2ecf20Sopenharmony_ci	unsigned long bit_offset;
1968c2ecf20Sopenharmony_ci	unsigned long word_offset;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	/* statistics; index: (h->command == P_BITMAP) */
1998c2ecf20Sopenharmony_ci	unsigned packets[2];
2008c2ecf20Sopenharmony_ci	unsigned bytes[2];
2018c2ecf20Sopenharmony_ci};
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ciextern void INFO_bm_xfer_stats(struct drbd_device *device,
2048c2ecf20Sopenharmony_ci		const char *direction, struct bm_xfer_ctx *c);
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic inline void bm_xfer_ctx_bit_to_word_offset(struct bm_xfer_ctx *c)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	/* word_offset counts "native long words" (32 or 64 bit),
2098c2ecf20Sopenharmony_ci	 * aligned at 64 bit.
2108c2ecf20Sopenharmony_ci	 * Encoded packet may end at an unaligned bit offset.
2118c2ecf20Sopenharmony_ci	 * In case a fallback clear text packet is transmitted in
2128c2ecf20Sopenharmony_ci	 * between, we adjust this offset back to the last 64bit
2138c2ecf20Sopenharmony_ci	 * aligned "native long word", which makes coding and decoding
2148c2ecf20Sopenharmony_ci	 * the plain text bitmap much more convenient.  */
2158c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 64
2168c2ecf20Sopenharmony_ci	c->word_offset = c->bit_offset >> 6;
2178c2ecf20Sopenharmony_ci#elif BITS_PER_LONG == 32
2188c2ecf20Sopenharmony_ci	c->word_offset = c->bit_offset >> 5;
2198c2ecf20Sopenharmony_ci	c->word_offset &= ~(1UL);
2208c2ecf20Sopenharmony_ci#else
2218c2ecf20Sopenharmony_ci# error "unsupported BITS_PER_LONG"
2228c2ecf20Sopenharmony_ci#endif
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ciextern unsigned int drbd_header_size(struct drbd_connection *connection);
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci/**********************************************************************/
2288c2ecf20Sopenharmony_cienum drbd_thread_state {
2298c2ecf20Sopenharmony_ci	NONE,
2308c2ecf20Sopenharmony_ci	RUNNING,
2318c2ecf20Sopenharmony_ci	EXITING,
2328c2ecf20Sopenharmony_ci	RESTARTING
2338c2ecf20Sopenharmony_ci};
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_cistruct drbd_thread {
2368c2ecf20Sopenharmony_ci	spinlock_t t_lock;
2378c2ecf20Sopenharmony_ci	struct task_struct *task;
2388c2ecf20Sopenharmony_ci	struct completion stop;
2398c2ecf20Sopenharmony_ci	enum drbd_thread_state t_state;
2408c2ecf20Sopenharmony_ci	int (*function) (struct drbd_thread *);
2418c2ecf20Sopenharmony_ci	struct drbd_resource *resource;
2428c2ecf20Sopenharmony_ci	struct drbd_connection *connection;
2438c2ecf20Sopenharmony_ci	int reset_cpu_mask;
2448c2ecf20Sopenharmony_ci	const char *name;
2458c2ecf20Sopenharmony_ci};
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_cistatic inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	/* THINK testing the t_state seems to be uncritical in all cases
2508c2ecf20Sopenharmony_ci	 * (but thread_{start,stop}), so we can read it *without* the lock.
2518c2ecf20Sopenharmony_ci	 *	--lge */
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	smp_rmb();
2548c2ecf20Sopenharmony_ci	return thi->t_state;
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistruct drbd_work {
2588c2ecf20Sopenharmony_ci	struct list_head list;
2598c2ecf20Sopenharmony_ci	int (*cb)(struct drbd_work *, int cancel);
2608c2ecf20Sopenharmony_ci};
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistruct drbd_device_work {
2638c2ecf20Sopenharmony_ci	struct drbd_work w;
2648c2ecf20Sopenharmony_ci	struct drbd_device *device;
2658c2ecf20Sopenharmony_ci};
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci#include "drbd_interval.h"
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ciextern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *);
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ciextern void lock_all_resources(void);
2728c2ecf20Sopenharmony_ciextern void unlock_all_resources(void);
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_cistruct drbd_request {
2758c2ecf20Sopenharmony_ci	struct drbd_work w;
2768c2ecf20Sopenharmony_ci	struct drbd_device *device;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	/* if local IO is not allowed, will be NULL.
2798c2ecf20Sopenharmony_ci	 * if local IO _is_ allowed, holds the locally submitted bio clone,
2808c2ecf20Sopenharmony_ci	 * or, after local IO completion, the ERR_PTR(error).
2818c2ecf20Sopenharmony_ci	 * see drbd_request_endio(). */
2828c2ecf20Sopenharmony_ci	struct bio *private_bio;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	struct drbd_interval i;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	/* epoch: used to check on "completion" whether this req was in
2878c2ecf20Sopenharmony_ci	 * the current epoch, and we therefore have to close it,
2888c2ecf20Sopenharmony_ci	 * causing a p_barrier packet to be send, starting a new epoch.
2898c2ecf20Sopenharmony_ci	 *
2908c2ecf20Sopenharmony_ci	 * This corresponds to "barrier" in struct p_barrier[_ack],
2918c2ecf20Sopenharmony_ci	 * and to "barrier_nr" in struct drbd_epoch (and various
2928c2ecf20Sopenharmony_ci	 * comments/function parameters/local variable names).
2938c2ecf20Sopenharmony_ci	 */
2948c2ecf20Sopenharmony_ci	unsigned int epoch;
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	struct list_head tl_requests; /* ring list in the transfer log */
2978c2ecf20Sopenharmony_ci	struct bio *master_bio;       /* master bio pointer */
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	/* see struct drbd_device */
3008c2ecf20Sopenharmony_ci	struct list_head req_pending_master_completion;
3018c2ecf20Sopenharmony_ci	struct list_head req_pending_local;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	/* for generic IO accounting */
3048c2ecf20Sopenharmony_ci	unsigned long start_jif;
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	/* for DRBD internal statistics */
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	/* Minimal set of time stamps to determine if we wait for activity log
3098c2ecf20Sopenharmony_ci	 * transactions, local disk or peer.  32 bit "jiffies" are good enough,
3108c2ecf20Sopenharmony_ci	 * we don't expect a DRBD request to be stalled for several month.
3118c2ecf20Sopenharmony_ci	 */
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	/* before actual request processing */
3148c2ecf20Sopenharmony_ci	unsigned long in_actlog_jif;
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	/* local disk */
3178c2ecf20Sopenharmony_ci	unsigned long pre_submit_jif;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	/* per connection */
3208c2ecf20Sopenharmony_ci	unsigned long pre_send_jif;
3218c2ecf20Sopenharmony_ci	unsigned long acked_jif;
3228c2ecf20Sopenharmony_ci	unsigned long net_done_jif;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	/* Possibly even more detail to track each phase:
3258c2ecf20Sopenharmony_ci	 *  master_completion_jif
3268c2ecf20Sopenharmony_ci	 *      how long did it take to complete the master bio
3278c2ecf20Sopenharmony_ci	 *      (application visible latency)
3288c2ecf20Sopenharmony_ci	 *  allocated_jif
3298c2ecf20Sopenharmony_ci	 *      how long the master bio was blocked until we finally allocated
3308c2ecf20Sopenharmony_ci	 *      a tracking struct
3318c2ecf20Sopenharmony_ci	 *  in_actlog_jif
3328c2ecf20Sopenharmony_ci	 *      how long did we wait for activity log transactions
3338c2ecf20Sopenharmony_ci	 *
3348c2ecf20Sopenharmony_ci	 *  net_queued_jif
3358c2ecf20Sopenharmony_ci	 *      when did we finally queue it for sending
3368c2ecf20Sopenharmony_ci	 *  pre_send_jif
3378c2ecf20Sopenharmony_ci	 *      when did we start sending it
3388c2ecf20Sopenharmony_ci	 *  post_send_jif
3398c2ecf20Sopenharmony_ci	 *      how long did we block in the network stack trying to send it
3408c2ecf20Sopenharmony_ci	 *  acked_jif
3418c2ecf20Sopenharmony_ci	 *      when did we receive (or fake, in protocol A) a remote ACK
3428c2ecf20Sopenharmony_ci	 *  net_done_jif
3438c2ecf20Sopenharmony_ci	 *      when did we receive final acknowledgement (P_BARRIER_ACK),
3448c2ecf20Sopenharmony_ci	 *      or decide, e.g. on connection loss, that we do no longer expect
3458c2ecf20Sopenharmony_ci	 *      anything from this peer for this request.
3468c2ecf20Sopenharmony_ci	 *
3478c2ecf20Sopenharmony_ci	 *  pre_submit_jif
3488c2ecf20Sopenharmony_ci	 *  post_sub_jif
3498c2ecf20Sopenharmony_ci	 *      when did we start submiting to the lower level device,
3508c2ecf20Sopenharmony_ci	 *      and how long did we block in that submit function
3518c2ecf20Sopenharmony_ci	 *  local_completion_jif
3528c2ecf20Sopenharmony_ci	 *      how long did it take the lower level device to complete this request
3538c2ecf20Sopenharmony_ci	 */
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	/* once it hits 0, we may complete the master_bio */
3578c2ecf20Sopenharmony_ci	atomic_t completion_ref;
3588c2ecf20Sopenharmony_ci	/* once it hits 0, we may destroy this drbd_request object */
3598c2ecf20Sopenharmony_ci	struct kref kref;
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	unsigned rq_state; /* see comments above _req_mod() */
3628c2ecf20Sopenharmony_ci};
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_cistruct drbd_epoch {
3658c2ecf20Sopenharmony_ci	struct drbd_connection *connection;
3668c2ecf20Sopenharmony_ci	struct list_head list;
3678c2ecf20Sopenharmony_ci	unsigned int barrier_nr;
3688c2ecf20Sopenharmony_ci	atomic_t epoch_size; /* increased on every request added. */
3698c2ecf20Sopenharmony_ci	atomic_t active;     /* increased on every req. added, and dec on every finished. */
3708c2ecf20Sopenharmony_ci	unsigned long flags;
3718c2ecf20Sopenharmony_ci};
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci/* Prototype declaration of function defined in drbd_receiver.c */
3748c2ecf20Sopenharmony_ciint drbdd_init(struct drbd_thread *);
3758c2ecf20Sopenharmony_ciint drbd_asender(struct drbd_thread *);
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci/* drbd_epoch flag bits */
3788c2ecf20Sopenharmony_cienum {
3798c2ecf20Sopenharmony_ci	DE_HAVE_BARRIER_NUMBER,
3808c2ecf20Sopenharmony_ci};
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_cienum epoch_event {
3838c2ecf20Sopenharmony_ci	EV_PUT,
3848c2ecf20Sopenharmony_ci	EV_GOT_BARRIER_NR,
3858c2ecf20Sopenharmony_ci	EV_BECAME_LAST,
3868c2ecf20Sopenharmony_ci	EV_CLEANUP = 32, /* used as flag */
3878c2ecf20Sopenharmony_ci};
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_cistruct digest_info {
3908c2ecf20Sopenharmony_ci	int digest_size;
3918c2ecf20Sopenharmony_ci	void *digest;
3928c2ecf20Sopenharmony_ci};
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistruct drbd_peer_request {
3958c2ecf20Sopenharmony_ci	struct drbd_work w;
3968c2ecf20Sopenharmony_ci	struct drbd_peer_device *peer_device;
3978c2ecf20Sopenharmony_ci	struct drbd_epoch *epoch; /* for writes */
3988c2ecf20Sopenharmony_ci	struct page *pages;
3998c2ecf20Sopenharmony_ci	atomic_t pending_bios;
4008c2ecf20Sopenharmony_ci	struct drbd_interval i;
4018c2ecf20Sopenharmony_ci	/* see comments on ee flag bits below */
4028c2ecf20Sopenharmony_ci	unsigned long flags;
4038c2ecf20Sopenharmony_ci	unsigned long submit_jif;
4048c2ecf20Sopenharmony_ci	union {
4058c2ecf20Sopenharmony_ci		u64 block_id;
4068c2ecf20Sopenharmony_ci		struct digest_info *digest;
4078c2ecf20Sopenharmony_ci	};
4088c2ecf20Sopenharmony_ci};
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci/* ee flag bits.
4118c2ecf20Sopenharmony_ci * While corresponding bios are in flight, the only modification will be
4128c2ecf20Sopenharmony_ci * set_bit WAS_ERROR, which has to be atomic.
4138c2ecf20Sopenharmony_ci * If no bios are in flight yet, or all have been completed,
4148c2ecf20Sopenharmony_ci * non-atomic modification to ee->flags is ok.
4158c2ecf20Sopenharmony_ci */
4168c2ecf20Sopenharmony_cienum {
4178c2ecf20Sopenharmony_ci	__EE_CALL_AL_COMPLETE_IO,
4188c2ecf20Sopenharmony_ci	__EE_MAY_SET_IN_SYNC,
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	/* is this a TRIM aka REQ_OP_DISCARD? */
4218c2ecf20Sopenharmony_ci	__EE_TRIM,
4228c2ecf20Sopenharmony_ci	/* explicit zero-out requested, or
4238c2ecf20Sopenharmony_ci	 * our lower level cannot handle trim,
4248c2ecf20Sopenharmony_ci	 * and we want to fall back to zeroout instead */
4258c2ecf20Sopenharmony_ci	__EE_ZEROOUT,
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	/* In case a barrier failed,
4288c2ecf20Sopenharmony_ci	 * we need to resubmit without the barrier flag. */
4298c2ecf20Sopenharmony_ci	__EE_RESUBMITTED,
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	/* we may have several bios per peer request.
4328c2ecf20Sopenharmony_ci	 * if any of those fail, we set this flag atomically
4338c2ecf20Sopenharmony_ci	 * from the endio callback */
4348c2ecf20Sopenharmony_ci	__EE_WAS_ERROR,
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	/* This ee has a pointer to a digest instead of a block id */
4378c2ecf20Sopenharmony_ci	__EE_HAS_DIGEST,
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	/* Conflicting local requests need to be restarted after this request */
4408c2ecf20Sopenharmony_ci	__EE_RESTART_REQUESTS,
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	/* The peer wants a write ACK for this (wire proto C) */
4438c2ecf20Sopenharmony_ci	__EE_SEND_WRITE_ACK,
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	/* Is set when net_conf had two_primaries set while creating this peer_req */
4468c2ecf20Sopenharmony_ci	__EE_IN_INTERVAL_TREE,
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	/* for debugfs: */
4498c2ecf20Sopenharmony_ci	/* has this been submitted, or does it still wait for something else? */
4508c2ecf20Sopenharmony_ci	__EE_SUBMITTED,
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci	/* this is/was a write request */
4538c2ecf20Sopenharmony_ci	__EE_WRITE,
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	/* this is/was a write same request */
4568c2ecf20Sopenharmony_ci	__EE_WRITE_SAME,
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	/* this originates from application on peer
4598c2ecf20Sopenharmony_ci	 * (not some resync or verify or other DRBD internal request) */
4608c2ecf20Sopenharmony_ci	__EE_APPLICATION,
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	/* If it contains only 0 bytes, send back P_RS_DEALLOCATED */
4638c2ecf20Sopenharmony_ci	__EE_RS_THIN_REQ,
4648c2ecf20Sopenharmony_ci};
4658c2ecf20Sopenharmony_ci#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
4668c2ecf20Sopenharmony_ci#define EE_MAY_SET_IN_SYNC     (1<<__EE_MAY_SET_IN_SYNC)
4678c2ecf20Sopenharmony_ci#define EE_TRIM                (1<<__EE_TRIM)
4688c2ecf20Sopenharmony_ci#define EE_ZEROOUT             (1<<__EE_ZEROOUT)
4698c2ecf20Sopenharmony_ci#define EE_RESUBMITTED         (1<<__EE_RESUBMITTED)
4708c2ecf20Sopenharmony_ci#define EE_WAS_ERROR           (1<<__EE_WAS_ERROR)
4718c2ecf20Sopenharmony_ci#define EE_HAS_DIGEST          (1<<__EE_HAS_DIGEST)
4728c2ecf20Sopenharmony_ci#define EE_RESTART_REQUESTS	(1<<__EE_RESTART_REQUESTS)
4738c2ecf20Sopenharmony_ci#define EE_SEND_WRITE_ACK	(1<<__EE_SEND_WRITE_ACK)
4748c2ecf20Sopenharmony_ci#define EE_IN_INTERVAL_TREE	(1<<__EE_IN_INTERVAL_TREE)
4758c2ecf20Sopenharmony_ci#define EE_SUBMITTED		(1<<__EE_SUBMITTED)
4768c2ecf20Sopenharmony_ci#define EE_WRITE		(1<<__EE_WRITE)
4778c2ecf20Sopenharmony_ci#define EE_WRITE_SAME		(1<<__EE_WRITE_SAME)
4788c2ecf20Sopenharmony_ci#define EE_APPLICATION		(1<<__EE_APPLICATION)
4798c2ecf20Sopenharmony_ci#define EE_RS_THIN_REQ		(1<<__EE_RS_THIN_REQ)
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci/* flag bits per device */
4828c2ecf20Sopenharmony_cienum {
4838c2ecf20Sopenharmony_ci	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
4848c2ecf20Sopenharmony_ci	MD_DIRTY,		/* current uuids and flags not yet on disk */
4858c2ecf20Sopenharmony_ci	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
4868c2ecf20Sopenharmony_ci	CL_ST_CHG_SUCCESS,
4878c2ecf20Sopenharmony_ci	CL_ST_CHG_FAIL,
4888c2ecf20Sopenharmony_ci	CRASHED_PRIMARY,	/* This node was a crashed primary.
4898c2ecf20Sopenharmony_ci				 * Gets cleared when the state.conn
4908c2ecf20Sopenharmony_ci				 * goes into C_CONNECTED state. */
4918c2ecf20Sopenharmony_ci	CONSIDER_RESYNC,
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	MD_NO_FUA,		/* Users wants us to not use FUA/FLUSH on meta data dev */
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	BITMAP_IO,		/* suspend application io;
4968c2ecf20Sopenharmony_ci				   once no more io in flight, start bitmap io */
4978c2ecf20Sopenharmony_ci	BITMAP_IO_QUEUED,       /* Started bitmap IO */
4988c2ecf20Sopenharmony_ci	WAS_IO_ERROR,		/* Local disk failed, returned IO error */
4998c2ecf20Sopenharmony_ci	WAS_READ_ERROR,		/* Local disk READ failed (set additionally to the above) */
5008c2ecf20Sopenharmony_ci	FORCE_DETACH,		/* Force-detach from local disk, aborting any pending local IO */
5018c2ecf20Sopenharmony_ci	RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
5028c2ecf20Sopenharmony_ci	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
5038c2ecf20Sopenharmony_ci				 * the peer, if it changed there as well. */
5048c2ecf20Sopenharmony_ci	NEW_CUR_UUID,		/* Create new current UUID when thawing IO */
5058c2ecf20Sopenharmony_ci	AL_SUSPENDED,		/* Activity logging is currently suspended. */
5068c2ecf20Sopenharmony_ci	AHEAD_TO_SYNC_SOURCE,   /* Ahead -> SyncSource queued */
5078c2ecf20Sopenharmony_ci	B_RS_H_DONE,		/* Before resync handler done (already executed) */
5088c2ecf20Sopenharmony_ci	DISCARD_MY_DATA,	/* discard_my_data flag per volume */
5098c2ecf20Sopenharmony_ci	READ_BALANCE_RR,
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	FLUSH_PENDING,		/* if set, device->flush_jif is when we submitted that flush
5128c2ecf20Sopenharmony_ci				 * from drbd_flush_after_epoch() */
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	/* cleared only after backing device related structures have been destroyed. */
5158c2ecf20Sopenharmony_ci	GOING_DISKLESS,		/* Disk is being detached, because of io-error, or admin request. */
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	/* to be used in drbd_device_post_work() */
5188c2ecf20Sopenharmony_ci	GO_DISKLESS,		/* tell worker to schedule cleanup before detach */
5198c2ecf20Sopenharmony_ci	DESTROY_DISK,		/* tell worker to close backing devices and destroy related structures. */
5208c2ecf20Sopenharmony_ci	MD_SYNC,		/* tell worker to call drbd_md_sync() */
5218c2ecf20Sopenharmony_ci	RS_START,		/* tell worker to start resync/OV */
5228c2ecf20Sopenharmony_ci	RS_PROGRESS,		/* tell worker that resync made significant progress */
5238c2ecf20Sopenharmony_ci	RS_DONE,		/* tell worker that resync is done */
5248c2ecf20Sopenharmony_ci};
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_cistruct drbd_bitmap; /* opaque for drbd_device */
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci/* definition of bits in bm_flags to be used in drbd_bm_lock
5298c2ecf20Sopenharmony_ci * and drbd_bitmap_io and friends. */
5308c2ecf20Sopenharmony_cienum bm_flag {
5318c2ecf20Sopenharmony_ci	/* currently locked for bulk operation */
5328c2ecf20Sopenharmony_ci	BM_LOCKED_MASK = 0xf,
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci	/* in detail, that is: */
5358c2ecf20Sopenharmony_ci	BM_DONT_CLEAR = 0x1,
5368c2ecf20Sopenharmony_ci	BM_DONT_SET   = 0x2,
5378c2ecf20Sopenharmony_ci	BM_DONT_TEST  = 0x4,
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	/* so we can mark it locked for bulk operation,
5408c2ecf20Sopenharmony_ci	 * and still allow all non-bulk operations */
5418c2ecf20Sopenharmony_ci	BM_IS_LOCKED  = 0x8,
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci	/* (test bit, count bit) allowed (common case) */
5448c2ecf20Sopenharmony_ci	BM_LOCKED_TEST_ALLOWED = BM_DONT_CLEAR | BM_DONT_SET | BM_IS_LOCKED,
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	/* testing bits, as well as setting new bits allowed, but clearing bits
5478c2ecf20Sopenharmony_ci	 * would be unexpected.  Used during bitmap receive.  Setting new bits
5488c2ecf20Sopenharmony_ci	 * requires sending of "out-of-sync" information, though. */
5498c2ecf20Sopenharmony_ci	BM_LOCKED_SET_ALLOWED = BM_DONT_CLEAR | BM_IS_LOCKED,
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_ci	/* for drbd_bm_write_copy_pages, everything is allowed,
5528c2ecf20Sopenharmony_ci	 * only concurrent bulk operations are locked out. */
5538c2ecf20Sopenharmony_ci	BM_LOCKED_CHANGE_ALLOWED = BM_IS_LOCKED,
5548c2ecf20Sopenharmony_ci};
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistruct drbd_work_queue {
5578c2ecf20Sopenharmony_ci	struct list_head q;
5588c2ecf20Sopenharmony_ci	spinlock_t q_lock;  /* to protect the list. */
5598c2ecf20Sopenharmony_ci	wait_queue_head_t q_wait;
5608c2ecf20Sopenharmony_ci};
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_cistruct drbd_socket {
5638c2ecf20Sopenharmony_ci	struct mutex mutex;
5648c2ecf20Sopenharmony_ci	struct socket    *socket;
5658c2ecf20Sopenharmony_ci	/* this way we get our
5668c2ecf20Sopenharmony_ci	 * send/receive buffers off the stack */
5678c2ecf20Sopenharmony_ci	void *sbuf;
5688c2ecf20Sopenharmony_ci	void *rbuf;
5698c2ecf20Sopenharmony_ci};
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_cistruct drbd_md {
5728c2ecf20Sopenharmony_ci	u64 md_offset;		/* sector offset to 'super' block */
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	u64 la_size_sect;	/* last agreed size, unit sectors */
5758c2ecf20Sopenharmony_ci	spinlock_t uuid_lock;
5768c2ecf20Sopenharmony_ci	u64 uuid[UI_SIZE];
5778c2ecf20Sopenharmony_ci	u64 device_uuid;
5788c2ecf20Sopenharmony_ci	u32 flags;
5798c2ecf20Sopenharmony_ci	u32 md_size_sect;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	s32 al_offset;	/* signed relative sector offset to activity log */
5828c2ecf20Sopenharmony_ci	s32 bm_offset;	/* signed relative sector offset to bitmap */
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci	/* cached value of bdev->disk_conf->meta_dev_idx (see below) */
5858c2ecf20Sopenharmony_ci	s32 meta_dev_idx;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	/* see al_tr_number_to_on_disk_sector() */
5888c2ecf20Sopenharmony_ci	u32 al_stripes;
5898c2ecf20Sopenharmony_ci	u32 al_stripe_size_4k;
5908c2ecf20Sopenharmony_ci	u32 al_size_4k; /* cached product of the above */
5918c2ecf20Sopenharmony_ci};
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistruct drbd_backing_dev {
5948c2ecf20Sopenharmony_ci	struct block_device *backing_bdev;
5958c2ecf20Sopenharmony_ci	struct block_device *md_bdev;
5968c2ecf20Sopenharmony_ci	struct drbd_md md;
5978c2ecf20Sopenharmony_ci	struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
5988c2ecf20Sopenharmony_ci	sector_t known_size; /* last known size of that backing device */
5998c2ecf20Sopenharmony_ci};
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_cistruct drbd_md_io {
6028c2ecf20Sopenharmony_ci	struct page *page;
6038c2ecf20Sopenharmony_ci	unsigned long start_jif;	/* last call to drbd_md_get_buffer */
6048c2ecf20Sopenharmony_ci	unsigned long submit_jif;	/* last _drbd_md_sync_page_io() submit */
6058c2ecf20Sopenharmony_ci	const char *current_use;
6068c2ecf20Sopenharmony_ci	atomic_t in_use;
6078c2ecf20Sopenharmony_ci	unsigned int done;
6088c2ecf20Sopenharmony_ci	int error;
6098c2ecf20Sopenharmony_ci};
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_cistruct bm_io_work {
6128c2ecf20Sopenharmony_ci	struct drbd_work w;
6138c2ecf20Sopenharmony_ci	char *why;
6148c2ecf20Sopenharmony_ci	enum bm_flag flags;
6158c2ecf20Sopenharmony_ci	int (*io_fn)(struct drbd_device *device);
6168c2ecf20Sopenharmony_ci	void (*done)(struct drbd_device *device, int rv);
6178c2ecf20Sopenharmony_ci};
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_cistruct fifo_buffer {
6208c2ecf20Sopenharmony_ci	unsigned int head_index;
6218c2ecf20Sopenharmony_ci	unsigned int size;
6228c2ecf20Sopenharmony_ci	int total; /* sum of all values */
6238c2ecf20Sopenharmony_ci	int values[];
6248c2ecf20Sopenharmony_ci};
6258c2ecf20Sopenharmony_ciextern struct fifo_buffer *fifo_alloc(unsigned int fifo_size);
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci/* flag bits per connection */
6288c2ecf20Sopenharmony_cienum {
6298c2ecf20Sopenharmony_ci	NET_CONGESTED,		/* The data socket is congested */
6308c2ecf20Sopenharmony_ci	RESOLVE_CONFLICTS,	/* Set on one node, cleared on the peer! */
6318c2ecf20Sopenharmony_ci	SEND_PING,
6328c2ecf20Sopenharmony_ci	GOT_PING_ACK,		/* set when we receive a ping_ack packet, ping_wait gets woken */
6338c2ecf20Sopenharmony_ci	CONN_WD_ST_CHG_REQ,	/* A cluster wide state change on the connection is active */
6348c2ecf20Sopenharmony_ci	CONN_WD_ST_CHG_OKAY,
6358c2ecf20Sopenharmony_ci	CONN_WD_ST_CHG_FAIL,
6368c2ecf20Sopenharmony_ci	CONN_DRY_RUN,		/* Expect disconnect after resync handshake. */
6378c2ecf20Sopenharmony_ci	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
6388c2ecf20Sopenharmony_ci	STATE_SENT,		/* Do not change state/UUIDs while this is set */
6398c2ecf20Sopenharmony_ci	CALLBACK_PENDING,	/* Whether we have a call_usermodehelper(, UMH_WAIT_PROC)
6408c2ecf20Sopenharmony_ci				 * pending, from drbd worker context.
6418c2ecf20Sopenharmony_ci				 * If set, bdi_write_congested() returns true,
6428c2ecf20Sopenharmony_ci				 * so shrink_page_list() would not recurse into,
6438c2ecf20Sopenharmony_ci				 * and potentially deadlock on, this drbd worker.
6448c2ecf20Sopenharmony_ci				 */
6458c2ecf20Sopenharmony_ci	DISCONNECT_SENT,
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	DEVICE_WORK_PENDING,	/* tell worker that some device has pending work */
6488c2ecf20Sopenharmony_ci};
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_cienum which_state { NOW, OLD = NOW, NEW };
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_cistruct drbd_resource {
6538c2ecf20Sopenharmony_ci	char *name;
6548c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
6558c2ecf20Sopenharmony_ci	struct dentry *debugfs_res;
6568c2ecf20Sopenharmony_ci	struct dentry *debugfs_res_volumes;
6578c2ecf20Sopenharmony_ci	struct dentry *debugfs_res_connections;
6588c2ecf20Sopenharmony_ci	struct dentry *debugfs_res_in_flight_summary;
6598c2ecf20Sopenharmony_ci#endif
6608c2ecf20Sopenharmony_ci	struct kref kref;
6618c2ecf20Sopenharmony_ci	struct idr devices;		/* volume number to device mapping */
6628c2ecf20Sopenharmony_ci	struct list_head connections;
6638c2ecf20Sopenharmony_ci	struct list_head resources;
6648c2ecf20Sopenharmony_ci	struct res_opts res_opts;
6658c2ecf20Sopenharmony_ci	struct mutex conf_update;	/* mutex for ready-copy-update of net_conf and disk_conf */
6668c2ecf20Sopenharmony_ci	struct mutex adm_mutex;		/* mutex to serialize administrative requests */
6678c2ecf20Sopenharmony_ci	spinlock_t req_lock;
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci	unsigned susp:1;		/* IO suspended by user */
6708c2ecf20Sopenharmony_ci	unsigned susp_nod:1;		/* IO suspended because no data */
6718c2ecf20Sopenharmony_ci	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci	enum write_ordering_e write_ordering;
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci	cpumask_var_t cpu_mask;
6768c2ecf20Sopenharmony_ci};
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_cistruct drbd_thread_timing_details
6798c2ecf20Sopenharmony_ci{
6808c2ecf20Sopenharmony_ci	unsigned long start_jif;
6818c2ecf20Sopenharmony_ci	void *cb_addr;
6828c2ecf20Sopenharmony_ci	const char *caller_fn;
6838c2ecf20Sopenharmony_ci	unsigned int line;
6848c2ecf20Sopenharmony_ci	unsigned int cb_nr;
6858c2ecf20Sopenharmony_ci};
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_cistruct drbd_connection {
6888c2ecf20Sopenharmony_ci	struct list_head connections;
6898c2ecf20Sopenharmony_ci	struct drbd_resource *resource;
6908c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
6918c2ecf20Sopenharmony_ci	struct dentry *debugfs_conn;
6928c2ecf20Sopenharmony_ci	struct dentry *debugfs_conn_callback_history;
6938c2ecf20Sopenharmony_ci	struct dentry *debugfs_conn_oldest_requests;
6948c2ecf20Sopenharmony_ci#endif
6958c2ecf20Sopenharmony_ci	struct kref kref;
6968c2ecf20Sopenharmony_ci	struct idr peer_devices;	/* volume number to peer device mapping */
6978c2ecf20Sopenharmony_ci	enum drbd_conns cstate;		/* Only C_STANDALONE to C_WF_REPORT_PARAMS */
6988c2ecf20Sopenharmony_ci	struct mutex cstate_mutex;	/* Protects graceful disconnects */
6998c2ecf20Sopenharmony_ci	unsigned int connect_cnt;	/* Inc each time a connection is established */
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci	unsigned long flags;
7028c2ecf20Sopenharmony_ci	struct net_conf *net_conf;	/* content protected by rcu */
7038c2ecf20Sopenharmony_ci	wait_queue_head_t ping_wait;	/* Woken upon reception of a ping, and a state change */
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ci	struct sockaddr_storage my_addr;
7068c2ecf20Sopenharmony_ci	int my_addr_len;
7078c2ecf20Sopenharmony_ci	struct sockaddr_storage peer_addr;
7088c2ecf20Sopenharmony_ci	int peer_addr_len;
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_ci	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
7118c2ecf20Sopenharmony_ci	struct drbd_socket meta;	/* ping/ack (metadata) packets */
7128c2ecf20Sopenharmony_ci	int agreed_pro_version;		/* actually used protocol version */
7138c2ecf20Sopenharmony_ci	u32 agreed_features;
7148c2ecf20Sopenharmony_ci	unsigned long last_received;	/* in jiffies, either socket */
7158c2ecf20Sopenharmony_ci	unsigned int ko_count;
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci	struct list_head transfer_log;	/* all requests not yet fully processed */
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci	struct crypto_shash *cram_hmac_tfm;
7208c2ecf20Sopenharmony_ci	struct crypto_shash *integrity_tfm;  /* checksums we compute, updates protected by connection->data->mutex */
7218c2ecf20Sopenharmony_ci	struct crypto_shash *peer_integrity_tfm;  /* checksums we verify, only accessed from receiver thread  */
7228c2ecf20Sopenharmony_ci	struct crypto_shash *csums_tfm;
7238c2ecf20Sopenharmony_ci	struct crypto_shash *verify_tfm;
7248c2ecf20Sopenharmony_ci	void *int_dig_in;
7258c2ecf20Sopenharmony_ci	void *int_dig_vv;
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci	/* receiver side */
7288c2ecf20Sopenharmony_ci	struct drbd_epoch *current_epoch;
7298c2ecf20Sopenharmony_ci	spinlock_t epoch_lock;
7308c2ecf20Sopenharmony_ci	unsigned int epochs;
7318c2ecf20Sopenharmony_ci	atomic_t current_tle_nr;	/* transfer log epoch number */
7328c2ecf20Sopenharmony_ci	unsigned current_tle_writes;	/* writes seen within this tl epoch */
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci	unsigned long last_reconnect_jif;
7358c2ecf20Sopenharmony_ci	/* empty member on older kernels without blk_start_plug() */
7368c2ecf20Sopenharmony_ci	struct blk_plug receiver_plug;
7378c2ecf20Sopenharmony_ci	struct drbd_thread receiver;
7388c2ecf20Sopenharmony_ci	struct drbd_thread worker;
7398c2ecf20Sopenharmony_ci	struct drbd_thread ack_receiver;
7408c2ecf20Sopenharmony_ci	struct workqueue_struct *ack_sender;
7418c2ecf20Sopenharmony_ci
7428c2ecf20Sopenharmony_ci	/* cached pointers,
7438c2ecf20Sopenharmony_ci	 * so we can look up the oldest pending requests more quickly.
7448c2ecf20Sopenharmony_ci	 * protected by resource->req_lock */
7458c2ecf20Sopenharmony_ci	struct drbd_request *req_next; /* DRBD 9: todo.req_next */
7468c2ecf20Sopenharmony_ci	struct drbd_request *req_ack_pending;
7478c2ecf20Sopenharmony_ci	struct drbd_request *req_not_net_done;
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_ci	/* sender side */
7508c2ecf20Sopenharmony_ci	struct drbd_work_queue sender_work;
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_ci#define DRBD_THREAD_DETAILS_HIST	16
7538c2ecf20Sopenharmony_ci	unsigned int w_cb_nr; /* keeps counting up */
7548c2ecf20Sopenharmony_ci	unsigned int r_cb_nr; /* keeps counting up */
7558c2ecf20Sopenharmony_ci	struct drbd_thread_timing_details w_timing_details[DRBD_THREAD_DETAILS_HIST];
7568c2ecf20Sopenharmony_ci	struct drbd_thread_timing_details r_timing_details[DRBD_THREAD_DETAILS_HIST];
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	struct {
7598c2ecf20Sopenharmony_ci		unsigned long last_sent_barrier_jif;
7608c2ecf20Sopenharmony_ci
7618c2ecf20Sopenharmony_ci		/* whether this sender thread
7628c2ecf20Sopenharmony_ci		 * has processed a single write yet. */
7638c2ecf20Sopenharmony_ci		bool seen_any_write_yet;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci		/* Which barrier number to send with the next P_BARRIER */
7668c2ecf20Sopenharmony_ci		int current_epoch_nr;
7678c2ecf20Sopenharmony_ci
7688c2ecf20Sopenharmony_ci		/* how many write requests have been sent
7698c2ecf20Sopenharmony_ci		 * with req->epoch == current_epoch_nr.
7708c2ecf20Sopenharmony_ci		 * If none, no P_BARRIER will be sent. */
7718c2ecf20Sopenharmony_ci		unsigned current_epoch_writes;
7728c2ecf20Sopenharmony_ci	} send;
7738c2ecf20Sopenharmony_ci};
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_cistatic inline bool has_net_conf(struct drbd_connection *connection)
7768c2ecf20Sopenharmony_ci{
7778c2ecf20Sopenharmony_ci	bool has_net_conf;
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	rcu_read_lock();
7808c2ecf20Sopenharmony_ci	has_net_conf = rcu_dereference(connection->net_conf);
7818c2ecf20Sopenharmony_ci	rcu_read_unlock();
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	return has_net_conf;
7848c2ecf20Sopenharmony_ci}
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_civoid __update_timing_details(
7878c2ecf20Sopenharmony_ci		struct drbd_thread_timing_details *tdp,
7888c2ecf20Sopenharmony_ci		unsigned int *cb_nr,
7898c2ecf20Sopenharmony_ci		void *cb,
7908c2ecf20Sopenharmony_ci		const char *fn, const unsigned int line);
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci#define update_worker_timing_details(c, cb) \
7938c2ecf20Sopenharmony_ci	__update_timing_details(c->w_timing_details, &c->w_cb_nr, cb, __func__ , __LINE__ )
7948c2ecf20Sopenharmony_ci#define update_receiver_timing_details(c, cb) \
7958c2ecf20Sopenharmony_ci	__update_timing_details(c->r_timing_details, &c->r_cb_nr, cb, __func__ , __LINE__ )
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_cistruct submit_worker {
7988c2ecf20Sopenharmony_ci	struct workqueue_struct *wq;
7998c2ecf20Sopenharmony_ci	struct work_struct worker;
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_ci	/* protected by ..->resource->req_lock */
8028c2ecf20Sopenharmony_ci	struct list_head writes;
8038c2ecf20Sopenharmony_ci};
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_cistruct drbd_peer_device {
8068c2ecf20Sopenharmony_ci	struct list_head peer_devices;
8078c2ecf20Sopenharmony_ci	struct drbd_device *device;
8088c2ecf20Sopenharmony_ci	struct drbd_connection *connection;
8098c2ecf20Sopenharmony_ci	struct work_struct send_acks_work;
8108c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
8118c2ecf20Sopenharmony_ci	struct dentry *debugfs_peer_dev;
8128c2ecf20Sopenharmony_ci#endif
8138c2ecf20Sopenharmony_ci};
8148c2ecf20Sopenharmony_ci
8158c2ecf20Sopenharmony_cistruct drbd_device {
8168c2ecf20Sopenharmony_ci	struct drbd_resource *resource;
8178c2ecf20Sopenharmony_ci	struct list_head peer_devices;
8188c2ecf20Sopenharmony_ci	struct list_head pending_bitmap_io;
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_ci	unsigned long flush_jif;
8218c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
8228c2ecf20Sopenharmony_ci	struct dentry *debugfs_minor;
8238c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol;
8248c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol_oldest_requests;
8258c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol_act_log_extents;
8268c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol_resync_extents;
8278c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol_data_gen_id;
8288c2ecf20Sopenharmony_ci	struct dentry *debugfs_vol_ed_gen_id;
8298c2ecf20Sopenharmony_ci#endif
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci	unsigned int vnr;	/* volume number within the connection */
8328c2ecf20Sopenharmony_ci	unsigned int minor;	/* device minor number */
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_ci	struct kref kref;
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	/* things that are stored as / read from meta data on disk */
8378c2ecf20Sopenharmony_ci	unsigned long flags;
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci	/* configured by drbdsetup */
8408c2ecf20Sopenharmony_ci	struct drbd_backing_dev *ldev __protected_by(local);
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	sector_t p_size;     /* partner's disk size */
8438c2ecf20Sopenharmony_ci	struct request_queue *rq_queue;
8448c2ecf20Sopenharmony_ci	struct gendisk	    *vdisk;
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ci	unsigned long last_reattach_jif;
8478c2ecf20Sopenharmony_ci	struct drbd_work resync_work;
8488c2ecf20Sopenharmony_ci	struct drbd_work unplug_work;
8498c2ecf20Sopenharmony_ci	struct timer_list resync_timer;
8508c2ecf20Sopenharmony_ci	struct timer_list md_sync_timer;
8518c2ecf20Sopenharmony_ci	struct timer_list start_resync_timer;
8528c2ecf20Sopenharmony_ci	struct timer_list request_timer;
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	/* Used after attach while negotiating new disk state. */
8558c2ecf20Sopenharmony_ci	union drbd_state new_state_tmp;
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	union drbd_dev_state state;
8588c2ecf20Sopenharmony_ci	wait_queue_head_t misc_wait;
8598c2ecf20Sopenharmony_ci	wait_queue_head_t state_wait;  /* upon each state change. */
8608c2ecf20Sopenharmony_ci	unsigned int send_cnt;
8618c2ecf20Sopenharmony_ci	unsigned int recv_cnt;
8628c2ecf20Sopenharmony_ci	unsigned int read_cnt;
8638c2ecf20Sopenharmony_ci	unsigned int writ_cnt;
8648c2ecf20Sopenharmony_ci	unsigned int al_writ_cnt;
8658c2ecf20Sopenharmony_ci	unsigned int bm_writ_cnt;
8668c2ecf20Sopenharmony_ci	atomic_t ap_bio_cnt;	 /* Requests we need to complete */
8678c2ecf20Sopenharmony_ci	atomic_t ap_actlog_cnt;  /* Requests waiting for activity log */
8688c2ecf20Sopenharmony_ci	atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */
8698c2ecf20Sopenharmony_ci	atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
8708c2ecf20Sopenharmony_ci	atomic_t unacked_cnt;	 /* Need to send replies for */
8718c2ecf20Sopenharmony_ci	atomic_t local_cnt;	 /* Waiting for local completion */
8728c2ecf20Sopenharmony_ci	atomic_t suspend_cnt;
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci	/* Interval tree of pending local requests */
8758c2ecf20Sopenharmony_ci	struct rb_root read_requests;
8768c2ecf20Sopenharmony_ci	struct rb_root write_requests;
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_ci	/* for statistics and timeouts */
8798c2ecf20Sopenharmony_ci	/* [0] read, [1] write */
8808c2ecf20Sopenharmony_ci	struct list_head pending_master_completion[2];
8818c2ecf20Sopenharmony_ci	struct list_head pending_completion[2];
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_ci	/* use checksums for *this* resync */
8848c2ecf20Sopenharmony_ci	bool use_csums;
8858c2ecf20Sopenharmony_ci	/* blocks to resync in this run [unit BM_BLOCK_SIZE] */
8868c2ecf20Sopenharmony_ci	unsigned long rs_total;
8878c2ecf20Sopenharmony_ci	/* number of resync blocks that failed in this run */
8888c2ecf20Sopenharmony_ci	unsigned long rs_failed;
8898c2ecf20Sopenharmony_ci	/* Syncer's start time [unit jiffies] */
8908c2ecf20Sopenharmony_ci	unsigned long rs_start;
8918c2ecf20Sopenharmony_ci	/* cumulated time in PausedSyncX state [unit jiffies] */
8928c2ecf20Sopenharmony_ci	unsigned long rs_paused;
8938c2ecf20Sopenharmony_ci	/* skipped because csum was equal [unit BM_BLOCK_SIZE] */
8948c2ecf20Sopenharmony_ci	unsigned long rs_same_csum;
8958c2ecf20Sopenharmony_ci#define DRBD_SYNC_MARKS 8
8968c2ecf20Sopenharmony_ci#define DRBD_SYNC_MARK_STEP (3*HZ)
8978c2ecf20Sopenharmony_ci	/* block not up-to-date at mark [unit BM_BLOCK_SIZE] */
8988c2ecf20Sopenharmony_ci	unsigned long rs_mark_left[DRBD_SYNC_MARKS];
8998c2ecf20Sopenharmony_ci	/* marks's time [unit jiffies] */
9008c2ecf20Sopenharmony_ci	unsigned long rs_mark_time[DRBD_SYNC_MARKS];
9018c2ecf20Sopenharmony_ci	/* current index into rs_mark_{left,time} */
9028c2ecf20Sopenharmony_ci	int rs_last_mark;
9038c2ecf20Sopenharmony_ci	unsigned long rs_last_bcast; /* [unit jiffies] */
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_ci	/* where does the admin want us to start? (sector) */
9068c2ecf20Sopenharmony_ci	sector_t ov_start_sector;
9078c2ecf20Sopenharmony_ci	sector_t ov_stop_sector;
9088c2ecf20Sopenharmony_ci	/* where are we now? (sector) */
9098c2ecf20Sopenharmony_ci	sector_t ov_position;
9108c2ecf20Sopenharmony_ci	/* Start sector of out of sync range (to merge printk reporting). */
9118c2ecf20Sopenharmony_ci	sector_t ov_last_oos_start;
9128c2ecf20Sopenharmony_ci	/* size of out-of-sync range in sectors. */
9138c2ecf20Sopenharmony_ci	sector_t ov_last_oos_size;
9148c2ecf20Sopenharmony_ci	unsigned long ov_left; /* in bits */
9158c2ecf20Sopenharmony_ci
9168c2ecf20Sopenharmony_ci	struct drbd_bitmap *bitmap;
9178c2ecf20Sopenharmony_ci	unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */
9188c2ecf20Sopenharmony_ci
9198c2ecf20Sopenharmony_ci	/* Used to track operations of resync... */
9208c2ecf20Sopenharmony_ci	struct lru_cache *resync;
9218c2ecf20Sopenharmony_ci	/* Number of locked elements in resync LRU */
9228c2ecf20Sopenharmony_ci	unsigned int resync_locked;
9238c2ecf20Sopenharmony_ci	/* resync extent number waiting for application requests */
9248c2ecf20Sopenharmony_ci	unsigned int resync_wenr;
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_ci	int open_cnt;
9278c2ecf20Sopenharmony_ci	u64 *p_uuid;
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_ci	struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */
9308c2ecf20Sopenharmony_ci	struct list_head sync_ee;   /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
9318c2ecf20Sopenharmony_ci	struct list_head done_ee;   /* need to send P_WRITE_ACK */
9328c2ecf20Sopenharmony_ci	struct list_head read_ee;   /* [RS]P_DATA_REQUEST being read */
9338c2ecf20Sopenharmony_ci	struct list_head net_ee;    /* zero-copy network send in progress */
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	int next_barrier_nr;
9368c2ecf20Sopenharmony_ci	struct list_head resync_reads;
9378c2ecf20Sopenharmony_ci	atomic_t pp_in_use;		/* allocated from page pool */
9388c2ecf20Sopenharmony_ci	atomic_t pp_in_use_by_net;	/* sendpage()d, still referenced by tcp */
9398c2ecf20Sopenharmony_ci	wait_queue_head_t ee_wait;
9408c2ecf20Sopenharmony_ci	struct drbd_md_io md_io;
9418c2ecf20Sopenharmony_ci	spinlock_t al_lock;
9428c2ecf20Sopenharmony_ci	wait_queue_head_t al_wait;
9438c2ecf20Sopenharmony_ci	struct lru_cache *act_log;	/* activity log */
9448c2ecf20Sopenharmony_ci	unsigned int al_tr_number;
9458c2ecf20Sopenharmony_ci	int al_tr_cycle;
9468c2ecf20Sopenharmony_ci	wait_queue_head_t seq_wait;
9478c2ecf20Sopenharmony_ci	atomic_t packet_seq;
9488c2ecf20Sopenharmony_ci	unsigned int peer_seq;
9498c2ecf20Sopenharmony_ci	spinlock_t peer_seq_lock;
9508c2ecf20Sopenharmony_ci	unsigned long comm_bm_set; /* communicated number of set bits. */
9518c2ecf20Sopenharmony_ci	struct bm_io_work bm_io_work;
9528c2ecf20Sopenharmony_ci	u64 ed_uuid; /* UUID of the exposed data */
9538c2ecf20Sopenharmony_ci	struct mutex own_state_mutex;
9548c2ecf20Sopenharmony_ci	struct mutex *state_mutex; /* either own_state_mutex or first_peer_device(device)->connection->cstate_mutex */
9558c2ecf20Sopenharmony_ci	char congestion_reason;  /* Why we where congested... */
9568c2ecf20Sopenharmony_ci	atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
9578c2ecf20Sopenharmony_ci	atomic_t rs_sect_ev; /* for submitted resync data rate, both */
9588c2ecf20Sopenharmony_ci	int rs_last_sect_ev; /* counter to compare with */
9598c2ecf20Sopenharmony_ci	int rs_last_events;  /* counter of read or write "events" (unit sectors)
9608c2ecf20Sopenharmony_ci			      * on the lower level device when we last looked. */
9618c2ecf20Sopenharmony_ci	int c_sync_rate; /* current resync rate after syncer throttle magic */
9628c2ecf20Sopenharmony_ci	struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
9638c2ecf20Sopenharmony_ci	int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
9648c2ecf20Sopenharmony_ci	atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
9658c2ecf20Sopenharmony_ci	unsigned int peer_max_bio_size;
9668c2ecf20Sopenharmony_ci	unsigned int local_max_bio_size;
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	/* any requests that would block in drbd_make_request()
9698c2ecf20Sopenharmony_ci	 * are deferred to this single-threaded work queue */
9708c2ecf20Sopenharmony_ci	struct submit_worker submit;
9718c2ecf20Sopenharmony_ci};
9728c2ecf20Sopenharmony_ci
9738c2ecf20Sopenharmony_cistruct drbd_bm_aio_ctx {
9748c2ecf20Sopenharmony_ci	struct drbd_device *device;
9758c2ecf20Sopenharmony_ci	struct list_head list; /* on device->pending_bitmap_io */;
9768c2ecf20Sopenharmony_ci	unsigned long start_jif;
9778c2ecf20Sopenharmony_ci	atomic_t in_flight;
9788c2ecf20Sopenharmony_ci	unsigned int done;
9798c2ecf20Sopenharmony_ci	unsigned flags;
9808c2ecf20Sopenharmony_ci#define BM_AIO_COPY_PAGES	1
9818c2ecf20Sopenharmony_ci#define BM_AIO_WRITE_HINTED	2
9828c2ecf20Sopenharmony_ci#define BM_AIO_WRITE_ALL_PAGES	4
9838c2ecf20Sopenharmony_ci#define BM_AIO_READ		8
9848c2ecf20Sopenharmony_ci	int error;
9858c2ecf20Sopenharmony_ci	struct kref kref;
9868c2ecf20Sopenharmony_ci};
9878c2ecf20Sopenharmony_ci
9888c2ecf20Sopenharmony_cistruct drbd_config_context {
9898c2ecf20Sopenharmony_ci	/* assigned from drbd_genlmsghdr */
9908c2ecf20Sopenharmony_ci	unsigned int minor;
9918c2ecf20Sopenharmony_ci	/* assigned from request attributes, if present */
9928c2ecf20Sopenharmony_ci	unsigned int volume;
9938c2ecf20Sopenharmony_ci#define VOLUME_UNSPECIFIED		(-1U)
9948c2ecf20Sopenharmony_ci	/* pointer into the request skb,
9958c2ecf20Sopenharmony_ci	 * limited lifetime! */
9968c2ecf20Sopenharmony_ci	char *resource_name;
9978c2ecf20Sopenharmony_ci	struct nlattr *my_addr;
9988c2ecf20Sopenharmony_ci	struct nlattr *peer_addr;
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	/* reply buffer */
10018c2ecf20Sopenharmony_ci	struct sk_buff *reply_skb;
10028c2ecf20Sopenharmony_ci	/* pointer into reply buffer */
10038c2ecf20Sopenharmony_ci	struct drbd_genlmsghdr *reply_dh;
10048c2ecf20Sopenharmony_ci	/* resolved from attributes, if possible */
10058c2ecf20Sopenharmony_ci	struct drbd_device *device;
10068c2ecf20Sopenharmony_ci	struct drbd_resource *resource;
10078c2ecf20Sopenharmony_ci	struct drbd_connection *connection;
10088c2ecf20Sopenharmony_ci};
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_cistatic inline struct drbd_device *minor_to_device(unsigned int minor)
10118c2ecf20Sopenharmony_ci{
10128c2ecf20Sopenharmony_ci	return (struct drbd_device *)idr_find(&drbd_devices, minor);
10138c2ecf20Sopenharmony_ci}
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_cistatic inline struct drbd_peer_device *first_peer_device(struct drbd_device *device)
10168c2ecf20Sopenharmony_ci{
10178c2ecf20Sopenharmony_ci	return list_first_entry_or_null(&device->peer_devices, struct drbd_peer_device, peer_devices);
10188c2ecf20Sopenharmony_ci}
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_cistatic inline struct drbd_peer_device *
10218c2ecf20Sopenharmony_ciconn_peer_device(struct drbd_connection *connection, int volume_number)
10228c2ecf20Sopenharmony_ci{
10238c2ecf20Sopenharmony_ci	return idr_find(&connection->peer_devices, volume_number);
10248c2ecf20Sopenharmony_ci}
10258c2ecf20Sopenharmony_ci
10268c2ecf20Sopenharmony_ci#define for_each_resource(resource, _resources) \
10278c2ecf20Sopenharmony_ci	list_for_each_entry(resource, _resources, resources)
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci#define for_each_resource_rcu(resource, _resources) \
10308c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(resource, _resources, resources)
10318c2ecf20Sopenharmony_ci
10328c2ecf20Sopenharmony_ci#define for_each_resource_safe(resource, tmp, _resources) \
10338c2ecf20Sopenharmony_ci	list_for_each_entry_safe(resource, tmp, _resources, resources)
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci#define for_each_connection(connection, resource) \
10368c2ecf20Sopenharmony_ci	list_for_each_entry(connection, &resource->connections, connections)
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci#define for_each_connection_rcu(connection, resource) \
10398c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(connection, &resource->connections, connections)
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci#define for_each_connection_safe(connection, tmp, resource) \
10428c2ecf20Sopenharmony_ci	list_for_each_entry_safe(connection, tmp, &resource->connections, connections)
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci#define for_each_peer_device(peer_device, device) \
10458c2ecf20Sopenharmony_ci	list_for_each_entry(peer_device, &device->peer_devices, peer_devices)
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ci#define for_each_peer_device_rcu(peer_device, device) \
10488c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(peer_device, &device->peer_devices, peer_devices)
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci#define for_each_peer_device_safe(peer_device, tmp, device) \
10518c2ecf20Sopenharmony_ci	list_for_each_entry_safe(peer_device, tmp, &device->peer_devices, peer_devices)
10528c2ecf20Sopenharmony_ci
10538c2ecf20Sopenharmony_cistatic inline unsigned int device_to_minor(struct drbd_device *device)
10548c2ecf20Sopenharmony_ci{
10558c2ecf20Sopenharmony_ci	return device->minor;
10568c2ecf20Sopenharmony_ci}
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci/*
10598c2ecf20Sopenharmony_ci * function declarations
10608c2ecf20Sopenharmony_ci *************************/
10618c2ecf20Sopenharmony_ci
10628c2ecf20Sopenharmony_ci/* drbd_main.c */
10638c2ecf20Sopenharmony_ci
10648c2ecf20Sopenharmony_cienum dds_flags {
10658c2ecf20Sopenharmony_ci	DDSF_FORCED    = 1,
10668c2ecf20Sopenharmony_ci	DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */
10678c2ecf20Sopenharmony_ci};
10688c2ecf20Sopenharmony_ci
10698c2ecf20Sopenharmony_ciextern void drbd_init_set_defaults(struct drbd_device *device);
10708c2ecf20Sopenharmony_ciextern int  drbd_thread_start(struct drbd_thread *thi);
10718c2ecf20Sopenharmony_ciextern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
10728c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
10738c2ecf20Sopenharmony_ciextern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
10748c2ecf20Sopenharmony_ci#else
10758c2ecf20Sopenharmony_ci#define drbd_thread_current_set_cpu(A) ({})
10768c2ecf20Sopenharmony_ci#endif
10778c2ecf20Sopenharmony_ciextern void tl_release(struct drbd_connection *, unsigned int barrier_nr,
10788c2ecf20Sopenharmony_ci		       unsigned int set_size);
10798c2ecf20Sopenharmony_ciextern void tl_clear(struct drbd_connection *);
10808c2ecf20Sopenharmony_ciextern void drbd_free_sock(struct drbd_connection *connection);
10818c2ecf20Sopenharmony_ciextern int drbd_send(struct drbd_connection *connection, struct socket *sock,
10828c2ecf20Sopenharmony_ci		     void *buf, size_t size, unsigned msg_flags);
10838c2ecf20Sopenharmony_ciextern int drbd_send_all(struct drbd_connection *, struct socket *, void *, size_t,
10848c2ecf20Sopenharmony_ci			 unsigned);
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ciextern int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd);
10878c2ecf20Sopenharmony_ciextern int drbd_send_protocol(struct drbd_connection *connection);
10888c2ecf20Sopenharmony_ciextern int drbd_send_uuids(struct drbd_peer_device *);
10898c2ecf20Sopenharmony_ciextern int drbd_send_uuids_skip_initial_sync(struct drbd_peer_device *);
10908c2ecf20Sopenharmony_ciextern void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *);
10918c2ecf20Sopenharmony_ciextern int drbd_send_sizes(struct drbd_peer_device *, int trigger_reply, enum dds_flags flags);
10928c2ecf20Sopenharmony_ciextern int drbd_send_state(struct drbd_peer_device *, union drbd_state s);
10938c2ecf20Sopenharmony_ciextern int drbd_send_current_state(struct drbd_peer_device *);
10948c2ecf20Sopenharmony_ciextern int drbd_send_sync_param(struct drbd_peer_device *);
10958c2ecf20Sopenharmony_ciextern void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr,
10968c2ecf20Sopenharmony_ci			    u32 set_size);
10978c2ecf20Sopenharmony_ciextern int drbd_send_ack(struct drbd_peer_device *, enum drbd_packet,
10988c2ecf20Sopenharmony_ci			 struct drbd_peer_request *);
10998c2ecf20Sopenharmony_ciextern void drbd_send_ack_rp(struct drbd_peer_device *, enum drbd_packet,
11008c2ecf20Sopenharmony_ci			     struct p_block_req *rp);
11018c2ecf20Sopenharmony_ciextern void drbd_send_ack_dp(struct drbd_peer_device *, enum drbd_packet,
11028c2ecf20Sopenharmony_ci			     struct p_data *dp, int data_size);
11038c2ecf20Sopenharmony_ciextern int drbd_send_ack_ex(struct drbd_peer_device *, enum drbd_packet,
11048c2ecf20Sopenharmony_ci			    sector_t sector, int blksize, u64 block_id);
11058c2ecf20Sopenharmony_ciextern int drbd_send_out_of_sync(struct drbd_peer_device *, struct drbd_request *);
11068c2ecf20Sopenharmony_ciextern int drbd_send_block(struct drbd_peer_device *, enum drbd_packet,
11078c2ecf20Sopenharmony_ci			   struct drbd_peer_request *);
11088c2ecf20Sopenharmony_ciextern int drbd_send_dblock(struct drbd_peer_device *, struct drbd_request *req);
11098c2ecf20Sopenharmony_ciextern int drbd_send_drequest(struct drbd_peer_device *, int cmd,
11108c2ecf20Sopenharmony_ci			      sector_t sector, int size, u64 block_id);
11118c2ecf20Sopenharmony_ciextern int drbd_send_drequest_csum(struct drbd_peer_device *, sector_t sector,
11128c2ecf20Sopenharmony_ci				   int size, void *digest, int digest_size,
11138c2ecf20Sopenharmony_ci				   enum drbd_packet cmd);
11148c2ecf20Sopenharmony_ciextern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int size);
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_ciextern int drbd_send_bitmap(struct drbd_device *device);
11178c2ecf20Sopenharmony_ciextern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
11188c2ecf20Sopenharmony_ciextern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
11198c2ecf20Sopenharmony_ciextern int drbd_send_rs_deallocated(struct drbd_peer_device *, struct drbd_peer_request *);
11208c2ecf20Sopenharmony_ciextern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
11218c2ecf20Sopenharmony_ciextern void drbd_device_cleanup(struct drbd_device *device);
11228c2ecf20Sopenharmony_ciextern void drbd_print_uuids(struct drbd_device *device, const char *text);
11238c2ecf20Sopenharmony_ciextern void drbd_queue_unplug(struct drbd_device *device);
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ciextern void conn_md_sync(struct drbd_connection *connection);
11268c2ecf20Sopenharmony_ciextern void drbd_md_write(struct drbd_device *device, void *buffer);
11278c2ecf20Sopenharmony_ciextern void drbd_md_sync(struct drbd_device *device);
11288c2ecf20Sopenharmony_ciextern int  drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev);
11298c2ecf20Sopenharmony_ciextern void drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
11308c2ecf20Sopenharmony_ciextern void _drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
11318c2ecf20Sopenharmony_ciextern void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local);
11328c2ecf20Sopenharmony_ciextern void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local);
11338c2ecf20Sopenharmony_ciextern void drbd_uuid_move_history(struct drbd_device *device) __must_hold(local);
11348c2ecf20Sopenharmony_ciextern void __drbd_uuid_set(struct drbd_device *device, int idx, u64 val) __must_hold(local);
11358c2ecf20Sopenharmony_ciextern void drbd_md_set_flag(struct drbd_device *device, int flags) __must_hold(local);
11368c2ecf20Sopenharmony_ciextern void drbd_md_clear_flag(struct drbd_device *device, int flags)__must_hold(local);
11378c2ecf20Sopenharmony_ciextern int drbd_md_test_flag(struct drbd_backing_dev *, int);
11388c2ecf20Sopenharmony_ciextern void drbd_md_mark_dirty(struct drbd_device *device);
11398c2ecf20Sopenharmony_ciextern void drbd_queue_bitmap_io(struct drbd_device *device,
11408c2ecf20Sopenharmony_ci				 int (*io_fn)(struct drbd_device *),
11418c2ecf20Sopenharmony_ci				 void (*done)(struct drbd_device *, int),
11428c2ecf20Sopenharmony_ci				 char *why, enum bm_flag flags);
11438c2ecf20Sopenharmony_ciextern int drbd_bitmap_io(struct drbd_device *device,
11448c2ecf20Sopenharmony_ci		int (*io_fn)(struct drbd_device *),
11458c2ecf20Sopenharmony_ci		char *why, enum bm_flag flags);
11468c2ecf20Sopenharmony_ciextern int drbd_bitmap_io_from_worker(struct drbd_device *device,
11478c2ecf20Sopenharmony_ci		int (*io_fn)(struct drbd_device *),
11488c2ecf20Sopenharmony_ci		char *why, enum bm_flag flags);
11498c2ecf20Sopenharmony_ciextern int drbd_bmio_set_n_write(struct drbd_device *device) __must_hold(local);
11508c2ecf20Sopenharmony_ciextern int drbd_bmio_clear_n_write(struct drbd_device *device) __must_hold(local);
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_ci/* Meta data layout
11538c2ecf20Sopenharmony_ci *
11548c2ecf20Sopenharmony_ci * We currently have two possible layouts.
11558c2ecf20Sopenharmony_ci * Offsets in (512 byte) sectors.
11568c2ecf20Sopenharmony_ci * external:
11578c2ecf20Sopenharmony_ci *   |----------- md_size_sect ------------------|
11588c2ecf20Sopenharmony_ci *   [ 4k superblock ][ activity log ][  Bitmap  ]
11598c2ecf20Sopenharmony_ci *   | al_offset == 8 |
11608c2ecf20Sopenharmony_ci *   | bm_offset = al_offset + X      |
11618c2ecf20Sopenharmony_ci *  ==> bitmap sectors = md_size_sect - bm_offset
11628c2ecf20Sopenharmony_ci *
11638c2ecf20Sopenharmony_ci *  Variants:
11648c2ecf20Sopenharmony_ci *     old, indexed fixed size meta data:
11658c2ecf20Sopenharmony_ci *
11668c2ecf20Sopenharmony_ci * internal:
11678c2ecf20Sopenharmony_ci *            |----------- md_size_sect ------------------|
11688c2ecf20Sopenharmony_ci * [data.....][  Bitmap  ][ activity log ][ 4k superblock ][padding*]
11698c2ecf20Sopenharmony_ci *                        | al_offset < 0 |
11708c2ecf20Sopenharmony_ci *            | bm_offset = al_offset - Y |
11718c2ecf20Sopenharmony_ci *  ==> bitmap sectors = Y = al_offset - bm_offset
11728c2ecf20Sopenharmony_ci *
11738c2ecf20Sopenharmony_ci *  [padding*] are zero or up to 7 unused 512 Byte sectors to the
11748c2ecf20Sopenharmony_ci *  end of the device, so that the [4k superblock] will be 4k aligned.
11758c2ecf20Sopenharmony_ci *
11768c2ecf20Sopenharmony_ci *  The activity log consists of 4k transaction blocks,
11778c2ecf20Sopenharmony_ci *  which are written in a ring-buffer, or striped ring-buffer like fashion,
11788c2ecf20Sopenharmony_ci *  which are writtensize used to be fixed 32kB,
11798c2ecf20Sopenharmony_ci *  but is about to become configurable.
11808c2ecf20Sopenharmony_ci */
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_ci/* Our old fixed size meta data layout
11838c2ecf20Sopenharmony_ci * allows up to about 3.8TB, so if you want more,
11848c2ecf20Sopenharmony_ci * you need to use the "flexible" meta data format. */
11858c2ecf20Sopenharmony_ci#define MD_128MB_SECT (128LLU << 11)  /* 128 MB, unit sectors */
11868c2ecf20Sopenharmony_ci#define MD_4kB_SECT	 8
11878c2ecf20Sopenharmony_ci#define MD_32kB_SECT	64
11888c2ecf20Sopenharmony_ci
11898c2ecf20Sopenharmony_ci/* One activity log extent represents 4M of storage */
11908c2ecf20Sopenharmony_ci#define AL_EXTENT_SHIFT 22
11918c2ecf20Sopenharmony_ci#define AL_EXTENT_SIZE (1<<AL_EXTENT_SHIFT)
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_ci/* We could make these currently hardcoded constants configurable
11948c2ecf20Sopenharmony_ci * variables at create-md time (or even re-configurable at runtime?).
11958c2ecf20Sopenharmony_ci * Which will require some more changes to the DRBD "super block"
11968c2ecf20Sopenharmony_ci * and attach code.
11978c2ecf20Sopenharmony_ci *
11988c2ecf20Sopenharmony_ci * updates per transaction:
11998c2ecf20Sopenharmony_ci *   This many changes to the active set can be logged with one transaction.
12008c2ecf20Sopenharmony_ci *   This number is arbitrary.
12018c2ecf20Sopenharmony_ci * context per transaction:
12028c2ecf20Sopenharmony_ci *   This many context extent numbers are logged with each transaction.
12038c2ecf20Sopenharmony_ci *   This number is resulting from the transaction block size (4k), the layout
12048c2ecf20Sopenharmony_ci *   of the transaction header, and the number of updates per transaction.
12058c2ecf20Sopenharmony_ci *   See drbd_actlog.c:struct al_transaction_on_disk
12068c2ecf20Sopenharmony_ci * */
12078c2ecf20Sopenharmony_ci#define AL_UPDATES_PER_TRANSACTION	 64	// arbitrary
12088c2ecf20Sopenharmony_ci#define AL_CONTEXT_PER_TRANSACTION	919	// (4096 - 36 - 6*64)/4
12098c2ecf20Sopenharmony_ci
12108c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 32
12118c2ecf20Sopenharmony_ci#define LN2_BPL 5
12128c2ecf20Sopenharmony_ci#define cpu_to_lel(A) cpu_to_le32(A)
12138c2ecf20Sopenharmony_ci#define lel_to_cpu(A) le32_to_cpu(A)
12148c2ecf20Sopenharmony_ci#elif BITS_PER_LONG == 64
12158c2ecf20Sopenharmony_ci#define LN2_BPL 6
12168c2ecf20Sopenharmony_ci#define cpu_to_lel(A) cpu_to_le64(A)
12178c2ecf20Sopenharmony_ci#define lel_to_cpu(A) le64_to_cpu(A)
12188c2ecf20Sopenharmony_ci#else
12198c2ecf20Sopenharmony_ci#error "LN2 of BITS_PER_LONG unknown!"
12208c2ecf20Sopenharmony_ci#endif
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_ci/* resync bitmap */
12238c2ecf20Sopenharmony_ci/* 16MB sized 'bitmap extent' to track syncer usage */
12248c2ecf20Sopenharmony_cistruct bm_extent {
12258c2ecf20Sopenharmony_ci	int rs_left; /* number of bits set (out of sync) in this extent. */
12268c2ecf20Sopenharmony_ci	int rs_failed; /* number of failed resync requests in this extent. */
12278c2ecf20Sopenharmony_ci	unsigned long flags;
12288c2ecf20Sopenharmony_ci	struct lc_element lce;
12298c2ecf20Sopenharmony_ci};
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci#define BME_NO_WRITES  0  /* bm_extent.flags: no more requests on this one! */
12328c2ecf20Sopenharmony_ci#define BME_LOCKED     1  /* bm_extent.flags: syncer active on this one. */
12338c2ecf20Sopenharmony_ci#define BME_PRIORITY   2  /* finish resync IO on this extent ASAP! App IO waiting! */
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_ci/* drbd_bitmap.c */
12368c2ecf20Sopenharmony_ci/*
12378c2ecf20Sopenharmony_ci * We need to store one bit for a block.
12388c2ecf20Sopenharmony_ci * Example: 1GB disk @ 4096 byte blocks ==> we need 32 KB bitmap.
12398c2ecf20Sopenharmony_ci * Bit 0 ==> local node thinks this block is binary identical on both nodes
12408c2ecf20Sopenharmony_ci * Bit 1 ==> local node thinks this block needs to be synced.
12418c2ecf20Sopenharmony_ci */
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ci#define SLEEP_TIME (HZ/10)
12448c2ecf20Sopenharmony_ci
12458c2ecf20Sopenharmony_ci/* We do bitmap IO in units of 4k blocks.
12468c2ecf20Sopenharmony_ci * We also still have a hardcoded 4k per bit relation. */
12478c2ecf20Sopenharmony_ci#define BM_BLOCK_SHIFT	12			 /* 4k per bit */
12488c2ecf20Sopenharmony_ci#define BM_BLOCK_SIZE	 (1<<BM_BLOCK_SHIFT)
12498c2ecf20Sopenharmony_ci/* mostly arbitrarily set the represented size of one bitmap extent,
12508c2ecf20Sopenharmony_ci * aka resync extent, to 16 MiB (which is also 512 Byte worth of bitmap
12518c2ecf20Sopenharmony_ci * at 4k per bit resolution) */
12528c2ecf20Sopenharmony_ci#define BM_EXT_SHIFT	 24	/* 16 MiB per resync extent */
12538c2ecf20Sopenharmony_ci#define BM_EXT_SIZE	 (1<<BM_EXT_SHIFT)
12548c2ecf20Sopenharmony_ci
12558c2ecf20Sopenharmony_ci#if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12)
12568c2ecf20Sopenharmony_ci#error "HAVE YOU FIXED drbdmeta AS WELL??"
12578c2ecf20Sopenharmony_ci#endif
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_ci/* thus many _storage_ sectors are described by one bit */
12608c2ecf20Sopenharmony_ci#define BM_SECT_TO_BIT(x)   ((x)>>(BM_BLOCK_SHIFT-9))
12618c2ecf20Sopenharmony_ci#define BM_BIT_TO_SECT(x)   ((sector_t)(x)<<(BM_BLOCK_SHIFT-9))
12628c2ecf20Sopenharmony_ci#define BM_SECT_PER_BIT     BM_BIT_TO_SECT(1)
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci/* bit to represented kilo byte conversion */
12658c2ecf20Sopenharmony_ci#define Bit2KB(bits) ((bits)<<(BM_BLOCK_SHIFT-10))
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci/* in which _bitmap_ extent (resp. sector) the bit for a certain
12688c2ecf20Sopenharmony_ci * _storage_ sector is located in */
12698c2ecf20Sopenharmony_ci#define BM_SECT_TO_EXT(x)   ((x)>>(BM_EXT_SHIFT-9))
12708c2ecf20Sopenharmony_ci#define BM_BIT_TO_EXT(x)    ((x) >> (BM_EXT_SHIFT - BM_BLOCK_SHIFT))
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_ci/* first storage sector a bitmap extent corresponds to */
12738c2ecf20Sopenharmony_ci#define BM_EXT_TO_SECT(x)   ((sector_t)(x) << (BM_EXT_SHIFT-9))
12748c2ecf20Sopenharmony_ci/* how much _storage_ sectors we have per bitmap extent */
12758c2ecf20Sopenharmony_ci#define BM_SECT_PER_EXT     BM_EXT_TO_SECT(1)
12768c2ecf20Sopenharmony_ci/* how many bits are covered by one bitmap extent (resync extent) */
12778c2ecf20Sopenharmony_ci#define BM_BITS_PER_EXT     (1UL << (BM_EXT_SHIFT - BM_BLOCK_SHIFT))
12788c2ecf20Sopenharmony_ci
12798c2ecf20Sopenharmony_ci#define BM_BLOCKS_PER_BM_EXT_MASK  (BM_BITS_PER_EXT - 1)
12808c2ecf20Sopenharmony_ci
12818c2ecf20Sopenharmony_ci
12828c2ecf20Sopenharmony_ci/* in one sector of the bitmap, we have this many activity_log extents. */
12838c2ecf20Sopenharmony_ci#define AL_EXT_PER_BM_SECT  (1 << (BM_EXT_SHIFT - AL_EXTENT_SHIFT))
12848c2ecf20Sopenharmony_ci
12858c2ecf20Sopenharmony_ci/* the extent in "PER_EXTENT" below is an activity log extent
12868c2ecf20Sopenharmony_ci * we need that many (long words/bytes) to store the bitmap
12878c2ecf20Sopenharmony_ci *		     of one AL_EXTENT_SIZE chunk of storage.
12888c2ecf20Sopenharmony_ci * we can store the bitmap for that many AL_EXTENTS within
12898c2ecf20Sopenharmony_ci * one sector of the _on_disk_ bitmap:
12908c2ecf20Sopenharmony_ci * bit	 0	  bit 37   bit 38	     bit (512*8)-1
12918c2ecf20Sopenharmony_ci *	     ...|........|........|.. // ..|........|
12928c2ecf20Sopenharmony_ci * sect. 0	 `296	  `304			   ^(512*8*8)-1
12938c2ecf20Sopenharmony_ci *
12948c2ecf20Sopenharmony_ci#define BM_WORDS_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / BITS_PER_LONG )
12958c2ecf20Sopenharmony_ci#define BM_BYTES_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / 8 )  // 128
12968c2ecf20Sopenharmony_ci#define BM_EXT_PER_SECT	    ( 512 / BM_BYTES_PER_EXTENT )	 //   4
12978c2ecf20Sopenharmony_ci */
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci#define DRBD_MAX_SECTORS_32 (0xffffffffLU)
13008c2ecf20Sopenharmony_ci/* we have a certain meta data variant that has a fixed on-disk size of 128
13018c2ecf20Sopenharmony_ci * MiB, of which 4k are our "superblock", and 32k are the fixed size activity
13028c2ecf20Sopenharmony_ci * log, leaving this many sectors for the bitmap.
13038c2ecf20Sopenharmony_ci */
13048c2ecf20Sopenharmony_ci
13058c2ecf20Sopenharmony_ci#define DRBD_MAX_SECTORS_FIXED_BM \
13068c2ecf20Sopenharmony_ci	  ((MD_128MB_SECT - MD_32kB_SECT - MD_4kB_SECT) * (1LL<<(BM_EXT_SHIFT-9)))
13078c2ecf20Sopenharmony_ci#define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_FIXED_BM
13088c2ecf20Sopenharmony_ci/* 16 TB in units of sectors */
13098c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 32
13108c2ecf20Sopenharmony_ci/* adjust by one page worth of bitmap,
13118c2ecf20Sopenharmony_ci * so we won't wrap around in drbd_bm_find_next_bit.
13128c2ecf20Sopenharmony_ci * you should use 64bit OS for that much storage, anyways. */
13138c2ecf20Sopenharmony_ci#define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff)
13148c2ecf20Sopenharmony_ci#else
13158c2ecf20Sopenharmony_ci/* we allow up to 1 PiB now on 64bit architecture with "flexible" meta data */
13168c2ecf20Sopenharmony_ci#define DRBD_MAX_SECTORS_FLEX (1UL << 51)
13178c2ecf20Sopenharmony_ci/* corresponds to (1UL << 38) bits right now. */
13188c2ecf20Sopenharmony_ci#endif
13198c2ecf20Sopenharmony_ci
13208c2ecf20Sopenharmony_ci/* Estimate max bio size as 256 * PAGE_SIZE,
13218c2ecf20Sopenharmony_ci * so for typical PAGE_SIZE of 4k, that is (1<<20) Byte.
13228c2ecf20Sopenharmony_ci * Since we may live in a mixed-platform cluster,
13238c2ecf20Sopenharmony_ci * we limit us to a platform agnostic constant here for now.
13248c2ecf20Sopenharmony_ci * A followup commit may allow even bigger BIO sizes,
13258c2ecf20Sopenharmony_ci * once we thought that through. */
13268c2ecf20Sopenharmony_ci#define DRBD_MAX_BIO_SIZE (1U << 20)
13278c2ecf20Sopenharmony_ci#if DRBD_MAX_BIO_SIZE > (BIO_MAX_PAGES << PAGE_SHIFT)
13288c2ecf20Sopenharmony_ci#error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE
13298c2ecf20Sopenharmony_ci#endif
13308c2ecf20Sopenharmony_ci#define DRBD_MAX_BIO_SIZE_SAFE (1U << 12)       /* Works always = 4k */
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci#define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* Header 80 only allows packets up to 32KiB data */
13338c2ecf20Sopenharmony_ci#define DRBD_MAX_BIO_SIZE_P95    (1U << 17) /* Protocol 95 to 99 allows bios up to 128KiB */
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci/* For now, don't allow more than half of what we can "activate" in one
13368c2ecf20Sopenharmony_ci * activity log transaction to be discarded in one go. We may need to rework
13378c2ecf20Sopenharmony_ci * drbd_al_begin_io() to allow for even larger discard ranges */
13388c2ecf20Sopenharmony_ci#define DRBD_MAX_BATCH_BIO_SIZE	 (AL_UPDATES_PER_TRANSACTION/2*AL_EXTENT_SIZE)
13398c2ecf20Sopenharmony_ci#define DRBD_MAX_BBIO_SECTORS    (DRBD_MAX_BATCH_BIO_SIZE >> 9)
13408c2ecf20Sopenharmony_ci
13418c2ecf20Sopenharmony_ciextern int  drbd_bm_init(struct drbd_device *device);
13428c2ecf20Sopenharmony_ciextern int  drbd_bm_resize(struct drbd_device *device, sector_t sectors, int set_new_bits);
13438c2ecf20Sopenharmony_ciextern void drbd_bm_cleanup(struct drbd_device *device);
13448c2ecf20Sopenharmony_ciextern void drbd_bm_set_all(struct drbd_device *device);
13458c2ecf20Sopenharmony_ciextern void drbd_bm_clear_all(struct drbd_device *device);
13468c2ecf20Sopenharmony_ci/* set/clear/test only a few bits at a time */
13478c2ecf20Sopenharmony_ciextern int  drbd_bm_set_bits(
13488c2ecf20Sopenharmony_ci		struct drbd_device *device, unsigned long s, unsigned long e);
13498c2ecf20Sopenharmony_ciextern int  drbd_bm_clear_bits(
13508c2ecf20Sopenharmony_ci		struct drbd_device *device, unsigned long s, unsigned long e);
13518c2ecf20Sopenharmony_ciextern int drbd_bm_count_bits(
13528c2ecf20Sopenharmony_ci	struct drbd_device *device, const unsigned long s, const unsigned long e);
13538c2ecf20Sopenharmony_ci/* bm_set_bits variant for use while holding drbd_bm_lock,
13548c2ecf20Sopenharmony_ci * may process the whole bitmap in one go */
13558c2ecf20Sopenharmony_ciextern void _drbd_bm_set_bits(struct drbd_device *device,
13568c2ecf20Sopenharmony_ci		const unsigned long s, const unsigned long e);
13578c2ecf20Sopenharmony_ciextern int  drbd_bm_test_bit(struct drbd_device *device, unsigned long bitnr);
13588c2ecf20Sopenharmony_ciextern int  drbd_bm_e_weight(struct drbd_device *device, unsigned long enr);
13598c2ecf20Sopenharmony_ciextern int  drbd_bm_read(struct drbd_device *device) __must_hold(local);
13608c2ecf20Sopenharmony_ciextern void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr);
13618c2ecf20Sopenharmony_ciextern int  drbd_bm_write(struct drbd_device *device) __must_hold(local);
13628c2ecf20Sopenharmony_ciextern void drbd_bm_reset_al_hints(struct drbd_device *device) __must_hold(local);
13638c2ecf20Sopenharmony_ciextern int  drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local);
13648c2ecf20Sopenharmony_ciextern int  drbd_bm_write_lazy(struct drbd_device *device, unsigned upper_idx) __must_hold(local);
13658c2ecf20Sopenharmony_ciextern int drbd_bm_write_all(struct drbd_device *device) __must_hold(local);
13668c2ecf20Sopenharmony_ciextern int  drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local);
13678c2ecf20Sopenharmony_ciextern size_t	     drbd_bm_words(struct drbd_device *device);
13688c2ecf20Sopenharmony_ciextern unsigned long drbd_bm_bits(struct drbd_device *device);
13698c2ecf20Sopenharmony_ciextern sector_t      drbd_bm_capacity(struct drbd_device *device);
13708c2ecf20Sopenharmony_ci
13718c2ecf20Sopenharmony_ci#define DRBD_END_OF_BITMAP	(~(unsigned long)0)
13728c2ecf20Sopenharmony_ciextern unsigned long drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
13738c2ecf20Sopenharmony_ci/* bm_find_next variants for use while you hold drbd_bm_lock() */
13748c2ecf20Sopenharmony_ciextern unsigned long _drbd_bm_find_next(struct drbd_device *device, unsigned long bm_fo);
13758c2ecf20Sopenharmony_ciextern unsigned long _drbd_bm_find_next_zero(struct drbd_device *device, unsigned long bm_fo);
13768c2ecf20Sopenharmony_ciextern unsigned long _drbd_bm_total_weight(struct drbd_device *device);
13778c2ecf20Sopenharmony_ciextern unsigned long drbd_bm_total_weight(struct drbd_device *device);
13788c2ecf20Sopenharmony_ci/* for receive_bitmap */
13798c2ecf20Sopenharmony_ciextern void drbd_bm_merge_lel(struct drbd_device *device, size_t offset,
13808c2ecf20Sopenharmony_ci		size_t number, unsigned long *buffer);
13818c2ecf20Sopenharmony_ci/* for _drbd_send_bitmap */
13828c2ecf20Sopenharmony_ciextern void drbd_bm_get_lel(struct drbd_device *device, size_t offset,
13838c2ecf20Sopenharmony_ci		size_t number, unsigned long *buffer);
13848c2ecf20Sopenharmony_ci
13858c2ecf20Sopenharmony_ciextern void drbd_bm_lock(struct drbd_device *device, char *why, enum bm_flag flags);
13868c2ecf20Sopenharmony_ciextern void drbd_bm_unlock(struct drbd_device *device);
13878c2ecf20Sopenharmony_ci/* drbd_main.c */
13888c2ecf20Sopenharmony_ci
13898c2ecf20Sopenharmony_ciextern struct kmem_cache *drbd_request_cache;
13908c2ecf20Sopenharmony_ciextern struct kmem_cache *drbd_ee_cache;	/* peer requests */
13918c2ecf20Sopenharmony_ciextern struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
13928c2ecf20Sopenharmony_ciextern struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
13938c2ecf20Sopenharmony_ciextern mempool_t drbd_request_mempool;
13948c2ecf20Sopenharmony_ciextern mempool_t drbd_ee_mempool;
13958c2ecf20Sopenharmony_ci
13968c2ecf20Sopenharmony_ci/* drbd's page pool, used to buffer data received from the peer,
13978c2ecf20Sopenharmony_ci * or data requested by the peer.
13988c2ecf20Sopenharmony_ci *
13998c2ecf20Sopenharmony_ci * This does not have an emergency reserve.
14008c2ecf20Sopenharmony_ci *
14018c2ecf20Sopenharmony_ci * When allocating from this pool, it first takes pages from the pool.
14028c2ecf20Sopenharmony_ci * Only if the pool is depleted will try to allocate from the system.
14038c2ecf20Sopenharmony_ci *
14048c2ecf20Sopenharmony_ci * The assumption is that pages taken from this pool will be processed,
14058c2ecf20Sopenharmony_ci * and given back, "quickly", and then can be recycled, so we can avoid
14068c2ecf20Sopenharmony_ci * frequent calls to alloc_page(), and still will be able to make progress even
14078c2ecf20Sopenharmony_ci * under memory pressure.
14088c2ecf20Sopenharmony_ci */
14098c2ecf20Sopenharmony_ciextern struct page *drbd_pp_pool;
14108c2ecf20Sopenharmony_ciextern spinlock_t   drbd_pp_lock;
14118c2ecf20Sopenharmony_ciextern int	    drbd_pp_vacant;
14128c2ecf20Sopenharmony_ciextern wait_queue_head_t drbd_pp_wait;
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci/* We also need a standard (emergency-reserve backed) page pool
14158c2ecf20Sopenharmony_ci * for meta data IO (activity log, bitmap).
14168c2ecf20Sopenharmony_ci * We can keep it global, as long as it is used as "N pages at a time".
14178c2ecf20Sopenharmony_ci * 128 should be plenty, currently we probably can get away with as few as 1.
14188c2ecf20Sopenharmony_ci */
14198c2ecf20Sopenharmony_ci#define DRBD_MIN_POOL_PAGES	128
14208c2ecf20Sopenharmony_ciextern mempool_t drbd_md_io_page_pool;
14218c2ecf20Sopenharmony_ci
14228c2ecf20Sopenharmony_ci/* We also need to make sure we get a bio
14238c2ecf20Sopenharmony_ci * when we need it for housekeeping purposes */
14248c2ecf20Sopenharmony_ciextern struct bio_set drbd_md_io_bio_set;
14258c2ecf20Sopenharmony_ci/* to allocate from that set */
14268c2ecf20Sopenharmony_ciextern struct bio *bio_alloc_drbd(gfp_t gfp_mask);
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci/* And a bio_set for cloning */
14298c2ecf20Sopenharmony_ciextern struct bio_set drbd_io_bio_set;
14308c2ecf20Sopenharmony_ci
14318c2ecf20Sopenharmony_ciextern struct mutex resources_mutex;
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ciextern int conn_lowest_minor(struct drbd_connection *connection);
14348c2ecf20Sopenharmony_ciextern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor);
14358c2ecf20Sopenharmony_ciextern void drbd_destroy_device(struct kref *kref);
14368c2ecf20Sopenharmony_ciextern void drbd_delete_device(struct drbd_device *device);
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ciextern struct drbd_resource *drbd_create_resource(const char *name);
14398c2ecf20Sopenharmony_ciextern void drbd_free_resource(struct drbd_resource *resource);
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ciextern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts);
14428c2ecf20Sopenharmony_ciextern struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts);
14438c2ecf20Sopenharmony_ciextern void drbd_destroy_connection(struct kref *kref);
14448c2ecf20Sopenharmony_ciextern struct drbd_connection *conn_get_by_addrs(void *my_addr, int my_addr_len,
14458c2ecf20Sopenharmony_ci					    void *peer_addr, int peer_addr_len);
14468c2ecf20Sopenharmony_ciextern struct drbd_resource *drbd_find_resource(const char *name);
14478c2ecf20Sopenharmony_ciextern void drbd_destroy_resource(struct kref *kref);
14488c2ecf20Sopenharmony_ciextern void conn_free_crypto(struct drbd_connection *connection);
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci/* drbd_req */
14518c2ecf20Sopenharmony_ciextern void do_submit(struct work_struct *ws);
14528c2ecf20Sopenharmony_ciextern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
14538c2ecf20Sopenharmony_ciextern blk_qc_t drbd_submit_bio(struct bio *bio);
14548c2ecf20Sopenharmony_ciextern int drbd_read_remote(struct drbd_device *device, struct drbd_request *req);
14558c2ecf20Sopenharmony_ciextern int is_valid_ar_handle(struct drbd_request *, sector_t);
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci/* drbd_nl.c */
14598c2ecf20Sopenharmony_ci
14608c2ecf20Sopenharmony_ciextern struct mutex notification_mutex;
14618c2ecf20Sopenharmony_ci
14628c2ecf20Sopenharmony_ciextern void drbd_suspend_io(struct drbd_device *device);
14638c2ecf20Sopenharmony_ciextern void drbd_resume_io(struct drbd_device *device);
14648c2ecf20Sopenharmony_ciextern char *ppsize(char *buf, unsigned long long size);
14658c2ecf20Sopenharmony_ciextern sector_t drbd_new_dev_size(struct drbd_device *, struct drbd_backing_dev *, sector_t, int);
14668c2ecf20Sopenharmony_cienum determine_dev_size {
14678c2ecf20Sopenharmony_ci	DS_ERROR_SHRINK = -3,
14688c2ecf20Sopenharmony_ci	DS_ERROR_SPACE_MD = -2,
14698c2ecf20Sopenharmony_ci	DS_ERROR = -1,
14708c2ecf20Sopenharmony_ci	DS_UNCHANGED = 0,
14718c2ecf20Sopenharmony_ci	DS_SHRUNK = 1,
14728c2ecf20Sopenharmony_ci	DS_GREW = 2,
14738c2ecf20Sopenharmony_ci	DS_GREW_FROM_ZERO = 3,
14748c2ecf20Sopenharmony_ci};
14758c2ecf20Sopenharmony_ciextern enum determine_dev_size
14768c2ecf20Sopenharmony_cidrbd_determine_dev_size(struct drbd_device *, enum dds_flags, struct resize_parms *) __must_hold(local);
14778c2ecf20Sopenharmony_ciextern void resync_after_online_grow(struct drbd_device *);
14788c2ecf20Sopenharmony_ciextern void drbd_reconsider_queue_parameters(struct drbd_device *device,
14798c2ecf20Sopenharmony_ci			struct drbd_backing_dev *bdev, struct o_qlim *o);
14808c2ecf20Sopenharmony_ciextern enum drbd_state_rv drbd_set_role(struct drbd_device *device,
14818c2ecf20Sopenharmony_ci					enum drbd_role new_role,
14828c2ecf20Sopenharmony_ci					int force);
14838c2ecf20Sopenharmony_ciextern bool conn_try_outdate_peer(struct drbd_connection *connection);
14848c2ecf20Sopenharmony_ciextern void conn_try_outdate_peer_async(struct drbd_connection *connection);
14858c2ecf20Sopenharmony_ciextern enum drbd_peer_state conn_khelper(struct drbd_connection *connection, char *cmd);
14868c2ecf20Sopenharmony_ciextern int drbd_khelper(struct drbd_device *device, char *cmd);
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_ci/* drbd_worker.c */
14898c2ecf20Sopenharmony_ci/* bi_end_io handlers */
14908c2ecf20Sopenharmony_ciextern void drbd_md_endio(struct bio *bio);
14918c2ecf20Sopenharmony_ciextern void drbd_peer_request_endio(struct bio *bio);
14928c2ecf20Sopenharmony_ciextern void drbd_request_endio(struct bio *bio);
14938c2ecf20Sopenharmony_ciextern int drbd_worker(struct drbd_thread *thi);
14948c2ecf20Sopenharmony_cienum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
14958c2ecf20Sopenharmony_civoid drbd_resync_after_changed(struct drbd_device *device);
14968c2ecf20Sopenharmony_ciextern void drbd_start_resync(struct drbd_device *device, enum drbd_conns side);
14978c2ecf20Sopenharmony_ciextern void resume_next_sg(struct drbd_device *device);
14988c2ecf20Sopenharmony_ciextern void suspend_other_sg(struct drbd_device *device);
14998c2ecf20Sopenharmony_ciextern int drbd_resync_finished(struct drbd_device *device);
15008c2ecf20Sopenharmony_ci/* maybe rather drbd_main.c ? */
15018c2ecf20Sopenharmony_ciextern void *drbd_md_get_buffer(struct drbd_device *device, const char *intent);
15028c2ecf20Sopenharmony_ciextern void drbd_md_put_buffer(struct drbd_device *device);
15038c2ecf20Sopenharmony_ciextern int drbd_md_sync_page_io(struct drbd_device *device,
15048c2ecf20Sopenharmony_ci		struct drbd_backing_dev *bdev, sector_t sector, int op);
15058c2ecf20Sopenharmony_ciextern void drbd_ov_out_of_sync_found(struct drbd_device *, sector_t, int);
15068c2ecf20Sopenharmony_ciextern void wait_until_done_or_force_detached(struct drbd_device *device,
15078c2ecf20Sopenharmony_ci		struct drbd_backing_dev *bdev, unsigned int *done);
15088c2ecf20Sopenharmony_ciextern void drbd_rs_controller_reset(struct drbd_device *device);
15098c2ecf20Sopenharmony_ci
15108c2ecf20Sopenharmony_cistatic inline void ov_out_of_sync_print(struct drbd_device *device)
15118c2ecf20Sopenharmony_ci{
15128c2ecf20Sopenharmony_ci	if (device->ov_last_oos_size) {
15138c2ecf20Sopenharmony_ci		drbd_err(device, "Out of sync: start=%llu, size=%lu (sectors)\n",
15148c2ecf20Sopenharmony_ci		     (unsigned long long)device->ov_last_oos_start,
15158c2ecf20Sopenharmony_ci		     (unsigned long)device->ov_last_oos_size);
15168c2ecf20Sopenharmony_ci	}
15178c2ecf20Sopenharmony_ci	device->ov_last_oos_size = 0;
15188c2ecf20Sopenharmony_ci}
15198c2ecf20Sopenharmony_ci
15208c2ecf20Sopenharmony_ci
15218c2ecf20Sopenharmony_ciextern void drbd_csum_bio(struct crypto_shash *, struct bio *, void *);
15228c2ecf20Sopenharmony_ciextern void drbd_csum_ee(struct crypto_shash *, struct drbd_peer_request *,
15238c2ecf20Sopenharmony_ci			 void *);
15248c2ecf20Sopenharmony_ci/* worker callbacks */
15258c2ecf20Sopenharmony_ciextern int w_e_end_data_req(struct drbd_work *, int);
15268c2ecf20Sopenharmony_ciextern int w_e_end_rsdata_req(struct drbd_work *, int);
15278c2ecf20Sopenharmony_ciextern int w_e_end_csum_rs_req(struct drbd_work *, int);
15288c2ecf20Sopenharmony_ciextern int w_e_end_ov_reply(struct drbd_work *, int);
15298c2ecf20Sopenharmony_ciextern int w_e_end_ov_req(struct drbd_work *, int);
15308c2ecf20Sopenharmony_ciextern int w_ov_finished(struct drbd_work *, int);
15318c2ecf20Sopenharmony_ciextern int w_resync_timer(struct drbd_work *, int);
15328c2ecf20Sopenharmony_ciextern int w_send_write_hint(struct drbd_work *, int);
15338c2ecf20Sopenharmony_ciextern int w_send_dblock(struct drbd_work *, int);
15348c2ecf20Sopenharmony_ciextern int w_send_read_req(struct drbd_work *, int);
15358c2ecf20Sopenharmony_ciextern int w_e_reissue(struct drbd_work *, int);
15368c2ecf20Sopenharmony_ciextern int w_restart_disk_io(struct drbd_work *, int);
15378c2ecf20Sopenharmony_ciextern int w_send_out_of_sync(struct drbd_work *, int);
15388c2ecf20Sopenharmony_ciextern int w_start_resync(struct drbd_work *, int);
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ciextern void resync_timer_fn(struct timer_list *t);
15418c2ecf20Sopenharmony_ciextern void start_resync_timer_fn(struct timer_list *t);
15428c2ecf20Sopenharmony_ci
15438c2ecf20Sopenharmony_ciextern void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req);
15448c2ecf20Sopenharmony_ci
15458c2ecf20Sopenharmony_ci/* drbd_receiver.c */
15468c2ecf20Sopenharmony_ciextern int drbd_issue_discard_or_zero_out(struct drbd_device *device,
15478c2ecf20Sopenharmony_ci		sector_t start, unsigned int nr_sectors, int flags);
15488c2ecf20Sopenharmony_ciextern int drbd_receiver(struct drbd_thread *thi);
15498c2ecf20Sopenharmony_ciextern int drbd_ack_receiver(struct drbd_thread *thi);
15508c2ecf20Sopenharmony_ciextern void drbd_send_ping_wf(struct work_struct *ws);
15518c2ecf20Sopenharmony_ciextern void drbd_send_acks_wf(struct work_struct *ws);
15528c2ecf20Sopenharmony_ciextern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device);
15538c2ecf20Sopenharmony_ciextern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector,
15548c2ecf20Sopenharmony_ci		bool throttle_if_app_is_waiting);
15558c2ecf20Sopenharmony_ciextern int drbd_submit_peer_request(struct drbd_device *,
15568c2ecf20Sopenharmony_ci				    struct drbd_peer_request *, const unsigned,
15578c2ecf20Sopenharmony_ci				    const unsigned, const int);
15588c2ecf20Sopenharmony_ciextern int drbd_free_peer_reqs(struct drbd_device *, struct list_head *);
15598c2ecf20Sopenharmony_ciextern struct drbd_peer_request *drbd_alloc_peer_req(struct drbd_peer_device *, u64,
15608c2ecf20Sopenharmony_ci						     sector_t, unsigned int,
15618c2ecf20Sopenharmony_ci						     unsigned int,
15628c2ecf20Sopenharmony_ci						     gfp_t) __must_hold(local);
15638c2ecf20Sopenharmony_ciextern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request *,
15648c2ecf20Sopenharmony_ci				 int);
15658c2ecf20Sopenharmony_ci#define drbd_free_peer_req(m,e) __drbd_free_peer_req(m, e, 0)
15668c2ecf20Sopenharmony_ci#define drbd_free_net_peer_req(m,e) __drbd_free_peer_req(m, e, 1)
15678c2ecf20Sopenharmony_ciextern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool);
15688c2ecf20Sopenharmony_ciextern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
15698c2ecf20Sopenharmony_ciextern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
15708c2ecf20Sopenharmony_ciextern int drbd_connected(struct drbd_peer_device *);
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_ci/* sets the number of 512 byte sectors of our virtual device */
15738c2ecf20Sopenharmony_civoid drbd_set_my_capacity(struct drbd_device *device, sector_t size);
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci/*
15768c2ecf20Sopenharmony_ci * used to submit our private bio
15778c2ecf20Sopenharmony_ci */
15788c2ecf20Sopenharmony_cistatic inline void drbd_submit_bio_noacct(struct drbd_device *device,
15798c2ecf20Sopenharmony_ci					     int fault_type, struct bio *bio)
15808c2ecf20Sopenharmony_ci{
15818c2ecf20Sopenharmony_ci	__release(local);
15828c2ecf20Sopenharmony_ci	if (!bio->bi_disk) {
15838c2ecf20Sopenharmony_ci		drbd_err(device, "drbd_submit_bio_noacct: bio->bi_disk == NULL\n");
15848c2ecf20Sopenharmony_ci		bio->bi_status = BLK_STS_IOERR;
15858c2ecf20Sopenharmony_ci		bio_endio(bio);
15868c2ecf20Sopenharmony_ci		return;
15878c2ecf20Sopenharmony_ci	}
15888c2ecf20Sopenharmony_ci
15898c2ecf20Sopenharmony_ci	if (drbd_insert_fault(device, fault_type))
15908c2ecf20Sopenharmony_ci		bio_io_error(bio);
15918c2ecf20Sopenharmony_ci	else
15928c2ecf20Sopenharmony_ci		submit_bio_noacct(bio);
15938c2ecf20Sopenharmony_ci}
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_civoid drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backing_dev *bdev,
15968c2ecf20Sopenharmony_ci			      enum write_ordering_e wo);
15978c2ecf20Sopenharmony_ci
15988c2ecf20Sopenharmony_ci/* drbd_proc.c */
15998c2ecf20Sopenharmony_ciextern struct proc_dir_entry *drbd_proc;
16008c2ecf20Sopenharmony_ciint drbd_seq_show(struct seq_file *seq, void *v);
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_ci/* drbd_actlog.c */
16038c2ecf20Sopenharmony_ciextern bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *i);
16048c2ecf20Sopenharmony_ciextern int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i);
16058c2ecf20Sopenharmony_ciextern void drbd_al_begin_io_commit(struct drbd_device *device);
16068c2ecf20Sopenharmony_ciextern bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i);
16078c2ecf20Sopenharmony_ciextern void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i);
16088c2ecf20Sopenharmony_ciextern void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i);
16098c2ecf20Sopenharmony_ciextern void drbd_rs_complete_io(struct drbd_device *device, sector_t sector);
16108c2ecf20Sopenharmony_ciextern int drbd_rs_begin_io(struct drbd_device *device, sector_t sector);
16118c2ecf20Sopenharmony_ciextern int drbd_try_rs_begin_io(struct drbd_device *device, sector_t sector);
16128c2ecf20Sopenharmony_ciextern void drbd_rs_cancel_all(struct drbd_device *device);
16138c2ecf20Sopenharmony_ciextern int drbd_rs_del_all(struct drbd_device *device);
16148c2ecf20Sopenharmony_ciextern void drbd_rs_failed_io(struct drbd_device *device,
16158c2ecf20Sopenharmony_ci		sector_t sector, int size);
16168c2ecf20Sopenharmony_ciextern void drbd_advance_rs_marks(struct drbd_device *device, unsigned long still_to_go);
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_cienum update_sync_bits_mode { RECORD_RS_FAILED, SET_OUT_OF_SYNC, SET_IN_SYNC };
16198c2ecf20Sopenharmony_ciextern int __drbd_change_sync(struct drbd_device *device, sector_t sector, int size,
16208c2ecf20Sopenharmony_ci		enum update_sync_bits_mode mode);
16218c2ecf20Sopenharmony_ci#define drbd_set_in_sync(device, sector, size) \
16228c2ecf20Sopenharmony_ci	__drbd_change_sync(device, sector, size, SET_IN_SYNC)
16238c2ecf20Sopenharmony_ci#define drbd_set_out_of_sync(device, sector, size) \
16248c2ecf20Sopenharmony_ci	__drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC)
16258c2ecf20Sopenharmony_ci#define drbd_rs_failed_io(device, sector, size) \
16268c2ecf20Sopenharmony_ci	__drbd_change_sync(device, sector, size, RECORD_RS_FAILED)
16278c2ecf20Sopenharmony_ciextern void drbd_al_shrink(struct drbd_device *device);
16288c2ecf20Sopenharmony_ciextern int drbd_al_initialize(struct drbd_device *, void *);
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci/* drbd_nl.c */
16318c2ecf20Sopenharmony_ci/* state info broadcast */
16328c2ecf20Sopenharmony_cistruct sib_info {
16338c2ecf20Sopenharmony_ci	enum drbd_state_info_bcast_reason sib_reason;
16348c2ecf20Sopenharmony_ci	union {
16358c2ecf20Sopenharmony_ci		struct {
16368c2ecf20Sopenharmony_ci			char *helper_name;
16378c2ecf20Sopenharmony_ci			unsigned helper_exit_code;
16388c2ecf20Sopenharmony_ci		};
16398c2ecf20Sopenharmony_ci		struct {
16408c2ecf20Sopenharmony_ci			union drbd_state os;
16418c2ecf20Sopenharmony_ci			union drbd_state ns;
16428c2ecf20Sopenharmony_ci		};
16438c2ecf20Sopenharmony_ci	};
16448c2ecf20Sopenharmony_ci};
16458c2ecf20Sopenharmony_civoid drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
16468c2ecf20Sopenharmony_ci
16478c2ecf20Sopenharmony_ciextern int notify_resource_state(struct sk_buff *,
16488c2ecf20Sopenharmony_ci				  unsigned int,
16498c2ecf20Sopenharmony_ci				  struct drbd_resource *,
16508c2ecf20Sopenharmony_ci				  struct resource_info *,
16518c2ecf20Sopenharmony_ci				  enum drbd_notification_type);
16528c2ecf20Sopenharmony_ciextern int notify_device_state(struct sk_buff *,
16538c2ecf20Sopenharmony_ci				unsigned int,
16548c2ecf20Sopenharmony_ci				struct drbd_device *,
16558c2ecf20Sopenharmony_ci				struct device_info *,
16568c2ecf20Sopenharmony_ci				enum drbd_notification_type);
16578c2ecf20Sopenharmony_ciextern int notify_connection_state(struct sk_buff *,
16588c2ecf20Sopenharmony_ci				    unsigned int,
16598c2ecf20Sopenharmony_ci				    struct drbd_connection *,
16608c2ecf20Sopenharmony_ci				    struct connection_info *,
16618c2ecf20Sopenharmony_ci				    enum drbd_notification_type);
16628c2ecf20Sopenharmony_ciextern int notify_peer_device_state(struct sk_buff *,
16638c2ecf20Sopenharmony_ci				     unsigned int,
16648c2ecf20Sopenharmony_ci				     struct drbd_peer_device *,
16658c2ecf20Sopenharmony_ci				     struct peer_device_info *,
16668c2ecf20Sopenharmony_ci				     enum drbd_notification_type);
16678c2ecf20Sopenharmony_ciextern void notify_helper(enum drbd_notification_type, struct drbd_device *,
16688c2ecf20Sopenharmony_ci			  struct drbd_connection *, const char *, int);
16698c2ecf20Sopenharmony_ci
16708c2ecf20Sopenharmony_ci/*
16718c2ecf20Sopenharmony_ci * inline helper functions
16728c2ecf20Sopenharmony_ci *************************/
16738c2ecf20Sopenharmony_ci
16748c2ecf20Sopenharmony_ci/* see also page_chain_add and friends in drbd_receiver.c */
16758c2ecf20Sopenharmony_cistatic inline struct page *page_chain_next(struct page *page)
16768c2ecf20Sopenharmony_ci{
16778c2ecf20Sopenharmony_ci	return (struct page *)page_private(page);
16788c2ecf20Sopenharmony_ci}
16798c2ecf20Sopenharmony_ci#define page_chain_for_each(page) \
16808c2ecf20Sopenharmony_ci	for (; page && ({ prefetch(page_chain_next(page)); 1; }); \
16818c2ecf20Sopenharmony_ci			page = page_chain_next(page))
16828c2ecf20Sopenharmony_ci#define page_chain_for_each_safe(page, n) \
16838c2ecf20Sopenharmony_ci	for (; page && ({ n = page_chain_next(page); 1; }); page = n)
16848c2ecf20Sopenharmony_ci
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_cistatic inline int drbd_peer_req_has_active_page(struct drbd_peer_request *peer_req)
16878c2ecf20Sopenharmony_ci{
16888c2ecf20Sopenharmony_ci	struct page *page = peer_req->pages;
16898c2ecf20Sopenharmony_ci	page_chain_for_each(page) {
16908c2ecf20Sopenharmony_ci		if (page_count(page) > 1)
16918c2ecf20Sopenharmony_ci			return 1;
16928c2ecf20Sopenharmony_ci	}
16938c2ecf20Sopenharmony_ci	return 0;
16948c2ecf20Sopenharmony_ci}
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_cistatic inline union drbd_state drbd_read_state(struct drbd_device *device)
16978c2ecf20Sopenharmony_ci{
16988c2ecf20Sopenharmony_ci	struct drbd_resource *resource = device->resource;
16998c2ecf20Sopenharmony_ci	union drbd_state rv;
17008c2ecf20Sopenharmony_ci
17018c2ecf20Sopenharmony_ci	rv.i = device->state.i;
17028c2ecf20Sopenharmony_ci	rv.susp = resource->susp;
17038c2ecf20Sopenharmony_ci	rv.susp_nod = resource->susp_nod;
17048c2ecf20Sopenharmony_ci	rv.susp_fen = resource->susp_fen;
17058c2ecf20Sopenharmony_ci
17068c2ecf20Sopenharmony_ci	return rv;
17078c2ecf20Sopenharmony_ci}
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_cienum drbd_force_detach_flags {
17108c2ecf20Sopenharmony_ci	DRBD_READ_ERROR,
17118c2ecf20Sopenharmony_ci	DRBD_WRITE_ERROR,
17128c2ecf20Sopenharmony_ci	DRBD_META_IO_ERROR,
17138c2ecf20Sopenharmony_ci	DRBD_FORCE_DETACH,
17148c2ecf20Sopenharmony_ci};
17158c2ecf20Sopenharmony_ci
17168c2ecf20Sopenharmony_ci#define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
17178c2ecf20Sopenharmony_cistatic inline void __drbd_chk_io_error_(struct drbd_device *device,
17188c2ecf20Sopenharmony_ci		enum drbd_force_detach_flags df,
17198c2ecf20Sopenharmony_ci		const char *where)
17208c2ecf20Sopenharmony_ci{
17218c2ecf20Sopenharmony_ci	enum drbd_io_error_p ep;
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci	rcu_read_lock();
17248c2ecf20Sopenharmony_ci	ep = rcu_dereference(device->ldev->disk_conf)->on_io_error;
17258c2ecf20Sopenharmony_ci	rcu_read_unlock();
17268c2ecf20Sopenharmony_ci	switch (ep) {
17278c2ecf20Sopenharmony_ci	case EP_PASS_ON: /* FIXME would this be better named "Ignore"? */
17288c2ecf20Sopenharmony_ci		if (df == DRBD_READ_ERROR || df == DRBD_WRITE_ERROR) {
17298c2ecf20Sopenharmony_ci			if (__ratelimit(&drbd_ratelimit_state))
17308c2ecf20Sopenharmony_ci				drbd_err(device, "Local IO failed in %s.\n", where);
17318c2ecf20Sopenharmony_ci			if (device->state.disk > D_INCONSISTENT)
17328c2ecf20Sopenharmony_ci				_drbd_set_state(_NS(device, disk, D_INCONSISTENT), CS_HARD, NULL);
17338c2ecf20Sopenharmony_ci			break;
17348c2ecf20Sopenharmony_ci		}
17358c2ecf20Sopenharmony_ci		fallthrough;	/* for DRBD_META_IO_ERROR or DRBD_FORCE_DETACH */
17368c2ecf20Sopenharmony_ci	case EP_DETACH:
17378c2ecf20Sopenharmony_ci	case EP_CALL_HELPER:
17388c2ecf20Sopenharmony_ci		/* Remember whether we saw a READ or WRITE error.
17398c2ecf20Sopenharmony_ci		 *
17408c2ecf20Sopenharmony_ci		 * Recovery of the affected area for WRITE failure is covered
17418c2ecf20Sopenharmony_ci		 * by the activity log.
17428c2ecf20Sopenharmony_ci		 * READ errors may fall outside that area though. Certain READ
17438c2ecf20Sopenharmony_ci		 * errors can be "healed" by writing good data to the affected
17448c2ecf20Sopenharmony_ci		 * blocks, which triggers block re-allocation in lower layers.
17458c2ecf20Sopenharmony_ci		 *
17468c2ecf20Sopenharmony_ci		 * If we can not write the bitmap after a READ error,
17478c2ecf20Sopenharmony_ci		 * we may need to trigger a full sync (see w_go_diskless()).
17488c2ecf20Sopenharmony_ci		 *
17498c2ecf20Sopenharmony_ci		 * Force-detach is not really an IO error, but rather a
17508c2ecf20Sopenharmony_ci		 * desperate measure to try to deal with a completely
17518c2ecf20Sopenharmony_ci		 * unresponsive lower level IO stack.
17528c2ecf20Sopenharmony_ci		 * Still it should be treated as a WRITE error.
17538c2ecf20Sopenharmony_ci		 *
17548c2ecf20Sopenharmony_ci		 * Meta IO error is always WRITE error:
17558c2ecf20Sopenharmony_ci		 * we read meta data only once during attach,
17568c2ecf20Sopenharmony_ci		 * which will fail in case of errors.
17578c2ecf20Sopenharmony_ci		 */
17588c2ecf20Sopenharmony_ci		set_bit(WAS_IO_ERROR, &device->flags);
17598c2ecf20Sopenharmony_ci		if (df == DRBD_READ_ERROR)
17608c2ecf20Sopenharmony_ci			set_bit(WAS_READ_ERROR, &device->flags);
17618c2ecf20Sopenharmony_ci		if (df == DRBD_FORCE_DETACH)
17628c2ecf20Sopenharmony_ci			set_bit(FORCE_DETACH, &device->flags);
17638c2ecf20Sopenharmony_ci		if (device->state.disk > D_FAILED) {
17648c2ecf20Sopenharmony_ci			_drbd_set_state(_NS(device, disk, D_FAILED), CS_HARD, NULL);
17658c2ecf20Sopenharmony_ci			drbd_err(device,
17668c2ecf20Sopenharmony_ci				"Local IO failed in %s. Detaching...\n", where);
17678c2ecf20Sopenharmony_ci		}
17688c2ecf20Sopenharmony_ci		break;
17698c2ecf20Sopenharmony_ci	}
17708c2ecf20Sopenharmony_ci}
17718c2ecf20Sopenharmony_ci
17728c2ecf20Sopenharmony_ci/**
17738c2ecf20Sopenharmony_ci * drbd_chk_io_error: Handle the on_io_error setting, should be called from all io completion handlers
17748c2ecf20Sopenharmony_ci * @device:	 DRBD device.
17758c2ecf20Sopenharmony_ci * @error:	 Error code passed to the IO completion callback
17768c2ecf20Sopenharmony_ci * @forcedetach: Force detach. I.e. the error happened while accessing the meta data
17778c2ecf20Sopenharmony_ci *
17788c2ecf20Sopenharmony_ci * See also drbd_main.c:after_state_ch() if (os.disk > D_FAILED && ns.disk == D_FAILED)
17798c2ecf20Sopenharmony_ci */
17808c2ecf20Sopenharmony_ci#define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__)
17818c2ecf20Sopenharmony_cistatic inline void drbd_chk_io_error_(struct drbd_device *device,
17828c2ecf20Sopenharmony_ci	int error, enum drbd_force_detach_flags forcedetach, const char *where)
17838c2ecf20Sopenharmony_ci{
17848c2ecf20Sopenharmony_ci	if (error) {
17858c2ecf20Sopenharmony_ci		unsigned long flags;
17868c2ecf20Sopenharmony_ci		spin_lock_irqsave(&device->resource->req_lock, flags);
17878c2ecf20Sopenharmony_ci		__drbd_chk_io_error_(device, forcedetach, where);
17888c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&device->resource->req_lock, flags);
17898c2ecf20Sopenharmony_ci	}
17908c2ecf20Sopenharmony_ci}
17918c2ecf20Sopenharmony_ci
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_ci/**
17948c2ecf20Sopenharmony_ci * drbd_md_first_sector() - Returns the first sector number of the meta data area
17958c2ecf20Sopenharmony_ci * @bdev:	Meta data block device.
17968c2ecf20Sopenharmony_ci *
17978c2ecf20Sopenharmony_ci * BTW, for internal meta data, this happens to be the maximum capacity
17988c2ecf20Sopenharmony_ci * we could agree upon with our peer node.
17998c2ecf20Sopenharmony_ci */
18008c2ecf20Sopenharmony_cistatic inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
18018c2ecf20Sopenharmony_ci{
18028c2ecf20Sopenharmony_ci	switch (bdev->md.meta_dev_idx) {
18038c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_INTERNAL:
18048c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_INT:
18058c2ecf20Sopenharmony_ci		return bdev->md.md_offset + bdev->md.bm_offset;
18068c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_EXT:
18078c2ecf20Sopenharmony_ci	default:
18088c2ecf20Sopenharmony_ci		return bdev->md.md_offset;
18098c2ecf20Sopenharmony_ci	}
18108c2ecf20Sopenharmony_ci}
18118c2ecf20Sopenharmony_ci
18128c2ecf20Sopenharmony_ci/**
18138c2ecf20Sopenharmony_ci * drbd_md_last_sector() - Return the last sector number of the meta data area
18148c2ecf20Sopenharmony_ci * @bdev:	Meta data block device.
18158c2ecf20Sopenharmony_ci */
18168c2ecf20Sopenharmony_cistatic inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
18178c2ecf20Sopenharmony_ci{
18188c2ecf20Sopenharmony_ci	switch (bdev->md.meta_dev_idx) {
18198c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_INTERNAL:
18208c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_INT:
18218c2ecf20Sopenharmony_ci		return bdev->md.md_offset + MD_4kB_SECT -1;
18228c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_EXT:
18238c2ecf20Sopenharmony_ci	default:
18248c2ecf20Sopenharmony_ci		return bdev->md.md_offset + bdev->md.md_size_sect -1;
18258c2ecf20Sopenharmony_ci	}
18268c2ecf20Sopenharmony_ci}
18278c2ecf20Sopenharmony_ci
18288c2ecf20Sopenharmony_ci/* Returns the number of 512 byte sectors of the device */
18298c2ecf20Sopenharmony_cistatic inline sector_t drbd_get_capacity(struct block_device *bdev)
18308c2ecf20Sopenharmony_ci{
18318c2ecf20Sopenharmony_ci	/* return bdev ? get_capacity(bdev->bd_disk) : 0; */
18328c2ecf20Sopenharmony_ci	return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0;
18338c2ecf20Sopenharmony_ci}
18348c2ecf20Sopenharmony_ci
18358c2ecf20Sopenharmony_ci/**
18368c2ecf20Sopenharmony_ci * drbd_get_max_capacity() - Returns the capacity we announce to out peer
18378c2ecf20Sopenharmony_ci * @bdev:	Meta data block device.
18388c2ecf20Sopenharmony_ci *
18398c2ecf20Sopenharmony_ci * returns the capacity we announce to out peer.  we clip ourselves at the
18408c2ecf20Sopenharmony_ci * various MAX_SECTORS, because if we don't, current implementation will
18418c2ecf20Sopenharmony_ci * oops sooner or later
18428c2ecf20Sopenharmony_ci */
18438c2ecf20Sopenharmony_cistatic inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
18448c2ecf20Sopenharmony_ci{
18458c2ecf20Sopenharmony_ci	sector_t s;
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci	switch (bdev->md.meta_dev_idx) {
18488c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_INTERNAL:
18498c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_INT:
18508c2ecf20Sopenharmony_ci		s = drbd_get_capacity(bdev->backing_bdev)
18518c2ecf20Sopenharmony_ci			? min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
18528c2ecf20Sopenharmony_ci				drbd_md_first_sector(bdev))
18538c2ecf20Sopenharmony_ci			: 0;
18548c2ecf20Sopenharmony_ci		break;
18558c2ecf20Sopenharmony_ci	case DRBD_MD_INDEX_FLEX_EXT:
18568c2ecf20Sopenharmony_ci		s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
18578c2ecf20Sopenharmony_ci				drbd_get_capacity(bdev->backing_bdev));
18588c2ecf20Sopenharmony_ci		/* clip at maximum size the meta device can support */
18598c2ecf20Sopenharmony_ci		s = min_t(sector_t, s,
18608c2ecf20Sopenharmony_ci			BM_EXT_TO_SECT(bdev->md.md_size_sect
18618c2ecf20Sopenharmony_ci				     - bdev->md.bm_offset));
18628c2ecf20Sopenharmony_ci		break;
18638c2ecf20Sopenharmony_ci	default:
18648c2ecf20Sopenharmony_ci		s = min_t(sector_t, DRBD_MAX_SECTORS,
18658c2ecf20Sopenharmony_ci				drbd_get_capacity(bdev->backing_bdev));
18668c2ecf20Sopenharmony_ci	}
18678c2ecf20Sopenharmony_ci	return s;
18688c2ecf20Sopenharmony_ci}
18698c2ecf20Sopenharmony_ci
18708c2ecf20Sopenharmony_ci/**
18718c2ecf20Sopenharmony_ci * drbd_md_ss() - Return the sector number of our meta data super block
18728c2ecf20Sopenharmony_ci * @bdev:	Meta data block device.
18738c2ecf20Sopenharmony_ci */
18748c2ecf20Sopenharmony_cistatic inline sector_t drbd_md_ss(struct drbd_backing_dev *bdev)
18758c2ecf20Sopenharmony_ci{
18768c2ecf20Sopenharmony_ci	const int meta_dev_idx = bdev->md.meta_dev_idx;
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci	if (meta_dev_idx == DRBD_MD_INDEX_FLEX_EXT)
18798c2ecf20Sopenharmony_ci		return 0;
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci	/* Since drbd08, internal meta data is always "flexible".
18828c2ecf20Sopenharmony_ci	 * position: last 4k aligned block of 4k size */
18838c2ecf20Sopenharmony_ci	if (meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
18848c2ecf20Sopenharmony_ci	    meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)
18858c2ecf20Sopenharmony_ci		return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) - 8;
18868c2ecf20Sopenharmony_ci
18878c2ecf20Sopenharmony_ci	/* external, some index; this is the old fixed size layout */
18888c2ecf20Sopenharmony_ci	return MD_128MB_SECT * bdev->md.meta_dev_idx;
18898c2ecf20Sopenharmony_ci}
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_cistatic inline void
18928c2ecf20Sopenharmony_cidrbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
18938c2ecf20Sopenharmony_ci{
18948c2ecf20Sopenharmony_ci	unsigned long flags;
18958c2ecf20Sopenharmony_ci	spin_lock_irqsave(&q->q_lock, flags);
18968c2ecf20Sopenharmony_ci	list_add_tail(&w->list, &q->q);
18978c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&q->q_lock, flags);
18988c2ecf20Sopenharmony_ci	wake_up(&q->q_wait);
18998c2ecf20Sopenharmony_ci}
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_cistatic inline void
19028c2ecf20Sopenharmony_cidrbd_queue_work_if_unqueued(struct drbd_work_queue *q, struct drbd_work *w)
19038c2ecf20Sopenharmony_ci{
19048c2ecf20Sopenharmony_ci	unsigned long flags;
19058c2ecf20Sopenharmony_ci	spin_lock_irqsave(&q->q_lock, flags);
19068c2ecf20Sopenharmony_ci	if (list_empty_careful(&w->list))
19078c2ecf20Sopenharmony_ci		list_add_tail(&w->list, &q->q);
19088c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&q->q_lock, flags);
19098c2ecf20Sopenharmony_ci	wake_up(&q->q_wait);
19108c2ecf20Sopenharmony_ci}
19118c2ecf20Sopenharmony_ci
19128c2ecf20Sopenharmony_cistatic inline void
19138c2ecf20Sopenharmony_cidrbd_device_post_work(struct drbd_device *device, int work_bit)
19148c2ecf20Sopenharmony_ci{
19158c2ecf20Sopenharmony_ci	if (!test_and_set_bit(work_bit, &device->flags)) {
19168c2ecf20Sopenharmony_ci		struct drbd_connection *connection =
19178c2ecf20Sopenharmony_ci			first_peer_device(device)->connection;
19188c2ecf20Sopenharmony_ci		struct drbd_work_queue *q = &connection->sender_work;
19198c2ecf20Sopenharmony_ci		if (!test_and_set_bit(DEVICE_WORK_PENDING, &connection->flags))
19208c2ecf20Sopenharmony_ci			wake_up(&q->q_wait);
19218c2ecf20Sopenharmony_ci	}
19228c2ecf20Sopenharmony_ci}
19238c2ecf20Sopenharmony_ci
19248c2ecf20Sopenharmony_ciextern void drbd_flush_workqueue(struct drbd_work_queue *work_queue);
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci/* To get the ack_receiver out of the blocking network stack,
19278c2ecf20Sopenharmony_ci * so it can change its sk_rcvtimeo from idle- to ping-timeout,
19288c2ecf20Sopenharmony_ci * and send a ping, we need to send a signal.
19298c2ecf20Sopenharmony_ci * Which signal we send is irrelevant. */
19308c2ecf20Sopenharmony_cistatic inline void wake_ack_receiver(struct drbd_connection *connection)
19318c2ecf20Sopenharmony_ci{
19328c2ecf20Sopenharmony_ci	struct task_struct *task = connection->ack_receiver.task;
19338c2ecf20Sopenharmony_ci	if (task && get_t_state(&connection->ack_receiver) == RUNNING)
19348c2ecf20Sopenharmony_ci		send_sig(SIGXCPU, task, 1);
19358c2ecf20Sopenharmony_ci}
19368c2ecf20Sopenharmony_ci
19378c2ecf20Sopenharmony_cistatic inline void request_ping(struct drbd_connection *connection)
19388c2ecf20Sopenharmony_ci{
19398c2ecf20Sopenharmony_ci	set_bit(SEND_PING, &connection->flags);
19408c2ecf20Sopenharmony_ci	wake_ack_receiver(connection);
19418c2ecf20Sopenharmony_ci}
19428c2ecf20Sopenharmony_ci
19438c2ecf20Sopenharmony_ciextern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
19448c2ecf20Sopenharmony_ciextern void *drbd_prepare_command(struct drbd_peer_device *, struct drbd_socket *);
19458c2ecf20Sopenharmony_ciextern int conn_send_command(struct drbd_connection *, struct drbd_socket *,
19468c2ecf20Sopenharmony_ci			     enum drbd_packet, unsigned int, void *,
19478c2ecf20Sopenharmony_ci			     unsigned int);
19488c2ecf20Sopenharmony_ciextern int drbd_send_command(struct drbd_peer_device *, struct drbd_socket *,
19498c2ecf20Sopenharmony_ci			     enum drbd_packet, unsigned int, void *,
19508c2ecf20Sopenharmony_ci			     unsigned int);
19518c2ecf20Sopenharmony_ci
19528c2ecf20Sopenharmony_ciextern int drbd_send_ping(struct drbd_connection *connection);
19538c2ecf20Sopenharmony_ciextern int drbd_send_ping_ack(struct drbd_connection *connection);
19548c2ecf20Sopenharmony_ciextern int drbd_send_state_req(struct drbd_peer_device *, union drbd_state, union drbd_state);
19558c2ecf20Sopenharmony_ciextern int conn_send_state_req(struct drbd_connection *, union drbd_state, union drbd_state);
19568c2ecf20Sopenharmony_ci
19578c2ecf20Sopenharmony_cistatic inline void drbd_thread_stop(struct drbd_thread *thi)
19588c2ecf20Sopenharmony_ci{
19598c2ecf20Sopenharmony_ci	_drbd_thread_stop(thi, false, true);
19608c2ecf20Sopenharmony_ci}
19618c2ecf20Sopenharmony_ci
19628c2ecf20Sopenharmony_cistatic inline void drbd_thread_stop_nowait(struct drbd_thread *thi)
19638c2ecf20Sopenharmony_ci{
19648c2ecf20Sopenharmony_ci	_drbd_thread_stop(thi, false, false);
19658c2ecf20Sopenharmony_ci}
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_cistatic inline void drbd_thread_restart_nowait(struct drbd_thread *thi)
19688c2ecf20Sopenharmony_ci{
19698c2ecf20Sopenharmony_ci	_drbd_thread_stop(thi, true, false);
19708c2ecf20Sopenharmony_ci}
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ci/* counts how many answer packets packets we expect from our peer,
19738c2ecf20Sopenharmony_ci * for either explicit application requests,
19748c2ecf20Sopenharmony_ci * or implicit barrier packets as necessary.
19758c2ecf20Sopenharmony_ci * increased:
19768c2ecf20Sopenharmony_ci *  w_send_barrier
19778c2ecf20Sopenharmony_ci *  _req_mod(req, QUEUE_FOR_NET_WRITE or QUEUE_FOR_NET_READ);
19788c2ecf20Sopenharmony_ci *    it is much easier and equally valid to count what we queue for the
19798c2ecf20Sopenharmony_ci *    worker, even before it actually was queued or send.
19808c2ecf20Sopenharmony_ci *    (drbd_make_request_common; recovery path on read io-error)
19818c2ecf20Sopenharmony_ci * decreased:
19828c2ecf20Sopenharmony_ci *  got_BarrierAck (respective tl_clear, tl_clear_barrier)
19838c2ecf20Sopenharmony_ci *  _req_mod(req, DATA_RECEIVED)
19848c2ecf20Sopenharmony_ci *     [from receive_DataReply]
19858c2ecf20Sopenharmony_ci *  _req_mod(req, WRITE_ACKED_BY_PEER or RECV_ACKED_BY_PEER or NEG_ACKED)
19868c2ecf20Sopenharmony_ci *     [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)]
19878c2ecf20Sopenharmony_ci *     for some reason it is NOT decreased in got_NegAck,
19888c2ecf20Sopenharmony_ci *     but in the resulting cleanup code from report_params.
19898c2ecf20Sopenharmony_ci *     we should try to remember the reason for that...
19908c2ecf20Sopenharmony_ci *  _req_mod(req, SEND_FAILED or SEND_CANCELED)
19918c2ecf20Sopenharmony_ci *  _req_mod(req, CONNECTION_LOST_WHILE_PENDING)
19928c2ecf20Sopenharmony_ci *     [from tl_clear_barrier]
19938c2ecf20Sopenharmony_ci */
19948c2ecf20Sopenharmony_cistatic inline void inc_ap_pending(struct drbd_device *device)
19958c2ecf20Sopenharmony_ci{
19968c2ecf20Sopenharmony_ci	atomic_inc(&device->ap_pending_cnt);
19978c2ecf20Sopenharmony_ci}
19988c2ecf20Sopenharmony_ci
19998c2ecf20Sopenharmony_ci#define ERR_IF_CNT_IS_NEGATIVE(which, func, line)			\
20008c2ecf20Sopenharmony_ci	if (atomic_read(&device->which) < 0)				\
20018c2ecf20Sopenharmony_ci		drbd_err(device, "in %s:%d: " #which " = %d < 0 !\n",	\
20028c2ecf20Sopenharmony_ci			func, line,					\
20038c2ecf20Sopenharmony_ci			atomic_read(&device->which))
20048c2ecf20Sopenharmony_ci
20058c2ecf20Sopenharmony_ci#define dec_ap_pending(device) _dec_ap_pending(device, __func__, __LINE__)
20068c2ecf20Sopenharmony_cistatic inline void _dec_ap_pending(struct drbd_device *device, const char *func, int line)
20078c2ecf20Sopenharmony_ci{
20088c2ecf20Sopenharmony_ci	if (atomic_dec_and_test(&device->ap_pending_cnt))
20098c2ecf20Sopenharmony_ci		wake_up(&device->misc_wait);
20108c2ecf20Sopenharmony_ci	ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt, func, line);
20118c2ecf20Sopenharmony_ci}
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci/* counts how many resync-related answers we still expect from the peer
20148c2ecf20Sopenharmony_ci *		     increase			decrease
20158c2ecf20Sopenharmony_ci * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY)
20168c2ecf20Sopenharmony_ci * C_SYNC_SOURCE sends P_RS_DATA_REPLY   (and expects P_WRITE_ACK with ID_SYNCER)
20178c2ecf20Sopenharmony_ci *					   (or P_NEG_ACK with ID_SYNCER)
20188c2ecf20Sopenharmony_ci */
20198c2ecf20Sopenharmony_cistatic inline void inc_rs_pending(struct drbd_device *device)
20208c2ecf20Sopenharmony_ci{
20218c2ecf20Sopenharmony_ci	atomic_inc(&device->rs_pending_cnt);
20228c2ecf20Sopenharmony_ci}
20238c2ecf20Sopenharmony_ci
20248c2ecf20Sopenharmony_ci#define dec_rs_pending(device) _dec_rs_pending(device, __func__, __LINE__)
20258c2ecf20Sopenharmony_cistatic inline void _dec_rs_pending(struct drbd_device *device, const char *func, int line)
20268c2ecf20Sopenharmony_ci{
20278c2ecf20Sopenharmony_ci	atomic_dec(&device->rs_pending_cnt);
20288c2ecf20Sopenharmony_ci	ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt, func, line);
20298c2ecf20Sopenharmony_ci}
20308c2ecf20Sopenharmony_ci
20318c2ecf20Sopenharmony_ci/* counts how many answers we still need to send to the peer.
20328c2ecf20Sopenharmony_ci * increased on
20338c2ecf20Sopenharmony_ci *  receive_Data	unless protocol A;
20348c2ecf20Sopenharmony_ci *			we need to send a P_RECV_ACK (proto B)
20358c2ecf20Sopenharmony_ci *			or P_WRITE_ACK (proto C)
20368c2ecf20Sopenharmony_ci *  receive_RSDataReply (recv_resync_read) we need to send a P_WRITE_ACK
20378c2ecf20Sopenharmony_ci *  receive_DataRequest (receive_RSDataRequest) we need to send back P_DATA
20388c2ecf20Sopenharmony_ci *  receive_Barrier_*	we need to send a P_BARRIER_ACK
20398c2ecf20Sopenharmony_ci */
20408c2ecf20Sopenharmony_cistatic inline void inc_unacked(struct drbd_device *device)
20418c2ecf20Sopenharmony_ci{
20428c2ecf20Sopenharmony_ci	atomic_inc(&device->unacked_cnt);
20438c2ecf20Sopenharmony_ci}
20448c2ecf20Sopenharmony_ci
20458c2ecf20Sopenharmony_ci#define dec_unacked(device) _dec_unacked(device, __func__, __LINE__)
20468c2ecf20Sopenharmony_cistatic inline void _dec_unacked(struct drbd_device *device, const char *func, int line)
20478c2ecf20Sopenharmony_ci{
20488c2ecf20Sopenharmony_ci	atomic_dec(&device->unacked_cnt);
20498c2ecf20Sopenharmony_ci	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
20508c2ecf20Sopenharmony_ci}
20518c2ecf20Sopenharmony_ci
20528c2ecf20Sopenharmony_ci#define sub_unacked(device, n) _sub_unacked(device, n, __func__, __LINE__)
20538c2ecf20Sopenharmony_cistatic inline void _sub_unacked(struct drbd_device *device, int n, const char *func, int line)
20548c2ecf20Sopenharmony_ci{
20558c2ecf20Sopenharmony_ci	atomic_sub(n, &device->unacked_cnt);
20568c2ecf20Sopenharmony_ci	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line);
20578c2ecf20Sopenharmony_ci}
20588c2ecf20Sopenharmony_ci
20598c2ecf20Sopenharmony_cistatic inline bool is_sync_target_state(enum drbd_conns connection_state)
20608c2ecf20Sopenharmony_ci{
20618c2ecf20Sopenharmony_ci	return	connection_state == C_SYNC_TARGET ||
20628c2ecf20Sopenharmony_ci		connection_state == C_PAUSED_SYNC_T;
20638c2ecf20Sopenharmony_ci}
20648c2ecf20Sopenharmony_ci
20658c2ecf20Sopenharmony_cistatic inline bool is_sync_source_state(enum drbd_conns connection_state)
20668c2ecf20Sopenharmony_ci{
20678c2ecf20Sopenharmony_ci	return	connection_state == C_SYNC_SOURCE ||
20688c2ecf20Sopenharmony_ci		connection_state == C_PAUSED_SYNC_S;
20698c2ecf20Sopenharmony_ci}
20708c2ecf20Sopenharmony_ci
20718c2ecf20Sopenharmony_cistatic inline bool is_sync_state(enum drbd_conns connection_state)
20728c2ecf20Sopenharmony_ci{
20738c2ecf20Sopenharmony_ci	return	is_sync_source_state(connection_state) ||
20748c2ecf20Sopenharmony_ci		is_sync_target_state(connection_state);
20758c2ecf20Sopenharmony_ci}
20768c2ecf20Sopenharmony_ci
20778c2ecf20Sopenharmony_ci/**
20788c2ecf20Sopenharmony_ci * get_ldev() - Increase the ref count on device->ldev. Returns 0 if there is no ldev
20798c2ecf20Sopenharmony_ci * @_device:		DRBD device.
20808c2ecf20Sopenharmony_ci * @_min_state:		Minimum device state required for success.
20818c2ecf20Sopenharmony_ci *
20828c2ecf20Sopenharmony_ci * You have to call put_ldev() when finished working with device->ldev.
20838c2ecf20Sopenharmony_ci */
20848c2ecf20Sopenharmony_ci#define get_ldev_if_state(_device, _min_state)				\
20858c2ecf20Sopenharmony_ci	(_get_ldev_if_state((_device), (_min_state)) ?			\
20868c2ecf20Sopenharmony_ci	 ({ __acquire(x); true; }) : false)
20878c2ecf20Sopenharmony_ci#define get_ldev(_device) get_ldev_if_state(_device, D_INCONSISTENT)
20888c2ecf20Sopenharmony_ci
20898c2ecf20Sopenharmony_cistatic inline void put_ldev(struct drbd_device *device)
20908c2ecf20Sopenharmony_ci{
20918c2ecf20Sopenharmony_ci	enum drbd_disk_state disk_state = device->state.disk;
20928c2ecf20Sopenharmony_ci	/* We must check the state *before* the atomic_dec becomes visible,
20938c2ecf20Sopenharmony_ci	 * or we have a theoretical race where someone hitting zero,
20948c2ecf20Sopenharmony_ci	 * while state still D_FAILED, will then see D_DISKLESS in the
20958c2ecf20Sopenharmony_ci	 * condition below and calling into destroy, where he must not, yet. */
20968c2ecf20Sopenharmony_ci	int i = atomic_dec_return(&device->local_cnt);
20978c2ecf20Sopenharmony_ci
20988c2ecf20Sopenharmony_ci	/* This may be called from some endio handler,
20998c2ecf20Sopenharmony_ci	 * so we must not sleep here. */
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_ci	__release(local);
21028c2ecf20Sopenharmony_ci	D_ASSERT(device, i >= 0);
21038c2ecf20Sopenharmony_ci	if (i == 0) {
21048c2ecf20Sopenharmony_ci		if (disk_state == D_DISKLESS)
21058c2ecf20Sopenharmony_ci			/* even internal references gone, safe to destroy */
21068c2ecf20Sopenharmony_ci			drbd_device_post_work(device, DESTROY_DISK);
21078c2ecf20Sopenharmony_ci		if (disk_state == D_FAILED)
21088c2ecf20Sopenharmony_ci			/* all application IO references gone. */
21098c2ecf20Sopenharmony_ci			if (!test_and_set_bit(GOING_DISKLESS, &device->flags))
21108c2ecf20Sopenharmony_ci				drbd_device_post_work(device, GO_DISKLESS);
21118c2ecf20Sopenharmony_ci		wake_up(&device->misc_wait);
21128c2ecf20Sopenharmony_ci	}
21138c2ecf20Sopenharmony_ci}
21148c2ecf20Sopenharmony_ci
21158c2ecf20Sopenharmony_ci#ifndef __CHECKER__
21168c2ecf20Sopenharmony_cistatic inline int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins)
21178c2ecf20Sopenharmony_ci{
21188c2ecf20Sopenharmony_ci	int io_allowed;
21198c2ecf20Sopenharmony_ci
21208c2ecf20Sopenharmony_ci	/* never get a reference while D_DISKLESS */
21218c2ecf20Sopenharmony_ci	if (device->state.disk == D_DISKLESS)
21228c2ecf20Sopenharmony_ci		return 0;
21238c2ecf20Sopenharmony_ci
21248c2ecf20Sopenharmony_ci	atomic_inc(&device->local_cnt);
21258c2ecf20Sopenharmony_ci	io_allowed = (device->state.disk >= mins);
21268c2ecf20Sopenharmony_ci	if (!io_allowed)
21278c2ecf20Sopenharmony_ci		put_ldev(device);
21288c2ecf20Sopenharmony_ci	return io_allowed;
21298c2ecf20Sopenharmony_ci}
21308c2ecf20Sopenharmony_ci#else
21318c2ecf20Sopenharmony_ciextern int _get_ldev_if_state(struct drbd_device *device, enum drbd_disk_state mins);
21328c2ecf20Sopenharmony_ci#endif
21338c2ecf20Sopenharmony_ci
21348c2ecf20Sopenharmony_ci/* this throttles on-the-fly application requests
21358c2ecf20Sopenharmony_ci * according to max_buffers settings;
21368c2ecf20Sopenharmony_ci * maybe re-implement using semaphores? */
21378c2ecf20Sopenharmony_cistatic inline int drbd_get_max_buffers(struct drbd_device *device)
21388c2ecf20Sopenharmony_ci{
21398c2ecf20Sopenharmony_ci	struct net_conf *nc;
21408c2ecf20Sopenharmony_ci	int mxb;
21418c2ecf20Sopenharmony_ci
21428c2ecf20Sopenharmony_ci	rcu_read_lock();
21438c2ecf20Sopenharmony_ci	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
21448c2ecf20Sopenharmony_ci	mxb = nc ? nc->max_buffers : 1000000;  /* arbitrary limit on open requests */
21458c2ecf20Sopenharmony_ci	rcu_read_unlock();
21468c2ecf20Sopenharmony_ci
21478c2ecf20Sopenharmony_ci	return mxb;
21488c2ecf20Sopenharmony_ci}
21498c2ecf20Sopenharmony_ci
21508c2ecf20Sopenharmony_cistatic inline int drbd_state_is_stable(struct drbd_device *device)
21518c2ecf20Sopenharmony_ci{
21528c2ecf20Sopenharmony_ci	union drbd_dev_state s = device->state;
21538c2ecf20Sopenharmony_ci
21548c2ecf20Sopenharmony_ci	/* DO NOT add a default clause, we want the compiler to warn us
21558c2ecf20Sopenharmony_ci	 * for any newly introduced state we may have forgotten to add here */
21568c2ecf20Sopenharmony_ci
21578c2ecf20Sopenharmony_ci	switch ((enum drbd_conns)s.conn) {
21588c2ecf20Sopenharmony_ci	/* new io only accepted when there is no connection, ... */
21598c2ecf20Sopenharmony_ci	case C_STANDALONE:
21608c2ecf20Sopenharmony_ci	case C_WF_CONNECTION:
21618c2ecf20Sopenharmony_ci	/* ... or there is a well established connection. */
21628c2ecf20Sopenharmony_ci	case C_CONNECTED:
21638c2ecf20Sopenharmony_ci	case C_SYNC_SOURCE:
21648c2ecf20Sopenharmony_ci	case C_SYNC_TARGET:
21658c2ecf20Sopenharmony_ci	case C_VERIFY_S:
21668c2ecf20Sopenharmony_ci	case C_VERIFY_T:
21678c2ecf20Sopenharmony_ci	case C_PAUSED_SYNC_S:
21688c2ecf20Sopenharmony_ci	case C_PAUSED_SYNC_T:
21698c2ecf20Sopenharmony_ci	case C_AHEAD:
21708c2ecf20Sopenharmony_ci	case C_BEHIND:
21718c2ecf20Sopenharmony_ci		/* transitional states, IO allowed */
21728c2ecf20Sopenharmony_ci	case C_DISCONNECTING:
21738c2ecf20Sopenharmony_ci	case C_UNCONNECTED:
21748c2ecf20Sopenharmony_ci	case C_TIMEOUT:
21758c2ecf20Sopenharmony_ci	case C_BROKEN_PIPE:
21768c2ecf20Sopenharmony_ci	case C_NETWORK_FAILURE:
21778c2ecf20Sopenharmony_ci	case C_PROTOCOL_ERROR:
21788c2ecf20Sopenharmony_ci	case C_TEAR_DOWN:
21798c2ecf20Sopenharmony_ci	case C_WF_REPORT_PARAMS:
21808c2ecf20Sopenharmony_ci	case C_STARTING_SYNC_S:
21818c2ecf20Sopenharmony_ci	case C_STARTING_SYNC_T:
21828c2ecf20Sopenharmony_ci		break;
21838c2ecf20Sopenharmony_ci
21848c2ecf20Sopenharmony_ci		/* Allow IO in BM exchange states with new protocols */
21858c2ecf20Sopenharmony_ci	case C_WF_BITMAP_S:
21868c2ecf20Sopenharmony_ci		if (first_peer_device(device)->connection->agreed_pro_version < 96)
21878c2ecf20Sopenharmony_ci			return 0;
21888c2ecf20Sopenharmony_ci		break;
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_ci		/* no new io accepted in these states */
21918c2ecf20Sopenharmony_ci	case C_WF_BITMAP_T:
21928c2ecf20Sopenharmony_ci	case C_WF_SYNC_UUID:
21938c2ecf20Sopenharmony_ci	case C_MASK:
21948c2ecf20Sopenharmony_ci		/* not "stable" */
21958c2ecf20Sopenharmony_ci		return 0;
21968c2ecf20Sopenharmony_ci	}
21978c2ecf20Sopenharmony_ci
21988c2ecf20Sopenharmony_ci	switch ((enum drbd_disk_state)s.disk) {
21998c2ecf20Sopenharmony_ci	case D_DISKLESS:
22008c2ecf20Sopenharmony_ci	case D_INCONSISTENT:
22018c2ecf20Sopenharmony_ci	case D_OUTDATED:
22028c2ecf20Sopenharmony_ci	case D_CONSISTENT:
22038c2ecf20Sopenharmony_ci	case D_UP_TO_DATE:
22048c2ecf20Sopenharmony_ci	case D_FAILED:
22058c2ecf20Sopenharmony_ci		/* disk state is stable as well. */
22068c2ecf20Sopenharmony_ci		break;
22078c2ecf20Sopenharmony_ci
22088c2ecf20Sopenharmony_ci	/* no new io accepted during transitional states */
22098c2ecf20Sopenharmony_ci	case D_ATTACHING:
22108c2ecf20Sopenharmony_ci	case D_NEGOTIATING:
22118c2ecf20Sopenharmony_ci	case D_UNKNOWN:
22128c2ecf20Sopenharmony_ci	case D_MASK:
22138c2ecf20Sopenharmony_ci		/* not "stable" */
22148c2ecf20Sopenharmony_ci		return 0;
22158c2ecf20Sopenharmony_ci	}
22168c2ecf20Sopenharmony_ci
22178c2ecf20Sopenharmony_ci	return 1;
22188c2ecf20Sopenharmony_ci}
22198c2ecf20Sopenharmony_ci
22208c2ecf20Sopenharmony_cistatic inline int drbd_suspended(struct drbd_device *device)
22218c2ecf20Sopenharmony_ci{
22228c2ecf20Sopenharmony_ci	struct drbd_resource *resource = device->resource;
22238c2ecf20Sopenharmony_ci
22248c2ecf20Sopenharmony_ci	return resource->susp || resource->susp_fen || resource->susp_nod;
22258c2ecf20Sopenharmony_ci}
22268c2ecf20Sopenharmony_ci
22278c2ecf20Sopenharmony_cistatic inline bool may_inc_ap_bio(struct drbd_device *device)
22288c2ecf20Sopenharmony_ci{
22298c2ecf20Sopenharmony_ci	int mxb = drbd_get_max_buffers(device);
22308c2ecf20Sopenharmony_ci
22318c2ecf20Sopenharmony_ci	if (drbd_suspended(device))
22328c2ecf20Sopenharmony_ci		return false;
22338c2ecf20Sopenharmony_ci	if (atomic_read(&device->suspend_cnt))
22348c2ecf20Sopenharmony_ci		return false;
22358c2ecf20Sopenharmony_ci
22368c2ecf20Sopenharmony_ci	/* to avoid potential deadlock or bitmap corruption,
22378c2ecf20Sopenharmony_ci	 * in various places, we only allow new application io
22388c2ecf20Sopenharmony_ci	 * to start during "stable" states. */
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci	/* no new io accepted when attaching or detaching the disk */
22418c2ecf20Sopenharmony_ci	if (!drbd_state_is_stable(device))
22428c2ecf20Sopenharmony_ci		return false;
22438c2ecf20Sopenharmony_ci
22448c2ecf20Sopenharmony_ci	/* since some older kernels don't have atomic_add_unless,
22458c2ecf20Sopenharmony_ci	 * and we are within the spinlock anyways, we have this workaround.  */
22468c2ecf20Sopenharmony_ci	if (atomic_read(&device->ap_bio_cnt) > mxb)
22478c2ecf20Sopenharmony_ci		return false;
22488c2ecf20Sopenharmony_ci	if (test_bit(BITMAP_IO, &device->flags))
22498c2ecf20Sopenharmony_ci		return false;
22508c2ecf20Sopenharmony_ci	return true;
22518c2ecf20Sopenharmony_ci}
22528c2ecf20Sopenharmony_ci
22538c2ecf20Sopenharmony_cistatic inline bool inc_ap_bio_cond(struct drbd_device *device)
22548c2ecf20Sopenharmony_ci{
22558c2ecf20Sopenharmony_ci	bool rv = false;
22568c2ecf20Sopenharmony_ci
22578c2ecf20Sopenharmony_ci	spin_lock_irq(&device->resource->req_lock);
22588c2ecf20Sopenharmony_ci	rv = may_inc_ap_bio(device);
22598c2ecf20Sopenharmony_ci	if (rv)
22608c2ecf20Sopenharmony_ci		atomic_inc(&device->ap_bio_cnt);
22618c2ecf20Sopenharmony_ci	spin_unlock_irq(&device->resource->req_lock);
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_ci	return rv;
22648c2ecf20Sopenharmony_ci}
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_cistatic inline void inc_ap_bio(struct drbd_device *device)
22678c2ecf20Sopenharmony_ci{
22688c2ecf20Sopenharmony_ci	/* we wait here
22698c2ecf20Sopenharmony_ci	 *    as long as the device is suspended
22708c2ecf20Sopenharmony_ci	 *    until the bitmap is no longer on the fly during connection
22718c2ecf20Sopenharmony_ci	 *    handshake as long as we would exceed the max_buffer limit.
22728c2ecf20Sopenharmony_ci	 *
22738c2ecf20Sopenharmony_ci	 * to avoid races with the reconnect code,
22748c2ecf20Sopenharmony_ci	 * we need to atomic_inc within the spinlock. */
22758c2ecf20Sopenharmony_ci
22768c2ecf20Sopenharmony_ci	wait_event(device->misc_wait, inc_ap_bio_cond(device));
22778c2ecf20Sopenharmony_ci}
22788c2ecf20Sopenharmony_ci
22798c2ecf20Sopenharmony_cistatic inline void dec_ap_bio(struct drbd_device *device)
22808c2ecf20Sopenharmony_ci{
22818c2ecf20Sopenharmony_ci	int mxb = drbd_get_max_buffers(device);
22828c2ecf20Sopenharmony_ci	int ap_bio = atomic_dec_return(&device->ap_bio_cnt);
22838c2ecf20Sopenharmony_ci
22848c2ecf20Sopenharmony_ci	D_ASSERT(device, ap_bio >= 0);
22858c2ecf20Sopenharmony_ci
22868c2ecf20Sopenharmony_ci	if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) {
22878c2ecf20Sopenharmony_ci		if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
22888c2ecf20Sopenharmony_ci			drbd_queue_work(&first_peer_device(device)->
22898c2ecf20Sopenharmony_ci				connection->sender_work,
22908c2ecf20Sopenharmony_ci				&device->bm_io_work.w);
22918c2ecf20Sopenharmony_ci	}
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	/* this currently does wake_up for every dec_ap_bio!
22948c2ecf20Sopenharmony_ci	 * maybe rather introduce some type of hysteresis?
22958c2ecf20Sopenharmony_ci	 * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */
22968c2ecf20Sopenharmony_ci	if (ap_bio < mxb)
22978c2ecf20Sopenharmony_ci		wake_up(&device->misc_wait);
22988c2ecf20Sopenharmony_ci}
22998c2ecf20Sopenharmony_ci
23008c2ecf20Sopenharmony_cistatic inline bool verify_can_do_stop_sector(struct drbd_device *device)
23018c2ecf20Sopenharmony_ci{
23028c2ecf20Sopenharmony_ci	return first_peer_device(device)->connection->agreed_pro_version >= 97 &&
23038c2ecf20Sopenharmony_ci		first_peer_device(device)->connection->agreed_pro_version != 100;
23048c2ecf20Sopenharmony_ci}
23058c2ecf20Sopenharmony_ci
23068c2ecf20Sopenharmony_cistatic inline int drbd_set_ed_uuid(struct drbd_device *device, u64 val)
23078c2ecf20Sopenharmony_ci{
23088c2ecf20Sopenharmony_ci	int changed = device->ed_uuid != val;
23098c2ecf20Sopenharmony_ci	device->ed_uuid = val;
23108c2ecf20Sopenharmony_ci	return changed;
23118c2ecf20Sopenharmony_ci}
23128c2ecf20Sopenharmony_ci
23138c2ecf20Sopenharmony_cistatic inline int drbd_queue_order_type(struct drbd_device *device)
23148c2ecf20Sopenharmony_ci{
23158c2ecf20Sopenharmony_ci	/* sorry, we currently have no working implementation
23168c2ecf20Sopenharmony_ci	 * of distributed TCQ stuff */
23178c2ecf20Sopenharmony_ci#ifndef QUEUE_ORDERED_NONE
23188c2ecf20Sopenharmony_ci#define QUEUE_ORDERED_NONE 0
23198c2ecf20Sopenharmony_ci#endif
23208c2ecf20Sopenharmony_ci	return QUEUE_ORDERED_NONE;
23218c2ecf20Sopenharmony_ci}
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_cistatic inline struct drbd_connection *first_connection(struct drbd_resource *resource)
23248c2ecf20Sopenharmony_ci{
23258c2ecf20Sopenharmony_ci	return list_first_entry_or_null(&resource->connections,
23268c2ecf20Sopenharmony_ci				struct drbd_connection, connections);
23278c2ecf20Sopenharmony_ci}
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci#endif
2330