drbd_nl.c 99.7 KB
Newer Older
P
Philipp Reisner 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
   drbd_nl.c

   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.

   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.

   drbd is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   drbd is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with drbd; see the file COPYING.  If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

 */

#include <linux/module.h>
#include <linux/drbd.h>
#include <linux/in.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/blkpg.h>
#include <linux/cpumask.h>
#include "drbd_int.h"
35
#include "drbd_protocol.h"
36
#include "drbd_req.h"
P
Philipp Reisner 已提交
37 38 39
#include "drbd_wrappers.h"
#include <asm/unaligned.h>
#include <linux/drbd_limits.h>
40
#include <linux/kthread.h>
P
Philipp Reisner 已提交
41

42 43 44 45 46 47
#include <net/genetlink.h>

/* .doit */
// int drbd_adm_create_resource(struct sk_buff *skb, struct genl_info *info);
// int drbd_adm_delete_resource(struct sk_buff *skb, struct genl_info *info);

48 49
int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info);
50

51 52
int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info);
53
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info);
54 55 56

int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info);
57
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info);
58 59
int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info);
60
int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info);
61 62 63 64 65 66 67 68 69 70 71
int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info);
72
int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info);
73 74 75 76 77 78
int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info);
/* .dumpit */
int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb);

#include <linux/drbd_genl_api.h>
79
#include "drbd_nla.h"
80 81 82
#include <linux/genl_magic_func.h>

/* used blkdev_get_by_path, to claim our meta data device(s) */
P
Philipp Reisner 已提交
83 84
static char *drbd_m_holder = "Hands off! this is DRBD's meta data device.";

85 86 87 88 89 90 91 92 93 94 95 96
/* Configuration is strictly serialized, because generic netlink message
 * processing is strictly serialized by the genl_lock().
 * Which means we can use one static global drbd_config_context struct.
 */
static struct drbd_config_context {
	/* assigned from drbd_genlmsghdr */
	unsigned int minor;
	/* assigned from request attributes, if present */
	unsigned int volume;
#define VOLUME_UNSPECIFIED		(-1U)
	/* pointer into the request skb,
	 * limited lifetime! */
97
	char *resource_name;
98 99
	struct nlattr *my_addr;
	struct nlattr *peer_addr;
100 101 102 103 104 105

	/* reply buffer */
	struct sk_buff *reply_skb;
	/* pointer into reply buffer */
	struct drbd_genlmsghdr *reply_dh;
	/* resolved from attributes, if possible */
106
	struct drbd_device *device;
107
	struct drbd_resource *resource;
108
	struct drbd_connection *connection;
109 110 111 112 113 114 115
} adm_ctx;

static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info)
{
	genlmsg_end(skb, genlmsg_data(nlmsg_data(nlmsg_hdr(skb))));
	if (genlmsg_reply(skb, info))
		printk(KERN_ERR "drbd: error sending genl reply\n");
P
Philipp Reisner 已提交
116
}
117 118 119

/* Used on a fresh "drbd_adm_prepare"d reply_skb, this cannot fail: The only
 * reason it could fail was no space in skb, and there are 4k available. */
120
int drbd_msg_put_info(const char *info)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
{
	struct sk_buff *skb = adm_ctx.reply_skb;
	struct nlattr *nla;
	int err = -EMSGSIZE;

	if (!info || !info[0])
		return 0;

	nla = nla_nest_start(skb, DRBD_NLA_CFG_REPLY);
	if (!nla)
		return err;

	err = nla_put_string(skb, T_info_text, info);
	if (err) {
		nla_nest_cancel(skb, nla);
		return err;
	} else
		nla_nest_end(skb, nla);
	return 0;
P
Philipp Reisner 已提交
140 141
}

142 143 144 145 146 147
/* This would be a good candidate for a "pre_doit" hook,
 * and per-family private info->pointers.
 * But we need to stay compatible with older kernels.
 * If it returns successfully, adm_ctx members are valid.
 */
#define DRBD_ADM_NEED_MINOR	1
148
#define DRBD_ADM_NEED_RESOURCE	2
149
#define DRBD_ADM_NEED_CONNECTION 4
150 151 152 153 154 155 156 157 158 159
static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info,
		unsigned flags)
{
	struct drbd_genlmsghdr *d_in = info->userhdr;
	const u8 cmd = info->genlhdr->cmd;
	int err;

	memset(&adm_ctx, 0, sizeof(adm_ctx));

	/* genl_rcv_msg only checks for CAP_NET_ADMIN on "GENL_ADMIN_PERM" :( */
160
	if (cmd != DRBD_ADM_GET_STATUS && !capable(CAP_NET_ADMIN))
161 162 163
	       return -EPERM;

	adm_ctx.reply_skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
164 165
	if (!adm_ctx.reply_skb) {
		err = -ENOMEM;
166
		goto fail;
167
	}
168 169 170 171 172

	adm_ctx.reply_dh = genlmsg_put_reply(adm_ctx.reply_skb,
					info, &drbd_genl_family, 0, cmd);
	/* put of a few bytes into a fresh skb of >= 4k will always succeed.
	 * but anyways */
173 174
	if (!adm_ctx.reply_dh) {
		err = -ENOMEM;
175
		goto fail;
176
	}
177 178 179 180

	adm_ctx.reply_dh->minor = d_in->minor;
	adm_ctx.reply_dh->ret_code = NO_ERROR;

181
	adm_ctx.volume = VOLUME_UNSPECIFIED;
182 183 184
	if (info->attrs[DRBD_NLA_CFG_CONTEXT]) {
		struct nlattr *nla;
		/* parse and validate only */
185
		err = drbd_cfg_context_from_attrs(NULL, info);
186 187 188 189 190 191 192 193 194 195 196 197 198
		if (err)
			goto fail;

		/* It was present, and valid,
		 * copy it over to the reply skb. */
		err = nla_put_nohdr(adm_ctx.reply_skb,
				info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len,
				info->attrs[DRBD_NLA_CFG_CONTEXT]);
		if (err)
			goto fail;

		/* and assign stuff to the global adm_ctx */
		nla = nested_attr_tb[__nla_type(T_ctx_volume)];
199 200
		if (nla)
			adm_ctx.volume = nla_get_u32(nla);
201
		nla = nested_attr_tb[__nla_type(T_ctx_resource_name)];
202
		if (nla)
203
			adm_ctx.resource_name = nla_data(nla);
204 205 206
		adm_ctx.my_addr = nested_attr_tb[__nla_type(T_ctx_my_addr)];
		adm_ctx.peer_addr = nested_attr_tb[__nla_type(T_ctx_peer_addr)];
		if ((adm_ctx.my_addr &&
207
		     nla_len(adm_ctx.my_addr) > sizeof(adm_ctx.connection->my_addr)) ||
208
		    (adm_ctx.peer_addr &&
209
		     nla_len(adm_ctx.peer_addr) > sizeof(adm_ctx.connection->peer_addr))) {
210 211 212 213
			err = -EINVAL;
			goto fail;
		}
	}
214 215

	adm_ctx.minor = d_in->minor;
216
	adm_ctx.device = minor_to_device(d_in->minor);
217 218 219 220 221 222 223
	if (adm_ctx.resource_name) {
		adm_ctx.resource = drbd_find_resource(adm_ctx.resource_name);
		if (adm_ctx.resource) {
			adm_ctx.connection = first_connection(adm_ctx.resource);
			kref_get(&adm_ctx.connection->kref);
		}
	}
224

225
	if (!adm_ctx.device && (flags & DRBD_ADM_NEED_MINOR)) {
226 227 228
		drbd_msg_put_info("unknown minor");
		return ERR_MINOR_INVALID;
	}
229
	if (!adm_ctx.resource && (flags & DRBD_ADM_NEED_RESOURCE)) {
230
		drbd_msg_put_info("unknown resource");
231 232
		if (adm_ctx.resource_name)
			return ERR_RES_NOT_KNOWN;
233 234 235
		return ERR_INVALID_REQUEST;
	}

236
	if (flags & DRBD_ADM_NEED_CONNECTION) {
237
		if (adm_ctx.connection && !(flags & DRBD_ADM_NEED_RESOURCE)) {
238 239 240
			drbd_msg_put_info("no resource name expected");
			return ERR_INVALID_REQUEST;
		}
241
		if (adm_ctx.device) {
242 243 244 245
			drbd_msg_put_info("no minor number expected");
			return ERR_INVALID_REQUEST;
		}
		if (adm_ctx.my_addr && adm_ctx.peer_addr)
246
			adm_ctx.connection = conn_get_by_addrs(nla_data(adm_ctx.my_addr),
247 248 249
							  nla_len(adm_ctx.my_addr),
							  nla_data(adm_ctx.peer_addr),
							  nla_len(adm_ctx.peer_addr));
250
		if (!adm_ctx.connection) {
251 252 253 254 255
			drbd_msg_put_info("unknown connection");
			return ERR_INVALID_REQUEST;
		}
	}

256
	/* some more paranoia, if the request was over-determined */
257 258 259 260
	if (adm_ctx.device && adm_ctx.resource &&
	    adm_ctx.device->resource != adm_ctx.resource) {
		pr_warning("request: minor=%u, resource=%s; but that minor belongs to resource %s\n",
				adm_ctx.minor, adm_ctx.resource->name,
261
				adm_ctx.device->resource->name);
262
		drbd_msg_put_info("minor exists in different resource");
263 264
		return ERR_INVALID_REQUEST;
	}
265
	if (adm_ctx.device &&
266
	    adm_ctx.volume != VOLUME_UNSPECIFIED &&
267
	    adm_ctx.volume != adm_ctx.device->vnr) {
268 269
		pr_warning("request: minor=%u, volume=%u; but that minor is volume %u in %s\n",
				adm_ctx.minor, adm_ctx.volume,
270
				adm_ctx.device->vnr,
271
				adm_ctx.device->resource->name);
272
		drbd_msg_put_info("minor exists as different volume");
273 274
		return ERR_INVALID_REQUEST;
	}
275

276 277 278 279 280
	return NO_ERROR;

fail:
	nlmsg_free(adm_ctx.reply_skb);
	adm_ctx.reply_skb = NULL;
281
	return err;
282 283 284 285
}

static int drbd_adm_finish(struct genl_info *info, int retcode)
{
286
	if (adm_ctx.connection) {
287
		kref_put(&adm_ctx.connection->kref, drbd_destroy_connection);
288
		adm_ctx.connection = NULL;
289
	}
290 291 292 293
	if (adm_ctx.resource) {
		kref_put(&adm_ctx.resource->kref, drbd_destroy_resource);
		adm_ctx.resource = NULL;
	}
294

295 296 297 298 299 300 301
	if (!adm_ctx.reply_skb)
		return -ENOMEM;

	adm_ctx.reply_dh->ret_code = retcode;
	drbd_adm_send_reply(adm_ctx.reply_skb, info);
	return 0;
}
P
Philipp Reisner 已提交
302

303
static void setup_khelper_env(struct drbd_connection *connection, char **envp)
P
Philipp Reisner 已提交
304
{
305
	char *afs;
P
Philipp Reisner 已提交
306

307
	/* FIXME: A future version will not allow this case. */
308
	if (connection->my_addr_len == 0 || connection->peer_addr_len == 0)
309 310
		return;

311
	switch (((struct sockaddr *)&connection->peer_addr)->sa_family) {
312 313 314
	case AF_INET6:
		afs = "ipv6";
		snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI6",
315
			 &((struct sockaddr_in6 *)&connection->peer_addr)->sin6_addr);
P
Philipp Reisner 已提交
316
		break;
317 318 319
	case AF_INET:
		afs = "ipv4";
		snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4",
320
			 &((struct sockaddr_in *)&connection->peer_addr)->sin_addr);
P
Philipp Reisner 已提交
321
		break;
322 323 324
	default:
		afs = "ssocks";
		snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4",
325
			 &((struct sockaddr_in *)&connection->peer_addr)->sin_addr);
P
Philipp Reisner 已提交
326
	}
327
	snprintf(envp[3], 20, "DRBD_PEER_AF=%s", afs);
328
}
P
Philipp Reisner 已提交
329

330
int drbd_khelper(struct drbd_device *device, char *cmd)
P
Philipp Reisner 已提交
331 332 333 334
{
	char *envp[] = { "HOME=/",
			"TERM=linux",
			"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
335 336
			 (char[20]) { }, /* address family */
			 (char[60]) { }, /* address */
P
Philipp Reisner 已提交
337
			NULL };
338
	char mb[12];
P
Philipp Reisner 已提交
339
	char *argv[] = {usermode_helper, cmd, mb, NULL };
340
	struct drbd_connection *connection = first_peer_device(device)->connection;
341
	struct sib_info sib;
P
Philipp Reisner 已提交
342 343
	int ret;

344 345
	if (current == connection->worker.task)
		set_bit(CALLBACK_PENDING, &connection->flags);
346

347
	snprintf(mb, 12, "minor-%d", device_to_minor(device));
348
	setup_khelper_env(connection, envp);
P
Philipp Reisner 已提交
349

350 351
	/* The helper may take some time.
	 * write out any unsynced meta data changes now */
352
	drbd_md_sync(device);
353

354
	drbd_info(device, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
355 356
	sib.sib_reason = SIB_HELPER_PRE;
	sib.helper_name = cmd;
357
	drbd_bcast_event(device, &sib);
358
	ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
P
Philipp Reisner 已提交
359
	if (ret)
360
		drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
P
Philipp Reisner 已提交
361 362 363
				usermode_helper, cmd, mb,
				(ret >> 8) & 0xff, ret);
	else
364
		drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n",
P
Philipp Reisner 已提交
365 366
				usermode_helper, cmd, mb,
				(ret >> 8) & 0xff, ret);
367 368
	sib.sib_reason = SIB_HELPER_POST;
	sib.helper_exit_code = ret;
369
	drbd_bcast_event(device, &sib);
P
Philipp Reisner 已提交
370

371 372
	if (current == connection->worker.task)
		clear_bit(CALLBACK_PENDING, &connection->flags);
P
Philipp Reisner 已提交
373 374 375 376 377 378 379

	if (ret < 0) /* Ignore any ERRNOs we got. */
		ret = 0;

	return ret;
}

380
static int conn_khelper(struct drbd_connection *connection, char *cmd)
381 382 383 384 385 386 387
{
	char *envp[] = { "HOME=/",
			"TERM=linux",
			"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
			 (char[20]) { }, /* address family */
			 (char[60]) { }, /* address */
			NULL };
388 389
	char *resource_name = connection->resource->name;
	char *argv[] = {usermode_helper, cmd, resource_name, NULL };
390 391
	int ret;

392 393
	setup_khelper_env(connection, envp);
	conn_md_sync(connection);
394

395
	drbd_info(connection, "helper command: %s %s %s\n", usermode_helper, cmd, resource_name);
396 397
	/* TODO: conn_bcast_event() ?? */

398
	ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
399
	if (ret)
400
		drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
401
			  usermode_helper, cmd, resource_name,
402 403
			  (ret >> 8) & 0xff, ret);
	else
404
		drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
405
			  usermode_helper, cmd, resource_name,
406 407
			  (ret >> 8) & 0xff, ret);
	/* TODO: conn_bcast_event() ?? */
408

P
Philipp Reisner 已提交
409 410 411 412 413 414
	if (ret < 0) /* Ignore any ERRNOs we got. */
		ret = 0;

	return ret;
}

415
static enum drbd_fencing_p highest_fencing_policy(struct drbd_connection *connection)
P
Philipp Reisner 已提交
416
{
417
	enum drbd_fencing_p fp = FP_NOT_AVAIL;
418
	struct drbd_peer_device *peer_device;
419 420
	int vnr;

421
	rcu_read_lock();
422 423
	idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
		struct drbd_device *device = peer_device->device;
424
		if (get_ldev_if_state(device, D_CONSISTENT)) {
425 426 427
			struct disk_conf *disk_conf =
				rcu_dereference(peer_device->device->ldev->disk_conf);
			fp = max_t(enum drbd_fencing_p, fp, disk_conf->fencing);
428
			put_ldev(device);
429 430
		}
	}
431
	rcu_read_unlock();
432 433 434 435

	return fp;
}

436
bool conn_try_outdate_peer(struct drbd_connection *connection)
P
Philipp Reisner 已提交
437
{
438
	unsigned int connect_cnt;
439 440 441
	union drbd_state mask = { };
	union drbd_state val = { };
	enum drbd_fencing_p fp;
P
Philipp Reisner 已提交
442 443 444
	char *ex_to_string;
	int r;

445
	if (connection->cstate >= C_WF_REPORT_PARAMS) {
446
		drbd_err(connection, "Expected cstate < C_WF_REPORT_PARAMS\n");
447 448
		return false;
	}
P
Philipp Reisner 已提交
449

450 451 452
	spin_lock_irq(&connection->req_lock);
	connect_cnt = connection->connect_cnt;
	spin_unlock_irq(&connection->req_lock);
453

454
	fp = highest_fencing_policy(connection);
455 456
	switch (fp) {
	case FP_NOT_AVAIL:
457
		drbd_warn(connection, "Not fencing peer, I'm not even Consistent myself.\n");
458
		goto out;
459 460 461
	case FP_DONT_CARE:
		return true;
	default: ;
P
Philipp Reisner 已提交
462 463
	}

464
	r = conn_khelper(connection, "fence-peer");
P
Philipp Reisner 已提交
465 466 467 468

	switch ((r>>8) & 0xff) {
	case 3: /* peer is inconsistent */
		ex_to_string = "peer is inconsistent or worse";
469 470
		mask.pdsk = D_MASK;
		val.pdsk = D_INCONSISTENT;
P
Philipp Reisner 已提交
471 472 473
		break;
	case 4: /* peer got outdated, or was already outdated */
		ex_to_string = "peer was fenced";
474 475
		mask.pdsk = D_MASK;
		val.pdsk = D_OUTDATED;
P
Philipp Reisner 已提交
476 477
		break;
	case 5: /* peer was down */
478
		if (conn_highest_disk(connection) == D_UP_TO_DATE) {
P
Philipp Reisner 已提交
479 480
			/* we will(have) create(d) a new UUID anyways... */
			ex_to_string = "peer is unreachable, assumed to be dead";
481 482
			mask.pdsk = D_MASK;
			val.pdsk = D_OUTDATED;
P
Philipp Reisner 已提交
483 484 485 486 487 488 489 490
		} else {
			ex_to_string = "peer unreachable, doing nothing since disk != UpToDate";
		}
		break;
	case 6: /* Peer is primary, voluntarily outdate myself.
		 * This is useful when an unconnected R_SECONDARY is asked to
		 * become R_PRIMARY, but finds the other peer being active. */
		ex_to_string = "peer is active";
491
		drbd_warn(connection, "Peer is primary, outdating myself.\n");
492 493
		mask.disk = D_MASK;
		val.disk = D_OUTDATED;
P
Philipp Reisner 已提交
494 495 496
		break;
	case 7:
		if (fp != FP_STONITH)
497
			drbd_err(connection, "fence-peer() = 7 && fencing != Stonith !!!\n");
P
Philipp Reisner 已提交
498
		ex_to_string = "peer was stonithed";
499 500
		mask.pdsk = D_MASK;
		val.pdsk = D_OUTDATED;
P
Philipp Reisner 已提交
501 502 503
		break;
	default:
		/* The script is broken ... */
504
		drbd_err(connection, "fence-peer helper broken, returned %d\n", (r>>8)&0xff);
505
		return false; /* Eventually leave IO frozen */
P
Philipp Reisner 已提交
506 507
	}

508
	drbd_info(connection, "fence-peer helper returned %d (%s)\n",
509
		  (r>>8) & 0xff, ex_to_string);
510

511
 out:
512

513
	/* Not using
514
	   conn_request_state(connection, mask, val, CS_VERBOSE);
515 516
	   here, because we might were able to re-establish the connection in the
	   meantime. */
517 518 519
	spin_lock_irq(&connection->req_lock);
	if (connection->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &connection->flags)) {
		if (connection->connect_cnt != connect_cnt)
520 521
			/* In case the connection was established and droped
			   while the fence-peer handler was running, ignore it */
522
			drbd_info(connection, "Ignoring fence-peer exit code\n");
523
		else
524
			_conn_request_state(connection, mask, val, CS_VERBOSE);
525
	}
