DRBD updates for 4.21
Subsystems (2)
Lars Ellenberg
maintainercover DRBD updates for 4.21
Hi Jens,
I hope this is not too late for your for-4.21 branch.
These are all from last April or even older,
I was convinced we sent these for 4.19 already.
But we didn't :-(
The interesting new feature is "introduce P_ZEROES", which is replacing 45c21793a660 drbd: implement REQ_OP_WRITE_ZEROES
because that led to "full allocation" for fstrim on dm-thin or similar, which is certainly not the intended behavior.
Patch 3 to 8 help with recovery from odd corner cases in multiple error scenarios in a cluster, potentially after some admin already "tried things".
All others are sufficiently simple and supposedly "obvious".
Lars Ellenberg (13):
drbd: must not use connection after kref_put(&connection->kref)
drbd: centralize printk reporting of new size into drbd_set_my_capacity()
drbd: ignore "all zero" peer volume sizes in handshake
drbd: disconnect, if the wrong UUIDs are attached on a connected peer
drbd: fix confusing error message during attach
drbd: attach on connected diskless peer must not shrink a consistent device
drbd: reject attach of unsuitable uuids even if connected
drbd: fix comment typos
drbd: do not block when adjusting "disk-options" while IO is frozen
drbd: avoid spurious self-outdating with concurrent disconnect / down
drbd: don't retry connection if peers do not agree on "authentication" settings
drbd: skip spurious timeout (ping-timeo) when failing promote
drbd: introduce P_ZEROES (REQ_OP_WRITE_ZEROES on the "wire")
Luc Van Oostenryck (1):
drbd: fix print_st_err()'s prototype to match the definition
Nathan Chancellor (2):
drbd: Avoid Clang warning about pointless switch statment
drbd: Change drbd_request_detach_interruptible's return type to int
Roland Kammerer (1):
drbd: narrow rcu_read_lock in drbd_sync_handshake
drivers/block/drbd/drbd_debugfs.c | 2 + drivers/block/drbd/drbd_int.h | 19 +-- drivers/block/drbd/drbd_main.c | 28 +++- drivers/block/drbd/drbd_nl.c | 133 ++++++++++++--- drivers/block/drbd/drbd_protocol.h | 47 ++++++ drivers/block/drbd/drbd_receiver.c | 251 +++++++++++++++++++++++++---- drivers/block/drbd/drbd_req.c | 19 +-- drivers/block/drbd/drbd_req.h | 2 + drivers/block/drbd/drbd_state.c | 11 +- drivers/block/drbd/drbd_state.h | 5 +- drivers/block/drbd/drbd_worker.c | 2 +- include/linux/drbd.h | 2 +- include/linux/genl_magic_struct.h | 5 +- 13 files changed, 434 insertions(+), 92 deletions(-)
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 1/17 drbd: narrow rcu_read_lock in drbd_sync_handshake
From: Roland Kammerer <[email protected]>
So far there was the possibility that we called genlmsg_new(GFP_NOIO)/mutex_lock() while holding an rcu_read_lock().
This included cases like:
drbd_sync_handshake (acquire the RCU lock)
drbd_asb_recover_1p
drbd_khelper
drbd_bcast_event
genlmsg_new(GFP_NOIO) --> may sleepdrbd_sync_handshake (acquire the RCU lock)
drbd_asb_recover_1p
drbd_khelper
notify_helper
genlmsg_new(GFP_NOIO) --> may sleepdrbd_sync_handshake (acquire the RCU lock)
drbd_asb_recover_1p
drbd_khelper
notify_helper
mutex_lock --> may sleepWhile using GFP_ATOMIC whould have been possible in the first two cases, the real fix is to narrow the rcu_read_lock.
--- drivers/block/drbd/drbd_receiver.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/block/drbd/drbd_receiver.c +6 -5
@@ -3364,7 +3364,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,enum drbd_conns rv =C_MASK ;enum drbd_disk_state mydisk;struct net_conf *nc; -int hg, rule_nr, rr_conflict, tentative; +int hg, rule_nr, rr_conflict, tentative, always_asbp; mydisk = device->state.disk;if (mydisk ==D_NEGOTIATING )
@@ -3415,8 +3415,12 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,rcu_read_lock (); nc =rcu_dereference (peer_device->connection->net_conf); + always_asbp = nc->always_asbp; + rr_conflict = nc->rr_conflict; + tentative = nc->tentative; +rcu_read_unlock (); -if (hg ==100 || (hg ==-100 && nc->always_asbp)) { +if (hg ==100 || (hg ==-100 && always_asbp)) {int pcount = (device->state.role ==R_PRIMARY ) + (peer_role ==R_PRIMARY );int forced = (hg ==-100 );
@@ -3455,9 +3459,6 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_peer_device *peer_device,"Sync from %s node\n" , (hg < 0) ? "peer" : "this"); } - rr_conflict = nc->rr_conflict; - tentative = nc->tentative; -rcu_read_unlock ();if (hg ==-100 ) {/* FIXME this log message is not correct if we end up here
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 2/17 drbd: must not use connection after kref_put(&connection->kref)
In reply to Lars Ellenberg--- drivers/block/drbd/drbd_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/block/drbd/drbd_state.c +1 -2
@@ -2109,9 +2109,8 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)spin_unlock_irq (&connection->resource->req_lock); } } -kref_put (&connection->kref, drbd_destroy_connection); -conn_md_sync (connection); +kref_put (&connection->kref, drbd_destroy_connection);return 0 ; }
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 3/17 drbd: centralize printk reporting of new size into drbd_set_my_capacity()
In reply to Lars EllenbergPreviously, some implicit resizes that happend during handshake have not been reported as prominently as explicit resize.
--- drivers/block/drbd/drbd_int.h | 8 +------- drivers/block/drbd/drbd_main.c | 17 ++++++++++++++++- drivers/block/drbd/drbd_nl.c | 3 --- 3 files changed, 17 insertions(+), 11 deletions(-)
drivers/block/drbd/drbd_int.h +1 -7
@@ -1609,13 +1609,7 @@ static inline void drbd_tcp_quickack(struct socket *sock) }/* sets the number of 512 byte sectors of our virtual device */ -static inline void drbd_set_my_capacity (struct drbd_device *device, -sector_t size) -{ -/* set_capacity(device->this_bdev->bd_disk, size); */ -set_capacity (device->vdisk, size); - device->this_bdev->bd_inode->i_size = (loff_t )size <<9 ; -} +void drbd_set_my_capacity (struct drbd_device *device,sector_t size);/* * used to submit our private bio
drivers/block/drbd/drbd_main.c +16 -1
@@ -2034,6 +2034,21 @@ void drbd_init_set_defaults(struct drbd_device *device) device->local_max_bio_size =DRBD_MAX_BIO_SIZE_SAFE ; } +static void _drbd_set_my_capacity (struct drbd_device *device,sector_t size) +{ +/* set_capacity(device->this_bdev->bd_disk, size); */ +set_capacity (device->vdisk, size); + device->this_bdev->bd_inode->i_size = (loff_t )size <<9 ; +} + +void drbd_set_my_capacity (struct drbd_device *device,sector_t size) +{ +char ppb[10 ]; +_drbd_set_my_capacity (device, size); +drbd_info (device,"size = %s (%llu KB)\n" , +ppsize (ppb, size>>1 ), (unsigned long long )size>>1 ); +} +void drbd_device_cleanup (struct drbd_device *device) {int i;
@@ -2059,7 +2074,7 @@ void drbd_device_cleanup(struct drbd_device *device) }D_ASSERT (device,first_peer_device (device)->connection->net_conf ==NULL ); -drbd_set_my_capacity (device,0 ); +_drbd_set_my_capacity (device,0 );if (device->bitmap) {/* maybe never allocated. */ drbd_bm_resize (device,0 ,1 );
drivers/block/drbd/drbd_nl.c +0 -3
@@ -921,7 +921,6 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct } prev;sector_t u_size, size;struct drbd_md *md = &device->ldev->md; -char ppb[10 ];void *buffer;int md_moved, la_size_changed;
@@ -999,8 +998,6 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct/* racy, see comments above. */ drbd_set_my_capacity (device, size); md->la_size_sect = size; -drbd_info (device,"size = %s (%llu KB)\n" ,ppsize (ppb, size>>1 ), - (unsigned long long )size>>1 ); }if (rv <=DS_ERROR ) goto err_out;
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 4/17 drbd: ignore "all zero" peer volume sizes in handshake
In reply to Lars EllenbergDuring handshake, if we are diskless ourselves, we used to accept any size presented by the peer.
Which could be zero if that peer was just brought up and connected to us without having a disk attached first, in which case both peers would just "flip" their volume sizes.
Now, even a diskless node will ignore "zero" sizes presented by a diskless peer.
Also a currently Diskless Primary will refuse to shrink during handshake:
it may be frozen, and waiting for a "suitable" local disk or peer to re-appear (on-no-data-accessible suspend-io). If the peer is smaller than what we used to be, it is not suitable.
The logic for a diskless node during handshake is now supposed to be:
believe the peer, if
- I don't have a current size myself
- we agree on the size anyways
- I do have a current size, am Secondary, and he has the only disk
- I do have a current size, am Primary, and he has the only disk, which is larger than my current size
--- drivers/block/drbd/drbd_receiver.c | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
drivers/block/drbd/drbd_receiver.c +30 -3
@@ -3981,6 +3981,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_infostruct o_qlim *o = (connection->agreed_features &DRBD_FF_WSAME ) ? p->qlim :NULL ;enum determine_dev_size dd =DS_UNCHANGED ;sector_t p_size, p_usize, p_csize, my_usize; +sector_t new_size, cur_size;int ldsc =0 ;/* local disk size changed */ enum dds_flags ddsf;
@@ -3988,6 +3989,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_infoif (!peer_device)return config_unknown_volume (connection, pi); device = peer_device->device; + cur_size =drbd_get_capacity (device->this_bdev); p_size =be64_to_cpu (p->d_size); p_usize =be64_to_cpu (p->u_size);
@@ -3998,7 +4000,6 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info device->p_size = p_size;if (get_ldev (device)) { -sector_t new_size, cur_size;rcu_read_lock (); my_usize =rcu_dereference (device->ldev->disk_conf)->disk_size;rcu_read_unlock ();
@@ -4016,7 +4017,6 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info/* Never shrink a device with usable data during connect. But allow online shrinking if we are connected. */ new_size =drbd_new_dev_size (device, device->ldev, p_usize,0 ); - cur_size =drbd_get_capacity (device->this_bdev);if (new_size < cur_size && device->state.disk >=D_OUTDATED && device->state.conn <C_CONNECTED ) {
@@ -4081,9 +4081,36 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info* * However, if he sends a zero current size, * take his (user-capped or) backing disk size anyways. +* +* Unless of course he does not have a disk himself. +* In which case we ignore this completely. */ +sector_t new_size = p_csize ?: p_usize ?: p_size;drbd_reconsider_queue_parameters (device,NULL , o); -drbd_set_my_capacity (device, p_csize ?: p_usize ?: p_size); +if (new_size ==0 ) { +/* Ignore, peer does not know nothing. */ + }else if (new_size == cur_size) { +/* nothing to do */ + }else if (cur_size !=0 && p_size ==0 ) { +drbd_warn (device,"Ignored diskless peer device size (peer:%llu != me:%llu sectors)!\n" , + (unsigned long long )new_size, (unsigned long long )cur_size); + }else if (new_size < cur_size && device->state.role ==R_PRIMARY ) { +drbd_err (device,"The peer's device size is too small! (%llu < %llu sectors); demote me first!\n" , + (unsigned long long )new_size, (unsigned long long )cur_size); +conn_request_state (peer_device->connection,NS (conn,C_DISCONNECTING ),CS_HARD ); +return -EIO ; + }else { +/* I believe the peer, if +* - I don't have a current size myself +* - we agree on the size anyways +* - I do have a current size, am Secondary, +* and he has the only disk +* - I do have a current size, am Primary, +* and he has the only disk, +* which is larger than my current size +*/ +drbd_set_my_capacity (device, new_size); + } }if (get_ldev (device)) {
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 5/17 drbd: disconnect, if the wrong UUIDs are attached on a connected peer
In reply to Lars EllenbergWith "on-no-data-accessible suspend-io", DRBD requires the next attach or connect to be to the very same data generation uuid tag it lost last.
If we first lost connection to the peer, then later lost connection to our own disk, we would usually refuse to re-connect to the peer, because it presents the wrong data set.
However, if the peer first connects without a disk,
and then attached its disk, we accepted that same wrong data set, which would be "unexpected" by any user of that DRBD and cause "undefined results" (read: very likely data corruption).
The fix is to forcefully disconnect as soon as we notice that the peer attached to the "wrong" dataset.
--- drivers/block/drbd/drbd_receiver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_receiver.c +1 -1
@@ -4170,7 +4170,7 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_infokfree (device->p_uuid); device->p_uuid = p_uuid; -if (device->state.conn <C_CONNECTED && +if ((device->state.conn <C_CONNECTED || device->state.pdsk ==D_DISKLESS ) && device->state.disk <D_INCONSISTENT && device->state.role ==R_PRIMARY && (device->ed_uuid & ~((u64 )1 )) != (p_uuid[UI_CURRENT ] & ~((u64 )1 ))) {
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 6/17 drbd: fix confusing error message during attach
In reply to Lars EllenbergIf we attach a (consistent) backing device,
which knows about a last-agreed effective size,
and that effective size is *larger* than the currently requested size, we refused to attach with ERR_DISK_TOO_SMALL
Failure: (111) Low.dev. smaller than requested DRBD-dev. size.
which is confusing to say the least.
This patch changes the error code in that case to ERR_IMPLICIT_SHRINK
Failure: (170) Implicit device shrinking not allowed. See kernel log. additional info from kernel:
To-be-attached device has last effective > current size, and is consistent (9999 > 7777 sectors). Refusing to attach.
It also allows to attach with an explicit size.
--- drivers/block/drbd/drbd_nl.c | 49 ++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-)
drivers/block/drbd/drbd_nl.c +44 -5
@@ -127,6 +127,35 @@ static int drbd_msg_put_info(struct sk_buff *skb, const char *info)return 0 ; } +__printf(2, 3) +static int drbd_msg_sprintf_info (struct sk_buff *skb,const char *fmt, ...) +{ +va_list args; +struct nlattr *nla, *txt; +int err = -EMSGSIZE ; +int len; + + nla =nla_nest_start (skb,DRBD_NLA_CFG_REPLY ); +if (!nla) +return err; + + txt =nla_reserve (skb, T_info_text,256 ); +if (!txt) { +nla_nest_cancel (skb, nla); +return err; + } +va_start (args, fmt); + len =vscnprintf (nla_data (txt),256 , fmt, args); +va_end (args); + +/* maybe: retry with larger reserve, if truncated */ + txt->nla_len =nla_attr_size (len+1 ); +nlmsg_trim (skb, (char *)txt +NLA_ALIGN (txt->nla_len)); +nla_nest_end (skb, nla); + +return 0 ; +} +/* This would be a good candidate for a "pre_doit" hook, * and per-family private info->pointers. * But we need to stay compatible with older kernels.
@@ -1947,11 +1976,21 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) }/* Prevent shrinking of consistent devices ! */ -if (drbd_md_test_flag (nbc,MDF_CONSISTENT ) && -drbd_new_dev_size (device, nbc, nbc->disk_conf->disk_size,0 ) < nbc->md.la_size_sect) { -drbd_warn (device,"refusing to truncate a consistent device\n" ); - retcode =ERR_DISK_TOO_SMALL ; - goto force_diskless_dec; + { +unsigned long long nsz =drbd_new_dev_size (device, nbc, nbc->disk_conf->disk_size,0 ); +unsigned long long eff = nbc->md.la_size_sect; +if (drbd_md_test_flag (nbc,MDF_CONSISTENT ) && nsz < eff) { +if (nsz == nbc->disk_conf->disk_size) { +drbd_warn (device,"truncating a consistent device during attach (%llu < %llu)\n" , nsz, eff); + }else { +drbd_warn (device,"refusing to truncate a consistent device (%llu < %llu)\n" , nsz, eff); +drbd_msg_sprintf_info (adm_ctx.reply_skb, +"To-be-attached device has last effective > current size, and is consistent\n" +"(%llu > %llu sectors). Refusing to attach." , eff, nsz); + retcode =ERR_IMPLICIT_SHRINK ; + goto force_diskless_dec; + } + } }lock_all_resources ();
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 7/17 drbd: attach on connected diskless peer must not shrink a consistent device
In reply to Lars EllenbergIf we would reject a new handshake, if the peer had attached first, and then connected, we should force disconnect if the peer first connects, and only then attaches.
--- drivers/block/drbd/drbd_receiver.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/block/drbd/drbd_receiver.c +6 -5
@@ -4014,12 +4014,13 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_infoif (device->state.conn ==C_WF_REPORT_PARAMS ) p_usize =min_not_zero (my_usize, p_usize); -/* Never shrink a device with usable data during connect. -But allow online shrinking if we are connected. */ +/* Never shrink a device with usable data during connect, +* or "attach" on the peer. +* But allow online shrinking if we are connected. */ new_size =drbd_new_dev_size (device, device->ldev, p_usize,0 );if (new_size < cur_size && device->state.disk >=D_OUTDATED && - device->state.conn <C_CONNECTED ) { + (device->state.conn <C_CONNECTED || device->state.pdsk ==D_DISKLESS )) {drbd_err (device,"The peer's disk size is too small! (%llu < %llu sectors)\n" , (unsigned long long )new_size, (unsigned long long )cur_size);conn_request_state (peer_device->connection,NS (conn,C_DISCONNECTING ),CS_HARD );
@@ -4047,8 +4048,8 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_infosynchronize_rcu ();kfree (old_disk_conf); -drbd_info (device,"Peer sets u_size to %lu sectors\n" , - (unsigned long )my_usize); +drbd_info (device,"Peer sets u_size to %lu sectors (old: %lu)\n" , + (unsigned long )p_usize, (unsigned long )my_usize); }put_ldev (device);
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 8/17 drbd: reject attach of unsuitable uuids even if connected
In reply to Lars EllenbergMultiple failure scenario:
a) all good
Connected Primary/Secondary UpToDate/UpToDate
b) lose disk on Primary,
Connected Primary/Secondary Diskless/UpToDate
c) continue to write to the device,
changes only make it to the Secondary storage.
d) lose disk on Secondary,
Connected Primary/Secondary Diskless/Diskless
e) now try to re-attach on Primary
This would have succeeded before, even though that is clearly the wrong data set to attach to (missing the modifications from c). Because we only compared our "effective" and the "to-be-attached" data generation uuid tags if (device->state.conn < C_CONNECTED).
Fix: change that constraint to (device->state.pdsk != D_UP_TO_DATE) compare the uuids, and reject the attach.
This patch also tries to improve the reverse scenario:
first lose Secondary, then Primary disk,
then try to attach the disk on Secondary.
Before this patch, the attach on the Secondary succeeds, but since commit
drbd: disconnect, if the wrong UUIDs are attached on a connected peer the Primary will notice unsuitable data, and drop the connection hard.
Though unfortunately at a point in time during the handshake where we cannot easily abort the attach on the peer without more refactoring of the handshake.
We now reject any attach to "unsuitable" uuids,
as long as we can see a Primary role,
unless we already have access to "good" data.
--- drivers/block/drbd/drbd_nl.c | 6 +++--- drivers/block/drbd/drbd_receiver.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-)
drivers/block/drbd/drbd_nl.c +3 -3
@@ -1960,9 +1960,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) } } -if (device->state.conn <C_CONNECTED && - device->state.role ==R_PRIMARY && device->ed_uuid && - (device->ed_uuid & ~((u64 )1 )) != (nbc->md.uuid[UI_CURRENT ] & ~((u64 )1 ))) { +if (device->state.pdsk !=D_UP_TO_DATE && device->ed_uuid && + (device->state.role ==R_PRIMARY || device->state.peer ==R_PRIMARY ) && + (device->ed_uuid & ~((u64 )1 )) != (nbc->md.uuid[UI_CURRENT ] & ~((u64 )1 ))) {drbd_err (device,"Can only attach to data with current UUID=%016llX\n" , (unsigned long long )device->ed_uuid); retcode =ERR_DATA_NOT_CURRENT ;
drivers/block/drbd/drbd_receiver.c +19 -0
@@ -4397,6 +4397,25 @@ static int receive_state(struct drbd_connection *connection, struct packet_infoif (peer_state.conn ==C_AHEAD ) ns.conn =C_BEHIND ; +/* TODO: +* if (primary and diskless and peer uuid != effective uuid) +* abort attach on peer; +* +* If this node does not have good data, was already connected, but +* the peer did a late attach only now, trying to "negotiate" with me, +* AND I am currently Primary, possibly frozen, with some specific +* "effective" uuid, this should never be reached, really, because +* we first send the uuids, then the current state. +* +* In this scenario, we already dropped the connection hard +* when we received the unsuitable uuids (receive_uuids(). +* +* Should we want to change this, that is: not drop the connection in +* receive_uuids() already, then we would need to add a branch here +* that aborts the attach of "unsuitable uuids" on the peer in case +* this node is currently Diskless Primary. +*/ +if (device->p_uuid && peer_state.disk >=D_NEGOTIATING &&get_ldev_if_state (device,D_NEGOTIATING )) {int cr;/* consider resync */
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 9/17 drbd: fix comment typos
In reply to Lars Ellenberg--- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_state.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/block/drbd/drbd_receiver.c +1 -1
@@ -4428,7 +4428,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info (peer_state.disk ==D_NEGOTIATING || os.disk == D_NEGOTIATING));/* if we have both been inconsistent, and the peer has been -* forced to be UpToDate with --overwrite-data */ +* forced to be UpToDate with --force */ cr |=test_bit (CONSIDER_RESYNC , &device->flags);/* if we had been plain connected, and the admin requested to * start a sync by "invalidate" or "invalidate-remote" */
drivers/block/drbd/drbd_state.c +1 -1
@@ -1124,7 +1124,7 @@ static union drbd_state sanitize_state(struct drbd_device *device, union drbd_st ns.pdsk =D_UP_TO_DATE ; } -/* Implications of the connection stat on the disk states */ +/* Implications of the connection state on the disk states */ disk_min =D_DISKLESS ; disk_max =D_UP_TO_DATE ; pdsk_min =D_INCONSISTENT ;
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 10/17 drbd: do not block when adjusting "disk-options" while IO is frozen
In reply to Lars Ellenberg"suspending" IO is overloaded.
It can mean "do not allow new requests" (obviously), but it also may mean "must not complete pending IO", for example while the fencing handlers do their arbitration.
When adjusting disk options, we suspend io (disallow new requests), then wait for the activity-log to become unused (drain all IO completions), and possibly replace it with a new activity log of different size.
If the other "suspend IO" aspect is active, pending IO completions won't happen, and we would block forever (unkillable drbdsetup process).
Fix this by skipping the activity log adjustment if the "al-extents" setting did not change. Also, in case it did change, fail early without blocking if it looks like we would block forever.
--- drivers/block/drbd/drbd_nl.c | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/block/drbd/drbd_nl.c +29 -8
@@ -1540,6 +1540,30 @@ static void sanitize_disk_conf(struct drbd_device *device, struct disk_conf *dis } } +static int disk_opts_check_al_size (struct drbd_device *device,struct disk_conf *dc) +{ +int err = -EBUSY ; + +if (device->act_log && + device->act_log->nr_elements == dc->al_extents) +return 0 ; + +drbd_suspend_io (device); +/* If IO completion is currently blocked, we would likely wait +* "forever" for the activity log to become unused. So we don't. */ +if (atomic_read (&device->ap_bio_cnt)) + goto out; + +wait_event (device->al_wait,lc_try_lock (device->act_log)); +drbd_al_shrink (device); + err =drbd_check_al_size (device, dc); +lc_unlock (device->act_log); +wake_up (&device->al_wait); +out: +drbd_resume_io (device); +return err; +} +int drbd_adm_disk_opts (struct sk_buff *skb,struct genl_info *info) {struct drbd_config_context adm_ctx;
@@ -1602,15 +1626,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) } } -drbd_suspend_io (device); -wait_event (device->al_wait,lc_try_lock (device->act_log)); -drbd_al_shrink (device); - err =drbd_check_al_size (device, new_disk_conf); -lc_unlock (device->act_log); -wake_up (&device->al_wait); -drbd_resume_io (device); - + err =disk_opts_check_al_size (device, new_disk_conf);if (err) { +/* Could be just "busy". Ignore? +* Introduce dedicated error code? */ +drbd_msg_put_info (adm_ctx.reply_skb, +"Try again without changing current al-extents setting" ); retcode =ERR_NOMEM ; goto fail_unlock; }
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 11/17 drbd: avoid spurious self-outdating with concurrent disconnect / down
In reply to Lars EllenbergIf peers are "simultaneously" told to disconnect from each other, either explicitly, or implicitly by taking down the resource, with bad timing, one side may see its disconnect "fail" with a result of "state change failed by peer", and interpret this as "please oudate yourself".
Try to catch this by checking for current connection status, and possibly retry as local-only state change instead.
--- drivers/block/drbd/drbd_nl.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/block/drbd/drbd_nl.c +7 -0
@@ -2711,8 +2711,10 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)static enum drbd_state_rv conn_try_disconnect (struct drbd_connection *connection,bool force) { +enum drbd_conns cstate;enum drbd_state_rv rv; +repeat: rv =conn_request_state (connection,NS (conn,C_DISCONNECTING ), force ?CS_HARD :0 );
@@ -2730,6 +2732,11 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connectionbreak ;case SS_CW_FAILED_BY_PEER : +spin_lock_irq (&connection->resource->req_lock); + cstate = connection->cstate; +spin_unlock_irq (&connection->resource->req_lock); +if (cstate <=C_WF_CONNECTION ) + goto repeat;/* The peer probably wants to see us outdated. */ rv =conn_request_state (connection,NS2 (conn,C_DISCONNECTING , disk,D_OUTDATED ),0 );
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 12/17 drbd: fix print_st_err()'s prototype to match the definition
In reply to Lars EllenbergFrom: Luc Van Oostenryck <[email protected]>
print_st_err() is defined with its 4th argument taking an 'enum drbd_state_rv' but its prototype use an int for it.
Fix this by using 'enum drbd_state_rv' in the prototype too.
--- drivers/block/drbd/drbd_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_state.h +1 -1
@@ -131,7 +131,7 @@ extern enum drbd_state_rv _drbd_set_state(struct drbd_device *, union drbd_state enum chg_state_flags, struct completion *done);extern void print_st_err (struct drbd_device *,union drbd_state , -union drbd_state ,int ); +union drbd_state ,enum drbd_state_rv ); enum drbd_state_rv _conn_request_state(struct drbd_connection *connection, union drbd_state mask, union drbd_state val,
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 13/17 drbd: don't retry connection if peers do not agree on "authentication" settings
In reply to Lars Ellenbergemma: "Unexpected data packet AuthChallenge (0x0010)"
ava: "expected AuthChallenge packet, received: ReportProtocol (0x000b)"
"Authentication of peer failed, trying again."
Pattern repeats.
There is no point in retrying the handshake,
if we expect to receive an AuthChallenge,
but the peer is not even configured to expect or use a shared secret.
--- drivers/block/drbd/drbd_receiver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_receiver.c +1 -1
@@ -5332,7 +5332,7 @@ static int drbd_do_auth(struct drbd_connection *connection)if (pi.cmd !=P_AUTH_CHALLENGE ) {drbd_err (connection,"expected AuthChallenge packet, received: %s (0x%04x)\n" ,cmdname (pi.cmd), pi.cmd); - rv =0 ; + rv =-1 ; goto fail; }
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 14/17 drbd: skip spurious timeout (ping-timeo) when failing promote
In reply to Lars EllenbergIf you try to promote a Secondary while connected to a Primary and allow-two-primaries is NOT set, we will wait for "ping-timeout" to give this node a chance to detect a dead primary,
in case the cluster manager noticed faster than we did.
But if we then are *still* connected to a Primary, we fail (after an additional timeout of ping-timout).
This change skips the spurious second timeout.
Most people won't notice really,
since "ping-timeout" by default is half a second.
But in some installations, ping-timeout may be 10 or 20 seconds or more, and spuriously delaying the error return becomes annoying.
--- drivers/block/drbd/drbd_nl.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/block/drbd/drbd_nl.c +8 -7
@@ -697,14 +697,15 @@ drbd_set_role(struct drbd_device *const device, enum drbd_role new_role, int forif (rv ==SS_TWO_PRIMARIES ) {/* Maybe the peer is detected as dead very soon... retry at most once more in this case. */ -int timeo; -rcu_read_lock (); - nc =rcu_dereference (connection->net_conf); - timeo = nc ? (nc->ping_timeo +1 ) *HZ /10 :1 ; -rcu_read_unlock (); -schedule_timeout_interruptible (timeo); -if (try < max_tries) +if (try < max_tries) { +int timeo; try = max_tries -1 ; +rcu_read_lock (); + nc =rcu_dereference (connection->net_conf); + timeo = nc ? (nc->ping_timeo +1 ) *HZ /10 :1 ; +rcu_read_unlock (); +schedule_timeout_interruptible (timeo); + }continue ; }if (rv <SS_SUCCESS ) {
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 15/17 drbd: introduce P_ZEROES (REQ_OP_WRITE_ZEROES on the "wire")
In reply to Lars EllenbergAnd also re-enable partial-zero-out + discard aligned.
With the introduction of REQ_OP_WRITE_ZEROES,
we started to use that for both WRITE_ZEROES and DISCARDS, hoping that WRITE_ZEROES would "do what we want", UNMAP if possible, zero-out the rest.
The example scenario is some LVM "thin" backend.
While an un-allocated block on dm-thin reads as zeroes, on a dm-thin with "skip_block_zeroing=true", after a partial block write allocated that block, that same block may well map "undefined old garbage" from the backends on LBAs that have not yet been written to.
If we cannot distinguish between zero-out and discard on the receiving side, to avoid "undefined old garbage" to pop up randomly at later times on supposedly zero-initialized blocks, we'd need to map all discards to zero-out on the receiving side. But that would potentially do a full alloc on thinly provisioned backends, even when the expectation was to unmap/trim/discard/de-allocate.
We need to distinguish on the protocol level, whether we need to guarantee zeroes (and thus use zero-out, potentially doing the mentioned full-alloc), or if we want to put the emphasis on discard, and only do a "best effort zeroing" (by "discarding" blocks aligned to discard-granularity, and zeroing only potential unaligned head and tail clippings to at least *try* to avoid "false positives" in an online-verify later), hoping that someone set skip_block_zeroing=false.
For some discussion regarding this on dm-devel, see also
https://www.mail-archive.com/dm-devel%40redhat.com/msg07965.html
https://www.redhat.com/archives/dm-devel/2018-January/msg00271.html
For backward compatibility, P_TRIM means zero-out, unless the DRBD_FF_WZEROES feature flag is agreed upon during handshake.
To have upper layers even try to submit WRITE ZEROES requests, we need to announce "efficient zeroout" independently.
We need to fixup max_write_zeroes_sectors after blk_queue_stack_limits():
if we can handle "zeroes" efficiently on the protocol,
we want to do that, even if our backend does not announce max_write_zeroes_sectors itself.
--- drivers/block/drbd/drbd_debugfs.c | 2 + drivers/block/drbd/drbd_int.h | 11 +- drivers/block/drbd/drbd_main.c | 11 +- drivers/block/drbd/drbd_nl.c | 16 +++ drivers/block/drbd/drbd_protocol.h | 47 ++++++++ drivers/block/drbd/drbd_receiver.c | 171 ++++++++++++++++++++++++++--- drivers/block/drbd/drbd_req.c | 19 ++-- drivers/block/drbd/drbd_req.h | 2 + drivers/block/drbd/drbd_worker.c | 2 +- include/linux/drbd.h | 2 +- 10 files changed, 252 insertions(+), 31 deletions(-)
drivers/block/drbd/drbd_debugfs.c +2 -0
@@ -237,6 +237,8 @@ static void seq_print_peer_request_flags(struct seq_file *m, struct drbd_peer_reseq_print_rq_state_bit (m, f &EE_CALL_AL_COMPLETE_IO , &sep,"in-AL" );seq_print_rq_state_bit (m, f &EE_SEND_WRITE_ACK , &sep,"C" );seq_print_rq_state_bit (m, f &EE_MAY_SET_IN_SYNC , &sep,"set-in-sync" ); +seq_print_rq_state_bit (m, f &EE_TRIM , &sep,"trim" ); +seq_print_rq_state_bit (m, f &EE_ZEROOUT , &sep,"zero-out" );seq_print_rq_state_bit (m, f &EE_WRITE_SAME , &sep,"write-same" );seq_putc (m,'\n' ); }
drivers/block/drbd/drbd_int.h +9 -2
@@ -430,7 +430,11 @@ enum { __EE_MAY_SET_IN_SYNC,/* is this a TRIM aka REQ_OP_DISCARD? */ - __EE_IS_TRIM, + __EE_TRIM, +/* explicit zero-out requested, or +* our lower level cannot handle trim, +* and we want to fall back to zeroout instead */ + __EE_ZEROOUT,/* In case a barrier failed, * we need to resubmit without the barrier flag. */
@@ -472,7 +476,8 @@ enum { };#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) -#define EE_IS_TRIM (1<<__EE_IS_TRIM) +#define EE_TRIM (1<<__EE_TRIM) +#define EE_ZEROOUT (1<<__EE_ZEROOUT)#define EE_RESUBMITTED (1<<__EE_RESUBMITTED)#define EE_WAS_ERROR (1<<__EE_WAS_ERROR)#define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST)
@@ -1556,6 +1561,8 @@ extern void start_resync_timer_fn(struct timer_list *t);extern void drbd_endio_write_sec_final (struct drbd_peer_request *peer_req);/* drbd_receiver.c */ +extern int drbd_issue_discard_or_zero_out (struct drbd_device *device, +sector_t start,unsigned int nr_sectors,int flags);extern int drbd_receiver (struct drbd_thread *thi);extern int drbd_ack_receiver (struct drbd_thread *thi);extern void drbd_send_ping_wf (struct work_struct *ws);
drivers/block/drbd/drbd_main.c +8 -3
@@ -1668,7 +1668,11 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection, (bio->bi_opf &REQ_PREFLUSH ?DP_FLUSH :0 ) | (bio_op (bio) ==REQ_OP_WRITE_SAME ?DP_WSAME :0 ) | (bio_op (bio) ==REQ_OP_DISCARD ?DP_DISCARD :0 ) | - (bio_op (bio) ==REQ_OP_WRITE_ZEROES ?DP_DISCARD :0 ); + (bio_op (bio) ==REQ_OP_WRITE_ZEROES ? + ((connection->agreed_features &DRBD_FF_WZEROES ) ? + (DP_ZEROES |(!(bio->bi_opf &REQ_NOUNMAP ) ?DP_DISCARD :0 )) + :DP_DISCARD ) + :0 ); else return bio->bi_opf & REQ_SYNC ? DP_RW_SYNC : 0; }
@@ -1712,10 +1716,11 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request * } p->dp_flags =cpu_to_be32 (dp_flags); -if (dp_flags &DP_DISCARD ) { +if (dp_flags & (DP_DISCARD |DP_ZEROES )) { +enum drbd_packet cmd = (dp_flags &DP_ZEROES ) ?P_ZEROES :P_TRIM ;struct p_trim *t = (struct p_trim *)p; t->size =cpu_to_be32 (req->i.size); - err =__send_command (peer_device->connection, device->vnr, sock,P_TRIM ,sizeof (*t),NULL ,0 ); + err =__send_command (peer_device->connection, device->vnr, sock, cmd,sizeof (*t),NULL ,0 ); goto out; }if (dp_flags &DP_WSAME ) {
drivers/block/drbd/drbd_nl.c +16 -0
@@ -1261,6 +1261,21 @@ static void fixup_discard_if_not_supported(struct request_queue *q) } } +static void fixup_write_zeroes (struct drbd_device *device,struct request_queue *q) +{ +/* Fixup max_write_zeroes_sectors after blk_queue_stack_limits(): +* if we can handle "zeroes" efficiently on the protocol, +* we want to do that, even if our backend does not announce +* max_write_zeroes_sectors itself. */ +struct drbd_connection *connection =first_peer_device (device)->connection; +/* If the peer announces WZEROES support, use it. Otherwise, rather +* send explicit zeroes than rely on some discard-zeroes-data magic. */ +if (connection->agreed_features &DRBD_FF_WZEROES ) + q->limits.max_write_zeroes_sectors =DRBD_MAX_BBIO_SECTORS ; +else + q->limits.max_write_zeroes_sectors =0 ; +} + static void decide_on_write_same_support(struct drbd_device *device, struct request_queue *q, struct request_queue *b, struct o_qlim *o,
@@ -1371,6 +1386,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi } }fixup_discard_if_not_supported (q); +fixup_write_zeroes (device, q); }void drbd_reconsider_queue_parameters (struct drbd_device *device,struct drbd_backing_dev *bdev,struct o_qlim *o)
drivers/block/drbd/drbd_protocol.h +47 -0
65 lines not on this page · raw message
drivers/block/drbd/drbd_receiver.c +156 -15
266 lines not on this page · raw message
drivers/block/drbd/drbd_req.c +10 -9
@@ -63,7 +63,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct biodrbd_req_make_private_bio (req, bio_src); req->rq_state = (bio_data_dir (bio_src) ==WRITE ?RQ_WRITE :0 ) | (bio_op (bio_src) ==REQ_OP_WRITE_SAME ?RQ_WSAME :0 ) - | (bio_op (bio_src) ==REQ_OP_WRITE_ZEROES ?RQ_UNMAP :0 ) + | (bio_op (bio_src) ==REQ_OP_WRITE_ZEROES ?RQ_ZEROES :0 ) | (bio_op (bio_src) ==REQ_OP_DISCARD ?RQ_UNMAP :0 ); req->device = device; req->master_bio = bio_src;
@@ -1155,12 +1155,11 @@ static int drbd_process_write_request(struct drbd_request *req)return remote; } -static void drbd_process_discard_req (struct drbd_request *req) +static void drbd_process_discard_or_zeroes_req (struct drbd_request *req,int flags) { -struct block_device *bdev = req->device->ldev->backing_bdev; - -if (blkdev_issue_zeroout (bdev, req->i.sector, req->i.size >>9 , -GFP_NOIO ,0 )) +int err =drbd_issue_discard_or_zero_out (req->device, + req->i.sector, req->i.size >>9 , flags); +if (err) req->private_bio->bi_status =BLK_STS_IOERR ;bio_endio (req->private_bio); }
@@ -1189,9 +1188,11 @@ drbd_submit_req_private_bio(struct drbd_request *req)if (get_ldev (device)) {if (drbd_insert_fault (device, type))bio_io_error (bio); -else if (bio_op (bio) ==REQ_OP_WRITE_ZEROES || -bio_op (bio) ==REQ_OP_DISCARD ) -drbd_process_discard_req (req); +else if (bio_op (bio) ==REQ_OP_WRITE_ZEROES ) +drbd_process_discard_or_zeroes_req (req,EE_ZEROOUT | + ((bio->bi_opf &REQ_NOUNMAP ) ?0 :EE_TRIM )); +else if (bio_op (bio) ==REQ_OP_DISCARD ) +drbd_process_discard_or_zeroes_req (req,EE_TRIM );else generic_make_request (bio);put_ldev (device);
drivers/block/drbd/drbd_req.h +2 -0
@@ -208,6 +208,7 @@ enum drbd_req_state_bits { __RQ_WRITE, __RQ_WSAME, __RQ_UNMAP, + __RQ_ZEROES,/* Should call drbd_al_complete_io() for this request... */ __RQ_IN_ACT_LOG,
@@ -253,6 +254,7 @@ enum drbd_req_state_bits {#define RQ_WRITE (1UL << __RQ_WRITE)#define RQ_WSAME (1UL << __RQ_WSAME)#define RQ_UNMAP (1UL << __RQ_UNMAP) +#define RQ_ZEROES (1UL << __RQ_ZEROES)#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)#define RQ_UNPLUG (1UL << __RQ_UNPLUG)#define RQ_POSTPONED (1UL << __RQ_POSTPONED)
drivers/block/drbd/drbd_worker.c +1 -1
@@ -153,7 +153,7 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l do_wake =list_empty (block_id ==ID_SYNCER ? &device->sync_ee : &device->active_ee);/* FIXME do we want to detach for failed REQ_OP_DISCARD? -* ((peer_req->flags & (EE_WAS_ERROR|EE_IS_TRIM)) == EE_WAS_ERROR) */ +* ((peer_req->flags & (EE_WAS_ERROR|EE_TRIM)) == EE_WAS_ERROR) */ if (peer_req->flags &EE_WAS_ERROR )__drbd_chk_io_error (device,DRBD_WRITE_ERROR );
include/linux/drbd.h +1 -1
@@ -51,7 +51,7 @@#endif extern const char *drbd_buildtag (void ); -#define REL_VERSION "8.4.10" +#define REL_VERSION "8.4.11"#define API_VERSION 1#define PRO_VERSION_MIN 86#define PRO_VERSION_MAX 101
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 16/17 drbd: Avoid Clang warning about pointless switch statment
In reply to Lars EllenbergFrom: Nathan Chancellor <[email protected]>
There are several warnings from Clang about no case statement matching the constant 0:
In file included from drivers/block/drbd/drbd_receiver.c:48:
In file included from drivers/block/drbd/drbd_int.h:48:
In file included from ./include/linux/drbd_genl_api.h:54:
In file included from ./include/linux/genl_magic_struct.h:236:./include/linux/drbd_genl.h:321:1: warning: no case matching constant switch condition '0'
GENL_struct(DRBD_NLA_HELPER, 24, drbd_helper_info, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./include/linux/genl_magic_struct.h:220:10: note: expanded from macro 'GENL_struct'
switch (0) {
^Silence this warning by adding a 'case 0:' statement. Additionally, adjust the alignment of the statements in the ct_assert_unique macro to avoid a checkpatch warning.
This solution was originally sent by Arnd Bergmann with a default case
statement: https://lore.kernel.org/patchwork/patch/756723/
--- include/linux/genl_magic_struct.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/genl_magic_struct.h +4 -1
@@ -191,6 +191,7 @@ static inline void ct_assert_unique_operations(void) {switch (0 ) {#include GENL_MAGIC_INCLUDE_FILE +case 0 : ; } }
@@ -209,6 +210,7 @@ static inline void ct_assert_unique_top_level_attributes(void) {switch (0 ) {#include GENL_MAGIC_INCLUDE_FILE +case 0 : ; } }
@@ -218,7 +220,8 @@ static inline void ct_assert_unique_top_level_attributes(void) static inline void ct_assert_unique_ ## s_name ## _attributes(void) \ { \ switch (0) { \ - s_fields \ + s_fields \ + case 0: \ ; \ } \ }
Signature · 1 line
2.17.1
Lars Ellenberg
maintainerPATCH 17/17 drbd: Change drbd_request_detach_interruptible's return type to int
In reply to Lars EllenbergFrom: Nathan Chancellor <[email protected]>
Clang warns when an implicit conversion is done between enumerated types:
drivers/block/drbd/drbd_state.c:708:8: warning: implicit conversion from enumeration type 'enum drbd_ret_code' to different enumeration type 'enum drbd_state_rv' [-Wenum-conversion]
rv = ERR_INTR;
~ ^~~~~~~~drbd_request_detach_interruptible's only call site is in the return statement of adm_detach, which returns an int. Change the return type of drbd_request_detach_interruptible to match, silencing Clang's warning.
--- drivers/block/drbd/drbd_state.c | 6 ++---- drivers/block/drbd/drbd_state.h | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-)
drivers/block/drbd/drbd_state.c +2 -4
@@ -688,11 +688,9 @@ request_detach(struct drbd_device *device) CS_VERBOSE | CS_ORDERED | CS_INHIBIT_MD_IO); } -enum drbd_state_rv -drbd_request_detach_interruptible (struct drbd_device *device) +int drbd_request_detach_interruptible (struct drbd_device *device) { -enum drbd_state_rv rv; -int ret; +int ret, rv;drbd_suspend_io (device);/* so no-one is stuck in drbd_al_begin_io */ wait_event_interruptible(device->state_wait,
drivers/block/drbd/drbd_state.h +1 -2
@@ -162,8 +162,7 @@ static inline int drbd_request_state(struct drbd_device *device, }/* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */ -enum drbd_state_rv -drbd_request_detach_interruptible (struct drbd_device *device); +int drbd_request_detach_interruptible (struct drbd_device *device);enum drbd_role conn_highest_role (struct drbd_connection *connection);enum drbd_role conn_highest_peer (struct drbd_connection *connection);
Signature · 1 line
2.17.1
Jens Axboe
maintainerQuoted 7 lines · Lars Ellenberg
Hi Jens,
I hope this is not too late for your for-4.21 branch.
These are all from last April or even older,
I was convinced we sent these for 4.19 already.
But we didn't :-(
It is very late - even for a normal merge window, I should have had this at least a week ago. This one is going to be earlier, so...
I'm going to take a look at these and queue them up for later inclusion in the merge window, they are not going to make the first pull.
Signature · 1 line
Jens Axboe