DRBD updates for the 3.19 merge window
Subsystems (2)
Philipp Reisner
maintainercover DRBD updates for the 3.19 merge window
Hi Jens,
please take these patches for you for-3.19/drivers branch. They where posted for review on 2014-10-29.
Some cleanups and 3 fixes. Two of them marked for stable:
0005-drbd-merge_bvec_fn-properly-remap-bvm-bi_bdev.patch and 0006-drbd-Fix-state-change-in-case-of-connection-timeout.patch (marked for stable)
Thanks!
Andreas Gruenbacher (2):
drbd: Minor cleanups
drbd: Only use drbd_msg_put_info() in drbd_nl.c
Lars Ellenberg (2):
drbd: fix resync throttling initialization
drbd: merge_bvec_fn: properly remap bvm->bi_bdev
Philipp Reisner (3):
drbd: fix race between role change and handshake
drbd: Fix state change in case of connection timeout
drbd: Remove an useless copy of kernel_setsockopt()
drivers/block/drbd/drbd_actlog.c | 3 +- drivers/block/drbd/drbd_int.h | 39 +++++------------------ drivers/block/drbd/drbd_main.c | 23 ++++---------- drivers/block/drbd/drbd_nl.c | 64 +++++++++++++++++--------------------- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_req.c | 3 +- drivers/block/drbd/drbd_state.c | 42 ++++++++++++++++++++----- drivers/block/drbd/drbd_state.h | 5 +++ drivers/block/drbd/drbd_worker.c | 5 ++- include/linux/drbd.h | 2 +- 10 files changed, 90 insertions(+), 98 deletions(-)
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 1/7 drbd: Minor cleanups
From: Andreas Gruenbacher <[email protected]>
. Update comments
. drbd_set_{in,out_of}_sync(): Remove unused parameters . Move common code into adm_del_resource()
. Redefine ERR_MINOR_EXISTS -> ERR_MINOR_OR_VOLUME_EXISTS
--- drivers/block/drbd/drbd_actlog.c | 3 +- drivers/block/drbd/drbd_int.h | 9 +++--- drivers/block/drbd/drbd_main.c | 6 ++-- drivers/block/drbd/drbd_nl.c | 60 +++++++++++++++++----------------------- include/linux/drbd.h | 2 +- 5 files changed, 35 insertions(+), 45 deletions(-)
drivers/block/drbd/drbd_actlog.c +1 -2
@@ -827,8 +827,7 @@ static int update_sync_bits(struct drbd_device *device,* */ int __drbd_change_sync (struct drbd_device *device,sector_t sector,int size, -enum update_sync_bits_mode mode, -const char *file,const unsigned int line) +enum update_sync_bits_mode mode) {/* Is called from worker and receiver context _only_ */ unsigned long sbnr, ebnr, lbnr;
drivers/block/drbd/drbd_int.h +4 -5
@@ -1662,14 +1662,13 @@ extern void drbd_advance_rs_marks(struct drbd_device *device, unsigned long stilenum update_sync_bits_mode {RECORD_RS_FAILED ,SET_OUT_OF_SYNC ,SET_IN_SYNC };extern int __drbd_change_sync (struct drbd_device *device,sector_t sector,int size, -enum update_sync_bits_mode mode, -const char *file,const unsigned int line); +enum update_sync_bits_mode mode);#define drbd_set_in_sync (device, sector, size) \ - __drbd_change_sync(device, sector, size, SET_IN_SYNC, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, SET_IN_SYNC)#define drbd_set_out_of_sync (device, sector, size) \ - __drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC)#define drbd_rs_failed_io (device, sector, size) \ - __drbd_change_sync(device, sector, size, RECORD_RS_FAILED, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, RECORD_RS_FAILED)extern void drbd_al_shrink (struct drbd_device *device);extern int drbd_initialize_al (struct drbd_device *,void *);
drivers/block/drbd/drbd_main.c +3 -3
@@ -2731,7 +2731,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig device =minor_to_device (minor);if (device) -return ERR_MINOR_EXISTS ; +return ERR_MINOR_OR_VOLUME_EXISTS ;/* GFP_KERNEL, we are outside of all write-out paths */ device =kzalloc (sizeof (struct drbd_device ),GFP_KERNEL );
@@ -2794,7 +2794,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id =idr_alloc (&drbd_devices, device, minor, minor +1 ,GFP_KERNEL );if (id <0 ) {if (id == -ENOSPC ) { - err =ERR_MINOR_EXISTS ; + err =ERR_MINOR_OR_VOLUME_EXISTS ;drbd_msg_put_info (adm_ctx->reply_skb,"requested minor exists already" ); } goto out_no_minor_idr;
@@ -2804,7 +2804,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id =idr_alloc (&resource->devices, device, vnr, vnr +1 ,GFP_KERNEL );if (id <0 ) {if (id == -ENOSPC ) { - err =ERR_MINOR_EXISTS ; + err =ERR_MINOR_OR_VOLUME_EXISTS ;drbd_msg_put_info (adm_ctx->reply_skb,"requested minor exists already" ); } goto out_idr_remove_minor;
drivers/block/drbd/drbd_nl.c +26 -34
104 lines not on this page · raw message
include/linux/drbd.h +1 -1
@@ -172,7 +172,7 @@ enum drbd_ret_code {ERR_RES_NOT_KNOWN =158 ,ERR_RES_IN_USE =159 ,ERR_MINOR_CONFIGURED =160 , -ERR_MINOR_EXISTS =161 , +ERR_MINOR_OR_VOLUME_EXISTS =161 ,ERR_INVALID_REQUEST =162 ,ERR_NEED_APV_100 =163 , ERR_NEED_ALLOW_TWO_PRI = 164,
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 2/7 drbd: Only use drbd_msg_put_info() in drbd_nl.c
In reply to Philipp ReisnerFrom: Andreas Gruenbacher <[email protected]>
Avoid generic netlink calls in other parts of the code base.
--- drivers/block/drbd/drbd_int.h | 1 - drivers/block/drbd/drbd_main.c | 17 +++-------------- drivers/block/drbd/drbd_nl.c | 2 +- 3 files changed, 4 insertions(+), 16 deletions(-)
drivers/block/drbd/drbd_int.h +0 -1
@@ -1454,7 +1454,6 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);/* drbd_nl.c */ -extern int drbd_msg_put_info (struct sk_buff *skb,const char *info);extern void drbd_suspend_io (struct drbd_device *device);extern void drbd_resume_io (struct drbd_device *device);extern char *ppsize (char *buf,unsigned long long size);
drivers/block/drbd/drbd_main.c +3 -14
@@ -2532,10 +2532,6 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opif (!zalloc_cpumask_var (&new_cpu_mask,GFP_KERNEL ))return -ENOMEM ; -/* -retcode = ERR_NOMEM; -drbd_msg_put_info("unable to allocate cpumask"); -*/ /* silently ignore cpu mask on UP kernel */ if (nr_cpu_ids >1 && res_opts->cpu_mask[0 ] !=0 ) {
@@ -2793,20 +2789,16 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id =idr_alloc (&drbd_devices, device, minor, minor +1 ,GFP_KERNEL );if (id <0 ) { -if (id == -ENOSPC ) { +if (id == -ENOSPC ) err =ERR_MINOR_OR_VOLUME_EXISTS ; -drbd_msg_put_info (adm_ctx->reply_skb,"requested minor exists already" ); - } goto out_no_minor_idr; }kref_get (&device->kref); id =idr_alloc (&resource->devices, device, vnr, vnr +1 ,GFP_KERNEL );if (id <0 ) { -if (id == -ENOSPC ) { +if (id == -ENOSPC ) err =ERR_MINOR_OR_VOLUME_EXISTS ; -drbd_msg_put_info (adm_ctx->reply_skb,"requested minor exists already" ); - } goto out_idr_remove_minor; }kref_get (&device->kref);
@@ -2825,10 +2817,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id =idr_alloc (&connection->peer_devices, peer_device, vnr, vnr +1 ,GFP_KERNEL );if (id <0 ) { -if (id == -ENOSPC ) { +if (id == -ENOSPC ) err =ERR_INVALID_REQUEST ; -drbd_msg_put_info (adm_ctx->reply_skb,"requested volume exists already" ); - } goto out_idr_remove_from_resource; }kref_get (&connection->kref);
@@ -2836,7 +2826,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigif (init_submitter (device)) { err =ERR_NOMEM ; -drbd_msg_put_info (adm_ctx->reply_skb,"unable to create submit workqueue" ); goto out_idr_remove_vol; }
drivers/block/drbd/drbd_nl.c +1 -1
@@ -92,7 +92,7 @@ static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info)/* Used on a fresh "drbd_adm_prepare"d reply_skb, this cannot fail: The only * reason it could fail was no space in skb, and there are 4k available. */ -int drbd_msg_put_info (struct sk_buff *skb,const char *info) +static int drbd_msg_put_info (struct sk_buff *skb,const char *info) {struct nlattr *nla;int err = -EMSGSIZE ;
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 3/7 drbd: fix race between role change and handshake
In reply to Philipp ReisnerSymptoms:
If DRBD was "cleanly shut down" (all in sync, both Secondary before disconnect, identical data generation uuids), and then one side was promoted *during* the next connection handshake, the role change could confuse the handshake.
The Primary would get stuck in WFBitmapS, the Secondary would log unexpected cstate (Connected) in receive_bitmap
and get stuck in WFBitmapT.
Fix:
The test in is_valid_soft_transition wrong. It works because the not allowed actions (promote/attach) do not touch the cstate. The previous condition failed to demand a cstate change in one clause.
In order to avoid deadlocks give up the state_mutex while waiting for the transient state to go away.
Conflicts:
drbd/drbd_state.c
drbd/drbd_state.h
drbd/drbd_wrappers.h
--- drivers/block/drbd/drbd_nl.c | 2 +- drivers/block/drbd/drbd_state.c | 41 ++++++++++++++++++++++++++++++++++------- drivers/block/drbd/drbd_state.h | 5 +++++ 3 files changed, 40 insertions(+), 8 deletions(-)
drivers/block/drbd/drbd_nl.c +1 -1
@@ -588,7 +588,7 @@ drbd_set_role(struct drbd_device *const device, enum drbd_role new_role, int for val.i =0 ; val.role = new_role;while (try++ < max_tries) { - rv =_drbd_request_state (device, mask, val,CS_WAIT_COMPLETE ); + rv =_drbd_request_state_holding_state_mutex (device, mask, val,CS_WAIT_COMPLETE );/* in case we first succeeded to outdate, * but now suddenly could establish a connection */
drivers/block/drbd/drbd_state.c +34 -7
68 lines not on this page · raw message
drivers/block/drbd/drbd_state.h +5 -0
@@ -117,6 +117,11 @@ extern enum drbd_state_rv _drbd_request_state(struct drbd_device *, union drbd_state, union drbd_state, enum chg_state_flags); + +extern enum drbd_state_rv +_drbd_request_state_holding_state_mutex (struct drbd_device *,union drbd_state , +union drbd_state ,enum chg_state_flags ); +extern enum drbd_state_rv __drbd_set_state (struct drbd_device *,union drbd_state ,enum chg_state_flags ,struct completion *done);
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 4/7 drbd: fix resync throttling initialization
In reply to Philipp ReisnerFrom: Lars Ellenberg <[email protected]>
If for some reason DRBD resync was the only activity on a backend device, drbd_rs_c_min_rate_throttle() would mistakenly decide that it is still initialization time, and keep throttling the resync.
This patch explicitly initializes ->rs_last_events to the current backend event counters, and drops the rs_last_events == 0 from the throttle condition.
--- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_state.c | 1 - drivers/block/drbd/drbd_worker.c | 5 ++++- 3 files changed, 5 insertions(+), 3 deletions(-)
drivers/block/drbd/drbd_receiver.c +1 -1
@@ -2482,7 +2482,7 @@ bool drbd_rs_c_min_rate_throttle(struct drbd_device *device)atomic_read (&device->rs_sect_ev);if (atomic_read (&device->ap_actlog_cnt) - || !device->rs_last_events || curr_events - device->rs_last_events >64 ) { + || curr_events - device->rs_last_events >64 ) {unsigned long rs_left;int i;
drivers/block/drbd/drbd_state.c +0 -1
@@ -1099,7 +1099,6 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,set_ov_position (device, ns.conn); device->rs_start = now; - device->rs_last_events =0 ; device->rs_last_sect_ev =0 ; device->ov_last_oos_size =0 ; device->ov_last_oos_start =0 ;
drivers/block/drbd/drbd_worker.c +4 -1
@@ -1592,11 +1592,15 @@ void drbd_resync_after_changed(struct drbd_device *device)void drbd_rs_controller_reset (struct drbd_device *device) { +struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk;struct fifo_buffer *plan;atomic_set (&device->rs_sect_in,0 );atomic_set (&device->rs_sect_ev,0 ); device->rs_in_flight =0 ; + device->rs_last_events = + (int )part_stat_read (&disk->part0, sectors[0 ]) + + (int )part_stat_read (&disk->part0, sectors[1 ]);/* Updating the RCU protected object in place is necessary since this function gets called from atomic context.
@@ -1743,7 +1747,6 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) device->rs_failed =0 ; device->rs_paused =0 ; device->rs_same_csum =0 ; - device->rs_last_events =0 ; device->rs_last_sect_ev =0 ; device->rs_total = tw; device->rs_start = now;
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 5/7 drbd: merge_bvec_fn: properly remap bvm->bi_bdev
In reply to Philipp ReisnerFrom: Lars Ellenberg <[email protected]>
This was not noticed for many years. Affects operation if md raid is used a backing device for DRBD.
--- drivers/block/drbd/drbd_req.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/drbd/drbd_req.c +1 -0
@@ -1545,6 +1545,7 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, structstruct request_queue *const b = device->ldev->backing_bdev->bd_disk->queue;if (b->merge_bvec_fn) { + bvm->bi_bdev = device->ldev->backing_bdev; backing_limit = b->merge_bvec_fn (b, bvm, bvec); limit =min (limit, backing_limit); }
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 6/7 drbd: Fix state change in case of connection timeout
In reply to Philipp ReisnerA connection timeout affects all volumes of a resource! Under the following conditions:
A resource with multiple volumes
AND
ko-count >=1
AND
a write request triggers the timeout (ko-count * timeout)
DRBD's internal state gets confused. That in turn may lead to very miss leading follow up failures. E.g. "BUG: scheduling while atomic"
--- drivers/block/drbd/drbd_req.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_req.c +1 -1
@@ -1629,7 +1629,7 @@ void request_timer_fn(unsigned long data) time_after(now, req_peer->pre_send_jif + ent) && !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) {drbd_warn (device,"Remote failed to finish a request within ko-count * timeout\n" ); -_drbd_set_state (_NS (device, conn,C_TIMEOUT ),CS_VERBOSE |CS_HARD ,NULL ); +_conn_request_state (connection,NS (conn,C_TIMEOUT ),CS_VERBOSE |CS_HARD ); } if (dt && oldest_submit_jif != now && time_after(now, oldest_submit_jif + dt) &&
Signature · 1 line
1.9.1
Philipp Reisner
maintainerPATCH 7/7 drbd: Remove an useless copy of kernel_setsockopt()
In reply to Philipp ReisnerOld backward-compat cruft
--- drivers/block/drbd/drbd_int.h | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-)
drivers/block/drbd/drbd_int.h +4 -25
@@ -1557,52 +1557,31 @@ extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);extern void _drbd_clear_done_ee (struct drbd_device *device,struct list_head *to_be_freed);extern int drbd_connected (struct drbd_peer_device *); -/* Yes, there is kernel_setsockopt, but only since 2.6.18. -* So we have our own copy of it here. */ -static inline int drbd_setsockopt (struct socket *sock,int level,int optname, -char *optval,int optlen) -{ -mm_segment_t oldfs =get_fs (); -char __user *uoptval; -int err; - - uoptval = (char __user __force *)optval; - -set_fs (KERNEL_DS ); -if (level ==SOL_SOCKET ) - err =sock_setsockopt (sock, level, optname, uoptval, optlen); -else - err = sock->ops->setsockopt (sock, level, optname, uoptval, - optlen); -set_fs (oldfs); -return err; -} -static inline void drbd_tcp_cork (struct socket *sock) {int val =1 ; - (void )drbd_setsockopt (sock,SOL_TCP ,TCP_CORK , + (void )kernel_setsockopt (sock,SOL_TCP ,TCP_CORK , (char *)&val,sizeof (val)); }static inline void drbd_tcp_uncork (struct socket *sock) {int val =0 ; - (void )drbd_setsockopt (sock,SOL_TCP ,TCP_CORK , + (void )kernel_setsockopt (sock,SOL_TCP ,TCP_CORK , (char *)&val,sizeof (val)); }static inline void drbd_tcp_nodelay (struct socket *sock) {int val =1 ; - (void )drbd_setsockopt (sock,SOL_TCP ,TCP_NODELAY , + (void )kernel_setsockopt (sock,SOL_TCP ,TCP_NODELAY , (char *)&val,sizeof (val)); }static inline void drbd_tcp_quickack (struct socket *sock) {int val =2 ; - (void )drbd_setsockopt (sock,SOL_TCP ,TCP_QUICKACK , + (void )kernel_setsockopt (sock,SOL_TCP ,TCP_QUICKACK , (char *)&val,sizeof (val)); }
Signature · 1 line
1.9.1
Quoted 9 lines · Philipp Reisner
Hi Jens,
please take these patches for you for-3.19/drivers branch. They where posted for review on 2014-10-29.
Some cleanups and 3 fixes. Two of them marked for stable:
0005-drbd-merge_bvec_fn-properly-remap-bvm-bi_bdev.patch and 0006-drbd-Fix-state-change-in-case-of-connection-timeout.patch (marked for stable)
Applied, thanks.
Signature · 1 line
Jens Axboe