526
	spin_unlock_irq(&connection->req_lock);
527

528
	return conn_highest_pdsk(connection) <= D_OUTDATED;
P
Philipp Reisner 已提交
529 530
}

531 532
static int _try_outdate_peer_async(void *data)
{
533
	struct drbd_connection *connection = (struct drbd_connection *)data;
534

535
	conn_try_outdate_peer(connection);
536

537
	kref_put(&connection->kref, drbd_destroy_connection);
538 539 540
	return 0;
}

541
void conn_try_outdate_peer_async(struct drbd_connection *connection)
542 543 544
{
	struct task_struct *opa;

545 546
	kref_get(&connection->kref);
	opa = kthread_run(_try_outdate_peer_async, connection, "drbd_async_h");
547
	if (IS_ERR(opa)) {
548
		drbd_err(connection, "out of mem, failed to invoke fence-peer helper\n");
549
		kref_put(&connection->kref, drbd_destroy_connection);
550
	}
551
}
P
Philipp Reisner 已提交
552

553
enum drbd_state_rv
554
drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
P
Philipp Reisner 已提交
555 556
{
	const int max_tries = 4;
557
	enum drbd_state_rv rv = SS_UNKNOWN_ERROR;
558
	struct net_conf *nc;
P
Philipp Reisner 已提交
559 560 561 562 563
	int try = 0;
	int forced = 0;
	union drbd_state mask, val;

	if (new_role == R_PRIMARY)
564
		request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */
P
Philipp Reisner 已提交
565

566
	mutex_lock(device->state_mutex);
P
Philipp Reisner 已提交
567 568 569 570 571

	mask.i = 0; mask.role = R_MASK;
	val.i  = 0; val.role  = new_role;

	while (try++ < max_tries) {
572
		rv = _drbd_request_state(device, mask, val, CS_WAIT_COMPLETE);
P
Philipp Reisner 已提交
573 574 575

		/* in case we first succeeded to outdate,
		 * but now suddenly could establish a connection */
576
		if (rv == SS_CW_FAILED_BY_PEER && mask.pdsk != 0) {
P
Philipp Reisner 已提交
577 578 579 580 581
			val.pdsk = 0;
			mask.pdsk = 0;
			continue;
		}

582
		if (rv == SS_NO_UP_TO_DATE_DISK && force &&
583 584
		    (device->state.disk < D_UP_TO_DATE &&
		     device->state.disk >= D_INCONSISTENT)) {
P
Philipp Reisner 已提交
585 586 587 588 589 590
			mask.disk = D_MASK;
			val.disk  = D_UP_TO_DATE;
			forced = 1;
			continue;
		}

591
		if (rv == SS_NO_UP_TO_DATE_DISK &&
592 593
		    device->state.disk == D_CONSISTENT && mask.pdsk == 0) {
			D_ASSERT(device->state.pdsk == D_UNKNOWN);
P
Philipp Reisner 已提交
594

595
			if (conn_try_outdate_peer(first_peer_device(device)->connection)) {
P
Philipp Reisner 已提交
596 597 598 599 600 601
				val.disk = D_UP_TO_DATE;
				mask.disk = D_MASK;
			}
			continue;
		}

602
		if (rv == SS_NOTHING_TO_DO)
603
			goto out;
604
		if (rv == SS_PRIMARY_NOP && mask.pdsk == 0) {
605
			if (!conn_try_outdate_peer(first_peer_device(device)->connection) && force) {
606
				drbd_warn(device, "Forced into split brain situation!\n");
607 608
				mask.pdsk = D_MASK;
				val.pdsk  = D_OUTDATED;
P
Philipp Reisner 已提交
609

610
			}
P
Philipp Reisner 已提交
611 612
			continue;
		}
613
		if (rv == SS_TWO_PRIMARIES) {
P
Philipp Reisner 已提交
614 615
			/* Maybe the peer is detected as dead very soon...
			   retry at most once more in this case. */
616 617
			int timeo;
			rcu_read_lock();
618
			nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
619 620 621
			timeo = nc ? (nc->ping_timeo + 1) * HZ / 10 : 1;
			rcu_read_unlock();
			schedule_timeout_interruptible(timeo);
P
Philipp Reisner 已提交
622 623 624 625
			if (try < max_tries)
				try = max_tries - 1;
			continue;
		}
626
		if (rv < SS_SUCCESS) {
627
			rv = _drbd_request_state(device, mask, val,
P
Philipp Reisner 已提交
628
						CS_VERBOSE + CS_WAIT_COMPLETE);
629
			if (rv < SS_SUCCESS)
630
				goto out;
P
Philipp Reisner 已提交
631 632 633 634
		}
		break;
	}

635
	if (rv < SS_SUCCESS)
636
		goto out;
P
Philipp Reisner 已提交
637 638

	if (forced)
639
		drbd_warn(device, "Forced to consider local data as UpToDate!\n");
P
Philipp Reisner 已提交
640 641

	/* Wait until nothing is on the fly :) */
642
	wait_event(device->misc_wait, atomic_read(&device->ap_pending_cnt) == 0);
P
Philipp Reisner 已提交
643

644 645
	/* FIXME also wait for all pending P_BARRIER_ACK? */

P
Philipp Reisner 已提交
646
	if (new_role == R_SECONDARY) {
647 648 649 650
		set_disk_ro(device->vdisk, true);
		if (get_ldev(device)) {
			device->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
			put_ldev(device);
P
Philipp Reisner 已提交
651 652
		}
	} else {
653 654
		mutex_lock(&first_peer_device(device)->connection->conf_update);
		nc = first_peer_device(device)->connection->net_conf;
655
		if (nc)
656
			nc->discard_my_data = 0; /* without copy; single bit op is atomic */
657
		mutex_unlock(&first_peer_device(device)->connection->conf_update);
658

659 660 661 662 663 664
		set_disk_ro(device->vdisk, false);
		if (get_ldev(device)) {
			if (((device->state.conn < C_CONNECTED ||
			       device->state.pdsk <= D_FAILED)
			      && device->ldev->md.uuid[UI_BITMAP] == 0) || forced)
				drbd_uuid_new_current(device);
P
Philipp Reisner 已提交
665

666 667
			device->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
			put_ldev(device);
P
Philipp Reisner 已提交
668 669 670
		}
	}

671 672
	/* writeout of activity log covered areas of the bitmap
	 * to stable storage done in after state change already */
P
Philipp Reisner 已提交
673

674
	if (device->state.conn >= C_WF_REPORT_PARAMS) {
P
Philipp Reisner 已提交
675 676
		/* if this was forced, we should consider sync */
		if (forced)
677 678
			drbd_send_uuids(device);
		drbd_send_current_state(device);
P
Philipp Reisner 已提交
679 680
	}

681
	drbd_md_sync(device);
P
Philipp Reisner 已提交
682

683
	kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE);
684
out:
685
	mutex_unlock(device->state_mutex);
686
	return rv;
P
Philipp Reisner 已提交
687 688
}

689
static const char *from_attrs_err_to_txt(int err)
690
{
691 692
	return	err == -ENOMSG ? "required attribute missing" :
		err == -EOPNOTSUPP ? "unknown mandatory attribute" :
693
		err == -EEXIST ? "can not change invariant setting" :
694
		"invalid attribute value";
695
}
P
Philipp Reisner 已提交
696

697
int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
698
{
699 700 701
	struct set_role_parms parms;
	int err;
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
702

703 704 705 706 707
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
708

709 710
	memset(&parms, 0, sizeof(parms));
	if (info->attrs[DRBD_NLA_SET_ROLE_PARMS]) {
711
		err = set_role_parms_from_attrs(&parms, info);
712 713 714 715 716 717
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
			goto out;
		}
	}
P
Philipp Reisner 已提交
718

719
	if (info->genlhdr->cmd == DRBD_ADM_PRIMARY)
720
		retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate);
721
	else
722
		retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0);
723 724
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
725 726 727
	return 0;
}

728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
/* Initializes the md.*_offset members, so we are able to find
 * the on disk meta data.
 *
 * We currently have two possible layouts:
 * external:
 *   |----------- md_size_sect ------------------|
 *   [ 4k superblock ][ activity log ][  Bitmap  ]
 *   | al_offset == 8 |
 *   | bm_offset = al_offset + X      |
 *  ==> bitmap sectors = md_size_sect - bm_offset
 *
 * internal:
 *            |----------- md_size_sect ------------------|
 * [data.....][  Bitmap  ][ activity log ][ 4k superblock ]
 *                        | al_offset < 0 |
 *            | bm_offset = al_offset - Y |
 *  ==> bitmap sectors = Y = al_offset - bm_offset
 *
 *  Activity log size used to be fixed 32kB,
 *  but is about to become configurable.
 */
749
static void drbd_md_set_sector_offsets(struct drbd_device *device,
P
Philipp Reisner 已提交
750 751 752
				       struct drbd_backing_dev *bdev)
{
	sector_t md_size_sect = 0;
753
	unsigned int al_size_sect = bdev->md.al_size_4k * 8;
P
Philipp Reisner 已提交
754

755 756
	bdev->md.md_offset = drbd_md_ss(bdev);

757
	switch (bdev->md.meta_dev_idx) {
P
Philipp Reisner 已提交
758 759
	default:
		/* v07 style fixed size indexed meta data */
760 761 762
		bdev->md.md_size_sect = MD_128MB_SECT;
		bdev->md.al_offset = MD_4kB_SECT;
		bdev->md.bm_offset = MD_4kB_SECT + al_size_sect;
P
Philipp Reisner 已提交
763 764 765 766
		break;
	case DRBD_MD_INDEX_FLEX_EXT:
		/* just occupy the full device; unit: sectors */
		bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev);
767 768
		bdev->md.al_offset = MD_4kB_SECT;
		bdev->md.bm_offset = MD_4kB_SECT + al_size_sect;
P
Philipp Reisner 已提交
769 770 771 772
		break;
	case DRBD_MD_INDEX_INTERNAL:
	case DRBD_MD_INDEX_FLEX_INT:
		/* al size is still fixed */
773
		bdev->md.al_offset = -al_size_sect;
P
Philipp Reisner 已提交
774 775 776 777 778 779 780 781
		/* we need (slightly less than) ~ this much bitmap sectors: */
		md_size_sect = drbd_get_capacity(bdev->backing_bdev);
		md_size_sect = ALIGN(md_size_sect, BM_SECT_PER_EXT);
		md_size_sect = BM_SECT_TO_EXT(md_size_sect);
		md_size_sect = ALIGN(md_size_sect, 8);

		/* plus the "drbd meta data super block",
		 * and the activity log; */
782
		md_size_sect += MD_4kB_SECT + al_size_sect;
P
Philipp Reisner 已提交
783 784 785

		bdev->md.md_size_sect = md_size_sect;
		/* bitmap offset is adjusted by 'super' block size */
786
		bdev->md.bm_offset   = -md_size_sect + MD_4kB_SECT;
P
Philipp Reisner 已提交
787 788 789 790
		break;
	}
}

791
/* input size is expected to be in KB */
P
Philipp Reisner 已提交
792 793
char *ppsize(char *buf, unsigned long long size)
{
794 795
	/* Needs 9 bytes at max including trailing NUL:
	 * -1ULL ==> "16384 EB" */
P
Philipp Reisner 已提交
796 797
	static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' };
	int base = 0;
798
	while (size >= 10000 && base < sizeof(units)-1) {
P
Philipp Reisner 已提交
799 800 801 802
		/* shift + round */
		size = (size >> 10) + !!(size & (1<<9));
		base++;
	}
803
	sprintf(buf, "%u %cB", (unsigned)size, units[base]);
P
Philipp Reisner 已提交
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820

	return buf;
}

/* there is still a theoretical deadlock when called from receiver
 * on an D_INCONSISTENT R_PRIMARY:
 *  remote READ does inc_ap_bio, receiver would need to receive answer
 *  packet from remote to dec_ap_bio again.
 *  receiver receive_sizes(), comes here,
 *  waits for ap_bio_cnt == 0. -> deadlock.
 * but this cannot happen, actually, because:
 *  R_PRIMARY D_INCONSISTENT, and peer's disk is unreachable
 *  (not connected, or bad/no disk on peer):
 *  see drbd_fail_request_early, ap_bio_cnt is zero.
 *  R_PRIMARY D_INCONSISTENT, and C_SYNC_TARGET:
 *  peer may not initiate a resize.
 */
821 822 823 824
/* Note these are not to be confused with
 * drbd_adm_suspend_io/drbd_adm_resume_io,
 * which are (sub) state changes triggered by admin (drbdsetup),
 * and can be long lived.
825
 * This changes an device->flag, is triggered by drbd internals,
826
 * and should be short-lived. */
827
void drbd_suspend_io(struct drbd_device *device)
P
Philipp Reisner 已提交
828
{
829 830
	set_bit(SUSPEND_IO, &device->flags);
	if (drbd_suspended(device))
831
		return;
832
	wait_event(device->misc_wait, !atomic_read(&device->ap_bio_cnt));
P
Philipp Reisner 已提交
833 834
}

835
void drbd_resume_io(struct drbd_device *device)
P
Philipp Reisner 已提交
836
{
837 838
	clear_bit(SUSPEND_IO, &device->flags);
	wake_up(&device->misc_wait);
P
Philipp Reisner 已提交
839 840 841 842
}

/**
 * drbd_determine_dev_size() -  Sets the right device size obeying all constraints
843
 * @device:	DRBD device.
P
Philipp Reisner 已提交
844 845 846 847
 *
 * Returns 0 on success, negative return values indicate errors.
 * You should call drbd_md_sync() after calling this function.
 */
