^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef DRBD_STATE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define DRBD_STATE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) struct drbd_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) struct drbd_connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * DOC: DRBD State macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * These macros are used to express state changes in easily readable form.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * The NS macros expand to a mask and a value, that can be bit ored onto the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * current state as soon as the spinlock (req_lock) was taken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * The _NS macros are used for state functions that get called with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * spinlock. These macros expand directly to the new state value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Besides the basic forms NS() and _NS() additional _?NS[23] are defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * to express state changes that affect more than one aspect of the state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * E.g. NS2(conn, C_CONNECTED, peer, R_SECONDARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Means that the network connection was established and that the peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * is in secondary role.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define role_MASK R_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define peer_MASK R_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define disk_MASK D_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define pdsk_MASK D_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define conn_MASK C_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define susp_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define user_isp_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define aftr_isp_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define susp_nod_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define susp_fen_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define NS(T, S) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ({ union drbd_state val; val.i = 0; val.T = (S); val; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define NS2(T1, S1, T2, S2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mask.T2 = T2##_MASK; mask; }), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ({ union drbd_state val; val.i = 0; val.T1 = (S1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) val.T2 = (S2); val; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define NS3(T1, S1, T2, S2, T3, S3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mask.T2 = T2##_MASK; mask.T3 = T3##_MASK; mask; }), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ({ union drbd_state val; val.i = 0; val.T1 = (S1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) val.T2 = (S2); val.T3 = (S3); val; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define _NS(D, T, S) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T = (S); __ns; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define _NS2(D, T1, S1, T2, S2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T1 = (S1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __ns.T2 = (S2); __ns; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define _NS3(D, T1, S1, T2, S2, T3, S3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) D, ({ union drbd_state __ns; __ns = drbd_read_state(D); __ns.T1 = (S1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) __ns.T2 = (S2); __ns.T3 = (S3); __ns; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) enum chg_state_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) CS_HARD = 1 << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) CS_VERBOSE = 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) CS_WAIT_COMPLETE = 1 << 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) CS_SERIALIZE = 1 << 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) CS_ORDERED = CS_WAIT_COMPLETE + CS_SERIALIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) CS_LOCAL_ONLY = 1 << 4, /* Do not consider a device pair wide state change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) CS_DC_ROLE = 1 << 5, /* DC = display as connection state change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) CS_DC_PEER = 1 << 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) CS_DC_CONN = 1 << 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) CS_DC_DISK = 1 << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) CS_DC_PDSK = 1 << 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) CS_DC_SUSP = 1 << 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) CS_IGN_OUTD_FAIL = 1 << 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Make sure no meta data IO is in flight, by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * drbd_md_get_buffer(). Used for graceful detach. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) CS_INHIBIT_MD_IO = 1 << 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* drbd_dev_state and drbd_state are different types. This is to stress the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) small difference. There is no suspended flag (.susp), and no suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) while fence handler runs flas (susp_fen). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) union drbd_dev_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #if defined(__LITTLE_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned role:2 ; /* 3/4 primary/secondary/unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned peer:2 ; /* 3/4 primary/secondary/unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned conn:5 ; /* 17/32 cstates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned disk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned pdsk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned _unused:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned aftr_isp:1 ; /* isp .. imposed sync pause */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned peer_isp:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned user_isp:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned _pad:11; /* 0 unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #elif defined(__BIG_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned _pad:11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned user_isp:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned peer_isp:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned aftr_isp:1 ; /* isp .. imposed sync pause */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned _unused:1 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned pdsk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned disk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned conn:5 ; /* 17/32 cstates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned peer:2 ; /* 3/4 primary/secondary/unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned role:2 ; /* 3/4 primary/secondary/unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) # error "this endianess is not supported"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) extern enum drbd_state_rv drbd_change_state(struct drbd_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) enum chg_state_flags f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) union drbd_state mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) union drbd_state val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) extern void drbd_force_state(struct drbd_device *, union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) union drbd_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) extern enum drbd_state_rv _drbd_request_state(struct drbd_device *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) enum chg_state_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) extern enum drbd_state_rv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) _drbd_request_state_holding_state_mutex(struct drbd_device *, union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) union drbd_state, enum chg_state_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) extern enum drbd_state_rv _drbd_set_state(struct drbd_device *, union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum chg_state_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct completion *done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) extern void print_st_err(struct drbd_device *, union drbd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) union drbd_state, enum drbd_state_rv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) enum drbd_state_rv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) _conn_request_state(struct drbd_connection *connection, union drbd_state mask, union drbd_state val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) enum chg_state_flags flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) enum drbd_state_rv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) conn_request_state(struct drbd_connection *connection, union drbd_state mask, union drbd_state val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) enum chg_state_flags flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) extern void drbd_resume_al(struct drbd_device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) extern bool conn_all_vols_unconf(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * drbd_request_state() - Request a state change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @device: DRBD device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @mask: mask of state bits to change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @val: value of new state bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * This is the most graceful way of requesting a state change. It is verbose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * quite verbose in case the state change is not possible, and all those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * state changes are globally serialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline int drbd_request_state(struct drbd_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) union drbd_state mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) union drbd_state val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return _drbd_request_state(device, mask, val, CS_VERBOSE + CS_ORDERED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int drbd_request_detach_interruptible(struct drbd_device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) enum drbd_role conn_highest_role(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) enum drbd_role conn_highest_peer(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) enum drbd_disk_state conn_lowest_disk(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) enum drbd_disk_state conn_highest_pdsk(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) enum drbd_conns conn_lowest_conn(struct drbd_connection *connection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #endif