blob: f1b870766deb91d9b456f165221938f489c549db [file] [log] [blame]
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001/*
2 * Copyright (C) 2015, SUSE
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 */
10
11
12#include <linux/module.h>
Guoqing Jiang7bcda712016-08-12 13:42:42 +080013#include <linux/kthread.h>
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060014#include <linux/dlm.h>
15#include <linux/sched.h>
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -050016#include <linux/raid/md_p.h>
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060017#include "md.h"
Mike Snitzer935fe092017-10-10 17:02:41 -040018#include "md-bitmap.h"
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -050019#include "md-cluster.h"
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060020
21#define LVB_SIZE 64
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -050022#define NEW_DEV_TIMEOUT 5000
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -060023
24struct dlm_lock_resource {
25 dlm_lockspace_t *ls;
26 struct dlm_lksb lksb;
27 char *name; /* lock name. */
28 uint32_t flags; /* flags to pass to dlm_lock() */
Guoqing Jiangfccb60a2016-08-12 13:42:41 +080029 wait_queue_head_t sync_locking; /* wait queue for synchronized locking */
30 bool sync_locking_done;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -050031 void (*bast)(void *arg, int mode); /* blocking AST function pointer*/
32 struct mddev *mddev; /* pointing back to mddev. */
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -050033 int mode;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -050034};
35
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -050036struct suspend_info {
37 int slot;
38 sector_t lo;
39 sector_t hi;
40 struct list_head list;
41};
42
43struct resync_info {
44 __le64 lo;
45 __le64 hi;
46};
47
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -060048/* md_cluster_info flags */
49#define MD_CLUSTER_WAITING_FOR_NEWDISK 1
Goldwyn Rodrigues90382ed2015-06-24 09:30:32 -050050#define MD_CLUSTER_SUSPEND_READ_BALANCING 2
Guoqing Jiangeece0752015-07-10 17:01:21 +080051#define MD_CLUSTER_BEGIN_JOIN_CLUSTER 3
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -060052
Guoqing Jiang8b9277c2015-12-21 10:51:00 +110053/* Lock the send communication. This is done through
54 * bit manipulation as opposed to a mutex in order to
55 * accomodate lock and hold. See next comment.
56 */
57#define MD_CLUSTER_SEND_LOCK 4
Guoqing Jiange19508f2015-12-21 10:51:01 +110058/* If cluster operations (such as adding a disk) must lock the
59 * communication channel, so as to perform extra operations
60 * (update metadata) and no other operation is allowed on the
61 * MD. Token needs to be locked and held until the operation
62 * completes witha md_update_sb(), which would eventually release
63 * the lock.
Guoqing Jiang8b9277c2015-12-21 10:51:00 +110064 */
65#define MD_CLUSTER_SEND_LOCKED_ALREADY 5
Guoqing Jiang51e453a2016-05-04 02:17:09 -040066/* We should receive message after node joined cluster and
67 * set up all the related infos such as bitmap and personality */
68#define MD_CLUSTER_ALREADY_IN_CLUSTER 6
69#define MD_CLUSTER_PENDING_RECV_EVENT 7
Guoqing Jiang0ba95972017-03-01 17:30:29 +080070#define MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD 8
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -060071
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -050072struct md_cluster_info {
Guoqing Jiang0ba95972017-03-01 17:30:29 +080073 struct mddev *mddev; /* the md device which md_cluster_info belongs to */
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -050074 /* dlm lock space and resources for clustered raid. */
75 dlm_lockspace_t *lockspace;
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -050076 int slot_number;
77 struct completion completion;
Guoqing Jiang8b9277c2015-12-21 10:51:00 +110078 struct mutex recv_mutex;
Goldwyn Rodrigues54519c52014-06-06 12:12:32 -050079 struct dlm_lock_resource *bitmap_lockres;
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +110080 struct dlm_lock_resource **other_bitmap_lockres;
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -050081 struct dlm_lock_resource *resync_lockres;
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -050082 struct list_head suspend_list;
83 spinlock_t suspend_lock;
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -050084 struct md_thread *recovery_thread;
85 unsigned long recovery_map;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -050086 /* communication loc resources */
87 struct dlm_lock_resource *ack_lockres;
88 struct dlm_lock_resource *message_lockres;
89 struct dlm_lock_resource *token_lockres;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -050090 struct dlm_lock_resource *no_new_dev_lockres;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -050091 struct md_thread *recv_thread;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -050092 struct completion newdisk_completion;
Guoqing Jiang8b9277c2015-12-21 10:51:00 +110093 wait_queue_head_t wait;
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -060094 unsigned long state;
Guoqing Jiang18c9ff72016-05-02 11:50:12 -040095 /* record the region in RESYNCING message */
96 sector_t sync_low;
97 sector_t sync_hi;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -050098};
99
100enum msg_type {
101 METADATA_UPDATED = 0,
102 RESYNCING,
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500103 NEWDISK,
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500104 REMOVE,
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500105 RE_ADD,
Guoqing Jiangdc737d72015-07-10 16:54:04 +0800106 BITMAP_NEEDS_SYNC,
Guoqing Jiang7da3d202017-03-01 16:42:38 +0800107 CHANGE_CAPACITY,
Guoqing Jiangafd75622018-10-18 16:37:41 +0800108 BITMAP_RESIZE,
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500109};
110
111struct cluster_msg {
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800112 __le32 type;
113 __le32 slot;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500114 /* TODO: Unionize this for smaller footprint */
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800115 __le64 low;
116 __le64 high;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500117 char uuid[16];
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800118 __le32 raid_slot;
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600119};
120
121static void sync_ast(void *arg)
122{
123 struct dlm_lock_resource *res;
124
NeilBrown2e2a7cd2015-10-19 15:42:18 +1100125 res = arg;
Guoqing Jiangfccb60a2016-08-12 13:42:41 +0800126 res->sync_locking_done = true;
127 wake_up(&res->sync_locking);
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600128}
129
130static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
131{
132 int ret = 0;
133
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600134 ret = dlm_lock(res->ls, mode, &res->lksb,
135 res->flags, res->name, strlen(res->name),
136 0, sync_ast, res, res->bast);
137 if (ret)
138 return ret;
Guoqing Jiangfccb60a2016-08-12 13:42:41 +0800139 wait_event(res->sync_locking, res->sync_locking_done);
140 res->sync_locking_done = false;
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -0500141 if (res->lksb.sb_status == 0)
142 res->mode = mode;
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600143 return res->lksb.sb_status;
144}
145
146static int dlm_unlock_sync(struct dlm_lock_resource *res)
147{
148 return dlm_lock_sync(res, DLM_LOCK_NL);
149}
150
Guoqing Jiang7bcda712016-08-12 13:42:42 +0800151/*
152 * An variation of dlm_lock_sync, which make lock request could
153 * be interrupted
154 */
155static int dlm_lock_sync_interruptible(struct dlm_lock_resource *res, int mode,
156 struct mddev *mddev)
157{
158 int ret = 0;
159
160 ret = dlm_lock(res->ls, mode, &res->lksb,
161 res->flags, res->name, strlen(res->name),
162 0, sync_ast, res, res->bast);
163 if (ret)
164 return ret;
165
166 wait_event(res->sync_locking, res->sync_locking_done
Guoqing Jiangd6385db2016-08-12 13:42:43 +0800167 || kthread_should_stop()
168 || test_bit(MD_CLOSING, &mddev->flags));
Guoqing Jiang7bcda712016-08-12 13:42:42 +0800169 if (!res->sync_locking_done) {
170 /*
171 * the convert queue contains the lock request when request is
172 * interrupted, and sync_ast could still be run, so need to
173 * cancel the request and reset completion
174 */
175 ret = dlm_unlock(res->ls, res->lksb.sb_lkid, DLM_LKF_CANCEL,
176 &res->lksb, res);
177 res->sync_locking_done = false;
178 if (unlikely(ret != 0))
179 pr_info("failed to cancel previous lock request "
180 "%s return %d\n", res->name, ret);
181 return -EPERM;
182 } else
183 res->sync_locking_done = false;
184 if (res->lksb.sb_status == 0)
185 res->mode = mode;
186 return res->lksb.sb_status;
187}
188
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500189static struct dlm_lock_resource *lockres_init(struct mddev *mddev,
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600190 char *name, void (*bastfn)(void *arg, int mode), int with_lvb)
191{
192 struct dlm_lock_resource *res = NULL;
193 int ret, namelen;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500194 struct md_cluster_info *cinfo = mddev->cluster_info;
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600195
196 res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL);
197 if (!res)
198 return NULL;
Guoqing Jiangfccb60a2016-08-12 13:42:41 +0800199 init_waitqueue_head(&res->sync_locking);
200 res->sync_locking_done = false;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500201 res->ls = cinfo->lockspace;
202 res->mddev = mddev;
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -0500203 res->mode = DLM_LOCK_IV;
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600204 namelen = strlen(name);
205 res->name = kzalloc(namelen + 1, GFP_KERNEL);
206 if (!res->name) {
207 pr_err("md-cluster: Unable to allocate resource name for resource %s\n", name);
208 goto out_err;
209 }
210 strlcpy(res->name, name, namelen + 1);
211 if (with_lvb) {
212 res->lksb.sb_lvbptr = kzalloc(LVB_SIZE, GFP_KERNEL);
213 if (!res->lksb.sb_lvbptr) {
214 pr_err("md-cluster: Unable to allocate LVB for resource %s\n", name);
215 goto out_err;
216 }
217 res->flags = DLM_LKF_VALBLK;
218 }
219
220 if (bastfn)
221 res->bast = bastfn;
222
223 res->flags |= DLM_LKF_EXPEDITE;
224
225 ret = dlm_lock_sync(res, DLM_LOCK_NL);
226 if (ret) {
227 pr_err("md-cluster: Unable to lock NL on new lock resource %s\n", name);
228 goto out_err;
229 }
230 res->flags &= ~DLM_LKF_EXPEDITE;
231 res->flags |= DLM_LKF_CONVERT;
232
233 return res;
234out_err:
235 kfree(res->lksb.sb_lvbptr);
236 kfree(res->name);
237 kfree(res);
238 return NULL;
239}
240
241static void lockres_free(struct dlm_lock_resource *res)
242{
Guoqing Jiang400cb452016-08-12 13:42:35 +0800243 int ret = 0;
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800244
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600245 if (!res)
246 return;
247
Guoqing Jiang400cb452016-08-12 13:42:35 +0800248 /*
249 * use FORCEUNLOCK flag, so we can unlock even the lock is on the
250 * waiting or convert queue
251 */
252 ret = dlm_unlock(res->ls, res->lksb.sb_lkid, DLM_LKF_FORCEUNLOCK,
253 &res->lksb, res);
254 if (unlikely(ret != 0))
255 pr_err("failed to unlock %s return %d\n", res->name, ret);
256 else
Guoqing Jiangfccb60a2016-08-12 13:42:41 +0800257 wait_event(res->sync_locking, res->sync_locking_done);
Goldwyn Rodrigues47741b72014-03-07 13:49:26 -0600258
259 kfree(res->name);
260 kfree(res->lksb.sb_lvbptr);
261 kfree(res);
262}
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -0600263
NeilBrown30661b42015-10-19 15:44:00 +1100264static void add_resync_info(struct dlm_lock_resource *lockres,
265 sector_t lo, sector_t hi)
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500266{
267 struct resync_info *ri;
268
269 ri = (struct resync_info *)lockres->lksb.sb_lvbptr;
270 ri->lo = cpu_to_le64(lo);
271 ri->hi = cpu_to_le64(hi);
272}
273
274static struct suspend_info *read_resync_info(struct mddev *mddev, struct dlm_lock_resource *lockres)
275{
276 struct resync_info ri;
277 struct suspend_info *s = NULL;
278 sector_t hi = 0;
279
280 dlm_lock_sync(lockres, DLM_LOCK_CR);
281 memcpy(&ri, lockres->lksb.sb_lvbptr, sizeof(struct resync_info));
282 hi = le64_to_cpu(ri.hi);
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800283 if (hi > 0) {
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500284 s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL);
285 if (!s)
286 goto out;
287 s->hi = hi;
288 s->lo = le64_to_cpu(ri.lo);
289 }
290 dlm_unlock_sync(lockres);
291out:
292 return s;
293}
294
kbuild test robot6dc69c92015-02-28 07:04:37 +0800295static void recover_bitmaps(struct md_thread *thread)
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500296{
297 struct mddev *mddev = thread->mddev;
298 struct md_cluster_info *cinfo = mddev->cluster_info;
299 struct dlm_lock_resource *bm_lockres;
300 char str[64];
301 int slot, ret;
302 struct suspend_info *s, *tmp;
303 sector_t lo, hi;
304
305 while (cinfo->recovery_map) {
306 slot = fls64((u64)cinfo->recovery_map) - 1;
307
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500308 snprintf(str, 64, "bitmap%04d", slot);
309 bm_lockres = lockres_init(mddev, str, NULL, 1);
310 if (!bm_lockres) {
311 pr_err("md-cluster: Cannot initialize bitmaps\n");
312 goto clear_bit;
313 }
314
Guoqing Jiang7bcda712016-08-12 13:42:42 +0800315 ret = dlm_lock_sync_interruptible(bm_lockres, DLM_LOCK_PW, mddev);
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500316 if (ret) {
317 pr_err("md-cluster: Could not DLM lock %s: %d\n",
318 str, ret);
319 goto clear_bit;
320 }
Andy Shevchenkoe64e40182018-08-01 15:20:50 -0700321 ret = md_bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);
Goldwyn Rodrigues4b26a082014-06-07 00:52:29 -0500322 if (ret) {
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500323 pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);
Guoqing Jiange3f924d2016-08-12 13:42:36 +0800324 goto clear_bit;
Goldwyn Rodrigues4b26a082014-06-07 00:52:29 -0500325 }
Guoqing Jiang010228e2018-07-02 16:26:24 +0800326
327 /* Clear suspend_area associated with the bitmap */
328 spin_lock_irq(&cinfo->suspend_lock);
329 list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list)
330 if (slot == s->slot) {
331 list_del(&s->list);
332 kfree(s);
333 }
334 spin_unlock_irq(&cinfo->suspend_lock);
335
Guoqing Jiangcb9ee152018-10-18 16:37:47 +0800336 /* Kick off a reshape if needed */
337 if (test_bit(MD_RESYNCING_REMOTE, &mddev->recovery) &&
338 test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
339 mddev->reshape_position != MaxSector)
340 md_wakeup_thread(mddev->sync_thread);
341
Goldwyn Rodrigues4b26a082014-06-07 00:52:29 -0500342 if (hi > 0) {
Goldwyn Rodrigues4b26a082014-06-07 00:52:29 -0500343 if (lo < mddev->recovery_cp)
344 mddev->recovery_cp = lo;
Guoqing Jiangeb315cd2016-05-02 11:33:10 -0400345 /* wake up thread to continue resync in case resync
346 * is not finished */
347 if (mddev->recovery_cp != MaxSector) {
Guoqing Jiang0357ba22018-07-02 16:26:25 +0800348 /*
349 * clear the REMOTE flag since we will launch
350 * resync thread in current node.
351 */
352 clear_bit(MD_RESYNCING_REMOTE,
353 &mddev->recovery);
354 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
355 md_wakeup_thread(mddev->thread);
Guoqing Jiangeb315cd2016-05-02 11:33:10 -0400356 }
Goldwyn Rodrigues4b26a082014-06-07 00:52:29 -0500357 }
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500358clear_bit:
Shaohua Li4ac7a652016-01-22 15:54:42 -0800359 lockres_free(bm_lockres);
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500360 clear_bit(slot, &cinfo->recovery_map);
361 }
362}
363
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500364static void recover_prep(void *arg)
365{
Goldwyn Rodrigues90382ed2015-06-24 09:30:32 -0500366 struct mddev *mddev = arg;
367 struct md_cluster_info *cinfo = mddev->cluster_info;
368 set_bit(MD_CLUSTER_SUSPEND_READ_BALANCING, &cinfo->state);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500369}
370
Guoqing Jiang05cd0e52015-07-10 16:54:03 +0800371static void __recover_slot(struct mddev *mddev, int slot)
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500372{
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500373 struct md_cluster_info *cinfo = mddev->cluster_info;
374
Guoqing Jiang05cd0e52015-07-10 16:54:03 +0800375 set_bit(slot, &cinfo->recovery_map);
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -0500376 if (!cinfo->recovery_thread) {
377 cinfo->recovery_thread = md_register_thread(recover_bitmaps,
378 mddev, "recover");
379 if (!cinfo->recovery_thread) {
380 pr_warn("md-cluster: Could not create recovery thread\n");
381 return;
382 }
383 }
384 md_wakeup_thread(cinfo->recovery_thread);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500385}
386
Guoqing Jiang05cd0e52015-07-10 16:54:03 +0800387static void recover_slot(void *arg, struct dlm_slot *slot)
388{
389 struct mddev *mddev = arg;
390 struct md_cluster_info *cinfo = mddev->cluster_info;
391
392 pr_info("md-cluster: %s Node %d/%d down. My slot: %d. Initiating recovery.\n",
393 mddev->bitmap_info.cluster_name,
394 slot->nodeid, slot->slot,
395 cinfo->slot_number);
396 /* deduct one since dlm slot starts from one while the num of
397 * cluster-md begins with 0 */
398 __recover_slot(mddev, slot->slot - 1);
399}
400
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500401static void recover_done(void *arg, struct dlm_slot *slots,
402 int num_slots, int our_slot,
403 uint32_t generation)
404{
405 struct mddev *mddev = arg;
406 struct md_cluster_info *cinfo = mddev->cluster_info;
407
408 cinfo->slot_number = our_slot;
Guoqing Jiangeece0752015-07-10 17:01:21 +0800409 /* completion is only need to be complete when node join cluster,
410 * it doesn't need to run during another node's failure */
411 if (test_bit(MD_CLUSTER_BEGIN_JOIN_CLUSTER, &cinfo->state)) {
412 complete(&cinfo->completion);
413 clear_bit(MD_CLUSTER_BEGIN_JOIN_CLUSTER, &cinfo->state);
414 }
Goldwyn Rodrigues90382ed2015-06-24 09:30:32 -0500415 clear_bit(MD_CLUSTER_SUSPEND_READ_BALANCING, &cinfo->state);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500416}
417
Guoqing Jiangeece0752015-07-10 17:01:21 +0800418/* the ops is called when node join the cluster, and do lock recovery
419 * if node failure occurs */
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500420static const struct dlm_lockspace_ops md_ls_ops = {
421 .recover_prep = recover_prep,
422 .recover_slot = recover_slot,
423 .recover_done = recover_done,
424};
425
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500426/*
427 * The BAST function for the ack lock resource
428 * This function wakes up the receive thread in
429 * order to receive and process the message.
430 */
431static void ack_bast(void *arg, int mode)
432{
NeilBrown2e2a7cd2015-10-19 15:42:18 +1100433 struct dlm_lock_resource *res = arg;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500434 struct md_cluster_info *cinfo = res->mddev->cluster_info;
435
Guoqing Jiang51e453a2016-05-04 02:17:09 -0400436 if (mode == DLM_LOCK_EX) {
437 if (test_bit(MD_CLUSTER_ALREADY_IN_CLUSTER, &cinfo->state))
438 md_wakeup_thread(cinfo->recv_thread);
439 else
440 set_bit(MD_CLUSTER_PENDING_RECV_EVENT, &cinfo->state);
441 }
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500442}
443
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500444static void __remove_suspend_info(struct md_cluster_info *cinfo, int slot)
445{
446 struct suspend_info *s, *tmp;
447
448 list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list)
449 if (slot == s->slot) {
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500450 list_del(&s->list);
451 kfree(s);
452 break;
453 }
454}
455
Goldwyn Rodriguesb8ca8462015-10-09 11:27:01 -0500456static void remove_suspend_info(struct mddev *mddev, int slot)
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500457{
Goldwyn Rodriguesb8ca8462015-10-09 11:27:01 -0500458 struct md_cluster_info *cinfo = mddev->cluster_info;
NeilBrownb03e0cc2017-10-19 12:49:15 +1100459 mddev->pers->quiesce(mddev, 1);
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500460 spin_lock_irq(&cinfo->suspend_lock);
461 __remove_suspend_info(cinfo, slot);
462 spin_unlock_irq(&cinfo->suspend_lock);
NeilBrownb03e0cc2017-10-19 12:49:15 +1100463 mddev->pers->quiesce(mddev, 0);
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500464}
465
Goldwyn Rodrigues9ed38ff52015-08-14 12:19:40 -0500466static void process_suspend_info(struct mddev *mddev,
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500467 int slot, sector_t lo, sector_t hi)
468{
Goldwyn Rodrigues9ed38ff52015-08-14 12:19:40 -0500469 struct md_cluster_info *cinfo = mddev->cluster_info;
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500470 struct suspend_info *s;
Guoqing Jiangcbce6862018-10-18 16:37:46 +0800471 struct mdp_superblock_1 *sb = NULL;
472 struct md_rdev *rdev;
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500473
474 if (!hi) {
Guoqing Jiang0357ba22018-07-02 16:26:25 +0800475 /*
476 * clear the REMOTE flag since resync or recovery is finished
477 * in remote node.
478 */
479 clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery);
Goldwyn Rodriguesb8ca8462015-10-09 11:27:01 -0500480 remove_suspend_info(mddev, slot);
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -0500481 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
482 md_wakeup_thread(mddev->thread);
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500483 return;
484 }
Guoqing Jiang18c9ff72016-05-02 11:50:12 -0400485
Guoqing Jiangcbce6862018-10-18 16:37:46 +0800486 rdev_for_each(rdev, mddev)
487 if (rdev->raid_disk > -1 && !test_bit(Faulty, &rdev->flags)) {
488 sb = page_address(rdev->sb_page);
489 break;
490 }
491
Guoqing Jiang18c9ff72016-05-02 11:50:12 -0400492 /*
493 * The bitmaps are not same for different nodes
494 * if RESYNCING is happening in one node, then
495 * the node which received the RESYNCING message
496 * probably will perform resync with the region
497 * [lo, hi] again, so we could reduce resync time
498 * a lot if we can ensure that the bitmaps among
499 * different nodes are match up well.
500 *
501 * sync_low/hi is used to record the region which
502 * arrived in the previous RESYNCING message,
503 *
Guoqing Jiangcbce6862018-10-18 16:37:46 +0800504 * Call md_bitmap_sync_with_cluster to clear NEEDED_MASK
505 * and set RESYNC_MASK since resync thread is running
506 * in another node, so we don't need to do the resync
507 * again with the same section.
508 *
509 * Skip md_bitmap_sync_with_cluster in case reshape
510 * happening, because reshaping region is small and
511 * we don't want to trigger lots of WARN.
512 */
513 if (sb && !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE))
514 md_bitmap_sync_with_cluster(mddev, cinfo->sync_low,
515 cinfo->sync_hi, lo, hi);
Guoqing Jiang18c9ff72016-05-02 11:50:12 -0400516 cinfo->sync_low = lo;
517 cinfo->sync_hi = hi;
518
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500519 s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL);
520 if (!s)
521 return;
522 s->slot = slot;
523 s->lo = lo;
524 s->hi = hi;
Goldwyn Rodrigues9ed38ff52015-08-14 12:19:40 -0500525 mddev->pers->quiesce(mddev, 1);
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500526 spin_lock_irq(&cinfo->suspend_lock);
527 /* Remove existing entry (if exists) before adding */
528 __remove_suspend_info(cinfo, slot);
529 list_add(&s->list, &cinfo->suspend_list);
530 spin_unlock_irq(&cinfo->suspend_lock);
NeilBrownb03e0cc2017-10-19 12:49:15 +1100531 mddev->pers->quiesce(mddev, 0);
Goldwyn Rodriguese59721c2014-06-07 02:30:30 -0500532}
533
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500534static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
535{
536 char disk_uuid[64];
537 struct md_cluster_info *cinfo = mddev->cluster_info;
538 char event_name[] = "EVENT=ADD_DEVICE";
539 char raid_slot[16];
540 char *envp[] = {event_name, disk_uuid, raid_slot, NULL};
541 int len;
542
543 len = snprintf(disk_uuid, 64, "DEVICE_UUID=");
Guoqing Jiangb89f7042015-07-10 16:54:02 +0800544 sprintf(disk_uuid + len, "%pU", cmsg->uuid);
Guoqing Jiangfaeff832015-10-12 17:21:21 +0800545 snprintf(raid_slot, 16, "RAID_DISK=%d", le32_to_cpu(cmsg->raid_slot));
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500546 pr_info("%s:%d Sending kobject change with %s and %s\n", __func__, __LINE__, disk_uuid, raid_slot);
547 init_completion(&cinfo->newdisk_completion);
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -0600548 set_bit(MD_CLUSTER_WAITING_FOR_NEWDISK, &cinfo->state);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500549 kobject_uevent_env(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE, envp);
550 wait_for_completion_timeout(&cinfo->newdisk_completion,
551 NEW_DEV_TIMEOUT);
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -0600552 clear_bit(MD_CLUSTER_WAITING_FOR_NEWDISK, &cinfo->state);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500553}
554
555
556static void process_metadata_update(struct mddev *mddev, struct cluster_msg *msg)
557{
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800558 int got_lock = 0;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500559 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiang15858fa2015-12-21 10:51:00 +1100560 mddev->good_device_nr = le32_to_cpu(msg->raid_slot);
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800561
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500562 dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR);
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800563 wait_event(mddev->thread->wqueue,
564 (got_lock = mddev_trylock(mddev)) ||
565 test_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state));
566 md_reload_sb(mddev, mddev->good_device_nr);
567 if (got_lock)
568 mddev_unlock(mddev);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500569}
570
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500571static void process_remove_disk(struct mddev *mddev, struct cluster_msg *msg)
572{
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800573 struct md_rdev *rdev;
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500574
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800575 rcu_read_lock();
576 rdev = md_find_rdev_nr_rcu(mddev, le32_to_cpu(msg->raid_slot));
Guoqing Jiang659b2542015-12-21 10:50:59 +1100577 if (rdev) {
578 set_bit(ClusterRemove, &rdev->flags);
579 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
580 md_wakeup_thread(mddev->thread);
581 }
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500582 else
Guoqing Jiangfaeff832015-10-12 17:21:21 +0800583 pr_warn("%s: %d Could not find disk(%d) to REMOVE\n",
584 __func__, __LINE__, le32_to_cpu(msg->raid_slot));
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800585 rcu_read_unlock();
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500586}
587
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500588static void process_readd_disk(struct mddev *mddev, struct cluster_msg *msg)
589{
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800590 struct md_rdev *rdev;
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500591
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800592 rcu_read_lock();
593 rdev = md_find_rdev_nr_rcu(mddev, le32_to_cpu(msg->raid_slot));
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500594 if (rdev && test_bit(Faulty, &rdev->flags))
595 clear_bit(Faulty, &rdev->flags);
596 else
Guoqing Jiangfaeff832015-10-12 17:21:21 +0800597 pr_warn("%s: %d Could not find disk(%d) which is faulty",
598 __func__, __LINE__, le32_to_cpu(msg->raid_slot));
Guoqing Jiang5f0aa212016-08-12 13:42:39 +0800599 rcu_read_unlock();
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500600}
601
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400602static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500603{
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400604 int ret = 0;
605
Guoqing Jiang256f5b22015-10-12 17:21:23 +0800606 if (WARN(mddev->cluster_info->slot_number - 1 == le32_to_cpu(msg->slot),
607 "node %d received it's own msg\n", le32_to_cpu(msg->slot)))
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400608 return -1;
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800609 switch (le32_to_cpu(msg->type)) {
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500610 case METADATA_UPDATED:
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500611 process_metadata_update(mddev, msg);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500612 break;
Guoqing Jiang7da3d202017-03-01 16:42:38 +0800613 case CHANGE_CAPACITY:
614 set_capacity(mddev->gendisk, mddev->array_sectors);
615 revalidate_disk(mddev->gendisk);
616 break;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500617 case RESYNCING:
Guoqing Jiang0357ba22018-07-02 16:26:25 +0800618 set_bit(MD_RESYNCING_REMOTE, &mddev->recovery);
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800619 process_suspend_info(mddev, le32_to_cpu(msg->slot),
620 le64_to_cpu(msg->low),
621 le64_to_cpu(msg->high));
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500622 break;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500623 case NEWDISK:
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500624 process_add_new_disk(mddev, msg);
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500625 break;
626 case REMOVE:
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500627 process_remove_disk(mddev, msg);
628 break;
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500629 case RE_ADD:
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -0500630 process_readd_disk(mddev, msg);
631 break;
Guoqing Jiangdc737d72015-07-10 16:54:04 +0800632 case BITMAP_NEEDS_SYNC:
Guoqing Jiangcf97a342015-10-16 15:40:22 +0800633 __recover_slot(mddev, le32_to_cpu(msg->slot));
Guoqing Jiangdc737d72015-07-10 16:54:04 +0800634 break;
Guoqing Jiangafd75622018-10-18 16:37:41 +0800635 case BITMAP_RESIZE:
636 if (le64_to_cpu(msg->high) != mddev->pers->size(mddev, 0, 0))
637 ret = md_bitmap_resize(mddev->bitmap,
638 le64_to_cpu(msg->high), 0, 0);
639 break;
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500640 default:
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400641 ret = -1;
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -0500642 pr_warn("%s:%d Received unknown message from %d\n",
643 __func__, __LINE__, msg->slot);
kbuild test robot09dd1af2015-02-28 09:16:08 +0800644 }
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400645 return ret;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500646}
647
648/*
649 * thread for receiving message
650 */
651static void recv_daemon(struct md_thread *thread)
652{
653 struct md_cluster_info *cinfo = thread->mddev->cluster_info;
654 struct dlm_lock_resource *ack_lockres = cinfo->ack_lockres;
655 struct dlm_lock_resource *message_lockres = cinfo->message_lockres;
656 struct cluster_msg msg;
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800657 int ret;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500658
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100659 mutex_lock(&cinfo->recv_mutex);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500660 /*get CR on Message*/
661 if (dlm_lock_sync(message_lockres, DLM_LOCK_CR)) {
662 pr_err("md/raid1:failed to get CR on MESSAGE\n");
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100663 mutex_unlock(&cinfo->recv_mutex);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500664 return;
665 }
666
667 /* read lvb and wake up thread to process this message_lockres */
668 memcpy(&msg, message_lockres->lksb.sb_lvbptr, sizeof(struct cluster_msg));
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400669 ret = process_recvd_msg(thread->mddev, &msg);
670 if (ret)
671 goto out;
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500672
673 /*release CR on ack_lockres*/
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800674 ret = dlm_unlock_sync(ack_lockres);
675 if (unlikely(ret != 0))
676 pr_info("unlock ack failed return %d\n", ret);
Guoqing Jiang66099bb2015-07-10 17:01:15 +0800677 /*up-convert to PR on message_lockres*/
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800678 ret = dlm_lock_sync(message_lockres, DLM_LOCK_PR);
679 if (unlikely(ret != 0))
680 pr_info("lock PR on msg failed return %d\n", ret);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500681 /*get CR on ack_lockres again*/
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800682 ret = dlm_lock_sync(ack_lockres, DLM_LOCK_CR);
683 if (unlikely(ret != 0))
684 pr_info("lock CR on ack failed return %d\n", ret);
Guoqing Jiang1fa9a1a2016-05-03 22:22:15 -0400685out:
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500686 /*release CR on message_lockres*/
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800687 ret = dlm_unlock_sync(message_lockres);
688 if (unlikely(ret != 0))
689 pr_info("unlock msg failed return %d\n", ret);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100690 mutex_unlock(&cinfo->recv_mutex);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500691}
692
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100693/* lock_token()
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500694 * Takes the lock on the TOKEN lock resource so no other
695 * node can communicate while the operation is underway.
696 */
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800697static int lock_token(struct md_cluster_info *cinfo, bool mddev_locked)
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500698{
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800699 int error, set_bit = 0;
700 struct mddev *mddev = cinfo->mddev;
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500701
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800702 /*
703 * If resync thread run after raid1d thread, then process_metadata_update
704 * could not continue if raid1d held reconfig_mutex (and raid1d is blocked
705 * since another node already got EX on Token and waitting the EX of Ack),
706 * so let resync wake up thread in case flag is set.
707 */
708 if (mddev_locked && !test_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
709 &cinfo->state)) {
710 error = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
711 &cinfo->state);
712 WARN_ON_ONCE(error);
713 md_wakeup_thread(mddev->thread);
714 set_bit = 1;
715 }
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500716 error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX);
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800717 if (set_bit)
718 clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
719
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500720 if (error)
721 pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n",
722 __func__, __LINE__, error);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100723
724 /* Lock the receive sequence */
725 mutex_lock(&cinfo->recv_mutex);
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500726 return error;
727}
728
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100729/* lock_comm()
730 * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel.
731 */
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800732static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked)
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100733{
734 wait_event(cinfo->wait,
735 !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state));
736
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800737 return lock_token(cinfo, mddev_locked);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100738}
739
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500740static void unlock_comm(struct md_cluster_info *cinfo)
741{
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -0500742 WARN_ON(cinfo->token_lockres->mode != DLM_LOCK_EX);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100743 mutex_unlock(&cinfo->recv_mutex);
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500744 dlm_unlock_sync(cinfo->token_lockres);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100745 clear_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state);
746 wake_up(&cinfo->wait);
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500747}
748
749/* __sendmsg()
750 * This function performs the actual sending of the message. This function is
751 * usually called after performing the encompassing operation
752 * The function:
753 * 1. Grabs the message lockresource in EX mode
754 * 2. Copies the message to the message LVB
Guoqing Jiang66099bb2015-07-10 17:01:15 +0800755 * 3. Downconverts message lockresource to CW
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500756 * 4. Upconverts ack lock resource from CR to EX. This forces the BAST on other nodes
757 * and the other nodes read the message. The thread will wait here until all other
758 * nodes have released ack lock resource.
759 * 5. Downconvert ack lockresource to CR
760 */
761static int __sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg)
762{
763 int error;
764 int slot = cinfo->slot_number - 1;
765
766 cmsg->slot = cpu_to_le32(slot);
767 /*get EX on Message*/
768 error = dlm_lock_sync(cinfo->message_lockres, DLM_LOCK_EX);
769 if (error) {
770 pr_err("md-cluster: failed to get EX on MESSAGE (%d)\n", error);
771 goto failed_message;
772 }
773
774 memcpy(cinfo->message_lockres->lksb.sb_lvbptr, (void *)cmsg,
775 sizeof(struct cluster_msg));
Guoqing Jiang66099bb2015-07-10 17:01:15 +0800776 /*down-convert EX to CW on Message*/
777 error = dlm_lock_sync(cinfo->message_lockres, DLM_LOCK_CW);
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500778 if (error) {
Guoqing Jiang66099bb2015-07-10 17:01:15 +0800779 pr_err("md-cluster: failed to convert EX to CW on MESSAGE(%d)\n",
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500780 error);
Guoqing Jiang66099bb2015-07-10 17:01:15 +0800781 goto failed_ack;
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500782 }
783
784 /*up-convert CR to EX on Ack*/
785 error = dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_EX);
786 if (error) {
787 pr_err("md-cluster: failed to convert CR to EX on ACK(%d)\n",
788 error);
789 goto failed_ack;
790 }
791
792 /*down-convert EX to CR on Ack*/
793 error = dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR);
794 if (error) {
795 pr_err("md-cluster: failed to convert EX to CR on ACK(%d)\n",
796 error);
797 goto failed_ack;
798 }
799
800failed_ack:
Guoqing Jiangb5ef5672015-07-10 17:01:17 +0800801 error = dlm_unlock_sync(cinfo->message_lockres);
802 if (unlikely(error != 0)) {
803 pr_err("md-cluster: failed convert to NL on MESSAGE(%d)\n",
804 error);
805 /* in case the message can't be released due to some reason */
806 goto failed_ack;
807 }
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500808failed_message:
809 return error;
810}
811
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800812static int sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg,
813 bool mddev_locked)
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500814{
815 int ret;
816
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800817 lock_comm(cinfo, mddev_locked);
Goldwyn Rodrigues601b5152014-06-07 01:28:53 -0500818 ret = __sendmsg(cinfo, cmsg);
819 unlock_comm(cinfo);
820 return ret;
821}
822
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500823static int gather_all_resync_info(struct mddev *mddev, int total_slots)
824{
825 struct md_cluster_info *cinfo = mddev->cluster_info;
826 int i, ret = 0;
827 struct dlm_lock_resource *bm_lockres;
828 struct suspend_info *s;
829 char str[64];
Guoqing Jiangabb9b222015-07-10 17:01:22 +0800830 sector_t lo, hi;
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500831
832
833 for (i = 0; i < total_slots; i++) {
834 memset(str, '\0', 64);
835 snprintf(str, 64, "bitmap%04d", i);
836 bm_lockres = lockres_init(mddev, str, NULL, 1);
837 if (!bm_lockres)
838 return -ENOMEM;
Shaohua Li4ac7a652016-01-22 15:54:42 -0800839 if (i == (cinfo->slot_number - 1)) {
840 lockres_free(bm_lockres);
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500841 continue;
Shaohua Li4ac7a652016-01-22 15:54:42 -0800842 }
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500843
844 bm_lockres->flags |= DLM_LKF_NOQUEUE;
845 ret = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);
846 if (ret == -EAGAIN) {
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500847 s = read_resync_info(mddev, bm_lockres);
848 if (s) {
849 pr_info("%s:%d Resync[%llu..%llu] in progress on %d\n",
850 __func__, __LINE__,
851 (unsigned long long) s->lo,
852 (unsigned long long) s->hi, i);
853 spin_lock_irq(&cinfo->suspend_lock);
854 s->slot = i;
855 list_add(&s->list, &cinfo->suspend_list);
856 spin_unlock_irq(&cinfo->suspend_lock);
857 }
858 ret = 0;
859 lockres_free(bm_lockres);
860 continue;
861 }
Guoqing Jiang6e6d9f22015-07-10 17:01:20 +0800862 if (ret) {
863 lockres_free(bm_lockres);
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500864 goto out;
Guoqing Jiang6e6d9f22015-07-10 17:01:20 +0800865 }
Guoqing Jiangabb9b222015-07-10 17:01:22 +0800866
867 /* Read the disk bitmap sb and check if it needs recovery */
Andy Shevchenkoe64e40182018-08-01 15:20:50 -0700868 ret = md_bitmap_copy_from_slot(mddev, i, &lo, &hi, false);
Guoqing Jiangabb9b222015-07-10 17:01:22 +0800869 if (ret) {
870 pr_warn("md-cluster: Could not gather bitmaps from slot %d", i);
871 lockres_free(bm_lockres);
872 continue;
873 }
874 if ((hi > 0) && (lo < mddev->recovery_cp)) {
875 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
876 mddev->recovery_cp = lo;
877 md_check_recovery(mddev);
878 }
879
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500880 lockres_free(bm_lockres);
881 }
882out:
883 return ret;
884}
885
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500886static int join(struct mddev *mddev, int nodes)
887{
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500888 struct md_cluster_info *cinfo;
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500889 int ret, ops_rv;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500890 char str[64];
891
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500892 cinfo = kzalloc(sizeof(struct md_cluster_info), GFP_KERNEL);
893 if (!cinfo)
894 return -ENOMEM;
895
Guoqing Jiang9e3072e2015-07-10 17:01:18 +0800896 INIT_LIST_HEAD(&cinfo->suspend_list);
897 spin_lock_init(&cinfo->suspend_lock);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500898 init_completion(&cinfo->completion);
Guoqing Jiangeece0752015-07-10 17:01:21 +0800899 set_bit(MD_CLUSTER_BEGIN_JOIN_CLUSTER, &cinfo->state);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +1100900 init_waitqueue_head(&cinfo->wait);
901 mutex_init(&cinfo->recv_mutex);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500902
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500903 mddev->cluster_info = cinfo;
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800904 cinfo->mddev = mddev;
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500905
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500906 memset(str, 0, 64);
Guoqing Jiangb89f7042015-07-10 16:54:02 +0800907 sprintf(str, "%pU", mddev->uuid);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500908 ret = dlm_new_lockspace(str, mddev->bitmap_info.cluster_name,
909 DLM_LSFL_FS, LVB_SIZE,
910 &md_ls_ops, mddev, &ops_rv, &cinfo->lockspace);
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500911 if (ret)
912 goto err;
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500913 wait_for_completion(&cinfo->completion);
Guoqing Jiang8c58f022015-04-21 11:25:52 -0500914 if (nodes < cinfo->slot_number) {
915 pr_err("md-cluster: Slot allotted(%d) is greater than available slots(%d).",
916 cinfo->slot_number, nodes);
Goldwyn Rodriguesb97e92572014-06-06 11:50:56 -0500917 ret = -ERANGE;
918 goto err;
919 }
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500920 /* Initiate the communication resources */
921 ret = -ENOMEM;
922 cinfo->recv_thread = md_register_thread(recv_daemon, mddev, "cluster_recv");
923 if (!cinfo->recv_thread) {
924 pr_err("md-cluster: cannot allocate memory for recv_thread!\n");
925 goto err;
926 }
927 cinfo->message_lockres = lockres_init(mddev, "message", NULL, 1);
928 if (!cinfo->message_lockres)
929 goto err;
930 cinfo->token_lockres = lockres_init(mddev, "token", NULL, 0);
931 if (!cinfo->token_lockres)
932 goto err;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500933 cinfo->no_new_dev_lockres = lockres_init(mddev, "no-new-dev", NULL, 0);
934 if (!cinfo->no_new_dev_lockres)
935 goto err;
936
Guoqing Jiang15352122016-05-02 11:33:12 -0400937 ret = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX);
938 if (ret) {
939 ret = -EAGAIN;
940 pr_err("md-cluster: can't join cluster to avoid lock issue\n");
941 goto err;
942 }
943 cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0);
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000944 if (!cinfo->ack_lockres) {
945 ret = -ENOMEM;
Guoqing Jiang15352122016-05-02 11:33:12 -0400946 goto err;
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000947 }
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500948 /* get sync CR lock on ACK. */
949 if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR))
950 pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n",
951 ret);
Guoqing Jiang15352122016-05-02 11:33:12 -0400952 dlm_unlock_sync(cinfo->token_lockres);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500953 /* get sync CR lock on no-new-dev. */
954 if (dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR))
955 pr_err("md-cluster: failed to get a sync CR lock on no-new-dev!(%d)\n", ret);
956
Goldwyn Rodrigues54519c52014-06-06 12:12:32 -0500957
958 pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number);
959 snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1);
960 cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1);
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000961 if (!cinfo->bitmap_lockres) {
962 ret = -ENOMEM;
Goldwyn Rodrigues54519c52014-06-06 12:12:32 -0500963 goto err;
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000964 }
Goldwyn Rodrigues54519c52014-06-06 12:12:32 -0500965 if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) {
966 pr_err("Failed to get bitmap lock\n");
967 ret = -EINVAL;
968 goto err;
969 }
970
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -0500971 cinfo->resync_lockres = lockres_init(mddev, "resync", NULL, 0);
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000972 if (!cinfo->resync_lockres) {
973 ret = -ENOMEM;
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -0500974 goto err;
Wei Yongjun0f6187d2016-08-21 14:42:25 +0000975 }
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -0500976
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500977 return 0;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500978err:
Guoqing Jiang0ba95972017-03-01 17:30:29 +0800979 set_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
Guoqing Jiang5b0fb332016-05-02 11:33:11 -0400980 md_unregister_thread(&cinfo->recovery_thread);
981 md_unregister_thread(&cinfo->recv_thread);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -0500982 lockres_free(cinfo->message_lockres);
983 lockres_free(cinfo->token_lockres);
984 lockres_free(cinfo->ack_lockres);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -0500985 lockres_free(cinfo->no_new_dev_lockres);
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -0500986 lockres_free(cinfo->resync_lockres);
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -0500987 lockres_free(cinfo->bitmap_lockres);
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500988 if (cinfo->lockspace)
989 dlm_release_lockspace(cinfo->lockspace, 2);
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -0500990 mddev->cluster_info = NULL;
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500991 kfree(cinfo);
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -0500992 return ret;
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -0500993}
994
Guoqing Jiang51e453a2016-05-04 02:17:09 -0400995static void load_bitmaps(struct mddev *mddev, int total_slots)
996{
997 struct md_cluster_info *cinfo = mddev->cluster_info;
998
999 /* load all the node's bitmap info for resync */
1000 if (gather_all_resync_info(mddev, total_slots))
1001 pr_err("md-cluster: failed to gather all resyn infos\n");
1002 set_bit(MD_CLUSTER_ALREADY_IN_CLUSTER, &cinfo->state);
1003 /* wake up recv thread in case something need to be handled */
1004 if (test_and_clear_bit(MD_CLUSTER_PENDING_RECV_EVENT, &cinfo->state))
1005 md_wakeup_thread(cinfo->recv_thread);
1006}
1007
Guoqing Jiang09995412015-10-01 00:09:18 +08001008static void resync_bitmap(struct mddev *mddev)
1009{
1010 struct md_cluster_info *cinfo = mddev->cluster_info;
1011 struct cluster_msg cmsg = {0};
1012 int err;
1013
1014 cmsg.type = cpu_to_le32(BITMAP_NEEDS_SYNC);
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001015 err = sendmsg(cinfo, &cmsg, 1);
Guoqing Jiang09995412015-10-01 00:09:18 +08001016 if (err)
1017 pr_err("%s:%d: failed to send BITMAP_NEEDS_SYNC message (%d)\n",
1018 __func__, __LINE__, err);
1019}
1020
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001021static void unlock_all_bitmaps(struct mddev *mddev);
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001022static int leave(struct mddev *mddev)
1023{
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -05001024 struct md_cluster_info *cinfo = mddev->cluster_info;
1025
1026 if (!cinfo)
1027 return 0;
Guoqing Jiang09995412015-10-01 00:09:18 +08001028
Guoqing Jiangcb9ee152018-10-18 16:37:47 +08001029 /*
1030 * BITMAP_NEEDS_SYNC message should be sent when node
Guoqing Jiang09995412015-10-01 00:09:18 +08001031 * is leaving the cluster with dirty bitmap, also we
Guoqing Jiangcb9ee152018-10-18 16:37:47 +08001032 * can only deliver it when dlm connection is available.
1033 *
1034 * Also, we should send BITMAP_NEEDS_SYNC message in
1035 * case reshaping is interrupted.
1036 */
1037 if ((cinfo->slot_number > 0 && mddev->recovery_cp != MaxSector) ||
1038 (mddev->reshape_position != MaxSector &&
1039 test_bit(MD_CLOSING, &mddev->flags)))
Guoqing Jiang09995412015-10-01 00:09:18 +08001040 resync_bitmap(mddev);
1041
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001042 set_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
Goldwyn Rodriguese94987d2014-06-07 00:45:22 -05001043 md_unregister_thread(&cinfo->recovery_thread);
Goldwyn Rodrigues46646802014-06-07 01:08:29 -05001044 md_unregister_thread(&cinfo->recv_thread);
1045 lockres_free(cinfo->message_lockres);
1046 lockres_free(cinfo->token_lockres);
1047 lockres_free(cinfo->ack_lockres);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001048 lockres_free(cinfo->no_new_dev_lockres);
Shaohua Li4ac7a652016-01-22 15:54:42 -08001049 lockres_free(cinfo->resync_lockres);
Goldwyn Rodrigues54519c52014-06-06 12:12:32 -05001050 lockres_free(cinfo->bitmap_lockres);
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001051 unlock_all_bitmaps(mddev);
Goldwyn Rodriguesc4ce8672014-03-29 10:20:02 -05001052 dlm_release_lockspace(cinfo->lockspace, 2);
Guoqing Jiang9c8043f2017-02-24 11:15:12 +08001053 kfree(cinfo);
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001054 return 0;
1055}
1056
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -05001057/* slot_number(): Returns the MD slot number to use
1058 * DLM starts the slot numbers from 1, wheras cluster-md
1059 * wants the number to be from zero, so we deduct one
1060 */
1061static int slot_number(struct mddev *mddev)
1062{
1063 struct md_cluster_info *cinfo = mddev->cluster_info;
1064
1065 return cinfo->slot_number - 1;
1066}
1067
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001068/*
1069 * Check if the communication is already locked, else lock the communication
1070 * channel.
1071 * If it is already locked, token is in EX mode, and hence lock_token()
1072 * should not be called.
1073 */
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001074static int metadata_update_start(struct mddev *mddev)
1075{
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001076 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001077 int ret;
1078
1079 /*
1080 * metadata_update_start is always called with the protection of
1081 * reconfig_mutex, so set WAITING_FOR_TOKEN here.
1082 */
1083 ret = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD,
1084 &cinfo->state);
1085 WARN_ON_ONCE(ret);
1086 md_wakeup_thread(mddev->thread);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001087
1088 wait_event(cinfo->wait,
1089 !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state) ||
1090 test_and_clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state));
1091
1092 /* If token is already locked, return 0 */
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001093 if (cinfo->token_lockres->mode == DLM_LOCK_EX) {
1094 clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001095 return 0;
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001096 }
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001097
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001098 ret = lock_token(cinfo, 1);
1099 clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
1100 return ret;
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001101}
1102
1103static int metadata_update_finish(struct mddev *mddev)
1104{
1105 struct md_cluster_info *cinfo = mddev->cluster_info;
1106 struct cluster_msg cmsg;
Goldwyn Rodrigues70bcecd2015-08-21 10:33:39 -05001107 struct md_rdev *rdev;
1108 int ret = 0;
NeilBrownba2746b2015-10-16 13:48:35 +11001109 int raid_slot = -1;
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001110
1111 memset(&cmsg, 0, sizeof(cmsg));
1112 cmsg.type = cpu_to_le32(METADATA_UPDATED);
Goldwyn Rodrigues70bcecd2015-08-21 10:33:39 -05001113 /* Pick up a good active device number to send.
1114 */
1115 rdev_for_each(rdev, mddev)
1116 if (rdev->raid_disk > -1 && !test_bit(Faulty, &rdev->flags)) {
NeilBrownba2746b2015-10-16 13:48:35 +11001117 raid_slot = rdev->desc_nr;
Goldwyn Rodrigues70bcecd2015-08-21 10:33:39 -05001118 break;
1119 }
NeilBrownba2746b2015-10-16 13:48:35 +11001120 if (raid_slot >= 0) {
1121 cmsg.raid_slot = cpu_to_le32(raid_slot);
Goldwyn Rodrigues70bcecd2015-08-21 10:33:39 -05001122 ret = __sendmsg(cinfo, &cmsg);
NeilBrownba2746b2015-10-16 13:48:35 +11001123 } else
Goldwyn Rodrigues70bcecd2015-08-21 10:33:39 -05001124 pr_warn("md-cluster: No good device id found to send\n");
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001125 clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state);
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001126 unlock_comm(cinfo);
1127 return ret;
1128}
1129
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001130static void metadata_update_cancel(struct mddev *mddev)
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001131{
1132 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001133 clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state);
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001134 unlock_comm(cinfo);
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001135}
1136
Guoqing Jiangafd75622018-10-18 16:37:41 +08001137static int update_bitmap_size(struct mddev *mddev, sector_t size)
1138{
1139 struct md_cluster_info *cinfo = mddev->cluster_info;
1140 struct cluster_msg cmsg = {0};
1141 int ret;
1142
1143 cmsg.type = cpu_to_le32(BITMAP_RESIZE);
1144 cmsg.high = cpu_to_le64(size);
1145 ret = sendmsg(cinfo, &cmsg, 0);
1146 if (ret)
1147 pr_err("%s:%d: failed to send BITMAP_RESIZE message (%d)\n",
1148 __func__, __LINE__, ret);
1149 return ret;
1150}
1151
1152static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsize)
1153{
1154 struct bitmap_counts *counts;
1155 char str[64];
1156 struct dlm_lock_resource *bm_lockres;
1157 struct bitmap *bitmap = mddev->bitmap;
1158 unsigned long my_pages = bitmap->counts.pages;
1159 int i, rv;
1160
1161 /*
1162 * We need to ensure all the nodes can grow to a larger
1163 * bitmap size before make the reshaping.
1164 */
1165 rv = update_bitmap_size(mddev, newsize);
1166 if (rv)
1167 return rv;
1168
1169 for (i = 0; i < mddev->bitmap_info.nodes; i++) {
1170 if (i == md_cluster_ops->slot_number(mddev))
1171 continue;
1172
1173 bitmap = get_bitmap_from_slot(mddev, i);
1174 if (IS_ERR(bitmap)) {
1175 pr_err("can't get bitmap from slot %d\n", i);
1176 goto out;
1177 }
1178 counts = &bitmap->counts;
1179
1180 /*
1181 * If we can hold the bitmap lock of one node then
1182 * the slot is not occupied, update the pages.
1183 */
1184 snprintf(str, 64, "bitmap%04d", i);
1185 bm_lockres = lockres_init(mddev, str, NULL, 1);
1186 if (!bm_lockres) {
1187 pr_err("Cannot initialize %s lock\n", str);
1188 goto out;
1189 }
1190 bm_lockres->flags |= DLM_LKF_NOQUEUE;
1191 rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);
1192 if (!rv)
1193 counts->pages = my_pages;
1194 lockres_free(bm_lockres);
1195
1196 if (my_pages != counts->pages)
1197 /*
1198 * Let's revert the bitmap size if one node
1199 * can't resize bitmap
1200 */
1201 goto out;
1202 }
1203
1204 return 0;
1205out:
1206 md_bitmap_free(bitmap);
1207 update_bitmap_size(mddev, oldsize);
1208 return -1;
1209}
1210
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001211/*
1212 * return 0 if all the bitmaps have the same sync_size
1213 */
Colin Ian King7a571572017-10-03 10:51:17 +01001214static int cluster_check_sync_size(struct mddev *mddev)
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001215{
1216 int i, rv;
1217 bitmap_super_t *sb;
1218 unsigned long my_sync_size, sync_size = 0;
1219 int node_num = mddev->bitmap_info.nodes;
1220 int current_slot = md_cluster_ops->slot_number(mddev);
1221 struct bitmap *bitmap = mddev->bitmap;
1222 char str[64];
1223 struct dlm_lock_resource *bm_lockres;
1224
1225 sb = kmap_atomic(bitmap->storage.sb_page);
1226 my_sync_size = sb->sync_size;
1227 kunmap_atomic(sb);
1228
1229 for (i = 0; i < node_num; i++) {
1230 if (i == current_slot)
1231 continue;
1232
1233 bitmap = get_bitmap_from_slot(mddev, i);
1234 if (IS_ERR(bitmap)) {
1235 pr_err("can't get bitmap from slot %d\n", i);
1236 return -1;
1237 }
1238
1239 /*
1240 * If we can hold the bitmap lock of one node then
1241 * the slot is not occupied, update the sb.
1242 */
1243 snprintf(str, 64, "bitmap%04d", i);
1244 bm_lockres = lockres_init(mddev, str, NULL, 1);
1245 if (!bm_lockres) {
1246 pr_err("md-cluster: Cannot initialize %s\n", str);
Andy Shevchenkoe64e40182018-08-01 15:20:50 -07001247 md_bitmap_free(bitmap);
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001248 return -1;
1249 }
1250 bm_lockres->flags |= DLM_LKF_NOQUEUE;
1251 rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);
1252 if (!rv)
Andy Shevchenkoe64e40182018-08-01 15:20:50 -07001253 md_bitmap_update_sb(bitmap);
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001254 lockres_free(bm_lockres);
1255
1256 sb = kmap_atomic(bitmap->storage.sb_page);
1257 if (sync_size == 0)
1258 sync_size = sb->sync_size;
1259 else if (sync_size != sb->sync_size) {
1260 kunmap_atomic(sb);
Andy Shevchenkoe64e40182018-08-01 15:20:50 -07001261 md_bitmap_free(bitmap);
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001262 return -1;
1263 }
1264 kunmap_atomic(sb);
Andy Shevchenkoe64e40182018-08-01 15:20:50 -07001265 md_bitmap_free(bitmap);
Guoqing Jiangb98938d2017-03-01 16:42:39 +08001266 }
1267
1268 return (my_sync_size == sync_size) ? 0 : -1;
1269}
1270
Guoqing Jiang818da592017-03-01 16:42:40 +08001271/*
1272 * Update the size for cluster raid is a little more complex, we perform it
1273 * by the steps:
1274 * 1. hold token lock and update superblock in initiator node.
1275 * 2. send METADATA_UPDATED msg to other nodes.
1276 * 3. The initiator node continues to check each bitmap's sync_size, if all
1277 * bitmaps have the same value of sync_size, then we can set capacity and
1278 * let other nodes to perform it. If one node can't update sync_size
1279 * accordingly, we need to revert to previous value.
1280 */
1281static void update_size(struct mddev *mddev, sector_t old_dev_sectors)
1282{
1283 struct md_cluster_info *cinfo = mddev->cluster_info;
1284 struct cluster_msg cmsg;
1285 struct md_rdev *rdev;
1286 int ret = 0;
1287 int raid_slot = -1;
1288
1289 md_update_sb(mddev, 1);
1290 lock_comm(cinfo, 1);
1291
1292 memset(&cmsg, 0, sizeof(cmsg));
1293 cmsg.type = cpu_to_le32(METADATA_UPDATED);
1294 rdev_for_each(rdev, mddev)
1295 if (rdev->raid_disk >= 0 && !test_bit(Faulty, &rdev->flags)) {
1296 raid_slot = rdev->desc_nr;
1297 break;
1298 }
1299 if (raid_slot >= 0) {
1300 cmsg.raid_slot = cpu_to_le32(raid_slot);
1301 /*
1302 * We can only change capiticy after all the nodes can do it,
1303 * so need to wait after other nodes already received the msg
1304 * and handled the change
1305 */
1306 ret = __sendmsg(cinfo, &cmsg);
1307 if (ret) {
1308 pr_err("%s:%d: failed to send METADATA_UPDATED msg\n",
1309 __func__, __LINE__);
1310 unlock_comm(cinfo);
1311 return;
1312 }
1313 } else {
1314 pr_err("md-cluster: No good device id found to send\n");
1315 unlock_comm(cinfo);
1316 return;
1317 }
1318
1319 /*
1320 * check the sync_size from other node's bitmap, if sync_size
1321 * have already updated in other nodes as expected, send an
1322 * empty metadata msg to permit the change of capacity
1323 */
1324 if (cluster_check_sync_size(mddev) == 0) {
1325 memset(&cmsg, 0, sizeof(cmsg));
1326 cmsg.type = cpu_to_le32(CHANGE_CAPACITY);
1327 ret = __sendmsg(cinfo, &cmsg);
1328 if (ret)
1329 pr_err("%s:%d: failed to send CHANGE_CAPACITY msg\n",
1330 __func__, __LINE__);
1331 set_capacity(mddev->gendisk, mddev->array_sectors);
1332 revalidate_disk(mddev->gendisk);
1333 } else {
1334 /* revert to previous sectors */
1335 ret = mddev->pers->resize(mddev, old_dev_sectors);
1336 if (!ret)
1337 revalidate_disk(mddev->gendisk);
1338 ret = __sendmsg(cinfo, &cmsg);
1339 if (ret)
1340 pr_err("%s:%d: failed to send METADATA_UPDATED msg\n",
1341 __func__, __LINE__);
1342 }
1343 unlock_comm(cinfo);
1344}
1345
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001346static int resync_start(struct mddev *mddev)
1347{
1348 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiangd6385db2016-08-12 13:42:43 +08001349 return dlm_lock_sync_interruptible(cinfo->resync_lockres, DLM_LOCK_EX, mddev);
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001350}
1351
Guoqing Jiang5ebaf802018-10-18 16:37:43 +08001352static void resync_info_get(struct mddev *mddev, sector_t *lo, sector_t *hi)
1353{
1354 struct md_cluster_info *cinfo = mddev->cluster_info;
1355 struct suspend_info *s;
1356
1357 spin_lock_irq(&cinfo->suspend_lock);
1358 list_for_each_entry(s, &cinfo->suspend_list, list) {
1359 *lo = s->lo;
1360 *hi = s->hi;
1361 }
1362 spin_unlock_irq(&cinfo->suspend_lock);
1363}
1364
Goldwyn Rodriguesc40f3412015-08-19 08:14:42 +10001365static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi)
Goldwyn Rodrigues965400e2014-06-07 02:16:58 -05001366{
1367 struct md_cluster_info *cinfo = mddev->cluster_info;
Goldwyn Rodriguesac277c62015-12-21 10:50:59 +11001368 struct resync_info ri;
Guoqing Jiangaee177a2015-10-12 17:21:24 +08001369 struct cluster_msg cmsg = {0};
Goldwyn Rodrigues965400e2014-06-07 02:16:58 -05001370
Goldwyn Rodriguesac277c62015-12-21 10:50:59 +11001371 /* do not send zero again, if we have sent before */
1372 if (hi == 0) {
1373 memcpy(&ri, cinfo->bitmap_lockres->lksb.sb_lvbptr, sizeof(struct resync_info));
1374 if (le64_to_cpu(ri.hi) == 0)
1375 return 0;
1376 }
1377
NeilBrown30661b42015-10-19 15:44:00 +11001378 add_resync_info(cinfo->bitmap_lockres, lo, hi);
Goldwyn Rodriguesc40f3412015-08-19 08:14:42 +10001379 /* Re-acquire the lock to refresh LVB */
1380 dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW);
Goldwyn Rodriguesc40f3412015-08-19 08:14:42 +10001381 cmsg.type = cpu_to_le32(RESYNCING);
Goldwyn Rodrigues965400e2014-06-07 02:16:58 -05001382 cmsg.low = cpu_to_le64(lo);
1383 cmsg.high = cpu_to_le64(hi);
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001384
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001385 /*
1386 * mddev_lock is held if resync_info_update is called from
1387 * resync_finish (md_reap_sync_thread -> resync_finish)
1388 */
1389 if (lo == 0 && hi == 0)
1390 return sendmsg(cinfo, &cmsg, 1);
1391 else
1392 return sendmsg(cinfo, &cmsg, 0);
Goldwyn Rodrigues965400e2014-06-07 02:16:58 -05001393}
1394
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001395static int resync_finish(struct mddev *mddev)
1396{
1397 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiang41a95042018-08-31 10:05:57 +08001398 int ret = 0;
Guoqing Jiang0357ba22018-07-02 16:26:25 +08001399
1400 clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery);
Guoqing Jiangdf8c6762018-07-02 16:26:26 +08001401
1402 /*
1403 * If resync thread is interrupted so we can't say resync is finished,
1404 * another node will launch resync thread to continue.
1405 */
Guoqing Jiang41a95042018-08-31 10:05:57 +08001406 if (!test_bit(MD_CLOSING, &mddev->flags))
1407 ret = resync_info_update(mddev, 0, 0);
1408 dlm_unlock_sync(cinfo->resync_lockres);
1409 return ret;
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001410}
1411
Goldwyn Rodrigues90382ed2015-06-24 09:30:32 -05001412static int area_resyncing(struct mddev *mddev, int direction,
1413 sector_t lo, sector_t hi)
Goldwyn Rodrigues589a1c42014-06-07 02:39:37 -05001414{
1415 struct md_cluster_info *cinfo = mddev->cluster_info;
1416 int ret = 0;
1417 struct suspend_info *s;
1418
Goldwyn Rodrigues90382ed2015-06-24 09:30:32 -05001419 if ((direction == READ) &&
1420 test_bit(MD_CLUSTER_SUSPEND_READ_BALANCING, &cinfo->state))
1421 return 1;
1422
Goldwyn Rodrigues589a1c42014-06-07 02:39:37 -05001423 spin_lock_irq(&cinfo->suspend_lock);
1424 if (list_empty(&cinfo->suspend_list))
1425 goto out;
1426 list_for_each_entry(s, &cinfo->suspend_list, list)
1427 if (hi > s->lo && lo < s->hi) {
1428 ret = 1;
1429 break;
1430 }
1431out:
1432 spin_unlock_irq(&cinfo->suspend_lock);
1433 return ret;
1434}
1435
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001436/* add_new_disk() - initiates a disk add
1437 * However, if this fails before writing md_update_sb(),
1438 * add_new_disk_cancel() must be called to release token lock
1439 */
1440static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev)
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001441{
1442 struct md_cluster_info *cinfo = mddev->cluster_info;
1443 struct cluster_msg cmsg;
1444 int ret = 0;
1445 struct mdp_superblock_1 *sb = page_address(rdev->sb_page);
1446 char *uuid = sb->device_uuid;
1447
1448 memset(&cmsg, 0, sizeof(cmsg));
1449 cmsg.type = cpu_to_le32(NEWDISK);
1450 memcpy(cmsg.uuid, uuid, 16);
Guoqing Jiangfaeff832015-10-12 17:21:21 +08001451 cmsg.raid_slot = cpu_to_le32(rdev->desc_nr);
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001452 lock_comm(cinfo, 1);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001453 ret = __sendmsg(cinfo, &cmsg);
Guoqing Jiang2dffdc02017-05-16 14:01:25 +08001454 if (ret) {
1455 unlock_comm(cinfo);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001456 return ret;
Guoqing Jiang2dffdc02017-05-16 14:01:25 +08001457 }
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001458 cinfo->no_new_dev_lockres->flags |= DLM_LKF_NOQUEUE;
1459 ret = dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_EX);
1460 cinfo->no_new_dev_lockres->flags &= ~DLM_LKF_NOQUEUE;
1461 /* Some node does not "see" the device */
1462 if (ret == -EAGAIN)
1463 ret = -ENOENT;
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001464 if (ret)
1465 unlock_comm(cinfo);
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001466 else {
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001467 dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR);
Guoqing Jiange19508f2015-12-21 10:51:01 +11001468 /* Since MD_CHANGE_DEVS will be set in add_bound_rdev which
1469 * will run soon after add_new_disk, the below path will be
1470 * invoked:
1471 * md_wakeup_thread(mddev->thread)
1472 * -> conf->thread (raid1d)
1473 * -> md_check_recovery -> md_update_sb
1474 * -> metadata_update_start/finish
1475 * MD_CLUSTER_SEND_LOCKED_ALREADY will be cleared eventually.
1476 *
1477 * For other failure cases, metadata_update_cancel and
1478 * add_new_disk_cancel also clear below bit as well.
1479 * */
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001480 set_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state);
1481 wake_up(&cinfo->wait);
1482 }
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001483 return ret;
1484}
1485
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001486static void add_new_disk_cancel(struct mddev *mddev)
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001487{
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001488 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiang8b9277c2015-12-21 10:51:00 +11001489 clear_bit(MD_CLUSTER_SEND_LOCKED_ALREADY, &cinfo->state);
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001490 unlock_comm(cinfo);
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001491}
1492
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -06001493static int new_disk_ack(struct mddev *mddev, bool ack)
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001494{
1495 struct md_cluster_info *cinfo = mddev->cluster_info;
1496
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -06001497 if (!test_bit(MD_CLUSTER_WAITING_FOR_NEWDISK, &cinfo->state)) {
1498 pr_warn("md-cluster(%s): Spurious cluster confirmation\n", mdname(mddev));
1499 return -EINVAL;
1500 }
1501
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001502 if (ack)
1503 dlm_unlock_sync(cinfo->no_new_dev_lockres);
1504 complete(&cinfo->newdisk_completion);
Goldwyn Rodriguesfa8259d2015-03-02 10:55:49 -06001505 return 0;
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001506}
1507
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -05001508static int remove_disk(struct mddev *mddev, struct md_rdev *rdev)
1509{
Guoqing Jiangaee177a2015-10-12 17:21:24 +08001510 struct cluster_msg cmsg = {0};
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -05001511 struct md_cluster_info *cinfo = mddev->cluster_info;
Guoqing Jiangfaeff832015-10-12 17:21:21 +08001512 cmsg.type = cpu_to_le32(REMOVE);
1513 cmsg.raid_slot = cpu_to_le32(rdev->desc_nr);
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001514 return sendmsg(cinfo, &cmsg, 1);
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -05001515}
1516
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001517static int lock_all_bitmaps(struct mddev *mddev)
1518{
1519 int slot, my_slot, ret, held = 1, i = 0;
1520 char str[64];
1521 struct md_cluster_info *cinfo = mddev->cluster_info;
1522
Kees Cook6396bb22018-06-12 14:03:40 -07001523 cinfo->other_bitmap_lockres =
1524 kcalloc(mddev->bitmap_info.nodes - 1,
1525 sizeof(struct dlm_lock_resource *), GFP_KERNEL);
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001526 if (!cinfo->other_bitmap_lockres) {
1527 pr_err("md: can't alloc mem for other bitmap locks\n");
1528 return 0;
1529 }
1530
1531 my_slot = slot_number(mddev);
1532 for (slot = 0; slot < mddev->bitmap_info.nodes; slot++) {
1533 if (slot == my_slot)
1534 continue;
1535
1536 memset(str, '\0', 64);
1537 snprintf(str, 64, "bitmap%04d", slot);
1538 cinfo->other_bitmap_lockres[i] = lockres_init(mddev, str, NULL, 1);
1539 if (!cinfo->other_bitmap_lockres[i])
1540 return -ENOMEM;
1541
1542 cinfo->other_bitmap_lockres[i]->flags |= DLM_LKF_NOQUEUE;
1543 ret = dlm_lock_sync(cinfo->other_bitmap_lockres[i], DLM_LOCK_PW);
1544 if (ret)
1545 held = -1;
1546 i++;
1547 }
1548
1549 return held;
1550}
1551
1552static void unlock_all_bitmaps(struct mddev *mddev)
1553{
1554 struct md_cluster_info *cinfo = mddev->cluster_info;
1555 int i;
1556
1557 /* release other node's bitmap lock if they are existed */
1558 if (cinfo->other_bitmap_lockres) {
1559 for (i = 0; i < mddev->bitmap_info.nodes - 1; i++) {
1560 if (cinfo->other_bitmap_lockres[i]) {
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001561 lockres_free(cinfo->other_bitmap_lockres[i]);
1562 }
1563 }
1564 kfree(cinfo->other_bitmap_lockres);
1565 }
1566}
1567
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -05001568static int gather_bitmaps(struct md_rdev *rdev)
1569{
1570 int sn, err;
1571 sector_t lo, hi;
Guoqing Jiangaee177a2015-10-12 17:21:24 +08001572 struct cluster_msg cmsg = {0};
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -05001573 struct mddev *mddev = rdev->mddev;
1574 struct md_cluster_info *cinfo = mddev->cluster_info;
1575
Guoqing Jiangfaeff832015-10-12 17:21:21 +08001576 cmsg.type = cpu_to_le32(RE_ADD);
1577 cmsg.raid_slot = cpu_to_le32(rdev->desc_nr);
Guoqing Jiang0ba95972017-03-01 17:30:29 +08001578 err = sendmsg(cinfo, &cmsg, 1);
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -05001579 if (err)
1580 goto out;
1581
1582 for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) {
1583 if (sn == (cinfo->slot_number - 1))
1584 continue;
Andy Shevchenkoe64e40182018-08-01 15:20:50 -07001585 err = md_bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -05001586 if (err) {
1587 pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn);
1588 goto out;
1589 }
1590 if ((hi > 0) && (lo < mddev->recovery_cp))
1591 mddev->recovery_cp = lo;
1592 }
1593out:
1594 return err;
1595}
1596
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001597static struct md_cluster_operations cluster_ops = {
1598 .join = join,
1599 .leave = leave,
Goldwyn Rodriguescf921cc2014-03-30 00:42:49 -05001600 .slot_number = slot_number,
Goldwyn Rodriguesc186b122015-09-30 13:20:35 -05001601 .resync_start = resync_start,
1602 .resync_finish = resync_finish,
Goldwyn Rodrigues96ae9232014-06-06 12:35:34 -05001603 .resync_info_update = resync_info_update,
Guoqing Jiang5ebaf802018-10-18 16:37:43 +08001604 .resync_info_get = resync_info_get,
Goldwyn Rodrigues293467a2014-06-07 01:44:51 -05001605 .metadata_update_start = metadata_update_start,
1606 .metadata_update_finish = metadata_update_finish,
1607 .metadata_update_cancel = metadata_update_cancel,
Goldwyn Rodrigues589a1c42014-06-07 02:39:37 -05001608 .area_resyncing = area_resyncing,
Goldwyn Rodriguesdbb64f82015-10-01 13:20:27 -05001609 .add_new_disk = add_new_disk,
1610 .add_new_disk_cancel = add_new_disk_cancel,
Goldwyn Rodrigues1aee41f2014-10-29 18:51:31 -05001611 .new_disk_ack = new_disk_ack,
Goldwyn Rodrigues88bcfef2015-04-14 10:44:44 -05001612 .remove_disk = remove_disk,
Guoqing Jiang51e453a2016-05-04 02:17:09 -04001613 .load_bitmaps = load_bitmaps,
Goldwyn Rodrigues97f6cd32015-04-14 10:45:42 -05001614 .gather_bitmaps = gather_bitmaps,
Guoqing Jiangafd75622018-10-18 16:37:41 +08001615 .resize_bitmaps = resize_bitmaps,
Guoqing Jiangf6a2dc62015-12-21 10:51:00 +11001616 .lock_all_bitmaps = lock_all_bitmaps,
1617 .unlock_all_bitmaps = unlock_all_bitmaps,
Guoqing Jiang818da592017-03-01 16:42:40 +08001618 .update_size = update_size,
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001619};
1620
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001621static int __init cluster_init(void)
1622{
Guoqing Jiangf0e230a2017-10-24 15:11:53 +08001623 pr_warn("md-cluster: support raid1 and raid10 (limited support)\n");
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001624 pr_info("Registering Cluster MD functions\n");
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001625 register_md_cluster_operations(&cluster_ops, THIS_MODULE);
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001626 return 0;
1627}
1628
1629static void cluster_exit(void)
1630{
Goldwyn Rodriguesedb39c92014-03-29 10:01:53 -05001631 unregister_md_cluster_operations();
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001632}
1633
1634module_init(cluster_init);
1635module_exit(cluster_exit);
Guoqing Jiang86b57272015-10-12 17:21:25 +08001636MODULE_AUTHOR("SUSE");
Goldwyn Rodrigues8e854e92014-03-07 11:21:15 -06001637MODULE_LICENSE("GPL");
1638MODULE_DESCRIPTION("Clustering support for MD");