848
enum determine_dev_size
849
drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct resize_parms *rs) __must_hold(local)
P
Philipp Reisner 已提交
850 851
{
	sector_t prev_first_sect, prev_size; /* previous meta location */
852
	sector_t la_size_sect, u_size;
853
	struct drbd_md *md = &device->ldev->md;
854 855
	u32 prev_al_stripe_size_4k;
	u32 prev_al_stripes;
P
Philipp Reisner 已提交
856 857
	sector_t size;
	char ppb[10];
858
	void *buffer;
P
Philipp Reisner 已提交
859 860

	int md_moved, la_size_changed;
861
	enum determine_dev_size rv = DS_UNCHANGED;
P
Philipp Reisner 已提交
862 863 864 865 866 867 868 869 870 871

	/* race:
	 * application request passes inc_ap_bio,
	 * but then cannot get an AL-reference.
	 * this function later may wait on ap_bio_cnt == 0. -> deadlock.
	 *
	 * to avoid that:
	 * Suspend IO right here.
	 * still lock the act_log to not trigger ASSERTs there.
	 */
872 873
	drbd_suspend_io(device);
	buffer = drbd_md_get_buffer(device); /* Lock meta-data IO */
874
	if (!buffer) {
875
		drbd_resume_io(device);
876 877
		return DS_ERROR;
	}
P
Philipp Reisner 已提交
878 879

	/* no wait necessary anymore, actually we could assert that */
880
	wait_event(device->al_wait, lc_try_lock(device->act_log));
P
Philipp Reisner 已提交
881

882 883 884
	prev_first_sect = drbd_md_first_sector(device->ldev);
	prev_size = device->ldev->md.md_size_sect;
	la_size_sect = device->ldev->md.la_size_sect;
P
Philipp Reisner 已提交
885

886 887 888 889 890 891 892 893 894 895 896
	if (rs) {
		/* rs is non NULL if we should change the AL layout only */

		prev_al_stripes = md->al_stripes;
		prev_al_stripe_size_4k = md->al_stripe_size_4k;

		md->al_stripes = rs->al_stripes;
		md->al_stripe_size_4k = rs->al_stripe_size / 4;
		md->al_size_4k = (u64)rs->al_stripes * rs->al_stripe_size / 4;
	}

897
	drbd_md_set_sector_offsets(device, device->ldev);
P
Philipp Reisner 已提交
898

P
Philipp Reisner 已提交
899
	rcu_read_lock();
900
	u_size = rcu_dereference(device->ldev->disk_conf)->disk_size;
P
Philipp Reisner 已提交
901
	rcu_read_unlock();
902
	size = drbd_new_dev_size(device, device->ldev, u_size, flags & DDSF_FORCED);
P
Philipp Reisner 已提交
903

904 905 906 907
	if (size < la_size_sect) {
		if (rs && u_size == 0) {
			/* Remove "rs &&" later. This check should always be active, but
			   right now the receiver expects the permissive behavior */
908
			drbd_warn(device, "Implicit shrink not allowed. "
909 910 911 912 913 914 915 916 917 918
				 "Use --size=%llus for explicit shrink.\n",
				 (unsigned long long)size);
			rv = DS_ERROR_SHRINK;
		}
		if (u_size > size)
			rv = DS_ERROR_SPACE_MD;
		if (rv != DS_UNCHANGED)
			goto err_out;
	}

919 920
	if (drbd_get_capacity(device->this_bdev) != size ||
	    drbd_bm_capacity(device) != size) {
P
Philipp Reisner 已提交
921
		int err;
922
		err = drbd_bm_resize(device, size, !(flags & DDSF_NO_RESYNC));
P
Philipp Reisner 已提交
923 924
		if (unlikely(err)) {
			/* currently there is only one error: ENOMEM! */
925
			size = drbd_bm_capacity(device)>>1;
P
Philipp Reisner 已提交
926
			if (size == 0) {
927
				drbd_err(device, "OUT OF MEMORY! "
P
Philipp Reisner 已提交
928 929
				    "Could not allocate bitmap!\n");
			} else {
930
				drbd_err(device, "BM resizing failed. "
P
Philipp Reisner 已提交
931 932 933
				    "Leaving size unchanged at size = %lu KB\n",
				    (unsigned long)size);
			}
934
			rv = DS_ERROR;
P
Philipp Reisner 已提交
935 936
		}
		/* racy, see comments above. */
937 938
		drbd_set_my_capacity(device, size);
		device->ldev->md.la_size_sect = size;
939
		drbd_info(device, "size = %s (%llu KB)\n", ppsize(ppb, size>>1),
P
Philipp Reisner 已提交
940 941
		     (unsigned long long)size>>1);
	}
942 943
	if (rv <= DS_ERROR)
		goto err_out;
P
Philipp Reisner 已提交
944

945
	la_size_changed = (la_size_sect != device->ldev->md.la_size_sect);
P
Philipp Reisner 已提交
946

947 948
	md_moved = prev_first_sect != drbd_md_first_sector(device->ldev)
		|| prev_size	   != device->ldev->md.md_size_sect;
P
Philipp Reisner 已提交
949

950 951
	if (la_size_changed || md_moved || rs) {
		u32 prev_flags;
952

953
		drbd_al_shrink(device); /* All extents inactive. */
954 955 956

		prev_flags = md->flags;
		md->flags &= ~MDF_PRIMARY_IND;
957
		drbd_md_write(device, buffer);
958

959
		drbd_info(device, "Writing the whole bitmap, %s\n",
P
Philipp Reisner 已提交
960 961
			 la_size_changed && md_moved ? "size changed and md moved" :
			 la_size_changed ? "size changed" : "md moved");
962
		/* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
963
		drbd_bitmap_io(device, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
964
			       "size changed", BM_LOCKED_MASK);
965
		drbd_initialize_al(device, buffer);
966 967

		md->flags = prev_flags;
968
		drbd_md_write(device, buffer);
969 970

		if (rs)
971 972
			drbd_info(device, "Changed AL layout to al-stripes = %d, al-stripe-size-kB = %d\n",
				  md->al_stripes, md->al_stripe_size_4k * 4);
P
Philipp Reisner 已提交
973 974
	}

975
	if (size > la_size_sect)
976
		rv = la_size_sect ? DS_GREW : DS_GREW_FROM_ZERO;
977
	if (size < la_size_sect)
978
		rv = DS_SHRUNK;
979 980 981 982 983 984 985 986

	if (0) {
	err_out:
		if (rs) {
			md->al_stripes = prev_al_stripes;
			md->al_stripe_size_4k = prev_al_stripe_size_4k;
			md->al_size_4k = (u64)prev_al_stripes * prev_al_stripe_size_4k;

987
			drbd_md_set_sector_offsets(device, device->ldev);
988 989
		}
	}
990 991 992 993
	lc_unlock(device->act_log);
	wake_up(&device->al_wait);
	drbd_md_put_buffer(device);
	drbd_resume_io(device);
P
Philipp Reisner 已提交
994 995 996 997 998

	return rv;
}

sector_t
999
drbd_new_dev_size(struct drbd_device *device, struct drbd_backing_dev *bdev,
1000
		  sector_t u_size, int assume_peer_has_space)
P
Philipp Reisner 已提交
1001
{
1002
	sector_t p_size = device->p_size;   /* partner's disk size. */
1003
	sector_t la_size_sect = bdev->md.la_size_sect; /* last agreed size. */
P
Philipp Reisner 已提交
1004 1005 1006 1007 1008
	sector_t m_size; /* my size */
	sector_t size = 0;

	m_size = drbd_get_max_capacity(bdev);

1009
	if (device->state.conn < C_CONNECTED && assume_peer_has_space) {
1010
		drbd_warn(device, "Resize while not connected was forced by the user!\n");
1011 1012 1013
		p_size = m_size;
	}

P
Philipp Reisner 已提交
1014 1015 1016
	if (p_size && m_size) {
		size = min_t(sector_t, p_size, m_size);
	} else {
1017 1018
		if (la_size_sect) {
			size = la_size_sect;
P
Philipp Reisner 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
			if (m_size && m_size < size)
				size = m_size;
			if (p_size && p_size < size)
				size = p_size;
		} else {
			if (m_size)
				size = m_size;
			if (p_size)
				size = p_size;
		}
	}

	if (size == 0)
1032
		drbd_err(device, "Both nodes diskless!\n");
P
Philipp Reisner 已提交
1033 1034 1035

	if (u_size) {
		if (u_size > size)
1036
			drbd_err(device, "Requested disk size is too big (%lu > %lu)\n",
P
Philipp Reisner 已提交
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
			    (unsigned long)u_size>>1, (unsigned long)size>>1);
		else
			size = u_size;
	}

	return size;
}

/**
 * drbd_check_al_size() - Ensures that the AL is of the right size
1047
 * @device:	DRBD device.
P
Philipp Reisner 已提交
1048 1049 1050 1051 1052
 *
 * Returns -EBUSY if current al lru is still used, -ENOMEM when allocation
 * failed, and 0 on success. You should call drbd_md_sync() after you called
 * this function.
 */
1053
static int drbd_check_al_size(struct drbd_device *device, struct disk_conf *dc)
P
Philipp Reisner 已提交
1054 1055 1056 1057 1058 1059
{
	struct lru_cache *n, *t;
	struct lc_element *e;
	unsigned int in_use;
	int i;

1060 1061
	if (device->act_log &&
	    device->act_log->nr_elements == dc->al_extents)
P
Philipp Reisner 已提交
1062 1063 1064
		return 0;

	in_use = 0;
1065
	t = device->act_log;
1066
	n = lc_create("act_log", drbd_al_ext_cache, AL_UPDATES_PER_TRANSACTION,
1067
		dc->al_extents, sizeof(struct lc_element), 0);
P
Philipp Reisner 已提交
1068 1069

	if (n == NULL) {
1070
		drbd_err(device, "Cannot allocate act_log lru!\n");
P
Philipp Reisner 已提交
1071 1072
		return -ENOMEM;
	}
1073
	spin_lock_irq(&device->al_lock);
P
Philipp Reisner 已提交
1074 1075 1076 1077
	if (t) {
		for (i = 0; i < t->nr_elements; i++) {
			e = lc_element_by_index(t, i);
			if (e->refcnt)
1078
				drbd_err(device, "refcnt(%d)==%d\n",
P
Philipp Reisner 已提交
1079 1080 1081 1082 1083
				    e->lc_number, e->refcnt);
			in_use += e->refcnt;
		}
	}
	if (!in_use)
1084 1085
		device->act_log = n;
	spin_unlock_irq(&device->al_lock);
P
Philipp Reisner 已提交
1086
	if (in_use) {
1087
		drbd_err(device, "Activity log still in use!\n");
P
Philipp Reisner 已提交
1088 1089 1090 1091 1092 1093
		lc_destroy(n);
		return -EBUSY;
	} else {
		if (t)
			lc_destroy(t);
	}
1094
	drbd_md_mark_dirty(device); /* we changed device->act_log->nr_elemens */
P
Philipp Reisner 已提交
1095 1096 1097
	return 0;
}

1098
static void drbd_setup_queue_param(struct drbd_device *device, unsigned int max_bio_size)
P
Philipp Reisner 已提交
1099
{
1100
	struct request_queue * const q = device->rq_queue;
1101 1102
	unsigned int max_hw_sectors = max_bio_size >> 9;
	unsigned int max_segments = 0;
1103

1104 1105
	if (get_ldev_if_state(device, D_ATTACHING)) {
		struct request_queue * const b = device->ldev->backing_bdev->bd_disk->queue;
1106 1107

		max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
P
Philipp Reisner 已提交
1108
		rcu_read_lock();
1109
		max_segments = rcu_dereference(device->ldev->disk_conf)->max_bio_bvecs;
P
Philipp Reisner 已提交
1110
		rcu_read_unlock();
1111
		put_ldev(device);
1112
	}
P
Philipp Reisner 已提交
1113 1114

	blk_queue_logical_block_size(q, 512);
1115 1116 1117 1118
	blk_queue_max_hw_sectors(q, max_hw_sectors);
	/* This is the workaround for "bio would need to, but cannot, be split" */
	blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
	blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1);
P
Philipp Reisner 已提交
1119

1120 1121
	if (get_ldev_if_state(device, D_ATTACHING)) {
		struct request_queue * const b = device->ldev->backing_bdev->bd_disk->queue;
1122 1123 1124 1125

		blk_queue_stack_limits(q, b);

		if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
1126
			drbd_info(device, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
1127 1128 1129 1130
				 q->backing_dev_info.ra_pages,
				 b->backing_dev_info.ra_pages);
			q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
		}
1131
		put_ldev(device);
1132 1133 1134
	}
}

1135
void drbd_reconsider_max_bio_size(struct drbd_device *device)
1136
{
1137
	unsigned int now, new, local, peer;
1138

1139 1140 1141
	now = queue_max_hw_sectors(device->rq_queue) << 9;
	local = device->local_max_bio_size; /* Eventually last known value, from volatile memory */
	peer = device->peer_max_bio_size; /* Eventually last known value, from meta data */
P
Philipp Reisner 已提交
1142

1143 1144 1145 1146
	if (get_ldev_if_state(device, D_ATTACHING)) {
		local = queue_max_hw_sectors(device->ldev->backing_bdev->bd_disk->queue) << 9;
		device->local_max_bio_size = local;
		put_ldev(device);
P
Philipp Reisner 已提交
1147
	}
1148
	local = min(local, DRBD_MAX_BIO_SIZE);
1149 1150 1151 1152

	/* We may ignore peer limits if the peer is modern enough.
	   Because new from 8.3.8 onwards the peer can use multiple
	   BIOs for a single peer_request */
1153
	if (device->state.conn >= C_WF_REPORT_PARAMS) {
1154
		if (first_peer_device(device)->connection->agreed_pro_version < 94)
1155
			peer = min(device->peer_max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
1156
			/* Correct old drbd (up to 8.3.7) if it believes it can do more than 32KiB */
1157
		else if (first_peer_device(device)->connection->agreed_pro_version == 94)
1158
			peer = DRBD_MAX_SIZE_H80_PACKET;
1159
		else if (first_peer_device(device)->connection->agreed_pro_version < 100)
1160 1161
			peer = DRBD_MAX_BIO_SIZE_P95;  /* drbd 8.3.8 onwards, before 8.4.0 */
		else
1162 1163 1164
			peer = DRBD_MAX_BIO_SIZE;
	}

1165
	new = min(local, peer);
1166

1167
	if (device->state.role == R_PRIMARY && new < now)
1168
		drbd_err(device, "ASSERT FAILED new < now; (%u < %u)\n", new, now);
1169 1170

	if (new != now)
1171
		drbd_info(device, "max BIO size = %u\n", new);
1172

1173
	drbd_setup_queue_param(device, new);
P
Philipp Reisner 已提交
1174 1175
}

1176
/* Starts the worker thread */
1177
static void conn_reconfig_start(struct drbd_connection *connection)
P
Philipp Reisner 已提交
1178
{
1179 1180
	drbd_thread_start(&connection->worker);
	conn_flush_workqueue(connection);
P
Philipp Reisner 已提交
1181 1182
}

1183
/* if still unconfigured, stops worker again. */
1184
static void conn_reconfig_done(struct drbd_connection *connection)
P
Philipp Reisner 已提交
1185
{
L
Lars Ellenberg 已提交
1186
	bool stop_threads;
1187 1188 1189 1190
	spin_lock_irq(&connection->req_lock);
	stop_threads = conn_all_vols_unconf(connection) &&
		connection->cstate == C_STANDALONE;
	spin_unlock_irq(&connection->req_lock);
L
Lars Ellenberg 已提交
1191 1192
	if (stop_threads) {
		/* asender is implicitly stopped by receiver
1193
		 * in conn_disconnect() */
1194 1195
		drbd_thread_stop(&connection->receiver);
		drbd_thread_stop(&connection->worker);
L
Lars Ellenberg 已提交
1196
	}
P
Philipp Reisner 已提交
1197 1198
}

1199
/* Make sure IO is suspended before calling this function(). */
1200
static void drbd_suspend_al(struct drbd_device *device)
1201 1202 1203
{
	int s = 0;

1204
	if (!lc_try_lock(device->act_log)) {
1205
		drbd_warn(device, "Failed to lock al in drbd_suspend_al()\n");
1206 1207 1208
		return;
	}

1209
	drbd_al_shrink(device);
1210
	spin_lock_irq(&first_peer_device(device)->connection->req_lock);
1211 1212
	if (device->state.conn < C_CONNECTED)
		s = !test_and_set_bit(AL_SUSPENDED, &device->flags);
1213
	spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
1214
	lc_unlock(device->act_log);
1215 1216

	if (s)
1217
		drbd_info(device, "Suspended AL updates\n");
1218 1219
}

1220 1221 1222 1223 1224 1225 1226

static bool should_set_defaults(struct genl_info *info)
{
	unsigned flags = ((struct drbd_genlmsghdr*)info->userhdr)->flags;
	return 0 != (flags & DRBD_GENL_F_SET_DEFAULTS);
}

1227
static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev)
1228
{
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
	/* This is limited by 16 bit "slot" numbers,
	 * and by available on-disk context storage.
	 *
	 * Also (u16)~0 is special (denotes a "free" extent).
	 *
	 * One transaction occupies one 4kB on-disk block,
	 * we have n such blocks in the on disk ring buffer,
	 * the "current" transaction may fail (n-1),
	 * and there is 919 slot numbers context information per transaction.
	 *
	 * 72 transaction blocks amounts to more than 2**16 context slots,
	 * so cap there first.
	 */
	const unsigned int max_al_nr = DRBD_AL_EXTENTS_MAX;
	const unsigned int sufficient_on_disk =
		(max_al_nr + AL_CONTEXT_PER_TRANSACTION -1)
		/AL_CONTEXT_PER_TRANSACTION;
1246

1247 1248 1249 1250 1251 1252
	unsigned int al_size_4k = bdev->md.al_size_4k;

	if (al_size_4k > sufficient_on_disk)
		return max_al_nr;

	return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION;
1253 1254
}

1255 1256 1257
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
{
	enum drbd_ret_code retcode;
1258
	struct drbd_device *device;
P
Philipp Reisner 已提交
1259
	struct disk_conf *new_disk_conf, *old_disk_conf;
P
Philipp Reisner 已提交
1260
	struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
1261 1262 1263 1264 1265 1266 1267 1268
	int err, fifo_size;

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;

1269
	device = adm_ctx.device;
1270 1271 1272

	/* we also need a disk
	 * to change the options on */
1273
	if (!get_ldev(device)) {
1274 1275 1276 1277
		retcode = ERR_NO_DISK;
		goto out;
	}

P
Philipp Reisner 已提交
1278
	new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL);
1279
	if (!new_disk_conf) {
1280 1281 1282 1283
		retcode = ERR_NOMEM;
		goto fail;
	}

1284
	mutex_lock(&first_peer_device(device)->connection->conf_update);
1285
	old_disk_conf = device->ldev->disk_conf;
P
Philipp Reisner 已提交
1286
	*new_disk_conf = *old_disk_conf;
1287
	if (should_set_defaults(info))
1288
		set_disk_conf_defaults(new_disk_conf);
1289

1290
	err = disk_conf_from_attrs_for_change(new_disk_conf, info);
1291
	if (err && err != -ENOMSG) {
1292 1293
		retcode = ERR_MANDATORY_TAG;
		drbd_msg_put_info(from_attrs_err_to_txt(err));
P
Philipp Reisner 已提交
1294
		goto fail_unlock;
1295 1296
	}

1297 1298
	if (!expect(new_disk_conf->resync_rate >= 1))
		new_disk_conf->resync_rate = 1;
1299

1300 1301
	if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN)
		new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
1302 1303
	if (new_disk_conf->al_extents > drbd_al_extents_max(device->ldev))
		new_disk_conf->al_extents = drbd_al_extents_max(device->ldev);
1304 1305 1306

	if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX)
		new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX;
1307

1308
	fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ;
1309
	if (fifo_size != device->rs_plan_s->size) {
P
Philipp Reisner 已提交
1310 1311
		new_plan = fifo_alloc(fifo_size);
		if (!new_plan) {
1312
			drbd_err(device, "kmalloc of fifo_buffer failed");
1313
			retcode = ERR_NOMEM;
P
Philipp Reisner 已提交
1314
			goto fail_unlock;
1315 1316 1317
		}
	}

1318 1319 1320 1321 1322 1323 1324
	drbd_suspend_io(device);
	wait_event(device->al_wait, lc_try_lock(device->act_log));
	drbd_al_shrink(device);
	err = drbd_check_al_size(device, new_disk_conf);
	lc_unlock(device->act_log);
	wake_up(&device->al_wait);
	drbd_resume_io(device);
1325 1326 1327

	if (err) {
		retcode = ERR_NOMEM;
P
Philipp Reisner 已提交
1328
		goto fail_unlock;
1329 1330
	}

1331
	write_lock_irq(&global_state_lock);
1332
	retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after);
1333
	if (retcode == NO_ERROR) {
1334 1335
		rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
		drbd_resync_after_changed(device);
1336 1337
	}
	write_unlock_irq(&global_state_lock);
