Loading drivers/block/drbd/drbd_main.c +33 −22 Original line number Diff line number Diff line Loading @@ -2661,9 +2661,9 @@ static int init_submitter(struct drbd_device *device) enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr) { struct drbd_connection *connection = first_connection(resource); struct drbd_connection *connection; struct drbd_device *device; struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device, *tmp_peer_device; struct gendisk *disk; struct request_queue *q; int id; Loading @@ -2679,18 +2679,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i return ERR_NOMEM; kref_init(&device->kref); peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); if (!peer_device) goto out_no_peer_device; INIT_LIST_HEAD(&device->peer_devices); list_add(&peer_device->peer_devices, &device->peer_devices); kref_get(&resource->kref); device->resource = resource; kref_get(&connection->kref); peer_device->connection = connection; peer_device->device = device; device->minor = minor; device->vnr = vnr; Loading Loading @@ -2761,6 +2751,17 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i } kref_get(&device->kref); INIT_LIST_HEAD(&device->peer_devices); for_each_connection(connection, resource) { peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); if (!peer_device) goto out_idr_remove_from_resource; peer_device->connection = connection; peer_device->device = device; list_add(&peer_device->peer_devices, &device->peer_devices); kref_get(&device->kref); id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL); if (id < 0) { if (id == -ENOSPC) { Loading @@ -2769,7 +2770,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i } goto out_idr_remove_from_resource; } kref_get(&device->kref); kref_get(&connection->kref); } if (init_submitter(device)) { err = ERR_NOMEM; Loading @@ -2780,7 +2782,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i add_disk(disk); /* inherit the connection state */ device->state.conn = connection->cstate; device->state.conn = first_connection(resource)->cstate; if (device->state.conn == C_WF_REPORT_PARAMS) drbd_connected(device); Loading @@ -2789,6 +2791,17 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i out_idr_remove_vol: idr_remove(&connection->peer_devices, vnr); out_idr_remove_from_resource: for_each_connection(connection, resource) { peer_device = idr_find(&connection->peer_devices, vnr); if (peer_device) { idr_remove(&connection->peer_devices, vnr); kref_put(&connection->kref, drbd_destroy_connection); } } for_each_peer_device_safe(peer_device, tmp_peer_device, device) { list_del(&peer_device->peer_devices); kfree(peer_device); } idr_remove(&resource->devices, vnr); out_idr_remove_minor: idr_remove(&drbd_devices, minor); Loading @@ -2802,9 +2815,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i out_no_disk: blk_cleanup_queue(q); out_no_q: kref_put(&connection->kref, drbd_destroy_connection); kref_put(&resource->kref, drbd_destroy_resource); out_no_peer_device: kfree(device); return err; } Loading drivers/block/drbd/drbd_nl.c +37 −31 Original line number Diff line number Diff line Loading @@ -560,8 +560,16 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) int forced = 0; union drbd_state mask, val; if (new_role == R_PRIMARY) request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */ if (new_role == R_PRIMARY) { struct drbd_connection *connection; /* Detect dead peers as soon as possible. */ rcu_read_lock(); for_each_connection(connection, device->resource) request_ping(connection); rcu_read_unlock(); } mutex_lock(device->state_mutex); Loading Loading @@ -3387,8 +3395,10 @@ int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) { struct drbd_resource *resource; struct drbd_connection *connection; struct drbd_device *device; int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ struct drbd_peer_device *peer_device; unsigned i; retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); Loading @@ -3397,8 +3407,12 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) if (retcode != NO_ERROR) goto out; resource = adm_ctx.resource; /* demote */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { for_each_connection(connection, resource) { struct drbd_peer_device *peer_device; idr_for_each_entry(&connection->peer_devices, peer_device, i) { retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0); if (retcode < SS_SUCCESS) { drbd_msg_put_info("failed to demote"); Loading @@ -3406,15 +3420,16 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } retcode = conn_try_disconnect(adm_ctx.connection, 0); retcode = conn_try_disconnect(connection, 0); if (retcode < SS_SUCCESS) { drbd_msg_put_info("failed to disconnect"); goto out; } } /* detach */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { retcode = adm_detach(peer_device->device, 0); idr_for_each_entry(&resource->devices, device, i) { retcode = adm_detach(device, 0); if (retcode < SS_SUCCESS || retcode > NO_ERROR) { drbd_msg_put_info("failed to detach"); goto out; Loading @@ -3424,13 +3439,14 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) /* If we reach this, all volumes (of this connection) are Secondary, * Disconnected, Diskless, aka Unconfigured. Make sure all threads have * actually stopped, state handling only does drbd_thread_stop_nowait(). */ drbd_thread_stop(&adm_ctx.connection->worker); for_each_connection(connection, resource) drbd_thread_stop(&connection->worker); /* Now, nothing can fail anymore */ /* delete volumes */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { retcode = adm_del_minor(peer_device->device); idr_for_each_entry(&resource->devices, device, i) { retcode = adm_del_minor(device); if (retcode != NO_ERROR) { /* "can not happen" */ drbd_msg_put_info("failed to delete volume"); Loading @@ -3438,21 +3454,11 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } /* delete connection */ if (conn_lowest_minor(adm_ctx.connection) < 0) { struct drbd_resource *resource = adm_ctx.connection->resource; list_del_rcu(&resource->resources); synchronize_rcu(); drbd_free_resource(resource); retcode = NO_ERROR; } else { /* "can not happen" */ retcode = ERR_RES_IN_USE; drbd_msg_put_info("failed to delete connection"); } goto out; out: drbd_adm_finish(info, retcode); return 0; Loading Loading
drivers/block/drbd/drbd_main.c +33 −22 Original line number Diff line number Diff line Loading @@ -2661,9 +2661,9 @@ static int init_submitter(struct drbd_device *device) enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr) { struct drbd_connection *connection = first_connection(resource); struct drbd_connection *connection; struct drbd_device *device; struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device, *tmp_peer_device; struct gendisk *disk; struct request_queue *q; int id; Loading @@ -2679,18 +2679,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i return ERR_NOMEM; kref_init(&device->kref); peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); if (!peer_device) goto out_no_peer_device; INIT_LIST_HEAD(&device->peer_devices); list_add(&peer_device->peer_devices, &device->peer_devices); kref_get(&resource->kref); device->resource = resource; kref_get(&connection->kref); peer_device->connection = connection; peer_device->device = device; device->minor = minor; device->vnr = vnr; Loading Loading @@ -2761,6 +2751,17 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i } kref_get(&device->kref); INIT_LIST_HEAD(&device->peer_devices); for_each_connection(connection, resource) { peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); if (!peer_device) goto out_idr_remove_from_resource; peer_device->connection = connection; peer_device->device = device; list_add(&peer_device->peer_devices, &device->peer_devices); kref_get(&device->kref); id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL); if (id < 0) { if (id == -ENOSPC) { Loading @@ -2769,7 +2770,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i } goto out_idr_remove_from_resource; } kref_get(&device->kref); kref_get(&connection->kref); } if (init_submitter(device)) { err = ERR_NOMEM; Loading @@ -2780,7 +2782,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i add_disk(disk); /* inherit the connection state */ device->state.conn = connection->cstate; device->state.conn = first_connection(resource)->cstate; if (device->state.conn == C_WF_REPORT_PARAMS) drbd_connected(device); Loading @@ -2789,6 +2791,17 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i out_idr_remove_vol: idr_remove(&connection->peer_devices, vnr); out_idr_remove_from_resource: for_each_connection(connection, resource) { peer_device = idr_find(&connection->peer_devices, vnr); if (peer_device) { idr_remove(&connection->peer_devices, vnr); kref_put(&connection->kref, drbd_destroy_connection); } } for_each_peer_device_safe(peer_device, tmp_peer_device, device) { list_del(&peer_device->peer_devices); kfree(peer_device); } idr_remove(&resource->devices, vnr); out_idr_remove_minor: idr_remove(&drbd_devices, minor); Loading @@ -2802,9 +2815,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i out_no_disk: blk_cleanup_queue(q); out_no_q: kref_put(&connection->kref, drbd_destroy_connection); kref_put(&resource->kref, drbd_destroy_resource); out_no_peer_device: kfree(device); return err; } Loading
drivers/block/drbd/drbd_nl.c +37 −31 Original line number Diff line number Diff line Loading @@ -560,8 +560,16 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force) int forced = 0; union drbd_state mask, val; if (new_role == R_PRIMARY) request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */ if (new_role == R_PRIMARY) { struct drbd_connection *connection; /* Detect dead peers as soon as possible. */ rcu_read_lock(); for_each_connection(connection, device->resource) request_ping(connection); rcu_read_unlock(); } mutex_lock(device->state_mutex); Loading Loading @@ -3387,8 +3395,10 @@ int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) { struct drbd_resource *resource; struct drbd_connection *connection; struct drbd_device *device; int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */ struct drbd_peer_device *peer_device; unsigned i; retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); Loading @@ -3397,8 +3407,12 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) if (retcode != NO_ERROR) goto out; resource = adm_ctx.resource; /* demote */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { for_each_connection(connection, resource) { struct drbd_peer_device *peer_device; idr_for_each_entry(&connection->peer_devices, peer_device, i) { retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0); if (retcode < SS_SUCCESS) { drbd_msg_put_info("failed to demote"); Loading @@ -3406,15 +3420,16 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } retcode = conn_try_disconnect(adm_ctx.connection, 0); retcode = conn_try_disconnect(connection, 0); if (retcode < SS_SUCCESS) { drbd_msg_put_info("failed to disconnect"); goto out; } } /* detach */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { retcode = adm_detach(peer_device->device, 0); idr_for_each_entry(&resource->devices, device, i) { retcode = adm_detach(device, 0); if (retcode < SS_SUCCESS || retcode > NO_ERROR) { drbd_msg_put_info("failed to detach"); goto out; Loading @@ -3424,13 +3439,14 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) /* If we reach this, all volumes (of this connection) are Secondary, * Disconnected, Diskless, aka Unconfigured. Make sure all threads have * actually stopped, state handling only does drbd_thread_stop_nowait(). */ drbd_thread_stop(&adm_ctx.connection->worker); for_each_connection(connection, resource) drbd_thread_stop(&connection->worker); /* Now, nothing can fail anymore */ /* delete volumes */ idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) { retcode = adm_del_minor(peer_device->device); idr_for_each_entry(&resource->devices, device, i) { retcode = adm_del_minor(device); if (retcode != NO_ERROR) { /* "can not happen" */ drbd_msg_put_info("failed to delete volume"); Loading @@ -3438,21 +3454,11 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } /* delete connection */ if (conn_lowest_minor(adm_ctx.connection) < 0) { struct drbd_resource *resource = adm_ctx.connection->resource; list_del_rcu(&resource->resources); synchronize_rcu(); drbd_free_resource(resource); retcode = NO_ERROR; } else { /* "can not happen" */ retcode = ERR_RES_IN_USE; drbd_msg_put_info("failed to delete connection"); } goto out; out: drbd_adm_finish(info, retcode); return 0; Loading