.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | drbd_nl.c |
---|
3 | 4 | |
---|
.. | .. |
---|
7 | 8 | Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>. |
---|
8 | 9 | Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>. |
---|
9 | 10 | |
---|
10 | | - drbd is free software; you can redistribute it and/or modify |
---|
11 | | - it under the terms of the GNU General Public License as published by |
---|
12 | | - the Free Software Foundation; either version 2, or (at your option) |
---|
13 | | - any later version. |
---|
14 | | - |
---|
15 | | - drbd is distributed in the hope that it will be useful, |
---|
16 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - GNU General Public License for more details. |
---|
19 | | - |
---|
20 | | - You should have received a copy of the GNU General Public License |
---|
21 | | - along with drbd; see the file COPYING. If not, write to |
---|
22 | | - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
23 | 11 | |
---|
24 | 12 | */ |
---|
25 | 13 | |
---|
.. | .. |
---|
114 | 102 | if (!info || !info[0]) |
---|
115 | 103 | return 0; |
---|
116 | 104 | |
---|
117 | | - nla = nla_nest_start(skb, DRBD_NLA_CFG_REPLY); |
---|
| 105 | + nla = nla_nest_start_noflag(skb, DRBD_NLA_CFG_REPLY); |
---|
118 | 106 | if (!nla) |
---|
119 | 107 | return err; |
---|
120 | 108 | |
---|
.. | .. |
---|
124 | 112 | return err; |
---|
125 | 113 | } else |
---|
126 | 114 | nla_nest_end(skb, nla); |
---|
| 115 | + return 0; |
---|
| 116 | +} |
---|
| 117 | + |
---|
| 118 | +__printf(2, 3) |
---|
| 119 | +static int drbd_msg_sprintf_info(struct sk_buff *skb, const char *fmt, ...) |
---|
| 120 | +{ |
---|
| 121 | + va_list args; |
---|
| 122 | + struct nlattr *nla, *txt; |
---|
| 123 | + int err = -EMSGSIZE; |
---|
| 124 | + int len; |
---|
| 125 | + |
---|
| 126 | + nla = nla_nest_start_noflag(skb, DRBD_NLA_CFG_REPLY); |
---|
| 127 | + if (!nla) |
---|
| 128 | + return err; |
---|
| 129 | + |
---|
| 130 | + txt = nla_reserve(skb, T_info_text, 256); |
---|
| 131 | + if (!txt) { |
---|
| 132 | + nla_nest_cancel(skb, nla); |
---|
| 133 | + return err; |
---|
| 134 | + } |
---|
| 135 | + va_start(args, fmt); |
---|
| 136 | + len = vscnprintf(nla_data(txt), 256, fmt, args); |
---|
| 137 | + va_end(args); |
---|
| 138 | + |
---|
| 139 | + /* maybe: retry with larger reserve, if truncated */ |
---|
| 140 | + txt->nla_len = nla_attr_size(len+1); |
---|
| 141 | + nlmsg_trim(skb, (char*)txt + NLA_ALIGN(txt->nla_len)); |
---|
| 142 | + nla_nest_end(skb, nla); |
---|
| 143 | + |
---|
127 | 144 | return 0; |
---|
128 | 145 | } |
---|
129 | 146 | |
---|
.. | .. |
---|
251 | 268 | /* some more paranoia, if the request was over-determined */ |
---|
252 | 269 | if (adm_ctx->device && adm_ctx->resource && |
---|
253 | 270 | adm_ctx->device->resource != adm_ctx->resource) { |
---|
254 | | - pr_warning("request: minor=%u, resource=%s; but that minor belongs to resource %s\n", |
---|
255 | | - adm_ctx->minor, adm_ctx->resource->name, |
---|
256 | | - adm_ctx->device->resource->name); |
---|
| 271 | + pr_warn("request: minor=%u, resource=%s; but that minor belongs to resource %s\n", |
---|
| 272 | + adm_ctx->minor, adm_ctx->resource->name, |
---|
| 273 | + adm_ctx->device->resource->name); |
---|
257 | 274 | drbd_msg_put_info(adm_ctx->reply_skb, "minor exists in different resource"); |
---|
258 | 275 | return ERR_INVALID_REQUEST; |
---|
259 | 276 | } |
---|
260 | 277 | if (adm_ctx->device && |
---|
261 | 278 | adm_ctx->volume != VOLUME_UNSPECIFIED && |
---|
262 | 279 | adm_ctx->volume != adm_ctx->device->vnr) { |
---|
263 | | - pr_warning("request: minor=%u, volume=%u; but that minor is volume %u in %s\n", |
---|
264 | | - adm_ctx->minor, adm_ctx->volume, |
---|
265 | | - adm_ctx->device->vnr, |
---|
266 | | - adm_ctx->device->resource->name); |
---|
| 280 | + pr_warn("request: minor=%u, volume=%u; but that minor is volume %u in %s\n", |
---|
| 281 | + adm_ctx->minor, adm_ctx->volume, |
---|
| 282 | + adm_ctx->device->vnr, adm_ctx->device->resource->name); |
---|
267 | 283 | drbd_msg_put_info(adm_ctx->reply_skb, "minor exists as different volume"); |
---|
268 | 284 | return ERR_INVALID_REQUEST; |
---|
269 | 285 | } |
---|
.. | .. |
---|
582 | 598 | struct task_struct *opa; |
---|
583 | 599 | |
---|
584 | 600 | kref_get(&connection->kref); |
---|
585 | | - /* We may just have force_sig()'ed this thread |
---|
| 601 | + /* We may have just sent a signal to this thread |
---|
586 | 602 | * to get it out of some blocking network function. |
---|
587 | 603 | * Clear signals; otherwise kthread_run(), which internally uses |
---|
588 | 604 | * wait_on_completion_killable(), will mistake our pending signal |
---|
.. | .. |
---|
774 | 790 | mutex_lock(&adm_ctx.resource->adm_mutex); |
---|
775 | 791 | |
---|
776 | 792 | if (info->genlhdr->cmd == DRBD_ADM_PRIMARY) |
---|
777 | | - retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate); |
---|
| 793 | + retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device, |
---|
| 794 | + R_PRIMARY, parms.assume_uptodate); |
---|
778 | 795 | else |
---|
779 | | - retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0); |
---|
| 796 | + retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device, |
---|
| 797 | + R_SECONDARY, 0); |
---|
780 | 798 | |
---|
781 | 799 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
---|
782 | 800 | genl_lock(); |
---|
.. | .. |
---|
922 | 940 | } prev; |
---|
923 | 941 | sector_t u_size, size; |
---|
924 | 942 | struct drbd_md *md = &device->ldev->md; |
---|
925 | | - char ppb[10]; |
---|
926 | 943 | void *buffer; |
---|
927 | 944 | |
---|
928 | 945 | int md_moved, la_size_changed; |
---|
.. | .. |
---|
981 | 998 | goto err_out; |
---|
982 | 999 | } |
---|
983 | 1000 | |
---|
984 | | - if (drbd_get_capacity(device->this_bdev) != size || |
---|
| 1001 | + if (get_capacity(device->vdisk) != size || |
---|
985 | 1002 | drbd_bm_capacity(device) != size) { |
---|
986 | 1003 | int err; |
---|
987 | 1004 | err = drbd_bm_resize(device, size, !(flags & DDSF_NO_RESYNC)); |
---|
.. | .. |
---|
1000 | 1017 | /* racy, see comments above. */ |
---|
1001 | 1018 | drbd_set_my_capacity(device, size); |
---|
1002 | 1019 | md->la_size_sect = size; |
---|
1003 | | - drbd_info(device, "size = %s (%llu KB)\n", ppsize(ppb, size>>1), |
---|
1004 | | - (unsigned long long)size>>1); |
---|
1005 | 1020 | } |
---|
1006 | 1021 | if (rv <= DS_ERROR) |
---|
1007 | 1022 | goto err_out; |
---|
.. | .. |
---|
1235 | 1250 | } |
---|
1236 | 1251 | } |
---|
1237 | 1252 | |
---|
| 1253 | +static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q) |
---|
| 1254 | +{ |
---|
| 1255 | + /* Fixup max_write_zeroes_sectors after blk_stack_limits(): |
---|
| 1256 | + * if we can handle "zeroes" efficiently on the protocol, |
---|
| 1257 | + * we want to do that, even if our backend does not announce |
---|
| 1258 | + * max_write_zeroes_sectors itself. */ |
---|
| 1259 | + struct drbd_connection *connection = first_peer_device(device)->connection; |
---|
| 1260 | + /* If the peer announces WZEROES support, use it. Otherwise, rather |
---|
| 1261 | + * send explicit zeroes than rely on some discard-zeroes-data magic. */ |
---|
| 1262 | + if (connection->agreed_features & DRBD_FF_WZEROES) |
---|
| 1263 | + q->limits.max_write_zeroes_sectors = DRBD_MAX_BBIO_SECTORS; |
---|
| 1264 | + else |
---|
| 1265 | + q->limits.max_write_zeroes_sectors = 0; |
---|
| 1266 | +} |
---|
| 1267 | + |
---|
1238 | 1268 | static void decide_on_write_same_support(struct drbd_device *device, |
---|
1239 | 1269 | struct request_queue *q, |
---|
1240 | 1270 | struct request_queue *b, struct o_qlim *o, |
---|
.. | .. |
---|
1333 | 1363 | decide_on_write_same_support(device, q, b, o, disable_write_same); |
---|
1334 | 1364 | |
---|
1335 | 1365 | if (b) { |
---|
1336 | | - blk_queue_stack_limits(q, b); |
---|
1337 | | - |
---|
1338 | | - if (q->backing_dev_info->ra_pages != |
---|
1339 | | - b->backing_dev_info->ra_pages) { |
---|
1340 | | - drbd_info(device, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n", |
---|
1341 | | - q->backing_dev_info->ra_pages, |
---|
1342 | | - b->backing_dev_info->ra_pages); |
---|
1343 | | - q->backing_dev_info->ra_pages = |
---|
1344 | | - b->backing_dev_info->ra_pages; |
---|
1345 | | - } |
---|
| 1366 | + blk_stack_limits(&q->limits, &b->limits, 0); |
---|
| 1367 | + blk_queue_update_readahead(q); |
---|
1346 | 1368 | } |
---|
1347 | 1369 | fixup_discard_if_not_supported(q); |
---|
| 1370 | + fixup_write_zeroes(device, q); |
---|
1348 | 1371 | } |
---|
1349 | 1372 | |
---|
1350 | 1373 | void drbd_reconsider_queue_parameters(struct drbd_device *device, struct drbd_backing_dev *bdev, struct o_qlim *o) |
---|
.. | .. |
---|
1546 | 1569 | struct drbd_device *device; |
---|
1547 | 1570 | struct disk_conf *new_disk_conf, *old_disk_conf; |
---|
1548 | 1571 | struct fifo_buffer *old_plan = NULL, *new_plan = NULL; |
---|
1549 | | - int err, fifo_size; |
---|
| 1572 | + int err; |
---|
| 1573 | + unsigned int fifo_size; |
---|
1550 | 1574 | |
---|
1551 | 1575 | retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR); |
---|
1552 | 1576 | if (!adm_ctx.reply_skb) |
---|
.. | .. |
---|
1911 | 1935 | |
---|
1912 | 1936 | /* Make sure the new disk is big enough |
---|
1913 | 1937 | * (we may currently be R_PRIMARY with no local disk...) */ |
---|
1914 | | - if (drbd_get_max_capacity(nbc) < |
---|
1915 | | - drbd_get_capacity(device->this_bdev)) { |
---|
| 1938 | + if (drbd_get_max_capacity(nbc) < get_capacity(device->vdisk)) { |
---|
1916 | 1939 | retcode = ERR_DISK_TOO_SMALL; |
---|
1917 | 1940 | goto fail; |
---|
1918 | 1941 | } |
---|
.. | .. |
---|
1941 | 1964 | drbd_flush_workqueue(&connection->sender_work); |
---|
1942 | 1965 | |
---|
1943 | 1966 | rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE); |
---|
1944 | | - retcode = rv; /* FIXME: Type mismatch. */ |
---|
| 1967 | + retcode = (enum drbd_ret_code)rv; |
---|
1945 | 1968 | drbd_resume_io(device); |
---|
1946 | 1969 | if (rv < SS_SUCCESS) |
---|
1947 | 1970 | goto fail; |
---|
.. | .. |
---|
1972 | 1995 | } |
---|
1973 | 1996 | |
---|
1974 | 1997 | /* Prevent shrinking of consistent devices ! */ |
---|
1975 | | - if (drbd_md_test_flag(nbc, MDF_CONSISTENT) && |
---|
1976 | | - drbd_new_dev_size(device, nbc, nbc->disk_conf->disk_size, 0) < nbc->md.la_size_sect) { |
---|
1977 | | - drbd_warn(device, "refusing to truncate a consistent device\n"); |
---|
1978 | | - retcode = ERR_DISK_TOO_SMALL; |
---|
1979 | | - goto force_diskless_dec; |
---|
| 1998 | + { |
---|
| 1999 | + unsigned long long nsz = drbd_new_dev_size(device, nbc, nbc->disk_conf->disk_size, 0); |
---|
| 2000 | + unsigned long long eff = nbc->md.la_size_sect; |
---|
| 2001 | + if (drbd_md_test_flag(nbc, MDF_CONSISTENT) && nsz < eff) { |
---|
| 2002 | + if (nsz == nbc->disk_conf->disk_size) { |
---|
| 2003 | + drbd_warn(device, "truncating a consistent device during attach (%llu < %llu)\n", nsz, eff); |
---|
| 2004 | + } else { |
---|
| 2005 | + drbd_warn(device, "refusing to truncate a consistent device (%llu < %llu)\n", nsz, eff); |
---|
| 2006 | + drbd_msg_sprintf_info(adm_ctx.reply_skb, |
---|
| 2007 | + "To-be-attached device has last effective > current size, and is consistent\n" |
---|
| 2008 | + "(%llu > %llu sectors). Refusing to attach.", eff, nsz); |
---|
| 2009 | + retcode = ERR_IMPLICIT_SHRINK; |
---|
| 2010 | + goto force_diskless_dec; |
---|
| 2011 | + } |
---|
| 2012 | + } |
---|
1980 | 2013 | } |
---|
1981 | 2014 | |
---|
1982 | 2015 | lock_all_resources(); |
---|
.. | .. |
---|
2325 | 2358 | } |
---|
2326 | 2359 | |
---|
2327 | 2360 | struct crypto { |
---|
2328 | | - struct crypto_ahash *verify_tfm; |
---|
2329 | | - struct crypto_ahash *csums_tfm; |
---|
| 2361 | + struct crypto_shash *verify_tfm; |
---|
| 2362 | + struct crypto_shash *csums_tfm; |
---|
2330 | 2363 | struct crypto_shash *cram_hmac_tfm; |
---|
2331 | | - struct crypto_ahash *integrity_tfm; |
---|
| 2364 | + struct crypto_shash *integrity_tfm; |
---|
2332 | 2365 | }; |
---|
2333 | 2366 | |
---|
2334 | 2367 | static int |
---|
.. | .. |
---|
2346 | 2379 | return NO_ERROR; |
---|
2347 | 2380 | } |
---|
2348 | 2381 | |
---|
2349 | | -static int |
---|
2350 | | -alloc_ahash(struct crypto_ahash **tfm, char *tfm_name, int err_alg) |
---|
2351 | | -{ |
---|
2352 | | - if (!tfm_name[0]) |
---|
2353 | | - return NO_ERROR; |
---|
2354 | | - |
---|
2355 | | - *tfm = crypto_alloc_ahash(tfm_name, 0, CRYPTO_ALG_ASYNC); |
---|
2356 | | - if (IS_ERR(*tfm)) { |
---|
2357 | | - *tfm = NULL; |
---|
2358 | | - return err_alg; |
---|
2359 | | - } |
---|
2360 | | - |
---|
2361 | | - return NO_ERROR; |
---|
2362 | | -} |
---|
2363 | | - |
---|
2364 | 2382 | static enum drbd_ret_code |
---|
2365 | 2383 | alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf) |
---|
2366 | 2384 | { |
---|
2367 | 2385 | char hmac_name[CRYPTO_MAX_ALG_NAME]; |
---|
2368 | 2386 | enum drbd_ret_code rv; |
---|
2369 | 2387 | |
---|
2370 | | - rv = alloc_ahash(&crypto->csums_tfm, new_net_conf->csums_alg, |
---|
| 2388 | + rv = alloc_shash(&crypto->csums_tfm, new_net_conf->csums_alg, |
---|
2371 | 2389 | ERR_CSUMS_ALG); |
---|
2372 | 2390 | if (rv != NO_ERROR) |
---|
2373 | 2391 | return rv; |
---|
2374 | | - rv = alloc_ahash(&crypto->verify_tfm, new_net_conf->verify_alg, |
---|
| 2392 | + rv = alloc_shash(&crypto->verify_tfm, new_net_conf->verify_alg, |
---|
2375 | 2393 | ERR_VERIFY_ALG); |
---|
2376 | 2394 | if (rv != NO_ERROR) |
---|
2377 | 2395 | return rv; |
---|
2378 | | - rv = alloc_ahash(&crypto->integrity_tfm, new_net_conf->integrity_alg, |
---|
| 2396 | + rv = alloc_shash(&crypto->integrity_tfm, new_net_conf->integrity_alg, |
---|
2379 | 2397 | ERR_INTEGRITY_ALG); |
---|
2380 | 2398 | if (rv != NO_ERROR) |
---|
2381 | 2399 | return rv; |
---|
.. | .. |
---|
2393 | 2411 | static void free_crypto(struct crypto *crypto) |
---|
2394 | 2412 | { |
---|
2395 | 2413 | crypto_free_shash(crypto->cram_hmac_tfm); |
---|
2396 | | - crypto_free_ahash(crypto->integrity_tfm); |
---|
2397 | | - crypto_free_ahash(crypto->csums_tfm); |
---|
2398 | | - crypto_free_ahash(crypto->verify_tfm); |
---|
| 2414 | + crypto_free_shash(crypto->integrity_tfm); |
---|
| 2415 | + crypto_free_shash(crypto->csums_tfm); |
---|
| 2416 | + crypto_free_shash(crypto->verify_tfm); |
---|
2399 | 2417 | } |
---|
2400 | 2418 | |
---|
2401 | 2419 | int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) |
---|
.. | .. |
---|
2472 | 2490 | rcu_assign_pointer(connection->net_conf, new_net_conf); |
---|
2473 | 2491 | |
---|
2474 | 2492 | if (!rsr) { |
---|
2475 | | - crypto_free_ahash(connection->csums_tfm); |
---|
| 2493 | + crypto_free_shash(connection->csums_tfm); |
---|
2476 | 2494 | connection->csums_tfm = crypto.csums_tfm; |
---|
2477 | 2495 | crypto.csums_tfm = NULL; |
---|
2478 | 2496 | } |
---|
2479 | 2497 | if (!ovr) { |
---|
2480 | | - crypto_free_ahash(connection->verify_tfm); |
---|
| 2498 | + crypto_free_shash(connection->verify_tfm); |
---|
2481 | 2499 | connection->verify_tfm = crypto.verify_tfm; |
---|
2482 | 2500 | crypto.verify_tfm = NULL; |
---|
2483 | 2501 | } |
---|
2484 | 2502 | |
---|
2485 | | - crypto_free_ahash(connection->integrity_tfm); |
---|
| 2503 | + crypto_free_shash(connection->integrity_tfm); |
---|
2486 | 2504 | connection->integrity_tfm = crypto.integrity_tfm; |
---|
2487 | 2505 | if (connection->cstate >= C_WF_REPORT_PARAMS && connection->agreed_pro_version >= 100) |
---|
2488 | 2506 | /* Do this without trying to take connection->data.mutex again. */ |
---|
.. | .. |
---|
2671 | 2689 | } |
---|
2672 | 2690 | rcu_read_unlock(); |
---|
2673 | 2691 | |
---|
2674 | | - retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE); |
---|
| 2692 | + retcode = (enum drbd_ret_code)conn_request_state(connection, |
---|
| 2693 | + NS(conn, C_UNCONNECTED), CS_VERBOSE); |
---|
2675 | 2694 | |
---|
2676 | 2695 | conn_reconfig_done(connection); |
---|
2677 | 2696 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
---|
.. | .. |
---|
2691 | 2710 | |
---|
2692 | 2711 | static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection, bool force) |
---|
2693 | 2712 | { |
---|
| 2713 | + enum drbd_conns cstate; |
---|
2694 | 2714 | enum drbd_state_rv rv; |
---|
2695 | 2715 | |
---|
| 2716 | +repeat: |
---|
2696 | 2717 | rv = conn_request_state(connection, NS(conn, C_DISCONNECTING), |
---|
2697 | 2718 | force ? CS_HARD : 0); |
---|
2698 | 2719 | |
---|
.. | .. |
---|
2710 | 2731 | |
---|
2711 | 2732 | break; |
---|
2712 | 2733 | case SS_CW_FAILED_BY_PEER: |
---|
| 2734 | + spin_lock_irq(&connection->resource->req_lock); |
---|
| 2735 | + cstate = connection->cstate; |
---|
| 2736 | + spin_unlock_irq(&connection->resource->req_lock); |
---|
| 2737 | + if (cstate <= C_WF_CONNECTION) |
---|
| 2738 | + goto repeat; |
---|
2713 | 2739 | /* The peer probably wants to see us outdated. */ |
---|
2714 | 2740 | rv = conn_request_state(connection, NS2(conn, C_DISCONNECTING, |
---|
2715 | 2741 | disk, D_OUTDATED), 0); |
---|
.. | .. |
---|
2777 | 2803 | mutex_lock(&adm_ctx.resource->adm_mutex); |
---|
2778 | 2804 | rv = conn_try_disconnect(connection, parms.force_disconnect); |
---|
2779 | 2805 | if (rv < SS_SUCCESS) |
---|
2780 | | - retcode = rv; /* FIXME: Type mismatch. */ |
---|
| 2806 | + retcode = (enum drbd_ret_code)rv; |
---|
2781 | 2807 | else |
---|
2782 | 2808 | retcode = NO_ERROR; |
---|
2783 | 2809 | mutex_unlock(&adm_ctx.resource->adm_mutex); |
---|
.. | .. |
---|
3225 | 3251 | struct drbd_device *device) |
---|
3226 | 3252 | { |
---|
3227 | 3253 | struct nlattr *nla; |
---|
3228 | | - nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); |
---|
| 3254 | + nla = nla_nest_start_noflag(skb, DRBD_NLA_CFG_CONTEXT); |
---|
3229 | 3255 | if (!nla) |
---|
3230 | 3256 | goto nla_put_failure; |
---|
3231 | 3257 | if (device && |
---|
.. | .. |
---|
3338 | 3364 | if (get_ldev(device)) { |
---|
3339 | 3365 | struct drbd_md *md = &device->ldev->md; |
---|
3340 | 3366 | u64 *history_uuids = (u64 *)s->history_uuids; |
---|
3341 | | - struct request_queue *q; |
---|
3342 | 3367 | int n; |
---|
3343 | 3368 | |
---|
3344 | 3369 | spin_lock_irq(&md->uuid_lock); |
---|
.. | .. |
---|
3352 | 3377 | spin_unlock_irq(&md->uuid_lock); |
---|
3353 | 3378 | |
---|
3354 | 3379 | s->dev_disk_flags = md->flags; |
---|
3355 | | - q = bdev_get_queue(device->ldev->backing_bdev); |
---|
3356 | | - s->dev_lower_blocked = |
---|
3357 | | - bdi_congested(q->backing_dev_info, |
---|
3358 | | - (1 << WB_async_congested) | |
---|
3359 | | - (1 << WB_sync_congested)); |
---|
3360 | 3380 | put_ldev(device); |
---|
3361 | 3381 | } |
---|
3362 | | - s->dev_size = drbd_get_capacity(device->this_bdev); |
---|
| 3382 | + s->dev_size = get_capacity(device->vdisk); |
---|
3363 | 3383 | s->dev_read = device->read_cnt; |
---|
3364 | 3384 | s->dev_write = device->writ_cnt; |
---|
3365 | 3385 | s->dev_al_writes = device->al_writ_cnt; |
---|
.. | .. |
---|
3391 | 3411 | { |
---|
3392 | 3412 | struct nlattr *resource_filter; |
---|
3393 | 3413 | struct drbd_resource *resource; |
---|
3394 | | - struct drbd_device *uninitialized_var(device); |
---|
| 3414 | + struct drbd_device *device; |
---|
3395 | 3415 | int minor, err, retcode; |
---|
3396 | 3416 | struct drbd_genlmsghdr *dh; |
---|
3397 | 3417 | struct device_info device_info; |
---|
.. | .. |
---|
3480 | 3500 | { |
---|
3481 | 3501 | struct nlattr *resource_filter; |
---|
3482 | 3502 | struct drbd_resource *resource = NULL, *next_resource; |
---|
3483 | | - struct drbd_connection *uninitialized_var(connection); |
---|
| 3503 | + struct drbd_connection *connection; |
---|
3484 | 3504 | int err = 0, retcode; |
---|
3485 | 3505 | struct drbd_genlmsghdr *dh; |
---|
3486 | 3506 | struct connection_info connection_info; |
---|
.. | .. |
---|
3642 | 3662 | { |
---|
3643 | 3663 | struct nlattr *resource_filter; |
---|
3644 | 3664 | struct drbd_resource *resource; |
---|
3645 | | - struct drbd_device *uninitialized_var(device); |
---|
| 3665 | + struct drbd_device *device; |
---|
3646 | 3666 | struct drbd_peer_device *peer_device = NULL; |
---|
3647 | 3667 | int minor, err, retcode; |
---|
3648 | 3668 | struct drbd_genlmsghdr *dh; |
---|
.. | .. |
---|
3793 | 3813 | if (err) |
---|
3794 | 3814 | goto nla_put_failure; |
---|
3795 | 3815 | |
---|
3796 | | - nla = nla_nest_start(skb, DRBD_NLA_STATE_INFO); |
---|
| 3816 | + nla = nla_nest_start_noflag(skb, DRBD_NLA_STATE_INFO); |
---|
3797 | 3817 | if (!nla) |
---|
3798 | 3818 | goto nla_put_failure; |
---|
3799 | 3819 | if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) || |
---|
3800 | 3820 | nla_put_u32(skb, T_current_state, device->state.i) || |
---|
3801 | 3821 | nla_put_u64_0pad(skb, T_ed_uuid, device->ed_uuid) || |
---|
3802 | | - nla_put_u64_0pad(skb, T_capacity, |
---|
3803 | | - drbd_get_capacity(device->this_bdev)) || |
---|
| 3822 | + nla_put_u64_0pad(skb, T_capacity, get_capacity(device->vdisk)) || |
---|
3804 | 3823 | nla_put_u64_0pad(skb, T_send_cnt, device->send_cnt) || |
---|
3805 | 3824 | nla_put_u64_0pad(skb, T_recv_cnt, device->recv_cnt) || |
---|
3806 | 3825 | nla_put_u64_0pad(skb, T_read_cnt, device->read_cnt) || |
---|
.. | .. |
---|
3851 | 3870 | if (nla_put_u32(skb, T_helper_exit_code, |
---|
3852 | 3871 | sib->helper_exit_code)) |
---|
3853 | 3872 | goto nla_put_failure; |
---|
3854 | | - /* fall through */ |
---|
| 3873 | + fallthrough; |
---|
3855 | 3874 | case SIB_HELPER_PRE: |
---|
3856 | 3875 | if (nla_put_string(skb, T_helper, sib->helper_name)) |
---|
3857 | 3876 | goto nla_put_failure; |
---|
.. | .. |
---|
4598 | 4617 | return drbd_notification_header_to_skb(msg, &nh, true); |
---|
4599 | 4618 | } |
---|
4600 | 4619 | |
---|
4601 | | -void notify_resource_state(struct sk_buff *skb, |
---|
| 4620 | +int notify_resource_state(struct sk_buff *skb, |
---|
4602 | 4621 | unsigned int seq, |
---|
4603 | 4622 | struct drbd_resource *resource, |
---|
4604 | 4623 | struct resource_info *resource_info, |
---|
.. | .. |
---|
4640 | 4659 | if (err && err != -ESRCH) |
---|
4641 | 4660 | goto failed; |
---|
4642 | 4661 | } |
---|
4643 | | - return; |
---|
| 4662 | + return 0; |
---|
4644 | 4663 | |
---|
4645 | 4664 | nla_put_failure: |
---|
4646 | 4665 | nlmsg_free(skb); |
---|
4647 | 4666 | failed: |
---|
4648 | 4667 | drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n", |
---|
4649 | 4668 | err, seq); |
---|
| 4669 | + return err; |
---|
4650 | 4670 | } |
---|
4651 | 4671 | |
---|
4652 | | -void notify_device_state(struct sk_buff *skb, |
---|
| 4672 | +int notify_device_state(struct sk_buff *skb, |
---|
4653 | 4673 | unsigned int seq, |
---|
4654 | 4674 | struct drbd_device *device, |
---|
4655 | 4675 | struct device_info *device_info, |
---|
.. | .. |
---|
4689 | 4709 | if (err && err != -ESRCH) |
---|
4690 | 4710 | goto failed; |
---|
4691 | 4711 | } |
---|
4692 | | - return; |
---|
| 4712 | + return 0; |
---|
4693 | 4713 | |
---|
4694 | 4714 | nla_put_failure: |
---|
4695 | 4715 | nlmsg_free(skb); |
---|
4696 | 4716 | failed: |
---|
4697 | 4717 | drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n", |
---|
4698 | 4718 | err, seq); |
---|
| 4719 | + return err; |
---|
4699 | 4720 | } |
---|
4700 | 4721 | |
---|
4701 | | -void notify_connection_state(struct sk_buff *skb, |
---|
| 4722 | +int notify_connection_state(struct sk_buff *skb, |
---|
4702 | 4723 | unsigned int seq, |
---|
4703 | 4724 | struct drbd_connection *connection, |
---|
4704 | 4725 | struct connection_info *connection_info, |
---|
.. | .. |
---|
4738 | 4759 | if (err && err != -ESRCH) |
---|
4739 | 4760 | goto failed; |
---|
4740 | 4761 | } |
---|
4741 | | - return; |
---|
| 4762 | + return 0; |
---|
4742 | 4763 | |
---|
4743 | 4764 | nla_put_failure: |
---|
4744 | 4765 | nlmsg_free(skb); |
---|
4745 | 4766 | failed: |
---|
4746 | 4767 | drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n", |
---|
4747 | 4768 | err, seq); |
---|
| 4769 | + return err; |
---|
4748 | 4770 | } |
---|
4749 | 4771 | |
---|
4750 | | -void notify_peer_device_state(struct sk_buff *skb, |
---|
| 4772 | +int notify_peer_device_state(struct sk_buff *skb, |
---|
4751 | 4773 | unsigned int seq, |
---|
4752 | 4774 | struct drbd_peer_device *peer_device, |
---|
4753 | 4775 | struct peer_device_info *peer_device_info, |
---|
.. | .. |
---|
4788 | 4810 | if (err && err != -ESRCH) |
---|
4789 | 4811 | goto failed; |
---|
4790 | 4812 | } |
---|
4791 | | - return; |
---|
| 4813 | + return 0; |
---|
4792 | 4814 | |
---|
4793 | 4815 | nla_put_failure: |
---|
4794 | 4816 | nlmsg_free(skb); |
---|
4795 | 4817 | failed: |
---|
4796 | 4818 | drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n", |
---|
4797 | 4819 | err, seq); |
---|
| 4820 | + return err; |
---|
4798 | 4821 | } |
---|
4799 | 4822 | |
---|
4800 | 4823 | void notify_helper(enum drbd_notification_type type, |
---|
.. | .. |
---|
4845 | 4868 | err, seq); |
---|
4846 | 4869 | } |
---|
4847 | 4870 | |
---|
4848 | | -static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) |
---|
| 4871 | +static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq) |
---|
4849 | 4872 | { |
---|
4850 | 4873 | struct drbd_genlmsghdr *dh; |
---|
4851 | 4874 | int err; |
---|
.. | .. |
---|
4859 | 4882 | if (nla_put_notification_header(skb, NOTIFY_EXISTS)) |
---|
4860 | 4883 | goto nla_put_failure; |
---|
4861 | 4884 | genlmsg_end(skb, dh); |
---|
4862 | | - return; |
---|
| 4885 | + return 0; |
---|
4863 | 4886 | |
---|
4864 | 4887 | nla_put_failure: |
---|
4865 | 4888 | nlmsg_free(skb); |
---|
4866 | 4889 | pr_err("Error %d sending event. Event seq:%u\n", err, seq); |
---|
| 4890 | + return err; |
---|
4867 | 4891 | } |
---|
4868 | 4892 | |
---|
4869 | 4893 | static void free_state_changes(struct list_head *list) |
---|
.. | .. |
---|
4890 | 4914 | unsigned int seq = cb->args[2]; |
---|
4891 | 4915 | unsigned int n; |
---|
4892 | 4916 | enum drbd_notification_type flags = 0; |
---|
| 4917 | + int err = 0; |
---|
4893 | 4918 | |
---|
4894 | 4919 | /* There is no need for taking notification_mutex here: it doesn't |
---|
4895 | 4920 | matter if the initial state events mix with later state chage |
---|
.. | .. |
---|
4898 | 4923 | |
---|
4899 | 4924 | cb->args[5]--; |
---|
4900 | 4925 | if (cb->args[5] == 1) { |
---|
4901 | | - notify_initial_state_done(skb, seq); |
---|
| 4926 | + err = notify_initial_state_done(skb, seq); |
---|
4902 | 4927 | goto out; |
---|
4903 | 4928 | } |
---|
4904 | 4929 | n = cb->args[4]++; |
---|
4905 | 4930 | if (cb->args[4] < cb->args[3]) |
---|
4906 | 4931 | flags |= NOTIFY_CONTINUES; |
---|
4907 | 4932 | if (n < 1) { |
---|
4908 | | - notify_resource_state_change(skb, seq, state_change->resource, |
---|
| 4933 | + err = notify_resource_state_change(skb, seq, state_change->resource, |
---|
4909 | 4934 | NOTIFY_EXISTS | flags); |
---|
4910 | 4935 | goto next; |
---|
4911 | 4936 | } |
---|
4912 | 4937 | n--; |
---|
4913 | 4938 | if (n < state_change->n_connections) { |
---|
4914 | | - notify_connection_state_change(skb, seq, &state_change->connections[n], |
---|
| 4939 | + err = notify_connection_state_change(skb, seq, &state_change->connections[n], |
---|
4915 | 4940 | NOTIFY_EXISTS | flags); |
---|
4916 | 4941 | goto next; |
---|
4917 | 4942 | } |
---|
4918 | 4943 | n -= state_change->n_connections; |
---|
4919 | 4944 | if (n < state_change->n_devices) { |
---|
4920 | | - notify_device_state_change(skb, seq, &state_change->devices[n], |
---|
| 4945 | + err = notify_device_state_change(skb, seq, &state_change->devices[n], |
---|
4921 | 4946 | NOTIFY_EXISTS | flags); |
---|
4922 | 4947 | goto next; |
---|
4923 | 4948 | } |
---|
4924 | 4949 | n -= state_change->n_devices; |
---|
4925 | 4950 | if (n < state_change->n_devices * state_change->n_connections) { |
---|
4926 | | - notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], |
---|
| 4951 | + err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], |
---|
4927 | 4952 | NOTIFY_EXISTS | flags); |
---|
4928 | 4953 | goto next; |
---|
4929 | 4954 | } |
---|
.. | .. |
---|
4938 | 4963 | cb->args[4] = 0; |
---|
4939 | 4964 | } |
---|
4940 | 4965 | out: |
---|
4941 | | - return skb->len; |
---|
| 4966 | + if (err) |
---|
| 4967 | + return err; |
---|
| 4968 | + else |
---|
| 4969 | + return skb->len; |
---|
4942 | 4970 | } |
---|
4943 | 4971 | |
---|
4944 | 4972 | int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) |
---|