1338

P
Philipp Reisner 已提交
1339 1340
	if (retcode != NO_ERROR)
		goto fail_unlock;
1341

P
Philipp Reisner 已提交
1342
	if (new_plan) {
1343 1344
		old_plan = device->rs_plan_s;
		rcu_assign_pointer(device->rs_plan_s, new_plan);
1345 1346
	}

1347
	mutex_unlock(&first_peer_device(device)->connection->conf_update);
1348

P
Philipp Reisner 已提交
1349
	if (new_disk_conf->al_updates)
1350
		device->ldev->md.flags &= ~MDF_AL_DISABLED;
P
Philipp Reisner 已提交
1351
	else
1352
		device->ldev->md.flags |= MDF_AL_DISABLED;
P
Philipp Reisner 已提交
1353

1354
	if (new_disk_conf->md_flushes)
1355
		clear_bit(MD_NO_FUA, &device->flags);
1356
	else
1357
		set_bit(MD_NO_FUA, &device->flags);
1358

1359
	drbd_bump_write_ordering(first_peer_device(device)->connection, WO_bdev_flush);
1360

1361
	drbd_md_sync(device);
1362

1363 1364
	if (device->state.conn >= C_CONNECTED)
		drbd_send_sync_param(device);
1365

P
Philipp Reisner 已提交
1366 1367
	synchronize_rcu();
	kfree(old_disk_conf);
P
Philipp Reisner 已提交
1368
	kfree(old_plan);
1369
	mod_timer(&device->request_timer, jiffies + HZ);
P
Philipp Reisner 已提交
1370 1371 1372
	goto success;

fail_unlock:
1373
	mutex_unlock(&first_peer_device(device)->connection->conf_update);
1374
 fail:
1375
	kfree(new_disk_conf);
P
Philipp Reisner 已提交
1376
	kfree(new_plan);
P
Philipp Reisner 已提交
1377
success:
1378
	put_ldev(device);
1379 1380 1381 1382 1383
 out:
	drbd_adm_finish(info, retcode);
	return 0;
}

1384
int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
1385
{
1386
	struct drbd_device *device;
1387
	int err;
1388
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
1389 1390 1391 1392
	enum determine_dev_size dd;
	sector_t max_possible_sectors;
	sector_t min_md_device_sectors;
	struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
P
Philipp Reisner 已提交
1393
	struct disk_conf *new_disk_conf = NULL;
1394
	struct block_device *bdev;
P
Philipp Reisner 已提交
1395
	struct lru_cache *resync_lru = NULL;
1396
	struct fifo_buffer *new_plan = NULL;
P
Philipp Reisner 已提交
1397
	union drbd_state ns, os;
1398
	enum drbd_state_rv rv;
1399
	struct net_conf *nc;
P
Philipp Reisner 已提交
1400

1401 1402 1403 1404
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
1405
		goto finish;
P
Philipp Reisner 已提交
1406

1407
	device = adm_ctx.device;
1408
	conn_reconfig_start(first_peer_device(device)->connection);
P
Philipp Reisner 已提交
1409 1410

	/* if you want to reconfigure, please tear down first */
1411
	if (device->state.disk > D_DISKLESS) {
P
Philipp Reisner 已提交
1412 1413 1414
		retcode = ERR_DISK_CONFIGURED;
		goto fail;
	}
1415 1416 1417 1418
	/* It may just now have detached because of IO error.  Make sure
	 * drbd_ldev_destroy is done already, we may end up here very fast,
	 * e.g. if someone calls attach from the on-io-error handler,
	 * to realize a "hot spare" feature (not that I'd recommend that) */
1419
	wait_event(device->misc_wait, !atomic_read(&device->local_cnt));
P
Philipp Reisner 已提交
1420

1421
	/* make sure there is no leftover from previous force-detach attempts */
1422 1423 1424
	clear_bit(FORCE_DETACH, &device->flags);
	clear_bit(WAS_IO_ERROR, &device->flags);
	clear_bit(WAS_READ_ERROR, &device->flags);
1425

1426
	/* and no leftover from previously aborted resync or verify, either */
1427 1428 1429
	device->rs_total = 0;
	device->rs_failed = 0;
	atomic_set(&device->rs_pending_cnt, 0);
1430

1431
	/* allocation not in the IO path, drbdsetup context */
P
Philipp Reisner 已提交
1432 1433 1434 1435 1436
	nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
	if (!nbc) {
		retcode = ERR_NOMEM;
		goto fail;
	}
1437 1438
	spin_lock_init(&nbc->md.uuid_lock);

P
Philipp Reisner 已提交
1439 1440 1441
	new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL);
	if (!new_disk_conf) {
		retcode = ERR_NOMEM;
P
Philipp Reisner 已提交
1442 1443
		goto fail;
	}
P
Philipp Reisner 已提交
1444
	nbc->disk_conf = new_disk_conf;
P
Philipp Reisner 已提交
1445

P
Philipp Reisner 已提交
1446 1447
	set_disk_conf_defaults(new_disk_conf);
	err = disk_conf_from_attrs(new_disk_conf, info);
1448
	if (err) {
P
Philipp Reisner 已提交
1449
		retcode = ERR_MANDATORY_TAG;
1450
		drbd_msg_put_info(from_attrs_err_to_txt(err));
P
Philipp Reisner 已提交
1451 1452 1453
		goto fail;
	}

1454 1455
	if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX)
		new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX;
1456

1457 1458 1459 1460 1461 1462
	new_plan = fifo_alloc((new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ);
	if (!new_plan) {
		retcode = ERR_NOMEM;
		goto fail;
	}

P
Philipp Reisner 已提交
1463
	if (new_disk_conf->meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
P
Philipp Reisner 已提交
1464 1465 1466 1467
		retcode = ERR_MD_IDX_INVALID;
		goto fail;
	}

1468
	write_lock_irq(&global_state_lock);
1469
	retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after);
1470 1471 1472 1473
	write_unlock_irq(&global_state_lock);
	if (retcode != NO_ERROR)
		goto fail;

1474
	rcu_read_lock();
1475
	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
1476
	if (nc) {
P
Philipp Reisner 已提交
1477
		if (new_disk_conf->fencing == FP_STONITH && nc->wire_protocol == DRBD_PROT_A) {
1478
			rcu_read_unlock();
1479 1480 1481 1482
			retcode = ERR_STONITH_AND_PROT_A;
			goto fail;
		}
	}
1483
	rcu_read_unlock();
1484

P
Philipp Reisner 已提交
1485
	bdev = blkdev_get_by_path(new_disk_conf->backing_dev,
1486
				  FMODE_READ | FMODE_WRITE | FMODE_EXCL, device);
1487
	if (IS_ERR(bdev)) {
1488
		drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->backing_dev,
1489
			PTR_ERR(bdev));
P
Philipp Reisner 已提交
1490 1491 1492
		retcode = ERR_OPEN_DISK;
		goto fail;
	}
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
	nbc->backing_bdev = bdev;

	/*
	 * meta_dev_idx >= 0: external fixed size, possibly multiple
	 * drbd sharing one meta device.  TODO in that case, paranoia
	 * check that [md_bdev, meta_dev_idx] is not yet used by some
	 * other drbd minor!  (if you use drbd.conf + drbdadm, that
	 * should check it for you already; but if you don't, or
	 * someone fooled it, we need to double check here)
	 */
P
Philipp Reisner 已提交
1503
	bdev = blkdev_get_by_path(new_disk_conf->meta_dev,
1504
				  FMODE_READ | FMODE_WRITE | FMODE_EXCL,
P
Philipp Reisner 已提交
1505
				  (new_disk_conf->meta_dev_idx < 0) ?
1506
				  (void *)device : (void *)drbd_m_holder);
1507
	if (IS_ERR(bdev)) {
1508
		drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->meta_dev,
1509
			PTR_ERR(bdev));
P
Philipp Reisner 已提交
1510 1511 1512
		retcode = ERR_OPEN_MD_DISK;
		goto fail;
	}
1513
	nbc->md_bdev = bdev;
P
Philipp Reisner 已提交
1514

1515
	if ((nbc->backing_bdev == nbc->md_bdev) !=
P
Philipp Reisner 已提交
1516 1517
	    (new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
	     new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
1518
		retcode = ERR_MD_IDX_INVALID;
P
Philipp Reisner 已提交
1519 1520 1521 1522
		goto fail;
	}

	resync_lru = lc_create("resync", drbd_bm_ext_cache,
1523
			1, 61, sizeof(struct bm_extent),
P
Philipp Reisner 已提交
1524 1525 1526
			offsetof(struct bm_extent, lce));
	if (!resync_lru) {
		retcode = ERR_NOMEM;
1527
		goto fail;
P
Philipp Reisner 已提交
1528 1529
	}

1530 1531
	/* Read our meta data super block early.
	 * This also sets other on-disk offsets. */
1532
	retcode = drbd_md_read(device, nbc);
1533 1534
	if (retcode != NO_ERROR)
		goto fail;
P
Philipp Reisner 已提交
1535

1536 1537 1538 1539 1540
	if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN)
		new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
	if (new_disk_conf->al_extents > drbd_al_extents_max(nbc))
		new_disk_conf->al_extents = drbd_al_extents_max(nbc);

P
Philipp Reisner 已提交
1541
	if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) {
1542
		drbd_err(device, "max capacity %llu smaller than disk size %llu\n",
P
Philipp Reisner 已提交
1543
			(unsigned long long) drbd_get_max_capacity(nbc),
P
Philipp Reisner 已提交
1544
			(unsigned long long) new_disk_conf->disk_size);
L
Lars Ellenberg 已提交
1545
		retcode = ERR_DISK_TOO_SMALL;
1546
		goto fail;
P
Philipp Reisner 已提交
1547 1548
	}

P
Philipp Reisner 已提交
1549
	if (new_disk_conf->meta_dev_idx < 0) {
P
Philipp Reisner 已提交
1550 1551 1552 1553 1554
		max_possible_sectors = DRBD_MAX_SECTORS_FLEX;
		/* at least one MB, otherwise it does not make sense */
		min_md_device_sectors = (2<<10);
	} else {
		max_possible_sectors = DRBD_MAX_SECTORS;
1555
		min_md_device_sectors = MD_128MB_SECT * (new_disk_conf->meta_dev_idx + 1);
P
Philipp Reisner 已提交
1556 1557 1558
	}

	if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) {
L
Lars Ellenberg 已提交
1559
		retcode = ERR_MD_DISK_TOO_SMALL;
1560
		drbd_warn(device, "refusing attach: md-device too small, "
P
Philipp Reisner 已提交
1561 1562
		     "at least %llu sectors needed for this meta-disk type\n",
		     (unsigned long long) min_md_device_sectors);
1563
		goto fail;
P
Philipp Reisner 已提交
1564 1565 1566 1567 1568
	}

	/* Make sure the new disk is big enough
	 * (we may currently be R_PRIMARY with no local disk...) */
	if (drbd_get_max_capacity(nbc) <
1569
	    drbd_get_capacity(device->this_bdev)) {
L
Lars Ellenberg 已提交
1570
		retcode = ERR_DISK_TOO_SMALL;
1571
		goto fail;
P
Philipp Reisner 已提交
1572 1573 1574 1575
	}

	nbc->known_size = drbd_get_capacity(nbc->backing_bdev);

1576
	if (nbc->known_size > max_possible_sectors) {
1577
		drbd_warn(device, "==> truncating very big lower level device "
1578 1579
			"to currently maximum possible %llu sectors <==\n",
			(unsigned long long) max_possible_sectors);
P
Philipp Reisner 已提交
1580
		if (new_disk_conf->meta_dev_idx >= 0)
1581
			drbd_warn(device, "==>> using internal or flexible "
1582 1583 1584
				      "meta data may help <<==\n");
	}

1585
	drbd_suspend_io(device);
P
Philipp Reisner 已提交
1586
	/* also wait for the last barrier ack. */
1587 1588 1589 1590 1591 1592
	/* FIXME see also https://daiquiri.linbit/cgi-bin/bugzilla/show_bug.cgi?id=171
	 * We need a way to either ignore barrier acks for barriers sent before a device
	 * was attached, or a way to wait for all pending barrier acks to come in.
	 * As barriers are counted per resource,
	 * we'd need to suspend io on all devices of a resource.
	 */
1593
	wait_event(device->misc_wait, !atomic_read(&device->ap_pending_cnt) || drbd_suspended(device));
P
Philipp Reisner 已提交
1594
	/* and for any other previously queued work */
1595
	drbd_flush_workqueue(device);
P
Philipp Reisner 已提交
1596

1597
	rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE);
1598
	retcode = rv;  /* FIXME: Type mismatch. */
1599
	drbd_resume_io(device);
1600
	if (rv < SS_SUCCESS)
1601
		goto fail;
P
Philipp Reisner 已提交
1602

1603
	if (!get_ldev_if_state(device, D_ATTACHING))
P
Philipp Reisner 已提交
1604 1605
		goto force_diskless;

1606 1607
	if (!device->bitmap) {
		if (drbd_bm_init(device)) {
P
Philipp Reisner 已提交
1608 1609 1610 1611 1612
			retcode = ERR_NOMEM;
			goto force_diskless_dec;
		}
	}

1613 1614 1615
	if (device->state.conn < C_CONNECTED &&
	    device->state.role == R_PRIMARY &&
	    (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) {
1616
		drbd_err(device, "Can only attach to data with current UUID=%016llX\n",
1617
		    (unsigned long long)device->ed_uuid);
P
Philipp Reisner 已提交
1618 1619 1620 1621 1622
		retcode = ERR_DATA_NOT_CURRENT;
		goto force_diskless_dec;
	}

	/* Since we are diskless, fix the activity log first... */
1623
	if (drbd_check_al_size(device, new_disk_conf)) {
P
Philipp Reisner 已提交
1624 1625 1626 1627 1628 1629
		retcode = ERR_NOMEM;
		goto force_diskless_dec;
	}

	/* Prevent shrinking of consistent devices ! */
	if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
1630
	    drbd_new_dev_size(device, nbc, nbc->disk_conf->disk_size, 0) < nbc->md.la_size_sect) {
1631
		drbd_warn(device, "refusing to truncate a consistent device\n");
L
Lars Ellenberg 已提交
1632
		retcode = ERR_DISK_TOO_SMALL;
P
Philipp Reisner 已提交
1633 1634 1635 1636 1637
		goto force_diskless_dec;
	}

	/* Reset the "barriers don't work" bits here, then force meta data to
	 * be written, to ensure we determine if barriers are supported. */
1638
	if (new_disk_conf->md_flushes)
1639
		clear_bit(MD_NO_FUA, &device->flags);
P
Philipp Reisner 已提交
1640
	else
1641
		set_bit(MD_NO_FUA, &device->flags);
P
Philipp Reisner 已提交
1642 1643 1644

	/* Point of no return reached.
	 * Devices and memory are no longer released by error cleanup below.
1645
	 * now device takes over responsibility, and the state engine should
P
Philipp Reisner 已提交
1646
	 * clean it up somewhere.  */
1647 1648 1649 1650
	D_ASSERT(device->ldev == NULL);
	device->ldev = nbc;
	device->resync = resync_lru;
	device->rs_plan_s = new_plan;
P
Philipp Reisner 已提交
1651 1652
	nbc = NULL;
	resync_lru = NULL;
P
Philipp Reisner 已提交
1653
	new_disk_conf = NULL;
1654
	new_plan = NULL;
P
Philipp Reisner 已提交
1655

1656
	drbd_bump_write_ordering(first_peer_device(device)->connection, WO_bdev_flush);
P
Philipp Reisner 已提交
1657

1658 1659
	if (drbd_md_test_flag(device->ldev, MDF_CRASHED_PRIMARY))
		set_bit(CRASHED_PRIMARY, &device->flags);
P
Philipp Reisner 已提交
1660
	else
1661
		clear_bit(CRASHED_PRIMARY, &device->flags);
P
Philipp Reisner 已提交
1662

1663
	if (drbd_md_test_flag(device->ldev, MDF_PRIMARY_IND) &&
1664 1665
	    !(device->state.role == R_PRIMARY &&
	      first_peer_device(device)->connection->susp_nod))
1666
		set_bit(CRASHED_PRIMARY, &device->flags);
P
Philipp Reisner 已提交
1667

1668 1669 1670 1671
	device->send_cnt = 0;
	device->recv_cnt = 0;
	device->read_cnt = 0;
	device->writ_cnt = 0;
P
Philipp Reisner 已提交
1672

1673
	drbd_reconsider_max_bio_size(device);
P
Philipp Reisner 已提交
1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688

	/* If I am currently not R_PRIMARY,
	 * but meta data primary indicator is set,
	 * I just now recover from a hard crash,
	 * and have been R_PRIMARY before that crash.
	 *
	 * Now, if I had no connection before that crash
	 * (have been degraded R_PRIMARY), chances are that
	 * I won't find my peer now either.
	 *
	 * In that case, and _only_ in that case,
	 * we use the degr-wfc-timeout instead of the default,
	 * so we can automatically recover from a crash of a
	 * degraded but active "cluster" after a certain timeout.
	 */
1689 1690 1691 1692 1693
	clear_bit(USE_DEGR_WFC_T, &device->flags);
	if (device->state.role != R_PRIMARY &&
	     drbd_md_test_flag(device->ldev, MDF_PRIMARY_IND) &&
	    !drbd_md_test_flag(device->ldev, MDF_CONNECTED_IND))
		set_bit(USE_DEGR_WFC_T, &device->flags);
P
Philipp Reisner 已提交
1694

1695
	dd = drbd_determine_dev_size(device, 0, NULL);
1696
	if (dd <= DS_ERROR) {
P
Philipp Reisner 已提交
1697 1698
		retcode = ERR_NOMEM_BITMAP;
		goto force_diskless_dec;
1699
	} else if (dd == DS_GREW)
1700
		set_bit(RESYNC_AFTER_NEG, &device->flags);
P
Philipp Reisner 已提交
1701

