1b411b363SPhilipp Reisner /* 2b411b363SPhilipp Reisner drbd_int.h 3b411b363SPhilipp Reisner 4b411b363SPhilipp Reisner This file is part of DRBD by Philipp Reisner and Lars Ellenberg. 5b411b363SPhilipp Reisner 6b411b363SPhilipp Reisner Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. 7b411b363SPhilipp Reisner Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>. 8b411b363SPhilipp Reisner Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>. 9b411b363SPhilipp Reisner 10b411b363SPhilipp Reisner drbd is free software; you can redistribute it and/or modify 11b411b363SPhilipp Reisner it under the terms of the GNU General Public License as published by 12b411b363SPhilipp Reisner the Free Software Foundation; either version 2, or (at your option) 13b411b363SPhilipp Reisner any later version. 14b411b363SPhilipp Reisner 15b411b363SPhilipp Reisner drbd is distributed in the hope that it will be useful, 16b411b363SPhilipp Reisner but WITHOUT ANY WARRANTY; without even the implied warranty of 17b411b363SPhilipp Reisner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18b411b363SPhilipp Reisner GNU General Public License for more details. 19b411b363SPhilipp Reisner 20b411b363SPhilipp Reisner You should have received a copy of the GNU General Public License 21b411b363SPhilipp Reisner along with drbd; see the file COPYING. If not, write to 22b411b363SPhilipp Reisner the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23b411b363SPhilipp Reisner 24b411b363SPhilipp Reisner */ 25b411b363SPhilipp Reisner 26b411b363SPhilipp Reisner #ifndef _DRBD_INT_H 27b411b363SPhilipp Reisner #define _DRBD_INT_H 28b411b363SPhilipp Reisner 29b411b363SPhilipp Reisner #include <linux/compiler.h> 30b411b363SPhilipp Reisner #include <linux/types.h> 31b411b363SPhilipp Reisner #include <linux/version.h> 32b411b363SPhilipp Reisner #include <linux/list.h> 33b411b363SPhilipp Reisner #include <linux/sched.h> 34b411b363SPhilipp Reisner #include <linux/bitops.h> 35b411b363SPhilipp Reisner #include <linux/slab.h> 36b411b363SPhilipp Reisner #include <linux/crypto.h> 37132cc538SRandy Dunlap #include <linux/ratelimit.h> 38b411b363SPhilipp Reisner #include <linux/tcp.h> 39b411b363SPhilipp Reisner #include <linux/mutex.h> 40b411b363SPhilipp Reisner #include <linux/major.h> 41b411b363SPhilipp Reisner #include <linux/blkdev.h> 42b411b363SPhilipp Reisner #include <linux/genhd.h> 43062e879cSPhilipp Reisner #include <linux/idr.h> 44b411b363SPhilipp Reisner #include <net/tcp.h> 45b411b363SPhilipp Reisner #include <linux/lru_cache.h> 4670c71606SPaul Gortmaker #include <linux/prefetch.h> 473b98c0c2SLars Ellenberg #include <linux/drbd_genl_api.h> 48b8907339SPhilipp Reisner #include <linux/drbd.h> 49b8907339SPhilipp Reisner #include "drbd_state.h" 50b411b363SPhilipp Reisner 51b411b363SPhilipp Reisner #ifdef __CHECKER__ 52b411b363SPhilipp Reisner # define __protected_by(x) __attribute__((require_context(x,1,999,"rdwr"))) 53b411b363SPhilipp Reisner # define __protected_read_by(x) __attribute__((require_context(x,1,999,"read"))) 54b411b363SPhilipp Reisner # define __protected_write_by(x) __attribute__((require_context(x,1,999,"write"))) 55b411b363SPhilipp Reisner # define __must_hold(x) __attribute__((context(x,1,1), require_context(x,1,999,"call"))) 56b411b363SPhilipp Reisner #else 57b411b363SPhilipp Reisner # define __protected_by(x) 58b411b363SPhilipp Reisner # define __protected_read_by(x) 59b411b363SPhilipp Reisner # define __protected_write_by(x) 60b411b363SPhilipp Reisner # define __must_hold(x) 61b411b363SPhilipp Reisner #endif 62b411b363SPhilipp Reisner 63b411b363SPhilipp Reisner #define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0) 64b411b363SPhilipp Reisner 65b411b363SPhilipp Reisner /* module parameter, defined in drbd_main.c */ 66b411b363SPhilipp Reisner extern unsigned int minor_count; 67b411b363SPhilipp Reisner extern int disable_sendpage; 68b411b363SPhilipp Reisner extern int allow_oos; 69b411b363SPhilipp Reisner 70b411b363SPhilipp Reisner #ifdef CONFIG_DRBD_FAULT_INJECTION 71b411b363SPhilipp Reisner extern int enable_faults; 72b411b363SPhilipp Reisner extern int fault_rate; 73b411b363SPhilipp Reisner extern int fault_devs; 74b411b363SPhilipp Reisner #endif 75b411b363SPhilipp Reisner 76b411b363SPhilipp Reisner extern char usermode_helper[]; 77b411b363SPhilipp Reisner 78b411b363SPhilipp Reisner 79b411b363SPhilipp Reisner /* I don't remember why XCPU ... 80b411b363SPhilipp Reisner * This is used to wake the asender, 81b411b363SPhilipp Reisner * and to interrupt sending the sending task 82b411b363SPhilipp Reisner * on disconnect. 83b411b363SPhilipp Reisner */ 84b411b363SPhilipp Reisner #define DRBD_SIG SIGXCPU 85b411b363SPhilipp Reisner 86b411b363SPhilipp Reisner /* This is used to stop/restart our threads. 87b411b363SPhilipp Reisner * Cannot use SIGTERM nor SIGKILL, since these 88b411b363SPhilipp Reisner * are sent out by init on runlevel changes 89b411b363SPhilipp Reisner * I choose SIGHUP for now. 90b411b363SPhilipp Reisner */ 91b411b363SPhilipp Reisner #define DRBD_SIGKILL SIGHUP 92b411b363SPhilipp Reisner 93b411b363SPhilipp Reisner #define ID_IN_SYNC (4711ULL) 94b411b363SPhilipp Reisner #define ID_OUT_OF_SYNC (4712ULL) 95b411b363SPhilipp Reisner #define ID_SYNCER (-1ULL) 96579b57edSAndreas Gruenbacher 974a23f264SPhilipp Reisner #define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL) 98b411b363SPhilipp Reisner 99b411b363SPhilipp Reisner struct drbd_conf; 1002111438bSPhilipp Reisner struct drbd_tconn; 101b411b363SPhilipp Reisner 102b411b363SPhilipp Reisner 103b411b363SPhilipp Reisner /* to shorten dev_warn(DEV, "msg"); and relatives statements */ 104b411b363SPhilipp Reisner #define DEV (disk_to_dev(mdev->vdisk)) 105b411b363SPhilipp Reisner 10660ae4966SPhilipp Reisner #define conn_printk(LEVEL, TCONN, FMT, ARGS...) \ 10760ae4966SPhilipp Reisner printk(LEVEL "d-con %s: " FMT, TCONN->name , ## ARGS) 10860ae4966SPhilipp Reisner #define conn_alert(TCONN, FMT, ARGS...) conn_printk(KERN_ALERT, TCONN, FMT, ## ARGS) 10960ae4966SPhilipp Reisner #define conn_crit(TCONN, FMT, ARGS...) conn_printk(KERN_CRIT, TCONN, FMT, ## ARGS) 11060ae4966SPhilipp Reisner #define conn_err(TCONN, FMT, ARGS...) conn_printk(KERN_ERR, TCONN, FMT, ## ARGS) 11160ae4966SPhilipp Reisner #define conn_warn(TCONN, FMT, ARGS...) conn_printk(KERN_WARNING, TCONN, FMT, ## ARGS) 11260ae4966SPhilipp Reisner #define conn_notice(TCONN, FMT, ARGS...) conn_printk(KERN_NOTICE, TCONN, FMT, ## ARGS) 11360ae4966SPhilipp Reisner #define conn_info(TCONN, FMT, ARGS...) conn_printk(KERN_INFO, TCONN, FMT, ## ARGS) 11460ae4966SPhilipp Reisner #define conn_dbg(TCONN, FMT, ARGS...) conn_printk(KERN_DEBUG, TCONN, FMT, ## ARGS) 11560ae4966SPhilipp Reisner 116b411b363SPhilipp Reisner #define D_ASSERT(exp) if (!(exp)) \ 117b411b363SPhilipp Reisner dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) 118b411b363SPhilipp Reisner 119841ce241SAndreas Gruenbacher /** 120841ce241SAndreas Gruenbacher * expect - Make an assertion 121841ce241SAndreas Gruenbacher * 122841ce241SAndreas Gruenbacher * Unlike the assert macro, this macro returns a boolean result. 123841ce241SAndreas Gruenbacher */ 124841ce241SAndreas Gruenbacher #define expect(exp) ({ \ 125841ce241SAndreas Gruenbacher bool _bool = (exp); \ 126841ce241SAndreas Gruenbacher if (!_bool) \ 127841ce241SAndreas Gruenbacher dev_err(DEV, "ASSERTION %s FAILED in %s\n", \ 128841ce241SAndreas Gruenbacher #exp, __func__); \ 129841ce241SAndreas Gruenbacher _bool; \ 130841ce241SAndreas Gruenbacher }) 131b411b363SPhilipp Reisner 132b411b363SPhilipp Reisner /* Defines to control fault insertion */ 133b411b363SPhilipp Reisner enum { 134b411b363SPhilipp Reisner DRBD_FAULT_MD_WR = 0, /* meta data write */ 135b411b363SPhilipp Reisner DRBD_FAULT_MD_RD = 1, /* read */ 136b411b363SPhilipp Reisner DRBD_FAULT_RS_WR = 2, /* resync */ 137b411b363SPhilipp Reisner DRBD_FAULT_RS_RD = 3, 138b411b363SPhilipp Reisner DRBD_FAULT_DT_WR = 4, /* data */ 139b411b363SPhilipp Reisner DRBD_FAULT_DT_RD = 5, 140b411b363SPhilipp Reisner DRBD_FAULT_DT_RA = 6, /* data read ahead */ 141b411b363SPhilipp Reisner DRBD_FAULT_BM_ALLOC = 7, /* bitmap allocation */ 142b411b363SPhilipp Reisner DRBD_FAULT_AL_EE = 8, /* alloc ee */ 1436b4388acSPhilipp Reisner DRBD_FAULT_RECEIVE = 9, /* Changes some bytes upon receiving a [rs]data block */ 144b411b363SPhilipp Reisner 145b411b363SPhilipp Reisner DRBD_FAULT_MAX, 146b411b363SPhilipp Reisner }; 147b411b363SPhilipp Reisner 148b411b363SPhilipp Reisner extern unsigned int 149b411b363SPhilipp Reisner _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type); 1500cf9d27eSAndreas Gruenbacher 151b411b363SPhilipp Reisner static inline int 152b411b363SPhilipp Reisner drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) { 1530cf9d27eSAndreas Gruenbacher #ifdef CONFIG_DRBD_FAULT_INJECTION 154b411b363SPhilipp Reisner return fault_rate && 155b411b363SPhilipp Reisner (enable_faults & (1<<type)) && 156b411b363SPhilipp Reisner _drbd_insert_fault(mdev, type); 157b411b363SPhilipp Reisner #else 1580cf9d27eSAndreas Gruenbacher return 0; 159b411b363SPhilipp Reisner #endif 1600cf9d27eSAndreas Gruenbacher } 161b411b363SPhilipp Reisner 162b411b363SPhilipp Reisner /* integer division, round _UP_ to the next integer */ 163b411b363SPhilipp Reisner #define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0)) 164b411b363SPhilipp Reisner /* usual integer division */ 165b411b363SPhilipp Reisner #define div_floor(A, B) ((A)/(B)) 166b411b363SPhilipp Reisner 167b411b363SPhilipp Reisner /* drbd_meta-data.c (still in drbd_main.c) */ 168b411b363SPhilipp Reisner /* 4th incarnation of the disk layout. */ 169b411b363SPhilipp Reisner #define DRBD_MD_MAGIC (DRBD_MAGIC+4) 170b411b363SPhilipp Reisner 171b411b363SPhilipp Reisner extern struct ratelimit_state drbd_ratelimit_state; 17281a5d60eSPhilipp Reisner extern struct idr minors; 17380883197SPhilipp Reisner extern struct list_head drbd_tconns; 174543cc10bSLars Ellenberg extern struct mutex drbd_cfg_mutex; 175b411b363SPhilipp Reisner 176b411b363SPhilipp Reisner /* on the wire */ 177d8763023SAndreas Gruenbacher enum drbd_packet { 178b411b363SPhilipp Reisner /* receiver (data socket) */ 179b411b363SPhilipp Reisner P_DATA = 0x00, 180b411b363SPhilipp Reisner P_DATA_REPLY = 0x01, /* Response to P_DATA_REQUEST */ 181b411b363SPhilipp Reisner P_RS_DATA_REPLY = 0x02, /* Response to P_RS_DATA_REQUEST */ 182b411b363SPhilipp Reisner P_BARRIER = 0x03, 183b411b363SPhilipp Reisner P_BITMAP = 0x04, 184b411b363SPhilipp Reisner P_BECOME_SYNC_TARGET = 0x05, 185b411b363SPhilipp Reisner P_BECOME_SYNC_SOURCE = 0x06, 186b411b363SPhilipp Reisner P_UNPLUG_REMOTE = 0x07, /* Used at various times to hint the peer */ 187b411b363SPhilipp Reisner P_DATA_REQUEST = 0x08, /* Used to ask for a data block */ 188b411b363SPhilipp Reisner P_RS_DATA_REQUEST = 0x09, /* Used to ask for a data block for resync */ 189b411b363SPhilipp Reisner P_SYNC_PARAM = 0x0a, 190b411b363SPhilipp Reisner P_PROTOCOL = 0x0b, 191b411b363SPhilipp Reisner P_UUIDS = 0x0c, 192b411b363SPhilipp Reisner P_SIZES = 0x0d, 193b411b363SPhilipp Reisner P_STATE = 0x0e, 194b411b363SPhilipp Reisner P_SYNC_UUID = 0x0f, 195b411b363SPhilipp Reisner P_AUTH_CHALLENGE = 0x10, 196b411b363SPhilipp Reisner P_AUTH_RESPONSE = 0x11, 197b411b363SPhilipp Reisner P_STATE_CHG_REQ = 0x12, 198b411b363SPhilipp Reisner 199b411b363SPhilipp Reisner /* asender (meta socket */ 200b411b363SPhilipp Reisner P_PING = 0x13, 201b411b363SPhilipp Reisner P_PING_ACK = 0x14, 202b411b363SPhilipp Reisner P_RECV_ACK = 0x15, /* Used in protocol B */ 203b411b363SPhilipp Reisner P_WRITE_ACK = 0x16, /* Used in protocol C */ 204b411b363SPhilipp Reisner P_RS_WRITE_ACK = 0x17, /* Is a P_WRITE_ACK, additionally call set_in_sync(). */ 2057be8da07SAndreas Gruenbacher P_DISCARD_WRITE = 0x18, /* Used in proto C, two-primaries conflict detection */ 206b411b363SPhilipp Reisner P_NEG_ACK = 0x19, /* Sent if local disk is unusable */ 207b411b363SPhilipp Reisner P_NEG_DREPLY = 0x1a, /* Local disk is broken... */ 208b411b363SPhilipp Reisner P_NEG_RS_DREPLY = 0x1b, /* Local disk is broken... */ 209b411b363SPhilipp Reisner P_BARRIER_ACK = 0x1c, 210b411b363SPhilipp Reisner P_STATE_CHG_REPLY = 0x1d, 211b411b363SPhilipp Reisner 212b411b363SPhilipp Reisner /* "new" commands, no longer fitting into the ordering scheme above */ 213b411b363SPhilipp Reisner 214b411b363SPhilipp Reisner P_OV_REQUEST = 0x1e, /* data socket */ 215b411b363SPhilipp Reisner P_OV_REPLY = 0x1f, 216b411b363SPhilipp Reisner P_OV_RESULT = 0x20, /* meta socket */ 217b411b363SPhilipp Reisner P_CSUM_RS_REQUEST = 0x21, /* data socket */ 218b411b363SPhilipp Reisner P_RS_IS_IN_SYNC = 0x22, /* meta socket */ 219b411b363SPhilipp Reisner P_SYNC_PARAM89 = 0x23, /* data socket, protocol version 89 replacement for P_SYNC_PARAM */ 220b411b363SPhilipp Reisner P_COMPRESSED_BITMAP = 0x24, /* compressed or otherwise encoded bitmap transfer */ 2210ced55a3SPhilipp Reisner /* P_CKPT_FENCE_REQ = 0x25, * currently reserved for protocol D */ 2220ced55a3SPhilipp Reisner /* P_CKPT_DISABLE_REQ = 0x26, * currently reserved for protocol D */ 2230ced55a3SPhilipp Reisner P_DELAY_PROBE = 0x27, /* is used on BOTH sockets */ 22473a01a18SPhilipp Reisner P_OUT_OF_SYNC = 0x28, /* Mark as out of sync (Outrunning), data socket */ 225d612d309SPhilipp Reisner P_RS_CANCEL = 0x29, /* meta: Used to cancel RS_DATA_REQUEST packet by SyncSource */ 226cf29c9d8SPhilipp Reisner P_CONN_ST_CHG_REQ = 0x2a, /* data sock: Connection wide state request */ 227cf29c9d8SPhilipp Reisner P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: Connection side state req reply */ 2287be8da07SAndreas Gruenbacher P_RETRY_WRITE = 0x2c, /* Protocol C: retry conflicting write request */ 229b411b363SPhilipp Reisner 230b411b363SPhilipp Reisner P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ 231b411b363SPhilipp Reisner P_MAX_OPT_CMD = 0x101, 232b411b363SPhilipp Reisner 233b411b363SPhilipp Reisner /* special command ids for handshake */ 234b411b363SPhilipp Reisner 235e5d6f33aSAndreas Gruenbacher P_INITIAL_META = 0xfff1, /* First Packet on the MetaSock */ 236e5d6f33aSAndreas Gruenbacher P_INITIAL_DATA = 0xfff2, /* First Packet on the Socket */ 237b411b363SPhilipp Reisner 2386038178eSAndreas Gruenbacher P_CONNECTION_FEATURES = 0xfffe /* FIXED for the next century! */ 239b411b363SPhilipp Reisner }; 240b411b363SPhilipp Reisner 241d8763023SAndreas Gruenbacher extern const char *cmdname(enum drbd_packet cmd); 242b411b363SPhilipp Reisner 243b411b363SPhilipp Reisner /* for sending/receiving the bitmap, 244b411b363SPhilipp Reisner * possibly in some encoding scheme */ 245b411b363SPhilipp Reisner struct bm_xfer_ctx { 246b411b363SPhilipp Reisner /* "const" 247b411b363SPhilipp Reisner * stores total bits and long words 248b411b363SPhilipp Reisner * of the bitmap, so we don't need to 249b411b363SPhilipp Reisner * call the accessor functions over and again. */ 250b411b363SPhilipp Reisner unsigned long bm_bits; 251b411b363SPhilipp Reisner unsigned long bm_words; 252b411b363SPhilipp Reisner /* during xfer, current position within the bitmap */ 253b411b363SPhilipp Reisner unsigned long bit_offset; 254b411b363SPhilipp Reisner unsigned long word_offset; 255b411b363SPhilipp Reisner 256b411b363SPhilipp Reisner /* statistics; index: (h->command == P_BITMAP) */ 257b411b363SPhilipp Reisner unsigned packets[2]; 258b411b363SPhilipp Reisner unsigned bytes[2]; 259b411b363SPhilipp Reisner }; 260b411b363SPhilipp Reisner 261b411b363SPhilipp Reisner extern void INFO_bm_xfer_stats(struct drbd_conf *mdev, 262b411b363SPhilipp Reisner const char *direction, struct bm_xfer_ctx *c); 263b411b363SPhilipp Reisner 264b411b363SPhilipp Reisner static inline void bm_xfer_ctx_bit_to_word_offset(struct bm_xfer_ctx *c) 265b411b363SPhilipp Reisner { 266b411b363SPhilipp Reisner /* word_offset counts "native long words" (32 or 64 bit), 267b411b363SPhilipp Reisner * aligned at 64 bit. 268b411b363SPhilipp Reisner * Encoded packet may end at an unaligned bit offset. 269b411b363SPhilipp Reisner * In case a fallback clear text packet is transmitted in 270b411b363SPhilipp Reisner * between, we adjust this offset back to the last 64bit 271b411b363SPhilipp Reisner * aligned "native long word", which makes coding and decoding 272b411b363SPhilipp Reisner * the plain text bitmap much more convenient. */ 273b411b363SPhilipp Reisner #if BITS_PER_LONG == 64 274b411b363SPhilipp Reisner c->word_offset = c->bit_offset >> 6; 275b411b363SPhilipp Reisner #elif BITS_PER_LONG == 32 276b411b363SPhilipp Reisner c->word_offset = c->bit_offset >> 5; 277b411b363SPhilipp Reisner c->word_offset &= ~(1UL); 278b411b363SPhilipp Reisner #else 279b411b363SPhilipp Reisner # error "unsupported BITS_PER_LONG" 280b411b363SPhilipp Reisner #endif 281b411b363SPhilipp Reisner } 282b411b363SPhilipp Reisner 283b411b363SPhilipp Reisner #ifndef __packed 284b411b363SPhilipp Reisner #define __packed __attribute__((packed)) 285b411b363SPhilipp Reisner #endif 286b411b363SPhilipp Reisner 287b411b363SPhilipp Reisner /* This is the layout for a packet on the wire. 288b411b363SPhilipp Reisner * The byteorder is the network byte order. 289b411b363SPhilipp Reisner * (except block_id and barrier fields. 290b411b363SPhilipp Reisner * these are pointers to local structs 291b411b363SPhilipp Reisner * and have no relevance for the partner, 292b411b363SPhilipp Reisner * which just echoes them as received.) 293b411b363SPhilipp Reisner * 294b411b363SPhilipp Reisner * NOTE that the payload starts at a long aligned offset, 295b411b363SPhilipp Reisner * regardless of 32 or 64 bit arch! 296b411b363SPhilipp Reisner */ 2970b70a13dSPhilipp Reisner struct p_header80 { 298b411b363SPhilipp Reisner u32 magic; 299b411b363SPhilipp Reisner u16 command; 300b411b363SPhilipp Reisner u16 length; /* bytes of data after this header */ 301b411b363SPhilipp Reisner } __packed; 3020b70a13dSPhilipp Reisner 3030b70a13dSPhilipp Reisner /* Header for big packets, Used for data packets exceeding 64kB */ 3040b70a13dSPhilipp Reisner struct p_header95 { 3050b70a13dSPhilipp Reisner u16 magic; /* use DRBD_MAGIC_BIG here */ 3060b70a13dSPhilipp Reisner u16 command; 307*b55d84baSAndreas Gruenbacher u32 length; 3080b70a13dSPhilipp Reisner } __packed; 3090b70a13dSPhilipp Reisner 3100c8e36d9SAndreas Gruenbacher struct p_header100 { 3110c8e36d9SAndreas Gruenbacher u32 magic; 3120c8e36d9SAndreas Gruenbacher u16 volume; 3130c8e36d9SAndreas Gruenbacher u16 command; 3140c8e36d9SAndreas Gruenbacher u32 length; 3150c8e36d9SAndreas Gruenbacher u32 pad; 3160c8e36d9SAndreas Gruenbacher } __packed; 3170c8e36d9SAndreas Gruenbacher 31852b061a4SAndreas Gruenbacher extern unsigned int drbd_header_size(struct drbd_tconn *tconn); 31952b061a4SAndreas Gruenbacher 320b411b363SPhilipp Reisner /* these defines must not be changed without changing the protocol version */ 32176d2e7ecSPhilipp Reisner #define DP_HARDBARRIER 1 /* depricated */ 32276d2e7ecSPhilipp Reisner #define DP_RW_SYNC 2 /* equals REQ_SYNC */ 323b411b363SPhilipp Reisner #define DP_MAY_SET_IN_SYNC 4 324721a9602SJens Axboe #define DP_UNPLUG 8 /* not used anymore */ 32576d2e7ecSPhilipp Reisner #define DP_FUA 16 /* equals REQ_FUA */ 32676d2e7ecSPhilipp Reisner #define DP_FLUSH 32 /* equals REQ_FLUSH */ 32776d2e7ecSPhilipp Reisner #define DP_DISCARD 64 /* equals REQ_DISCARD */ 328b411b363SPhilipp Reisner 329b411b363SPhilipp Reisner struct p_data { 330b411b363SPhilipp Reisner u64 sector; /* 64 bits sector number */ 331b411b363SPhilipp Reisner u64 block_id; /* to identify the request in protocol B&C */ 332b411b363SPhilipp Reisner u32 seq_num; 333b411b363SPhilipp Reisner u32 dp_flags; 334b411b363SPhilipp Reisner } __packed; 335b411b363SPhilipp Reisner 336b411b363SPhilipp Reisner /* 337b411b363SPhilipp Reisner * commands which share a struct: 338b411b363SPhilipp Reisner * p_block_ack: 339b411b363SPhilipp Reisner * P_RECV_ACK (proto B), P_WRITE_ACK (proto C), 3407be8da07SAndreas Gruenbacher * P_DISCARD_WRITE (proto C, two-primaries conflict detection) 341b411b363SPhilipp Reisner * p_block_req: 342b411b363SPhilipp Reisner * P_DATA_REQUEST, P_RS_DATA_REQUEST 343b411b363SPhilipp Reisner */ 344b411b363SPhilipp Reisner struct p_block_ack { 345b411b363SPhilipp Reisner u64 sector; 346b411b363SPhilipp Reisner u64 block_id; 347b411b363SPhilipp Reisner u32 blksize; 348b411b363SPhilipp Reisner u32 seq_num; 349b411b363SPhilipp Reisner } __packed; 350b411b363SPhilipp Reisner 351b411b363SPhilipp Reisner struct p_block_req { 352b411b363SPhilipp Reisner u64 sector; 353b411b363SPhilipp Reisner u64 block_id; 354b411b363SPhilipp Reisner u32 blksize; 355b411b363SPhilipp Reisner u32 pad; /* to multiple of 8 Byte */ 356b411b363SPhilipp Reisner } __packed; 357b411b363SPhilipp Reisner 358b411b363SPhilipp Reisner /* 359b411b363SPhilipp Reisner * commands with their own struct for additional fields: 3606038178eSAndreas Gruenbacher * P_CONNECTION_FEATURES 361b411b363SPhilipp Reisner * P_BARRIER 362b411b363SPhilipp Reisner * P_BARRIER_ACK 363b411b363SPhilipp Reisner * P_SYNC_PARAM 364b411b363SPhilipp Reisner * ReportParams 365b411b363SPhilipp Reisner */ 366b411b363SPhilipp Reisner 3676038178eSAndreas Gruenbacher struct p_connection_features { 368b411b363SPhilipp Reisner u32 protocol_min; 369b411b363SPhilipp Reisner u32 feature_flags; 370b411b363SPhilipp Reisner u32 protocol_max; 371b411b363SPhilipp Reisner 372b411b363SPhilipp Reisner /* should be more than enough for future enhancements 373b411b363SPhilipp Reisner * for now, feature_flags and the reserverd array shall be zero. 374b411b363SPhilipp Reisner */ 375b411b363SPhilipp Reisner 376b411b363SPhilipp Reisner u32 _pad; 377b411b363SPhilipp Reisner u64 reserverd[7]; 378b411b363SPhilipp Reisner } __packed; 379b411b363SPhilipp Reisner 380b411b363SPhilipp Reisner struct p_barrier { 381b411b363SPhilipp Reisner u32 barrier; /* barrier number _handle_ only */ 382b411b363SPhilipp Reisner u32 pad; /* to multiple of 8 Byte */ 383b411b363SPhilipp Reisner } __packed; 384b411b363SPhilipp Reisner 385b411b363SPhilipp Reisner struct p_barrier_ack { 386b411b363SPhilipp Reisner u32 barrier; 387b411b363SPhilipp Reisner u32 set_size; 388b411b363SPhilipp Reisner } __packed; 389b411b363SPhilipp Reisner 390b411b363SPhilipp Reisner struct p_rs_param { 391b411b363SPhilipp Reisner u32 rate; 392b411b363SPhilipp Reisner 393b411b363SPhilipp Reisner /* Since protocol version 88 and higher. */ 394b411b363SPhilipp Reisner char verify_alg[0]; 395b411b363SPhilipp Reisner } __packed; 396b411b363SPhilipp Reisner 397b411b363SPhilipp Reisner struct p_rs_param_89 { 398b411b363SPhilipp Reisner u32 rate; 399b411b363SPhilipp Reisner /* protocol version 89: */ 400b411b363SPhilipp Reisner char verify_alg[SHARED_SECRET_MAX]; 401b411b363SPhilipp Reisner char csums_alg[SHARED_SECRET_MAX]; 402b411b363SPhilipp Reisner } __packed; 403b411b363SPhilipp Reisner 4048e26f9ccSPhilipp Reisner struct p_rs_param_95 { 4058e26f9ccSPhilipp Reisner u32 rate; 4068e26f9ccSPhilipp Reisner char verify_alg[SHARED_SECRET_MAX]; 4078e26f9ccSPhilipp Reisner char csums_alg[SHARED_SECRET_MAX]; 4088e26f9ccSPhilipp Reisner u32 c_plan_ahead; 4098e26f9ccSPhilipp Reisner u32 c_delay_target; 4108e26f9ccSPhilipp Reisner u32 c_fill_target; 4118e26f9ccSPhilipp Reisner u32 c_max_rate; 4128e26f9ccSPhilipp Reisner } __packed; 4138e26f9ccSPhilipp Reisner 414cf14c2e9SPhilipp Reisner enum drbd_conn_flags { 415cf14c2e9SPhilipp Reisner CF_WANT_LOSE = 1, 416cf14c2e9SPhilipp Reisner CF_DRY_RUN = 2, 417cf14c2e9SPhilipp Reisner }; 418cf14c2e9SPhilipp Reisner 419b411b363SPhilipp Reisner struct p_protocol { 420b411b363SPhilipp Reisner u32 protocol; 421b411b363SPhilipp Reisner u32 after_sb_0p; 422b411b363SPhilipp Reisner u32 after_sb_1p; 423b411b363SPhilipp Reisner u32 after_sb_2p; 424cf14c2e9SPhilipp Reisner u32 conn_flags; 425b411b363SPhilipp Reisner u32 two_primaries; 426b411b363SPhilipp Reisner 427b411b363SPhilipp Reisner /* Since protocol version 87 and higher. */ 428b411b363SPhilipp Reisner char integrity_alg[0]; 429b411b363SPhilipp Reisner 430b411b363SPhilipp Reisner } __packed; 431b411b363SPhilipp Reisner 432b411b363SPhilipp Reisner struct p_uuids { 433b411b363SPhilipp Reisner u64 uuid[UI_EXTENDED_SIZE]; 434b411b363SPhilipp Reisner } __packed; 435b411b363SPhilipp Reisner 436b411b363SPhilipp Reisner struct p_rs_uuid { 437b411b363SPhilipp Reisner u64 uuid; 438b411b363SPhilipp Reisner } __packed; 439b411b363SPhilipp Reisner 440b411b363SPhilipp Reisner struct p_sizes { 441b411b363SPhilipp Reisner u64 d_size; /* size of disk */ 442b411b363SPhilipp Reisner u64 u_size; /* user requested size */ 443b411b363SPhilipp Reisner u64 c_size; /* current exported size */ 4441816a2b4SLars Ellenberg u32 max_bio_size; /* Maximal size of a BIO */ 445e89b591cSPhilipp Reisner u16 queue_order_type; /* not yet implemented in DRBD*/ 446e89b591cSPhilipp Reisner u16 dds_flags; /* use enum dds_flags here. */ 447b411b363SPhilipp Reisner } __packed; 448b411b363SPhilipp Reisner 449b411b363SPhilipp Reisner struct p_state { 450b411b363SPhilipp Reisner u32 state; 451b411b363SPhilipp Reisner } __packed; 452b411b363SPhilipp Reisner 453b411b363SPhilipp Reisner struct p_req_state { 454b411b363SPhilipp Reisner u32 mask; 455b411b363SPhilipp Reisner u32 val; 456b411b363SPhilipp Reisner } __packed; 457b411b363SPhilipp Reisner 458b411b363SPhilipp Reisner struct p_req_state_reply { 459b411b363SPhilipp Reisner u32 retcode; 460b411b363SPhilipp Reisner } __packed; 461b411b363SPhilipp Reisner 462b411b363SPhilipp Reisner struct p_drbd06_param { 463b411b363SPhilipp Reisner u64 size; 464b411b363SPhilipp Reisner u32 state; 465b411b363SPhilipp Reisner u32 blksize; 466b411b363SPhilipp Reisner u32 protocol; 467b411b363SPhilipp Reisner u32 version; 468b411b363SPhilipp Reisner u32 gen_cnt[5]; 469b411b363SPhilipp Reisner u32 bit_map_gen[5]; 470b411b363SPhilipp Reisner } __packed; 471b411b363SPhilipp Reisner 472b411b363SPhilipp Reisner struct p_discard { 473b411b363SPhilipp Reisner u64 block_id; 474b411b363SPhilipp Reisner u32 seq_num; 475b411b363SPhilipp Reisner u32 pad; 476b411b363SPhilipp Reisner } __packed; 477b411b363SPhilipp Reisner 47873a01a18SPhilipp Reisner struct p_block_desc { 47973a01a18SPhilipp Reisner u64 sector; 48073a01a18SPhilipp Reisner u32 blksize; 48173a01a18SPhilipp Reisner u32 pad; /* to multiple of 8 Byte */ 48273a01a18SPhilipp Reisner } __packed; 48373a01a18SPhilipp Reisner 484b411b363SPhilipp Reisner /* Valid values for the encoding field. 485b411b363SPhilipp Reisner * Bump proto version when changing this. */ 486b411b363SPhilipp Reisner enum drbd_bitmap_code { 487b411b363SPhilipp Reisner /* RLE_VLI_Bytes = 0, 488b411b363SPhilipp Reisner * and other bit variants had been defined during 489b411b363SPhilipp Reisner * algorithm evaluation. */ 490b411b363SPhilipp Reisner RLE_VLI_Bits = 2, 491b411b363SPhilipp Reisner }; 492b411b363SPhilipp Reisner 493b411b363SPhilipp Reisner struct p_compressed_bm { 494b411b363SPhilipp Reisner /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code 495b411b363SPhilipp Reisner * (encoding & 0x80): polarity (set/unset) of first runlength 496b411b363SPhilipp Reisner * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits 497b411b363SPhilipp Reisner * used to pad up to head.length bytes 498b411b363SPhilipp Reisner */ 499b411b363SPhilipp Reisner u8 encoding; 500b411b363SPhilipp Reisner 501b411b363SPhilipp Reisner u8 code[0]; 502b411b363SPhilipp Reisner } __packed; 503b411b363SPhilipp Reisner 5040b70a13dSPhilipp Reisner struct p_delay_probe93 { 5050ced55a3SPhilipp Reisner u32 seq_num; /* sequence number to match the two probe packets */ 5060ced55a3SPhilipp Reisner u32 offset; /* usecs the probe got sent after the reference time point */ 5070ced55a3SPhilipp Reisner } __packed; 5080ced55a3SPhilipp Reisner 50950d0b1adSAndreas Gruenbacher /* 51050d0b1adSAndreas Gruenbacher * Bitmap packets need to fit within a single page on the sender and receiver, 51150d0b1adSAndreas Gruenbacher * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger). 512b411b363SPhilipp Reisner */ 513e6ef8a5cSAndreas Gruenbacher #define DRBD_SOCKET_BUFFER_SIZE 4096 514e6ef8a5cSAndreas Gruenbacher 515b411b363SPhilipp Reisner /**********************************************************************/ 516b411b363SPhilipp Reisner enum drbd_thread_state { 517e77a0a5cSAndreas Gruenbacher NONE, 518e77a0a5cSAndreas Gruenbacher RUNNING, 519e77a0a5cSAndreas Gruenbacher EXITING, 520e77a0a5cSAndreas Gruenbacher RESTARTING 521b411b363SPhilipp Reisner }; 522b411b363SPhilipp Reisner 523b411b363SPhilipp Reisner struct drbd_thread { 524b411b363SPhilipp Reisner spinlock_t t_lock; 525b411b363SPhilipp Reisner struct task_struct *task; 526b411b363SPhilipp Reisner struct completion stop; 527b411b363SPhilipp Reisner enum drbd_thread_state t_state; 528b411b363SPhilipp Reisner int (*function) (struct drbd_thread *); 529392c8801SPhilipp Reisner struct drbd_tconn *tconn; 530b411b363SPhilipp Reisner int reset_cpu_mask; 531bed879aeSPhilipp Reisner char name[9]; 532b411b363SPhilipp Reisner }; 533b411b363SPhilipp Reisner 534b411b363SPhilipp Reisner static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi) 535b411b363SPhilipp Reisner { 536b411b363SPhilipp Reisner /* THINK testing the t_state seems to be uncritical in all cases 537b411b363SPhilipp Reisner * (but thread_{start,stop}), so we can read it *without* the lock. 538b411b363SPhilipp Reisner * --lge */ 539b411b363SPhilipp Reisner 540b411b363SPhilipp Reisner smp_rmb(); 541b411b363SPhilipp Reisner return thi->t_state; 542b411b363SPhilipp Reisner } 543b411b363SPhilipp Reisner 544b411b363SPhilipp Reisner struct drbd_work { 545b411b363SPhilipp Reisner struct list_head list; 546309a8348SAndreas Gruenbacher int (*cb)(struct drbd_work *, int cancel); 54700d56944SPhilipp Reisner union { 548a21e9298SPhilipp Reisner struct drbd_conf *mdev; 54900d56944SPhilipp Reisner struct drbd_tconn *tconn; 55000d56944SPhilipp Reisner }; 551b411b363SPhilipp Reisner }; 552b411b363SPhilipp Reisner 553ace652acSAndreas Gruenbacher #include "drbd_interval.h" 554ace652acSAndreas Gruenbacher 5557be8da07SAndreas Gruenbacher extern int drbd_wait_misc(struct drbd_conf *, struct drbd_interval *); 5567be8da07SAndreas Gruenbacher 557b411b363SPhilipp Reisner struct drbd_request { 558b411b363SPhilipp Reisner struct drbd_work w; 559b411b363SPhilipp Reisner 560b411b363SPhilipp Reisner /* if local IO is not allowed, will be NULL. 561b411b363SPhilipp Reisner * if local IO _is_ allowed, holds the locally submitted bio clone, 562b411b363SPhilipp Reisner * or, after local IO completion, the ERR_PTR(error). 563fcefa62eSAndreas Gruenbacher * see drbd_request_endio(). */ 564b411b363SPhilipp Reisner struct bio *private_bio; 565b411b363SPhilipp Reisner 566ace652acSAndreas Gruenbacher struct drbd_interval i; 567b411b363SPhilipp Reisner unsigned int epoch; /* barrier_nr */ 568b411b363SPhilipp Reisner 569b411b363SPhilipp Reisner /* barrier_nr: used to check on "completion" whether this req was in 570b411b363SPhilipp Reisner * the current epoch, and we therefore have to close it, 571b411b363SPhilipp Reisner * starting a new epoch... 572b411b363SPhilipp Reisner */ 573b411b363SPhilipp Reisner 574b411b363SPhilipp Reisner struct list_head tl_requests; /* ring list in the transfer log */ 575b411b363SPhilipp Reisner struct bio *master_bio; /* master bio pointer */ 576b411b363SPhilipp Reisner unsigned long rq_state; /* see comments above _req_mod() */ 577b411b363SPhilipp Reisner int seq_num; 578b411b363SPhilipp Reisner unsigned long start_time; 579b411b363SPhilipp Reisner }; 580b411b363SPhilipp Reisner 581b411b363SPhilipp Reisner struct drbd_tl_epoch { 582b411b363SPhilipp Reisner struct drbd_work w; 583b411b363SPhilipp Reisner struct list_head requests; /* requests before */ 584b411b363SPhilipp Reisner struct drbd_tl_epoch *next; /* pointer to the next barrier */ 585b411b363SPhilipp Reisner unsigned int br_number; /* the barriers identifier. */ 5867e602c0aSPhilipp Reisner int n_writes; /* number of requests attached before this barrier */ 587b411b363SPhilipp Reisner }; 588b411b363SPhilipp Reisner 589b411b363SPhilipp Reisner struct drbd_epoch { 590b411b363SPhilipp Reisner struct list_head list; 591b411b363SPhilipp Reisner unsigned int barrier_nr; 592b411b363SPhilipp Reisner atomic_t epoch_size; /* increased on every request added. */ 593b411b363SPhilipp Reisner atomic_t active; /* increased on every req. added, and dec on every finished. */ 594b411b363SPhilipp Reisner unsigned long flags; 595b411b363SPhilipp Reisner }; 596b411b363SPhilipp Reisner 597b411b363SPhilipp Reisner /* drbd_epoch flag bits */ 598b411b363SPhilipp Reisner enum { 599b411b363SPhilipp Reisner DE_HAVE_BARRIER_NUMBER, 600b411b363SPhilipp Reisner }; 601b411b363SPhilipp Reisner 602b411b363SPhilipp Reisner enum epoch_event { 603b411b363SPhilipp Reisner EV_PUT, 604b411b363SPhilipp Reisner EV_GOT_BARRIER_NR, 605b411b363SPhilipp Reisner EV_BECAME_LAST, 606b411b363SPhilipp Reisner EV_CLEANUP = 32, /* used as flag */ 607b411b363SPhilipp Reisner }; 608b411b363SPhilipp Reisner 609b411b363SPhilipp Reisner struct drbd_wq_barrier { 610b411b363SPhilipp Reisner struct drbd_work w; 611b411b363SPhilipp Reisner struct completion done; 612b411b363SPhilipp Reisner }; 613b411b363SPhilipp Reisner 614b411b363SPhilipp Reisner struct digest_info { 615b411b363SPhilipp Reisner int digest_size; 616b411b363SPhilipp Reisner void *digest; 617b411b363SPhilipp Reisner }; 618b411b363SPhilipp Reisner 619f6ffca9fSAndreas Gruenbacher struct drbd_peer_request { 62045bb912bSLars Ellenberg struct drbd_work w; 62185719573SPhilipp Reisner struct drbd_epoch *epoch; /* for writes */ 62245bb912bSLars Ellenberg struct page *pages; 62345bb912bSLars Ellenberg atomic_t pending_bios; 624010f6e67SAndreas Gruenbacher struct drbd_interval i; 62545bb912bSLars Ellenberg /* see comments on ee flag bits below */ 62645bb912bSLars Ellenberg unsigned long flags; 62785719573SPhilipp Reisner union { 62845bb912bSLars Ellenberg u64 block_id; 62985719573SPhilipp Reisner struct digest_info *digest; 63085719573SPhilipp Reisner }; 63145bb912bSLars Ellenberg }; 63245bb912bSLars Ellenberg 63345bb912bSLars Ellenberg /* ee flag bits. 63445bb912bSLars Ellenberg * While corresponding bios are in flight, the only modification will be 63545bb912bSLars Ellenberg * set_bit WAS_ERROR, which has to be atomic. 63645bb912bSLars Ellenberg * If no bios are in flight yet, or all have been completed, 63745bb912bSLars Ellenberg * non-atomic modification to ee->flags is ok. 63845bb912bSLars Ellenberg */ 639b411b363SPhilipp Reisner enum { 640b411b363SPhilipp Reisner __EE_CALL_AL_COMPLETE_IO, 641b411b363SPhilipp Reisner __EE_MAY_SET_IN_SYNC, 64245bb912bSLars Ellenberg 64345bb912bSLars Ellenberg /* In case a barrier failed, 64445bb912bSLars Ellenberg * we need to resubmit without the barrier flag. */ 64545bb912bSLars Ellenberg __EE_RESUBMITTED, 64645bb912bSLars Ellenberg 6476c852becSAndreas Gruenbacher /* we may have several bios per peer request. 64845bb912bSLars Ellenberg * if any of those fail, we set this flag atomically 64945bb912bSLars Ellenberg * from the endio callback */ 65045bb912bSLars Ellenberg __EE_WAS_ERROR, 651c36c3cedSLars Ellenberg 652c36c3cedSLars Ellenberg /* This ee has a pointer to a digest instead of a block id */ 653c36c3cedSLars Ellenberg __EE_HAS_DIGEST, 6547be8da07SAndreas Gruenbacher 6557be8da07SAndreas Gruenbacher /* Conflicting local requests need to be restarted after this request */ 6567be8da07SAndreas Gruenbacher __EE_RESTART_REQUESTS, 657b411b363SPhilipp Reisner }; 658b411b363SPhilipp Reisner #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) 659b411b363SPhilipp Reisner #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) 66045bb912bSLars Ellenberg #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) 66145bb912bSLars Ellenberg #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) 662c36c3cedSLars Ellenberg #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) 6637be8da07SAndreas Gruenbacher #define EE_RESTART_REQUESTS (1<<__EE_RESTART_REQUESTS) 664b411b363SPhilipp Reisner 66501a311a5SPhilipp Reisner /* flag bits per mdev */ 666b411b363SPhilipp Reisner enum { 66725985edcSLucas De Marchi CREATE_BARRIER, /* next P_DATA is preceded by a P_BARRIER */ 668b411b363SPhilipp Reisner UNPLUG_QUEUED, /* only relevant with kernel 2.4 */ 669b411b363SPhilipp Reisner UNPLUG_REMOTE, /* sending a "UnplugRemote" could help */ 670b411b363SPhilipp Reisner MD_DIRTY, /* current uuids and flags not yet on disk */ 671b411b363SPhilipp Reisner USE_DEGR_WFC_T, /* degr-wfc-timeout instead of wfc-timeout. */ 672b411b363SPhilipp Reisner CL_ST_CHG_SUCCESS, 673b411b363SPhilipp Reisner CL_ST_CHG_FAIL, 674b411b363SPhilipp Reisner CRASHED_PRIMARY, /* This node was a crashed primary. 675b411b363SPhilipp Reisner * Gets cleared when the state.conn 676b411b363SPhilipp Reisner * goes into C_CONNECTED state. */ 67719f843aaSLars Ellenberg NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ 678b411b363SPhilipp Reisner CONSIDER_RESYNC, 679b411b363SPhilipp Reisner 680a8a4e51eSPhilipp Reisner MD_NO_FUA, /* Users wants us to not use FUA/FLUSH on meta data dev */ 681b411b363SPhilipp Reisner SUSPEND_IO, /* suspend application io */ 682b411b363SPhilipp Reisner BITMAP_IO, /* suspend application io; 683b411b363SPhilipp Reisner once no more io in flight, start bitmap io */ 684b411b363SPhilipp Reisner BITMAP_IO_QUEUED, /* Started bitmap IO */ 68582f59cc6SLars Ellenberg GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */ 68682f59cc6SLars Ellenberg WAS_IO_ERROR, /* Local disk failed returned IO error */ 687b411b363SPhilipp Reisner RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ 688b411b363SPhilipp Reisner RESIZE_PENDING, /* Size change detected locally, waiting for the response from 689b411b363SPhilipp Reisner * the peer, if it changed there as well. */ 69043a5182cSPhilipp Reisner NEW_CUR_UUID, /* Create new current UUID when thawing IO */ 6910778286aSPhilipp Reisner AL_SUSPENDED, /* Activity logging is currently suspended. */ 692370a43e7SPhilipp Reisner AHEAD_TO_SYNC_SOURCE, /* Ahead -> SyncSource queued */ 693e64a3294SPhilipp Reisner B_RS_H_DONE, /* Before resync handler done (already executed) */ 694b411b363SPhilipp Reisner }; 695b411b363SPhilipp Reisner 696b411b363SPhilipp Reisner struct drbd_bitmap; /* opaque for drbd_conf */ 697b411b363SPhilipp Reisner 69820ceb2b2SLars Ellenberg /* definition of bits in bm_flags to be used in drbd_bm_lock 69920ceb2b2SLars Ellenberg * and drbd_bitmap_io and friends. */ 70020ceb2b2SLars Ellenberg enum bm_flag { 70120ceb2b2SLars Ellenberg /* do we need to kfree, or vfree bm_pages? */ 70220ceb2b2SLars Ellenberg BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */ 70320ceb2b2SLars Ellenberg 70420ceb2b2SLars Ellenberg /* currently locked for bulk operation */ 70520ceb2b2SLars Ellenberg BM_LOCKED_MASK = 0x7, 70620ceb2b2SLars Ellenberg 70720ceb2b2SLars Ellenberg /* in detail, that is: */ 70820ceb2b2SLars Ellenberg BM_DONT_CLEAR = 0x1, 70920ceb2b2SLars Ellenberg BM_DONT_SET = 0x2, 71020ceb2b2SLars Ellenberg BM_DONT_TEST = 0x4, 71120ceb2b2SLars Ellenberg 71220ceb2b2SLars Ellenberg /* (test bit, count bit) allowed (common case) */ 71320ceb2b2SLars Ellenberg BM_LOCKED_TEST_ALLOWED = 0x3, 71420ceb2b2SLars Ellenberg 71520ceb2b2SLars Ellenberg /* testing bits, as well as setting new bits allowed, but clearing bits 71620ceb2b2SLars Ellenberg * would be unexpected. Used during bitmap receive. Setting new bits 71720ceb2b2SLars Ellenberg * requires sending of "out-of-sync" information, though. */ 71820ceb2b2SLars Ellenberg BM_LOCKED_SET_ALLOWED = 0x1, 71920ceb2b2SLars Ellenberg 72020ceb2b2SLars Ellenberg /* clear is not expected while bitmap is locked for bulk operation */ 72120ceb2b2SLars Ellenberg }; 72220ceb2b2SLars Ellenberg 72320ceb2b2SLars Ellenberg 724b411b363SPhilipp Reisner /* TODO sort members for performance 725b411b363SPhilipp Reisner * MAYBE group them further */ 726b411b363SPhilipp Reisner 727b411b363SPhilipp Reisner /* THINK maybe we actually want to use the default "event/%s" worker threads 728b411b363SPhilipp Reisner * or similar in linux 2.6, which uses per cpu data and threads. 729b411b363SPhilipp Reisner */ 730b411b363SPhilipp Reisner struct drbd_work_queue { 731b411b363SPhilipp Reisner struct list_head q; 732b411b363SPhilipp Reisner struct semaphore s; /* producers up it, worker down()s it */ 733b411b363SPhilipp Reisner spinlock_t q_lock; /* to protect the list. */ 734b411b363SPhilipp Reisner }; 735b411b363SPhilipp Reisner 736b411b363SPhilipp Reisner struct drbd_socket { 737b411b363SPhilipp Reisner struct drbd_work_queue work; 738b411b363SPhilipp Reisner struct mutex mutex; 739b411b363SPhilipp Reisner struct socket *socket; 740b411b363SPhilipp Reisner /* this way we get our 741b411b363SPhilipp Reisner * send/receive buffers off the stack */ 7425a87d920SAndreas Gruenbacher void *sbuf; 743e6ef8a5cSAndreas Gruenbacher void *rbuf; 744b411b363SPhilipp Reisner }; 745b411b363SPhilipp Reisner 746b411b363SPhilipp Reisner struct drbd_md { 747b411b363SPhilipp Reisner u64 md_offset; /* sector offset to 'super' block */ 748b411b363SPhilipp Reisner 749b411b363SPhilipp Reisner u64 la_size_sect; /* last agreed size, unit sectors */ 750b411b363SPhilipp Reisner u64 uuid[UI_SIZE]; 751b411b363SPhilipp Reisner u64 device_uuid; 752b411b363SPhilipp Reisner u32 flags; 753b411b363SPhilipp Reisner u32 md_size_sect; 754b411b363SPhilipp Reisner 755b411b363SPhilipp Reisner s32 al_offset; /* signed relative sector offset to al area */ 756b411b363SPhilipp Reisner s32 bm_offset; /* signed relative sector offset to bitmap */ 757b411b363SPhilipp Reisner 758b411b363SPhilipp Reisner /* u32 al_nr_extents; important for restoring the AL 759f399002eSLars Ellenberg * is stored into ldev->dc.al_extents, which in turn 760b411b363SPhilipp Reisner * gets applied to act_log->nr_elements 761b411b363SPhilipp Reisner */ 762b411b363SPhilipp Reisner }; 763b411b363SPhilipp Reisner 764b411b363SPhilipp Reisner struct drbd_backing_dev { 765b411b363SPhilipp Reisner struct block_device *backing_bdev; 766b411b363SPhilipp Reisner struct block_device *md_bdev; 767b411b363SPhilipp Reisner struct drbd_md md; 768b411b363SPhilipp Reisner struct disk_conf dc; /* The user provided config... */ 769b411b363SPhilipp Reisner sector_t known_size; /* last known size of that backing device */ 770b411b363SPhilipp Reisner }; 771b411b363SPhilipp Reisner 772b411b363SPhilipp Reisner struct drbd_md_io { 773b411b363SPhilipp Reisner struct drbd_conf *mdev; 774b411b363SPhilipp Reisner struct completion event; 775b411b363SPhilipp Reisner int error; 776b411b363SPhilipp Reisner }; 777b411b363SPhilipp Reisner 778b411b363SPhilipp Reisner struct bm_io_work { 779b411b363SPhilipp Reisner struct drbd_work w; 780b411b363SPhilipp Reisner char *why; 78120ceb2b2SLars Ellenberg enum bm_flag flags; 782b411b363SPhilipp Reisner int (*io_fn)(struct drbd_conf *mdev); 783b411b363SPhilipp Reisner void (*done)(struct drbd_conf *mdev, int rv); 784b411b363SPhilipp Reisner }; 785b411b363SPhilipp Reisner 786b411b363SPhilipp Reisner enum write_ordering_e { 787b411b363SPhilipp Reisner WO_none, 788b411b363SPhilipp Reisner WO_drain_io, 789b411b363SPhilipp Reisner WO_bdev_flush, 790b411b363SPhilipp Reisner }; 791b411b363SPhilipp Reisner 792778f271dSPhilipp Reisner struct fifo_buffer { 793778f271dSPhilipp Reisner int *values; 794778f271dSPhilipp Reisner unsigned int head_index; 795778f271dSPhilipp Reisner unsigned int size; 796778f271dSPhilipp Reisner }; 797778f271dSPhilipp Reisner 79801a311a5SPhilipp Reisner /* flag bits per tconn */ 79901a311a5SPhilipp Reisner enum { 80001a311a5SPhilipp Reisner NET_CONGESTED, /* The data socket is congested */ 80125703f83SPhilipp Reisner DISCARD_CONCURRENT, /* Set on one node, cleared on the peer! */ 802e43ef195SPhilipp Reisner SEND_PING, /* whether asender should send a ping asap */ 803808e37b8SPhilipp Reisner SIGNAL_ASENDER, /* whether asender wants to be interrupted */ 8042a67d8b9SPhilipp Reisner GOT_PING_ACK, /* set when we receive a ping_ack packet, ping_wait gets woken */ 805fc3b10a4SPhilipp Reisner CONN_WD_ST_CHG_OKAY, 806fc3b10a4SPhilipp Reisner CONN_WD_ST_CHG_FAIL, 8070e29d163SPhilipp Reisner CONFIG_PENDING, /* serialization of (re)configuration requests. 8080e29d163SPhilipp Reisner * if set, also prevents the device from dying */ 8090e29d163SPhilipp Reisner OBJECT_DYING, /* device became unconfigured, 8100e29d163SPhilipp Reisner * but worker thread is still handling the cleanup. 8110e29d163SPhilipp Reisner * reconfiguring (nl_disk_conf, nl_net_conf) is dissalowed, 8120e29d163SPhilipp Reisner * while this is set. */ 8138169e41bSPhilipp Reisner CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ 81401a311a5SPhilipp Reisner }; 81501a311a5SPhilipp Reisner 8162111438bSPhilipp Reisner struct drbd_tconn { /* is a resource from the config file */ 8172111438bSPhilipp Reisner char *name; /* Resource name */ 818543cc10bSLars Ellenberg struct list_head all_tconn; /* linked on global drbd_tconns */ 819062e879cSPhilipp Reisner struct idr volumes; /* <tconn, vnr> to mdev mapping */ 820bbeb641cSPhilipp Reisner enum drbd_conns cstate; /* Only C_STANDALONE to C_WF_REPORT_PARAMS */ 8218e0af25fSPhilipp Reisner unsigned susp:1; /* IO suspended by user */ 8228e0af25fSPhilipp Reisner unsigned susp_nod:1; /* IO suspended because no data */ 8238e0af25fSPhilipp Reisner unsigned susp_fen:1; /* IO suspended because fence peer handler runs */ 8248410da8fSPhilipp Reisner struct mutex cstate_mutex; /* Protects graceful disconnects */ 8252111438bSPhilipp Reisner 826062e879cSPhilipp Reisner unsigned long flags; 8272111438bSPhilipp Reisner struct net_conf *net_conf; /* protected by get_net_conf() and put_net_conf() */ 828b2fb6dbeSPhilipp Reisner atomic_t net_cnt; /* Users of net_conf */ 829b2fb6dbeSPhilipp Reisner wait_queue_head_t net_cnt_wait; 8302a67d8b9SPhilipp Reisner wait_queue_head_t ping_wait; /* Woken upon reception of a ping, and a state change */ 831f399002eSLars Ellenberg struct res_opts res_opts; 832e42325a5SPhilipp Reisner 833e42325a5SPhilipp Reisner struct drbd_socket data; /* data/barrier/cstate/parameter packets */ 834e42325a5SPhilipp Reisner struct drbd_socket meta; /* ping/ack (metadata) packets */ 83531890f4aSPhilipp Reisner int agreed_pro_version; /* actually used protocol version */ 83631890f4aSPhilipp Reisner unsigned long last_received; /* in jiffies, either socket */ 83731890f4aSPhilipp Reisner unsigned int ko_count; 838e6b3ea83SPhilipp Reisner 83987eeee41SPhilipp Reisner spinlock_t req_lock; 84087eeee41SPhilipp Reisner struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */ 84187eeee41SPhilipp Reisner struct drbd_tl_epoch *newest_tle; 84287eeee41SPhilipp Reisner struct drbd_tl_epoch *oldest_tle; 84387eeee41SPhilipp Reisner struct list_head out_of_sequence_requests; 84487eeee41SPhilipp Reisner 845a0638456SPhilipp Reisner struct crypto_hash *cram_hmac_tfm; 846a0638456SPhilipp Reisner struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */ 847a0638456SPhilipp Reisner struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */ 848f399002eSLars Ellenberg struct crypto_hash *csums_tfm; 849f399002eSLars Ellenberg struct crypto_hash *verify_tfm; 850a0638456SPhilipp Reisner void *int_dig_in; 851a0638456SPhilipp Reisner void *int_dig_vv; 852a0638456SPhilipp Reisner 853e6b3ea83SPhilipp Reisner struct drbd_thread receiver; 854e6b3ea83SPhilipp Reisner struct drbd_thread worker; 855e6b3ea83SPhilipp Reisner struct drbd_thread asender; 85680822284SPhilipp Reisner cpumask_var_t cpu_mask; 8572111438bSPhilipp Reisner }; 8582111438bSPhilipp Reisner 859b411b363SPhilipp Reisner struct drbd_conf { 8602111438bSPhilipp Reisner struct drbd_tconn *tconn; 8612111438bSPhilipp Reisner int vnr; /* volume number within the connection */ 8622111438bSPhilipp Reisner 863b411b363SPhilipp Reisner /* things that are stored as / read from meta data on disk */ 864b411b363SPhilipp Reisner unsigned long flags; 865b411b363SPhilipp Reisner 866b411b363SPhilipp Reisner /* configured by drbdsetup */ 867b411b363SPhilipp Reisner struct drbd_backing_dev *ldev __protected_by(local); 868b411b363SPhilipp Reisner 869b411b363SPhilipp Reisner sector_t p_size; /* partner's disk size */ 870b411b363SPhilipp Reisner struct request_queue *rq_queue; 871b411b363SPhilipp Reisner struct block_device *this_bdev; 872b411b363SPhilipp Reisner struct gendisk *vdisk; 873b411b363SPhilipp Reisner 874b411b363SPhilipp Reisner struct drbd_work resync_work, 875b411b363SPhilipp Reisner unplug_work, 876e9e6f3ecSLars Ellenberg go_diskless, 877c4752ef1SPhilipp Reisner md_sync_work, 878c4752ef1SPhilipp Reisner start_resync_work; 879b411b363SPhilipp Reisner struct timer_list resync_timer; 880b411b363SPhilipp Reisner struct timer_list md_sync_timer; 881370a43e7SPhilipp Reisner struct timer_list start_resync_timer; 8827fde2be9SPhilipp Reisner struct timer_list request_timer; 883ee15b038SLars Ellenberg #ifdef DRBD_DEBUG_MD_SYNC 884ee15b038SLars Ellenberg struct { 885ee15b038SLars Ellenberg unsigned int line; 886ee15b038SLars Ellenberg const char* func; 887ee15b038SLars Ellenberg } last_md_mark_dirty; 888ee15b038SLars Ellenberg #endif 889b411b363SPhilipp Reisner 890b411b363SPhilipp Reisner /* Used after attach while negotiating new disk state. */ 891b411b363SPhilipp Reisner union drbd_state new_state_tmp; 892b411b363SPhilipp Reisner 893da9fbc27SPhilipp Reisner union drbd_dev_state state; 894b411b363SPhilipp Reisner wait_queue_head_t misc_wait; 895b411b363SPhilipp Reisner wait_queue_head_t state_wait; /* upon each state change. */ 896b411b363SPhilipp Reisner unsigned int send_cnt; 897b411b363SPhilipp Reisner unsigned int recv_cnt; 898b411b363SPhilipp Reisner unsigned int read_cnt; 899b411b363SPhilipp Reisner unsigned int writ_cnt; 900b411b363SPhilipp Reisner unsigned int al_writ_cnt; 901b411b363SPhilipp Reisner unsigned int bm_writ_cnt; 902b411b363SPhilipp Reisner atomic_t ap_bio_cnt; /* Requests we need to complete */ 903b411b363SPhilipp Reisner atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */ 904b411b363SPhilipp Reisner atomic_t rs_pending_cnt; /* RS request/data packets on the wire */ 905b411b363SPhilipp Reisner atomic_t unacked_cnt; /* Need to send replys for */ 906b411b363SPhilipp Reisner atomic_t local_cnt; /* Waiting for local completion */ 907b2fb6dbeSPhilipp Reisner 908dac1389cSAndreas Gruenbacher /* Interval tree of pending local requests */ 909dac1389cSAndreas Gruenbacher struct rb_root read_requests; 910de696716SAndreas Gruenbacher struct rb_root write_requests; 911de696716SAndreas Gruenbacher 9124b0715f0SLars Ellenberg /* blocks to resync in this run [unit BM_BLOCK_SIZE] */ 913b411b363SPhilipp Reisner unsigned long rs_total; 9144b0715f0SLars Ellenberg /* number of resync blocks that failed in this run */ 915b411b363SPhilipp Reisner unsigned long rs_failed; 916b411b363SPhilipp Reisner /* Syncer's start time [unit jiffies] */ 917b411b363SPhilipp Reisner unsigned long rs_start; 918b411b363SPhilipp Reisner /* cumulated time in PausedSyncX state [unit jiffies] */ 919b411b363SPhilipp Reisner unsigned long rs_paused; 9201d7734a0SLars Ellenberg /* skipped because csum was equal [unit BM_BLOCK_SIZE] */ 921b411b363SPhilipp Reisner unsigned long rs_same_csum; 9221d7734a0SLars Ellenberg #define DRBD_SYNC_MARKS 8 9231d7734a0SLars Ellenberg #define DRBD_SYNC_MARK_STEP (3*HZ) 9241d7734a0SLars Ellenberg /* block not up-to-date at mark [unit BM_BLOCK_SIZE] */ 9251d7734a0SLars Ellenberg unsigned long rs_mark_left[DRBD_SYNC_MARKS]; 9261d7734a0SLars Ellenberg /* marks's time [unit jiffies] */ 9271d7734a0SLars Ellenberg unsigned long rs_mark_time[DRBD_SYNC_MARKS]; 9281d7734a0SLars Ellenberg /* current index into rs_mark_{left,time} */ 9291d7734a0SLars Ellenberg int rs_last_mark; 930b411b363SPhilipp Reisner 931b411b363SPhilipp Reisner /* where does the admin want us to start? (sector) */ 932b411b363SPhilipp Reisner sector_t ov_start_sector; 933b411b363SPhilipp Reisner /* where are we now? (sector) */ 934b411b363SPhilipp Reisner sector_t ov_position; 935b411b363SPhilipp Reisner /* Start sector of out of sync range (to merge printk reporting). */ 936b411b363SPhilipp Reisner sector_t ov_last_oos_start; 937b411b363SPhilipp Reisner /* size of out-of-sync range in sectors. */ 938b411b363SPhilipp Reisner sector_t ov_last_oos_size; 939b411b363SPhilipp Reisner unsigned long ov_left; /* in bits */ 940b411b363SPhilipp Reisner 941b411b363SPhilipp Reisner struct drbd_bitmap *bitmap; 942b411b363SPhilipp Reisner unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */ 943b411b363SPhilipp Reisner 944b411b363SPhilipp Reisner /* Used to track operations of resync... */ 945b411b363SPhilipp Reisner struct lru_cache *resync; 946b411b363SPhilipp Reisner /* Number of locked elements in resync LRU */ 947b411b363SPhilipp Reisner unsigned int resync_locked; 948b411b363SPhilipp Reisner /* resync extent number waiting for application requests */ 949b411b363SPhilipp Reisner unsigned int resync_wenr; 950b411b363SPhilipp Reisner 951b411b363SPhilipp Reisner int open_cnt; 952b411b363SPhilipp Reisner u64 *p_uuid; 953b411b363SPhilipp Reisner struct drbd_epoch *current_epoch; 954b411b363SPhilipp Reisner spinlock_t epoch_lock; 955b411b363SPhilipp Reisner unsigned int epochs; 956b411b363SPhilipp Reisner enum write_ordering_e write_ordering; 95785719573SPhilipp Reisner struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */ 95885719573SPhilipp Reisner struct list_head sync_ee; /* IO in progress (P_RS_DATA_REPLY gets written to disk) */ 95918b75d75SAndreas Gruenbacher struct list_head done_ee; /* need to send P_WRITE_ACK */ 96018b75d75SAndreas Gruenbacher struct list_head read_ee; /* [RS]P_DATA_REQUEST being read */ 961b411b363SPhilipp Reisner struct list_head net_ee; /* zero-copy network send in progress */ 962b411b363SPhilipp Reisner 963b411b363SPhilipp Reisner int next_barrier_nr; 964b411b363SPhilipp Reisner struct list_head resync_reads; 965435f0740SLars Ellenberg atomic_t pp_in_use; /* allocated from page pool */ 966435f0740SLars Ellenberg atomic_t pp_in_use_by_net; /* sendpage()d, still referenced by tcp */ 967b411b363SPhilipp Reisner wait_queue_head_t ee_wait; 968b411b363SPhilipp Reisner struct page *md_io_page; /* one page buffer for md_io */ 969b411b363SPhilipp Reisner struct mutex md_io_mutex; /* protects the md_io_buffer */ 970b411b363SPhilipp Reisner spinlock_t al_lock; 971b411b363SPhilipp Reisner wait_queue_head_t al_wait; 972b411b363SPhilipp Reisner struct lru_cache *act_log; /* activity log */ 973b411b363SPhilipp Reisner unsigned int al_tr_number; 974b411b363SPhilipp Reisner int al_tr_cycle; 975b411b363SPhilipp Reisner int al_tr_pos; /* position of the next transaction in the journal */ 976b411b363SPhilipp Reisner wait_queue_head_t seq_wait; 977b411b363SPhilipp Reisner atomic_t packet_seq; 978b411b363SPhilipp Reisner unsigned int peer_seq; 979b411b363SPhilipp Reisner spinlock_t peer_seq_lock; 980b411b363SPhilipp Reisner unsigned int minor; 981b411b363SPhilipp Reisner unsigned long comm_bm_set; /* communicated number of set bits. */ 982b411b363SPhilipp Reisner struct bm_io_work bm_io_work; 983b411b363SPhilipp Reisner u64 ed_uuid; /* UUID of the exposed data */ 9848410da8fSPhilipp Reisner struct mutex own_state_mutex; 9858410da8fSPhilipp Reisner struct mutex *state_mutex; /* either own_state_mutex or mdev->tconn->cstate_mutex */ 986b411b363SPhilipp Reisner char congestion_reason; /* Why we where congested... */ 9871d7734a0SLars Ellenberg atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */ 9881d7734a0SLars Ellenberg atomic_t rs_sect_ev; /* for submitted resync data rate, both */ 9891d7734a0SLars Ellenberg int rs_last_sect_ev; /* counter to compare with */ 9901d7734a0SLars Ellenberg int rs_last_events; /* counter of read or write "events" (unit sectors) 9911d7734a0SLars Ellenberg * on the lower level device when we last looked. */ 9921d7734a0SLars Ellenberg int c_sync_rate; /* current resync rate after syncer throttle magic */ 993778f271dSPhilipp Reisner struct fifo_buffer rs_plan_s; /* correction values of resync planer */ 994778f271dSPhilipp Reisner int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ 99525985edcSLucas De Marchi int rs_planed; /* resync sectors already planned */ 996759fbdfbSPhilipp Reisner atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ 99799432fccSPhilipp Reisner int peer_max_bio_size; 99899432fccSPhilipp Reisner int local_max_bio_size; 999b411b363SPhilipp Reisner }; 1000b411b363SPhilipp Reisner 1001b411b363SPhilipp Reisner static inline struct drbd_conf *minor_to_mdev(unsigned int minor) 1002b411b363SPhilipp Reisner { 100381a5d60eSPhilipp Reisner return (struct drbd_conf *)idr_find(&minors, minor); 1004b411b363SPhilipp Reisner } 1005b411b363SPhilipp Reisner 1006b411b363SPhilipp Reisner static inline unsigned int mdev_to_minor(struct drbd_conf *mdev) 1007b411b363SPhilipp Reisner { 1008b411b363SPhilipp Reisner return mdev->minor; 1009b411b363SPhilipp Reisner } 1010b411b363SPhilipp Reisner 1011eefc2f7dSPhilipp Reisner static inline struct drbd_conf *vnr_to_mdev(struct drbd_tconn *tconn, int vnr) 1012eefc2f7dSPhilipp Reisner { 1013eefc2f7dSPhilipp Reisner return (struct drbd_conf *)idr_find(&tconn->volumes, vnr); 1014eefc2f7dSPhilipp Reisner } 1015eefc2f7dSPhilipp Reisner 1016b411b363SPhilipp Reisner /* 1017b411b363SPhilipp Reisner * function declarations 1018b411b363SPhilipp Reisner *************************/ 1019b411b363SPhilipp Reisner 1020b411b363SPhilipp Reisner /* drbd_main.c */ 1021b411b363SPhilipp Reisner 1022e89b591cSPhilipp Reisner enum dds_flags { 1023e89b591cSPhilipp Reisner DDSF_FORCED = 1, 1024e89b591cSPhilipp Reisner DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */ 1025e89b591cSPhilipp Reisner }; 1026e89b591cSPhilipp Reisner 1027b411b363SPhilipp Reisner extern void drbd_init_set_defaults(struct drbd_conf *mdev); 1028b411b363SPhilipp Reisner extern int drbd_thread_start(struct drbd_thread *thi); 1029b411b363SPhilipp Reisner extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait); 1030392c8801SPhilipp Reisner extern char *drbd_task_to_thread_name(struct drbd_tconn *tconn, struct task_struct *task); 1031b411b363SPhilipp Reisner #ifdef CONFIG_SMP 103280822284SPhilipp Reisner extern void drbd_thread_current_set_cpu(struct drbd_thread *thi); 103380822284SPhilipp Reisner extern void drbd_calc_cpu_mask(struct drbd_tconn *tconn); 1034b411b363SPhilipp Reisner #else 103580822284SPhilipp Reisner #define drbd_thread_current_set_cpu(A) ({}) 1036b411b363SPhilipp Reisner #define drbd_calc_cpu_mask(A) ({}) 1037b411b363SPhilipp Reisner #endif 1038b411b363SPhilipp Reisner extern void drbd_free_resources(struct drbd_conf *mdev); 10392f5cdd0bSPhilipp Reisner extern void tl_release(struct drbd_tconn *, unsigned int barrier_nr, 1040b411b363SPhilipp Reisner unsigned int set_size); 10412f5cdd0bSPhilipp Reisner extern void tl_clear(struct drbd_tconn *); 10422f5cdd0bSPhilipp Reisner extern void _tl_add_barrier(struct drbd_tconn *, struct drbd_tl_epoch *); 1043360cc740SPhilipp Reisner extern void drbd_free_sock(struct drbd_tconn *tconn); 1044bedbd2a5SPhilipp Reisner extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock, 1045b411b363SPhilipp Reisner void *buf, size_t size, unsigned msg_flags); 1046fb708e40SAndreas Gruenbacher extern int drbd_send_all(struct drbd_tconn *, struct socket *, void *, size_t, 1047fb708e40SAndreas Gruenbacher unsigned); 1048fb708e40SAndreas Gruenbacher 1049dc8228d1SPhilipp Reisner extern int drbd_send_protocol(struct drbd_tconn *tconn); 1050b411b363SPhilipp Reisner extern int drbd_send_uuids(struct drbd_conf *mdev); 1051b411b363SPhilipp Reisner extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev); 10529c1b7f72SAndreas Gruenbacher extern void drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev); 1053e89b591cSPhilipp Reisner extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags); 1054cf29c9d8SPhilipp Reisner extern int _conn_send_state_req(struct drbd_tconn *, int vnr, enum drbd_packet cmd, 1055cf29c9d8SPhilipp Reisner union drbd_state, union drbd_state); 1056b411b363SPhilipp Reisner extern int _drbd_send_state(struct drbd_conf *mdev); 1057b411b363SPhilipp Reisner extern int drbd_send_state(struct drbd_conf *mdev); 1058f399002eSLars Ellenberg extern int drbd_send_sync_param(struct drbd_conf *mdev); 1059d4e67d7cSAndreas Gruenbacher extern void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, 1060b411b363SPhilipp Reisner u32 set_size); 1061f6ffca9fSAndreas Gruenbacher extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet, 1062f6ffca9fSAndreas Gruenbacher struct drbd_peer_request *); 1063a9a9994dSAndreas Gruenbacher extern void drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd, 1064b411b363SPhilipp Reisner struct p_block_req *rp); 1065a9a9994dSAndreas Gruenbacher extern void drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd, 10662b2bf214SLars Ellenberg struct p_data *dp, int data_size); 1067d8763023SAndreas Gruenbacher extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packet cmd, 1068b411b363SPhilipp Reisner sector_t sector, int blksize, u64 block_id); 10698f7bed77SAndreas Gruenbacher extern int drbd_send_out_of_sync(struct drbd_conf *, struct drbd_request *); 1070f6ffca9fSAndreas Gruenbacher extern int drbd_send_block(struct drbd_conf *, enum drbd_packet, 1071f6ffca9fSAndreas Gruenbacher struct drbd_peer_request *); 1072b411b363SPhilipp Reisner extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req); 1073b411b363SPhilipp Reisner extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd, 1074b411b363SPhilipp Reisner sector_t sector, int size, u64 block_id); 1075d8763023SAndreas Gruenbacher extern int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector, 1076d8763023SAndreas Gruenbacher int size, void *digest, int digest_size, 1077d8763023SAndreas Gruenbacher enum drbd_packet cmd); 1078b411b363SPhilipp Reisner extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size); 1079b411b363SPhilipp Reisner 1080b411b363SPhilipp Reisner extern int drbd_send_bitmap(struct drbd_conf *mdev); 10812f4e7abeSAndreas Gruenbacher extern void drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode); 10829f5bdc33SAndreas Gruenbacher extern void conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode); 1083b411b363SPhilipp Reisner extern void drbd_free_bc(struct drbd_backing_dev *ldev); 1084b411b363SPhilipp Reisner extern void drbd_mdev_cleanup(struct drbd_conf *mdev); 108562b0da3aSLars Ellenberg void drbd_print_uuids(struct drbd_conf *mdev, const char *text); 1086b411b363SPhilipp Reisner 1087b411b363SPhilipp Reisner extern void drbd_md_sync(struct drbd_conf *mdev); 1088b411b363SPhilipp Reisner extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); 1089b411b363SPhilipp Reisner extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); 1090b411b363SPhilipp Reisner extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); 1091b411b363SPhilipp Reisner extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); 1092b411b363SPhilipp Reisner extern void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); 1093b411b363SPhilipp Reisner extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local); 1094b411b363SPhilipp Reisner extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); 1095b411b363SPhilipp Reisner extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); 1096b411b363SPhilipp Reisner extern int drbd_md_test_flag(struct drbd_backing_dev *, int); 1097ee15b038SLars Ellenberg #ifndef DRBD_DEBUG_MD_SYNC 1098b411b363SPhilipp Reisner extern void drbd_md_mark_dirty(struct drbd_conf *mdev); 1099ee15b038SLars Ellenberg #else 1100ee15b038SLars Ellenberg #define drbd_md_mark_dirty(m) drbd_md_mark_dirty_(m, __LINE__ , __func__ ) 1101ee15b038SLars Ellenberg extern void drbd_md_mark_dirty_(struct drbd_conf *mdev, 1102ee15b038SLars Ellenberg unsigned int line, const char *func); 1103ee15b038SLars Ellenberg #endif 1104b411b363SPhilipp Reisner extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, 1105b411b363SPhilipp Reisner int (*io_fn)(struct drbd_conf *), 1106b411b363SPhilipp Reisner void (*done)(struct drbd_conf *, int), 110720ceb2b2SLars Ellenberg char *why, enum bm_flag flags); 110820ceb2b2SLars Ellenberg extern int drbd_bitmap_io(struct drbd_conf *mdev, 110920ceb2b2SLars Ellenberg int (*io_fn)(struct drbd_conf *), 111020ceb2b2SLars Ellenberg char *why, enum bm_flag flags); 1111b411b363SPhilipp Reisner extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); 1112b411b363SPhilipp Reisner extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); 1113e9e6f3ecSLars Ellenberg extern void drbd_go_diskless(struct drbd_conf *mdev); 111482f59cc6SLars Ellenberg extern void drbd_ldev_destroy(struct drbd_conf *mdev); 1115b411b363SPhilipp Reisner 1116b411b363SPhilipp Reisner /* Meta data layout 1117b411b363SPhilipp Reisner We reserve a 128MB Block (4k aligned) 1118b411b363SPhilipp Reisner * either at the end of the backing device 11193ad2f3fbSDaniel Mack * or on a separate meta data device. */ 1120b411b363SPhilipp Reisner 1121b411b363SPhilipp Reisner /* The following numbers are sectors */ 11227ad651b5SLars Ellenberg /* Allows up to about 3.8TB, so if you want more, 11237ad651b5SLars Ellenberg * you need to use the "flexible" meta data format. */ 11247ad651b5SLars Ellenberg #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ 1125b411b363SPhilipp Reisner #define MD_AL_OFFSET 8 /* 8 Sectors after start of meta area */ 11267ad651b5SLars Ellenberg #define MD_AL_SECTORS 64 /* = 32 kB on disk activity log ring buffer */ 11277ad651b5SLars Ellenberg #define MD_BM_OFFSET (MD_AL_OFFSET + MD_AL_SECTORS) 1128b411b363SPhilipp Reisner 11297ad651b5SLars Ellenberg /* we do all meta data IO in 4k blocks */ 11307ad651b5SLars Ellenberg #define MD_BLOCK_SHIFT 12 11317ad651b5SLars Ellenberg #define MD_BLOCK_SIZE (1<<MD_BLOCK_SHIFT) 1132b411b363SPhilipp Reisner 11337ad651b5SLars Ellenberg /* One activity log extent represents 4M of storage */ 11347ad651b5SLars Ellenberg #define AL_EXTENT_SHIFT 22 1135b411b363SPhilipp Reisner #define AL_EXTENT_SIZE (1<<AL_EXTENT_SHIFT) 1136b411b363SPhilipp Reisner 11377ad651b5SLars Ellenberg /* We could make these currently hardcoded constants configurable 11387ad651b5SLars Ellenberg * variables at create-md time (or even re-configurable at runtime?). 11397ad651b5SLars Ellenberg * Which will require some more changes to the DRBD "super block" 11407ad651b5SLars Ellenberg * and attach code. 11417ad651b5SLars Ellenberg * 11427ad651b5SLars Ellenberg * updates per transaction: 11437ad651b5SLars Ellenberg * This many changes to the active set can be logged with one transaction. 11447ad651b5SLars Ellenberg * This number is arbitrary. 11457ad651b5SLars Ellenberg * context per transaction: 11467ad651b5SLars Ellenberg * This many context extent numbers are logged with each transaction. 11477ad651b5SLars Ellenberg * This number is resulting from the transaction block size (4k), the layout 11487ad651b5SLars Ellenberg * of the transaction header, and the number of updates per transaction. 11497ad651b5SLars Ellenberg * See drbd_actlog.c:struct al_transaction_on_disk 11507ad651b5SLars Ellenberg * */ 11517ad651b5SLars Ellenberg #define AL_UPDATES_PER_TRANSACTION 64 // arbitrary 11527ad651b5SLars Ellenberg #define AL_CONTEXT_PER_TRANSACTION 919 // (4096 - 36 - 6*64)/4 11537ad651b5SLars Ellenberg 1154b411b363SPhilipp Reisner #if BITS_PER_LONG == 32 1155b411b363SPhilipp Reisner #define LN2_BPL 5 1156b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le32(A) 1157b411b363SPhilipp Reisner #define lel_to_cpu(A) le32_to_cpu(A) 1158b411b363SPhilipp Reisner #elif BITS_PER_LONG == 64 1159b411b363SPhilipp Reisner #define LN2_BPL 6 1160b411b363SPhilipp Reisner #define cpu_to_lel(A) cpu_to_le64(A) 1161b411b363SPhilipp Reisner #define lel_to_cpu(A) le64_to_cpu(A) 1162b411b363SPhilipp Reisner #else 1163b411b363SPhilipp Reisner #error "LN2 of BITS_PER_LONG unknown!" 1164b411b363SPhilipp Reisner #endif 1165b411b363SPhilipp Reisner 1166b411b363SPhilipp Reisner /* resync bitmap */ 1167b411b363SPhilipp Reisner /* 16MB sized 'bitmap extent' to track syncer usage */ 1168b411b363SPhilipp Reisner struct bm_extent { 1169b411b363SPhilipp Reisner int rs_left; /* number of bits set (out of sync) in this extent. */ 1170b411b363SPhilipp Reisner int rs_failed; /* number of failed resync requests in this extent. */ 1171b411b363SPhilipp Reisner unsigned long flags; 1172b411b363SPhilipp Reisner struct lc_element lce; 1173b411b363SPhilipp Reisner }; 1174b411b363SPhilipp Reisner 1175b411b363SPhilipp Reisner #define BME_NO_WRITES 0 /* bm_extent.flags: no more requests on this one! */ 1176b411b363SPhilipp Reisner #define BME_LOCKED 1 /* bm_extent.flags: syncer active on this one. */ 1177e3555d85SPhilipp Reisner #define BME_PRIORITY 2 /* finish resync IO on this extent ASAP! App IO waiting! */ 1178b411b363SPhilipp Reisner 1179b411b363SPhilipp Reisner /* drbd_bitmap.c */ 1180b411b363SPhilipp Reisner /* 1181b411b363SPhilipp Reisner * We need to store one bit for a block. 1182b411b363SPhilipp Reisner * Example: 1GB disk @ 4096 byte blocks ==> we need 32 KB bitmap. 1183b411b363SPhilipp Reisner * Bit 0 ==> local node thinks this block is binary identical on both nodes 1184b411b363SPhilipp Reisner * Bit 1 ==> local node thinks this block needs to be synced. 1185b411b363SPhilipp Reisner */ 1186b411b363SPhilipp Reisner 11878e26f9ccSPhilipp Reisner #define SLEEP_TIME (HZ/10) 11888e26f9ccSPhilipp Reisner 118945dfffebSLars Ellenberg /* We do bitmap IO in units of 4k blocks. 119045dfffebSLars Ellenberg * We also still have a hardcoded 4k per bit relation. */ 1191b411b363SPhilipp Reisner #define BM_BLOCK_SHIFT 12 /* 4k per bit */ 1192b411b363SPhilipp Reisner #define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) 119345dfffebSLars Ellenberg /* mostly arbitrarily set the represented size of one bitmap extent, 119445dfffebSLars Ellenberg * aka resync extent, to 16 MiB (which is also 512 Byte worth of bitmap 119545dfffebSLars Ellenberg * at 4k per bit resolution) */ 119645dfffebSLars Ellenberg #define BM_EXT_SHIFT 24 /* 16 MiB per resync extent */ 1197b411b363SPhilipp Reisner #define BM_EXT_SIZE (1<<BM_EXT_SHIFT) 1198b411b363SPhilipp Reisner 1199b411b363SPhilipp Reisner #if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12) 1200b411b363SPhilipp Reisner #error "HAVE YOU FIXED drbdmeta AS WELL??" 1201b411b363SPhilipp Reisner #endif 1202b411b363SPhilipp Reisner 1203b411b363SPhilipp Reisner /* thus many _storage_ sectors are described by one bit */ 1204b411b363SPhilipp Reisner #define BM_SECT_TO_BIT(x) ((x)>>(BM_BLOCK_SHIFT-9)) 1205b411b363SPhilipp Reisner #define BM_BIT_TO_SECT(x) ((sector_t)(x)<<(BM_BLOCK_SHIFT-9)) 1206b411b363SPhilipp Reisner #define BM_SECT_PER_BIT BM_BIT_TO_SECT(1) 1207b411b363SPhilipp Reisner 1208b411b363SPhilipp Reisner /* bit to represented kilo byte conversion */ 1209b411b363SPhilipp Reisner #define Bit2KB(bits) ((bits)<<(BM_BLOCK_SHIFT-10)) 1210b411b363SPhilipp Reisner 1211b411b363SPhilipp Reisner /* in which _bitmap_ extent (resp. sector) the bit for a certain 1212b411b363SPhilipp Reisner * _storage_ sector is located in */ 1213b411b363SPhilipp Reisner #define BM_SECT_TO_EXT(x) ((x)>>(BM_EXT_SHIFT-9)) 1214b411b363SPhilipp Reisner 1215b411b363SPhilipp Reisner /* how much _storage_ sectors we have per bitmap sector */ 1216b411b363SPhilipp Reisner #define BM_EXT_TO_SECT(x) ((sector_t)(x) << (BM_EXT_SHIFT-9)) 1217b411b363SPhilipp Reisner #define BM_SECT_PER_EXT BM_EXT_TO_SECT(1) 1218b411b363SPhilipp Reisner 1219b411b363SPhilipp Reisner /* in one sector of the bitmap, we have this many activity_log extents. */ 1220b411b363SPhilipp Reisner #define AL_EXT_PER_BM_SECT (1 << (BM_EXT_SHIFT - AL_EXTENT_SHIFT)) 1221b411b363SPhilipp Reisner #define BM_WORDS_PER_AL_EXT (1 << (AL_EXTENT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) 1222b411b363SPhilipp Reisner 1223b411b363SPhilipp Reisner #define BM_BLOCKS_PER_BM_EXT_B (BM_EXT_SHIFT - BM_BLOCK_SHIFT) 1224b411b363SPhilipp Reisner #define BM_BLOCKS_PER_BM_EXT_MASK ((1<<BM_BLOCKS_PER_BM_EXT_B) - 1) 1225b411b363SPhilipp Reisner 1226b411b363SPhilipp Reisner /* the extent in "PER_EXTENT" below is an activity log extent 1227b411b363SPhilipp Reisner * we need that many (long words/bytes) to store the bitmap 1228b411b363SPhilipp Reisner * of one AL_EXTENT_SIZE chunk of storage. 1229b411b363SPhilipp Reisner * we can store the bitmap for that many AL_EXTENTS within 1230b411b363SPhilipp Reisner * one sector of the _on_disk_ bitmap: 1231b411b363SPhilipp Reisner * bit 0 bit 37 bit 38 bit (512*8)-1 1232b411b363SPhilipp Reisner * ...|........|........|.. // ..|........| 1233b411b363SPhilipp Reisner * sect. 0 `296 `304 ^(512*8*8)-1 1234b411b363SPhilipp Reisner * 1235b411b363SPhilipp Reisner #define BM_WORDS_PER_EXT ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / BITS_PER_LONG ) 1236b411b363SPhilipp Reisner #define BM_BYTES_PER_EXT ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / 8 ) // 128 1237b411b363SPhilipp Reisner #define BM_EXT_PER_SECT ( 512 / BM_BYTES_PER_EXTENT ) // 4 1238b411b363SPhilipp Reisner */ 1239b411b363SPhilipp Reisner 1240b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_32 (0xffffffffLU) 1241b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_BM \ 1242b411b363SPhilipp Reisner ((MD_RESERVED_SECT - MD_BM_OFFSET) * (1LL<<(BM_EXT_SHIFT-9))) 1243b411b363SPhilipp Reisner #if DRBD_MAX_SECTORS_BM < DRBD_MAX_SECTORS_32 1244b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS DRBD_MAX_SECTORS_BM 1245b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_BM 124636bfc7e2SLars Ellenberg #elif !defined(CONFIG_LBDAF) && BITS_PER_LONG == 32 1247b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS DRBD_MAX_SECTORS_32 1248b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_32 1249b411b363SPhilipp Reisner #else 1250b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS DRBD_MAX_SECTORS_BM 1251b411b363SPhilipp Reisner /* 16 TB in units of sectors */ 1252b411b363SPhilipp Reisner #if BITS_PER_LONG == 32 1253b411b363SPhilipp Reisner /* adjust by one page worth of bitmap, 1254b411b363SPhilipp Reisner * so we won't wrap around in drbd_bm_find_next_bit. 1255b411b363SPhilipp Reisner * you should use 64bit OS for that much storage, anyways. */ 1256b411b363SPhilipp Reisner #define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff) 1257b411b363SPhilipp Reisner #else 12584b0715f0SLars Ellenberg /* we allow up to 1 PiB now on 64bit architecture with "flexible" meta data */ 12594b0715f0SLars Ellenberg #define DRBD_MAX_SECTORS_FLEX (1UL << 51) 12604b0715f0SLars Ellenberg /* corresponds to (1UL << 38) bits right now. */ 1261b411b363SPhilipp Reisner #endif 1262b411b363SPhilipp Reisner #endif 1263b411b363SPhilipp Reisner 126423361cf3SLars Ellenberg /* BIO_MAX_SIZE is 256 * PAGE_CACHE_SIZE, 126523361cf3SLars Ellenberg * so for typical PAGE_CACHE_SIZE of 4k, that is (1<<20) Byte. 126623361cf3SLars Ellenberg * Since we may live in a mixed-platform cluster, 126723361cf3SLars Ellenberg * we limit us to a platform agnostic constant here for now. 126823361cf3SLars Ellenberg * A followup commit may allow even bigger BIO sizes, 126923361cf3SLars Ellenberg * once we thought that through. */ 127023361cf3SLars Ellenberg #define DRBD_MAX_BIO_SIZE (1 << 20) 127123361cf3SLars Ellenberg #if DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE 127223361cf3SLars Ellenberg #error Architecture not supported: DRBD_MAX_BIO_SIZE > BIO_MAX_SIZE 127323361cf3SLars Ellenberg #endif 127499432fccSPhilipp Reisner #define DRBD_MAX_BIO_SIZE_SAFE (1 << 12) /* Works always = 4k */ 1275b411b363SPhilipp Reisner 1276d5373389SPhilipp Reisner #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */ 1277d5373389SPhilipp Reisner 1278b411b363SPhilipp Reisner extern int drbd_bm_init(struct drbd_conf *mdev); 127902d9a94bSPhilipp Reisner extern int drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors, int set_new_bits); 1280b411b363SPhilipp Reisner extern void drbd_bm_cleanup(struct drbd_conf *mdev); 1281b411b363SPhilipp Reisner extern void drbd_bm_set_all(struct drbd_conf *mdev); 1282b411b363SPhilipp Reisner extern void drbd_bm_clear_all(struct drbd_conf *mdev); 12834b0715f0SLars Ellenberg /* set/clear/test only a few bits at a time */ 1284b411b363SPhilipp Reisner extern int drbd_bm_set_bits( 1285b411b363SPhilipp Reisner struct drbd_conf *mdev, unsigned long s, unsigned long e); 1286b411b363SPhilipp Reisner extern int drbd_bm_clear_bits( 1287b411b363SPhilipp Reisner struct drbd_conf *mdev, unsigned long s, unsigned long e); 12884b0715f0SLars Ellenberg extern int drbd_bm_count_bits( 12894b0715f0SLars Ellenberg struct drbd_conf *mdev, const unsigned long s, const unsigned long e); 12904b0715f0SLars Ellenberg /* bm_set_bits variant for use while holding drbd_bm_lock, 12914b0715f0SLars Ellenberg * may process the whole bitmap in one go */ 1292b411b363SPhilipp Reisner extern void _drbd_bm_set_bits(struct drbd_conf *mdev, 1293b411b363SPhilipp Reisner const unsigned long s, const unsigned long e); 1294b411b363SPhilipp Reisner extern int drbd_bm_test_bit(struct drbd_conf *mdev, unsigned long bitnr); 1295b411b363SPhilipp Reisner extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr); 129619f843aaSLars Ellenberg extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); 1297b411b363SPhilipp Reisner extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); 129845dfffebSLars Ellenberg extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr); 1299b411b363SPhilipp Reisner extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); 130045dfffebSLars Ellenberg extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local); 1301b411b363SPhilipp Reisner extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, 1302b411b363SPhilipp Reisner unsigned long al_enr); 1303b411b363SPhilipp Reisner extern size_t drbd_bm_words(struct drbd_conf *mdev); 1304b411b363SPhilipp Reisner extern unsigned long drbd_bm_bits(struct drbd_conf *mdev); 1305b411b363SPhilipp Reisner extern sector_t drbd_bm_capacity(struct drbd_conf *mdev); 13064b0715f0SLars Ellenberg 13074b0715f0SLars Ellenberg #define DRBD_END_OF_BITMAP (~(unsigned long)0) 1308b411b363SPhilipp Reisner extern unsigned long drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); 1309b411b363SPhilipp Reisner /* bm_find_next variants for use while you hold drbd_bm_lock() */ 1310b411b363SPhilipp Reisner extern unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); 1311b411b363SPhilipp Reisner extern unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo); 13120778286aSPhilipp Reisner extern unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev); 1313b411b363SPhilipp Reisner extern unsigned long drbd_bm_total_weight(struct drbd_conf *mdev); 1314b411b363SPhilipp Reisner extern int drbd_bm_rs_done(struct drbd_conf *mdev); 1315b411b363SPhilipp Reisner /* for receive_bitmap */ 1316b411b363SPhilipp Reisner extern void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, 1317b411b363SPhilipp Reisner size_t number, unsigned long *buffer); 131819f843aaSLars Ellenberg /* for _drbd_send_bitmap */ 1319b411b363SPhilipp Reisner extern void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, 1320b411b363SPhilipp Reisner size_t number, unsigned long *buffer); 1321b411b363SPhilipp Reisner 132220ceb2b2SLars Ellenberg extern void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags); 1323b411b363SPhilipp Reisner extern void drbd_bm_unlock(struct drbd_conf *mdev); 1324b411b363SPhilipp Reisner /* drbd_main.c */ 1325b411b363SPhilipp Reisner 1326b411b363SPhilipp Reisner extern struct kmem_cache *drbd_request_cache; 13276c852becSAndreas Gruenbacher extern struct kmem_cache *drbd_ee_cache; /* peer requests */ 1328b411b363SPhilipp Reisner extern struct kmem_cache *drbd_bm_ext_cache; /* bitmap extents */ 1329b411b363SPhilipp Reisner extern struct kmem_cache *drbd_al_ext_cache; /* activity log extents */ 1330b411b363SPhilipp Reisner extern mempool_t *drbd_request_mempool; 1331b411b363SPhilipp Reisner extern mempool_t *drbd_ee_mempool; 1332b411b363SPhilipp Reisner 133335abf594SLars Ellenberg /* drbd's page pool, used to buffer data received from the peer, 133435abf594SLars Ellenberg * or data requested by the peer. 133535abf594SLars Ellenberg * 133635abf594SLars Ellenberg * This does not have an emergency reserve. 133735abf594SLars Ellenberg * 133835abf594SLars Ellenberg * When allocating from this pool, it first takes pages from the pool. 133935abf594SLars Ellenberg * Only if the pool is depleted will try to allocate from the system. 134035abf594SLars Ellenberg * 134135abf594SLars Ellenberg * The assumption is that pages taken from this pool will be processed, 134235abf594SLars Ellenberg * and given back, "quickly", and then can be recycled, so we can avoid 134335abf594SLars Ellenberg * frequent calls to alloc_page(), and still will be able to make progress even 134435abf594SLars Ellenberg * under memory pressure. 134535abf594SLars Ellenberg */ 134635abf594SLars Ellenberg extern struct page *drbd_pp_pool; 1347b411b363SPhilipp Reisner extern spinlock_t drbd_pp_lock; 1348b411b363SPhilipp Reisner extern int drbd_pp_vacant; 1349b411b363SPhilipp Reisner extern wait_queue_head_t drbd_pp_wait; 1350b411b363SPhilipp Reisner 135135abf594SLars Ellenberg /* We also need a standard (emergency-reserve backed) page pool 135235abf594SLars Ellenberg * for meta data IO (activity log, bitmap). 135335abf594SLars Ellenberg * We can keep it global, as long as it is used as "N pages at a time". 135435abf594SLars Ellenberg * 128 should be plenty, currently we probably can get away with as few as 1. 135535abf594SLars Ellenberg */ 135635abf594SLars Ellenberg #define DRBD_MIN_POOL_PAGES 128 135735abf594SLars Ellenberg extern mempool_t *drbd_md_io_page_pool; 135835abf594SLars Ellenberg 1359da4a75d2SLars Ellenberg /* We also need to make sure we get a bio 1360da4a75d2SLars Ellenberg * when we need it for housekeeping purposes */ 1361da4a75d2SLars Ellenberg extern struct bio_set *drbd_md_io_bio_set; 1362da4a75d2SLars Ellenberg /* to allocate from that set */ 1363da4a75d2SLars Ellenberg extern struct bio *bio_alloc_drbd(gfp_t gfp_mask); 1364da4a75d2SLars Ellenberg 1365b411b363SPhilipp Reisner extern rwlock_t global_state_lock; 1366b411b363SPhilipp Reisner 136780883197SPhilipp Reisner extern int conn_lowest_minor(struct drbd_tconn *tconn); 1368774b3055SPhilipp Reisner enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr); 1369b411b363SPhilipp Reisner extern void drbd_free_mdev(struct drbd_conf *mdev); 1370774b3055SPhilipp Reisner extern void drbd_delete_device(unsigned int minor); 1371b411b363SPhilipp Reisner 13723b98c0c2SLars Ellenberg struct drbd_tconn *drbd_new_tconn(const char *name); 13732111438bSPhilipp Reisner extern void drbd_free_tconn(struct drbd_tconn *tconn); 13741aba4d7fSPhilipp Reisner struct drbd_tconn *conn_by_name(const char *name); 13752111438bSPhilipp Reisner 1376b411b363SPhilipp Reisner extern int proc_details; 1377b411b363SPhilipp Reisner 1378b411b363SPhilipp Reisner /* drbd_req */ 13797be8da07SAndreas Gruenbacher extern int __drbd_make_request(struct drbd_conf *, struct bio *, unsigned long); 13802f58dcfcSAndreas Gruenbacher extern int drbd_make_request(struct request_queue *q, struct bio *bio); 1381b411b363SPhilipp Reisner extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); 1382b411b363SPhilipp Reisner extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec); 1383b411b363SPhilipp Reisner extern int is_valid_ar_handle(struct drbd_request *, sector_t); 1384b411b363SPhilipp Reisner 1385b411b363SPhilipp Reisner 1386b411b363SPhilipp Reisner /* drbd_nl.c */ 13878432b314SLars Ellenberg extern int drbd_msg_put_info(const char *info); 1388b411b363SPhilipp Reisner extern void drbd_suspend_io(struct drbd_conf *mdev); 1389b411b363SPhilipp Reisner extern void drbd_resume_io(struct drbd_conf *mdev); 1390b411b363SPhilipp Reisner extern char *ppsize(char *buf, unsigned long long size); 1391a393db6fSPhilipp Reisner extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int); 1392b411b363SPhilipp Reisner enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; 139324c4830cSBart Van Assche extern enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); 1394b411b363SPhilipp Reisner extern void resync_after_online_grow(struct drbd_conf *); 139599432fccSPhilipp Reisner extern void drbd_reconsider_max_bio_size(struct drbd_conf *mdev); 1396bf885f8aSAndreas Gruenbacher extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev, 1397bf885f8aSAndreas Gruenbacher enum drbd_role new_role, 1398b411b363SPhilipp Reisner int force); 1399cb703454SPhilipp Reisner extern bool conn_try_outdate_peer(struct drbd_tconn *tconn); 1400cb703454SPhilipp Reisner extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn); 1401b411b363SPhilipp Reisner extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); 1402b411b363SPhilipp Reisner 1403b411b363SPhilipp Reisner /* drbd_worker.c */ 1404b411b363SPhilipp Reisner extern int drbd_worker(struct drbd_thread *thi); 1405b411b363SPhilipp Reisner extern int drbd_alter_sa(struct drbd_conf *mdev, int na); 1406b411b363SPhilipp Reisner extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side); 1407b411b363SPhilipp Reisner extern void resume_next_sg(struct drbd_conf *mdev); 1408b411b363SPhilipp Reisner extern void suspend_other_sg(struct drbd_conf *mdev); 1409b411b363SPhilipp Reisner extern int drbd_resync_finished(struct drbd_conf *mdev); 1410b411b363SPhilipp Reisner /* maybe rather drbd_main.c ? */ 1411b411b363SPhilipp Reisner extern int drbd_md_sync_page_io(struct drbd_conf *mdev, 1412b411b363SPhilipp Reisner struct drbd_backing_dev *bdev, sector_t sector, int rw); 14138f7bed77SAndreas Gruenbacher extern void drbd_ov_out_of_sync_found(struct drbd_conf *, sector_t, int); 14149bd28d3cSLars Ellenberg extern void drbd_rs_controller_reset(struct drbd_conf *mdev); 1415b411b363SPhilipp Reisner 14168f7bed77SAndreas Gruenbacher static inline void ov_out_of_sync_print(struct drbd_conf *mdev) 1417b411b363SPhilipp Reisner { 1418b411b363SPhilipp Reisner if (mdev->ov_last_oos_size) { 1419b411b363SPhilipp Reisner dev_err(DEV, "Out of sync: start=%llu, size=%lu (sectors)\n", 1420b411b363SPhilipp Reisner (unsigned long long)mdev->ov_last_oos_start, 1421b411b363SPhilipp Reisner (unsigned long)mdev->ov_last_oos_size); 1422b411b363SPhilipp Reisner } 1423b411b363SPhilipp Reisner mdev->ov_last_oos_size=0; 1424b411b363SPhilipp Reisner } 1425b411b363SPhilipp Reisner 1426b411b363SPhilipp Reisner 142745bb912bSLars Ellenberg extern void drbd_csum_bio(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); 1428f6ffca9fSAndreas Gruenbacher extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *, 1429f6ffca9fSAndreas Gruenbacher struct drbd_peer_request *, void *); 1430b411b363SPhilipp Reisner /* worker callbacks */ 143199920dc5SAndreas Gruenbacher extern int w_read_retry_remote(struct drbd_work *, int); 143299920dc5SAndreas Gruenbacher extern int w_e_end_data_req(struct drbd_work *, int); 143399920dc5SAndreas Gruenbacher extern int w_e_end_rsdata_req(struct drbd_work *, int); 143499920dc5SAndreas Gruenbacher extern int w_e_end_csum_rs_req(struct drbd_work *, int); 143599920dc5SAndreas Gruenbacher extern int w_e_end_ov_reply(struct drbd_work *, int); 143699920dc5SAndreas Gruenbacher extern int w_e_end_ov_req(struct drbd_work *, int); 143799920dc5SAndreas Gruenbacher extern int w_ov_finished(struct drbd_work *, int); 143899920dc5SAndreas Gruenbacher extern int w_resync_timer(struct drbd_work *, int); 143999920dc5SAndreas Gruenbacher extern int w_send_write_hint(struct drbd_work *, int); 144099920dc5SAndreas Gruenbacher extern int w_make_resync_request(struct drbd_work *, int); 144199920dc5SAndreas Gruenbacher extern int w_send_dblock(struct drbd_work *, int); 144299920dc5SAndreas Gruenbacher extern int w_send_barrier(struct drbd_work *, int); 144399920dc5SAndreas Gruenbacher extern int w_send_read_req(struct drbd_work *, int); 144499920dc5SAndreas Gruenbacher extern int w_prev_work_done(struct drbd_work *, int); 144599920dc5SAndreas Gruenbacher extern int w_e_reissue(struct drbd_work *, int); 144699920dc5SAndreas Gruenbacher extern int w_restart_disk_io(struct drbd_work *, int); 14478f7bed77SAndreas Gruenbacher extern int w_send_out_of_sync(struct drbd_work *, int); 144899920dc5SAndreas Gruenbacher extern int w_start_resync(struct drbd_work *, int); 1449b411b363SPhilipp Reisner 1450b411b363SPhilipp Reisner extern void resync_timer_fn(unsigned long data); 1451370a43e7SPhilipp Reisner extern void start_resync_timer_fn(unsigned long data); 1452b411b363SPhilipp Reisner 1453b411b363SPhilipp Reisner /* drbd_receiver.c */ 1454e3555d85SPhilipp Reisner extern int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector); 1455fbe29decSAndreas Gruenbacher extern int drbd_submit_peer_request(struct drbd_conf *, 1456fbe29decSAndreas Gruenbacher struct drbd_peer_request *, const unsigned, 1457fbe29decSAndreas Gruenbacher const int); 1458b411b363SPhilipp Reisner extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); 1459f6ffca9fSAndreas Gruenbacher extern struct drbd_peer_request *drbd_alloc_ee(struct drbd_conf *, 1460f6ffca9fSAndreas Gruenbacher u64, sector_t, unsigned int, 1461f6ffca9fSAndreas Gruenbacher gfp_t) __must_hold(local); 1462f6ffca9fSAndreas Gruenbacher extern void drbd_free_some_ee(struct drbd_conf *, struct drbd_peer_request *, 1463f6ffca9fSAndreas Gruenbacher int); 1464435f0740SLars Ellenberg #define drbd_free_ee(m,e) drbd_free_some_ee(m, e, 0) 1465435f0740SLars Ellenberg #define drbd_free_net_ee(m,e) drbd_free_some_ee(m, e, 1) 1466b411b363SPhilipp Reisner extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev, 1467b411b363SPhilipp Reisner struct list_head *head); 1468b411b363SPhilipp Reisner extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, 1469b411b363SPhilipp Reisner struct list_head *head); 1470b411b363SPhilipp Reisner extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled); 1471b411b363SPhilipp Reisner extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed); 14720e29d163SPhilipp Reisner extern void conn_flush_workqueue(struct drbd_tconn *tconn); 14732325eb66SPhilipp Reisner extern int drbd_connected(int vnr, void *p, void *data); 14740e29d163SPhilipp Reisner static inline void drbd_flush_workqueue(struct drbd_conf *mdev) 14750e29d163SPhilipp Reisner { 14760e29d163SPhilipp Reisner conn_flush_workqueue(mdev->tconn); 14770e29d163SPhilipp Reisner } 1478b411b363SPhilipp Reisner 1479b411b363SPhilipp Reisner /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to 1480b411b363SPhilipp Reisner * mess with get_fs/set_fs, we know we are KERNEL_DS always. */ 1481b411b363SPhilipp Reisner static inline int drbd_setsockopt(struct socket *sock, int level, int optname, 1482b411b363SPhilipp Reisner char __user *optval, int optlen) 1483b411b363SPhilipp Reisner { 1484b411b363SPhilipp Reisner int err; 1485b411b363SPhilipp Reisner if (level == SOL_SOCKET) 1486b411b363SPhilipp Reisner err = sock_setsockopt(sock, level, optname, optval, optlen); 1487b411b363SPhilipp Reisner else 1488b411b363SPhilipp Reisner err = sock->ops->setsockopt(sock, level, optname, optval, 1489b411b363SPhilipp Reisner optlen); 1490b411b363SPhilipp Reisner return err; 1491b411b363SPhilipp Reisner } 1492b411b363SPhilipp Reisner 1493b411b363SPhilipp Reisner static inline void drbd_tcp_cork(struct socket *sock) 1494b411b363SPhilipp Reisner { 1495b411b363SPhilipp Reisner int __user val = 1; 1496b411b363SPhilipp Reisner (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, 1497b411b363SPhilipp Reisner (char __user *)&val, sizeof(val)); 1498b411b363SPhilipp Reisner } 1499b411b363SPhilipp Reisner 1500b411b363SPhilipp Reisner static inline void drbd_tcp_uncork(struct socket *sock) 1501b411b363SPhilipp Reisner { 1502b411b363SPhilipp Reisner int __user val = 0; 1503b411b363SPhilipp Reisner (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, 1504b411b363SPhilipp Reisner (char __user *)&val, sizeof(val)); 1505b411b363SPhilipp Reisner } 1506b411b363SPhilipp Reisner 1507b411b363SPhilipp Reisner static inline void drbd_tcp_nodelay(struct socket *sock) 1508b411b363SPhilipp Reisner { 1509b411b363SPhilipp Reisner int __user val = 1; 1510b411b363SPhilipp Reisner (void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY, 1511b411b363SPhilipp Reisner (char __user *)&val, sizeof(val)); 1512b411b363SPhilipp Reisner } 1513b411b363SPhilipp Reisner 1514b411b363SPhilipp Reisner static inline void drbd_tcp_quickack(struct socket *sock) 1515b411b363SPhilipp Reisner { 1516344fa462SLars Ellenberg int __user val = 2; 1517b411b363SPhilipp Reisner (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, 1518b411b363SPhilipp Reisner (char __user *)&val, sizeof(val)); 1519b411b363SPhilipp Reisner } 1520b411b363SPhilipp Reisner 1521b411b363SPhilipp Reisner void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); 1522b411b363SPhilipp Reisner 1523b411b363SPhilipp Reisner /* drbd_proc.c */ 1524b411b363SPhilipp Reisner extern struct proc_dir_entry *drbd_proc; 15257d4e9d09SEmese Revfy extern const struct file_operations drbd_proc_fops; 1526b411b363SPhilipp Reisner extern const char *drbd_conn_str(enum drbd_conns s); 1527b411b363SPhilipp Reisner extern const char *drbd_role_str(enum drbd_role s); 1528b411b363SPhilipp Reisner 1529b411b363SPhilipp Reisner /* drbd_actlog.c */ 1530181286adSLars Ellenberg extern void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i); 1531181286adSLars Ellenberg extern void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i); 1532b411b363SPhilipp Reisner extern void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector); 1533b411b363SPhilipp Reisner extern int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector); 1534b411b363SPhilipp Reisner extern int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector); 1535b411b363SPhilipp Reisner extern void drbd_rs_cancel_all(struct drbd_conf *mdev); 1536b411b363SPhilipp Reisner extern int drbd_rs_del_all(struct drbd_conf *mdev); 1537b411b363SPhilipp Reisner extern void drbd_rs_failed_io(struct drbd_conf *mdev, 1538b411b363SPhilipp Reisner sector_t sector, int size); 1539b411b363SPhilipp Reisner extern int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *); 1540ea5442afSLars Ellenberg extern void drbd_advance_rs_marks(struct drbd_conf *mdev, unsigned long still_to_go); 1541b411b363SPhilipp Reisner extern void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, 1542b411b363SPhilipp Reisner int size, const char *file, const unsigned int line); 1543b411b363SPhilipp Reisner #define drbd_set_in_sync(mdev, sector, size) \ 1544b411b363SPhilipp Reisner __drbd_set_in_sync(mdev, sector, size, __FILE__, __LINE__) 154573a01a18SPhilipp Reisner extern int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, 1546b411b363SPhilipp Reisner int size, const char *file, const unsigned int line); 1547b411b363SPhilipp Reisner #define drbd_set_out_of_sync(mdev, sector, size) \ 1548b411b363SPhilipp Reisner __drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__) 1549b411b363SPhilipp Reisner extern void drbd_al_apply_to_bm(struct drbd_conf *mdev); 1550b411b363SPhilipp Reisner extern void drbd_al_shrink(struct drbd_conf *mdev); 1551b411b363SPhilipp Reisner 1552b411b363SPhilipp Reisner /* drbd_nl.c */ 15533b98c0c2SLars Ellenberg /* state info broadcast */ 15543b98c0c2SLars Ellenberg struct sib_info { 15553b98c0c2SLars Ellenberg enum drbd_state_info_bcast_reason sib_reason; 15563b98c0c2SLars Ellenberg union { 15573b98c0c2SLars Ellenberg struct { 15583b98c0c2SLars Ellenberg char *helper_name; 15593b98c0c2SLars Ellenberg unsigned helper_exit_code; 15603b98c0c2SLars Ellenberg }; 15613b98c0c2SLars Ellenberg struct { 15623b98c0c2SLars Ellenberg union drbd_state os; 15633b98c0c2SLars Ellenberg union drbd_state ns; 15643b98c0c2SLars Ellenberg }; 15653b98c0c2SLars Ellenberg }; 15663b98c0c2SLars Ellenberg }; 15673b98c0c2SLars Ellenberg void drbd_bcast_event(struct drbd_conf *mdev, const struct sib_info *sib); 1568b411b363SPhilipp Reisner 1569b411b363SPhilipp Reisner /* 1570b411b363SPhilipp Reisner * inline helper functions 1571b411b363SPhilipp Reisner *************************/ 1572b411b363SPhilipp Reisner 157345bb912bSLars Ellenberg /* see also page_chain_add and friends in drbd_receiver.c */ 157445bb912bSLars Ellenberg static inline struct page *page_chain_next(struct page *page) 157545bb912bSLars Ellenberg { 157645bb912bSLars Ellenberg return (struct page *)page_private(page); 157745bb912bSLars Ellenberg } 157845bb912bSLars Ellenberg #define page_chain_for_each(page) \ 157945bb912bSLars Ellenberg for (; page && ({ prefetch(page_chain_next(page)); 1; }); \ 158045bb912bSLars Ellenberg page = page_chain_next(page)) 158145bb912bSLars Ellenberg #define page_chain_for_each_safe(page, n) \ 158245bb912bSLars Ellenberg for (; page && ({ n = page_chain_next(page); 1; }); page = n) 158345bb912bSLars Ellenberg 158445bb912bSLars Ellenberg static inline int drbd_bio_has_active_page(struct bio *bio) 158545bb912bSLars Ellenberg { 158645bb912bSLars Ellenberg struct bio_vec *bvec; 158745bb912bSLars Ellenberg int i; 158845bb912bSLars Ellenberg 158945bb912bSLars Ellenberg __bio_for_each_segment(bvec, bio, i, 0) { 159045bb912bSLars Ellenberg if (page_count(bvec->bv_page) > 1) 159145bb912bSLars Ellenberg return 1; 159245bb912bSLars Ellenberg } 159345bb912bSLars Ellenberg 159445bb912bSLars Ellenberg return 0; 159545bb912bSLars Ellenberg } 159645bb912bSLars Ellenberg 1597db830c46SAndreas Gruenbacher static inline int drbd_ee_has_active_page(struct drbd_peer_request *peer_req) 159845bb912bSLars Ellenberg { 1599db830c46SAndreas Gruenbacher struct page *page = peer_req->pages; 160045bb912bSLars Ellenberg page_chain_for_each(page) { 160145bb912bSLars Ellenberg if (page_count(page) > 1) 160245bb912bSLars Ellenberg return 1; 160345bb912bSLars Ellenberg } 160445bb912bSLars Ellenberg return 0; 160545bb912bSLars Ellenberg } 160645bb912bSLars Ellenberg 1607bf885f8aSAndreas Gruenbacher static inline enum drbd_state_rv 1608bf885f8aSAndreas Gruenbacher _drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, 1609bf885f8aSAndreas Gruenbacher enum chg_state_flags flags, struct completion *done) 1610b411b363SPhilipp Reisner { 1611bf885f8aSAndreas Gruenbacher enum drbd_state_rv rv; 1612b411b363SPhilipp Reisner 1613b411b363SPhilipp Reisner read_lock(&global_state_lock); 1614b411b363SPhilipp Reisner rv = __drbd_set_state(mdev, ns, flags, done); 1615b411b363SPhilipp Reisner read_unlock(&global_state_lock); 1616b411b363SPhilipp Reisner 1617b411b363SPhilipp Reisner return rv; 1618b411b363SPhilipp Reisner } 1619b411b363SPhilipp Reisner 162078bae59bSPhilipp Reisner static inline union drbd_state drbd_read_state(struct drbd_conf *mdev) 162178bae59bSPhilipp Reisner { 162278bae59bSPhilipp Reisner union drbd_state rv; 162378bae59bSPhilipp Reisner 1624da9fbc27SPhilipp Reisner rv.i = mdev->state.i; 16258e0af25fSPhilipp Reisner rv.susp = mdev->tconn->susp; 16268e0af25fSPhilipp Reisner rv.susp_nod = mdev->tconn->susp_nod; 16278e0af25fSPhilipp Reisner rv.susp_fen = mdev->tconn->susp_fen; 162878bae59bSPhilipp Reisner 162978bae59bSPhilipp Reisner return rv; 163078bae59bSPhilipp Reisner } 163178bae59bSPhilipp Reisner 1632b411b363SPhilipp Reisner #define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__) 1633b411b363SPhilipp Reisner static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, const char *where) 1634b411b363SPhilipp Reisner { 1635b411b363SPhilipp Reisner switch (mdev->ldev->dc.on_io_error) { 1636b411b363SPhilipp Reisner case EP_PASS_ON: 1637b411b363SPhilipp Reisner if (!forcedetach) { 16387383506cSLars Ellenberg if (__ratelimit(&drbd_ratelimit_state)) 163982f59cc6SLars Ellenberg dev_err(DEV, "Local IO failed in %s.\n", where); 1640d2e17807SPhilipp Reisner if (mdev->state.disk > D_INCONSISTENT) 1641738a84b2SPhilipp Reisner _drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_HARD, NULL); 1642b411b363SPhilipp Reisner break; 1643b411b363SPhilipp Reisner } 1644b411b363SPhilipp Reisner /* NOTE fall through to detach case if forcedetach set */ 1645b411b363SPhilipp Reisner case EP_DETACH: 1646b411b363SPhilipp Reisner case EP_CALL_HELPER: 164782f59cc6SLars Ellenberg set_bit(WAS_IO_ERROR, &mdev->flags); 1648b411b363SPhilipp Reisner if (mdev->state.disk > D_FAILED) { 1649b411b363SPhilipp Reisner _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); 165082f59cc6SLars Ellenberg dev_err(DEV, 165182f59cc6SLars Ellenberg "Local IO failed in %s. Detaching...\n", where); 1652b411b363SPhilipp Reisner } 1653b411b363SPhilipp Reisner break; 1654b411b363SPhilipp Reisner } 1655b411b363SPhilipp Reisner } 1656b411b363SPhilipp Reisner 1657b411b363SPhilipp Reisner /** 1658b411b363SPhilipp Reisner * drbd_chk_io_error: Handle the on_io_error setting, should be called from all io completion handlers 1659b411b363SPhilipp Reisner * @mdev: DRBD device. 1660b411b363SPhilipp Reisner * @error: Error code passed to the IO completion callback 1661b411b363SPhilipp Reisner * @forcedetach: Force detach. I.e. the error happened while accessing the meta data 1662b411b363SPhilipp Reisner * 1663b411b363SPhilipp Reisner * See also drbd_main.c:after_state_ch() if (os.disk > D_FAILED && ns.disk == D_FAILED) 1664b411b363SPhilipp Reisner */ 1665b411b363SPhilipp Reisner #define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__) 1666b411b363SPhilipp Reisner static inline void drbd_chk_io_error_(struct drbd_conf *mdev, 1667b411b363SPhilipp Reisner int error, int forcedetach, const char *where) 1668b411b363SPhilipp Reisner { 1669b411b363SPhilipp Reisner if (error) { 1670b411b363SPhilipp Reisner unsigned long flags; 167187eeee41SPhilipp Reisner spin_lock_irqsave(&mdev->tconn->req_lock, flags); 1672b411b363SPhilipp Reisner __drbd_chk_io_error_(mdev, forcedetach, where); 167387eeee41SPhilipp Reisner spin_unlock_irqrestore(&mdev->tconn->req_lock, flags); 1674b411b363SPhilipp Reisner } 1675b411b363SPhilipp Reisner } 1676b411b363SPhilipp Reisner 1677b411b363SPhilipp Reisner 1678b411b363SPhilipp Reisner /** 1679b411b363SPhilipp Reisner * drbd_md_first_sector() - Returns the first sector number of the meta data area 1680b411b363SPhilipp Reisner * @bdev: Meta data block device. 1681b411b363SPhilipp Reisner * 1682b411b363SPhilipp Reisner * BTW, for internal meta data, this happens to be the maximum capacity 1683b411b363SPhilipp Reisner * we could agree upon with our peer node. 1684b411b363SPhilipp Reisner */ 1685b411b363SPhilipp Reisner static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev) 1686b411b363SPhilipp Reisner { 1687b411b363SPhilipp Reisner switch (bdev->dc.meta_dev_idx) { 1688b411b363SPhilipp Reisner case DRBD_MD_INDEX_INTERNAL: 1689b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_INT: 1690b411b363SPhilipp Reisner return bdev->md.md_offset + bdev->md.bm_offset; 1691b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_EXT: 1692b411b363SPhilipp Reisner default: 1693b411b363SPhilipp Reisner return bdev->md.md_offset; 1694b411b363SPhilipp Reisner } 1695b411b363SPhilipp Reisner } 1696b411b363SPhilipp Reisner 1697b411b363SPhilipp Reisner /** 1698b411b363SPhilipp Reisner * drbd_md_last_sector() - Return the last sector number of the meta data area 1699b411b363SPhilipp Reisner * @bdev: Meta data block device. 1700b411b363SPhilipp Reisner */ 1701b411b363SPhilipp Reisner static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) 1702b411b363SPhilipp Reisner { 1703b411b363SPhilipp Reisner switch (bdev->dc.meta_dev_idx) { 1704b411b363SPhilipp Reisner case DRBD_MD_INDEX_INTERNAL: 1705b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_INT: 1706b411b363SPhilipp Reisner return bdev->md.md_offset + MD_AL_OFFSET - 1; 1707b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_EXT: 1708b411b363SPhilipp Reisner default: 1709b411b363SPhilipp Reisner return bdev->md.md_offset + bdev->md.md_size_sect; 1710b411b363SPhilipp Reisner } 1711b411b363SPhilipp Reisner } 1712b411b363SPhilipp Reisner 1713b411b363SPhilipp Reisner /* Returns the number of 512 byte sectors of the device */ 1714b411b363SPhilipp Reisner static inline sector_t drbd_get_capacity(struct block_device *bdev) 1715b411b363SPhilipp Reisner { 1716b411b363SPhilipp Reisner /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ 171777304d2aSMike Snitzer return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0; 1718b411b363SPhilipp Reisner } 1719b411b363SPhilipp Reisner 1720b411b363SPhilipp Reisner /** 1721b411b363SPhilipp Reisner * drbd_get_max_capacity() - Returns the capacity we announce to out peer 1722b411b363SPhilipp Reisner * @bdev: Meta data block device. 1723b411b363SPhilipp Reisner * 1724b411b363SPhilipp Reisner * returns the capacity we announce to out peer. we clip ourselves at the 1725b411b363SPhilipp Reisner * various MAX_SECTORS, because if we don't, current implementation will 1726b411b363SPhilipp Reisner * oops sooner or later 1727b411b363SPhilipp Reisner */ 1728b411b363SPhilipp Reisner static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev) 1729b411b363SPhilipp Reisner { 1730b411b363SPhilipp Reisner sector_t s; 1731b411b363SPhilipp Reisner switch (bdev->dc.meta_dev_idx) { 1732b411b363SPhilipp Reisner case DRBD_MD_INDEX_INTERNAL: 1733b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_INT: 1734b411b363SPhilipp Reisner s = drbd_get_capacity(bdev->backing_bdev) 1735b411b363SPhilipp Reisner ? min_t(sector_t, DRBD_MAX_SECTORS_FLEX, 1736b411b363SPhilipp Reisner drbd_md_first_sector(bdev)) 1737b411b363SPhilipp Reisner : 0; 1738b411b363SPhilipp Reisner break; 1739b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_EXT: 1740b411b363SPhilipp Reisner s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX, 1741b411b363SPhilipp Reisner drbd_get_capacity(bdev->backing_bdev)); 1742b411b363SPhilipp Reisner /* clip at maximum size the meta device can support */ 1743b411b363SPhilipp Reisner s = min_t(sector_t, s, 1744b411b363SPhilipp Reisner BM_EXT_TO_SECT(bdev->md.md_size_sect 1745b411b363SPhilipp Reisner - bdev->md.bm_offset)); 1746b411b363SPhilipp Reisner break; 1747b411b363SPhilipp Reisner default: 1748b411b363SPhilipp Reisner s = min_t(sector_t, DRBD_MAX_SECTORS, 1749b411b363SPhilipp Reisner drbd_get_capacity(bdev->backing_bdev)); 1750b411b363SPhilipp Reisner } 1751b411b363SPhilipp Reisner return s; 1752b411b363SPhilipp Reisner } 1753b411b363SPhilipp Reisner 1754b411b363SPhilipp Reisner /** 1755b411b363SPhilipp Reisner * drbd_md_ss__() - Return the sector number of our meta data super block 1756b411b363SPhilipp Reisner * @mdev: DRBD device. 1757b411b363SPhilipp Reisner * @bdev: Meta data block device. 1758b411b363SPhilipp Reisner */ 1759b411b363SPhilipp Reisner static inline sector_t drbd_md_ss__(struct drbd_conf *mdev, 1760b411b363SPhilipp Reisner struct drbd_backing_dev *bdev) 1761b411b363SPhilipp Reisner { 1762b411b363SPhilipp Reisner switch (bdev->dc.meta_dev_idx) { 1763b411b363SPhilipp Reisner default: /* external, some index */ 1764b411b363SPhilipp Reisner return MD_RESERVED_SECT * bdev->dc.meta_dev_idx; 1765b411b363SPhilipp Reisner case DRBD_MD_INDEX_INTERNAL: 1766b411b363SPhilipp Reisner /* with drbd08, internal meta data is always "flexible" */ 1767b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_INT: 1768b411b363SPhilipp Reisner /* sizeof(struct md_on_disk_07) == 4k 1769b411b363SPhilipp Reisner * position: last 4k aligned block of 4k size */ 1770b411b363SPhilipp Reisner if (!bdev->backing_bdev) { 1771b411b363SPhilipp Reisner if (__ratelimit(&drbd_ratelimit_state)) { 1772b411b363SPhilipp Reisner dev_err(DEV, "bdev->backing_bdev==NULL\n"); 1773b411b363SPhilipp Reisner dump_stack(); 1774b411b363SPhilipp Reisner } 1775b411b363SPhilipp Reisner return 0; 1776b411b363SPhilipp Reisner } 1777b411b363SPhilipp Reisner return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) 1778b411b363SPhilipp Reisner - MD_AL_OFFSET; 1779b411b363SPhilipp Reisner case DRBD_MD_INDEX_FLEX_EXT: 1780b411b363SPhilipp Reisner return 0; 1781b411b363SPhilipp Reisner } 1782b411b363SPhilipp Reisner } 1783b411b363SPhilipp Reisner 1784b411b363SPhilipp Reisner static inline void 1785b411b363SPhilipp Reisner drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w) 1786b411b363SPhilipp Reisner { 1787b411b363SPhilipp Reisner unsigned long flags; 1788b411b363SPhilipp Reisner spin_lock_irqsave(&q->q_lock, flags); 1789b411b363SPhilipp Reisner list_add(&w->list, &q->q); 1790b411b363SPhilipp Reisner up(&q->s); /* within the spinlock, 1791b411b363SPhilipp Reisner see comment near end of drbd_worker() */ 1792b411b363SPhilipp Reisner spin_unlock_irqrestore(&q->q_lock, flags); 1793b411b363SPhilipp Reisner } 1794b411b363SPhilipp Reisner 1795b411b363SPhilipp Reisner static inline void 1796b411b363SPhilipp Reisner drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) 1797b411b363SPhilipp Reisner { 1798b411b363SPhilipp Reisner unsigned long flags; 1799b411b363SPhilipp Reisner spin_lock_irqsave(&q->q_lock, flags); 1800b411b363SPhilipp Reisner list_add_tail(&w->list, &q->q); 1801b411b363SPhilipp Reisner up(&q->s); /* within the spinlock, 1802b411b363SPhilipp Reisner see comment near end of drbd_worker() */ 1803b411b363SPhilipp Reisner spin_unlock_irqrestore(&q->q_lock, flags); 1804b411b363SPhilipp Reisner } 1805b411b363SPhilipp Reisner 18060625ac19SPhilipp Reisner static inline void wake_asender(struct drbd_tconn *tconn) 1807b411b363SPhilipp Reisner { 18080625ac19SPhilipp Reisner if (test_bit(SIGNAL_ASENDER, &tconn->flags)) 18090625ac19SPhilipp Reisner force_sig(DRBD_SIG, tconn->asender.task); 1810b411b363SPhilipp Reisner } 1811b411b363SPhilipp Reisner 18120625ac19SPhilipp Reisner static inline void request_ping(struct drbd_tconn *tconn) 1813b411b363SPhilipp Reisner { 18140625ac19SPhilipp Reisner set_bit(SEND_PING, &tconn->flags); 18150625ac19SPhilipp Reisner wake_asender(tconn); 1816b411b363SPhilipp Reisner } 1817b411b363SPhilipp Reisner 1818dba58587SAndreas Gruenbacher extern void *conn_prepare_command(struct drbd_tconn *, struct drbd_socket *); 1819dba58587SAndreas Gruenbacher extern void *drbd_prepare_command(struct drbd_conf *, struct drbd_socket *); 1820dba58587SAndreas Gruenbacher extern int conn_send_command(struct drbd_tconn *, struct drbd_socket *, 1821dba58587SAndreas Gruenbacher enum drbd_packet, unsigned int, void *, 1822dba58587SAndreas Gruenbacher unsigned int); 1823dba58587SAndreas Gruenbacher extern int drbd_send_command(struct drbd_conf *, struct drbd_socket *, 1824dba58587SAndreas Gruenbacher enum drbd_packet, unsigned int, void *, 1825dba58587SAndreas Gruenbacher unsigned int); 1826dba58587SAndreas Gruenbacher 1827e307f352SAndreas Gruenbacher extern int drbd_send_ping(struct drbd_tconn *tconn); 1828e307f352SAndreas Gruenbacher extern int drbd_send_ping_ack(struct drbd_tconn *tconn); 18299f5bdc33SAndreas Gruenbacher extern int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state); 18309f5bdc33SAndreas Gruenbacher extern int conn_send_state_req(struct drbd_tconn *, union drbd_state, union drbd_state); 1831cf29c9d8SPhilipp Reisner 1832b411b363SPhilipp Reisner static inline void drbd_thread_stop(struct drbd_thread *thi) 1833b411b363SPhilipp Reisner { 183481e84650SAndreas Gruenbacher _drbd_thread_stop(thi, false, true); 1835b411b363SPhilipp Reisner } 1836b411b363SPhilipp Reisner 1837b411b363SPhilipp Reisner static inline void drbd_thread_stop_nowait(struct drbd_thread *thi) 1838b411b363SPhilipp Reisner { 183981e84650SAndreas Gruenbacher _drbd_thread_stop(thi, false, false); 1840b411b363SPhilipp Reisner } 1841b411b363SPhilipp Reisner 1842b411b363SPhilipp Reisner static inline void drbd_thread_restart_nowait(struct drbd_thread *thi) 1843b411b363SPhilipp Reisner { 184481e84650SAndreas Gruenbacher _drbd_thread_stop(thi, true, false); 1845b411b363SPhilipp Reisner } 1846b411b363SPhilipp Reisner 1847b411b363SPhilipp Reisner /* counts how many answer packets packets we expect from our peer, 1848b411b363SPhilipp Reisner * for either explicit application requests, 1849b411b363SPhilipp Reisner * or implicit barrier packets as necessary. 1850b411b363SPhilipp Reisner * increased: 1851b411b363SPhilipp Reisner * w_send_barrier 18528554df1cSAndreas Gruenbacher * _req_mod(req, QUEUE_FOR_NET_WRITE or QUEUE_FOR_NET_READ); 1853b411b363SPhilipp Reisner * it is much easier and equally valid to count what we queue for the 1854b411b363SPhilipp Reisner * worker, even before it actually was queued or send. 1855b411b363SPhilipp Reisner * (drbd_make_request_common; recovery path on read io-error) 1856b411b363SPhilipp Reisner * decreased: 1857b411b363SPhilipp Reisner * got_BarrierAck (respective tl_clear, tl_clear_barrier) 18588554df1cSAndreas Gruenbacher * _req_mod(req, DATA_RECEIVED) 1859b411b363SPhilipp Reisner * [from receive_DataReply] 18608554df1cSAndreas Gruenbacher * _req_mod(req, WRITE_ACKED_BY_PEER or RECV_ACKED_BY_PEER or NEG_ACKED) 1861b411b363SPhilipp Reisner * [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)] 1862b411b363SPhilipp Reisner * for some reason it is NOT decreased in got_NegAck, 1863b411b363SPhilipp Reisner * but in the resulting cleanup code from report_params. 1864b411b363SPhilipp Reisner * we should try to remember the reason for that... 18658554df1cSAndreas Gruenbacher * _req_mod(req, SEND_FAILED or SEND_CANCELED) 18668554df1cSAndreas Gruenbacher * _req_mod(req, CONNECTION_LOST_WHILE_PENDING) 1867b411b363SPhilipp Reisner * [from tl_clear_barrier] 1868b411b363SPhilipp Reisner */ 1869b411b363SPhilipp Reisner static inline void inc_ap_pending(struct drbd_conf *mdev) 1870b411b363SPhilipp Reisner { 1871b411b363SPhilipp Reisner atomic_inc(&mdev->ap_pending_cnt); 1872b411b363SPhilipp Reisner } 1873b411b363SPhilipp Reisner 187449559d87SPhilipp Reisner #define ERR_IF_CNT_IS_NEGATIVE(which, func, line) \ 1875b411b363SPhilipp Reisner if (atomic_read(&mdev->which) < 0) \ 1876b411b363SPhilipp Reisner dev_err(DEV, "in %s:%d: " #which " = %d < 0 !\n", \ 187749559d87SPhilipp Reisner func, line, \ 1878b411b363SPhilipp Reisner atomic_read(&mdev->which)) 1879b411b363SPhilipp Reisner 188049559d87SPhilipp Reisner #define dec_ap_pending(mdev) _dec_ap_pending(mdev, __FUNCTION__, __LINE__) 188149559d87SPhilipp Reisner static inline void _dec_ap_pending(struct drbd_conf *mdev, const char *func, int line) 188249559d87SPhilipp Reisner { 188349559d87SPhilipp Reisner if (atomic_dec_and_test(&mdev->ap_pending_cnt)) 188449559d87SPhilipp Reisner wake_up(&mdev->misc_wait); 188549559d87SPhilipp Reisner ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt, func, line); 188649559d87SPhilipp Reisner } 1887b411b363SPhilipp Reisner 1888b411b363SPhilipp Reisner /* counts how many resync-related answers we still expect from the peer 1889b411b363SPhilipp Reisner * increase decrease 1890b411b363SPhilipp Reisner * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY) 189125985edcSLucas De Marchi * C_SYNC_SOURCE sends P_RS_DATA_REPLY (and expects P_WRITE_ACK with ID_SYNCER) 1892b411b363SPhilipp Reisner * (or P_NEG_ACK with ID_SYNCER) 1893b411b363SPhilipp Reisner */ 1894b411b363SPhilipp Reisner static inline void inc_rs_pending(struct drbd_conf *mdev) 1895b411b363SPhilipp Reisner { 1896b411b363SPhilipp Reisner atomic_inc(&mdev->rs_pending_cnt); 1897b411b363SPhilipp Reisner } 1898b411b363SPhilipp Reisner 189949559d87SPhilipp Reisner #define dec_rs_pending(mdev) _dec_rs_pending(mdev, __FUNCTION__, __LINE__) 190049559d87SPhilipp Reisner static inline void _dec_rs_pending(struct drbd_conf *mdev, const char *func, int line) 190149559d87SPhilipp Reisner { 190249559d87SPhilipp Reisner atomic_dec(&mdev->rs_pending_cnt); 190349559d87SPhilipp Reisner ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt, func, line); 190449559d87SPhilipp Reisner } 1905b411b363SPhilipp Reisner 1906b411b363SPhilipp Reisner /* counts how many answers we still need to send to the peer. 1907b411b363SPhilipp Reisner * increased on 1908b411b363SPhilipp Reisner * receive_Data unless protocol A; 1909b411b363SPhilipp Reisner * we need to send a P_RECV_ACK (proto B) 1910b411b363SPhilipp Reisner * or P_WRITE_ACK (proto C) 1911b411b363SPhilipp Reisner * receive_RSDataReply (recv_resync_read) we need to send a P_WRITE_ACK 1912b411b363SPhilipp Reisner * receive_DataRequest (receive_RSDataRequest) we need to send back P_DATA 1913b411b363SPhilipp Reisner * receive_Barrier_* we need to send a P_BARRIER_ACK 1914b411b363SPhilipp Reisner */ 1915b411b363SPhilipp Reisner static inline void inc_unacked(struct drbd_conf *mdev) 1916b411b363SPhilipp Reisner { 1917b411b363SPhilipp Reisner atomic_inc(&mdev->unacked_cnt); 1918b411b363SPhilipp Reisner } 1919b411b363SPhilipp Reisner 192049559d87SPhilipp Reisner #define dec_unacked(mdev) _dec_unacked(mdev, __FUNCTION__, __LINE__) 192149559d87SPhilipp Reisner static inline void _dec_unacked(struct drbd_conf *mdev, const char *func, int line) 192249559d87SPhilipp Reisner { 192349559d87SPhilipp Reisner atomic_dec(&mdev->unacked_cnt); 192449559d87SPhilipp Reisner ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line); 192549559d87SPhilipp Reisner } 1926b411b363SPhilipp Reisner 192749559d87SPhilipp Reisner #define sub_unacked(mdev, n) _sub_unacked(mdev, n, __FUNCTION__, __LINE__) 192849559d87SPhilipp Reisner static inline void _sub_unacked(struct drbd_conf *mdev, int n, const char *func, int line) 192949559d87SPhilipp Reisner { 193049559d87SPhilipp Reisner atomic_sub(n, &mdev->unacked_cnt); 193149559d87SPhilipp Reisner ERR_IF_CNT_IS_NEGATIVE(unacked_cnt, func, line); 193249559d87SPhilipp Reisner } 1933b411b363SPhilipp Reisner 1934b2fb6dbeSPhilipp Reisner static inline void put_net_conf(struct drbd_tconn *tconn) 1935b411b363SPhilipp Reisner { 1936b2fb6dbeSPhilipp Reisner if (atomic_dec_and_test(&tconn->net_cnt)) 1937b2fb6dbeSPhilipp Reisner wake_up(&tconn->net_cnt_wait); 1938b411b363SPhilipp Reisner } 1939b411b363SPhilipp Reisner 1940b411b363SPhilipp Reisner /** 194189e58e75SPhilipp Reisner * get_net_conf() - Increase ref count on mdev->tconn->net_conf; Returns 0 if nothing there 1942b411b363SPhilipp Reisner * @mdev: DRBD device. 1943b411b363SPhilipp Reisner * 194489e58e75SPhilipp Reisner * You have to call put_net_conf() when finished working with mdev->tconn->net_conf. 1945b411b363SPhilipp Reisner */ 1946b2fb6dbeSPhilipp Reisner static inline int get_net_conf(struct drbd_tconn *tconn) 1947b411b363SPhilipp Reisner { 1948b411b363SPhilipp Reisner int have_net_conf; 1949b411b363SPhilipp Reisner 1950b2fb6dbeSPhilipp Reisner atomic_inc(&tconn->net_cnt); 1951bbeb641cSPhilipp Reisner have_net_conf = tconn->cstate >= C_UNCONNECTED; 1952b411b363SPhilipp Reisner if (!have_net_conf) 1953b2fb6dbeSPhilipp Reisner put_net_conf(tconn); 1954b411b363SPhilipp Reisner return have_net_conf; 1955b411b363SPhilipp Reisner } 1956b411b363SPhilipp Reisner 1957b411b363SPhilipp Reisner /** 1958b411b363SPhilipp Reisner * get_ldev() - Increase the ref count on mdev->ldev. Returns 0 if there is no ldev 1959b411b363SPhilipp Reisner * @M: DRBD device. 1960b411b363SPhilipp Reisner * 1961b411b363SPhilipp Reisner * You have to call put_ldev() when finished working with mdev->ldev. 1962b411b363SPhilipp Reisner */ 1963b411b363SPhilipp Reisner #define get_ldev(M) __cond_lock(local, _get_ldev_if_state(M,D_INCONSISTENT)) 1964b411b363SPhilipp Reisner #define get_ldev_if_state(M,MINS) __cond_lock(local, _get_ldev_if_state(M,MINS)) 1965b411b363SPhilipp Reisner 1966b411b363SPhilipp Reisner static inline void put_ldev(struct drbd_conf *mdev) 1967b411b363SPhilipp Reisner { 19681d7734a0SLars Ellenberg int i = atomic_dec_return(&mdev->local_cnt); 19699a0d9d03SLars Ellenberg 19709a0d9d03SLars Ellenberg /* This may be called from some endio handler, 19719a0d9d03SLars Ellenberg * so we must not sleep here. */ 19729a0d9d03SLars Ellenberg 1973b411b363SPhilipp Reisner __release(local); 19741d7734a0SLars Ellenberg D_ASSERT(i >= 0); 1975e9e6f3ecSLars Ellenberg if (i == 0) { 197682f59cc6SLars Ellenberg if (mdev->state.disk == D_DISKLESS) 197782f59cc6SLars Ellenberg /* even internal references gone, safe to destroy */ 197882f59cc6SLars Ellenberg drbd_ldev_destroy(mdev); 1979e9e6f3ecSLars Ellenberg if (mdev->state.disk == D_FAILED) 198082f59cc6SLars Ellenberg /* all application IO references gone. */ 1981e9e6f3ecSLars Ellenberg drbd_go_diskless(mdev); 1982b411b363SPhilipp Reisner wake_up(&mdev->misc_wait); 1983b411b363SPhilipp Reisner } 1984e9e6f3ecSLars Ellenberg } 1985b411b363SPhilipp Reisner 1986b411b363SPhilipp Reisner #ifndef __CHECKER__ 1987b411b363SPhilipp Reisner static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins) 1988b411b363SPhilipp Reisner { 1989b411b363SPhilipp Reisner int io_allowed; 1990b411b363SPhilipp Reisner 199182f59cc6SLars Ellenberg /* never get a reference while D_DISKLESS */ 199282f59cc6SLars Ellenberg if (mdev->state.disk == D_DISKLESS) 199382f59cc6SLars Ellenberg return 0; 199482f59cc6SLars Ellenberg 1995b411b363SPhilipp Reisner atomic_inc(&mdev->local_cnt); 1996b411b363SPhilipp Reisner io_allowed = (mdev->state.disk >= mins); 1997b411b363SPhilipp Reisner if (!io_allowed) 1998b411b363SPhilipp Reisner put_ldev(mdev); 1999b411b363SPhilipp Reisner return io_allowed; 2000b411b363SPhilipp Reisner } 2001b411b363SPhilipp Reisner #else 2002b411b363SPhilipp Reisner extern int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins); 2003b411b363SPhilipp Reisner #endif 2004b411b363SPhilipp Reisner 2005b411b363SPhilipp Reisner /* you must have an "get_ldev" reference */ 2006b411b363SPhilipp Reisner static inline void drbd_get_syncer_progress(struct drbd_conf *mdev, 2007b411b363SPhilipp Reisner unsigned long *bits_left, unsigned int *per_mil_done) 2008b411b363SPhilipp Reisner { 20094b0715f0SLars Ellenberg /* this is to break it at compile time when we change that, in case we 20104b0715f0SLars Ellenberg * want to support more than (1<<32) bits on a 32bit arch. */ 2011b411b363SPhilipp Reisner typecheck(unsigned long, mdev->rs_total); 2012b411b363SPhilipp Reisner 2013b411b363SPhilipp Reisner /* note: both rs_total and rs_left are in bits, i.e. in 2014b411b363SPhilipp Reisner * units of BM_BLOCK_SIZE. 2015b411b363SPhilipp Reisner * for the percentage, we don't care. */ 2016b411b363SPhilipp Reisner 2017439d5953SLars Ellenberg if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) 2018439d5953SLars Ellenberg *bits_left = mdev->ov_left; 2019439d5953SLars Ellenberg else 2020b411b363SPhilipp Reisner *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; 2021b411b363SPhilipp Reisner /* >> 10 to prevent overflow, 2022b411b363SPhilipp Reisner * +1 to prevent division by zero */ 2023b411b363SPhilipp Reisner if (*bits_left > mdev->rs_total) { 2024b411b363SPhilipp Reisner /* doh. maybe a logic bug somewhere. 2025b411b363SPhilipp Reisner * may also be just a race condition 2026b411b363SPhilipp Reisner * between this and a disconnect during sync. 2027b411b363SPhilipp Reisner * for now, just prevent in-kernel buffer overflow. 2028b411b363SPhilipp Reisner */ 2029b411b363SPhilipp Reisner smp_rmb(); 2030b411b363SPhilipp Reisner dev_warn(DEV, "cs:%s rs_left=%lu > rs_total=%lu (rs_failed %lu)\n", 2031b411b363SPhilipp Reisner drbd_conn_str(mdev->state.conn), 2032b411b363SPhilipp Reisner *bits_left, mdev->rs_total, mdev->rs_failed); 2033b411b363SPhilipp Reisner *per_mil_done = 0; 2034b411b363SPhilipp Reisner } else { 20354b0715f0SLars Ellenberg /* Make sure the division happens in long context. 20364b0715f0SLars Ellenberg * We allow up to one petabyte storage right now, 20374b0715f0SLars Ellenberg * at a granularity of 4k per bit that is 2**38 bits. 20384b0715f0SLars Ellenberg * After shift right and multiplication by 1000, 20394b0715f0SLars Ellenberg * this should still fit easily into a 32bit long, 20404b0715f0SLars Ellenberg * so we don't need a 64bit division on 32bit arch. 20414b0715f0SLars Ellenberg * Note: currently we don't support such large bitmaps on 32bit 20424b0715f0SLars Ellenberg * arch anyways, but no harm done to be prepared for it here. 20434b0715f0SLars Ellenberg */ 20444b0715f0SLars Ellenberg unsigned int shift = mdev->rs_total >= (1ULL << 32) ? 16 : 10; 20454b0715f0SLars Ellenberg unsigned long left = *bits_left >> shift; 20464b0715f0SLars Ellenberg unsigned long total = 1UL + (mdev->rs_total >> shift); 20474b0715f0SLars Ellenberg unsigned long tmp = 1000UL - left * 1000UL/total; 2048b411b363SPhilipp Reisner *per_mil_done = tmp; 2049b411b363SPhilipp Reisner } 2050b411b363SPhilipp Reisner } 2051b411b363SPhilipp Reisner 2052b411b363SPhilipp Reisner 2053b411b363SPhilipp Reisner /* this throttles on-the-fly application requests 2054b411b363SPhilipp Reisner * according to max_buffers settings; 2055b411b363SPhilipp Reisner * maybe re-implement using semaphores? */ 2056b411b363SPhilipp Reisner static inline int drbd_get_max_buffers(struct drbd_conf *mdev) 2057b411b363SPhilipp Reisner { 2058b411b363SPhilipp Reisner int mxb = 1000000; /* arbitrary limit on open requests */ 2059b2fb6dbeSPhilipp Reisner if (get_net_conf(mdev->tconn)) { 206089e58e75SPhilipp Reisner mxb = mdev->tconn->net_conf->max_buffers; 2061b2fb6dbeSPhilipp Reisner put_net_conf(mdev->tconn); 2062b411b363SPhilipp Reisner } 2063b411b363SPhilipp Reisner return mxb; 2064b411b363SPhilipp Reisner } 2065b411b363SPhilipp Reisner 20663719094eSPhilipp Reisner static inline int drbd_state_is_stable(struct drbd_conf *mdev) 2067b411b363SPhilipp Reisner { 2068da9fbc27SPhilipp Reisner union drbd_dev_state s = mdev->state; 2069b411b363SPhilipp Reisner 2070b411b363SPhilipp Reisner /* DO NOT add a default clause, we want the compiler to warn us 2071b411b363SPhilipp Reisner * for any newly introduced state we may have forgotten to add here */ 2072b411b363SPhilipp Reisner 2073b411b363SPhilipp Reisner switch ((enum drbd_conns)s.conn) { 2074b411b363SPhilipp Reisner /* new io only accepted when there is no connection, ... */ 2075b411b363SPhilipp Reisner case C_STANDALONE: 2076b411b363SPhilipp Reisner case C_WF_CONNECTION: 2077b411b363SPhilipp Reisner /* ... or there is a well established connection. */ 2078b411b363SPhilipp Reisner case C_CONNECTED: 2079b411b363SPhilipp Reisner case C_SYNC_SOURCE: 2080b411b363SPhilipp Reisner case C_SYNC_TARGET: 2081b411b363SPhilipp Reisner case C_VERIFY_S: 2082b411b363SPhilipp Reisner case C_VERIFY_T: 2083b411b363SPhilipp Reisner case C_PAUSED_SYNC_S: 2084b411b363SPhilipp Reisner case C_PAUSED_SYNC_T: 208567531718SPhilipp Reisner case C_AHEAD: 208667531718SPhilipp Reisner case C_BEHIND: 20873719094eSPhilipp Reisner /* transitional states, IO allowed */ 2088b411b363SPhilipp Reisner case C_DISCONNECTING: 2089b411b363SPhilipp Reisner case C_UNCONNECTED: 2090b411b363SPhilipp Reisner case C_TIMEOUT: 2091b411b363SPhilipp Reisner case C_BROKEN_PIPE: 2092b411b363SPhilipp Reisner case C_NETWORK_FAILURE: 2093b411b363SPhilipp Reisner case C_PROTOCOL_ERROR: 2094b411b363SPhilipp Reisner case C_TEAR_DOWN: 2095b411b363SPhilipp Reisner case C_WF_REPORT_PARAMS: 2096b411b363SPhilipp Reisner case C_STARTING_SYNC_S: 2097b411b363SPhilipp Reisner case C_STARTING_SYNC_T: 20983719094eSPhilipp Reisner break; 20993719094eSPhilipp Reisner 21003719094eSPhilipp Reisner /* Allow IO in BM exchange states with new protocols */ 2101b411b363SPhilipp Reisner case C_WF_BITMAP_S: 210231890f4aSPhilipp Reisner if (mdev->tconn->agreed_pro_version < 96) 21033719094eSPhilipp Reisner return 0; 21043719094eSPhilipp Reisner break; 21053719094eSPhilipp Reisner 21063719094eSPhilipp Reisner /* no new io accepted in these states */ 2107b411b363SPhilipp Reisner case C_WF_BITMAP_T: 2108b411b363SPhilipp Reisner case C_WF_SYNC_UUID: 2109b411b363SPhilipp Reisner case C_MASK: 2110b411b363SPhilipp Reisner /* not "stable" */ 2111b411b363SPhilipp Reisner return 0; 2112b411b363SPhilipp Reisner } 2113b411b363SPhilipp Reisner 2114b411b363SPhilipp Reisner switch ((enum drbd_disk_state)s.disk) { 2115b411b363SPhilipp Reisner case D_DISKLESS: 2116b411b363SPhilipp Reisner case D_INCONSISTENT: 2117b411b363SPhilipp Reisner case D_OUTDATED: 2118b411b363SPhilipp Reisner case D_CONSISTENT: 2119b411b363SPhilipp Reisner case D_UP_TO_DATE: 2120b411b363SPhilipp Reisner /* disk state is stable as well. */ 2121b411b363SPhilipp Reisner break; 2122b411b363SPhilipp Reisner 2123b411b363SPhilipp Reisner /* no new io accepted during tansitional states */ 2124b411b363SPhilipp Reisner case D_ATTACHING: 2125b411b363SPhilipp Reisner case D_FAILED: 2126b411b363SPhilipp Reisner case D_NEGOTIATING: 2127b411b363SPhilipp Reisner case D_UNKNOWN: 2128b411b363SPhilipp Reisner case D_MASK: 2129b411b363SPhilipp Reisner /* not "stable" */ 2130b411b363SPhilipp Reisner return 0; 2131b411b363SPhilipp Reisner } 2132b411b363SPhilipp Reisner 2133b411b363SPhilipp Reisner return 1; 2134b411b363SPhilipp Reisner } 2135b411b363SPhilipp Reisner 21362aebfabbSPhilipp Reisner static inline int drbd_suspended(struct drbd_conf *mdev) 2137fb22c402SPhilipp Reisner { 21388e0af25fSPhilipp Reisner struct drbd_tconn *tconn = mdev->tconn; 21398e0af25fSPhilipp Reisner 21408e0af25fSPhilipp Reisner return tconn->susp || tconn->susp_fen || tconn->susp_nod; 2141fb22c402SPhilipp Reisner } 2142fb22c402SPhilipp Reisner 21431b881ef7SAndreas Gruenbacher static inline bool may_inc_ap_bio(struct drbd_conf *mdev) 2144b411b363SPhilipp Reisner { 2145b411b363SPhilipp Reisner int mxb = drbd_get_max_buffers(mdev); 2146b411b363SPhilipp Reisner 21472aebfabbSPhilipp Reisner if (drbd_suspended(mdev)) 21481b881ef7SAndreas Gruenbacher return false; 2149b411b363SPhilipp Reisner if (test_bit(SUSPEND_IO, &mdev->flags)) 21501b881ef7SAndreas Gruenbacher return false; 2151b411b363SPhilipp Reisner 2152b411b363SPhilipp Reisner /* to avoid potential deadlock or bitmap corruption, 2153b411b363SPhilipp Reisner * in various places, we only allow new application io 2154b411b363SPhilipp Reisner * to start during "stable" states. */ 2155b411b363SPhilipp Reisner 2156b411b363SPhilipp Reisner /* no new io accepted when attaching or detaching the disk */ 21573719094eSPhilipp Reisner if (!drbd_state_is_stable(mdev)) 21581b881ef7SAndreas Gruenbacher return false; 2159b411b363SPhilipp Reisner 2160b411b363SPhilipp Reisner /* since some older kernels don't have atomic_add_unless, 2161b411b363SPhilipp Reisner * and we are within the spinlock anyways, we have this workaround. */ 2162b411b363SPhilipp Reisner if (atomic_read(&mdev->ap_bio_cnt) > mxb) 21631b881ef7SAndreas Gruenbacher return false; 2164b411b363SPhilipp Reisner if (test_bit(BITMAP_IO, &mdev->flags)) 21651b881ef7SAndreas Gruenbacher return false; 21661b881ef7SAndreas Gruenbacher return true; 2167b411b363SPhilipp Reisner } 2168b411b363SPhilipp Reisner 216923361cf3SLars Ellenberg static inline bool inc_ap_bio_cond(struct drbd_conf *mdev) 21708869d683SPhilipp Reisner { 21711b881ef7SAndreas Gruenbacher bool rv = false; 21728869d683SPhilipp Reisner 217387eeee41SPhilipp Reisner spin_lock_irq(&mdev->tconn->req_lock); 21741b881ef7SAndreas Gruenbacher rv = may_inc_ap_bio(mdev); 21758869d683SPhilipp Reisner if (rv) 217623361cf3SLars Ellenberg atomic_inc(&mdev->ap_bio_cnt); 217787eeee41SPhilipp Reisner spin_unlock_irq(&mdev->tconn->req_lock); 21788869d683SPhilipp Reisner 21798869d683SPhilipp Reisner return rv; 21808869d683SPhilipp Reisner } 21818869d683SPhilipp Reisner 218223361cf3SLars Ellenberg static inline void inc_ap_bio(struct drbd_conf *mdev) 2183b411b363SPhilipp Reisner { 2184b411b363SPhilipp Reisner /* we wait here 2185b411b363SPhilipp Reisner * as long as the device is suspended 2186b411b363SPhilipp Reisner * until the bitmap is no longer on the fly during connection 2187b411b363SPhilipp Reisner * handshake as long as we would exeed the max_buffer limit. 2188b411b363SPhilipp Reisner * 2189b411b363SPhilipp Reisner * to avoid races with the reconnect code, 2190b411b363SPhilipp Reisner * we need to atomic_inc within the spinlock. */ 2191b411b363SPhilipp Reisner 219223361cf3SLars Ellenberg wait_event(mdev->misc_wait, inc_ap_bio_cond(mdev)); 2193b411b363SPhilipp Reisner } 2194b411b363SPhilipp Reisner 2195b411b363SPhilipp Reisner static inline void dec_ap_bio(struct drbd_conf *mdev) 2196b411b363SPhilipp Reisner { 2197b411b363SPhilipp Reisner int mxb = drbd_get_max_buffers(mdev); 2198b411b363SPhilipp Reisner int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt); 2199b411b363SPhilipp Reisner 2200b411b363SPhilipp Reisner D_ASSERT(ap_bio >= 0); 2201b411b363SPhilipp Reisner /* this currently does wake_up for every dec_ap_bio! 2202b411b363SPhilipp Reisner * maybe rather introduce some type of hysteresis? 2203b411b363SPhilipp Reisner * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */ 2204b411b363SPhilipp Reisner if (ap_bio < mxb) 2205b411b363SPhilipp Reisner wake_up(&mdev->misc_wait); 2206b411b363SPhilipp Reisner if (ap_bio == 0 && test_bit(BITMAP_IO, &mdev->flags)) { 2207b411b363SPhilipp Reisner if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags)) 2208e42325a5SPhilipp Reisner drbd_queue_work(&mdev->tconn->data.work, &mdev->bm_io_work.w); 2209b411b363SPhilipp Reisner } 2210b411b363SPhilipp Reisner } 2211b411b363SPhilipp Reisner 221262b0da3aSLars Ellenberg static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) 2213b411b363SPhilipp Reisner { 221462b0da3aSLars Ellenberg int changed = mdev->ed_uuid != val; 2215b411b363SPhilipp Reisner mdev->ed_uuid = val; 221662b0da3aSLars Ellenberg return changed; 2217b411b363SPhilipp Reisner } 2218b411b363SPhilipp Reisner 2219b411b363SPhilipp Reisner static inline int drbd_queue_order_type(struct drbd_conf *mdev) 2220b411b363SPhilipp Reisner { 2221b411b363SPhilipp Reisner /* sorry, we currently have no working implementation 2222b411b363SPhilipp Reisner * of distributed TCQ stuff */ 2223b411b363SPhilipp Reisner #ifndef QUEUE_ORDERED_NONE 2224b411b363SPhilipp Reisner #define QUEUE_ORDERED_NONE 0 2225b411b363SPhilipp Reisner #endif 2226b411b363SPhilipp Reisner return QUEUE_ORDERED_NONE; 2227b411b363SPhilipp Reisner } 2228b411b363SPhilipp Reisner 2229b411b363SPhilipp Reisner static inline void drbd_md_flush(struct drbd_conf *mdev) 2230b411b363SPhilipp Reisner { 2231b411b363SPhilipp Reisner int r; 2232b411b363SPhilipp Reisner 2233a8a4e51eSPhilipp Reisner if (test_bit(MD_NO_FUA, &mdev->flags)) 2234b411b363SPhilipp Reisner return; 2235b411b363SPhilipp Reisner 2236dd3932edSChristoph Hellwig r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL); 2237b411b363SPhilipp Reisner if (r) { 2238a8a4e51eSPhilipp Reisner set_bit(MD_NO_FUA, &mdev->flags); 2239b411b363SPhilipp Reisner dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); 2240b411b363SPhilipp Reisner } 2241b411b363SPhilipp Reisner } 2242b411b363SPhilipp Reisner 2243b411b363SPhilipp Reisner #endif 2244