1b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/*
2b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd_nl.c
3b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
4b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
5b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
6b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
7b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
8b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
9b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
10b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd is free software; you can redistribute it and/or modify
11b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   it under the terms of the GNU General Public License as published by
12b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   the Free Software Foundation; either version 2, or (at your option)
13b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   any later version.
14b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
15b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd is distributed in the hope that it will be useful,
16b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   but WITHOUT ANY WARRANTY; without even the implied warranty of
17b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   GNU General Public License for more details.
19b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
20b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   You should have received a copy of the GNU General Public License
21b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   along with drbd; see the file COPYING.  If not, write to
22b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
24b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
25b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
26b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/module.h>
27b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/drbd.h>
28b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/in.h>
29b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/fs.h>
30b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/file.h>
31b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/slab.h>
32b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/connector.h>
33b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/blkpg.h>
34b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/cpumask.h>
35b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include "drbd_int.h"
36265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner#include "drbd_req.h"
37b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include "drbd_wrappers.h"
38b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <asm/unaligned.h>
39b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/drbd_tag_magic.h>
40b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/drbd_limits.h>
4187f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner#include <linux/compiler.h>
4287f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner#include <linux/kthread.h>
43b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
44b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *tl_add_blob(unsigned short *, enum drbd_tags, const void *, int);
45b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *tl_add_str(unsigned short *, enum drbd_tags, const char *);
46b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *tl_add_int(unsigned short *, enum drbd_tags, const void *);
47b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
48b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* see get_sb_bdev and bd_claim */
49b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic char *drbd_m_holder = "Hands off! this is DRBD's meta data device.";
50b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
51b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* Generate the tag_list to struct functions */
52b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_PACKET(name, number, fields) \
53b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int name ## _from_tags(struct drbd_conf *mdev, \
54b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tags, struct name *arg) __attribute__ ((unused)); \
55b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int name ## _from_tags(struct drbd_conf *mdev, \
56b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tags, struct name *arg) \
57b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ \
58b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int tag; \
59b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int dlen; \
60b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	\
61b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	while ((tag = get_unaligned(tags++)) != TT_END) {	\
62b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dlen = get_unaligned(tags++);			\
63b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		switch (tag_number(tag)) { \
64b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		fields \
65b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		default: \
66b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (tag & T_MANDATORY) { \
67b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				dev_err(DEV, "Unknown tag: %d\n", tag_number(tag)); \
68b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				return 0; \
69b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			} \
70b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		} \
71b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tags = (unsigned short *)((char *)tags + dlen); \
72b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} \
73b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 1; \
74b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
75b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_INTEGER(pn, pr, member) \
76b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case pn: /* D_ASSERT( tag_type(tag) == TT_INTEGER ); */ \
77b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		arg->member = get_unaligned((int *)(tags));	\
78b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
79b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_INT64(pn, pr, member) \
80b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case pn: /* D_ASSERT( tag_type(tag) == TT_INT64 ); */ \
81b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		arg->member = get_unaligned((u64 *)(tags));	\
82b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
83b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_BIT(pn, pr, member) \
84b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case pn: /* D_ASSERT( tag_type(tag) == TT_BIT ); */ \
85b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		arg->member = *(char *)(tags) ? 1 : 0; \
86b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
87b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_STRING(pn, pr, member, len) \
88b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case pn: /* D_ASSERT( tag_type(tag) == TT_STRING ); */ \
89b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (dlen > len) { \
90b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dev_err(DEV, "arg too long: %s (%u wanted, max len: %u bytes)\n", \
91b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				#member, dlen, (unsigned int)len); \
92b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			return 0; \
93b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		} \
94b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 arg->member ## _len = dlen; \
95b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 memcpy(arg->member, tags, min_t(size_t, dlen, len)); \
96b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 break;
971d273b929cad7b1ee95d5c15ac806b3abc764278Joe Perches#include <linux/drbd_nl.h>
98b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
99b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* Generate the struct to tag_list functions */
100b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_PACKET(name, number, fields) \
101b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short* \
102b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnername ## _to_tags(struct drbd_conf *mdev, \
103b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct name *arg, unsigned short *tags) __attribute__ ((unused)); \
104b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short* \
105b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnername ## _to_tags(struct drbd_conf *mdev, \
106b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct name *arg, unsigned short *tags) \
107b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ \
108b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	fields \
109b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return tags; \
110b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_INTEGER(pn, pr, member) \
113b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(pn | pr | TT_INTEGER, tags++);	\
114b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(sizeof(int), tags++);		\
115b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(arg->member, (int *)tags);	\
116b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tags = (unsigned short *)((char *)tags+sizeof(int));
117b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_INT64(pn, pr, member) \
118b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(pn | pr | TT_INT64, tags++);	\
119b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(sizeof(u64), tags++);		\
120b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(arg->member, (u64 *)tags);	\
121b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tags = (unsigned short *)((char *)tags+sizeof(u64));
122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_BIT(pn, pr, member) \
123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(pn | pr | TT_BIT, tags++);	\
124b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(sizeof(char), tags++);		\
125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	*(char *)tags = arg->member; \
126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tags = (unsigned short *)((char *)tags+sizeof(char));
127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define NL_STRING(pn, pr, member, len) \
128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(pn | pr | TT_STRING, tags++);	\
129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(arg->member ## _len, tags++);	\
130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	memcpy(tags, arg->member, arg->member ## _len); \
131b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tags = (unsigned short *)((char *)tags + arg->member ## _len);
1321d273b929cad7b1ee95d5c15ac806b3abc764278Joe Perches#include <linux/drbd_nl.h>
133b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
134b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name);
135b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_nl_send_reply(struct cn_msg *, int);
136b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
137b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerint drbd_khelper(struct drbd_conf *mdev, char *cmd)
138b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
139b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char *envp[] = { "HOME=/",
140b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			"TERM=linux",
141b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
142b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			NULL, /* Will be set to address family */
143b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			NULL, /* Will be set to address */
144b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			NULL };
145b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char mb[12], af[20], ad[60], *afs;
147b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char *argv[] = {usermode_helper, cmd, mb, NULL };
148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int ret;
149b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
150b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
151b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_net_conf(mdev)) {
153b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		switch (((struct sockaddr *)mdev->net_conf->peer_addr)->sa_family) {
154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		case AF_INET6:
155b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			afs = "ipv6";
156b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI6",
157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				 &((struct sockaddr_in6 *)mdev->net_conf->peer_addr)->sin6_addr);
158b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			break;
159b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		case AF_INET:
160b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			afs = "ipv4";
161b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
162b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
163b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			break;
164b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		default:
165b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			afs = "ssocks";
166b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
167b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
168b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
169b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		snprintf(af, 20, "DRBD_PEER_AF=%s", afs);
170b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		envp[3]=af;
171b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		envp[4]=ad;
172b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_net_conf(mdev);
173b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
174b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1751090c056c5eb6d5335cceb381683e77ac24c71abLars Ellenberg	/* The helper may take some time.
1761090c056c5eb6d5335cceb381683e77ac24c71abLars Ellenberg	 * write out any unsynced meta data changes now */
1771090c056c5eb6d5335cceb381683e77ac24c71abLars Ellenberg	drbd_md_sync(mdev);
1781090c056c5eb6d5335cceb381683e77ac24c71abLars Ellenberg
179b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
180b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
181b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_bcast_ev_helper(mdev, cmd);
18270834d3070c3f3015ab5c05176d54bd4a0100546Oleg Nesterov	ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
183b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (ret)
184b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
185b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				usermode_helper, cmd, mb,
186b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				(ret >> 8) & 0xff, ret);
187b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
188b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_info(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
189b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				usermode_helper, cmd, mb,
190b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				(ret >> 8) & 0xff, ret);
191b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
192b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (ret < 0) /* Ignore any ERRNOs we got. */
193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ret = 0;
194b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return ret;
196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
197b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
198b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerenum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
200b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char *ex_to_string;
201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int r;
202b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum drbd_disk_state nps;
203b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum drbd_fencing_p fp;
204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
205b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
206b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
207b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_ldev_if_state(mdev, D_CONSISTENT)) {
208b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		fp = mdev->ldev->dc.fencing;
209b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_ldev(mdev);
210b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
211b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "Not fencing peer, I'm not even Consistent myself.\n");
212fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner		nps = mdev->state.pdsk;
213fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner		goto out;
214b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
215b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
216b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	r = drbd_khelper(mdev, "fence-peer");
217b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
218b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	switch ((r>>8) & 0xff) {
219b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case 3: /* peer is inconsistent */
220b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ex_to_string = "peer is inconsistent or worse";
221b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		nps = D_INCONSISTENT;
222b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
223b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case 4: /* peer got outdated, or was already outdated */
224b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ex_to_string = "peer was fenced";
225b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		nps = D_OUTDATED;
226b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
227b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case 5: /* peer was down */
228b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (mdev->state.disk == D_UP_TO_DATE) {
229b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			/* we will(have) create(d) a new UUID anyways... */
230b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			ex_to_string = "peer is unreachable, assumed to be dead";
231b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			nps = D_OUTDATED;
232b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		} else {
233b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			ex_to_string = "peer unreachable, doing nothing since disk != UpToDate";
234b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			nps = mdev->state.pdsk;
235b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
236b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
237b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case 6: /* Peer is primary, voluntarily outdate myself.
238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 * This is useful when an unconnected R_SECONDARY is asked to
239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 * become R_PRIMARY, but finds the other peer being active. */
240b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ex_to_string = "peer is active";
241b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "Peer is primary, outdating myself.\n");
242b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		nps = D_UNKNOWN;
243b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		_drbd_request_state(mdev, NS(disk, D_OUTDATED), CS_WAIT_COMPLETE);
244b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
245b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case 7:
246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (fp != FP_STONITH)
247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dev_err(DEV, "fence-peer() = 7 && fencing != Stonith !!!\n");
248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ex_to_string = "peer was stonithed";
249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		nps = D_OUTDATED;
250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
251b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	default:
252b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* The script is broken ... */
253b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		nps = D_UNKNOWN;
254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "fence-peer helper broken, returned %d\n", (r>>8)&0xff);
255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return nps;
256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
258b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dev_info(DEV, "fence-peer helper returned %d (%s)\n",
259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			(r>>8) & 0xff, ex_to_string);
260fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner
261fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisnerout:
262fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	if (mdev->state.susp_fen && nps >= D_UNKNOWN) {
263fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner		/* The handler was not successful... unfreeze here, the
264fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner		   state engine can not unfreeze... */
265fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner		_drbd_request_state(mdev, NS(susp_fen, 0), CS_VERBOSE);
266fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	}
267fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner
268b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return nps;
269b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
270b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
27187f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisnerstatic int _try_outdate_peer_async(void *data)
27287f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner{
27387f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	struct drbd_conf *mdev = (struct drbd_conf *)data;
27487f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	enum drbd_disk_state nps;
27521423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	union drbd_state ns;
27687f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner
27787f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	nps = drbd_try_outdate_peer(mdev);
27821423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner
27921423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	/* Not using
28021423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	   drbd_request_state(mdev, NS(pdsk, nps));
28199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   here, because we might were able to re-establish the connection
28299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   in the meantime. This can only partially be solved in the state's
28399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   engine is_valid_state() and is_valid_state_transition()
28499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   functions.
28599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
28699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   nps can be D_INCONSISTENT, D_OUTDATED or D_UNKNOWN.
28799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   pdsk == D_INCONSISTENT while conn >= C_CONNECTED is valid,
28899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   therefore we have to have the pre state change check here.
28921423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	*/
29021423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	spin_lock_irq(&mdev->req_lock);
29121423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	ns = mdev->state;
29221423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	if (ns.conn < C_WF_REPORT_PARAMS) {
29321423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner		ns.pdsk = nps;
29421423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner		_drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
29521423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	}
29621423fa79119a80e335de0c82ec29f67ed59f1bcPhilipp Reisner	spin_unlock_irq(&mdev->req_lock);
29787f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner
29887f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	return 0;
29987f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner}
30087f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner
30187f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisnervoid drbd_try_outdate_peer_async(struct drbd_conf *mdev)
30287f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner{
30387f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	struct task_struct *opa;
30487f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner
30587f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	opa = kthread_run(_try_outdate_peer_async, mdev, "drbd%d_a_helper", mdev_to_minor(mdev));
30687f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner	if (IS_ERR(opa))
30787f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner		dev_err(DEV, "out of mem, failed to invoke fence-peer helper\n");
30887f7be4cf88e93069f4cc63baf2ce70fdfc59c63Philipp Reisner}
309b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
310bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacherenum drbd_state_rv
311bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacherdrbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
312b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
313b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	const int max_tries = 4;
314bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher	enum drbd_state_rv rv = SS_UNKNOWN_ERROR;
315b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int try = 0;
316b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int forced = 0;
317b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	union drbd_state mask, val;
318b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum drbd_disk_state nps;
319b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
320b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_role == R_PRIMARY)
321b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		request_ping(mdev); /* Detect a dead peer ASAP */
322b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
323b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mutex_lock(&mdev->state_mutex);
324b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
325b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mask.i = 0; mask.role = R_MASK;
326b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	val.i  = 0; val.role  = new_role;
327b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
328b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	while (try++ < max_tries) {
329bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		rv = _drbd_request_state(mdev, mask, val, CS_WAIT_COMPLETE);
330b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
331b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* in case we first succeeded to outdate,
332b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 * but now suddenly could establish a connection */
333bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_CW_FAILED_BY_PEER && mask.pdsk != 0) {
334b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			val.pdsk = 0;
335b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mask.pdsk = 0;
336b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
337b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
338b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
339bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_NO_UP_TO_DATE_DISK && force &&
340d10a33c68b8526d95ef6ee72b371c392d48df4d3Philipp Reisner		    (mdev->state.disk < D_UP_TO_DATE &&
341d10a33c68b8526d95ef6ee72b371c392d48df4d3Philipp Reisner		     mdev->state.disk >= D_INCONSISTENT)) {
342b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mask.disk = D_MASK;
343b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			val.disk  = D_UP_TO_DATE;
344b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			forced = 1;
345b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
346b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
347b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
348bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_NO_UP_TO_DATE_DISK &&
349b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    mdev->state.disk == D_CONSISTENT && mask.pdsk == 0) {
350b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
351b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			nps = drbd_try_outdate_peer(mdev);
352b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
353b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (nps == D_OUTDATED || nps == D_INCONSISTENT) {
354b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				val.disk = D_UP_TO_DATE;
355b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				mask.disk = D_MASK;
356b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			}
357b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
358b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			val.pdsk = nps;
359b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mask.pdsk = D_MASK;
360b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
361b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
362b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
363b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
364bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_NOTHING_TO_DO)
365b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
366bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_PRIMARY_NOP && mask.pdsk == 0) {
367b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			nps = drbd_try_outdate_peer(mdev);
368b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
369b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (force && nps > D_OUTDATED) {
370b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				dev_warn(DEV, "Forced into split brain situation!\n");
371b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				nps = D_OUTDATED;
372b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			}
373b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
374b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mask.pdsk = D_MASK;
375b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			val.pdsk  = nps;
376b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
377b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
378b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
379bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv == SS_TWO_PRIMARIES) {
380b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			/* Maybe the peer is detected as dead very soon...
381b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   retry at most once more in this case. */
38220ee639024e3d33111df0e343050b218c656bf16Philipp Reisner			schedule_timeout_interruptible((mdev->net_conf->ping_timeo+1)*HZ/10);
383b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (try < max_tries)
384b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				try = max_tries - 1;
385b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
386b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
387bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher		if (rv < SS_SUCCESS) {
388bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher			rv = _drbd_request_state(mdev, mask, val,
389b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner						CS_VERBOSE + CS_WAIT_COMPLETE);
390bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher			if (rv < SS_SUCCESS)
391b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				goto fail;
392b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
393b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
394b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
395b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
396bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher	if (rv < SS_SUCCESS)
397b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
398b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
399b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (forced)
400b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "Forced to consider local data as UpToDate!\n");
401b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
402b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Wait until nothing is on the fly :) */
403b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wait_event(mdev->misc_wait, atomic_read(&mdev->ap_pending_cnt) == 0);
404b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
405b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_role == R_SECONDARY) {
40681e84650c200de0695372461964dd960365696dbAndreas Gruenbacher		set_disk_ro(mdev->vdisk, true);
407b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (get_ldev(mdev)) {
408b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mdev->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
409b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_ldev(mdev);
410b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
411b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
412b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (get_net_conf(mdev)) {
413b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mdev->net_conf->want_lose = 0;
414b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_net_conf(mdev);
415b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
41681e84650c200de0695372461964dd960365696dbAndreas Gruenbacher		set_disk_ro(mdev->vdisk, false);
417b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (get_ldev(mdev)) {
418b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (((mdev->state.conn < C_CONNECTED ||
419b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			       mdev->state.pdsk <= D_FAILED)
420b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      && mdev->ldev->md.uuid[UI_BITMAP] == 0) || forced)
421b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				drbd_uuid_new_current(mdev);
422b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
423b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			mdev->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
424b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_ldev(mdev);
425b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
426b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
427b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
42819f843aa08e2d8f87a09b4c2edc43b00638423a8Lars Ellenberg	/* writeout of activity log covered areas of the bitmap
42919f843aa08e2d8f87a09b4c2edc43b00638423a8Lars Ellenberg	 * to stable storage done in after state change already */
430b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
431b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn >= C_WF_REPORT_PARAMS) {
432b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* if this was forced, we should consider sync */
433b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (forced)
434b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			drbd_send_uuids(mdev);
435b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_send_state(mdev);
436b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
437b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
438b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
439b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
440b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
441b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner fail:
442b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mutex_unlock(&mdev->state_mutex);
443bf885f8a6772fb48409dd505a09d974a5e621f22Andreas Gruenbacher	return rv;
444b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
445b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
446ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenbergstatic struct drbd_conf *ensure_mdev(int minor, int create)
447ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg{
448ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	struct drbd_conf *mdev;
449ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
450ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	if (minor >= minor_count)
451ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		return NULL;
452ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
453ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	mdev = minor_to_mdev(minor);
454ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
455ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	if (!mdev && create) {
456ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		struct gendisk *disk = NULL;
457ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		mdev = drbd_new_device(minor);
458ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
459ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		spin_lock_irq(&drbd_pp_lock);
460ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		if (minor_table[minor] == NULL) {
461ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			minor_table[minor] = mdev;
462ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			disk = mdev->vdisk;
463ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			mdev = NULL;
464ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		} /* else: we lost the race */
465ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		spin_unlock_irq(&drbd_pp_lock);
466ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
467ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		if (disk) /* we won the race above */
468ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			/* in case we ever add a drbd_delete_device(),
469ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			 * don't forget the del_gendisk! */
470ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			add_disk(disk);
471ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		else /* we lost the race above */
472ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			drbd_free_mdev(mdev);
473ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
474ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		mdev = minor_to_mdev(minor);
475ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	}
476ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
477ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	return mdev;
478ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg}
479b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
480b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
481b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   struct drbd_nl_cfg_reply *reply)
482b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
483b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct primary primary_args;
484b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
485b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	memset(&primary_args, 0, sizeof(struct primary));
486b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!primary_from_tags(mdev, nlp->tag_list, &primary_args)) {
487b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		reply->ret_code = ERR_MANDATORY_TAG;
488b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return 0;
489b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
490b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
491b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code =
4921f55243024087b56aef0b1e6d9c0ea89c76f0a6bPhilipp Reisner		drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force);
493b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
494b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
495b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
496b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
497b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_secondary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
498b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			     struct drbd_nl_cfg_reply *reply)
499b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
500b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = drbd_set_role(mdev, R_SECONDARY, 0);
501b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
502b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
503b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
504b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
505b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* initializes the md.*_offset members, so we are able to find
506b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * the on disk meta data */
507b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void drbd_md_set_sector_offsets(struct drbd_conf *mdev,
508b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				       struct drbd_backing_dev *bdev)
509b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
510b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t md_size_sect = 0;
511b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	switch (bdev->dc.meta_dev_idx) {
512b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	default:
513b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* v07 style fixed size indexed meta data */
514b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_size_sect = MD_RESERVED_SECT;
515b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_offset = drbd_md_ss__(mdev, bdev);
516b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.al_offset = MD_AL_OFFSET;
517b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.bm_offset = MD_BM_OFFSET;
518b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
519b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case DRBD_MD_INDEX_FLEX_EXT:
520b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* just occupy the full device; unit: sectors */
521b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev);
522b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_offset = 0;
523b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.al_offset = MD_AL_OFFSET;
524b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.bm_offset = MD_BM_OFFSET;
525b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
526b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case DRBD_MD_INDEX_INTERNAL:
527b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case DRBD_MD_INDEX_FLEX_INT:
528b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_offset = drbd_md_ss__(mdev, bdev);
529b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* al size is still fixed */
530b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.al_offset = -MD_AL_MAX_SIZE;
531b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* we need (slightly less than) ~ this much bitmap sectors: */
532b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		md_size_sect = drbd_get_capacity(bdev->backing_bdev);
533b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		md_size_sect = ALIGN(md_size_sect, BM_SECT_PER_EXT);
534b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		md_size_sect = BM_SECT_TO_EXT(md_size_sect);
535b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		md_size_sect = ALIGN(md_size_sect, 8);
536b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
537b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* plus the "drbd meta data super block",
538b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 * and the activity log; */
539b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		md_size_sect += MD_BM_OFFSET;
540b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
541b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.md_size_sect = md_size_sect;
542b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* bitmap offset is adjusted by 'super' block size */
543b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		bdev->md.bm_offset   = -md_size_sect + MD_AL_OFFSET;
544b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
545b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
546b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
547b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
5484b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg/* input size is expected to be in KB */
549b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerchar *ppsize(char *buf, unsigned long long size)
550b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
5514b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg	/* Needs 9 bytes at max including trailing NUL:
5524b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg	 * -1ULL ==> "16384 EB" */
553b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' };
554b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int base = 0;
5554b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg	while (size >= 10000 && base < sizeof(units)-1) {
556b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* shift + round */
557b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		size = (size >> 10) + !!(size & (1<<9));
558b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		base++;
559b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
5604b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg	sprintf(buf, "%u %cB", (unsigned)size, units[base]);
561b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
562b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return buf;
563b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
564b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
565b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* there is still a theoretical deadlock when called from receiver
566b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * on an D_INCONSISTENT R_PRIMARY:
567b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  remote READ does inc_ap_bio, receiver would need to receive answer
568b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  packet from remote to dec_ap_bio again.
569b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  receiver receive_sizes(), comes here,
570b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  waits for ap_bio_cnt == 0. -> deadlock.
571b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * but this cannot happen, actually, because:
572b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  R_PRIMARY D_INCONSISTENT, and peer's disk is unreachable
573b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  (not connected, or bad/no disk on peer):
574b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  see drbd_fail_request_early, ap_bio_cnt is zero.
575b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  R_PRIMARY D_INCONSISTENT, and C_SYNC_TARGET:
576b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *  peer may not initiate a resize.
577b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
578b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_suspend_io(struct drbd_conf *mdev)
579b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
580b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	set_bit(SUSPEND_IO, &mdev->flags);
581fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	if (is_susp(mdev->state))
582265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner		return;
583b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
584b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
585b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
586b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_resume_io(struct drbd_conf *mdev)
587b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
588b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	clear_bit(SUSPEND_IO, &mdev->flags);
589b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wake_up(&mdev->misc_wait);
590b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
591b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
592b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/**
593b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * drbd_determine_dev_size() -  Sets the right device size obeying all constraints
594b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * @mdev:	DRBD device.
595b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *
596b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * Returns 0 on success, negative return values indicate errors.
597b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * You should call drbd_md_sync() after calling this function.
598b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
59924c4830c8ec3cbc904d84c213126a35f41a4e455Bart Van Asscheenum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local)
600b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
601b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t prev_first_sect, prev_size; /* previous meta location */
602b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t la_size;
603b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t size;
604b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char ppb[10];
605b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
606b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int md_moved, la_size_changed;
607b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum determine_dev_size rv = unchanged;
608b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
609b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* race:
610b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * application request passes inc_ap_bio,
611b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * but then cannot get an AL-reference.
612b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * this function later may wait on ap_bio_cnt == 0. -> deadlock.
613b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 *
614b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * to avoid that:
615b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * Suspend IO right here.
616b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * still lock the act_log to not trigger ASSERTs there.
617b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 */
618b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_suspend_io(mdev);
619b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
620b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* no wait necessary anymore, actually we could assert that */
621b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
622b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
623b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	prev_first_sect = drbd_md_first_sector(mdev->ldev);
624b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	prev_size = mdev->ldev->md.md_size_sect;
625b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	la_size = mdev->ldev->md.la_size_sect;
626b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
627b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* TODO: should only be some assert here, not (re)init... */
628b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_set_sector_offsets(mdev, mdev->ldev);
629b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
630d845030f21859dd11bcecc7e1b8575fb845eb425Philipp Reisner	size = drbd_new_dev_size(mdev, mdev->ldev, flags & DDSF_FORCED);
631b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
632b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_get_capacity(mdev->this_bdev) != size ||
633b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    drbd_bm_capacity(mdev) != size) {
634b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		int err;
63502d9a94bbb0d4e0fec8db6735bdc4ccfaac8f0cePhilipp Reisner		err = drbd_bm_resize(mdev, size, !(flags & DDSF_NO_RESYNC));
636b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (unlikely(err)) {
637b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			/* currently there is only one error: ENOMEM! */
638b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			size = drbd_bm_capacity(mdev)>>1;
639b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (size == 0) {
640b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				dev_err(DEV, "OUT OF MEMORY! "
641b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    "Could not allocate bitmap!\n");
642b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			} else {
643b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				dev_err(DEV, "BM resizing failed. "
644b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    "Leaving size unchanged at size = %lu KB\n",
645b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    (unsigned long)size);
646b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			}
647b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			rv = dev_size_error;
648b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
649b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* racy, see comments above. */
650b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_set_my_capacity(mdev, size);
651b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ldev->md.la_size_sect = size;
652b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_info(DEV, "size = %s (%llu KB)\n", ppsize(ppb, size>>1),
653b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		     (unsigned long long)size>>1);
654b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
655b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (rv == dev_size_error)
656b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto out;
657b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
658b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	la_size_changed = (la_size != mdev->ldev->md.la_size_sect);
659b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
660b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	md_moved = prev_first_sect != drbd_md_first_sector(mdev->ldev)
661b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		|| prev_size	   != mdev->ldev->md.md_size_sect;
662b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
663b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (la_size_changed || md_moved) {
66424dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher		int err;
66524dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher
666b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_al_shrink(mdev); /* All extents inactive. */
667b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_info(DEV, "Writing the whole bitmap, %s\n",
668b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			 la_size_changed && md_moved ? "size changed and md moved" :
669b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			 la_size_changed ? "size changed" : "md moved");
67020ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		/* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
67120ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		err = drbd_bitmap_io(mdev, &drbd_bm_write,
67220ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg				"size changed", BM_LOCKED_MASK);
67324dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher		if (err) {
67424dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher			rv = dev_size_error;
67524dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher			goto out;
67624dccabb390412d04435e11cfb535df51def7b2dAndreas Gruenbacher		}
677b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_md_mark_dirty(mdev);
678b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
679b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
680b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (size > la_size)
681b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		rv = grew;
682b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (size < la_size)
683b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		rv = shrunk;
684b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerout:
685b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	lc_unlock(mdev->act_log);
686b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wake_up(&mdev->al_wait);
687b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_resume_io(mdev);
688b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
689b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return rv;
690b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
691b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
692b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnersector_t
693a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisnerdrbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, int assume_peer_has_space)
694b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
695b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t p_size = mdev->p_size;   /* partner's disk size. */
696b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */
697b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t m_size; /* my size */
698b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t u_size = bdev->dc.disk_size; /* size requested by user. */
699b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t size = 0;
700b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
701b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	m_size = drbd_get_max_capacity(bdev);
702b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
703a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner	if (mdev->state.conn < C_CONNECTED && assume_peer_has_space) {
704a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner		dev_warn(DEV, "Resize while not connected was forced by the user!\n");
705a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner		p_size = m_size;
706a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner	}
707a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner
708b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (p_size && m_size) {
709b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		size = min_t(sector_t, p_size, m_size);
710b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
711b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (la_size) {
712b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			size = la_size;
713b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (m_size && m_size < size)
714b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				size = m_size;
715b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (p_size && p_size < size)
716b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				size = p_size;
717b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		} else {
718b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (m_size)
719b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				size = m_size;
720b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (p_size)
721b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				size = p_size;
722b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
723b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
724b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
725b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (size == 0)
726b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "Both nodes diskless!\n");
727b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
728b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (u_size) {
729b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (u_size > size)
730b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dev_err(DEV, "Requested disk size is too big (%lu > %lu)\n",
731b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (unsigned long)u_size>>1, (unsigned long)size>>1);
732b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		else
733b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			size = u_size;
734b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
735b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
736b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return size;
737b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
738b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
739b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/**
740b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * drbd_check_al_size() - Ensures that the AL is of the right size
741b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * @mdev:	DRBD device.
742b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *
743b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * Returns -EBUSY if current al lru is still used, -ENOMEM when allocation
744b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * failed, and 0 on success. You should call drbd_md_sync() after you called
745b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * this function.
746b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
747b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_check_al_size(struct drbd_conf *mdev)
748b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
749b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct lru_cache *n, *t;
750b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct lc_element *e;
751b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned int in_use;
752b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int i;
753b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
754b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ERR_IF(mdev->sync_conf.al_extents < 7)
755b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->sync_conf.al_extents = 127;
756b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
757b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->act_log &&
758b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->act_log->nr_elements == mdev->sync_conf.al_extents)
759b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return 0;
760b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
761b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	in_use = 0;
762b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	t = mdev->act_log;
763b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	n = lc_create("act_log", drbd_al_ext_cache,
764b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->sync_conf.al_extents, sizeof(struct lc_element), 0);
765b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
766b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (n == NULL) {
767b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "Cannot allocate act_log lru!\n");
768b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return -ENOMEM;
769b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
770b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_lock_irq(&mdev->al_lock);
771b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (t) {
772b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		for (i = 0; i < t->nr_elements; i++) {
773b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			e = lc_element_by_index(t, i);
774b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (e->refcnt)
775b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				dev_err(DEV, "refcnt(%d)==%d\n",
776b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    e->lc_number, e->refcnt);
777b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			in_use += e->refcnt;
778b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
779b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
780b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!in_use)
781b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->act_log = n;
782b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_unlock_irq(&mdev->al_lock);
783b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (in_use) {
784b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "Activity log still in use!\n");
785b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		lc_destroy(n);
786b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return -EBUSY;
787b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
788b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (t)
789b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			lc_destroy(t);
790b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
791b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_mark_dirty(mdev); /* we changed mdev->act_log->nr_elemens */
792b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
793b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
794b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
79599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisnerstatic void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size)
796b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
797b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct request_queue * const q = mdev->rq_queue;
79899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	int max_hw_sectors = max_bio_size >> 9;
79999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	int max_segments = 0;
80099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
80199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (get_ldev_if_state(mdev, D_ATTACHING)) {
80299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
80399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
80499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
80599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		max_segments = mdev->ldev->dc.max_bio_bvecs;
80699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		put_ldev(mdev);
80799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	}
808b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
809b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	blk_queue_logical_block_size(q, 512);
8101816a2b47afae838e53a177d5d166cc7be97d6b5Lars Ellenberg	blk_queue_max_hw_sectors(q, max_hw_sectors);
8111816a2b47afae838e53a177d5d166cc7be97d6b5Lars Ellenberg	/* This is the workaround for "bio would need to, but cannot, be split" */
8121816a2b47afae838e53a177d5d166cc7be97d6b5Lars Ellenberg	blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
8131816a2b47afae838e53a177d5d166cc7be97d6b5Lars Ellenberg	blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1);
814b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
81599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (get_ldev_if_state(mdev, D_ATTACHING)) {
81699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
81799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
81899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		blk_queue_stack_limits(q, b);
81999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
82099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
82199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner			dev_info(DEV, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
82299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner				 q->backing_dev_info.ra_pages,
82399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner				 b->backing_dev_info.ra_pages);
82499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner			q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
82599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		}
82699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		put_ldev(mdev);
82799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	}
82899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner}
82999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
83099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisnervoid drbd_reconsider_max_bio_size(struct drbd_conf *mdev)
83199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner{
83299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	int now, new, local, peer;
83399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
83499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	now = queue_max_hw_sectors(mdev->rq_queue) << 9;
83599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	local = mdev->local_max_bio_size; /* Eventually last known value, from volatile memory */
83699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	peer = mdev->peer_max_bio_size; /* Eventually last known value, from meta data */
837b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
83899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (get_ldev_if_state(mdev, D_ATTACHING)) {
83999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		local = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9;
84099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		mdev->local_max_bio_size = local;
84199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		put_ldev(mdev);
842b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
84399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
84499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	/* We may ignore peer limits if the peer is modern enough.
84599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   Because new from 8.3.8 onwards the peer can use multiple
84699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	   BIOs for a single peer_request */
84799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (mdev->state.conn >= C_CONNECTED) {
84899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		if (mdev->agreed_pro_version < 94)
84999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner			peer = mdev->peer_max_bio_size;
85099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		else if (mdev->agreed_pro_version == 94)
85199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner			peer = DRBD_MAX_SIZE_H80_PACKET;
85299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		else /* drbd 8.3.8 onwards */
85399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner			peer = DRBD_MAX_BIO_SIZE;
85499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	}
85599432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
85699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	new = min_t(int, local, peer);
85799432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
85899432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (mdev->state.role == R_PRIMARY && new < now)
85999432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		dev_err(DEV, "ASSERT FAILED new < now; (%d < %d)\n", new, now);
86099432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
86199432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	if (new != now)
86299432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner		dev_info(DEV, "max BIO size = %u\n", new);
86399432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner
86499432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	drbd_setup_queue_param(mdev, new);
865b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
866b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
867b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* serialize deconfig (worker exiting, doing cleanup)
868b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * and reconfig (drbdsetup disk, drbdsetup net)
869b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *
870c518d04fdec3d8b9d6f8b2228040934de9ee6708Lars Ellenberg * Wait for a potentially exiting worker, then restart it,
871c518d04fdec3d8b9d6f8b2228040934de9ee6708Lars Ellenberg * or start a new one.  Flush any pending work, there may still be an
872c518d04fdec3d8b9d6f8b2228040934de9ee6708Lars Ellenberg * after_state_change queued.
873b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
874b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void drbd_reconfig_start(struct drbd_conf *mdev)
875b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
8766c6c7951be7652f86109f2193651b78d90907c0dLars Ellenberg	wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
877b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
878b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_thread_start(&mdev->worker);
879c518d04fdec3d8b9d6f8b2228040934de9ee6708Lars Ellenberg	drbd_flush_workqueue(mdev);
880b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
881b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
882b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* if still unconfigured, stops worker again.
883b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * if configured now, clears CONFIG_PENDING.
884b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * wakes potential waiters */
885b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void drbd_reconfig_done(struct drbd_conf *mdev)
886b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
887b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_lock_irq(&mdev->req_lock);
888b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.disk == D_DISKLESS &&
889b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->state.conn == C_STANDALONE &&
890b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->state.role == R_SECONDARY) {
891b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		set_bit(DEVICE_DYING, &mdev->flags);
892b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_thread_stop_nowait(&mdev->worker);
893b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else
894b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		clear_bit(CONFIG_PENDING, &mdev->flags);
895b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_unlock_irq(&mdev->req_lock);
896b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	wake_up(&mdev->state_wait);
897b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
898b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
8990778286a133d2d3f81861a4e5db308e359583006Philipp Reisner/* Make sure IO is suspended before calling this function(). */
9000778286a133d2d3f81861a4e5db308e359583006Philipp Reisnerstatic void drbd_suspend_al(struct drbd_conf *mdev)
9010778286a133d2d3f81861a4e5db308e359583006Philipp Reisner{
9020778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	int s = 0;
9030778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
9040778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	if (lc_try_lock(mdev->act_log)) {
9050778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		drbd_al_shrink(mdev);
9060778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		lc_unlock(mdev->act_log);
9070778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	} else {
9080778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		dev_warn(DEV, "Failed to lock al in drbd_suspend_al()\n");
9090778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		return;
9100778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	}
9110778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
9120778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	spin_lock_irq(&mdev->req_lock);
9130778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	if (mdev->state.conn < C_CONNECTED)
9140778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		s = !test_and_set_bit(AL_SUSPENDED, &mdev->flags);
9150778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
9160778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	spin_unlock_irq(&mdev->req_lock);
9170778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
9180778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	if (s)
9190778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		dev_info(DEV, "Suspended AL updates\n");
9200778286a133d2d3f81861a4e5db308e359583006Philipp Reisner}
9210778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
922b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* does always return 0;
923b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * interesting return code is in reply->ret_code */
924b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
925b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			     struct drbd_nl_cfg_reply *reply)
926b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
927116676ca621a862a8124969772f4dd61c8b40eeeAndreas Gruenbacher	enum drbd_ret_code retcode;
928b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum determine_dev_size dd;
929b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t max_possible_sectors;
930b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	sector_t min_md_device_sectors;
931b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
932e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	struct block_device *bdev;
933b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct lru_cache *resync_lru = NULL;
934b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	union drbd_state ns, os;
935f2024e7ce29f4287395ce879364cd68c7ac226f2Andreas Gruenbacher	enum drbd_state_rv rv;
936b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int cp_discovered = 0;
937b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int logical_block_size;
938b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
939b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_start(mdev);
940b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
941b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* if you want to reconfigure, please tear down first */
942b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.disk > D_DISKLESS) {
943b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DISK_CONFIGURED;
944b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
945b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
94682f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	/* It may just now have detached because of IO error.  Make sure
94782f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	 * drbd_ldev_destroy is done already, we may end up here very fast,
94882f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	 * e.g. if someone calls attach from the on-io-error handler,
94982f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	 * to realize a "hot spare" feature (not that I'd recommend that) */
95082f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
951b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
952b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* allocation not in the IO path, cqueue thread context */
953b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
954b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!nbc) {
955b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
956b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
957b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
958b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
959b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc->dc.disk_size     = DRBD_DISK_SIZE_SECT_DEF;
960b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc->dc.on_io_error   = DRBD_ON_IO_ERROR_DEF;
961b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc->dc.fencing       = DRBD_FENCING_DEF;
962b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc->dc.max_bio_bvecs = DRBD_MAX_BIO_BVECS_DEF;
963b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
964b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!disk_conf_from_tags(mdev, nlp->tag_list, &nbc->dc)) {
965b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MANDATORY_TAG;
966b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
967b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
968b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
969b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
970b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MD_IDX_INVALID;
971b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
972b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
973b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
97447ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner	if (get_net_conf(mdev)) {
97547ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		int prot = mdev->net_conf->wire_protocol;
97647ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		put_net_conf(mdev);
97747ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		if (nbc->dc.fencing == FP_STONITH && prot == DRBD_PROT_A) {
97847ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner			retcode = ERR_STONITH_AND_PROT_A;
97947ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner			goto fail;
98047ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		}
98147ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner	}
98247ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner
983d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo	bdev = blkdev_get_by_path(nbc->dc.backing_dev,
984d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo				  FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev);
985e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	if (IS_ERR(bdev)) {
986b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
987e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo			PTR_ERR(bdev));
988b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_OPEN_DISK;
989b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
990b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
991e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	nbc->backing_bdev = bdev;
992e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo
993e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	/*
994e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * meta_dev_idx >= 0: external fixed size, possibly multiple
995e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * drbd sharing one meta device.  TODO in that case, paranoia
996e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * check that [md_bdev, meta_dev_idx] is not yet used by some
997e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * other drbd minor!  (if you use drbd.conf + drbdadm, that
998e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * should check it for you already; but if you don't, or
999e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 * someone fooled it, we need to double check here)
1000e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	 */
1001d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo	bdev = blkdev_get_by_path(nbc->dc.meta_dev,
1002d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo				  FMODE_READ | FMODE_WRITE | FMODE_EXCL,
1003d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo				  (nbc->dc.meta_dev_idx < 0) ?
1004d4d77629953eabd3c14f6fa5746f6b28babfc55fTejun Heo				  (void *)mdev : (void *)drbd_m_holder);
1005e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	if (IS_ERR(bdev)) {
1006b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
1007e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo			PTR_ERR(bdev));
1008b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_OPEN_MD_DISK;
1009b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1010b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1011e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	nbc->md_bdev = bdev;
1012b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1013e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	if ((nbc->backing_bdev == nbc->md_bdev) !=
1014e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	    (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
1015e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo	     nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
1016e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		retcode = ERR_MD_IDX_INVALID;
1017b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1018b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1019b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1020b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	resync_lru = lc_create("resync", drbd_bm_ext_cache,
1021b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			61, sizeof(struct bm_extent),
1022b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			offsetof(struct bm_extent, lce));
1023b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!resync_lru) {
1024b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
1025e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		goto fail;
1026b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1027b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1028b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
1029b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_set_sector_offsets(mdev, nbc);
1030b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1031b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_get_max_capacity(nbc) < nbc->dc.disk_size) {
1032b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "max capacity %llu smaller than disk size %llu\n",
1033b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			(unsigned long long) drbd_get_max_capacity(nbc),
1034b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			(unsigned long long) nbc->dc.disk_size);
1035b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DISK_TO_SMALL;
1036e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		goto fail;
1037b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1038b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1039b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nbc->dc.meta_dev_idx < 0) {
1040b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		max_possible_sectors = DRBD_MAX_SECTORS_FLEX;
1041b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* at least one MB, otherwise it does not make sense */
1042b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		min_md_device_sectors = (2<<10);
1043b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
1044b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		max_possible_sectors = DRBD_MAX_SECTORS;
1045b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		min_md_device_sectors = MD_RESERVED_SECT * (nbc->dc.meta_dev_idx + 1);
1046b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1047b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1048b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) {
1049b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MD_DISK_TO_SMALL;
1050b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "refusing attach: md-device too small, "
1051b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		     "at least %llu sectors needed for this meta-disk type\n",
1052b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		     (unsigned long long) min_md_device_sectors);
1053e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		goto fail;
1054b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1055b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1056b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Make sure the new disk is big enough
1057b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * (we may currently be R_PRIMARY with no local disk...) */
1058b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_get_max_capacity(nbc) <
1059b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    drbd_get_capacity(mdev->this_bdev)) {
1060b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DISK_TO_SMALL;
1061e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		goto fail;
1062b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1063b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1064b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
1065b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
10661352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg	if (nbc->known_size > max_possible_sectors) {
10671352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg		dev_warn(DEV, "==> truncating very big lower level device "
10681352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg			"to currently maximum possible %llu sectors <==\n",
10691352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg			(unsigned long long) max_possible_sectors);
10701352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg		if (nbc->dc.meta_dev_idx >= 0)
10711352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg			dev_warn(DEV, "==>> using internal or flexible "
10721352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg				      "meta data may help <<==\n");
10731352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg	}
10741352994b363195ce932749d3518d4dc9a5479feaLars Ellenberg
1075b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_suspend_io(mdev);
1076b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* also wait for the last barrier ack. */
1077fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || is_susp(mdev->state));
1078b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* and for any other previously queued work */
1079b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_flush_workqueue(mdev);
1080b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1081f2024e7ce29f4287395ce879364cd68c7ac226f2Andreas Gruenbacher	rv = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
1082f2024e7ce29f4287395ce879364cd68c7ac226f2Andreas Gruenbacher	retcode = rv;  /* FIXME: Type mismatch. */
1083b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_resume_io(mdev);
1084f2024e7ce29f4287395ce879364cd68c7ac226f2Andreas Gruenbacher	if (rv < SS_SUCCESS)
1085e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		goto fail;
1086b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1087b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!get_ldev_if_state(mdev, D_ATTACHING))
1088b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless;
1089b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1090b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_set_sector_offsets(mdev, nbc);
1091b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
10924aa83b7bf122106669346eef40632289f540653fLars Ellenberg	/* allocate a second IO page if logical_block_size != 512 */
10934aa83b7bf122106669346eef40632289f540653fLars Ellenberg	logical_block_size = bdev_logical_block_size(nbc->md_bdev);
10944aa83b7bf122106669346eef40632289f540653fLars Ellenberg	if (logical_block_size == 0)
10954aa83b7bf122106669346eef40632289f540653fLars Ellenberg		logical_block_size = MD_SECTOR_SIZE;
10964aa83b7bf122106669346eef40632289f540653fLars Ellenberg
10974aa83b7bf122106669346eef40632289f540653fLars Ellenberg	if (logical_block_size != MD_SECTOR_SIZE) {
10984aa83b7bf122106669346eef40632289f540653fLars Ellenberg		if (!mdev->md_io_tmpp) {
10994aa83b7bf122106669346eef40632289f540653fLars Ellenberg			struct page *page = alloc_page(GFP_NOIO);
11004aa83b7bf122106669346eef40632289f540653fLars Ellenberg			if (!page)
11014aa83b7bf122106669346eef40632289f540653fLars Ellenberg				goto force_diskless_dec;
11024aa83b7bf122106669346eef40632289f540653fLars Ellenberg
11034aa83b7bf122106669346eef40632289f540653fLars Ellenberg			dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
11044aa83b7bf122106669346eef40632289f540653fLars Ellenberg			     logical_block_size, MD_SECTOR_SIZE);
11054aa83b7bf122106669346eef40632289f540653fLars Ellenberg			dev_warn(DEV, "Workaround engaged (has performance impact).\n");
11064aa83b7bf122106669346eef40632289f540653fLars Ellenberg
11074aa83b7bf122106669346eef40632289f540653fLars Ellenberg			mdev->md_io_tmpp = page;
11084aa83b7bf122106669346eef40632289f540653fLars Ellenberg		}
11094aa83b7bf122106669346eef40632289f540653fLars Ellenberg	}
11104aa83b7bf122106669346eef40632289f540653fLars Ellenberg
1111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!mdev->bitmap) {
1112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (drbd_bm_init(mdev)) {
1113b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1114b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto force_diskless_dec;
1115b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1116b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1117b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1118b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = drbd_md_read(mdev, nbc);
1119b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (retcode != NO_ERROR)
1120b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1121b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn < C_CONNECTED &&
1123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->state.role == R_PRIMARY &&
1124b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    (mdev->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) {
1125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "Can only attach to data with current UUID=%016llX\n",
1126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    (unsigned long long)mdev->ed_uuid);
1127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DATA_NOT_CURRENT;
1128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1131b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Since we are diskless, fix the activity log first... */
1132b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_check_al_size(mdev)) {
1133b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
1134b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1135b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1136b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1137b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Prevent shrinking of consistent devices ! */
1138b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
1139a393db6f10ef2d4f28257234cfc730e744dfb6a4Philipp Reisner	    drbd_new_dev_size(mdev, nbc, 0) < nbc->md.la_size_sect) {
1140b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_warn(DEV, "refusing to truncate a consistent device\n");
1141b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DISK_TO_SMALL;
1142b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1143b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1144b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1145b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!drbd_al_read_log(mdev, nbc)) {
1146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_IO_MD_DISK;
1147b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1149b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1150b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Reset the "barriers don't work" bits here, then force meta data to
1151b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * be written, to ensure we determine if barriers are supported. */
1152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nbc->dc.no_md_flush)
1153a8a4e51e6965db84d2af041370ea2ab6232aa4f1Philipp Reisner		set_bit(MD_NO_FUA, &mdev->flags);
1154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
1155a8a4e51e6965db84d2af041370ea2ab6232aa4f1Philipp Reisner		clear_bit(MD_NO_FUA, &mdev->flags);
1156b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* Point of no return reached.
1158b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * Devices and memory are no longer released by error cleanup below.
1159b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * now mdev takes over responsibility, and the state engine should
1160b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * clean it up somewhere.  */
1161b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	D_ASSERT(mdev->ldev == NULL);
1162b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->ldev = nbc;
1163b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->resync = resync_lru;
1164b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	nbc = NULL;
1165b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	resync_lru = NULL;
1166b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
11672451fc3b2bd3a7205270da75a21dde0d5d7c96a2Philipp Reisner	mdev->write_ordering = WO_bdev_flush;
11682451fc3b2bd3a7205270da75a21dde0d5d7c96a2Philipp Reisner	drbd_bump_write_ordering(mdev, WO_bdev_flush);
1169b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1170b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY))
1171b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		set_bit(CRASHED_PRIMARY, &mdev->flags);
1172b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
1173b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		clear_bit(CRASHED_PRIMARY, &mdev->flags);
1174b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1175894c6a946199cf91e52bc1864c3dc6529cceb3dbPhilipp Reisner	if (drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) &&
1176fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	    !(mdev->state.role == R_PRIMARY && mdev->state.susp_nod)) {
1177b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		set_bit(CRASHED_PRIMARY, &mdev->flags);
1178b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		cp_discovered = 1;
1179b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1180b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1181b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->send_cnt = 0;
1182b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->recv_cnt = 0;
1183b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->read_cnt = 0;
1184b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->writ_cnt = 0;
1185b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
118699432fcc528d7a5ac8494a4c07ad4726670c96e2Philipp Reisner	drbd_reconsider_max_bio_size(mdev);
1187b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1188b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* If I am currently not R_PRIMARY,
1189b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * but meta data primary indicator is set,
1190b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * I just now recover from a hard crash,
1191b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * and have been R_PRIMARY before that crash.
1192b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 *
1193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * Now, if I had no connection before that crash
1194b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * (have been degraded R_PRIMARY), chances are that
1195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * I won't find my peer now either.
1196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 *
1197b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * In that case, and _only_ in that case,
1198b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * we use the degr-wfc-timeout instead of the default,
1199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * so we can automatically recover from a crash of a
1200b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * degraded but active "cluster" after a certain timeout.
1201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 */
1202b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
1203b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.role != R_PRIMARY &&
1204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	     drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) &&
1205b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND))
1206b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		set_bit(USE_DEGR_WFC_T, &mdev->flags);
1207b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
120824c4830c8ec3cbc904d84c213126a35f41a4e455Bart Van Assche	dd = drbd_determine_dev_size(mdev, 0);
1209b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dd == dev_size_error) {
1210b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM_BITMAP;
1211b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1212b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else if (dd == grew)
1213b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		set_bit(RESYNC_AFTER_NEG, &mdev->flags);
1214b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1215b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC)) {
1216b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_info(DEV, "Assuming that all blocks are out of sync "
1217b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		     "(aka FullSync)\n");
121820ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write,
121920ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg			"set_n_write from attaching", BM_LOCKED_MASK)) {
1220b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_IO_MD_DISK;
1221b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto force_diskless_dec;
1222b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1223b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
122420ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		if (drbd_bitmap_io(mdev, &drbd_bm_read,
122520ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg			"read from attaching", BM_LOCKED_MASK) < 0) {
1226b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_IO_MD_DISK;
1227b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto force_diskless_dec;
1228b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1229b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1230b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1231b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (cp_discovered) {
1232b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_al_apply_to_bm(mdev);
123320ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		if (drbd_bitmap_io(mdev, &drbd_bm_write,
123420ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg			"crashed primary apply AL", BM_LOCKED_MASK)) {
123519f843aa08e2d8f87a09b4c2edc43b00638423a8Lars Ellenberg			retcode = ERR_IO_MD_DISK;
123619f843aa08e2d8f87a09b4c2edc43b00638423a8Lars Ellenberg			goto force_diskless_dec;
123719f843aa08e2d8f87a09b4c2edc43b00638423a8Lars Ellenberg		}
1238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
12400778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	if (_drbd_bm_total_weight(mdev) == drbd_bm_bits(mdev))
12410778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		drbd_suspend_al(mdev); /* IO is still suspended here... */
12420778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
1243b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_lock_irq(&mdev->req_lock);
1244b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	os = mdev->state;
1245b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ns.i = os.i;
1246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* If MDF_CONSISTENT is not set go into inconsistent state,
1247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   otherwise investigate MDF_WasUpToDate...
1248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   If MDF_WAS_UP_TO_DATE is not set go into D_OUTDATED disk state,
1249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   otherwise into D_CONSISTENT state.
1250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	*/
1251b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_md_test_flag(mdev->ldev, MDF_CONSISTENT)) {
1252b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (drbd_md_test_flag(mdev->ldev, MDF_WAS_UP_TO_DATE))
1253b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			ns.disk = D_CONSISTENT;
1254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		else
1255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			ns.disk = D_OUTDATED;
1256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else {
1257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ns.disk = D_INCONSISTENT;
1258b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1260b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_md_test_flag(mdev->ldev, MDF_PEER_OUT_DATED))
1261b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ns.pdsk = D_OUTDATED;
1262b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1263b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if ( ns.disk == D_CONSISTENT &&
1264b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    (ns.pdsk == D_OUTDATED || mdev->ldev->dc.fencing == FP_DONT_CARE))
1265b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ns.disk = D_UP_TO_DATE;
1266b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1267b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* All tests on MDF_PRIMARY_IND, MDF_CONNECTED_IND,
1268b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   MDF_CONSISTENT and MDF_WAS_UP_TO_DATE must happen before
1269b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   this point, because drbd_request_state() modifies these
1270b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   flags. */
1271b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1272b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* In case we are C_CONNECTED postpone any decision on the new disk
1273b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	   state after the negotiation phase. */
1274b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn == C_CONNECTED) {
1275b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->new_state_tmp.i = ns.i;
1276b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ns.i = os.i;
1277b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		ns.disk = D_NEGOTIATING;
1278dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner
1279dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner		/* We expect to receive up-to-date UUIDs soon.
1280dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner		   To avoid a race in receive_state, free p_uuid while
1281dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner		   holding req_lock. I.e. atomic with the state change */
1282dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner		kfree(mdev->p_uuid);
1283dc66c74de6f4238020db3e2041d4aca5c5b3e9bcPhilipp Reisner		mdev->p_uuid = NULL;
1284b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1285b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1286b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
1287b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ns = mdev->state;
1288b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_unlock_irq(&mdev->req_lock);
1289b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1290b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (rv < SS_SUCCESS)
1291b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto force_diskless_dec;
1292b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1293b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.role == R_PRIMARY)
1294b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
1295b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
1296b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
1297b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1298b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_mark_dirty(mdev);
1299b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
1300b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1301b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
1302b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_ldev(mdev);
1303b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1304b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_done(mdev);
1305b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1306b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1307b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner force_diskless_dec:
1308b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_ldev(mdev);
1309b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner force_diskless:
131082f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	drbd_force_state(mdev, NS(disk, D_FAILED));
1311b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
1312b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner fail:
1313b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nbc) {
1314e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		if (nbc->backing_bdev)
1315e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo			blkdev_put(nbc->backing_bdev,
1316e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo				   FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1317e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo		if (nbc->md_bdev)
1318e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo			blkdev_put(nbc->md_bdev,
1319e525fd89d380c4a94c0d63913a1dd1a593ed25e7Tejun Heo				   FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1320b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		kfree(nbc);
1321b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1322b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	lc_destroy(resync_lru);
1323b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1324b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1325b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_done(mdev);
1326b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1327b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1328b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
132982f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg/* Detaching the disk is a process in multiple stages.  First we need to lock
133082f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg * out application IO, in-flight IO, IO stuck in drbd_al_begin_io.
133182f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg * Then we transition to D_DISKLESS, and wait for put_ldev() to return all
133282f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg * internal references as well.
133382f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg * Only then we have finally detached. */
1334b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1335b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			  struct drbd_nl_cfg_reply *reply)
1336b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
13379a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	enum drbd_ret_code retcode;
13389a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	int ret;
133982f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */
13409a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	retcode = drbd_request_state(mdev, NS(disk, D_FAILED));
13419a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	/* D_FAILED will transition to DISKLESS. */
13429a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	ret = wait_event_interruptible(mdev->misc_wait,
13439a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg			mdev->state.disk != D_FAILED);
134482f59cc6353889b426cf13b6596d5a3d100fa09eLars Ellenberg	drbd_resume_io(mdev);
13459b2f61aec73dc9e735e247fd720c673b30999e7cPhilipp Reisner	if ((int)retcode == (int)SS_IS_DISKLESS)
13469a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg		retcode = SS_NOTHING_TO_DO;
13479a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	if (ret)
13489a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg		retcode = ERR_INTR;
13499a0d9d0389ef769e4b01abf50fcc11407706270bLars Ellenberg	reply->ret_code = retcode;
1350b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1351b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1352b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1353b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1354b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    struct drbd_nl_cfg_reply *reply)
1355b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1356b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int i, ns;
1357116676ca621a862a8124969772f4dd61c8b40eeeAndreas Gruenbacher	enum drbd_ret_code retcode;
1358b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct net_conf *new_conf = NULL;
1359b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct crypto_hash *tfm = NULL;
1360b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct crypto_hash *integrity_w_tfm = NULL;
1361b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct crypto_hash *integrity_r_tfm = NULL;
1362b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct hlist_head *new_tl_hash = NULL;
1363b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct hlist_head *new_ee_hash = NULL;
1364b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_conf *odev;
1365b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char hmac_name[CRYPTO_MAX_ALG_NAME];
1366b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	void *int_dig_out = NULL;
1367b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	void *int_dig_in = NULL;
1368b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	void *int_dig_vv = NULL;
1369b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr;
1370b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1371b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_start(mdev);
1372b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1373b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn > C_STANDALONE) {
1374b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NET_CONFIGURED;
1375b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1376b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1377b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1378b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* allocation not in the IO path, cqueue thread context */
13792db4e42eaceabec42f738f3895300632cd375e67Julia Lawall	new_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL);
1380b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!new_conf) {
1381b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
1382b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1383b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1384b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1385b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->timeout	   = DRBD_TIMEOUT_DEF;
1386b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->try_connect_int  = DRBD_CONNECT_INT_DEF;
1387b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->ping_int	   = DRBD_PING_INT_DEF;
1388b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->max_epoch_size   = DRBD_MAX_EPOCH_SIZE_DEF;
1389b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->max_buffers	   = DRBD_MAX_BUFFERS_DEF;
1390b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF;
1391b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->sndbuf_size	   = DRBD_SNDBUF_SIZE_DEF;
1392b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->rcvbuf_size	   = DRBD_RCVBUF_SIZE_DEF;
1393b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->ko_count	   = DRBD_KO_COUNT_DEF;
1394b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->after_sb_0p	   = DRBD_AFTER_SB_0P_DEF;
1395b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->after_sb_1p	   = DRBD_AFTER_SB_1P_DEF;
1396b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->after_sb_2p	   = DRBD_AFTER_SB_2P_DEF;
1397b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->want_lose	   = 0;
1398b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->two_primaries    = 0;
1399b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->wire_protocol    = DRBD_PROT_C;
1400b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->ping_timeo	   = DRBD_PING_TIMEO_DEF;
1401b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_conf->rr_conflict	   = DRBD_RR_CONFLICT_DEF;
1402422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner	new_conf->on_congestion    = DRBD_ON_CONGESTION_DEF;
1403422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner	new_conf->cong_extents     = DRBD_CONG_EXTENTS_DEF;
1404b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1405b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!net_conf_from_tags(mdev, nlp->tag_list, new_conf)) {
1406b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MANDATORY_TAG;
1407b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1408b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1409b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1410b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_conf->two_primaries
1411b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    && (new_conf->wire_protocol != DRBD_PROT_C)) {
1412b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOT_PROTO_C;
1413b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
141447ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner	}
141547ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner
141647ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner	if (get_ldev(mdev)) {
141747ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		enum drbd_fencing_p fp = mdev->ldev->dc.fencing;
141847ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		put_ldev(mdev);
141947ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		if (new_conf->wire_protocol == DRBD_PROT_A && fp == FP_STONITH) {
142047ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner			retcode = ERR_STONITH_AND_PROT_A;
142147ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner			goto fail;
142247ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner		}
142347ff2d0a8e7ce87fed180729e8341f650bf585c8Philipp Reisner	}
1424b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1425422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner	if (new_conf->on_congestion != OC_BLOCK && new_conf->wire_protocol != DRBD_PROT_A) {
1426422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner		retcode = ERR_CONG_NOT_PROTO_A;
1427422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner		goto fail;
1428422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner	}
1429422028b1ca4c07995af82a18abced022ff4c296cPhilipp Reisner
1430b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.role == R_PRIMARY && new_conf->want_lose) {
1431b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_DISCARD;
1432b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1433b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1434b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1435b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = NO_ERROR;
1436b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1437b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_my_addr = (struct sockaddr *)&new_conf->my_addr;
1438b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	new_peer_addr = (struct sockaddr *)&new_conf->peer_addr;
1439b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	for (i = 0; i < minor_count; i++) {
1440b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		odev = minor_to_mdev(i);
1441b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!odev || odev == mdev)
1442b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
1443b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (get_net_conf(odev)) {
1444b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			taken_addr = (struct sockaddr *)&odev->net_conf->my_addr;
1445b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (new_conf->my_addr_len == odev->net_conf->my_addr_len &&
1446b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    !memcmp(new_my_addr, taken_addr, new_conf->my_addr_len))
1447b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				retcode = ERR_LOCAL_ADDR;
1448b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1449b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			taken_addr = (struct sockaddr *)&odev->net_conf->peer_addr;
1450b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (new_conf->peer_addr_len == odev->net_conf->peer_addr_len &&
1451b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    !memcmp(new_peer_addr, taken_addr, new_conf->peer_addr_len))
1452b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				retcode = ERR_PEER_ADDR;
1453b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1454b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_net_conf(odev);
1455b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (retcode != NO_ERROR)
1456b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				goto fail;
1457b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1458b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1459b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1460b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_conf->cram_hmac_alg[0] != 0) {
1461b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
1462b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			new_conf->cram_hmac_alg);
1463b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC);
1464b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (IS_ERR(tfm)) {
1465b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			tfm = NULL;
1466b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_AUTH_ALG;
1467b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1468b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1469b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
14700798219f6154baa6a8efe767bfffb4a724e4b1e1Philipp Reisner		if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
1471b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_AUTH_ALG_ND;
1472b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1473b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1474b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1475b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1476b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_conf->integrity_alg[0]) {
1477b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
1478b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (IS_ERR(integrity_w_tfm)) {
1479b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			integrity_w_tfm = NULL;
1480b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode=ERR_INTEGRITY_ALG;
1481b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1482b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1483b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1484b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!drbd_crypto_is_hash(crypto_hash_tfm(integrity_w_tfm))) {
1485b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode=ERR_INTEGRITY_ALG_ND;
1486b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1487b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1488b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1489b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
1490b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (IS_ERR(integrity_r_tfm)) {
1491b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			integrity_r_tfm = NULL;
1492b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode=ERR_INTEGRITY_ALG;
1493b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1494b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1495b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1496b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1497b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ns = new_conf->max_epoch_size/8;
1498b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->tl_hash_s != ns) {
1499b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
1500b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!new_tl_hash) {
1501b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1502b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1503b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1504b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1505b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1506b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ns = new_conf->max_buffers/8;
1507b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_conf->two_primaries && (mdev->ee_hash_s != ns)) {
1508b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		new_ee_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
1509b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!new_ee_hash) {
1510b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1511b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1512b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1513b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1514b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1515b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
1516b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1517b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (integrity_w_tfm) {
1518b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		i = crypto_hash_digestsize(integrity_w_tfm);
1519b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		int_dig_out = kmalloc(i, GFP_KERNEL);
1520b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!int_dig_out) {
1521b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1522b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1523b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1524b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		int_dig_in = kmalloc(i, GFP_KERNEL);
1525b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!int_dig_in) {
1526b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1527b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1528b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1529b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		int_dig_vv = kmalloc(i, GFP_KERNEL);
1530b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!int_dig_vv) {
1531b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1532b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1533b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1534b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1535b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1536b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!mdev->bitmap) {
1537b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if(drbd_bm_init(mdev)) {
1538b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1539b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1540b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1541b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1542b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1543f70b3511599c49a3dc20ae349d6cdc5af47659dfPhilipp Reisner	drbd_flush_workqueue(mdev);
1544b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_lock_irq(&mdev->req_lock);
1545b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->net_conf != NULL) {
1546b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NET_CONFIGURED;
1547b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		spin_unlock_irq(&mdev->req_lock);
1548b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1549b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1550b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->net_conf = new_conf;
1551b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1552b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->send_cnt = 0;
1553b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->recv_cnt = 0;
1554b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1555b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_tl_hash) {
1556b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		kfree(mdev->tl_hash);
1557b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->tl_hash_s = mdev->net_conf->max_epoch_size/8;
1558b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->tl_hash = new_tl_hash;
1559b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1560b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1561b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (new_ee_hash) {
1562b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		kfree(mdev->ee_hash);
1563b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ee_hash_s = mdev->net_conf->max_buffers/8;
1564b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ee_hash = new_ee_hash;
1565b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1566b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1567b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(mdev->cram_hmac_tfm);
1568b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->cram_hmac_tfm = tfm;
1569b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1570b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(mdev->integrity_w_tfm);
1571b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->integrity_w_tfm = integrity_w_tfm;
1572b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1573b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(mdev->integrity_r_tfm);
1574b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->integrity_r_tfm = integrity_r_tfm;
1575b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1576b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(mdev->int_dig_out);
1577b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(mdev->int_dig_in);
1578b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(mdev->int_dig_vv);
1579b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->int_dig_out=int_dig_out;
1580b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->int_dig_in=int_dig_in;
1581b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->int_dig_vv=int_dig_vv;
1582f70b3511599c49a3dc20ae349d6cdc5af47659dfPhilipp Reisner	retcode = _drbd_set_state(_NS(mdev, conn, C_UNCONNECTED), CS_VERBOSE, NULL);
1583b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_unlock_irq(&mdev->req_lock);
1584b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1585b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
1586b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1587b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_done(mdev);
1588b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1589b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1590b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerfail:
1591b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(int_dig_out);
1592b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(int_dig_in);
1593b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(int_dig_vv);
1594b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(tfm);
1595b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(integrity_w_tfm);
1596b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(integrity_r_tfm);
1597b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(new_tl_hash);
1598b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(new_ee_hash);
1599b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(new_conf);
1600b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1601b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1602b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_reconfig_done(mdev);
1603b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1604b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1605b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1606b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1607b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      struct drbd_nl_cfg_reply *reply)
1608b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1609b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode;
16102561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	struct disconnect dc;
16112561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner
16122561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	memset(&dc, 0, sizeof(struct disconnect));
16132561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	if (!disconnect_from_tags(mdev, nlp->tag_list, &dc)) {
16142561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		retcode = ERR_MANDATORY_TAG;
16152561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		goto fail;
16162561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	}
16172561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner
16182561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	if (dc.force) {
16192561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		spin_lock_irq(&mdev->req_lock);
16202561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		if (mdev->state.conn >= C_WF_CONNECTION)
16212561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner			_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), CS_HARD, NULL);
16222561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		spin_unlock_irq(&mdev->req_lock);
16232561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner		goto done;
16242561b9c1f1d63077c41903fc6ad58dc9ec47248bPhilipp Reisner	}
1625b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1626b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = _drbd_request_state(mdev, NS(conn, C_DISCONNECTING), CS_ORDERED);
1627b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1628b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (retcode == SS_NOTHING_TO_DO)
1629b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto done;
1630b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else if (retcode == SS_ALREADY_STANDALONE)
1631b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto done;
1632b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else if (retcode == SS_PRIMARY_NOP) {
1633b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* Our statche checking code wants to see the peer outdated. */
1634b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
1635b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner						      pdsk, D_OUTDATED));
1636b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else if (retcode == SS_CW_FAILED_BY_PEER) {
1637b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* The peer probably wants to see us outdated. */
1638b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = _drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
1639b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner							disk, D_OUTDATED),
1640b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner					      CS_ORDERED);
1641b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (retcode == SS_IS_DISKLESS || retcode == SS_LOWER_THAN_OUTDATED) {
1642b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
1643b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = SS_SUCCESS;
1644b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1645b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1646b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1647b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (retcode < SS_SUCCESS)
1648b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1649b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1650b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (wait_event_interruptible(mdev->state_wait,
1651b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				     mdev->state.conn != C_DISCONNECTING)) {
1652b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* Do not test for mdev->state.conn == C_STANDALONE, since
1653b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		   someone else might connect us in the mean time! */
1654b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_INTR;
1655b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1656b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1657b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1658b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner done:
1659b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = NO_ERROR;
1660b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner fail:
1661b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
1662b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1663b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1664b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1665b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1666b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid resync_after_online_grow(struct drbd_conf *mdev)
1667b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1668b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int iass; /* I am sync source */
1669b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1670b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dev_info(DEV, "Resync of new storage after online grow\n");
1671b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.role != mdev->state.peer)
1672b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		iass = (mdev->state.role == R_PRIMARY);
1673b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
1674b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		iass = test_bit(DISCARD_CONCURRENT, &mdev->flags);
1675b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1676b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (iass)
1677b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_start_resync(mdev, C_SYNC_SOURCE);
1678b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
1679b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		_drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE + CS_SERIALIZE);
1680b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1681b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1682b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1683b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			  struct drbd_nl_cfg_reply *reply)
1684b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1685b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct resize rs;
1686b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode = NO_ERROR;
1687b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	enum determine_dev_size dd;
16886495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner	enum dds_flags ddsf;
1689b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1690b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	memset(&rs, 0, sizeof(struct resize));
1691b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!resize_from_tags(mdev, nlp->tag_list, &rs)) {
1692b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MANDATORY_TAG;
1693b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1694b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1695b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1696b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn > C_CONNECTED) {
1697b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_RESIZE_RESYNC;
1698b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1699b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1700b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1701b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.role == R_SECONDARY &&
1702b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->state.peer == R_SECONDARY) {
1703b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NO_PRIMARY;
1704b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1705b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1706b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1707b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!get_ldev(mdev)) {
1708b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NO_DISK;
1709b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1710b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1711b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
17126495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner	if (rs.no_resync && mdev->agreed_pro_version < 93) {
17136495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner		retcode = ERR_NEED_APV_93;
17146495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner		goto fail;
17156495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner	}
17166495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner
1717087c24925cf4209be1a91f8ede9241e17e9734c7Philipp Reisner	if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev))
1718b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
1719b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1720b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->ldev->dc.disk_size = (sector_t)rs.resize_size;
17216495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner	ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
172224c4830c8ec3cbc904d84c213126a35f41a4e455Bart Van Assche	dd = drbd_determine_dev_size(mdev, ddsf);
1723b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
1724b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_ldev(mdev);
1725b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dd == dev_size_error) {
1726b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM_BITMAP;
1727b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1728b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1729b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1730087c24925cf4209be1a91f8ede9241e17e9734c7Philipp Reisner	if (mdev->state.conn == C_CONNECTED) {
1731b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (dd == grew)
1732b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			set_bit(RESIZE_PENDING, &mdev->flags);
1733b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1734b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_send_uuids(mdev);
17356495d2c6d04f4c45411fdb1b40527c24015f39d6Philipp Reisner		drbd_send_sizes(mdev, 1, ddsf);
1736b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1737b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1738b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner fail:
1739b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1740b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1741b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1742b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1743b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1744b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			       struct drbd_nl_cfg_reply *reply)
1745b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1746b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode = NO_ERROR;
1747b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int err;
1748b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int ovr; /* online verify running */
1749b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int rsr; /* re-sync running */
1750b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct crypto_hash *verify_tfm = NULL;
1751b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct crypto_hash *csums_tfm = NULL;
1752b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct syncer_conf sc;
1753b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cpumask_var_t new_cpu_mask;
1754778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	int *rs_plan_s = NULL;
1755778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	int fifo_size;
1756b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1757b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) {
1758b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
1759b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1760b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1761b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1762b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nlp->flags & DRBD_NL_SET_DEFAULTS) {
1763b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		memset(&sc, 0, sizeof(struct syncer_conf));
1764b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sc.rate       = DRBD_RATE_DEF;
1765b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sc.after      = DRBD_AFTER_DEF;
1766b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sc.al_extents = DRBD_AL_EXTENTS_DEF;
1767265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner		sc.on_no_data  = DRBD_ON_NO_DATA_DEF;
17689a31d7164d409ca59cfadb7957ac7b0acf4545b8Philipp Reisner		sc.c_plan_ahead = DRBD_C_PLAN_AHEAD_DEF;
17699a31d7164d409ca59cfadb7957ac7b0acf4545b8Philipp Reisner		sc.c_delay_target = DRBD_C_DELAY_TARGET_DEF;
17709a31d7164d409ca59cfadb7957ac7b0acf4545b8Philipp Reisner		sc.c_fill_target = DRBD_C_FILL_TARGET_DEF;
17710f0601f4ea2f53cfd8bcae060fb03d9bbde070ecLars Ellenberg		sc.c_max_rate = DRBD_C_MAX_RATE_DEF;
17720f0601f4ea2f53cfd8bcae060fb03d9bbde070ecLars Ellenberg		sc.c_min_rate = DRBD_C_MIN_RATE_DEF;
1773b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else
1774b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf));
1775b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1776b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!syncer_conf_from_tags(mdev, nlp->tag_list, &sc)) {
1777b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MANDATORY_TAG;
1778b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1779b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1780b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1781b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* re-sync running */
1782b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rsr = (	mdev->state.conn == C_SYNC_SOURCE ||
1783b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->state.conn == C_SYNC_TARGET ||
1784b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->state.conn == C_PAUSED_SYNC_S ||
1785b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->state.conn == C_PAUSED_SYNC_T );
1786b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1787b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (rsr && strcmp(sc.csums_alg, mdev->sync_conf.csums_alg)) {
1788b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_CSUMS_RESYNC_RUNNING;
1789b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1790b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1791b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1792b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!rsr && sc.csums_alg[0]) {
1793b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		csums_tfm = crypto_alloc_hash(sc.csums_alg, 0, CRYPTO_ALG_ASYNC);
1794b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (IS_ERR(csums_tfm)) {
1795b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			csums_tfm = NULL;
1796b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_CSUMS_ALG;
1797b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1798b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1799b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1800b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!drbd_crypto_is_hash(crypto_hash_tfm(csums_tfm))) {
1801b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_CSUMS_ALG_ND;
1802b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1803b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1804b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1805b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1806b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* online verify running */
1807b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ovr = (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T);
1808b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1809b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (ovr) {
1810b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (strcmp(sc.verify_alg, mdev->sync_conf.verify_alg)) {
1811b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_VERIFY_RUNNING;
1812b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1813b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1814b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1815b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1816b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!ovr && sc.verify_alg[0]) {
1817b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		verify_tfm = crypto_alloc_hash(sc.verify_alg, 0, CRYPTO_ALG_ASYNC);
1818b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (IS_ERR(verify_tfm)) {
1819b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			verify_tfm = NULL;
1820b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_VERIFY_ALG;
1821b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1822b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1823b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1824b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!drbd_crypto_is_hash(crypto_hash_tfm(verify_tfm))) {
1825b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_VERIFY_ALG_ND;
1826b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1827b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1828b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1829b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1830b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* silently ignore cpu mask on UP kernel */
1831b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nr_cpu_ids > 1 && sc.cpu_mask[0] != 0) {
1832ddad9ef5826efdfbbdb67b13b46f30e43e46ec3eH Hartley Sweeten		err = bitmap_parse(sc.cpu_mask, 32,
1833b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				cpumask_bits(new_cpu_mask), nr_cpu_ids);
1834b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (err) {
1835ddad9ef5826efdfbbdb67b13b46f30e43e46ec3eH Hartley Sweeten			dev_warn(DEV, "bitmap_parse() failed with %d\n", err);
1836b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_CPU_MASK_PARSE;
1837b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1838b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1839b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1840b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1841b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ERR_IF (sc.rate < 1) sc.rate = 1;
1842b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	ERR_IF (sc.al_extents < 7) sc.al_extents = 127; /* arbitrary minimum */
1843b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#define AL_MAX ((MD_AL_MAX_SIZE-1) * AL_EXTENTS_PT)
1844b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (sc.al_extents > AL_MAX) {
1845b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "sc.al_extents > %d\n", AL_MAX);
1846b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sc.al_extents = AL_MAX;
1847b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1848b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#undef AL_MAX
1849b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1850ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	/* to avoid spurious errors when configuring minors before configuring
1851ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	 * the minors they depend on: if necessary, first create the minor we
1852ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	 * depend on */
1853ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	if (sc.after >= 0)
1854ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg		ensure_mdev(sc.after, 1);
1855ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg
1856b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* most sanity checks done, try to assign the new sync-after
1857b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * dependency.  need to hold the global lock in there,
1858b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * to avoid a race in the dependency loop check. */
1859b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = drbd_alter_sa(mdev, sc.after);
1860b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (retcode != NO_ERROR)
1861b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
1862b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1863778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	fifo_size = (sc.c_plan_ahead * 10 * SLEEP_TIME) / HZ;
1864778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	if (fifo_size != mdev->rs_plan_s.size && fifo_size > 0) {
1865778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		rs_plan_s   = kzalloc(sizeof(int) * fifo_size, GFP_KERNEL);
1866778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		if (!rs_plan_s) {
1867778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner			dev_err(DEV, "kmalloc of fifo_buffer failed");
1868778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner			retcode = ERR_NOMEM;
1869778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner			goto fail;
1870778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		}
1871778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	}
1872778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner
1873b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* ok, assign the rest of it as well.
1874b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * lock against receive_SyncParam() */
1875b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_lock(&mdev->peer_seq_lock);
1876b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->sync_conf = sc;
1877b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1878b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!rsr) {
1879b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		crypto_free_hash(mdev->csums_tfm);
1880b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->csums_tfm = csums_tfm;
1881b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		csums_tfm = NULL;
1882b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1883b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1884b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!ovr) {
1885b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		crypto_free_hash(mdev->verify_tfm);
1886b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->verify_tfm = verify_tfm;
1887b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		verify_tfm = NULL;
1888b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1889778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner
1890778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	if (fifo_size != mdev->rs_plan_s.size) {
1891778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		kfree(mdev->rs_plan_s.values);
1892778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		mdev->rs_plan_s.values = rs_plan_s;
1893778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		mdev->rs_plan_s.size   = fifo_size;
1894778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		mdev->rs_planed = 0;
1895778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner		rs_plan_s = NULL;
1896778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	}
1897778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner
1898b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	spin_unlock(&mdev->peer_seq_lock);
1899b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1900b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_ldev(mdev)) {
1901b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
1902b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_al_shrink(mdev);
1903b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		err = drbd_check_al_size(mdev);
1904b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		lc_unlock(mdev->act_log);
1905b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		wake_up(&mdev->al_wait);
1906b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1907b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_ldev(mdev);
1908b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_md_sync(mdev);
1909b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1910b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (err) {
1911b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_NOMEM;
1912b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			goto fail;
1913b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
1914b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1915b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1916b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn >= C_CONNECTED)
1917b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_send_sync_param(mdev, &sc);
1918b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1919b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!cpumask_equal(mdev->cpu_mask, new_cpu_mask)) {
1920b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		cpumask_copy(mdev->cpu_mask, new_cpu_mask);
1921b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		drbd_calc_cpu_mask(mdev);
1922b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->receiver.reset_cpu_mask = 1;
1923b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->asender.reset_cpu_mask = 1;
1924b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev->worker.reset_cpu_mask = 1;
1925b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1926b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1927b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
1928b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerfail:
1929778f271dfe7a7173c0bae2d6cde8d9bd1533e668Philipp Reisner	kfree(rs_plan_s);
1930b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	free_cpumask_var(new_cpu_mask);
1931b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(csums_tfm);
1932b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	crypto_free_hash(verify_tfm);
1933b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1934b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1935b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1936b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1937b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1938b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      struct drbd_nl_cfg_reply *reply)
1939b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
1940b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode;
1941b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1942194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	/* If there is still bitmap IO pending, probably because of a previous
1943194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	 * resync just being finished, wait for it before requesting a new resync. */
1944194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
1945194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg
1946b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T), CS_ORDERED);
1947b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1948b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (retcode < SS_SUCCESS && retcode != SS_NEED_CONNECTION)
1949b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T));
1950b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1951b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	while (retcode == SS_NEED_CONNECTION) {
1952b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		spin_lock_irq(&mdev->req_lock);
1953b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (mdev->state.conn < C_CONNECTED)
1954b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = _drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_VERBOSE, NULL);
1955b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		spin_unlock_irq(&mdev->req_lock);
1956b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1957b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (retcode != SS_NEED_CONNECTION)
1958b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			break;
1959b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1960b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T));
1961b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
1962b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1963b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
1964b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
1965b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
1966b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
19670778286a133d2d3f81861a4e5db308e359583006Philipp Reisnerstatic int drbd_bmio_set_susp_al(struct drbd_conf *mdev)
19680778286a133d2d3f81861a4e5db308e359583006Philipp Reisner{
19690778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	int rv;
19700778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
19710778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	rv = drbd_bmio_set_n_write(mdev);
19720778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	drbd_suspend_al(mdev);
19730778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	return rv;
19740778286a133d2d3f81861a4e5db308e359583006Philipp Reisner}
19750778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
1976b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1977b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				   struct drbd_nl_cfg_reply *reply)
1978b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
19790778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	int retcode;
1980b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
1981194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	/* If there is still bitmap IO pending, probably because of a previous
1982194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	 * resync just being finished, wait for it before requesting a new resync. */
1983194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
1984194bfb32dba8345a7e0f83e9b1ee965e14d4b679Lars Ellenberg
19850778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S), CS_ORDERED);
19860778286a133d2d3f81861a4e5db308e359583006Philipp Reisner
19870778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	if (retcode < SS_SUCCESS) {
19880778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		if (retcode == SS_NEED_CONNECTION && mdev->state.role == R_PRIMARY) {
19890778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			/* The peer will get a resync upon connect anyways. Just make that
19900778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			   into a full resync. */
19910778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			retcode = drbd_request_state(mdev, NS(pdsk, D_INCONSISTENT));
19920778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			if (retcode >= SS_SUCCESS) {
19930778286a133d2d3f81861a4e5db308e359583006Philipp Reisner				if (drbd_bitmap_io(mdev, &drbd_bmio_set_susp_al,
199420ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg					"set_n_write from invalidate_peer",
199520ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg					BM_LOCKED_SET_ALLOWED))
19960778286a133d2d3f81861a4e5db308e359583006Philipp Reisner					retcode = ERR_IO_MD_DISK;
19970778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			}
19980778286a133d2d3f81861a4e5db308e359583006Philipp Reisner		} else
19990778286a133d2d3f81861a4e5db308e359583006Philipp Reisner			retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S));
20000778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	}
2001b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
20020778286a133d2d3f81861a4e5db308e359583006Philipp Reisner	reply->ret_code = retcode;
2003b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2004b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2005b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2006b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_pause_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2007b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      struct drbd_nl_cfg_reply *reply)
2008b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2009b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode = NO_ERROR;
2010b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2011b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (drbd_request_state(mdev, NS(user_isp, 1)) == SS_NOTHING_TO_DO)
2012b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_PAUSE_IS_SET;
2013b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2014b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
2015b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2016b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2017b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2018b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_resume_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2019b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			       struct drbd_nl_cfg_reply *reply)
2020b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2021b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode = NO_ERROR;
2022cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner	union drbd_state s;
2023b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2024cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner	if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NOTHING_TO_DO) {
2025cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner		s = mdev->state;
2026cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner		if (s.conn == C_PAUSED_SYNC_S || s.conn == C_PAUSED_SYNC_T) {
2027cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner			retcode = s.aftr_isp ? ERR_PIC_AFTER_DEP :
2028cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner				  s.peer_isp ? ERR_PIC_PEER_DEP : ERR_PAUSE_IS_CLEAR;
2029cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner		} else {
2030cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner			retcode = ERR_PAUSE_IS_CLEAR;
2031cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner		}
2032cd88d030d41a9b0100fd5fee872024e6ebc8b276Philipp Reisner	}
2033b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2034b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
2035b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2036b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2037b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2038b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2039b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      struct drbd_nl_cfg_reply *reply)
2040b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2041b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = drbd_request_state(mdev, NS(susp, 1));
2042b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2043b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2044b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2045b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2046b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2047b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			     struct drbd_nl_cfg_reply *reply)
2048b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
204943a5182cccae5850f7590f78dd9651bd407be440Philipp Reisner	if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
205043a5182cccae5850f7590f78dd9651bd407be440Philipp Reisner		drbd_uuid_new_current(mdev);
205143a5182cccae5850f7590f78dd9651bd407be440Philipp Reisner		clear_bit(NEW_CUR_UUID, &mdev->flags);
205243a5182cccae5850f7590f78dd9651bd407be440Philipp Reisner	}
2053265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner	drbd_suspend_io(mdev);
2054fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner	reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0));
2055265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner	if (reply->ret_code == SS_SUCCESS) {
2056265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner		if (mdev->state.conn < C_CONNECTED)
2057265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner			tl_clear(mdev);
2058265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner		if (mdev->state.disk == D_DISKLESS || mdev->state.disk == D_FAILED)
2059265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner			tl_restart(mdev, fail_frozen_disk_io);
2060265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner	}
2061265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner	drbd_resume_io(mdev);
2062265be2d09853d425ad14a61cda0ca63345613d0cPhilipp Reisner
2063b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2064b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2065b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2066b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_outdate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2067b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   struct drbd_nl_cfg_reply *reply)
2068b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2069b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = drbd_request_state(mdev, NS(disk, D_OUTDATED));
2070b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2071b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2072b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2073b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2074b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   struct drbd_nl_cfg_reply *reply)
2075b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2076b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl;
2077b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2078b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = reply->tag_list;
2079b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2080b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_ldev(mdev)) {
2081b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = disk_conf_to_tags(mdev, &mdev->ldev->dc, tl);
2082b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_ldev(mdev);
2083b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2084b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2085b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_net_conf(mdev)) {
2086b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = net_conf_to_tags(mdev, mdev->net_conf, tl);
2087b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_net_conf(mdev);
2088b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2089b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl);
2090b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2091b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2092b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2093b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return (int)((char *)tl - (char *)reply->tag_list);
2094b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2095b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2096b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_get_state(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2097b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			     struct drbd_nl_cfg_reply *reply)
2098b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2099b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl = reply->tag_list;
2100b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	union drbd_state s = mdev->state;
2101b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned long rs_left;
2102b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned int res;
2103b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2104b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = get_state_to_tags(mdev, (struct get_state *)&s, tl);
2105b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2106b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* no local ref, no bitmap, no syncer progress. */
2107b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (s.conn >= C_SYNC_SOURCE && s.conn <= C_PAUSED_SYNC_T) {
2108b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (get_ldev(mdev)) {
2109b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			drbd_get_syncer_progress(mdev, &rs_left, &res);
2110b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			tl = tl_add_int(tl, T_sync_progress, &res);
2111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_ldev(mdev);
2112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
2113b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2114b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2115b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2116b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return (int)((char *)tl - (char *)reply->tag_list);
2117b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2118b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2119b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_get_uuids(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2120b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			     struct drbd_nl_cfg_reply *reply)
2121b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl;
2123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2124b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = reply->tag_list;
2125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (get_ldev(mdev)) {
2127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = tl_add_blob(tl, T_uuids, mdev->ldev->md.uuid, UI_SIZE*sizeof(u64));
2128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = tl_add_int(tl, T_uuids_flags, &mdev->ldev->md.flags);
2129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_ldev(mdev);
2130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2131b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2132b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2133b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return (int)((char *)tl - (char *)reply->tag_list);
2134b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2135b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2136b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/**
2137b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * drbd_nl_get_timeout_flag() - Used by drbdsetup to find out which timeout value to use
2138b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * @mdev:	DRBD device.
2139b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * @nlp:	Netlink/connector packet from drbdsetup
2140b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * @reply:	Reply packet for drbdsetup
2141b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
2142b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_get_timeout_flag(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2143b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    struct drbd_nl_cfg_reply *reply)
2144b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2145b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl;
2146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char rv;
2147b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = reply->tag_list;
2149b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2150b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rv = mdev->state.pdsk == D_OUTDATED        ? UT_PEER_OUTDATED :
2151b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  test_bit(USE_DEGR_WFC_T, &mdev->flags) ? UT_DEGRADED : UT_DEFAULT;
2152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2153b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_blob(tl, T_use_degraded, &rv, sizeof(rv));
2154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2155b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2156b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return (int)((char *)tl - (char *)reply->tag_list);
2157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2158b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2159b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2160b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    struct drbd_nl_cfg_reply *reply)
2161b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2162b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* default to resume from last known position, if possible */
2163b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct start_ov args =
2164b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		{ .start_sector = mdev->ov_start_sector };
2165b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2166b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!start_ov_from_tags(mdev, nlp->tag_list, &args)) {
2167b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		reply->ret_code = ERR_MANDATORY_TAG;
2168b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return 0;
2169b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2170873b0d5f98ab70e4df7a62b2ef0305373f88f330Lars Ellenberg
2171873b0d5f98ab70e4df7a62b2ef0305373f88f330Lars Ellenberg	/* If there is still bitmap IO pending, e.g. previous resync or verify
2172873b0d5f98ab70e4df7a62b2ef0305373f88f330Lars Ellenberg	 * just being finished, wait for it before requesting a new resync. */
2173873b0d5f98ab70e4df7a62b2ef0305373f88f330Lars Ellenberg	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
2174873b0d5f98ab70e4df7a62b2ef0305373f88f330Lars Ellenberg
2175b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* w_make_ov_request expects position to be aligned */
2176b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT;
2177b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S));
2178b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2179b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2180b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2181b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2182b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
2183b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			      struct drbd_nl_cfg_reply *reply)
2184b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2185b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode = NO_ERROR;
2186b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int skip_initial_sync = 0;
2187b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int err;
2188b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2189b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct new_c_uuid args;
2190b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2191b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	memset(&args, 0, sizeof(struct new_c_uuid));
2192b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!new_c_uuid_from_tags(mdev, nlp->tag_list, &args)) {
2193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		reply->ret_code = ERR_MANDATORY_TAG;
2194b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return 0;
2195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2197b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mutex_lock(&mdev->state_mutex); /* Protects us against serialized state changes. */
2198b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!get_ldev(mdev)) {
2200b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NO_DISK;
2201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto out;
2202b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2203b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* this is "skip initial sync", assume to be clean */
2205b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->state.conn == C_CONNECTED && mdev->agreed_pro_version >= 90 &&
2206b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	    mdev->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
2207b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_info(DEV, "Preparing to skip initial sync\n");
2208b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		skip_initial_sync = 1;
2209b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} else if (mdev->state.conn != C_STANDALONE) {
2210b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_CONNECTED;
2211b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto out_dec;
2212b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2213b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2214b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_uuid_set(mdev, UI_BITMAP, 0); /* Rotate UI_BITMAP to History 1, etc... */
2215b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_uuid_new_current(mdev); /* New current, previous to UI_BITMAP */
2216b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2217b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (args.clear_bm) {
221820ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg		err = drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write,
221920ceb2b22edaf51e59e76087efdc71a16a2858deLars Ellenberg			"clear_n_write from new_c_uuid", BM_LOCKED_MASK);
2220b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (err) {
2221b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dev_err(DEV, "Writing bitmap failed with %d\n",err);
2222b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			retcode = ERR_IO_MD_DISK;
2223b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
2224b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (skip_initial_sync) {
2225b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			drbd_send_uuids_skip_initial_sync(mdev);
2226b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			_drbd_uuid_set(mdev, UI_BITMAP, 0);
222762b0da3a244ac33d25a77861ef1cc0080103f2ffLars Ellenberg			drbd_print_uuids(mdev, "cleared bitmap UUID");
2228b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			spin_lock_irq(&mdev->req_lock);
2229b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			_drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
2230b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner					CS_VERBOSE, NULL);
2231b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			spin_unlock_irq(&mdev->req_lock);
2232b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
2233b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2234b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2235b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_md_sync(mdev);
2236b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerout_dec:
2237b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_ldev(mdev);
2238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerout:
2239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	mutex_unlock(&mdev->state_mutex);
2240b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2241b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = retcode;
2242b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2243b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2244b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2245b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstruct cn_handler_struct {
2246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int (*function)(struct drbd_conf *,
2247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			 struct drbd_nl_cfg_req *,
2248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			 struct drbd_nl_cfg_reply *);
2249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int reply_body_size;
2250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner};
2251b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2252b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic struct cn_handler_struct cnd_table[] = {
2253b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_primary ]		= { &drbd_nl_primary,		0 },
2254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_secondary ]		= { &drbd_nl_secondary,		0 },
2255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_disk_conf ]		= { &drbd_nl_disk_conf,		0 },
2256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_detach ]		= { &drbd_nl_detach,		0 },
2257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_net_conf ]		= { &drbd_nl_net_conf,		0 },
2258b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_disconnect ]	= { &drbd_nl_disconnect,	0 },
2259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_resize ]		= { &drbd_nl_resize,		0 },
2260b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_syncer_conf ]	= { &drbd_nl_syncer_conf,	0 },
2261b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_invalidate ]	= { &drbd_nl_invalidate,	0 },
2262b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_invalidate_peer ]	= { &drbd_nl_invalidate_peer,	0 },
2263b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_pause_sync ]	= { &drbd_nl_pause_sync,	0 },
2264b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_resume_sync ]	= { &drbd_nl_resume_sync,	0 },
2265b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_suspend_io ]	= { &drbd_nl_suspend_io,	0 },
2266b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_resume_io ]		= { &drbd_nl_resume_io,		0 },
2267b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_outdate ]		= { &drbd_nl_outdate,		0 },
2268b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_get_config ]	= { &drbd_nl_get_config,
2269b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct syncer_conf_tag_len_struct) +
2270b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct disk_conf_tag_len_struct) +
2271b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct net_conf_tag_len_struct) },
2272b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_get_state ]		= { &drbd_nl_get_state,
2273b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct get_state_tag_len_struct) +
2274b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct sync_progress_tag_len_struct)	},
2275b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_get_uuids ]		= { &drbd_nl_get_uuids,
2276b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct get_uuids_tag_len_struct) },
2277b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_get_timeout_flag ]	= { &drbd_nl_get_timeout_flag,
2278b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				    sizeof(struct get_timeout_flag_tag_len_struct)},
2279b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_start_ov ]		= { &drbd_nl_start_ov,		0 },
2280b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	[ P_new_c_uuid ]	= { &drbd_nl_new_c_uuid,	0 },
2281b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner};
2282b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
22839f5180e5c331d7b3ccc35e1a78072235d38f9f34Philipp Reisnerstatic void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms *nsp)
2284b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2285b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data;
2286b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_handler_struct *cm;
2287b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply;
2288b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply;
2289b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_conf *mdev;
2290b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int retcode, rr;
2291b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int reply_size = sizeof(struct cn_msg)
2292b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		+ sizeof(struct drbd_nl_cfg_reply)
2293b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		+ sizeof(short int);
2294b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2295b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!try_module_get(THIS_MODULE)) {
2296b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		printk(KERN_ERR "drbd: try_module_get() failed!\n");
2297b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
2298b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2299b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
230038bf1953987c1735f3c9140fca762949a8cae507Eric W. Biederman	if (!capable(CAP_SYS_ADMIN)) {
23019f5180e5c331d7b3ccc35e1a78072235d38f9f34Philipp Reisner		retcode = ERR_PERM;
23029f5180e5c331d7b3ccc35e1a78072235d38f9f34Philipp Reisner		goto fail;
23039f5180e5c331d7b3ccc35e1a78072235d38f9f34Philipp Reisner	}
23049f5180e5c331d7b3ccc35e1a78072235d38f9f34Philipp Reisner
2305ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg	mdev = ensure_mdev(nlp->drbd_minor,
2306ef50a3e34f93a067ada541346be3175e924331a2Lars Ellenberg			(nlp->flags & DRBD_NL_CREATE_DEVICE));
2307b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!mdev) {
2308b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_MINOR_INVALID;
2309b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
2310b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2311b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
231242ff269d1022a86be4f526cf674998c47b7ab856Lars Ellenberg	if (nlp->packet_type >= P_nl_after_last_packet ||
231342ff269d1022a86be4f526cf674998c47b7ab856Lars Ellenberg	    nlp->packet_type == P_return_code_only) {
2314b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_PACKET_NR;
2315b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
2316b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2317b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2318b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cm = cnd_table + nlp->packet_type;
2319b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2320b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* This may happen if packet number is 0: */
2321b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (cm->function == NULL) {
2322b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_PACKET_NR;
2323b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
2324b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2325b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2326b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply_size += cm->reply_body_size;
2327b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2328b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* allocation not in the IO path, cqueue thread context */
23293e3a7766c2e6995ac98e7855017abc3544d54e08Lars Ellenberg	cn_reply = kzalloc(reply_size, GFP_KERNEL);
2330b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!cn_reply) {
2331b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		retcode = ERR_NOMEM;
2332b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		goto fail;
2333b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2334b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply = (struct drbd_nl_cfg_reply *) cn_reply->data;
2335b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2336b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->packet_type =
233742ff269d1022a86be4f526cf674998c47b7ab856Lars Ellenberg		cm->reply_body_size ? nlp->packet_type : P_return_code_only;
2338b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = nlp->drbd_minor;
2339b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = NO_ERROR; /* Might by modified by cm->function. */
2340b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* reply->tag_list; might be modified by cm->function. */
2341b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2342b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rr = cm->function(mdev, nlp, reply);
2343b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2344b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id = req->id;
2345b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = req->seq;
2346b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = req->ack  + 1;
2347b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr;
2348b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2349b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2350b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
2351b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (rr && rr != -ESRCH)
2352b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
2353b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2354b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(cn_reply);
2355b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	module_put(THIS_MODULE);
2356b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return;
2357b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner fail:
2358b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_nl_send_reply(req, retcode);
2359b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	module_put(THIS_MODULE);
2360b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2361b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2362b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic atomic_t drbd_nl_seq = ATOMIC_INIT(2); /* two. */
2363b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2364b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *
2365b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner__tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data,
2366b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short len, int nul_terminated)
2367b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2368b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short l = tag_descriptions[tag_number(tag)].max_len;
2369b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	len = (len < l) ? len :  l;
2370b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(tag, tl++);
2371b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(len, tl++);
2372b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	memcpy(tl, data, len);
2373b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = (unsigned short*)((char*)tl + len);
2374b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (nul_terminated)
2375b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		*((char*)tl - 1) = 0;
2376b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return tl;
2377b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2378b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2379b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *
2380b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnertl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, int len)
2381b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2382b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return __tl_add_blob(tl, tag, data, len, 0);
2383b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2384b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2385b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *
2386b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnertl_add_str(unsigned short *tl, enum drbd_tags tag, const char *str)
2387b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2388b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return __tl_add_blob(tl, tag, str, strlen(str)+1, 0);
2389b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2390b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2391b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic unsigned short *
2392b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnertl_add_int(unsigned short *tl, enum drbd_tags tag, const void *val)
2393b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2394b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(tag, tl++);
2395b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	switch(tag_type(tag)) {
2396b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case TT_INTEGER:
2397b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_unaligned(sizeof(int), tl++);
2398b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_unaligned(*(int *)val, (int *)tl);
2399b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = (unsigned short*)((char*)tl+sizeof(int));
2400b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
2401b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	case TT_INT64:
2402b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_unaligned(sizeof(u64), tl++);
2403b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		put_unaligned(*(u64 *)val, (u64 *)tl);
2404b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		tl = (unsigned short*)((char*)tl+sizeof(u64));
2405b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		break;
2406b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	default:
2407b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* someone did something stupid. */
2408b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		;
2409b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2410b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return tl;
2411b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2412b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2413b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_bcast_state(struct drbd_conf *mdev, union drbd_state state)
2414b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2415b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char buffer[sizeof(struct cn_msg)+
2416b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct drbd_nl_cfg_reply)+
2417b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct get_state_tag_len_struct)+
2418b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(short int)];
2419b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
2420b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply =
2421b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(struct drbd_nl_cfg_reply *)cn_reply->data;
2422b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl = reply->tag_list;
2423b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2424b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* dev_warn(DEV, "drbd_bcast_state() got called\n"); */
2425b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2426b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = get_state_to_tags(mdev, (struct get_state *)&state, tl);
2427b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2428b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2429b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2430b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.idx = CN_IDX_DRBD;
2431b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.val = CN_VAL_DRBD;
2432b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2433b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
2434b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = 0; /* not used here. */
2435b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
2436b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(int)((char *)tl - (char *)reply->tag_list);
2437b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2438b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2439b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->packet_type = P_get_state;
2440b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = mdev_to_minor(mdev);
2441b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = NO_ERROR;
2442b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2443b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
2444b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2445b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2446b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name)
2447b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2448b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char buffer[sizeof(struct cn_msg)+
2449b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct drbd_nl_cfg_reply)+
2450b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct call_helper_tag_len_struct)+
2451b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(short int)];
2452b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
2453b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply =
2454b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(struct drbd_nl_cfg_reply *)cn_reply->data;
2455b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl = reply->tag_list;
2456b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2457b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* dev_warn(DEV, "drbd_bcast_state() got called\n"); */
2458b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2459b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_str(tl, T_helper, helper_name);
2460b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2461b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2462b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.idx = CN_IDX_DRBD;
2463b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.val = CN_VAL_DRBD;
2464b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2465b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
2466b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = 0; /* not used here. */
2467b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
2468b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(int)((char *)tl - (char *)reply->tag_list);
2469b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2470b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2471b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->packet_type = P_call_helper;
2472b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = mdev_to_minor(mdev);
2473b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = NO_ERROR;
2474b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2475b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
2476b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2477b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2478b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_bcast_ee(struct drbd_conf *mdev,
2479b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		const char *reason, const int dgs,
2480b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		const char* seen_hash, const char* calc_hash,
2481b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		const struct drbd_epoch_entry* e)
2482b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2483b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply;
2484b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply;
2485b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl;
248645bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg	struct page *page;
248745bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg	unsigned len;
2488b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2489b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!e)
2490b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
2491b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!reason || !reason[0])
2492b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
2493b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2494b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* apparently we have to memcpy twice, first to prepare the data for the
2495b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * struct cn_msg, then within cn_netlink_send from the cn_msg to the
2496b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * netlink skb. */
2497b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* receiver thread context, which is not in the writeout path (of this node),
2498b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * but may be in the writeout path of the _other_ node.
2499b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * GFP_NOIO to avoid potential "distributed deadlock". */
25003e3a7766c2e6995ac98e7855017abc3544d54e08Lars Ellenberg	cn_reply = kzalloc(
2501b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sizeof(struct cn_msg)+
2502b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sizeof(struct drbd_nl_cfg_reply)+
2503b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sizeof(struct dump_ee_tag_len_struct)+
2504b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sizeof(short int),
2505b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		GFP_NOIO);
2506b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2507b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!cn_reply) {
2508b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dev_err(DEV, "could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n",
2509b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				(unsigned long long)e->sector, e->size);
2510b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
2511b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2512b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2513b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply = (struct drbd_nl_cfg_reply*)cn_reply->data;
2514b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = reply->tag_list;
2515b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2516b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_str(tl, T_dump_ee_reason, reason);
2517b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs);
2518b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs);
2519b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_int(tl, T_ee_sector, &e->sector);
2520b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_int(tl, T_ee_block_id, &e->block_id);
2521b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
25223129b1b9aed15bbebde1b2a5719434273feb295dLars Ellenberg	/* dump the first 32k */
25233129b1b9aed15bbebde1b2a5719434273feb295dLars Ellenberg	len = min_t(unsigned, e->size, 32 << 10);
2524b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(T_ee_data, tl++);
25253129b1b9aed15bbebde1b2a5719434273feb295dLars Ellenberg	put_unaligned(len, tl++);
2526b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
252745bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg	page = e->pages;
252845bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg	page_chain_for_each(page) {
2529cfd8005c99c68882e962807d36603791adddfb9fCong Wang		void *d = kmap_atomic(page);
253045bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg		unsigned l = min_t(unsigned, len, PAGE_SIZE);
253145bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg		memcpy(tl, d, l);
2532cfd8005c99c68882e962807d36603791adddfb9fCong Wang		kunmap_atomic(d);
253345bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg		tl = (unsigned short*)((char*)tl + l);
253445bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5Lars Ellenberg		len -= l;
25353129b1b9aed15bbebde1b2a5719434273feb295dLars Ellenberg		if (len == 0)
25363129b1b9aed15bbebde1b2a5719434273feb295dLars Ellenberg			break;
2537b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2538b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2539b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2540b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.idx = CN_IDX_DRBD;
2541b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.val = CN_VAL_DRBD;
2542b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2543b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = atomic_add_return(1,&drbd_nl_seq);
2544b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = 0; // not used here.
2545b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
2546b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(int)((char*)tl - (char*)reply->tag_list);
2547b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2548b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2549b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->packet_type = P_dump_ee;
2550b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = mdev_to_minor(mdev);
2551b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = NO_ERROR;
2552b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2553b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
2554b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	kfree(cn_reply);
2555b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2556b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2557b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_bcast_sync_progress(struct drbd_conf *mdev)
2558b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2559b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char buffer[sizeof(struct cn_msg)+
2560b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct drbd_nl_cfg_reply)+
2561b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(struct sync_progress_tag_len_struct)+
2562b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    sizeof(short int)];
2563b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
2564b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply =
2565b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(struct drbd_nl_cfg_reply *)cn_reply->data;
2566b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned short *tl = reply->tag_list;
2567b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned long rs_left;
2568b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned int res;
2569b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2570b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* no local ref, no bitmap, no syncer progress, no broadcast. */
2571b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!get_ldev(mdev))
2572b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
2573b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_get_syncer_progress(mdev, &rs_left, &res);
2574b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_ldev(mdev);
2575b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2576b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	tl = tl_add_int(tl, T_sync_progress, &res);
2577b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	put_unaligned(TT_END, tl++); /* Close the tag list */
2578b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2579b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.idx = CN_IDX_DRBD;
2580b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id.val = CN_VAL_DRBD;
2581b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2582b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
2583b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = 0; /* not used here. */
2584b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
2585b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(int)((char *)tl - (char *)reply->tag_list);
2586b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2587b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2588b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->packet_type = P_sync_progress;
2589b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = mdev_to_minor(mdev);
2590b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = NO_ERROR;
2591b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2592b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
2593b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2594b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2595b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerint __init drbd_nl_init(void)
2596b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2597b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	static struct cb_id cn_id_drbd;
2598b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int err, try=10;
2599b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2600b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_id_drbd.val = CN_VAL_DRBD;
2601b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	do {
2602b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		cn_id_drbd.idx = cn_idx;
2603b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		err = cn_add_callback(&cn_id_drbd, "cn_drbd", &drbd_connector_callback);
2604b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!err)
2605b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			break;
2606b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		cn_idx = (cn_idx + CN_IDX_STEP);
2607b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	} while (try--);
2608b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2609b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (err) {
2610b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		printk(KERN_ERR "drbd: cn_drbd failed to register\n");
2611b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return err;
2612b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
2613b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2614b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
2615b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2616b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2617b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_nl_cleanup(void)
2618b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2619b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	static struct cb_id cn_id_drbd;
2620b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2621b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_id_drbd.idx = cn_idx;
2622b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_id_drbd.val = CN_VAL_DRBD;
2623b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2624b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_del_callback(&cn_id_drbd);
2625b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2626b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2627b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnervoid drbd_nl_send_reply(struct cn_msg *req, int ret_code)
2628b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
2629b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	char buffer[sizeof(struct cn_msg)+sizeof(struct drbd_nl_cfg_reply)];
2630b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
2631b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_nl_cfg_reply *reply =
2632b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		(struct drbd_nl_cfg_reply *)cn_reply->data;
2633b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int rr;
2634b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
26353e3a7766c2e6995ac98e7855017abc3544d54e08Lars Ellenberg	memset(buffer, 0, sizeof(buffer));
2636b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->id = req->id;
2637b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2638b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->seq = req->seq;
2639b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->ack = req->ack  + 1;
2640b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->len = sizeof(struct drbd_nl_cfg_reply);
2641b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	cn_reply->flags = 0;
2642b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
264342ff269d1022a86be4f526cf674998c47b7ab856Lars Ellenberg	reply->packet_type = P_return_code_only;
2644b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor;
2645b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	reply->ret_code = ret_code;
2646b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2647b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
2648b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (rr && rr != -ESRCH)
2649b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
2650b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
2651b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
2652