1702 1703 1704
	if (drbd_md_test_flag(device->ldev, MDF_FULL_SYNC) ||
	    (test_bit(CRASHED_PRIMARY, &device->flags) &&
	     drbd_md_test_flag(device->ldev, MDF_AL_DISABLED))) {
1705
		drbd_info(device, "Assuming that all blocks are out of sync "
P
Philipp Reisner 已提交
1706
		     "(aka FullSync)\n");
1707
		if (drbd_bitmap_io(device, &drbd_bmio_set_n_write,
1708
			"set_n_write from attaching", BM_LOCKED_MASK)) {
P
Philipp Reisner 已提交
1709 1710 1711 1712
			retcode = ERR_IO_MD_DISK;
			goto force_diskless_dec;
		}
	} else {
1713
		if (drbd_bitmap_io(device, &drbd_bm_read,
1714
			"read from attaching", BM_LOCKED_MASK)) {
1715 1716 1717
			retcode = ERR_IO_MD_DISK;
			goto force_diskless_dec;
		}
P
Philipp Reisner 已提交
1718 1719
	}

1720 1721
	if (_drbd_bm_total_weight(device) == drbd_bm_bits(device))
		drbd_suspend_al(device); /* IO is still suspended here... */
1722

1723
	spin_lock_irq(&first_peer_device(device)->connection->req_lock);
1724
	os = drbd_read_state(device);
1725
	ns = os;
P
Philipp Reisner 已提交
1726 1727 1728 1729 1730
	/* If MDF_CONSISTENT is not set go into inconsistent state,
	   otherwise investigate MDF_WasUpToDate...
	   If MDF_WAS_UP_TO_DATE is not set go into D_OUTDATED disk state,
	   otherwise into D_CONSISTENT state.
	*/
1731 1732
	if (drbd_md_test_flag(device->ldev, MDF_CONSISTENT)) {
		if (drbd_md_test_flag(device->ldev, MDF_WAS_UP_TO_DATE))
P
Philipp Reisner 已提交
1733 1734 1735 1736 1737 1738 1739
			ns.disk = D_CONSISTENT;
		else
			ns.disk = D_OUTDATED;
	} else {
		ns.disk = D_INCONSISTENT;
	}

1740
	if (drbd_md_test_flag(device->ldev, MDF_PEER_OUT_DATED))
P
Philipp Reisner 已提交
1741 1742
		ns.pdsk = D_OUTDATED;

P
Philipp Reisner 已提交
1743 1744
	rcu_read_lock();
	if (ns.disk == D_CONSISTENT &&
1745
	    (ns.pdsk == D_OUTDATED || rcu_dereference(device->ldev->disk_conf)->fencing == FP_DONT_CARE))
P
Philipp Reisner 已提交
1746 1747 1748 1749 1750 1751 1752
		ns.disk = D_UP_TO_DATE;

	/* All tests on MDF_PRIMARY_IND, MDF_CONNECTED_IND,
	   MDF_CONSISTENT and MDF_WAS_UP_TO_DATE must happen before
	   this point, because drbd_request_state() modifies these
	   flags. */

1753 1754
	if (rcu_dereference(device->ldev->disk_conf)->al_updates)
		device->ldev->md.flags &= ~MDF_AL_DISABLED;
P
Philipp Reisner 已提交
1755
	else
1756
		device->ldev->md.flags |= MDF_AL_DISABLED;
P
Philipp Reisner 已提交
1757 1758 1759

	rcu_read_unlock();

P
Philipp Reisner 已提交
1760 1761
	/* In case we are C_CONNECTED postpone any decision on the new disk
	   state after the negotiation phase. */
1762 1763
	if (device->state.conn == C_CONNECTED) {
		device->new_state_tmp.i = ns.i;
P
Philipp Reisner 已提交
1764 1765
		ns.i = os.i;
		ns.disk = D_NEGOTIATING;
1766 1767 1768 1769

		/* We expect to receive up-to-date UUIDs soon.
		   To avoid a race in receive_state, free p_uuid while
		   holding req_lock. I.e. atomic with the state change */
1770 1771
		kfree(device->p_uuid);
		device->p_uuid = NULL;
P
Philipp Reisner 已提交
1772 1773
	}

1774
	rv = _drbd_set_state(device, ns, CS_VERBOSE, NULL);
1775
	spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
P
Philipp Reisner 已提交
1776 1777 1778 1779

	if (rv < SS_SUCCESS)
		goto force_diskless_dec;

1780
	mod_timer(&device->request_timer, jiffies + HZ);
1781

1782 1783
	if (device->state.role == R_PRIMARY)
		device->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
P
Philipp Reisner 已提交
1784
	else
1785
		device->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
P
Philipp Reisner 已提交
1786

1787 1788
	drbd_md_mark_dirty(device);
	drbd_md_sync(device);
P
Philipp Reisner 已提交
1789

1790 1791
	kobject_uevent(&disk_to_dev(device->vdisk)->kobj, KOBJ_CHANGE);
	put_ldev(device);
1792
	conn_reconfig_done(first_peer_device(device)->connection);
1793
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
1794 1795 1796
	return 0;

 force_diskless_dec:
1797
	put_ldev(device);
P
Philipp Reisner 已提交
1798
 force_diskless:
1799 1800
	drbd_force_state(device, NS(disk, D_DISKLESS));
	drbd_md_sync(device);
P
Philipp Reisner 已提交
1801
 fail:
1802
	conn_reconfig_done(first_peer_device(device)->connection);
P
Philipp Reisner 已提交
1803
	if (nbc) {
1804 1805 1806 1807 1808 1809
		if (nbc->backing_bdev)
			blkdev_put(nbc->backing_bdev,
				   FMODE_READ | FMODE_WRITE | FMODE_EXCL);
		if (nbc->md_bdev)
			blkdev_put(nbc->md_bdev,
				   FMODE_READ | FMODE_WRITE | FMODE_EXCL);
P
Philipp Reisner 已提交
1810 1811
		kfree(nbc);
	}
P
Philipp Reisner 已提交
1812
	kfree(new_disk_conf);
P
Philipp Reisner 已提交
1813
	lc_destroy(resync_lru);
1814
	kfree(new_plan);
P
Philipp Reisner 已提交
1815

1816
 finish:
1817
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
1818 1819 1820
	return 0;
}

1821
static int adm_detach(struct drbd_device *device, int force)
P
Philipp Reisner 已提交
1822
{
1823
	enum drbd_state_rv retcode;
L
Lars Ellenberg 已提交
1824
	int ret;
1825

1826
	if (force) {
1827 1828
		set_bit(FORCE_DETACH, &device->flags);
		drbd_force_state(device, NS(disk, D_FAILED));
1829
		retcode = SS_SUCCESS;
1830 1831 1832
		goto out;
	}

1833 1834 1835 1836
	drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
	drbd_md_get_buffer(device); /* make sure there is no in-flight meta-data IO */
	retcode = drbd_request_state(device, NS(disk, D_FAILED));
	drbd_md_put_buffer(device);
L
Lars Ellenberg 已提交
1837
	/* D_FAILED will transition to DISKLESS. */
1838 1839 1840
	ret = wait_event_interruptible(device->misc_wait,
			device->state.disk != D_FAILED);
	drbd_resume_io(device);
P
Philipp Reisner 已提交
1841
	if ((int)retcode == (int)SS_IS_DISKLESS)
L
Lars Ellenberg 已提交
1842 1843 1844
		retcode = SS_NOTHING_TO_DO;
	if (ret)
		retcode = ERR_INTR;
1845
out:
1846
	return retcode;
P
Philipp Reisner 已提交
1847 1848
}

1849 1850 1851 1852 1853
/* Detaching the disk is a process in multiple stages.  First we need to lock
 * out application IO, in-flight IO, IO stuck in drbd_al_begin_io.
 * Then we transition to D_DISKLESS, and wait for put_ldev() to return all
 * internal references as well.
 * Only then we have finally detached. */
1854
int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
1855
{
1856
	enum drbd_ret_code retcode;
1857 1858
	struct detach_parms parms = { };
	int err;
P
Philipp Reisner 已提交
1859

1860 1861 1862 1863 1864
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
1865

1866 1867 1868 1869 1870 1871 1872
	if (info->attrs[DRBD_NLA_DETACH_PARMS]) {
		err = detach_parms_from_attrs(&parms, info);
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
			goto out;
		}
P
Philipp Reisner 已提交
1873 1874
	}

1875
	retcode = adm_detach(adm_ctx.device, parms.force_detach);
1876 1877
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
1878 1879 1880
	return 0;
}

1881
static bool conn_resync_running(struct drbd_connection *connection)
1882
{
1883
	struct drbd_peer_device *peer_device;
1884
	bool rv = false;
1885 1886
	int vnr;

1887
	rcu_read_lock();
1888 1889
	idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
		struct drbd_device *device = peer_device->device;
1890 1891 1892 1893
		if (device->state.conn == C_SYNC_SOURCE ||
		    device->state.conn == C_SYNC_TARGET ||
		    device->state.conn == C_PAUSED_SYNC_S ||
		    device->state.conn == C_PAUSED_SYNC_T) {
1894 1895 1896
			rv = true;
			break;
		}
P
Philipp Reisner 已提交
1897
	}
1898
	rcu_read_unlock();
P
Philipp Reisner 已提交
1899

1900
	return rv;
1901
}
1902

1903
static bool conn_ov_running(struct drbd_connection *connection)
1904
{
1905
	struct drbd_peer_device *peer_device;
1906
	bool rv = false;
1907 1908
	int vnr;

1909
	rcu_read_lock();
1910 1911
	idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
		struct drbd_device *device = peer_device->device;
1912 1913
		if (device->state.conn == C_VERIFY_S ||
		    device->state.conn == C_VERIFY_T) {
1914 1915
			rv = true;
			break;
1916 1917
		}
	}
1918
	rcu_read_unlock();
P
Philipp Reisner 已提交
1919

1920
	return rv;
1921
}
1922

1923
static enum drbd_ret_code
1924
_check_net_options(struct drbd_connection *connection, struct net_conf *old_conf, struct net_conf *new_conf)
1925
{
1926
	struct drbd_peer_device *peer_device;
1927
	int i;
P
Philipp Reisner 已提交
1928

1929
	if (old_conf && connection->cstate == C_WF_REPORT_PARAMS && connection->agreed_pro_version < 100) {
1930 1931
		if (new_conf->wire_protocol != old_conf->wire_protocol)
			return ERR_NEED_APV_100;
P
Philipp Reisner 已提交
1932

1933 1934 1935 1936 1937
		if (new_conf->two_primaries != old_conf->two_primaries)
			return ERR_NEED_APV_100;

		if (strcmp(new_conf->integrity_alg, old_conf->integrity_alg))
			return ERR_NEED_APV_100;
P
Philipp Reisner 已提交
1938 1939
	}

1940
	if (!new_conf->two_primaries &&
1941 1942
	    conn_highest_role(connection) == R_PRIMARY &&
	    conn_highest_peer(connection) == R_PRIMARY)
1943
		return ERR_NEED_ALLOW_TWO_PRI;
P
Philipp Reisner 已提交
1944

1945 1946 1947 1948
	if (new_conf->two_primaries &&
	    (new_conf->wire_protocol != DRBD_PROT_C))
		return ERR_NOT_PROTO_C;

1949 1950
	idr_for_each_entry(&connection->peer_devices, peer_device, i) {
		struct drbd_device *device = peer_device->device;
1951 1952 1953
		if (get_ldev(device)) {
			enum drbd_fencing_p fp = rcu_dereference(device->ldev->disk_conf)->fencing;
			put_ldev(device);
1954
			if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH)
1955
				return ERR_STONITH_AND_PROT_A;
P
Philipp Reisner 已提交
1956
		}
1957
		if (device->state.role == R_PRIMARY && new_conf->discard_my_data)
1958
			return ERR_DISCARD_IMPOSSIBLE;
P
Philipp Reisner 已提交
1959 1960
	}

1961 1962
	if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A)
		return ERR_CONG_NOT_PROTO_A;
P
Philipp Reisner 已提交
1963

1964 1965
	return NO_ERROR;
}
P
Philipp Reisner 已提交
1966

1967
static enum drbd_ret_code
1968
check_net_options(struct drbd_connection *connection, struct net_conf *new_conf)
1969 1970
{
	static enum drbd_ret_code rv;
1971
	struct drbd_peer_device *peer_device;
1972
	int i;
P
Philipp Reisner 已提交
1973

1974
	rcu_read_lock();
1975
	rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_conf);
1976
	rcu_read_unlock();
P
Philipp Reisner 已提交
1977

1978
	/* connection->volumes protected by genl_lock() here */
1979 1980
	idr_for_each_entry(&connection->peer_devices, peer_device, i) {
		struct drbd_device *device = peer_device->device;
1981 1982
		if (!device->bitmap) {
			if (drbd_bm_init(device))
1983
				return ERR_NOMEM;
P
Philipp Reisner 已提交
1984 1985 1986
		}
	}

1987 1988
	return rv;
}
P
Philipp Reisner 已提交
1989

1990 1991 1992 1993
struct crypto {
	struct crypto_hash *verify_tfm;
	struct crypto_hash *csums_tfm;
	struct crypto_hash *cram_hmac_tfm;
1994
	struct crypto_hash *integrity_tfm;
1995
};
P
Philipp Reisner 已提交
1996

1997
static int
1998
alloc_hash(struct crypto_hash **tfm, char *tfm_name, int err_alg)
1999 2000 2001
{
	if (!tfm_name[0])
		return NO_ERROR;
P
Philipp Reisner 已提交
2002

2003 2004 2005 2006
	*tfm = crypto_alloc_hash(tfm_name, 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(*tfm)) {
		*tfm = NULL;
		return err_alg;
P
Philipp Reisner 已提交
2007 2008
	}

2009 2010
	return NO_ERROR;
}
P
Philipp Reisner 已提交
2011

2012 2013 2014 2015 2016 2017
static enum drbd_ret_code
alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
{
	char hmac_name[CRYPTO_MAX_ALG_NAME];
	enum drbd_ret_code rv;

2018 2019
	rv = alloc_hash(&crypto->csums_tfm, new_conf->csums_alg,
		       ERR_CSUMS_ALG);
2020 2021
	if (rv != NO_ERROR)
		return rv;
2022 2023
	rv = alloc_hash(&crypto->verify_tfm, new_conf->verify_alg,
		       ERR_VERIFY_ALG);
2024 2025
	if (rv != NO_ERROR)
		return rv;
2026 2027
	rv = alloc_hash(&crypto->integrity_tfm, new_conf->integrity_alg,
		       ERR_INTEGRITY_ALG);
2028 2029 2030 2031 2032
	if (rv != NO_ERROR)
		return rv;
	if (new_conf->cram_hmac_alg[0] != 0) {
		snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
			 new_conf->cram_hmac_alg);
P
Philipp Reisner 已提交
2033

2034 2035
		rv = alloc_hash(&crypto->cram_hmac_tfm, hmac_name,
			       ERR_AUTH_ALG);
P
Philipp Reisner 已提交
2036 2037
	}

2038 2039
	return rv;
}
P
Philipp Reisner 已提交
2040

2041 2042 2043
static void free_crypto(struct crypto *crypto)
{
	crypto_free_hash(crypto->cram_hmac_tfm);
2044
	crypto_free_hash(crypto->integrity_tfm);
2045 2046 2047
	crypto_free_hash(crypto->csums_tfm);
	crypto_free_hash(crypto->verify_tfm);
}
P
Philipp Reisner 已提交
2048

2049 2050 2051
int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
{
	enum drbd_ret_code retcode;
2052
	struct drbd_connection *connection;
2053
	struct net_conf *old_conf, *new_conf = NULL;
2054 2055 2056
	int err;
	int ovr; /* online verify running */
	int rsr; /* re-sync running */
2057
	struct crypto crypto = { };
P
Philipp Reisner 已提交
2058

2059
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION);
2060 2061 2062 2063
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
2064

2065
	connection = adm_ctx.connection;
P
Philipp Reisner 已提交
2066

2067 2068 2069 2070 2071
	new_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
	if (!new_conf) {
		retcode = ERR_NOMEM;
		goto out;
	}
P
Philipp Reisner 已提交
2072

2073
	conn_reconfig_start(connection);
P
Philipp Reisner 已提交
2074

2075 2076 2077
	mutex_lock(&connection->data.mutex);
	mutex_lock(&connection->conf_update);
	old_conf = connection->net_conf;
2078

2079
	if (!old_conf) {
2080 2081
		drbd_msg_put_info("net conf missing, try connect");
		retcode = ERR_INVALID_REQUEST;
2082 2083 2084
		goto fail;
	}

2085
	*new_conf = *old_conf;
2086
	if (should_set_defaults(info))
2087
		set_net_conf_defaults(new_conf);
2088 2089

	err = net_conf_from_attrs_for_change(new_conf, info);
2090
	if (err && err != -ENOMSG) {
2091 2092 2093
		retcode = ERR_MANDATORY_TAG;
		drbd_msg_put_info(from_attrs_err_to_txt(err));
		goto fail;
2094
	}
P
Philipp Reisner 已提交
2095

2096
	retcode = check_net_options(connection, new_conf);
2097 2098
	if (retcode != NO_ERROR)
		goto fail;
P
Philipp Reisner 已提交
2099

2100
	/* re-sync running */
2101
	rsr = conn_resync_running(connection);
2102
	if (rsr && strcmp(new_conf->csums_alg, old_conf->csums_alg)) {
2103
		retcode = ERR_CSUMS_RESYNC_RUNNING;
2104
		goto fail;
P
Philipp Reisner 已提交
2105 2106
	}

2107
	/* online verify running */
2108
	ovr = conn_ov_running(connection);
2109 2110
	if (ovr && strcmp(new_conf->verify_alg, old_conf->verify_alg)) {
		retcode = ERR_VERIFY_RUNNING;
P
Philipp Reisner 已提交
2111
		goto fail;
2112
	}
P
Philipp Reisner 已提交
2113

2114 2115
	retcode = alloc_crypto(&crypto, new_conf);
	if (retcode != NO_ERROR)
P
Philipp Reisner 已提交
2116
		goto fail;
2117

2118
	rcu_assign_pointer(connection->net_conf, new_conf);
2119 2120

	if (!rsr) {
2121 2122
		crypto_free_hash(connection->csums_tfm);
		connection->csums_tfm = crypto.csums_tfm;
2123
		crypto.csums_tfm = NULL;
2124 2125
	}
	if (!ovr) {
2126 2127
		crypto_free_hash(connection->verify_tfm);
		connection->verify_tfm = crypto.verify_tfm;
2128
		crypto.verify_tfm = NULL;
P
Philipp Reisner 已提交
2129 2130
	}

