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