Lines Matching +full:nc +full:- +full:si
1 // SPDX-License-Identifier: GPL-2.0-only
7 Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
8 Copyright (C) 1999-2008, Philipp Reisner <[email protected]>.
9 Copyright (C) 2002-2008, Lars Ellenberg <[email protected]>.
100 int err = -EMSGSIZE; in drbd_msg_put_info()
123 int err = -EMSGSIZE; in drbd_msg_sprintf_info()
140 txt->nla_len = nla_attr_size(len+1); in drbd_msg_sprintf_info()
141 nlmsg_trim(skb, (char*)txt + NLA_ALIGN(txt->nla_len)); in drbd_msg_sprintf_info()
148 * and per-family private info->pointers.
163 const u8 cmd = info->genlhdr->cmd; in drbd_adm_prepare()
170 return -EPERM; in drbd_adm_prepare()
172 adm_ctx->reply_skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); in drbd_adm_prepare()
173 if (!adm_ctx->reply_skb) { in drbd_adm_prepare()
174 err = -ENOMEM; in drbd_adm_prepare()
178 adm_ctx->reply_dh = genlmsg_put_reply(adm_ctx->reply_skb, in drbd_adm_prepare()
182 if (!adm_ctx->reply_dh) { in drbd_adm_prepare()
183 err = -ENOMEM; in drbd_adm_prepare()
187 adm_ctx->reply_dh->minor = d_in->minor; in drbd_adm_prepare()
188 adm_ctx->reply_dh->ret_code = NO_ERROR; in drbd_adm_prepare()
190 adm_ctx->volume = VOLUME_UNSPECIFIED; in drbd_adm_prepare()
191 if (info->attrs[DRBD_NLA_CFG_CONTEXT]) { in drbd_adm_prepare()
200 err = nla_put_nohdr(adm_ctx->reply_skb, in drbd_adm_prepare()
201 info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len, in drbd_adm_prepare()
202 info->attrs[DRBD_NLA_CFG_CONTEXT]); in drbd_adm_prepare()
209 adm_ctx->volume = nla_get_u32(nla); in drbd_adm_prepare()
212 adm_ctx->resource_name = nla_data(nla); in drbd_adm_prepare()
213 adm_ctx->my_addr = nested_attr_tb[__nla_type(T_ctx_my_addr)]; in drbd_adm_prepare()
214 adm_ctx->peer_addr = nested_attr_tb[__nla_type(T_ctx_peer_addr)]; in drbd_adm_prepare()
215 if ((adm_ctx->my_addr && in drbd_adm_prepare()
216 nla_len(adm_ctx->my_addr) > sizeof(adm_ctx->connection->my_addr)) || in drbd_adm_prepare()
217 (adm_ctx->peer_addr && in drbd_adm_prepare()
218 nla_len(adm_ctx->peer_addr) > sizeof(adm_ctx->connection->peer_addr))) { in drbd_adm_prepare()
219 err = -EINVAL; in drbd_adm_prepare()
224 adm_ctx->minor = d_in->minor; in drbd_adm_prepare()
225 adm_ctx->device = minor_to_device(d_in->minor); in drbd_adm_prepare()
230 if (adm_ctx->device) in drbd_adm_prepare()
231 kref_get(&adm_ctx->device->kref); in drbd_adm_prepare()
233 if (adm_ctx->resource_name) { in drbd_adm_prepare()
234 adm_ctx->resource = drbd_find_resource(adm_ctx->resource_name); in drbd_adm_prepare()
237 if (!adm_ctx->device && (flags & DRBD_ADM_NEED_MINOR)) { in drbd_adm_prepare()
238 drbd_msg_put_info(adm_ctx->reply_skb, "unknown minor"); in drbd_adm_prepare()
241 if (!adm_ctx->resource && (flags & DRBD_ADM_NEED_RESOURCE)) { in drbd_adm_prepare()
242 drbd_msg_put_info(adm_ctx->reply_skb, "unknown resource"); in drbd_adm_prepare()
243 if (adm_ctx->resource_name) in drbd_adm_prepare()
249 if (adm_ctx->resource) { in drbd_adm_prepare()
250 drbd_msg_put_info(adm_ctx->reply_skb, "no resource name expected"); in drbd_adm_prepare()
253 if (adm_ctx->device) { in drbd_adm_prepare()
254 drbd_msg_put_info(adm_ctx->reply_skb, "no minor number expected"); in drbd_adm_prepare()
257 if (adm_ctx->my_addr && adm_ctx->peer_addr) in drbd_adm_prepare()
258 adm_ctx->connection = conn_get_by_addrs(nla_data(adm_ctx->my_addr), in drbd_adm_prepare()
259 nla_len(adm_ctx->my_addr), in drbd_adm_prepare()
260 nla_data(adm_ctx->peer_addr), in drbd_adm_prepare()
261 nla_len(adm_ctx->peer_addr)); in drbd_adm_prepare()
262 if (!adm_ctx->connection) { in drbd_adm_prepare()
263 drbd_msg_put_info(adm_ctx->reply_skb, "unknown connection"); in drbd_adm_prepare()
268 /* some more paranoia, if the request was over-determined */ in drbd_adm_prepare()
269 if (adm_ctx->device && adm_ctx->resource && in drbd_adm_prepare()
270 adm_ctx->device->resource != adm_ctx->resource) { in drbd_adm_prepare()
272 adm_ctx->minor, adm_ctx->resource->name, in drbd_adm_prepare()
273 adm_ctx->device->resource->name); in drbd_adm_prepare()
274 drbd_msg_put_info(adm_ctx->reply_skb, "minor exists in different resource"); in drbd_adm_prepare()
277 if (adm_ctx->device && in drbd_adm_prepare()
278 adm_ctx->volume != VOLUME_UNSPECIFIED && in drbd_adm_prepare()
279 adm_ctx->volume != adm_ctx->device->vnr) { in drbd_adm_prepare()
281 adm_ctx->minor, adm_ctx->volume, in drbd_adm_prepare()
282 adm_ctx->device->vnr, adm_ctx->device->resource->name); in drbd_adm_prepare()
283 drbd_msg_put_info(adm_ctx->reply_skb, "minor exists as different volume"); in drbd_adm_prepare()
287 /* still, provide adm_ctx->resource always, if possible. */ in drbd_adm_prepare()
288 if (!adm_ctx->resource) { in drbd_adm_prepare()
289 adm_ctx->resource = adm_ctx->device ? adm_ctx->device->resource in drbd_adm_prepare()
290 : adm_ctx->connection ? adm_ctx->connection->resource : NULL; in drbd_adm_prepare()
291 if (adm_ctx->resource) in drbd_adm_prepare()
292 kref_get(&adm_ctx->resource->kref); in drbd_adm_prepare()
298 nlmsg_free(adm_ctx->reply_skb); in drbd_adm_prepare()
299 adm_ctx->reply_skb = NULL; in drbd_adm_prepare()
306 if (adm_ctx->device) { in drbd_adm_finish()
307 kref_put(&adm_ctx->device->kref, drbd_destroy_device); in drbd_adm_finish()
308 adm_ctx->device = NULL; in drbd_adm_finish()
310 if (adm_ctx->connection) { in drbd_adm_finish()
311 kref_put(&adm_ctx->connection->kref, &drbd_destroy_connection); in drbd_adm_finish()
312 adm_ctx->connection = NULL; in drbd_adm_finish()
314 if (adm_ctx->resource) { in drbd_adm_finish()
315 kref_put(&adm_ctx->resource->kref, drbd_destroy_resource); in drbd_adm_finish()
316 adm_ctx->resource = NULL; in drbd_adm_finish()
319 if (!adm_ctx->reply_skb) in drbd_adm_finish()
320 return -ENOMEM; in drbd_adm_finish()
322 adm_ctx->reply_dh->ret_code = retcode; in drbd_adm_finish()
323 drbd_adm_send_reply(adm_ctx->reply_skb, info); in drbd_adm_finish()
332 if (connection->my_addr_len == 0 || connection->peer_addr_len == 0) in setup_khelper_env()
335 switch (((struct sockaddr *)&connection->peer_addr)->sa_family) { in setup_khelper_env()
339 &((struct sockaddr_in6 *)&connection->peer_addr)->sin6_addr); in setup_khelper_env()
344 &((struct sockaddr_in *)&connection->peer_addr)->sin_addr); in setup_khelper_env()
349 &((struct sockaddr_in *)&connection->peer_addr)->sin_addr); in setup_khelper_env()
364 struct drbd_connection *connection = first_peer_device(device)->connection; in drbd_khelper()
368 if (current == connection->worker.task) in drbd_khelper()
369 set_bit(CALLBACK_PENDING, &connection->flags); in drbd_khelper()
371 snprintf(mb, 14, "minor-%d", device_to_minor(device)); in drbd_khelper()
397 if (current == connection->worker.task) in drbd_khelper()
398 clear_bit(CALLBACK_PENDING, &connection->flags); in drbd_khelper()
414 char *resource_name = connection->resource->name; in conn_khelper()
450 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { in highest_fencing_policy()
451 struct drbd_device *device = peer_device->device; in highest_fencing_policy()
454 rcu_dereference(peer_device->device->ldev->disk_conf); in highest_fencing_policy()
455 fp = max_t(enum drbd_fencing_p, fp, disk_conf->fencing); in highest_fencing_policy()
466 return resource->susp || resource->susp_fen || resource->susp_nod; in resource_is_supended()
471 struct drbd_resource * const resource = connection->resource; in conn_try_outdate_peer()
479 spin_lock_irq(&resource->req_lock); in conn_try_outdate_peer()
480 if (connection->cstate >= C_WF_REPORT_PARAMS) { in conn_try_outdate_peer()
482 spin_unlock_irq(&resource->req_lock); in conn_try_outdate_peer()
486 connect_cnt = connection->connect_cnt; in conn_try_outdate_peer()
487 spin_unlock_irq(&resource->req_lock); in conn_try_outdate_peer()
493 spin_lock_irq(&resource->req_lock); in conn_try_outdate_peer()
494 if (connection->cstate < C_WF_REPORT_PARAMS) { in conn_try_outdate_peer()
500 * We may still be suspended due to the on-no-data-accessible policy. in conn_try_outdate_peer()
509 * resolved by either re-establishing the replication link, or in conn_try_outdate_peer()
511 spin_unlock_irq(&resource->req_lock); in conn_try_outdate_peer()
519 r = conn_khelper(connection, "fence-peer"); in conn_try_outdate_peer()
554 drbd_err(connection, "fence-peer() = 7 && fencing != Stonith !!!\n"); in conn_try_outdate_peer()
561 drbd_err(connection, "fence-peer helper broken, returned %d\n", (r>>8)&0xff); in conn_try_outdate_peer()
565 drbd_info(connection, "fence-peer helper returned %d (%s)\n", in conn_try_outdate_peer()
570 here, because we might were able to re-establish the connection in the in conn_try_outdate_peer()
572 spin_lock_irq(&resource->req_lock); in conn_try_outdate_peer()
573 if (connection->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &connection->flags)) { in conn_try_outdate_peer()
574 if (connection->connect_cnt != connect_cnt) in conn_try_outdate_peer()
576 while the fence-peer handler was running, ignore it */ in conn_try_outdate_peer()
577 drbd_info(connection, "Ignoring fence-peer exit code\n"); in conn_try_outdate_peer()
581 spin_unlock_irq(&resource->req_lock); in conn_try_outdate_peer()
592 kref_put(&connection->kref, drbd_destroy_connection); in _try_outdate_peer_async()
600 kref_get(&connection->kref); in conn_try_outdate_peer_async()
609 drbd_err(connection, "out of mem, failed to invoke fence-peer helper\n"); in conn_try_outdate_peer_async()
610 kref_put(&connection->kref, drbd_destroy_connection); in conn_try_outdate_peer_async()
618 struct drbd_connection *const connection = peer_device ? peer_device->connection : NULL; in drbd_set_role()
621 struct net_conf *nc; in drbd_set_role() local
632 for_each_connection(connection, device->resource) in drbd_set_role()
637 mutex_lock(device->state_mutex); in drbd_set_role()
654 (device->state.disk < D_UP_TO_DATE && in drbd_set_role()
655 device->state.disk >= D_INCONSISTENT)) { in drbd_set_role()
663 device->state.disk == D_CONSISTENT && mask.pdsk == 0) { in drbd_set_role()
664 D_ASSERT(device, device->state.pdsk == D_UNKNOWN); in drbd_set_role()
689 try = max_tries - 1; in drbd_set_role()
691 nc = rcu_dereference(connection->net_conf); in drbd_set_role()
692 timeo = nc ? (nc->ping_timeo + 1) * HZ / 10 : 1; in drbd_set_role()
714 wait_event(device->misc_wait, atomic_read(&device->ap_pending_cnt) == 0); in drbd_set_role()
720 device->ldev->md.uuid[UI_CURRENT] &= ~(u64)1; in drbd_set_role()
724 mutex_lock(&device->resource->conf_update); in drbd_set_role()
725 nc = connection->net_conf; in drbd_set_role()
726 if (nc) in drbd_set_role()
727 nc->discard_my_data = 0; /* without copy; single bit op is atomic */ in drbd_set_role()
728 mutex_unlock(&device->resource->conf_update); in drbd_set_role()
731 if (((device->state.conn < C_CONNECTED || in drbd_set_role()
732 device->state.pdsk <= D_FAILED) in drbd_set_role()
733 && device->ldev->md.uuid[UI_BITMAP] == 0) || forced) in drbd_set_role()
736 device->ldev->md.uuid[UI_CURRENT] |= (u64)1; in drbd_set_role()
744 if (device->state.conn >= C_WF_REPORT_PARAMS) { in drbd_set_role()
752 set_disk_ro(device->vdisk, new_role == R_SECONDARY); in drbd_set_role()
753 kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE); in drbd_set_role()
755 mutex_unlock(device->state_mutex); in drbd_set_role()
761 return err == -ENOMSG ? "required attribute missing" : in from_attrs_err_to_txt()
762 err == -EOPNOTSUPP ? "unknown mandatory attribute" : in from_attrs_err_to_txt()
763 err == -EEXIST ? "can not change invariant setting" : in from_attrs_err_to_txt()
782 if (info->attrs[DRBD_NLA_SET_ROLE_PARMS]) { in drbd_adm_set_role()
791 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_set_role()
793 if (info->genlhdr->cmd == DRBD_ADM_PRIMARY) in drbd_adm_set_role()
798 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_set_role()
812 * |----------- md_size_sect ------------------|
816 * ==> bitmap sectors = md_size_sect - bm_offset
819 * |----------- md_size_sect ------------------|
822 * | bm_offset = al_offset - Y |
823 * ==> bitmap sectors = Y = al_offset - bm_offset
832 unsigned int al_size_sect = bdev->md.al_size_4k * 8; in drbd_md_set_sector_offsets()
834 bdev->md.md_offset = drbd_md_ss(bdev); in drbd_md_set_sector_offsets()
836 switch (bdev->md.meta_dev_idx) { in drbd_md_set_sector_offsets()
839 bdev->md.md_size_sect = MD_128MB_SECT; in drbd_md_set_sector_offsets()
840 bdev->md.al_offset = MD_4kB_SECT; in drbd_md_set_sector_offsets()
841 bdev->md.bm_offset = MD_4kB_SECT + al_size_sect; in drbd_md_set_sector_offsets()
845 bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev); in drbd_md_set_sector_offsets()
846 bdev->md.al_offset = MD_4kB_SECT; in drbd_md_set_sector_offsets()
847 bdev->md.bm_offset = MD_4kB_SECT + al_size_sect; in drbd_md_set_sector_offsets()
852 bdev->md.al_offset = -al_size_sect; in drbd_md_set_sector_offsets()
854 md_size_sect = drbd_get_capacity(bdev->backing_bdev); in drbd_md_set_sector_offsets()
863 bdev->md.md_size_sect = md_size_sect; in drbd_md_set_sector_offsets()
865 bdev->md.bm_offset = -md_size_sect + MD_4kB_SECT; in drbd_md_set_sector_offsets()
874 * -1ULL ==> "16384 EB" */ in ppsize()
877 while (size >= 10000 && base < sizeof(units)-1) { in ppsize()
892 * waits for ap_bio_cnt == 0. -> deadlock.
904 * This changes an device->flag, is triggered by drbd internals,
905 * and should be short-lived. */
910 atomic_inc(&device->suspend_cnt); in drbd_suspend_io()
913 wait_event(device->misc_wait, !atomic_read(&device->ap_bio_cnt)); in drbd_suspend_io()
918 if (atomic_dec_and_test(&device->suspend_cnt)) in drbd_resume_io()
919 wake_up(&device->misc_wait); in drbd_resume_io()
923 * drbd_determine_dev_size() - Sets the right device size obeying all constraints
943 struct drbd_md *md = &device->ldev->md; in drbd_determine_dev_size()
949 /* We may change the on-disk offsets of our meta data below. Lock out in drbd_determine_dev_size()
958 buffer = drbd_md_get_buffer(device, __func__); /* Lock meta-data IO */ in drbd_determine_dev_size()
965 prev.last_agreed_sect = md->la_size_sect; in drbd_determine_dev_size()
966 prev.md_offset = md->md_offset; in drbd_determine_dev_size()
967 prev.al_offset = md->al_offset; in drbd_determine_dev_size()
968 prev.bm_offset = md->bm_offset; in drbd_determine_dev_size()
969 prev.md_size_sect = md->md_size_sect; in drbd_determine_dev_size()
970 prev.al_stripes = md->al_stripes; in drbd_determine_dev_size()
971 prev.al_stripe_size_4k = md->al_stripe_size_4k; in drbd_determine_dev_size()
975 md->al_stripes = rs->al_stripes; in drbd_determine_dev_size()
976 md->al_stripe_size_4k = rs->al_stripe_size / 4; in drbd_determine_dev_size()
977 md->al_size_4k = (u64)rs->al_stripes * rs->al_stripe_size / 4; in drbd_determine_dev_size()
980 drbd_md_set_sector_offsets(device, device->ldev); in drbd_determine_dev_size()
983 u_size = rcu_dereference(device->ldev->disk_conf)->disk_size; in drbd_determine_dev_size()
985 size = drbd_new_dev_size(device, device->ldev, u_size, flags & DDSF_FORCED); in drbd_determine_dev_size()
992 "Use --size=%llus for explicit shrink.\n", in drbd_determine_dev_size()
1002 if (get_capacity(device->vdisk) != size || in drbd_determine_dev_size()
1020 md->la_size_sect = size; in drbd_determine_dev_size()
1025 la_size_changed = (prev.last_agreed_sect != md->la_size_sect); in drbd_determine_dev_size()
1027 md_moved = prev.md_offset != md->md_offset in drbd_determine_dev_size()
1028 || prev.md_size_sect != md->md_size_sect; in drbd_determine_dev_size()
1036 del_timer(&device->md_sync_timer); in drbd_determine_dev_size()
1038 /* We won't change the "al-extents" setting, we just may need in drbd_determine_dev_size()
1039 * to move the on-disk location of the activity log ringbuffer. in drbd_determine_dev_size()
1042 wait_event(device->al_wait, lc_try_lock_for_transaction(device->act_log)); in drbd_determine_dev_size()
1044 /* mark current on-disk bitmap and activity log as unreliable */ in drbd_determine_dev_size()
1045 prev_flags = md->flags; in drbd_determine_dev_size()
1046 md->flags |= MDF_FULL_SYNC | MDF_AL_DISABLED; in drbd_determine_dev_size()
1058 /* on-disk bitmap and activity log is authoritative again in drbd_determine_dev_size()
1060 md->flags = prev_flags; in drbd_determine_dev_size()
1064 drbd_info(device, "Changed AL layout to al-stripes = %d, al-stripe-size-kB = %d\n", in drbd_determine_dev_size()
1065 md->al_stripes, md->al_stripe_size_4k * 4); in drbd_determine_dev_size()
1076 md->la_size_sect = prev.last_agreed_sect; in drbd_determine_dev_size()
1077 md->md_offset = prev.md_offset; in drbd_determine_dev_size()
1078 md->al_offset = prev.al_offset; in drbd_determine_dev_size()
1079 md->bm_offset = prev.bm_offset; in drbd_determine_dev_size()
1080 md->md_size_sect = prev.md_size_sect; in drbd_determine_dev_size()
1081 md->al_stripes = prev.al_stripes; in drbd_determine_dev_size()
1082 md->al_stripe_size_4k = prev.al_stripe_size_4k; in drbd_determine_dev_size()
1083 md->al_size_4k = (u64)prev.al_stripes * prev.al_stripe_size_4k; in drbd_determine_dev_size()
1085 lc_unlock(device->act_log); in drbd_determine_dev_size()
1086 wake_up(&device->al_wait); in drbd_determine_dev_size()
1097 sector_t p_size = device->p_size; /* partner's disk size. */ in drbd_new_dev_size()
1098 sector_t la_size_sect = bdev->md.la_size_sect; /* last agreed size. */ in drbd_new_dev_size()
1104 if (device->state.conn < C_CONNECTED && assume_peer_has_space) { in drbd_new_dev_size()
1141 * drbd_check_al_size() - Ensures that the AL is of the right size
1144 * Returns -EBUSY if current al lru is still used, -ENOMEM when allocation
1155 if (device->act_log && in drbd_check_al_size()
1156 device->act_log->nr_elements == dc->al_extents) in drbd_check_al_size()
1160 t = device->act_log; in drbd_check_al_size()
1162 dc->al_extents, sizeof(struct lc_element), 0); in drbd_check_al_size()
1166 return -ENOMEM; in drbd_check_al_size()
1168 spin_lock_irq(&device->al_lock); in drbd_check_al_size()
1170 for (i = 0; i < t->nr_elements; i++) { in drbd_check_al_size()
1172 if (e->refcnt) in drbd_check_al_size()
1174 e->lc_number, e->refcnt); in drbd_check_al_size()
1175 in_use += e->refcnt; in drbd_check_al_size()
1179 device->act_log = n; in drbd_check_al_size()
1180 spin_unlock_irq(&device->al_lock); in drbd_check_al_size()
1184 return -EBUSY; in drbd_check_al_size()
1188 drbd_md_mark_dirty(device); /* we changed device->act_log->nr_elemens */ in drbd_check_al_size()
1198 if (device->state.conn < C_WF_REPORT_PARAMS) in drbd_max_peer_bio_size()
1199 return device->peer_max_bio_size; in drbd_max_peer_bio_size()
1201 if (first_peer_device(device)->connection->agreed_pro_version < 94) in drbd_max_peer_bio_size()
1202 return min(device->peer_max_bio_size, DRBD_MAX_SIZE_H80_PACKET); in drbd_max_peer_bio_size()
1208 if (first_peer_device(device)->connection->agreed_pro_version == 94) in drbd_max_peer_bio_size()
1214 if (first_peer_device(device)->connection->agreed_pro_version < 100) in drbd_max_peer_bio_size()
1223 if (connection->agreed_features & DRBD_FF_WSAME) in drbd_max_discard_sectors()
1232 if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev)) in drbd_discard_supported()
1235 if (connection->cstate >= C_CONNECTED && in drbd_discard_supported()
1236 !(connection->agreed_features & DRBD_FF_TRIM)) { in drbd_discard_supported()
1251 max_segments = rcu_dereference(device->ldev->disk_conf)->max_bio_bvecs; in drbd_backing_dev_max_segments()
1263 first_peer_device(device)->connection; in drbd_reconsider_queue_parameters()
1264 struct request_queue * const q = device->rq_queue; in drbd_reconsider_queue_parameters()
1271 b = bdev->backing_bdev->bd_disk->queue; in drbd_reconsider_queue_parameters()
1273 device->local_max_bio_size = in drbd_reconsider_queue_parameters()
1278 * We may later detach and re-attach on a disconnected Primary. Avoid in drbd_reconsider_queue_parameters()
1284 new = min3(DRBD_MAX_BIO_SIZE, device->local_max_bio_size, in drbd_reconsider_queue_parameters()
1285 max(drbd_max_peer_bio_size(device), device->peer_max_bio_size)); in drbd_reconsider_queue_parameters()
1287 if (device->state.role == R_PRIMARY && new < now) in drbd_reconsider_queue_parameters()
1302 lim.seg_boundary_mask = PAGE_SIZE - 1; in drbd_reconsider_queue_parameters()
1322 blk_stack_limits(&lim, &b->limits, 0); in drbd_reconsider_queue_parameters()
1329 if (connection->agreed_features & DRBD_FF_WZEROES) in drbd_reconsider_queue_parameters()
1347 drbd_thread_start(&connection->worker); in conn_reconfig_start()
1348 drbd_flush_workqueue(&connection->sender_work); in conn_reconfig_start()
1355 spin_lock_irq(&connection->resource->req_lock); in conn_reconfig_done()
1357 connection->cstate == C_STANDALONE; in conn_reconfig_done()
1358 spin_unlock_irq(&connection->resource->req_lock); in conn_reconfig_done()
1362 drbd_thread_stop(&connection->receiver); in conn_reconfig_done()
1363 drbd_thread_stop(&connection->worker); in conn_reconfig_done()
1372 if (!lc_try_lock(device->act_log)) { in drbd_suspend_al()
1378 spin_lock_irq(&device->resource->req_lock); in drbd_suspend_al()
1379 if (device->state.conn < C_CONNECTED) in drbd_suspend_al()
1380 s = !test_and_set_bit(AL_SUSPENDED, &device->flags); in drbd_suspend_al()
1381 spin_unlock_irq(&device->resource->req_lock); in drbd_suspend_al()
1382 lc_unlock(device->act_log); in drbd_suspend_al()
1393 return 0 != (dh->flags & DRBD_GENL_F_SET_DEFAULTS); in should_set_defaults()
1399 * and by available on-disk context storage. in drbd_al_extents_max()
1403 * One transaction occupies one 4kB on-disk block, in drbd_al_extents_max()
1405 * the "current" transaction may fail (n-1), in drbd_al_extents_max()
1413 (max_al_nr + AL_CONTEXT_PER_TRANSACTION -1) in drbd_al_extents_max()
1416 unsigned int al_size_4k = bdev->md.al_size_4k; in drbd_al_extents_max()
1421 return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION; in drbd_al_extents_max()
1426 return a->disk_barrier != b->disk_barrier || in write_ordering_changed()
1427 a->disk_flushes != b->disk_flushes || in write_ordering_changed()
1428 a->disk_drain != b->disk_drain; in write_ordering_changed()
1434 struct block_device *bdev = nbc->backing_bdev; in sanitize_disk_conf()
1436 if (disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) in sanitize_disk_conf()
1437 disk_conf->al_extents = DRBD_AL_EXTENTS_MIN; in sanitize_disk_conf()
1438 if (disk_conf->al_extents > drbd_al_extents_max(nbc)) in sanitize_disk_conf()
1439 disk_conf->al_extents = drbd_al_extents_max(nbc); in sanitize_disk_conf()
1442 if (disk_conf->rs_discard_granularity) { in sanitize_disk_conf()
1443 disk_conf->rs_discard_granularity = 0; /* disable feature */ in sanitize_disk_conf()
1448 if (disk_conf->rs_discard_granularity) { in sanitize_disk_conf()
1449 int orig_value = disk_conf->rs_discard_granularity; in sanitize_disk_conf()
1454 if (discard_granularity > disk_conf->rs_discard_granularity) in sanitize_disk_conf()
1455 disk_conf->rs_discard_granularity = discard_granularity; in sanitize_disk_conf()
1457 remainder = disk_conf->rs_discard_granularity % in sanitize_disk_conf()
1459 disk_conf->rs_discard_granularity += remainder; in sanitize_disk_conf()
1461 if (disk_conf->rs_discard_granularity > discard_size) in sanitize_disk_conf()
1462 disk_conf->rs_discard_granularity = discard_size; in sanitize_disk_conf()
1464 if (disk_conf->rs_discard_granularity != orig_value) in sanitize_disk_conf()
1466 disk_conf->rs_discard_granularity); in sanitize_disk_conf()
1472 int err = -EBUSY; in disk_opts_check_al_size()
1474 if (device->act_log && in disk_opts_check_al_size()
1475 device->act_log->nr_elements == dc->al_extents) in disk_opts_check_al_size()
1481 if (atomic_read(&device->ap_bio_cnt)) in disk_opts_check_al_size()
1484 wait_event(device->al_wait, lc_try_lock(device->act_log)); in disk_opts_check_al_size()
1487 lc_unlock(device->act_log); in disk_opts_check_al_size()
1488 wake_up(&device->al_wait); in disk_opts_check_al_size()
1511 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_disk_opts()
1526 mutex_lock(&device->resource->conf_update); in drbd_adm_disk_opts()
1527 old_disk_conf = device->ldev->disk_conf; in drbd_adm_disk_opts()
1533 if (err && err != -ENOMSG) { in drbd_adm_disk_opts()
1539 if (!expect(device, new_disk_conf->resync_rate >= 1)) in drbd_adm_disk_opts()
1540 new_disk_conf->resync_rate = 1; in drbd_adm_disk_opts()
1542 sanitize_disk_conf(device, new_disk_conf, device->ldev); in drbd_adm_disk_opts()
1544 if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) in drbd_adm_disk_opts()
1545 new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; in drbd_adm_disk_opts()
1547 fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ; in drbd_adm_disk_opts()
1548 if (fifo_size != device->rs_plan_s->size) { in drbd_adm_disk_opts()
1562 "Try again without changing current al-extents setting"); in drbd_adm_disk_opts()
1568 retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after); in drbd_adm_disk_opts()
1570 rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf); in drbd_adm_disk_opts()
1579 old_plan = device->rs_plan_s; in drbd_adm_disk_opts()
1580 rcu_assign_pointer(device->rs_plan_s, new_plan); in drbd_adm_disk_opts()
1583 mutex_unlock(&device->resource->conf_update); in drbd_adm_disk_opts()
1585 if (new_disk_conf->al_updates) in drbd_adm_disk_opts()
1586 device->ldev->md.flags &= ~MDF_AL_DISABLED; in drbd_adm_disk_opts()
1588 device->ldev->md.flags |= MDF_AL_DISABLED; in drbd_adm_disk_opts()
1590 if (new_disk_conf->md_flushes) in drbd_adm_disk_opts()
1591 clear_bit(MD_NO_FUA, &device->flags); in drbd_adm_disk_opts()
1593 set_bit(MD_NO_FUA, &device->flags); in drbd_adm_disk_opts()
1596 drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); in drbd_adm_disk_opts()
1598 if (old_disk_conf->discard_zeroes_if_aligned != in drbd_adm_disk_opts()
1599 new_disk_conf->discard_zeroes_if_aligned) in drbd_adm_disk_opts()
1600 drbd_reconsider_queue_parameters(device, device->ldev, NULL); in drbd_adm_disk_opts()
1604 if (device->state.conn >= C_CONNECTED) { in drbd_adm_disk_opts()
1613 mod_timer(&device->request_timer, jiffies + HZ); in drbd_adm_disk_opts()
1617 mutex_unlock(&device->resource->conf_update); in drbd_adm_disk_opts()
1624 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_disk_opts()
1647 err = bd_link_disk_holder(file_bdev(file), device->vdisk); in open_backing_dev()
1663 file = open_backing_dev(device, new_disk_conf->backing_dev, device, in open_backing_devices()
1667 nbc->backing_bdev = file_bdev(file); in open_backing_devices()
1668 nbc->backing_bdev_file = file; in open_backing_devices()
1678 file = open_backing_dev(device, new_disk_conf->meta_dev, in open_backing_devices()
1681 (new_disk_conf->meta_dev_idx < 0) ? (void*)device : (void*)drbd_m_holder, in open_backing_devices()
1684 (new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_FLEX_INT && in open_backing_devices()
1685 new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_INTERNAL)); in open_backing_devices()
1688 nbc->md_bdev = file_bdev(file); in open_backing_devices()
1689 nbc->f_md_bdev = file; in open_backing_devices()
1699 bd_unlink_disk_holder(file_bdev(bdev_file), device->vdisk); in close_backing_dev()
1708 close_backing_dev(device, ldev->f_md_bdev, in drbd_backing_dev_free()
1709 ldev->md_bdev != ldev->backing_bdev); in drbd_backing_dev_free()
1710 close_backing_dev(device, ldev->backing_bdev_file, true); in drbd_backing_dev_free()
1712 kfree(ldev->disk_conf); in drbd_backing_dev_free()
1733 struct net_conf *nc; in drbd_adm_attach() local
1742 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_attach()
1744 connection = peer_device->connection; in drbd_adm_attach()
1748 if (device->state.disk > D_DISKLESS) { in drbd_adm_attach()
1754 * e.g. if someone calls attach from the on-io-error handler, in drbd_adm_attach()
1756 wait_event(device->misc_wait, !test_bit(GOING_DISKLESS, &device->flags)); in drbd_adm_attach()
1758 /* make sure there is no leftover from previous force-detach attempts */ in drbd_adm_attach()
1759 clear_bit(FORCE_DETACH, &device->flags); in drbd_adm_attach()
1760 clear_bit(WAS_IO_ERROR, &device->flags); in drbd_adm_attach()
1761 clear_bit(WAS_READ_ERROR, &device->flags); in drbd_adm_attach()
1764 device->rs_total = 0; in drbd_adm_attach()
1765 device->rs_failed = 0; in drbd_adm_attach()
1766 atomic_set(&device->rs_pending_cnt, 0); in drbd_adm_attach()
1774 spin_lock_init(&nbc->md.uuid_lock); in drbd_adm_attach()
1781 nbc->disk_conf = new_disk_conf; in drbd_adm_attach()
1791 if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) in drbd_adm_attach()
1792 new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; in drbd_adm_attach()
1794 new_plan = fifo_alloc((new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ); in drbd_adm_attach()
1800 if (new_disk_conf->meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) { in drbd_adm_attach()
1806 nc = rcu_dereference(connection->net_conf); in drbd_adm_attach()
1807 if (nc) { in drbd_adm_attach()
1808 if (new_disk_conf->fencing == FP_STONITH && nc->wire_protocol == DRBD_PROT_A) { in drbd_adm_attach()
1820 if ((nbc->backing_bdev == nbc->md_bdev) != in drbd_adm_attach()
1821 (new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_INTERNAL || in drbd_adm_attach()
1822 new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { in drbd_adm_attach()
1836 * This also sets other on-disk offsets. */ in drbd_adm_attach()
1843 if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) { in drbd_adm_attach()
1846 (unsigned long long) new_disk_conf->disk_size); in drbd_adm_attach()
1851 if (new_disk_conf->meta_dev_idx < 0) { in drbd_adm_attach()
1857 min_md_device_sectors = MD_128MB_SECT * (new_disk_conf->meta_dev_idx + 1); in drbd_adm_attach()
1860 if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) { in drbd_adm_attach()
1862 drbd_warn(device, "refusing attach: md-device too small, " in drbd_adm_attach()
1863 "at least %llu sectors needed for this meta-disk type\n", in drbd_adm_attach()
1870 if (drbd_get_max_capacity(nbc) < get_capacity(device->vdisk)) { in drbd_adm_attach()
1875 nbc->known_size = drbd_get_capacity(nbc->backing_bdev); in drbd_adm_attach()
1877 if (nbc->known_size > max_possible_sectors) { in drbd_adm_attach()
1881 if (new_disk_conf->meta_dev_idx >= 0) in drbd_adm_attach()
1888 /* FIXME see also https://daiquiri.linbit/cgi-bin/bugzilla/show_bug.cgi?id=171 in drbd_adm_attach()
1894 wait_event(device->misc_wait, !atomic_read(&device->ap_pending_cnt) || drbd_suspended(device)); in drbd_adm_attach()
1896 drbd_flush_workqueue(&connection->sender_work); in drbd_adm_attach()
1907 if (!device->bitmap) { in drbd_adm_attach()
1914 if (device->state.pdsk != D_UP_TO_DATE && device->ed_uuid && in drbd_adm_attach()
1915 (device->state.role == R_PRIMARY || device->state.peer == R_PRIMARY) && in drbd_adm_attach()
1916 (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) { in drbd_adm_attach()
1918 (unsigned long long)device->ed_uuid); in drbd_adm_attach()
1931 unsigned long long nsz = drbd_new_dev_size(device, nbc, nbc->disk_conf->disk_size, 0); in drbd_adm_attach()
1932 unsigned long long eff = nbc->md.la_size_sect; in drbd_adm_attach()
1934 if (nsz == nbc->disk_conf->disk_size) { in drbd_adm_attach()
1939 "To-be-attached device has last effective > current size, and is consistent\n" in drbd_adm_attach()
1948 retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after); in drbd_adm_attach()
1956 if (new_disk_conf->md_flushes) in drbd_adm_attach()
1957 clear_bit(MD_NO_FUA, &device->flags); in drbd_adm_attach()
1959 set_bit(MD_NO_FUA, &device->flags); in drbd_adm_attach()
1965 D_ASSERT(device, device->ldev == NULL); in drbd_adm_attach()
1966 device->ldev = nbc; in drbd_adm_attach()
1967 device->resync = resync_lru; in drbd_adm_attach()
1968 device->rs_plan_s = new_plan; in drbd_adm_attach()
1975 drbd_bump_write_ordering(device->resource, device->ldev, WO_BDEV_FLUSH); in drbd_adm_attach()
1978 if (drbd_md_test_flag(device->ldev, MDF_CRASHED_PRIMARY)) in drbd_adm_attach()
1979 set_bit(CRASHED_PRIMARY, &device->flags); in drbd_adm_attach()
1981 clear_bit(CRASHED_PRIMARY, &device->flags); in drbd_adm_attach()
1983 if (drbd_md_test_flag(device->ldev, MDF_PRIMARY_IND) && in drbd_adm_attach()
1984 !(device->state.role == R_PRIMARY && device->resource->susp_nod)) in drbd_adm_attach()
1985 set_bit(CRASHED_PRIMARY, &device->flags); in drbd_adm_attach()
1987 device->send_cnt = 0; in drbd_adm_attach()
1988 device->recv_cnt = 0; in drbd_adm_attach()
1989 device->read_cnt = 0; in drbd_adm_attach()
1990 device->writ_cnt = 0; in drbd_adm_attach()
1992 drbd_reconsider_queue_parameters(device, device->ldev, NULL); in drbd_adm_attach()
2004 * we use the degr-wfc-timeout instead of the default, in drbd_adm_attach()
2008 clear_bit(USE_DEGR_WFC_T, &device->flags); in drbd_adm_attach()
2009 if (device->state.role != R_PRIMARY && in drbd_adm_attach()
2010 drbd_md_test_flag(device->ldev, MDF_PRIMARY_IND) && in drbd_adm_attach()
2011 !drbd_md_test_flag(device->ldev, MDF_CONNECTED_IND)) in drbd_adm_attach()
2012 set_bit(USE_DEGR_WFC_T, &device->flags); in drbd_adm_attach()
2019 set_bit(RESYNC_AFTER_NEG, &device->flags); in drbd_adm_attach()
2021 if (drbd_md_test_flag(device->ldev, MDF_FULL_SYNC) || in drbd_adm_attach()
2022 (test_bit(CRASHED_PRIMARY, &device->flags) && in drbd_adm_attach()
2023 drbd_md_test_flag(device->ldev, MDF_AL_DISABLED))) { in drbd_adm_attach()
2044 spin_lock_irq(&device->resource->req_lock); in drbd_adm_attach()
2052 if (drbd_md_test_flag(device->ldev, MDF_CONSISTENT)) { in drbd_adm_attach()
2053 if (drbd_md_test_flag(device->ldev, MDF_WAS_UP_TO_DATE)) in drbd_adm_attach()
2061 if (drbd_md_test_flag(device->ldev, MDF_PEER_OUT_DATED)) in drbd_adm_attach()
2066 (ns.pdsk == D_OUTDATED || rcu_dereference(device->ldev->disk_conf)->fencing == FP_DONT_CARE)) in drbd_adm_attach()
2074 if (rcu_dereference(device->ldev->disk_conf)->al_updates) in drbd_adm_attach()
2075 device->ldev->md.flags &= ~MDF_AL_DISABLED; in drbd_adm_attach()
2077 device->ldev->md.flags |= MDF_AL_DISABLED; in drbd_adm_attach()
2083 if (device->state.conn == C_CONNECTED) { in drbd_adm_attach()
2084 device->new_state_tmp.i = ns.i; in drbd_adm_attach()
2088 /* We expect to receive up-to-date UUIDs soon. in drbd_adm_attach()
2091 kfree(device->p_uuid); in drbd_adm_attach()
2092 device->p_uuid = NULL; in drbd_adm_attach()
2096 spin_unlock_irq(&device->resource->req_lock); in drbd_adm_attach()
2101 mod_timer(&device->request_timer, jiffies + HZ); in drbd_adm_attach()
2103 if (device->state.role == R_PRIMARY) in drbd_adm_attach()
2104 device->ldev->md.uuid[UI_CURRENT] |= (u64)1; in drbd_adm_attach()
2106 device->ldev->md.uuid[UI_CURRENT] &= ~(u64)1; in drbd_adm_attach()
2111 kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE); in drbd_adm_attach()
2114 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_attach()
2126 close_backing_dev(device, nbc->f_md_bdev, in drbd_adm_attach()
2127 nbc->md_bdev != nbc->backing_bdev); in drbd_adm_attach()
2128 close_backing_dev(device, nbc->backing_bdev_file, true); in drbd_adm_attach()
2134 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_attach()
2143 set_bit(FORCE_DETACH, &device->flags); in adm_detach()
2152 * out application IO, in-flight IO, IO stuck in drbd_al_begin_io.
2169 if (info->attrs[DRBD_NLA_DETACH_PARMS]) { in drbd_adm_detach()
2178 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_detach()
2180 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_detach()
2193 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { in conn_resync_running()
2194 struct drbd_device *device = peer_device->device; in conn_resync_running()
2195 if (device->state.conn == C_SYNC_SOURCE || in conn_resync_running()
2196 device->state.conn == C_SYNC_TARGET || in conn_resync_running()
2197 device->state.conn == C_PAUSED_SYNC_S || in conn_resync_running()
2198 device->state.conn == C_PAUSED_SYNC_T) { in conn_resync_running()
2215 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { in conn_ov_running()
2216 struct drbd_device *device = peer_device->device; in conn_ov_running()
2217 if (device->state.conn == C_VERIFY_S || in conn_ov_running()
2218 device->state.conn == C_VERIFY_T) { in conn_ov_running()
2234 …if (old_net_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 1… in _check_net_options()
2235 if (new_net_conf->wire_protocol != old_net_conf->wire_protocol) in _check_net_options()
2238 if (new_net_conf->two_primaries != old_net_conf->two_primaries) in _check_net_options()
2241 if (strcmp(new_net_conf->integrity_alg, old_net_conf->integrity_alg)) in _check_net_options()
2245 if (!new_net_conf->two_primaries && in _check_net_options()
2250 if (new_net_conf->two_primaries && in _check_net_options()
2251 (new_net_conf->wire_protocol != DRBD_PROT_C)) in _check_net_options()
2254 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in _check_net_options()
2255 struct drbd_device *device = peer_device->device; in _check_net_options()
2257 enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing; in _check_net_options()
2259 if (new_net_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH) in _check_net_options()
2262 if (device->state.role == R_PRIMARY && new_net_conf->discard_my_data) in _check_net_options()
2266 if (new_net_conf->on_congestion != OC_BLOCK && new_net_conf->wire_protocol != DRBD_PROT_A) in _check_net_options()
2280 rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_net_conf); in check_net_options()
2283 /* connection->peer_devices protected by genl_lock() here */ in check_net_options()
2284 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in check_net_options()
2285 struct drbd_device *device = peer_device->device; in check_net_options()
2286 if (!device->bitmap) { in check_net_options()
2323 rv = alloc_shash(&crypto->csums_tfm, new_net_conf->csums_alg, in alloc_crypto()
2327 rv = alloc_shash(&crypto->verify_tfm, new_net_conf->verify_alg, in alloc_crypto()
2331 rv = alloc_shash(&crypto->integrity_tfm, new_net_conf->integrity_alg, in alloc_crypto()
2335 if (new_net_conf->cram_hmac_alg[0] != 0) { in alloc_crypto()
2337 new_net_conf->cram_hmac_alg); in alloc_crypto()
2339 rv = alloc_shash(&crypto->cram_hmac_tfm, hmac_name, in alloc_crypto()
2348 crypto_free_shash(crypto->cram_hmac_tfm); in free_crypto()
2349 crypto_free_shash(crypto->integrity_tfm); in free_crypto()
2350 crypto_free_shash(crypto->csums_tfm); in free_crypto()
2351 crypto_free_shash(crypto->verify_tfm); in free_crypto()
2362 int rsr; /* re-sync running */ in drbd_adm_net_opts()
2372 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_net_opts()
2382 mutex_lock(&connection->data.mutex); in drbd_adm_net_opts()
2383 mutex_lock(&connection->resource->conf_update); in drbd_adm_net_opts()
2384 old_net_conf = connection->net_conf; in drbd_adm_net_opts()
2397 if (err && err != -ENOMSG) { in drbd_adm_net_opts()
2407 /* re-sync running */ in drbd_adm_net_opts()
2409 if (rsr && strcmp(new_net_conf->csums_alg, old_net_conf->csums_alg)) { in drbd_adm_net_opts()
2416 if (ovr && strcmp(new_net_conf->verify_alg, old_net_conf->verify_alg)) { in drbd_adm_net_opts()
2425 rcu_assign_pointer(connection->net_conf, new_net_conf); in drbd_adm_net_opts()
2428 crypto_free_shash(connection->csums_tfm); in drbd_adm_net_opts()
2429 connection->csums_tfm = crypto.csums_tfm; in drbd_adm_net_opts()
2433 crypto_free_shash(connection->verify_tfm); in drbd_adm_net_opts()
2434 connection->verify_tfm = crypto.verify_tfm; in drbd_adm_net_opts()
2438 crypto_free_shash(connection->integrity_tfm); in drbd_adm_net_opts()
2439 connection->integrity_tfm = crypto.integrity_tfm; in drbd_adm_net_opts()
2440 if (connection->cstate >= C_WF_REPORT_PARAMS && connection->agreed_pro_version >= 100) in drbd_adm_net_opts()
2441 /* Do this without trying to take connection->data.mutex again. */ in drbd_adm_net_opts()
2444 crypto_free_shash(connection->cram_hmac_tfm); in drbd_adm_net_opts()
2445 connection->cram_hmac_tfm = crypto.cram_hmac_tfm; in drbd_adm_net_opts()
2447 mutex_unlock(&connection->resource->conf_update); in drbd_adm_net_opts()
2448 mutex_unlock(&connection->data.mutex); in drbd_adm_net_opts()
2451 if (connection->cstate >= C_WF_REPORT_PARAMS) { in drbd_adm_net_opts()
2455 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) in drbd_adm_net_opts()
2462 mutex_unlock(&connection->resource->conf_update); in drbd_adm_net_opts()
2463 mutex_unlock(&connection->data.mutex); in drbd_adm_net_opts()
2469 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_net_opts()
2478 info->conn_connection_state = connection->cstate; in connection_to_info()
2479 info->conn_role = conn_highest_peer(connection); in connection_to_info()
2485 struct drbd_device *device = peer_device->device; in peer_device_to_info()
2487 info->peer_repl_state = in peer_device_to_info()
2488 max_t(enum drbd_conns, C_WF_REPORT_PARAMS, device->state.conn); in peer_device_to_info()
2489 info->peer_disk_state = device->state.pdsk; in peer_device_to_info()
2490 info->peer_resync_susp_user = device->state.user_isp; in peer_device_to_info()
2491 info->peer_resync_susp_peer = device->state.peer_isp; in peer_device_to_info()
2492 info->peer_resync_susp_dependency = device->state.aftr_isp; in peer_device_to_info()
2528 if (nla_len(adm_ctx.my_addr) == connection->my_addr_len && in drbd_adm_connect()
2529 !memcmp(nla_data(adm_ctx.my_addr), &connection->my_addr, in drbd_adm_connect()
2530 connection->my_addr_len)) { in drbd_adm_connect()
2535 if (nla_len(adm_ctx.peer_addr) == connection->peer_addr_len && in drbd_adm_connect()
2536 !memcmp(nla_data(adm_ctx.peer_addr), &connection->peer_addr, in drbd_adm_connect()
2537 connection->peer_addr_len)) { in drbd_adm_connect()
2544 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_connect()
2548 if (connection->cstate > C_STANDALONE) { in drbd_adm_connect()
2563 if (err && err != -ENOMSG) { in drbd_adm_connect()
2577 ((char *)new_net_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; in drbd_adm_connect()
2579 drbd_flush_workqueue(&connection->sender_work); in drbd_adm_connect()
2581 mutex_lock(&adm_ctx.resource->conf_update); in drbd_adm_connect()
2582 old_net_conf = connection->net_conf; in drbd_adm_connect()
2585 mutex_unlock(&adm_ctx.resource->conf_update); in drbd_adm_connect()
2588 rcu_assign_pointer(connection->net_conf, new_net_conf); in drbd_adm_connect()
2591 connection->cram_hmac_tfm = crypto.cram_hmac_tfm; in drbd_adm_connect()
2592 connection->integrity_tfm = crypto.integrity_tfm; in drbd_adm_connect()
2593 connection->csums_tfm = crypto.csums_tfm; in drbd_adm_connect()
2594 connection->verify_tfm = crypto.verify_tfm; in drbd_adm_connect()
2596 connection->my_addr_len = nla_len(adm_ctx.my_addr); in drbd_adm_connect()
2597 memcpy(&connection->my_addr, nla_data(adm_ctx.my_addr), connection->my_addr_len); in drbd_adm_connect()
2598 connection->peer_addr_len = nla_len(adm_ctx.peer_addr); in drbd_adm_connect()
2599 memcpy(&connection->peer_addr, nla_data(adm_ctx.peer_addr), connection->peer_addr_len); in drbd_adm_connect()
2601 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in drbd_adm_connect()
2606 flags = (peer_devices--) ? NOTIFY_CONTINUES : 0; in drbd_adm_connect()
2609 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in drbd_adm_connect()
2613 flags = (peer_devices--) ? NOTIFY_CONTINUES : 0; in drbd_adm_connect()
2617 mutex_unlock(&adm_ctx.resource->conf_update); in drbd_adm_connect()
2620 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in drbd_adm_connect()
2621 struct drbd_device *device = peer_device->device; in drbd_adm_connect()
2622 device->send_cnt = 0; in drbd_adm_connect()
2623 device->recv_cnt = 0; in drbd_adm_connect()
2630 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_connect()
2639 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_connect()
2668 spin_lock_irq(&connection->resource->req_lock); in conn_try_disconnect()
2669 cstate = connection->cstate; in conn_try_disconnect()
2670 spin_unlock_irq(&connection->resource->req_lock); in conn_try_disconnect()
2691 drbd_thread_stop(&connection->receiver); in conn_try_disconnect()
2697 * C_STANDALONE already, now, and this becomes a no-op. in conn_try_disconnect()
2706 * NOTIFY_DESTROY events before clearing connection->net_conf. */ in conn_try_disconnect()
2728 if (info->attrs[DRBD_NLA_DISCONNECT_PARMS]) { in drbd_adm_disconnect()
2737 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_disconnect()
2739 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_disconnect()
2755 if (device->state.role != device->state.peer) in resync_after_online_grow()
2756 iass = (device->state.role == R_PRIMARY); in resync_after_online_grow()
2758 iass = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags); in resync_after_online_grow()
2785 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_resize()
2793 rs.al_stripes = device->ldev->md.al_stripes; in drbd_adm_resize()
2794 rs.al_stripe_size = device->ldev->md.al_stripe_size_4k * 4; in drbd_adm_resize()
2795 if (info->attrs[DRBD_NLA_RESIZE_PARMS]) { in drbd_adm_resize()
2804 if (device->state.conn > C_CONNECTED) { in drbd_adm_resize()
2809 if (device->state.role == R_SECONDARY && in drbd_adm_resize()
2810 device->state.peer == R_SECONDARY) { in drbd_adm_resize()
2815 if (rs.no_resync && first_peer_device(device)->connection->agreed_pro_version < 93) { in drbd_adm_resize()
2821 u_size = rcu_dereference(device->ldev->disk_conf)->disk_size; in drbd_adm_resize()
2831 if (device->ldev->md.al_stripes != rs.al_stripes || in drbd_adm_resize()
2832 device->ldev->md.al_stripe_size_4k != rs.al_stripe_size / 4) { in drbd_adm_resize()
2845 if (device->state.conn != C_CONNECTED && !rs.resize_force) { in drbd_adm_resize()
2853 if (device->ldev->known_size != drbd_get_capacity(device->ldev->backing_bdev)) in drbd_adm_resize()
2854 device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev); in drbd_adm_resize()
2857 mutex_lock(&device->resource->conf_update); in drbd_adm_resize()
2858 old_disk_conf = device->ldev->disk_conf; in drbd_adm_resize()
2860 new_disk_conf->disk_size = (sector_t)rs.resize_size; in drbd_adm_resize()
2861 rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf); in drbd_adm_resize()
2862 mutex_unlock(&device->resource->conf_update); in drbd_adm_resize()
2882 if (device->state.conn == C_CONNECTED) { in drbd_adm_resize()
2884 set_bit(RESIZE_PENDING, &device->flags); in drbd_adm_resize()
2891 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_resize()
2915 res_opts = adm_ctx.resource->res_opts; in drbd_adm_resource_opts()
2920 if (err && err != -ENOMSG) { in drbd_adm_resource_opts()
2926 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_resource_opts()
2930 if (err == -ENOMEM) in drbd_adm_resource_opts()
2933 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_resource_opts()
2958 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_invalidate()
2964 wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); in drbd_adm_invalidate()
2965 drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work); in drbd_adm_invalidate()
2971 if (device->state.conn == C_STANDALONE && device->state.role == R_SECONDARY) { in drbd_adm_invalidate()
2981 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_invalidate()
3000 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_simple_request_state()
3002 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_simple_request_state()
3036 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_invalidate_peer()
3042 wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); in drbd_adm_invalidate_peer()
3043 drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work); in drbd_adm_invalidate_peer()
3049 if (device->state.conn == C_STANDALONE && device->state.role == R_PRIMARY) { in drbd_adm_invalidate_peer()
3062 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_invalidate_peer()
3080 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_pause_sync()
3083 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_pause_sync()
3101 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_resume_sync()
3103 s = adm_ctx.device->state; in drbd_adm_resume_sync()
3111 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_resume_sync()
3134 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_resume_io()
3136 if (test_bit(NEW_CUR_UUID, &device->flags)) { in drbd_adm_resume_io()
3141 /* This is effectively a multi-stage "forced down". in drbd_adm_resume_io()
3144 * to freeze IO and wait for some fence-peer handler. in drbd_adm_resume_io()
3153 * the refuse to re-connect or re-attach (because no in drbd_adm_resume_io()
3159 …drbd_warn(device, "Resumed without access to data; please tear down before attempting to re-config… in drbd_adm_resume_io()
3161 clear_bit(NEW_CUR_UUID, &device->flags); in drbd_adm_resume_io()
3166 if (device->state.conn < C_CONNECTED) in drbd_adm_resume_io()
3167 tl_clear(first_peer_device(device)->connection); in drbd_adm_resume_io()
3168 if (device->state.disk == D_DISKLESS || device->state.disk == D_FAILED) in drbd_adm_resume_io()
3169 tl_restart(first_peer_device(device)->connection, FAIL_FROZEN_DISK_IO); in drbd_adm_resume_io()
3172 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_resume_io()
3193 nla_put_u32(skb, T_ctx_volume, device->vnr)) in nla_put_drbd_cfg_context()
3195 if (nla_put_string(skb, T_ctx_resource_name, resource->name)) in nla_put_drbd_cfg_context()
3198 if (connection->my_addr_len && in nla_put_drbd_cfg_context()
3199 nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr)) in nla_put_drbd_cfg_context()
3201 if (connection->peer_addr_len && in nla_put_drbd_cfg_context()
3202 nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr)) in nla_put_drbd_cfg_context()
3211 return -EMSGSIZE; in nla_put_drbd_cfg_context()
3222 const int maxtype = ARRAY_SIZE(drbd_cfg_context_nl_policy) - 1; in find_cfg_context_attr()
3243 if (cb->args[0]) { in drbd_adm_dump_resources()
3245 if (resource == (struct drbd_resource *)cb->args[0]) in drbd_adm_dump_resources()
3261 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, in drbd_adm_dump_resources()
3262 cb->nlh->nlmsg_seq, &drbd_genl_family, in drbd_adm_dump_resources()
3264 err = -ENOMEM; in drbd_adm_dump_resources()
3267 dh->minor = -1U; in drbd_adm_dump_resources()
3268 dh->ret_code = NO_ERROR; in drbd_adm_dump_resources()
3272 err = res_opts_to_skb(skb, &resource->res_opts, !capable(CAP_SYS_ADMIN)); in drbd_adm_dump_resources()
3279 resource_statistics.res_stat_write_ordering = resource->write_ordering; in drbd_adm_dump_resources()
3283 cb->args[0] = (long)resource; in drbd_adm_dump_resources()
3291 return skb->len; in drbd_adm_dump_resources()
3298 s->dev_upper_blocked = !may_inc_ap_bio(device); in device_to_statistics()
3300 struct drbd_md *md = &device->ldev->md; in device_to_statistics()
3301 u64 *history_uuids = (u64 *)s->history_uuids; in device_to_statistics()
3304 spin_lock_irq(&md->uuid_lock); in device_to_statistics()
3305 s->dev_current_uuid = md->uuid[UI_CURRENT]; in device_to_statistics()
3306 BUILD_BUG_ON(sizeof(s->history_uuids) < UI_HISTORY_END - UI_HISTORY_START + 1); in device_to_statistics()
3307 for (n = 0; n < UI_HISTORY_END - UI_HISTORY_START + 1; n++) in device_to_statistics()
3308 history_uuids[n] = md->uuid[UI_HISTORY_START + n]; in device_to_statistics()
3311 s->history_uuids_len = HISTORY_UUIDS; in device_to_statistics()
3312 spin_unlock_irq(&md->uuid_lock); in device_to_statistics()
3314 s->dev_disk_flags = md->flags; in device_to_statistics()
3317 s->dev_size = get_capacity(device->vdisk); in device_to_statistics()
3318 s->dev_read = device->read_cnt; in device_to_statistics()
3319 s->dev_write = device->writ_cnt; in device_to_statistics()
3320 s->dev_al_writes = device->al_writ_cnt; in device_to_statistics()
3321 s->dev_bm_writes = device->bm_writ_cnt; in device_to_statistics()
3322 s->dev_upper_pending = atomic_read(&device->ap_bio_cnt); in device_to_statistics()
3323 s->dev_lower_pending = atomic_read(&device->local_cnt); in device_to_statistics()
3324 s->dev_al_suspended = test_bit(AL_SUSPENDED, &device->flags); in device_to_statistics()
3325 s->dev_exposed_data_uuid = device->ed_uuid; in device_to_statistics()
3330 if (cb->args[0]) { in put_resource_in_arg0()
3332 (struct drbd_resource *)cb->args[0]; in put_resource_in_arg0()
3333 kref_put(&resource->kref, drbd_destroy_resource); in put_resource_in_arg0()
3356 resource = (struct drbd_resource *)cb->args[0]; in drbd_adm_dump_devices()
3357 if (!cb->args[0] && !cb->args[1]) { in drbd_adm_dump_devices()
3358 resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name); in drbd_adm_dump_devices()
3364 cb->args[0] = (long)resource; in drbd_adm_dump_devices()
3369 minor = cb->args[1]; in drbd_adm_dump_devices()
3370 idr_to_search = resource ? &resource->devices : &drbd_devices; in drbd_adm_dump_devices()
3384 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, in drbd_adm_dump_devices()
3385 cb->nlh->nlmsg_seq, &drbd_genl_family, in drbd_adm_dump_devices()
3387 err = -ENOMEM; in drbd_adm_dump_devices()
3390 dh->ret_code = retcode; in drbd_adm_dump_devices()
3391 dh->minor = -1U; in drbd_adm_dump_devices()
3393 dh->minor = device->minor; in drbd_adm_dump_devices()
3394 err = nla_put_drbd_cfg_context(skb, device->resource, NULL, device); in drbd_adm_dump_devices()
3399 rcu_dereference(device->ldev->disk_conf); in drbd_adm_dump_devices()
3415 cb->args[1] = minor + 1; in drbd_adm_dump_devices()
3424 return skb->len; in drbd_adm_dump_devices()
3445 resource = (struct drbd_resource *)cb->args[0]; in drbd_adm_dump_connections()
3446 if (!cb->args[0]) { in drbd_adm_dump_connections()
3447 resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name); in drbd_adm_dump_connections()
3453 cb->args[0] = (long)resource; in drbd_adm_dump_connections()
3454 cb->args[1] = SINGLE_RESOURCE; in drbd_adm_dump_connections()
3461 kref_get(&resource->kref); in drbd_adm_dump_connections()
3462 cb->args[0] = (long)resource; in drbd_adm_dump_connections()
3463 cb->args[1] = ITERATE_RESOURCES; in drbd_adm_dump_connections()
3468 mutex_lock(&resource->conf_update); in drbd_adm_dump_connections()
3470 if (cb->args[2]) { in drbd_adm_dump_connections()
3472 if (connection == (struct drbd_connection *)cb->args[2]) in drbd_adm_dump_connections()
3477 connection = list_entry(&resource->connections, struct drbd_connection, connections); in drbd_adm_dump_connections()
3480 list_for_each_entry_continue_rcu(connection, &resource->connections, connections) { in drbd_adm_dump_connections()
3488 if (cb->args[1] == ITERATE_RESOURCES) { in drbd_adm_dump_connections()
3499 mutex_unlock(&resource->conf_update); in drbd_adm_dump_connections()
3500 kref_put(&resource->kref, drbd_destroy_resource); in drbd_adm_dump_connections()
3502 kref_get(&resource->kref); in drbd_adm_dump_connections()
3503 cb->args[0] = (long)resource; in drbd_adm_dump_connections()
3504 cb->args[2] = 0; in drbd_adm_dump_connections()
3510 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, in drbd_adm_dump_connections()
3511 cb->nlh->nlmsg_seq, &drbd_genl_family, in drbd_adm_dump_connections()
3513 err = -ENOMEM; in drbd_adm_dump_connections()
3516 dh->ret_code = retcode; in drbd_adm_dump_connections()
3517 dh->minor = -1U; in drbd_adm_dump_connections()
3524 net_conf = rcu_dereference(connection->net_conf); in drbd_adm_dump_connections()
3534 connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags); in drbd_adm_dump_connections()
3538 cb->args[2] = (long)connection; in drbd_adm_dump_connections()
3546 mutex_unlock(&resource->conf_update); in drbd_adm_dump_connections()
3549 return skb->len; in drbd_adm_dump_connections()
3562 struct drbd_device *device = peer_device->device; in peer_device_to_statistics()
3565 s->peer_dev_received = device->recv_cnt; in peer_device_to_statistics()
3566 s->peer_dev_sent = device->send_cnt; in peer_device_to_statistics()
3567 s->peer_dev_pending = atomic_read(&device->ap_pending_cnt) + in peer_device_to_statistics()
3568 atomic_read(&device->rs_pending_cnt); in peer_device_to_statistics()
3569 s->peer_dev_unacked = atomic_read(&device->unacked_cnt); in peer_device_to_statistics()
3570 s->peer_dev_out_of_sync = drbd_bm_total_weight(device) << (BM_BLOCK_SHIFT - 9); in peer_device_to_statistics()
3571 s->peer_dev_resync_failed = device->rs_failed << (BM_BLOCK_SHIFT - 9); in peer_device_to_statistics()
3573 struct drbd_md *md = &device->ldev->md; in peer_device_to_statistics()
3575 spin_lock_irq(&md->uuid_lock); in peer_device_to_statistics()
3576 s->peer_dev_bitmap_uuid = md->uuid[UI_BITMAP]; in peer_device_to_statistics()
3577 spin_unlock_irq(&md->uuid_lock); in peer_device_to_statistics()
3578 s->peer_dev_flags = in peer_device_to_statistics()
3579 (drbd_md_test_flag(device->ldev, MDF_CONNECTED_IND) ? in peer_device_to_statistics()
3581 (drbd_md_test_flag(device->ldev, MDF_CONSISTENT) && in peer_device_to_statistics()
3582 !drbd_md_test_flag(device->ldev, MDF_WAS_UP_TO_DATE) ? in peer_device_to_statistics()
3585 (drbd_md_test_flag(device->ldev, MDF_FULL_SYNC) ? in peer_device_to_statistics()
3606 resource = (struct drbd_resource *)cb->args[0]; in drbd_adm_dump_peer_devices()
3607 if (!cb->args[0] && !cb->args[1]) { in drbd_adm_dump_peer_devices()
3608 resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name); in drbd_adm_dump_peer_devices()
3615 cb->args[0] = (long)resource; in drbd_adm_dump_peer_devices()
3619 minor = cb->args[1]; in drbd_adm_dump_peer_devices()
3620 idr_to_search = resource ? &resource->devices : &drbd_devices; in drbd_adm_dump_peer_devices()
3625 cb->args[2] = 0; in drbd_adm_dump_peer_devices()
3632 if (cb->args[2]) { in drbd_adm_dump_peer_devices()
3634 if (peer_device == (struct drbd_peer_device *)cb->args[2]) in drbd_adm_dump_peer_devices()
3640 peer_device = list_entry(&device->peer_devices, struct drbd_peer_device, peer_devices); in drbd_adm_dump_peer_devices()
3643 list_for_each_entry_continue_rcu(peer_device, &device->peer_devices, peer_devices) { in drbd_adm_dump_peer_devices()
3644 if (!has_net_conf(peer_device->connection)) in drbd_adm_dump_peer_devices()
3652 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, in drbd_adm_dump_peer_devices()
3653 cb->nlh->nlmsg_seq, &drbd_genl_family, in drbd_adm_dump_peer_devices()
3655 err = -ENOMEM; in drbd_adm_dump_peer_devices()
3658 dh->ret_code = retcode; in drbd_adm_dump_peer_devices()
3659 dh->minor = -1U; in drbd_adm_dump_peer_devices()
3664 dh->minor = minor; in drbd_adm_dump_peer_devices()
3665 err = nla_put_drbd_cfg_context(skb, device->resource, peer_device->connection, device); in drbd_adm_dump_peer_devices()
3676 cb->args[1] = minor; in drbd_adm_dump_peer_devices()
3677 cb->args[2] = (long)peer_device; in drbd_adm_dump_peer_devices()
3686 return skb->len; in drbd_adm_dump_peer_devices()
3693 struct list_head *connections = &resource->connections; in the_only_connection()
3695 if (list_empty(connections) || connections->next->next != connections) in the_only_connection()
3697 return list_first_entry(&resource->connections, struct drbd_connection, connections); in the_only_connection()
3703 struct drbd_resource *resource = device->resource; in nla_put_status_info()
3704 struct state_info *si = NULL; /* for sizeof(si->member); */ in nla_put_status_info() local
3730 if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive)) in nla_put_status_info()
3737 disk_conf = rcu_dereference(device->ldev->disk_conf); in nla_put_status_info()
3741 struct net_conf *nc; in nla_put_status_info() local
3743 nc = rcu_dereference(first_peer_device(device)->connection->net_conf); in nla_put_status_info()
3744 if (nc) in nla_put_status_info()
3745 err = net_conf_to_skb(skb, nc, exclude_sensitive); in nla_put_status_info()
3754 if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) || in nla_put_status_info()
3755 nla_put_u32(skb, T_current_state, device->state.i) || in nla_put_status_info()
3756 nla_put_u64_0pad(skb, T_ed_uuid, device->ed_uuid) || in nla_put_status_info()
3757 nla_put_u64_0pad(skb, T_capacity, get_capacity(device->vdisk)) || in nla_put_status_info()
3758 nla_put_u64_0pad(skb, T_send_cnt, device->send_cnt) || in nla_put_status_info()
3759 nla_put_u64_0pad(skb, T_recv_cnt, device->recv_cnt) || in nla_put_status_info()
3760 nla_put_u64_0pad(skb, T_read_cnt, device->read_cnt) || in nla_put_status_info()
3761 nla_put_u64_0pad(skb, T_writ_cnt, device->writ_cnt) || in nla_put_status_info()
3762 nla_put_u64_0pad(skb, T_al_writ_cnt, device->al_writ_cnt) || in nla_put_status_info()
3763 nla_put_u64_0pad(skb, T_bm_writ_cnt, device->bm_writ_cnt) || in nla_put_status_info()
3764 nla_put_u32(skb, T_ap_bio_cnt, atomic_read(&device->ap_bio_cnt)) || in nla_put_status_info()
3765 nla_put_u32(skb, T_ap_pending_cnt, atomic_read(&device->ap_pending_cnt)) || in nla_put_status_info()
3766 nla_put_u32(skb, T_rs_pending_cnt, atomic_read(&device->rs_pending_cnt))) in nla_put_status_info()
3772 spin_lock_irq(&device->ldev->md.uuid_lock); in nla_put_status_info()
3773 err = nla_put(skb, T_uuids, sizeof(si->uuids), device->ldev->md.uuid); in nla_put_status_info()
3774 spin_unlock_irq(&device->ldev->md.uuid_lock); in nla_put_status_info()
3779 if (nla_put_u32(skb, T_disk_flags, device->ldev->md.flags) || in nla_put_status_info()
3784 if (C_SYNC_SOURCE <= device->state.conn && in nla_put_status_info()
3785 C_PAUSED_SYNC_T >= device->state.conn) { in nla_put_status_info()
3787 device->rs_total) || in nla_put_status_info()
3789 device->rs_failed)) in nla_put_status_info()
3795 switch(sib->sib_reason) { in nla_put_status_info()
3800 if (nla_put_u32(skb, T_prev_state, sib->os.i) || in nla_put_status_info()
3801 nla_put_u32(skb, T_new_state, sib->ns.i)) in nla_put_status_info()
3806 sib->helper_exit_code)) in nla_put_status_info()
3810 if (nla_put_string(skb, T_helper, sib->helper_name)) in nla_put_status_info()
3819 err = -EMSGSIZE; in nla_put_status_info()
3851 struct drbd_resource *pos = (struct drbd_resource *)cb->args[0]; in get_one_status()
3854 unsigned volume = cb->args[1]; in get_one_status()
3859 * idr_for_each_entry(&resource->devices, device, i) { in get_one_status()
3863 * where resource is cb->args[0]; in get_one_status()
3864 * and i is cb->args[1]; in get_one_status()
3866 * cb->args[2] indicates if we shall loop over all resources, in get_one_status()
3894 device = idr_get_next(&resource->devices, &volume); in get_one_status()
3898 pos = list_entry_rcu(resource->resources.next, in get_one_status()
3905 if (&pos->resources == &drbd_resources || cb->args[2]) in get_one_status()
3913 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, in get_one_status()
3914 cb->nlh->nlmsg_seq, &drbd_genl_family, in get_one_status()
3925 dh->minor = -1U; in get_one_status()
3926 dh->ret_code = NO_ERROR; in get_one_status()
3931 struct net_conf *nc; in get_one_status() local
3933 nc = rcu_dereference(connection->net_conf); in get_one_status()
3934 if (nc && net_conf_to_skb(skb, nc, 1) != 0) in get_one_status()
3940 D_ASSERT(device, device->vnr == volume); in get_one_status()
3941 D_ASSERT(device, device->resource == resource); in get_one_status()
3943 dh->minor = device_to_minor(device); in get_one_status()
3944 dh->ret_code = NO_ERROR; in get_one_status()
3958 cb->args[0] = (long)pos; in get_one_status()
3959 cb->args[1] = (pos == resource) ? volume + 1 : 0; in get_one_status()
3963 return skb->len; in get_one_status()
3970 * Which means we cannot use the family->attrbuf or other such members, because
3985 if (cb->args[0]) { in drbd_adm_get_status_all()
3988 if (cb->args[2] && cb->args[2] != cb->args[0]) in drbd_adm_get_status_all()
3995 nla = nla_find(nlmsg_attrdata(cb->nlh, hdrlen), in drbd_adm_get_status_all()
3996 nlmsg_attrlen(cb->nlh, hdrlen), in drbd_adm_get_status_all()
4002 maxtype = ARRAY_SIZE(drbd_cfg_context_nl_policy) - 1; in drbd_adm_get_status_all()
4008 return -EINVAL; in drbd_adm_get_status_all()
4011 return -ENODEV; in drbd_adm_get_status_all()
4014 return -ENODEV; in drbd_adm_get_status_all()
4016 kref_put(&resource->kref, drbd_destroy_resource); /* get_one_status() revalidates the resource */ in drbd_adm_get_status_all()
4020 cb->args[0] = (long)resource; in drbd_adm_get_status_all()
4021 /* cb->args[1] = 0; passed in this way. */ in drbd_adm_get_status_all()
4022 cb->args[2] = (long)resource; in drbd_adm_get_status_all()
4042 adm_ctx.device->state.pdsk == D_OUTDATED ? UT_PEER_OUTDATED : in drbd_adm_get_timeout_type()
4043 test_bit(USE_DEGR_WFC_T, &adm_ctx.device->flags) ? UT_DEGRADED : in drbd_adm_get_timeout_type()
4072 parms.ov_start_sector = device->ov_start_sector; in drbd_adm_start_ov()
4074 if (info->attrs[DRBD_NLA_START_OV_PARMS]) { in drbd_adm_start_ov()
4082 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_start_ov()
4085 device->ov_start_sector = parms.ov_start_sector & ~(BM_SECT_PER_BIT-1); in drbd_adm_start_ov()
4086 device->ov_stop_sector = parms.ov_stop_sector; in drbd_adm_start_ov()
4091 wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); in drbd_adm_start_ov()
4095 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_start_ov()
4119 if (info->attrs[DRBD_NLA_NEW_C_UUID_PARMS]) { in drbd_adm_new_c_uuid()
4128 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_new_c_uuid()
4129 mutex_lock(device->state_mutex); /* Protects us against serialized state changes. */ in drbd_adm_new_c_uuid()
4137 if (device->state.conn == C_CONNECTED && in drbd_adm_new_c_uuid()
4138 first_peer_device(device)->connection->agreed_pro_version >= 90 && in drbd_adm_new_c_uuid()
4139 device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) { in drbd_adm_new_c_uuid()
4142 } else if (device->state.conn != C_STANDALONE) { in drbd_adm_new_c_uuid()
4161 spin_lock_irq(&device->resource->req_lock); in drbd_adm_new_c_uuid()
4164 spin_unlock_irq(&device->resource->req_lock); in drbd_adm_new_c_uuid()
4172 mutex_unlock(device->state_mutex); in drbd_adm_new_c_uuid()
4173 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_new_c_uuid()
4182 const char *name = adm_ctx->resource_name; in drbd_check_resource_name()
4184 drbd_msg_put_info(adm_ctx->reply_skb, "resource name missing"); in drbd_check_resource_name()
4190 drbd_msg_put_info(adm_ctx->reply_skb, "invalid resource name"); in drbd_check_resource_name()
4199 info->res_role = conn_highest_role(first_connection(resource)); in resource_to_info()
4200 info->res_susp = resource->susp; in resource_to_info()
4201 info->res_susp_nod = resource->susp_nod; in resource_to_info()
4202 info->res_susp_fen = resource->susp_fen; in resource_to_info()
4221 if (err && err != -ENOMSG) { in drbd_adm_new_resource()
4232 if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) { in drbd_adm_new_resource()
4249 resource_to_info(&resource_info, connection->resource); in drbd_adm_new_resource()
4250 notify_resource_state(NULL, 0, connection->resource, in drbd_adm_new_resource()
4264 info->dev_disk_state = device->state.disk; in device_to_info()
4280 if (dh->minor > MINORMASK) { in drbd_adm_new_minor()
4292 * that first_peer_device(device)->connection and device->vnr match the request. */ in drbd_adm_new_minor()
4294 if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) in drbd_adm_new_minor()
4300 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_new_minor()
4301 retcode = drbd_create_device(&adm_ctx, dh->minor); in drbd_adm_new_minor()
4309 device = minor_to_device(dh->minor); in drbd_adm_new_minor()
4311 if (!has_net_conf(peer_device->connection)) in drbd_adm_new_minor()
4318 flags = (peer_devices--) ? NOTIFY_CONTINUES : 0; in drbd_adm_new_minor()
4323 if (!has_net_conf(peer_device->connection)) in drbd_adm_new_minor()
4326 flags = (peer_devices--) ? NOTIFY_CONTINUES : 0; in drbd_adm_new_minor()
4332 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_new_minor()
4342 if (device->state.disk == D_DISKLESS && in adm_del_minor()
4343 /* no need to be device->state.conn == C_STANDALONE && in adm_del_minor()
4346 device->state.role == R_SECONDARY) { in adm_del_minor()
4348 first_connection(device->resource); in adm_del_minor()
4356 if (get_t_state(&connection->worker) == RUNNING) in adm_del_minor()
4357 drbd_flush_workqueue(&connection->sender_work); in adm_del_minor()
4361 if (!has_net_conf(peer_device->connection)) in adm_del_minor()
4386 mutex_lock(&adm_ctx.resource->adm_mutex); in drbd_adm_del_minor()
4388 mutex_unlock(&adm_ctx.resource->adm_mutex); in drbd_adm_del_minor()
4399 if (connection->cstate > C_STANDALONE) in adm_del_resource()
4402 if (!idr_is_empty(&resource->devices)) in adm_del_resource()
4413 list_del_rcu(&resource->resources); in adm_del_resource()
4417 list_for_each_entry(connection, &resource->connections, connections) in adm_del_resource()
4418 drbd_thread_stop(&connection->worker); in adm_del_resource()
4440 mutex_lock(&resource->adm_mutex); in drbd_adm_down()
4445 idr_for_each_entry(&connection->peer_devices, peer_device, i) { in drbd_adm_down()
4446 retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0); in drbd_adm_down()
4461 idr_for_each_entry(&resource->devices, device, i) { in drbd_adm_down()
4470 idr_for_each_entry(&resource->devices, device, i) { in drbd_adm_down()
4481 mutex_unlock(&resource->adm_mutex); in drbd_adm_down()
4500 mutex_lock(&resource->adm_mutex); in drbd_adm_del_resource()
4502 mutex_unlock(&resource->adm_mutex); in drbd_adm_del_resource()
4513 int err = -ENOMEM; in drbd_bcast_event()
4520 err = -EMSGSIZE; in drbd_bcast_event()
4524 d_out->minor = device_to_minor(device); in drbd_bcast_event()
4525 d_out->ret_code = NO_ERROR; in drbd_bcast_event()
4532 if (err && err != -ESRCH) in drbd_bcast_event()
4542 err, seq, sib->sib_reason); in drbd_bcast_event()
4569 err = -ENOMEM; in notify_resource_state()
4575 err = -EMSGSIZE; in notify_resource_state()
4579 dh->minor = -1U; in notify_resource_state()
4580 dh->ret_code = NO_ERROR; in notify_resource_state()
4586 resource_statistics.res_stat_write_ordering = resource->write_ordering; in notify_resource_state()
4594 if (err && err != -ESRCH) in notify_resource_state()
4621 err = -ENOMEM; in notify_device_state()
4627 err = -EMSGSIZE; in notify_device_state()
4631 dh->minor = device->minor; in notify_device_state()
4632 dh->ret_code = NO_ERROR; in notify_device_state()
4633 if (nla_put_drbd_cfg_context(skb, device->resource, NULL, device) || in notify_device_state()
4644 if (err && err != -ESRCH) in notify_device_state()
4671 err = -ENOMEM; in notify_connection_state()
4677 err = -EMSGSIZE; in notify_connection_state()
4681 dh->minor = -1U; in notify_connection_state()
4682 dh->ret_code = NO_ERROR; in notify_connection_state()
4683 if (nla_put_drbd_cfg_context(skb, connection->resource, connection, NULL) || in notify_connection_state()
4688 connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags); in notify_connection_state()
4694 if (err && err != -ESRCH) in notify_connection_state()
4714 struct drbd_resource *resource = peer_device->device->resource; in notify_peer_device_state()
4722 err = -ENOMEM; in notify_peer_device_state()
4728 err = -EMSGSIZE; in notify_peer_device_state()
4732 dh->minor = -1U; in notify_peer_device_state()
4733 dh->ret_code = NO_ERROR; in notify_peer_device_state()
4734 if (nla_put_drbd_cfg_context(skb, resource, peer_device->connection, peer_device->device) || in notify_peer_device_state()
4745 if (err && err != -ESRCH) in notify_peer_device_state()
4762 struct drbd_resource *resource = device ? device->resource : connection->resource; in notify_helper()
4774 err = -ENOMEM; in notify_helper()
4778 err = -EMSGSIZE; in notify_helper()
4782 dh->minor = device ? device->minor : -1; in notify_helper()
4783 dh->ret_code = NO_ERROR; in notify_helper()
4793 if (err && err != -ESRCH) in notify_helper()
4811 err = -EMSGSIZE; in notify_initial_state_done()
4815 dh->minor = -1U; in notify_initial_state_done()
4816 dh->ret_code = NO_ERROR; in notify_initial_state_done()
4833 list_del(&state_change->list); in free_state_changes()
4841 state_change->n_connections + in notifications_for_state_change()
4842 state_change->n_devices + in notifications_for_state_change()
4843 state_change->n_devices * state_change->n_connections; in notifications_for_state_change()
4848 struct drbd_state_change *state_change = (struct drbd_state_change *)cb->args[0]; in get_initial_state()
4849 unsigned int seq = cb->args[2]; in get_initial_state()
4859 cb->args[5]--; in get_initial_state()
4860 if (cb->args[5] == 1) { in get_initial_state()
4864 n = cb->args[4]++; in get_initial_state()
4865 if (cb->args[4] < cb->args[3]) in get_initial_state()
4868 err = notify_resource_state_change(skb, seq, state_change->resource, in get_initial_state()
4872 n--; in get_initial_state()
4873 if (n < state_change->n_connections) { in get_initial_state()
4874 err = notify_connection_state_change(skb, seq, &state_change->connections[n], in get_initial_state()
4878 n -= state_change->n_connections; in get_initial_state()
4879 if (n < state_change->n_devices) { in get_initial_state()
4880 err = notify_device_state_change(skb, seq, &state_change->devices[n], in get_initial_state()
4884 n -= state_change->n_devices; in get_initial_state()
4885 if (n < state_change->n_devices * state_change->n_connections) { in get_initial_state()
4886 err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], in get_initial_state()
4892 if (cb->args[4] == cb->args[3]) { in get_initial_state()
4894 list_entry(state_change->list.next, in get_initial_state()
4896 cb->args[0] = (long)next_state_change; in get_initial_state()
4897 cb->args[3] = notifications_for_state_change(next_state_change); in get_initial_state()
4898 cb->args[4] = 0; in get_initial_state()
4904 return skb->len; in get_initial_state()
4912 if (cb->args[5] >= 1) { in drbd_adm_get_initial_state()
4913 if (cb->args[5] > 1) in drbd_adm_get_initial_state()
4915 if (cb->args[0]) { in drbd_adm_get_initial_state()
4917 (struct drbd_state_change *)cb->args[0]; in drbd_adm_get_initial_state()
4920 list_add(&head, &state_change->list); in drbd_adm_get_initial_state()
4926 cb->args[5] = 2; /* number of iterations */ in drbd_adm_get_initial_state()
4936 return -ENOMEM; in drbd_adm_get_initial_state()
4939 list_add_tail(&state_change->list, &head); in drbd_adm_get_initial_state()
4940 cb->args[5] += notifications_for_state_change(state_change); in drbd_adm_get_initial_state()
4947 cb->args[0] = (long)state_change; in drbd_adm_get_initial_state()
4948 cb->args[3] = notifications_for_state_change(state_change); in drbd_adm_get_initial_state()
4952 cb->args[2] = cb->nlh->nlmsg_seq; in drbd_adm_get_initial_state()