2131 2132 2133 2134 2135
	crypto_free_hash(connection->integrity_tfm);
	connection->integrity_tfm = crypto.integrity_tfm;
	if (connection->cstate >= C_WF_REPORT_PARAMS && connection->agreed_pro_version >= 100)
		/* Do this without trying to take connection->data.mutex again.  */
		__drbd_send_protocol(connection, P_PROTOCOL_UPDATE);
2136

2137 2138
	crypto_free_hash(connection->cram_hmac_tfm);
	connection->cram_hmac_tfm = crypto.cram_hmac_tfm;
2139

2140 2141
	mutex_unlock(&connection->conf_update);
	mutex_unlock(&connection->data.mutex);
2142 2143 2144
	synchronize_rcu();
	kfree(old_conf);

2145 2146
	if (connection->cstate >= C_WF_REPORT_PARAMS)
		drbd_send_sync_param(minor_to_device(conn_lowest_minor(connection)));
2147

2148 2149
	goto done;

P
Philipp Reisner 已提交
2150
 fail:
2151 2152
	mutex_unlock(&connection->conf_update);
	mutex_unlock(&connection->data.mutex);
2153
	free_crypto(&crypto);
2154
	kfree(new_conf);
2155
 done:
2156
	conn_reconfig_done(connection);
2157 2158
 out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2159 2160 2161
	return 0;
}

2162
int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2163
{
2164
	struct drbd_peer_device *peer_device;
2165
	struct net_conf *old_conf, *new_conf = NULL;
2166
	struct crypto crypto = { };
2167
	struct drbd_resource *resource;
2168
	struct drbd_connection *connection;
2169 2170 2171
	enum drbd_ret_code retcode;
	int i;
	int err;
P
Philipp Reisner 已提交
2172

2173
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
P
Philipp Reisner 已提交
2174

2175 2176 2177 2178
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
2179 2180 2181 2182 2183
	if (!(adm_ctx.my_addr && adm_ctx.peer_addr)) {
		drbd_msg_put_info("connection endpoint(s) missing");
		retcode = ERR_INVALID_REQUEST;
		goto out;
	}
P
Philipp Reisner 已提交
2184

2185 2186 2187
	/* No need for _rcu here. All reconfiguration is
	 * strictly serialized on genl_lock(). We are protected against
	 * concurrent reconfiguration/addition/deletion */
2188 2189 2190 2191 2192 2193 2194 2195
	for_each_resource(resource, &drbd_resources) {
		for_each_connection(connection, resource) {
			if (nla_len(adm_ctx.my_addr) == connection->my_addr_len &&
			    !memcmp(nla_data(adm_ctx.my_addr), &connection->my_addr,
				    connection->my_addr_len)) {
				retcode = ERR_LOCAL_ADDR;
				goto out;
			}
P
Philipp Reisner 已提交
2196

2197 2198 2199 2200 2201 2202
			if (nla_len(adm_ctx.peer_addr) == connection->peer_addr_len &&
			    !memcmp(nla_data(adm_ctx.peer_addr), &connection->peer_addr,
				    connection->peer_addr_len)) {
				retcode = ERR_PEER_ADDR;
				goto out;
			}
2203
		}
P
Philipp Reisner 已提交
2204 2205
	}

2206 2207
	connection = adm_ctx.connection;
	conn_reconfig_start(connection);
P
Philipp Reisner 已提交
2208

2209
	if (connection->cstate > C_STANDALONE) {
P
Philipp Reisner 已提交
2210 2211 2212 2213
		retcode = ERR_NET_CONFIGURED;
		goto fail;
	}

2214
	/* allocation not in the IO path, drbdsetup / netlink process context */
2215
	new_conf = kzalloc(sizeof(*new_conf), GFP_KERNEL);
P
Philipp Reisner 已提交
2216 2217 2218 2219 2220
	if (!new_conf) {
		retcode = ERR_NOMEM;
		goto fail;
	}

2221
	set_net_conf_defaults(new_conf);
P
Philipp Reisner 已提交
2222

2223
	err = net_conf_from_attrs(new_conf, info);
2224
	if (err && err != -ENOMSG) {
P
Philipp Reisner 已提交
2225
		retcode = ERR_MANDATORY_TAG;
2226
		drbd_msg_put_info(from_attrs_err_to_txt(err));
P
Philipp Reisner 已提交
2227 2228 2229
		goto fail;
	}

2230
	retcode = check_net_options(connection, new_conf);
2231
	if (retcode != NO_ERROR)
2232
		goto fail;
P
Philipp Reisner 已提交
2233

2234 2235 2236
	retcode = alloc_crypto(&crypto, new_conf);
	if (retcode != NO_ERROR)
		goto fail;
P
Philipp Reisner 已提交
2237 2238

	((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
2239

2240
	conn_flush_workqueue(connection);
P
Philipp Reisner 已提交
2241

2242 2243
	mutex_lock(&connection->conf_update);
	old_conf = connection->net_conf;
2244
	if (old_conf) {
P
Philipp Reisner 已提交
2245
		retcode = ERR_NET_CONFIGURED;
2246
		mutex_unlock(&connection->conf_update);
P
Philipp Reisner 已提交
2247 2248
		goto fail;
	}
2249
	rcu_assign_pointer(connection->net_conf, new_conf);
P
Philipp Reisner 已提交
2250

2251 2252 2253 2254 2255
	conn_free_crypto(connection);
	connection->cram_hmac_tfm = crypto.cram_hmac_tfm;
	connection->integrity_tfm = crypto.integrity_tfm;
	connection->csums_tfm = crypto.csums_tfm;
	connection->verify_tfm = crypto.verify_tfm;
P
Philipp Reisner 已提交
2256

2257 2258 2259 2260
	connection->my_addr_len = nla_len(adm_ctx.my_addr);
	memcpy(&connection->my_addr, nla_data(adm_ctx.my_addr), connection->my_addr_len);
	connection->peer_addr_len = nla_len(adm_ctx.peer_addr);
	memcpy(&connection->peer_addr, nla_data(adm_ctx.peer_addr), connection->peer_addr_len);
P
Philipp Reisner 已提交
2261

2262
	mutex_unlock(&connection->conf_update);
P
Philipp Reisner 已提交
2263

2264
	rcu_read_lock();
2265 2266
	idr_for_each_entry(&connection->peer_devices, peer_device, i) {
		struct drbd_device *device = peer_device->device;
2267 2268
		device->send_cnt = 0;
		device->recv_cnt = 0;
P
Philipp Reisner 已提交
2269
	}
2270
	rcu_read_unlock();
P
Philipp Reisner 已提交
2271

2272
	retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE);
P
Philipp Reisner 已提交
2273

2274
	conn_reconfig_done(connection);
2275
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2276 2277 2278
	return 0;

fail:
2279
	free_crypto(&crypto);
P
Philipp Reisner 已提交
2280 2281
	kfree(new_conf);

2282
	conn_reconfig_done(connection);
2283 2284
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2285 2286 2287
	return 0;
}

2288
static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection, bool force)
2289 2290 2291
{
	enum drbd_state_rv rv;

2292
	rv = conn_request_state(connection, NS(conn, C_DISCONNECTING),
2293
			force ? CS_HARD : 0);
2294 2295 2296

	switch (rv) {
	case SS_NOTHING_TO_DO:
2297
		break;
2298 2299 2300 2301
	case SS_ALREADY_STANDALONE:
		return SS_SUCCESS;
	case SS_PRIMARY_NOP:
		/* Our state checking code wants to see the peer outdated. */
2302
		rv = conn_request_state(connection, NS2(conn, C_DISCONNECTING, pdsk, D_OUTDATED), 0);
2303 2304

		if (rv == SS_OUTDATE_WO_CONN) /* lost connection before graceful disconnect succeeded */
2305
			rv = conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_VERBOSE);
2306

2307 2308 2309
		break;
	case SS_CW_FAILED_BY_PEER:
		/* The peer probably wants to see us outdated. */
2310
		rv = conn_request_state(connection, NS2(conn, C_DISCONNECTING,
2311 2312
							disk, D_OUTDATED), 0);
		if (rv == SS_IS_DISKLESS || rv == SS_LOWER_THAN_OUTDATED) {
2313
			rv = conn_request_state(connection, NS(conn, C_DISCONNECTING),
2314
					CS_HARD);
P
Philipp Reisner 已提交
2315
		}
2316 2317 2318 2319 2320
		break;
	default:;
		/* no special handling necessary */
	}

2321 2322 2323 2324 2325 2326
	if (rv >= SS_SUCCESS) {
		enum drbd_state_rv rv2;
		/* No one else can reconfigure the network while I am here.
		 * The state handling only uses drbd_thread_stop_nowait(),
		 * we want to really wait here until the receiver is no more.
		 */
2327
		drbd_thread_stop(&connection->receiver);
2328 2329 2330 2331 2332 2333 2334

		/* Race breaker.  This additional state change request may be
		 * necessary, if this was a forced disconnect during a receiver
		 * restart.  We may have "killed" the receiver thread just
		 * after drbdd_init() returned.  Typically, we should be
		 * C_STANDALONE already, now, and this becomes a no-op.
		 */
2335
		rv2 = conn_request_state(connection, NS(conn, C_STANDALONE),
2336 2337
				CS_VERBOSE | CS_HARD);
		if (rv2 < SS_SUCCESS)
2338
			drbd_err(connection,
2339 2340
				"unexpected rv2=%d in conn_try_disconnect()\n",
				rv2);
P
Philipp Reisner 已提交
2341
	}
2342 2343
	return rv;
}
P
Philipp Reisner 已提交
2344

2345
int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2346
{
2347
	struct disconnect_parms parms;
2348
	struct drbd_connection *connection;
2349
	enum drbd_state_rv rv;
2350 2351
	enum drbd_ret_code retcode;
	int err;
2352

2353
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION);
2354 2355 2356
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
2357
		goto fail;
P
Philipp Reisner 已提交
2358

2359
	connection = adm_ctx.connection;
2360 2361
	memset(&parms, 0, sizeof(parms));
	if (info->attrs[DRBD_NLA_DISCONNECT_PARMS]) {
2362
		err = disconnect_parms_from_attrs(&parms, info);
2363 2364 2365
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
P
Philipp Reisner 已提交
2366 2367 2368 2369
			goto fail;
		}
	}

2370
	rv = conn_try_disconnect(connection, parms.force_disconnect);
2371
	if (rv < SS_SUCCESS)
2372 2373 2374
		retcode = rv;  /* FIXME: Type mismatch. */
	else
		retcode = NO_ERROR;
P
Philipp Reisner 已提交
2375
 fail:
2376
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2377 2378 2379
	return 0;
}

2380
void resync_after_online_grow(struct drbd_device *device)
P
Philipp Reisner 已提交
2381 2382 2383
{
	int iass; /* I am sync source */

2384
	drbd_info(device, "Resync of new storage after online grow\n");
2385 2386
	if (device->state.role != device->state.peer)
		iass = (device->state.role == R_PRIMARY);
P
Philipp Reisner 已提交
2387
	else
2388
		iass = test_bit(RESOLVE_CONFLICTS, &first_peer_device(device)->connection->flags);
P
Philipp Reisner 已提交
2389 2390

	if (iass)
2391
		drbd_start_resync(device, C_SYNC_SOURCE);
P
Philipp Reisner 已提交
2392
	else
2393
		_drbd_request_state(device, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE + CS_SERIALIZE);
P
Philipp Reisner 已提交
2394 2395
}

2396
int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2397
{
P
Philipp Reisner 已提交
2398
	struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
2399
	struct resize_parms rs;
2400
	struct drbd_device *device;
2401
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
2402
	enum determine_dev_size dd;
2403
	bool change_al_layout = false;
2404
	enum dds_flags ddsf;
P
Philipp Reisner 已提交
2405
	sector_t u_size;
2406
	int err;
P
Philipp Reisner 已提交
2407

2408 2409 2410 2411
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
P
Philipp Reisner 已提交
2412
		goto fail;
2413

2414 2415
	device = adm_ctx.device;
	if (!get_ldev(device)) {
2416 2417 2418 2419
		retcode = ERR_NO_DISK;
		goto fail;
	}

2420
	memset(&rs, 0, sizeof(struct resize_parms));
2421 2422
	rs.al_stripes = device->ldev->md.al_stripes;
	rs.al_stripe_size = device->ldev->md.al_stripe_size_4k * 4;
2423
	if (info->attrs[DRBD_NLA_RESIZE_PARMS]) {
2424
		err = resize_parms_from_attrs(&rs, info);
P
Philipp Reisner 已提交
2425
		if (err) {
2426 2427
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
2428
			goto fail_ldev;
P
Philipp Reisner 已提交
2429 2430 2431
		}
	}

2432
	if (device->state.conn > C_CONNECTED) {
P
Philipp Reisner 已提交
2433
		retcode = ERR_RESIZE_RESYNC;
2434
		goto fail_ldev;
P
Philipp Reisner 已提交
2435 2436
	}

2437 2438
	if (device->state.role == R_SECONDARY &&
	    device->state.peer == R_SECONDARY) {
P
Philipp Reisner 已提交
2439
		retcode = ERR_NO_PRIMARY;
2440
		goto fail_ldev;
P
Philipp Reisner 已提交
2441 2442
	}

2443
	if (rs.no_resync && first_peer_device(device)->connection->agreed_pro_version < 93) {
2444
		retcode = ERR_NEED_APV_93;
P
Philipp Reisner 已提交
2445
		goto fail_ldev;
2446 2447
	}

P
Philipp Reisner 已提交
2448
	rcu_read_lock();
2449
	u_size = rcu_dereference(device->ldev->disk_conf)->disk_size;
P
Philipp Reisner 已提交
2450 2451 2452 2453
	rcu_read_unlock();
	if (u_size != (sector_t)rs.resize_size) {
		new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL);
		if (!new_disk_conf) {
2454
			retcode = ERR_NOMEM;
P
Philipp Reisner 已提交
2455
			goto fail_ldev;
2456 2457 2458
		}
	}

2459 2460
	if (device->ldev->md.al_stripes != rs.al_stripes ||
	    device->ldev->md.al_stripe_size_4k != rs.al_stripe_size / 4) {
2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472
		u32 al_size_k = rs.al_stripes * rs.al_stripe_size;

		if (al_size_k > (16 * 1024 * 1024)) {
			retcode = ERR_MD_LAYOUT_TOO_BIG;
			goto fail_ldev;
		}

		if (al_size_k < MD_32kB_SECT/2) {
			retcode = ERR_MD_LAYOUT_TOO_SMALL;
			goto fail_ldev;
		}

2473
		if (device->state.conn != C_CONNECTED) {
2474 2475 2476 2477 2478 2479 2480
			retcode = ERR_MD_LAYOUT_CONNECTED;
			goto fail_ldev;
		}

		change_al_layout = true;
	}

2481 2482
	if (device->ldev->known_size != drbd_get_capacity(device->ldev->backing_bdev))
		device->ldev->known_size = drbd_get_capacity(device->ldev->backing_bdev);
P
Philipp Reisner 已提交
2483

P
Philipp Reisner 已提交
2484
	if (new_disk_conf) {
2485
		mutex_lock(&first_peer_device(device)->connection->conf_update);
2486
		old_disk_conf = device->ldev->disk_conf;
P
Philipp Reisner 已提交
2487 2488
		*new_disk_conf = *old_disk_conf;
		new_disk_conf->disk_size = (sector_t)rs.resize_size;
2489
		rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
2490
		mutex_unlock(&first_peer_device(device)->connection->conf_update);
P
Philipp Reisner 已提交
2491 2492
		synchronize_rcu();
		kfree(old_disk_conf);
P
Philipp Reisner 已提交
2493 2494
	}

2495
	ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
2496 2497 2498
	dd = drbd_determine_dev_size(device, ddsf, change_al_layout ? &rs : NULL);
	drbd_md_sync(device);
	put_ldev(device);
2499
	if (dd == DS_ERROR) {
P
Philipp Reisner 已提交
2500 2501
		retcode = ERR_NOMEM_BITMAP;
		goto fail;
2502 2503 2504 2505 2506 2507
	} else if (dd == DS_ERROR_SPACE_MD) {
		retcode = ERR_MD_LAYOUT_NO_FIT;
		goto fail;
	} else if (dd == DS_ERROR_SHRINK) {
		retcode = ERR_IMPLICIT_SHRINK;
		goto fail;
P
Philipp Reisner 已提交
2508
	}
2509

2510
	if (device->state.conn == C_CONNECTED) {
2511
		if (dd == DS_GREW)
2512
			set_bit(RESIZE_PENDING, &device->flags);
P
Philipp Reisner 已提交
2513

2514 2515
		drbd_send_uuids(device);
		drbd_send_sizes(device, 1, ddsf);
2516 2517
	}

P
Philipp Reisner 已提交
2518
 fail:
2519
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2520 2521
	return 0;

P
Philipp Reisner 已提交
2522
 fail_ldev:
2523
	put_ldev(device);
P
Philipp Reisner 已提交
2524
	goto fail;
P
Philipp Reisner 已提交
2525 2526
}

2527
int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2528
{
2529
	enum drbd_ret_code retcode;
2530
	struct res_opts res_opts;
2531
	int err;
P
Philipp Reisner 已提交
2532

2533
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
2534 2535 2536 2537
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto fail;
P
Philipp Reisner 已提交
2538

2539
	res_opts = adm_ctx.resource->res_opts;
2540
	if (should_set_defaults(info))
2541
		set_res_opts_defaults(&res_opts);
P
Philipp Reisner 已提交
2542

2543
	err = res_opts_from_attrs(&res_opts, info);
2544
	if (err && err != -ENOMSG) {
P
Philipp Reisner 已提交
2545
		retcode = ERR_MANDATORY_TAG;
2546
		drbd_msg_put_info(from_attrs_err_to_txt(err));
P
Philipp Reisner 已提交
2547 2548 2549
		goto fail;
	}

2550
	err = set_resource_options(adm_ctx.resource, &res_opts);
2551 2552 2553 2554
	if (err) {
		retcode = ERR_INVALID_REQUEST;
		if (err == -ENOMEM)
			retcode = ERR_NOMEM;
P
Philipp Reisner 已提交
2555 2556 2557
	}

fail:
2558
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2559 2560 2561
	return 0;
}

2562
int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2563
{
2564
	struct drbd_device *device;
2565 2566 2567 2568 2569 2570 2571 2572
	int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;

2573
	device = adm_ctx.device;
P
Philipp Reisner 已提交
2574

2575
	/* If there is still bitmap IO pending, probably because of a previous
2576 2577
	 * resync just being finished, wait for it before requesting a new resync.
	 * Also wait for it's after_state_ch(). */
2578 2579 2580
	drbd_suspend_io(device);
	wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
	drbd_flush_workqueue(device);
2581

2582 2583 2584
	/* If we happen to be C_STANDALONE R_SECONDARY, just change to
	 * D_INCONSISTENT, and set all bits in the bitmap.  Otherwise,
	 * try to start a resync handshake as sync target for full sync.
2585
	 */
2586 2587
	if (device->state.conn == C_STANDALONE && device->state.role == R_SECONDARY) {
		retcode = drbd_request_state(device, NS(disk, D_INCONSISTENT));
2588
		if (retcode >= SS_SUCCESS) {
2589
			if (drbd_bitmap_io(device, &drbd_bmio_set_n_write,
2590 2591 2592 2593
				"set_n_write from invalidate", BM_LOCKED_MASK))
				retcode = ERR_IO_MD_DISK;
		}
	} else
2594 2595
		retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_T));
	drbd_resume_io(device);
P
Philipp Reisner 已提交
2596

2597 2598
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2599 2600 2601
	return 0;
}

2602 2603
static int drbd_adm_simple_request_state(struct sk_buff *skb, struct genl_info *info,
		union drbd_state mask, union drbd_state val)
P
Philipp Reisner 已提交
2604
{
2605
	enum drbd_ret_code retcode;
2606

2607 2608 2609 2610 2611
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
2612

2613
	retcode = drbd_request_state(adm_ctx.device, mask, val);
2614 2615
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2616 2617 2618
	return 0;
}

2619
static int drbd_bmio_set_susp_al(struct drbd_device *device)
2620 2621 2622
{
	int rv;

2623 2624
	rv = drbd_bmio_set_n_write(device);
	drbd_suspend_al(device);
2625 2626 2627
	return rv;
}

2628
int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2629
{
2630
	int retcode; /* drbd_ret_code, drbd_state_rv */
2631
	struct drbd_device *device;
2632 2633 2634 2635 2636 2637 2638

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;

2639
	device = adm_ctx.device;
P
Philipp Reisner 已提交
2640

2641
	/* If there is still bitmap IO pending, probably because of a previous
2642 2643
	 * resync just being finished, wait for it before requesting a new resync.
	 * Also wait for it's after_state_ch(). */
2644 2645 2646
	drbd_suspend_io(device);
	wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
	drbd_flush_workqueue(device);
2647

2648 2649 2650 2651
	/* If we happen to be C_STANDALONE R_PRIMARY, just set all bits
	 * in the bitmap.  Otherwise, try to start a resync handshake
	 * as sync source for full sync.
	 */
2652
	if (device->state.conn == C_STANDALONE && device->state.role == R_PRIMARY) {
2653 2654
		/* The peer will get a resync upon connect anyways. Just make that
		   into a full resync. */
2655
		retcode = drbd_request_state(device, NS(pdsk, D_INCONSISTENT));
2656
		if (retcode >= SS_SUCCESS) {
2657
			if (drbd_bitmap_io(device, &drbd_bmio_set_susp_al,
2658 2659 2660 2661 2662
				"set_n_write from invalidate_peer",
				BM_LOCKED_SET_ALLOWED))
				retcode = ERR_IO_MD_DISK;
		}
	} else
2663 2664
		retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_S));
	drbd_resume_io(device);
P
Philipp Reisner 已提交
2665

2666 2667
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2668 2669 2670
	return 0;
}

2671
int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2672
{
2673
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
2674

2675 2676 2677 2678 2679
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
2680

2681
	if (drbd_request_state(adm_ctx.device, NS(user_isp, 1)) == SS_NOTHING_TO_DO)
2682 2683 2684
		retcode = ERR_PAUSE_IS_SET;
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2685 2686 2687
	return 0;
}

2688
int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2689
{
2690
	union drbd_dev_state s;
2691 2692 2693 2694 2695 2696 2697
	enum drbd_ret_code retcode;

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
2698

2699 2700
	if (drbd_request_state(adm_ctx.device, NS(user_isp, 0)) == SS_NOTHING_TO_DO) {
		s = adm_ctx.device->state;
2701 2702 2703 2704 2705 2706 2707
		if (s.conn == C_PAUSED_SYNC_S || s.conn == C_PAUSED_SYNC_T) {
			retcode = s.aftr_isp ? ERR_PIC_AFTER_DEP :
				  s.peer_isp ? ERR_PIC_PEER_DEP : ERR_PAUSE_IS_CLEAR;
		} else {
			retcode = ERR_PAUSE_IS_CLEAR;
		}
	}
P
Philipp Reisner 已提交
2708

2709 2710
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2711 2712 2713
	return 0;
}

2714
int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2715
{
2716
	return drbd_adm_simple_request_state(skb, info, NS(susp, 1));
P
Philipp Reisner 已提交
2717 2718
}

2719
int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2720
{
2721
	struct drbd_device *device;
2722 2723 2724 2725 2726 2727 2728 2729
	int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;

2730 2731 2732 2733
	device = adm_ctx.device;
	if (test_bit(NEW_CUR_UUID, &device->flags)) {
		drbd_uuid_new_current(device);
		clear_bit(NEW_CUR_UUID, &device->flags);
2734
	}
2735 2736
	drbd_suspend_io(device);
	retcode = drbd_request_state(device, NS3(susp, 0, susp_nod, 0, susp_fen, 0));
2737
	if (retcode == SS_SUCCESS) {
2738
		if (device->state.conn < C_CONNECTED)
2739
			tl_clear(first_peer_device(device)->connection);
2740
		if (device->state.disk == D_DISKLESS || device->state.disk == D_FAILED)
2741
			tl_restart(first_peer_device(device)->connection, FAIL_FROZEN_DISK_IO);
2742
	}
2743
	drbd_resume_io(device);
2744

2745 2746
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
2747 2748 2749
	return 0;
}

2750
int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2751
{
2752
	return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED));
P
Philipp Reisner 已提交
2753 2754
}

2755
static int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_connection *connection, unsigned vnr)
P
Philipp Reisner 已提交
2756
{
2757 2758 2759 2760
	struct nlattr *nla;
	nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT);
	if (!nla)
		goto nla_put_failure;
A
Andreas Gruenbacher 已提交
2761 2762 2763
	if (vnr != VOLUME_UNSPECIFIED &&
	    nla_put_u32(skb, T_ctx_volume, vnr))
		goto nla_put_failure;
2764
	if (nla_put_string(skb, T_ctx_resource_name, connection->resource->name))
A
Andreas Gruenbacher 已提交
2765
		goto nla_put_failure;
2766 2767
	if (connection->my_addr_len &&
	    nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr))
A
Andreas Gruenbacher 已提交
2768
		goto nla_put_failure;
2769 2770
	if (connection->peer_addr_len &&
	    nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr))
A
Andreas Gruenbacher 已提交
2771
		goto nla_put_failure;
2772 2773
	nla_nest_end(skb, nla);
	return 0;
P
Philipp Reisner 已提交
2774

2775 2776 2777 2778 2779
nla_put_failure:
	if (nla)
		nla_nest_cancel(skb, nla);
	return -EMSGSIZE;
}
P
Philipp Reisner 已提交
2780

2781
static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
2782
		const struct sib_info *sib)
P
Philipp Reisner 已提交
2783
{
2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802
	struct state_info *si = NULL; /* for sizeof(si->member); */
	struct nlattr *nla;
	int got_ldev;
	int err = 0;
	int exclude_sensitive;

	/* If sib != NULL, this is drbd_bcast_event, which anyone can listen
	 * to.  So we better exclude_sensitive information.
	 *
	 * If sib == NULL, this is drbd_adm_get_status, executed synchronously
	 * in the context of the requesting user process. Exclude sensitive
	 * information, unless current has superuser.
	 *
	 * NOTE: for drbd_adm_get_status_all(), this is a netlink dump, and
	 * relies on the current implementation of netlink_dump(), which
	 * executes the dump callback successively from netlink_recvmsg(),
	 * always in the context of the receiving process */
	exclude_sensitive = sib || !capable(CAP_SYS_ADMIN);

2803
	got_ldev = get_ldev(device);
2804 2805 2806

	/* We need to add connection name and volume number information still.
	 * Minor number is in drbd_genlmsghdr. */
2807
	if (nla_put_drbd_cfg_context(skb, first_peer_device(device)->connection, device->vnr))
2808 2809
		goto nla_put_failure;

2810
	if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive))
2811 2812
		goto nla_put_failure;

P
Philipp Reisner 已提交
2813
	rcu_read_lock();
2814 2815
	if (got_ldev) {
		struct disk_conf *disk_conf;
2816

2817
		disk_conf = rcu_dereference(device->ldev->disk_conf);
2818 2819 2820 2821 2822
		err = disk_conf_to_skb(skb, disk_conf, exclude_sensitive);
	}
	if (!err) {
		struct net_conf *nc;

2823
		nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
2824 2825 2826
		if (nc)
			err = net_conf_to_skb(skb, nc, exclude_sensitive);
	}
2827 2828 2829
	rcu_read_unlock();
	if (err)
		goto nla_put_failure;
2830 2831 2832 2833

	nla = nla_nest_start(skb, DRBD_NLA_STATE_INFO);
	if (!nla)
		goto nla_put_failure;
A
Andreas Gruenbacher 已提交
2834
	if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) ||
2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846
	    nla_put_u32(skb, T_current_state, device->state.i) ||
	    nla_put_u64(skb, T_ed_uuid, device->ed_uuid) ||
	    nla_put_u64(skb, T_capacity, drbd_get_capacity(device->this_bdev)) ||
	    nla_put_u64(skb, T_send_cnt, device->send_cnt) ||
	    nla_put_u64(skb, T_recv_cnt, device->recv_cnt) ||
	    nla_put_u64(skb, T_read_cnt, device->read_cnt) ||
	    nla_put_u64(skb, T_writ_cnt, device->writ_cnt) ||
	    nla_put_u64(skb, T_al_writ_cnt, device->al_writ_cnt) ||
	    nla_put_u64(skb, T_bm_writ_cnt, device->bm_writ_cnt) ||
	    nla_put_u32(skb, T_ap_bio_cnt, atomic_read(&device->ap_bio_cnt)) ||
	    nla_put_u32(skb, T_ap_pending_cnt, atomic_read(&device->ap_pending_cnt)) ||
	    nla_put_u32(skb, T_rs_pending_cnt, atomic_read(&device->rs_pending_cnt)))
A
Andreas Gruenbacher 已提交
2847
		goto nla_put_failure;
2848 2849

	if (got_ldev) {
2850
		int err;
P
Philipp Reisner 已提交
2851

2852 2853 2854
		spin_lock_irq(&device->ldev->md.uuid_lock);
		err = nla_put(skb, T_uuids, sizeof(si->uuids), device->ldev->md.uuid);
		spin_unlock_irq(&device->ldev->md.uuid_lock);
2855 2856 2857 2858

		if (err)
			goto nla_put_failure;

2859 2860 2861
		if (nla_put_u32(skb, T_disk_flags, device->ldev->md.flags) ||
		    nla_put_u64(skb, T_bits_total, drbd_bm_bits(device)) ||
		    nla_put_u64(skb, T_bits_oos, drbd_bm_total_weight(device)))
A
Andreas Gruenbacher 已提交
2862
			goto nla_put_failure;
2863 2864 2865 2866
		if (C_SYNC_SOURCE <= device->state.conn &&
		    C_PAUSED_SYNC_T >= device->state.conn) {
			if (nla_put_u64(skb, T_bits_rs_total, device->rs_total) ||
			    nla_put_u64(skb, T_bits_rs_failed, device->rs_failed))
A
Andreas Gruenbacher 已提交
2867
				goto nla_put_failure;
2868
		}
P
Philipp Reisner 已提交
2869 2870
	}

2871 2872 2873 2874 2875 2876
	if (sib) {
		switch(sib->sib_reason) {
		case SIB_SYNC_PROGRESS:
		case SIB_GET_STATUS_REPLY:
			break;
		case SIB_STATE_CHANGE:
A
Andreas Gruenbacher 已提交
2877 2878 2879
			if (nla_put_u32(skb, T_prev_state, sib->os.i) ||
			    nla_put_u32(skb, T_new_state, sib->ns.i))
				goto nla_put_failure;
2880 2881
			break;
		case SIB_HELPER_POST:
A
Andreas Gruenbacher 已提交
2882 2883 2884
			if (nla_put_u32(skb, T_helper_exit_code,
					sib->helper_exit_code))
				goto nla_put_failure;
2885 2886
			/* fall through */
		case SIB_HELPER_PRE:
A
Andreas Gruenbacher 已提交
2887 2888
			if (nla_put_string(skb, T_helper, sib->helper_name))
				goto nla_put_failure;
2889 2890
			break;
		}
P
Philipp Reisner 已提交
2891
	}
2892
	nla_nest_end(skb, nla);
P
Philipp Reisner 已提交
2893

2894 2895 2896 2897
	if (0)
nla_put_failure:
		err = -EMSGSIZE;
	if (got_ldev)
2898
		put_ldev(device);
2899
	return err;
P
Philipp Reisner 已提交
2900 2901
}

2902
int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
2903
{
2904 2905
	enum drbd_ret_code retcode;
	int err;
P
Philipp Reisner 已提交
2906

2907 2908 2909 2910 2911
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
2912

2913
	err = nla_put_status_info(adm_ctx.reply_skb, adm_ctx.device, NULL);
2914 2915 2916
	if (err) {
		nlmsg_free(adm_ctx.reply_skb);
		return err;
P
Philipp Reisner 已提交
2917
	}
2918 2919 2920
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
2921 2922
}

2923
static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
P
Philipp Reisner 已提交
2924
{
2925
	struct drbd_peer_device *peer_device;
2926
	struct drbd_device *device;
2927
	struct drbd_genlmsghdr *dh;
2928 2929 2930 2931
	struct drbd_resource *pos = (struct drbd_resource *)cb->args[0];
	struct drbd_resource *resource = NULL;
	struct drbd_connection *connection;
	struct drbd_resource *tmp;
2932 2933 2934
	unsigned volume = cb->args[1];

	/* Open coded, deferred, iteration:
2935 2936
	 * for_each_resource_safe(resource, tmp, &drbd_resources) {
	 *      connection = "first connection of resource";
2937
	 *	idr_for_each_entry(&connection->peer_devices, peer_device, i) {
2938 2939 2940
	 *	  ...
	 *	}
	 * }
2941
	 * where resource is cb->args[0];
2942 2943
	 * and i is cb->args[1];
	 *
2944 2945 2946
	 * cb->args[2] indicates if we shall loop over all resources,
	 * or just dump all volumes of a single resource.
	 *
2947 2948
	 * This may miss entries inserted after this dump started,
	 * or entries deleted before they are reached.
2949
	 *
2950
	 * We need to make sure the device won't disappear while
2951 2952 2953
	 * we are looking at it, and revalidate our iterators
	 * on each iteration.
	 */
P
Philipp Reisner 已提交
2954

2955
	/* synchronize with conn_create()/drbd_destroy_connection() */
P
Philipp Reisner 已提交
2956
	rcu_read_lock();
2957
	/* revalidate iterator position */
2958
	for_each_resource_rcu(tmp, &drbd_resources) {
2959 2960 2961
		if (pos == NULL) {
			/* first iteration */
			pos = tmp;
2962
			resource = pos;
2963 2964 2965
			break;
		}
		if (tmp == pos) {
2966
			resource = pos;
2967 2968
			break;
		}
P
Philipp Reisner 已提交
2969
	}
2970 2971 2972
	if (resource) {
next_resource:
		connection = first_connection(resource);
2973 2974
		peer_device = idr_get_next(&connection->peer_devices, &volume);
		if (!peer_device) {
2975 2976 2977 2978 2979
			/* No more volumes to dump on this resource.
			 * Advance resource iterator. */
			pos = list_entry_rcu(resource->resources.next,
					     struct drbd_resource, resources);
			/* Did we dump any volume of this resource yet? */
2980
			if (volume != 0) {
2981 2982 2983
				/* If we reached the end of the list,
				 * or only a single resource dump was requested,
				 * we are done. */
2984
				if (&pos->resources == &drbd_resources || cb->args[2])
2985
					goto out;
2986
				volume = 0;
2987 2988
				resource = pos;
				goto next_resource;
2989 2990 2991
			}
		}

2992
		dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
2993 2994 2995
				cb->nlh->nlmsg_seq, &drbd_genl_family,
				NLM_F_MULTI, DRBD_ADM_GET_STATUS);
		if (!dh)
2996 2997
			goto out;

2998
		if (!peer_device) {
2999
			/* This is a connection without a single volume.
3000 3001 3002
			 * Suprisingly enough, it may have a network
			 * configuration. */
			struct net_conf *nc;
3003 3004
			dh->minor = -1U;
			dh->ret_code = NO_ERROR;
3005
			if (nla_put_drbd_cfg_context(skb, connection, VOLUME_UNSPECIFIED))
3006
				goto cancel;
3007
			nc = rcu_dereference(connection->net_conf);
3008 3009 3010
			if (nc && net_conf_to_skb(skb, nc, 1) != 0)
				goto cancel;
			goto done;
3011
		}
P
Philipp Reisner 已提交
3012

3013
		device = peer_device->device;
3014
		D_ASSERT(device->vnr == volume);
3015
		D_ASSERT(first_peer_device(device)->connection == connection);
3016

3017
		dh->minor = device_to_minor(device);
3018 3019
		dh->ret_code = NO_ERROR;

3020
		if (nla_put_status_info(skb, device, NULL)) {
3021
cancel:
3022
			genlmsg_cancel(skb, dh);
3023
			goto out;
3024
		}
3025
done:
3026
		genlmsg_end(skb, dh);
3027
	}
P
Philipp Reisner 已提交
3028

3029
out:
P
Philipp Reisner 已提交
3030
	rcu_read_unlock();
3031
	/* where to start the next iteration */
3032
	cb->args[0] = (long)pos;
3033
	cb->args[1] = (pos == resource) ? volume + 1 : 0;
P
Philipp Reisner 已提交
3034

3035
	/* No more resources/volumes/minors found results in an empty skb.
3036
	 * Which will terminate the dump. */
3037
        return skb->len;
P
Philipp Reisner 已提交
3038 3039
}

3040 3041 3042 3043 3044 3045 3046 3047 3048
/*
 * Request status of all resources, or of all volumes within a single resource.
 *
 * This is a dump, as the answer may not fit in a single reply skb otherwise.
 * Which means we cannot use the family->attrbuf or other such members, because
 * dump is NOT protected by the genl_lock().  During dump, we only have access
 * to the incoming skb, and need to opencode "parsing" of the nlattr payload.
 *
 * Once things are setup properly, we call into get_one_status().
P
Philipp Reisner 已提交
3049
 */
3050
int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
P
Philipp Reisner 已提交
3051
{
3052 3053
	const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
	struct nlattr *nla;
3054
	const char *resource_name;
3055
	struct drbd_resource *resource;
3056
	int maxtype;
3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075

	/* Is this a followup call? */
	if (cb->args[0]) {
		/* ... of a single resource dump,
		 * and the resource iterator has been advanced already? */
		if (cb->args[2] && cb->args[2] != cb->args[0])
			return 0; /* DONE. */
		goto dump;
	}

	/* First call (from netlink_dump_start).  We need to figure out
	 * which resource(s) the user wants us to dump. */
	nla = nla_find(nlmsg_attrdata(cb->nlh, hdrlen),
			nlmsg_attrlen(cb->nlh, hdrlen),
			DRBD_NLA_CFG_CONTEXT);

	/* No explicit context given.  Dump all. */
	if (!nla)
		goto dump;
3076 3077 3078 3079
	maxtype = ARRAY_SIZE(drbd_cfg_context_nl_policy) - 1;
	nla = drbd_nla_find_nested(maxtype, nla, __nla_type(T_ctx_resource_name));
	if (IS_ERR(nla))
		return PTR_ERR(nla);
3080 3081 3082
	/* context given, but no name present? */
	if (!nla)
		return -EINVAL;
3083
	resource_name = nla_data(nla);
3084 3085 3086 3087
	if (!*resource_name)
		return -ENODEV;
	resource = drbd_find_resource(resource_name);
	if (!resource)
3088 3089
		return -ENODEV;

3090
	kref_put(&resource->kref, drbd_destroy_resource); /* get_one_status() revalidates the resource */
3091

3092
	/* prime iterators, and set "filter" mode mark:
3093
	 * only dump this connection. */
3094
	cb->args[0] = (long)resource;
3095
	/* cb->args[1] = 0; passed in this way. */
3096
	cb->args[2] = (long)resource;
3097 3098 3099 3100

dump:
	return get_one_status(skb, cb);
}
P
Philipp Reisner 已提交
3101

3102
int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3103
{
3104 3105 3106
	enum drbd_ret_code retcode;
	struct timeout_parms tp;
	int err;
P
Philipp Reisner 已提交
3107

3108 3109 3110 3111 3112
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3113

3114
	tp.timeout_type =
3115 3116
		adm_ctx.device->state.pdsk == D_OUTDATED ? UT_PEER_OUTDATED :
		test_bit(USE_DEGR_WFC_T, &adm_ctx.device->flags) ? UT_DEGRADED :
3117
		UT_DEFAULT;
P
Philipp Reisner 已提交
3118

3119 3120 3121 3122 3123 3124 3125 3126
	err = timeout_parms_to_priv_skb(adm_ctx.reply_skb, &tp);
	if (err) {
		nlmsg_free(adm_ctx.reply_skb);
		return err;
	}
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
3127 3128
}

3129
int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3130
{
3131
	struct drbd_device *device;
3132
	enum drbd_ret_code retcode;
3133
	struct start_ov_parms parms;
P
Philipp Reisner 已提交
3134

3135 3136 3137 3138 3139
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
3140

3141
	device = adm_ctx.device;
3142 3143

	/* resume from last known position, if possible */
3144
	parms.ov_start_sector = device->ov_start_sector;
3145
	parms.ov_stop_sector = ULLONG_MAX;
3146
	if (info->attrs[DRBD_NLA_START_OV_PARMS]) {
3147
		int err = start_ov_parms_from_attrs(&parms, info);
3148 3149 3150 3151 3152
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
			goto out;
		}
P
Philipp Reisner 已提交
3153
	}
3154
	/* w_make_ov_request expects position to be aligned */
3155 3156
	device->ov_start_sector = parms.ov_start_sector & ~(BM_SECT_PER_BIT-1);
	device->ov_stop_sector = parms.ov_stop_sector;
3157 3158 3159

	/* If there is still bitmap IO pending, e.g. previous resync or verify
	 * just being finished, wait for it before requesting a new resync. */
3160 3161 3162 3163
	drbd_suspend_io(device);
	wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags));
	retcode = drbd_request_state(device, NS(conn, C_VERIFY_S));
	drbd_resume_io(device);
3164 3165
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
3166 3167 3168 3169
	return 0;
}


3170
int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3171
{
3172
	struct drbd_device *device;
3173
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
3174 3175
	int skip_initial_sync = 0;
	int err;
3176
	struct new_c_uuid_parms args;
P
Philipp Reisner 已提交
3177

3178 3179 3180 3181 3182
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out_nolock;
P
Philipp Reisner 已提交
3183

3184
	device = adm_ctx.device;
3185 3186
	memset(&args, 0, sizeof(args));
	if (info->attrs[DRBD_NLA_NEW_C_UUID_PARMS]) {
3187
		err = new_c_uuid_parms_from_attrs(&args, info);
3188 3189 3190 3191 3192
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
			goto out_nolock;
		}
P
Philipp Reisner 已提交
3193 3194
	}

3195
	mutex_lock(device->state_mutex); /* Protects us against serialized state changes. */
P
Philipp Reisner 已提交
3196

3197
	if (!get_ldev(device)) {
P
Philipp Reisner 已提交
3198 3199 3200 3201 3202
		retcode = ERR_NO_DISK;
		goto out;
	}

	/* this is "skip initial sync", assume to be clean */
3203 3204
	if (device->state.conn == C_CONNECTED &&
	    first_peer_device(device)->connection->agreed_pro_version >= 90 &&
3205
	    device->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
3206
		drbd_info(device, "Preparing to skip initial sync\n");
P
Philipp Reisner 已提交
3207
		skip_initial_sync = 1;
3208
	} else if (device->state.conn != C_STANDALONE) {
P
Philipp Reisner 已提交
3209 3210 3211 3212
		retcode = ERR_CONNECTED;
		goto out_dec;
	}

3213 3214
	drbd_uuid_set(device, UI_BITMAP, 0); /* Rotate UI_BITMAP to History 1, etc... */
	drbd_uuid_new_current(device); /* New current, previous to UI_BITMAP */
P
Philipp Reisner 已提交
3215 3216

	if (args.clear_bm) {
3217
		err = drbd_bitmap_io(device, &drbd_bmio_clear_n_write,
3218
			"clear_n_write from new_c_uuid", BM_LOCKED_MASK);
P
Philipp Reisner 已提交
3219
		if (err) {
3220
			drbd_err(device, "Writing bitmap failed with %d\n", err);
P
Philipp Reisner 已提交
3221 3222 3223
			retcode = ERR_IO_MD_DISK;
		}
		if (skip_initial_sync) {
3224 3225 3226
			drbd_send_uuids_skip_initial_sync(device);
			_drbd_uuid_set(device, UI_BITMAP, 0);
			drbd_print_uuids(device, "cleared bitmap UUID");
3227
			spin_lock_irq(&first_peer_device(device)->connection->req_lock);
3228
			_drbd_set_state(_NS2(device, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
P
Philipp Reisner 已提交
3229
					CS_VERBOSE, NULL);
3230
			spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
P
Philipp Reisner 已提交
3231 3232 3233
		}
	}

3234
	drbd_md_sync(device);
P
Philipp Reisner 已提交
3235
out_dec:
3236
	put_ldev(device);
P
Philipp Reisner 已提交
3237
out:
3238
	mutex_unlock(device->state_mutex);
3239 3240
out_nolock:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
3241 3242 3243
	return 0;
}

3244
static enum drbd_ret_code
3245
drbd_check_resource_name(const char *name)
P
Philipp Reisner 已提交
3246
{
3247
	if (!name || !name[0]) {
3248
		drbd_msg_put_info("resource name missing");
3249
		return ERR_MANDATORY_TAG;
P
Philipp Reisner 已提交
3250
	}
3251 3252 3253
	/* if we want to use these in sysfs/configfs/debugfs some day,
	 * we must not allow slashes */
	if (strchr(name, '/')) {
3254
		drbd_msg_put_info("invalid resource name");
3255
		return ERR_INVALID_REQUEST;
P
Philipp Reisner 已提交
3256
	}
3257
	return NO_ERROR;
3258
}
P
Philipp Reisner 已提交
3259

3260
int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3261
{
3262
	enum drbd_ret_code retcode;
3263 3264
	struct res_opts res_opts;
	int err;
P
Philipp Reisner 已提交
3265

3266 3267 3268 3269 3270
	retcode = drbd_adm_prepare(skb, info, 0);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3271

3272 3273 3274 3275 3276 3277
	set_res_opts_defaults(&res_opts);
	err = res_opts_from_attrs(&res_opts, info);
	if (err && err != -ENOMSG) {
		retcode = ERR_MANDATORY_TAG;
		drbd_msg_put_info(from_attrs_err_to_txt(err));
		goto out;
P
Philipp Reisner 已提交
3278 3279
	}

3280
	retcode = drbd_check_resource_name(adm_ctx.resource_name);
3281 3282
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3283

3284
	if (adm_ctx.connection) {
3285 3286
		if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) {
			retcode = ERR_INVALID_REQUEST;
3287
			drbd_msg_put_info("resource exists");
3288 3289
		}
		/* else: still NO_ERROR */
3290
		goto out;
P
Philipp Reisner 已提交
3291 3292
	}

3293
	if (!conn_create(adm_ctx.resource_name, &res_opts))
P
Philipp Reisner 已提交
3294
		retcode = ERR_NOMEM;
3295 3296 3297
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
3298 3299
}

3300
int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3301
{
3302 3303
	struct drbd_genlmsghdr *dh = info->userhdr;
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
3304

3305
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
3306 3307 3308 3309
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3310

3311
	if (dh->minor > MINORMASK) {
3312 3313 3314
		drbd_msg_put_info("requested minor out of range");
		retcode = ERR_INVALID_REQUEST;
		goto out;
P
Philipp Reisner 已提交
3315
	}
3316
	if (adm_ctx.volume > DRBD_VOLUME_MAX) {
3317 3318 3319
		drbd_msg_put_info("requested volume id out of range");
		retcode = ERR_INVALID_REQUEST;
		goto out;
P
Philipp Reisner 已提交
3320 3321
	}

3322
	/* drbd_adm_prepare made sure already
3323
	 * that first_peer_device(device)->connection and device->vnr match the request. */
3324
	if (adm_ctx.device) {
3325 3326 3327 3328
		if (info->nlhdr->nlmsg_flags & NLM_F_EXCL)
			retcode = ERR_MINOR_EXISTS;
		/* else: still NO_ERROR */
		goto out;
P
Philipp Reisner 已提交
3329
	}
3330

3331
	retcode = drbd_create_minor(adm_ctx.connection, dh->minor, adm_ctx.volume);
3332 3333 3334
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
3335 3336
}

3337
static enum drbd_ret_code adm_del_minor(struct drbd_device *device)
P
Philipp Reisner 已提交
3338
{
3339 3340
	if (device->state.disk == D_DISKLESS &&
	    /* no need to be device->state.conn == C_STANDALONE &&
3341 3342
	     * we may want to delete a minor from a live replication group.
	     */
3343 3344
	    device->state.role == R_SECONDARY) {
		_drbd_request_state(device, NS(conn, C_WF_REPORT_PARAMS),
3345
				    CS_VERBOSE + CS_WAIT_COMPLETE);
3346
		drbd_delete_minor(device);
3347 3348 3349
		return NO_ERROR;
	} else
		return ERR_MINOR_CONFIGURED;
P
Philipp Reisner 已提交
3350 3351
}

3352
int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3353
{
3354
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
3355

3356 3357 3358 3359 3360
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3361

3362
	retcode = adm_del_minor(adm_ctx.device);
3363 3364 3365
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
3366 3367
}

3368
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3369
{
3370
	int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
3371
	struct drbd_peer_device *peer_device;
3372
	unsigned i;
P
Philipp Reisner 已提交
3373

3374
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
3375 3376 3377 3378
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3379

3380
	/* demote */
3381 3382
	idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
		retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
3383 3384
		if (retcode < SS_SUCCESS) {
			drbd_msg_put_info("failed to demote");
P
Philipp Reisner 已提交
3385
			goto out;
3386
		}
P
Philipp Reisner 已提交
3387 3388
	}

3389
	retcode = conn_try_disconnect(adm_ctx.connection, 0);
3390
	if (retcode < SS_SUCCESS) {
3391
		drbd_msg_put_info("failed to disconnect");
3392
		goto out;
3393
	}
P
Philipp Reisner 已提交
3394

3395
	/* detach */
3396 3397
	idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
		retcode = adm_detach(peer_device->device, 0);
3398
		if (retcode < SS_SUCCESS || retcode > NO_ERROR) {
3399
			drbd_msg_put_info("failed to detach");
P
Philipp Reisner 已提交
3400
			goto out;
3401 3402
		}
	}
P
Philipp Reisner 已提交
3403

3404
	/* If we reach this, all volumes (of this connection) are Secondary,
3405
	 * Disconnected, Diskless, aka Unconfigured. Make sure all threads have
P
Philipp Reisner 已提交
3406
	 * actually stopped, state handling only does drbd_thread_stop_nowait(). */
3407
	drbd_thread_stop(&adm_ctx.connection->worker);
P
Philipp Reisner 已提交
3408

3409
	/* Now, nothing can fail anymore */
P
Philipp Reisner 已提交
3410

3411
	/* delete volumes */
3412 3413
	idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
		retcode = adm_del_minor(peer_device->device);
3414 3415 3416
		if (retcode != NO_ERROR) {
			/* "can not happen" */
			drbd_msg_put_info("failed to delete volume");
3417
			goto out;
3418 3419
		}
	}
P
Philipp Reisner 已提交
3420

3421
	/* delete connection */
3422
	if (conn_lowest_minor(adm_ctx.connection) < 0) {
3423 3424 3425
		struct drbd_resource *resource = adm_ctx.connection->resource;

		list_del_rcu(&resource->resources);
3426
		synchronize_rcu();
3427
		drbd_free_resource(resource);
P
Philipp Reisner 已提交
3428

3429 3430 3431
		retcode = NO_ERROR;
	} else {
		/* "can not happen" */
3432
		retcode = ERR_RES_IN_USE;
3433 3434
		drbd_msg_put_info("failed to delete connection");
	}
3435
	goto out;
3436 3437 3438
out:
	drbd_adm_finish(info, retcode);
	return 0;
P
Philipp Reisner 已提交
3439 3440
}

3441
int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info)
P
Philipp Reisner 已提交
3442
{
3443 3444
	struct drbd_resource *resource;
	struct drbd_connection *connection;
3445
	enum drbd_ret_code retcode;
P
Philipp Reisner 已提交
3446

3447
	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
3448 3449 3450 3451
	if (!adm_ctx.reply_skb)
		return retcode;
	if (retcode != NO_ERROR)
		goto out;
P
Philipp Reisner 已提交
3452

3453 3454 3455 3456 3457 3458 3459 3460
	resource = adm_ctx.resource;
	for_each_connection(connection, resource) {
		if (connection->cstate > C_STANDALONE) {
			retcode = ERR_NET_CONFIGURED;
			goto out;
		}
	}
	if (!idr_is_empty(&resource->devices)) {
3461
		retcode = ERR_RES_IN_USE;
3462
		goto out;
P
Philipp Reisner 已提交
3463 3464
	}

3465 3466 3467 3468 3469 3470
	list_del_rcu(&resource->resources);
	for_each_connection(connection, resource)
		drbd_thread_stop(&connection->worker);
	synchronize_rcu();
	drbd_free_resource(resource);
	retcode = NO_ERROR;
3471 3472
out:
	drbd_adm_finish(info, retcode);
P
Philipp Reisner 已提交
3473 3474 3475
	return 0;
}

3476
void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib)
P
Philipp Reisner 已提交
3477
{
3478 3479 3480 3481 3482 3483
	static atomic_t drbd_genl_seq = ATOMIC_INIT(2); /* two. */
	struct sk_buff *msg;
	struct drbd_genlmsghdr *d_out;
	unsigned seq;
	int err = -ENOMEM;

3484
	if (sib->sib_reason == SIB_SYNC_PROGRESS) {
3485 3486
		if (time_after(jiffies, device->rs_last_bcast + HZ))
			device->rs_last_bcast = jiffies;
3487 3488 3489
		else
			return;
	}
P
Philipp Reisner 已提交
3490

3491 3492 3493 3494 3495 3496 3497 3498 3499
	seq = atomic_inc_return(&drbd_genl_seq);
	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
	if (!msg)
		goto failed;

	err = -EMSGSIZE;
	d_out = genlmsg_put(msg, 0, seq, &drbd_genl_family, 0, DRBD_EVENT);
	if (!d_out) /* cannot happen, but anyways. */
		goto nla_put_failure;
3500
	d_out->minor = device_to_minor(device);
3501
	d_out->ret_code = NO_ERROR;
3502

3503
	if (nla_put_status_info(msg, device, sib))
3504 3505 3506 3507 3508 3509
		goto nla_put_failure;
	genlmsg_end(msg, d_out);
	err = drbd_genl_multicast_events(msg, 0);
	/* msg has been consumed or freed in netlink_broadcast() */
	if (err && err != -ESRCH)
		goto failed;
P
Philipp Reisner 已提交
3510

3511
	return;
P
Philipp Reisner 已提交
3512

3513 3514 3515
nla_put_failure:
	nlmsg_free(msg);
failed:
3516
	drbd_err(device, "Error %d while broadcasting event. "
3517 3518
			"Event seq:%u sib_reason:%u\n",
			err, seq, sib->sib_reason);
P
Philipp Reisner 已提交
3519
}