diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2014-03-29 11:20:02 -0400 |
---|---|---|
committer | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2015-02-23 08:28:42 -0500 |
commit | c4ce867fdad200dfd8aa8cbe1eabc26c14c51635 (patch) | |
tree | 529e265c90fbc91a3d4fe8a327f9d7ff9a284890 | |
parent | edb39c9deda87da5aad9c090e2e8eaf8470c852c (diff) |
Introduce md_cluster_info
md_cluster_info stores the cluster information in the MD device.
The join() is called when mddev detects it is a clustered device.
The main responsibilities are:
1. Setup a DLM lockspace
2. Setup all initial locks such as super block locks and bitmap lock (will come later)
The leave() clears up the lockspace and all the locks held.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-rw-r--r-- | drivers/md/bitmap.c | 9 | ||||
-rw-r--r-- | drivers/md/md-cluster.c | 65 | ||||
-rw-r--r-- | drivers/md/md.c | 2 | ||||
-rw-r--r-- | drivers/md/md.h | 8 |
4 files changed, 80 insertions, 4 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 3a5767968ba0..e2aacca46911 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -433,6 +433,7 @@ void bitmap_update_sb(struct bitmap *bitmap) | |||
433 | /* This might have been changed by a reshape */ | 433 | /* This might have been changed by a reshape */ |
434 | sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors); | 434 | sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors); |
435 | sb->chunksize = cpu_to_le32(bitmap->mddev->bitmap_info.chunksize); | 435 | sb->chunksize = cpu_to_le32(bitmap->mddev->bitmap_info.chunksize); |
436 | sb->nodes = cpu_to_le32(bitmap->mddev->bitmap_info.nodes); | ||
436 | sb->sectors_reserved = cpu_to_le32(bitmap->mddev-> | 437 | sb->sectors_reserved = cpu_to_le32(bitmap->mddev-> |
437 | bitmap_info.space); | 438 | bitmap_info.space); |
438 | kunmap_atomic(sb); | 439 | kunmap_atomic(sb); |
@@ -544,6 +545,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
544 | bitmap_super_t *sb; | 545 | bitmap_super_t *sb; |
545 | unsigned long chunksize, daemon_sleep, write_behind; | 546 | unsigned long chunksize, daemon_sleep, write_behind; |
546 | unsigned long long events; | 547 | unsigned long long events; |
548 | int nodes = 0; | ||
547 | unsigned long sectors_reserved = 0; | 549 | unsigned long sectors_reserved = 0; |
548 | int err = -EINVAL; | 550 | int err = -EINVAL; |
549 | struct page *sb_page; | 551 | struct page *sb_page; |
@@ -583,6 +585,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
583 | daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; | 585 | daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; |
584 | write_behind = le32_to_cpu(sb->write_behind); | 586 | write_behind = le32_to_cpu(sb->write_behind); |
585 | sectors_reserved = le32_to_cpu(sb->sectors_reserved); | 587 | sectors_reserved = le32_to_cpu(sb->sectors_reserved); |
588 | nodes = le32_to_cpu(sb->nodes); | ||
586 | 589 | ||
587 | /* verify that the bitmap-specific fields are valid */ | 590 | /* verify that the bitmap-specific fields are valid */ |
588 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) | 591 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) |
@@ -643,6 +646,7 @@ out_no_sb: | |||
643 | bitmap->mddev->bitmap_info.chunksize = chunksize; | 646 | bitmap->mddev->bitmap_info.chunksize = chunksize; |
644 | bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; | 647 | bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; |
645 | bitmap->mddev->bitmap_info.max_write_behind = write_behind; | 648 | bitmap->mddev->bitmap_info.max_write_behind = write_behind; |
649 | bitmap->mddev->bitmap_info.nodes = nodes; | ||
646 | if (bitmap->mddev->bitmap_info.space == 0 || | 650 | if (bitmap->mddev->bitmap_info.space == 0 || |
647 | bitmap->mddev->bitmap_info.space > sectors_reserved) | 651 | bitmap->mddev->bitmap_info.space > sectors_reserved) |
648 | bitmap->mddev->bitmap_info.space = sectors_reserved; | 652 | bitmap->mddev->bitmap_info.space = sectors_reserved; |
@@ -2186,6 +2190,8 @@ __ATTR(chunksize, S_IRUGO|S_IWUSR, chunksize_show, chunksize_store); | |||
2186 | 2190 | ||
2187 | static ssize_t metadata_show(struct mddev *mddev, char *page) | 2191 | static ssize_t metadata_show(struct mddev *mddev, char *page) |
2188 | { | 2192 | { |
2193 | if (mddev_is_clustered(mddev)) | ||
2194 | return sprintf(page, "clustered\n"); | ||
2189 | return sprintf(page, "%s\n", (mddev->bitmap_info.external | 2195 | return sprintf(page, "%s\n", (mddev->bitmap_info.external |
2190 | ? "external" : "internal")); | 2196 | ? "external" : "internal")); |
2191 | } | 2197 | } |
@@ -2198,7 +2204,8 @@ static ssize_t metadata_store(struct mddev *mddev, const char *buf, size_t len) | |||
2198 | return -EBUSY; | 2204 | return -EBUSY; |
2199 | if (strncmp(buf, "external", 8) == 0) | 2205 | if (strncmp(buf, "external", 8) == 0) |
2200 | mddev->bitmap_info.external = 1; | 2206 | mddev->bitmap_info.external = 1; |
2201 | else if (strncmp(buf, "internal", 8) == 0) | 2207 | else if ((strncmp(buf, "internal", 8) == 0) || |
2208 | (strncmp(buf, "clustered", 9) == 0)) | ||
2202 | mddev->bitmap_info.external = 0; | 2209 | mddev->bitmap_info.external = 0; |
2203 | else | 2210 | else |
2204 | return -EINVAL; | 2211 | return -EINVAL; |
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index e2235600a72b..d141d4812c8c 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
@@ -22,8 +22,16 @@ struct dlm_lock_resource { | |||
22 | struct dlm_lksb lksb; | 22 | struct dlm_lksb lksb; |
23 | char *name; /* lock name. */ | 23 | char *name; /* lock name. */ |
24 | uint32_t flags; /* flags to pass to dlm_lock() */ | 24 | uint32_t flags; /* flags to pass to dlm_lock() */ |
25 | void (*bast)(void *arg, int mode); /* blocking AST function pointer*/ | ||
26 | struct completion completion; /* completion for synchronized locking */ | 25 | struct completion completion; /* completion for synchronized locking */ |
26 | void (*bast)(void *arg, int mode); /* blocking AST function pointer*/ | ||
27 | struct mddev *mddev; /* pointing back to mddev. */ | ||
28 | }; | ||
29 | |||
30 | struct md_cluster_info { | ||
31 | /* dlm lock space and resources for clustered raid. */ | ||
32 | dlm_lockspace_t *lockspace; | ||
33 | struct dlm_lock_resource *sb_lock; | ||
34 | struct mutex sb_mutex; | ||
27 | }; | 35 | }; |
28 | 36 | ||
29 | static void sync_ast(void *arg) | 37 | static void sync_ast(void *arg) |
@@ -53,16 +61,18 @@ static int dlm_unlock_sync(struct dlm_lock_resource *res) | |||
53 | return dlm_lock_sync(res, DLM_LOCK_NL); | 61 | return dlm_lock_sync(res, DLM_LOCK_NL); |
54 | } | 62 | } |
55 | 63 | ||
56 | static struct dlm_lock_resource *lockres_init(dlm_lockspace_t *lockspace, | 64 | static struct dlm_lock_resource *lockres_init(struct mddev *mddev, |
57 | char *name, void (*bastfn)(void *arg, int mode), int with_lvb) | 65 | char *name, void (*bastfn)(void *arg, int mode), int with_lvb) |
58 | { | 66 | { |
59 | struct dlm_lock_resource *res = NULL; | 67 | struct dlm_lock_resource *res = NULL; |
60 | int ret, namelen; | 68 | int ret, namelen; |
69 | struct md_cluster_info *cinfo = mddev->cluster_info; | ||
61 | 70 | ||
62 | res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL); | 71 | res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL); |
63 | if (!res) | 72 | if (!res) |
64 | return NULL; | 73 | return NULL; |
65 | res->ls = lockspace; | 74 | res->ls = cinfo->lockspace; |
75 | res->mddev = mddev; | ||
66 | namelen = strlen(name); | 76 | namelen = strlen(name); |
67 | res->name = kzalloc(namelen + 1, GFP_KERNEL); | 77 | res->name = kzalloc(namelen + 1, GFP_KERNEL); |
68 | if (!res->name) { | 78 | if (!res->name) { |
@@ -114,13 +124,62 @@ static void lockres_free(struct dlm_lock_resource *res) | |||
114 | kfree(res); | 124 | kfree(res); |
115 | } | 125 | } |
116 | 126 | ||
127 | static char *pretty_uuid(char *dest, char *src) | ||
128 | { | ||
129 | int i, len = 0; | ||
130 | |||
131 | for (i = 0; i < 16; i++) { | ||
132 | if (i == 4 || i == 6 || i == 8 || i == 10) | ||
133 | len += sprintf(dest + len, "-"); | ||
134 | len += sprintf(dest + len, "%02x", (__u8)src[i]); | ||
135 | } | ||
136 | return dest; | ||
137 | } | ||
138 | |||
117 | static int join(struct mddev *mddev, int nodes) | 139 | static int join(struct mddev *mddev, int nodes) |
118 | { | 140 | { |
141 | struct md_cluster_info *cinfo; | ||
142 | int ret; | ||
143 | char str[64]; | ||
144 | |||
145 | if (!try_module_get(THIS_MODULE)) | ||
146 | return -ENOENT; | ||
147 | |||
148 | cinfo = kzalloc(sizeof(struct md_cluster_info), GFP_KERNEL); | ||
149 | if (!cinfo) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | memset(str, 0, 64); | ||
153 | pretty_uuid(str, mddev->uuid); | ||
154 | ret = dlm_new_lockspace(str, NULL, DLM_LSFL_FS, LVB_SIZE, | ||
155 | NULL, NULL, NULL, &cinfo->lockspace); | ||
156 | if (ret) | ||
157 | goto err; | ||
158 | cinfo->sb_lock = lockres_init(mddev, "cmd-super", | ||
159 | NULL, 0); | ||
160 | if (!cinfo->sb_lock) { | ||
161 | ret = -ENOMEM; | ||
162 | goto err; | ||
163 | } | ||
164 | mutex_init(&cinfo->sb_mutex); | ||
165 | mddev->cluster_info = cinfo; | ||
119 | return 0; | 166 | return 0; |
167 | err: | ||
168 | if (cinfo->lockspace) | ||
169 | dlm_release_lockspace(cinfo->lockspace, 2); | ||
170 | kfree(cinfo); | ||
171 | module_put(THIS_MODULE); | ||
172 | return ret; | ||
120 | } | 173 | } |
121 | 174 | ||
122 | static int leave(struct mddev *mddev) | 175 | static int leave(struct mddev *mddev) |
123 | { | 176 | { |
177 | struct md_cluster_info *cinfo = mddev->cluster_info; | ||
178 | |||
179 | if (!cinfo) | ||
180 | return 0; | ||
181 | lockres_free(cinfo->sb_lock); | ||
182 | dlm_release_lockspace(cinfo->lockspace, 2); | ||
124 | return 0; | 183 | return 0; |
125 | } | 184 | } |
126 | 185 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 57ecb51ec5fd..3387f940140b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -7279,6 +7279,8 @@ int md_setup_cluster(struct mddev *mddev, int nodes) | |||
7279 | 7279 | ||
7280 | void md_cluster_stop(struct mddev *mddev) | 7280 | void md_cluster_stop(struct mddev *mddev) |
7281 | { | 7281 | { |
7282 | if (!md_cluster_ops) | ||
7283 | return; | ||
7282 | md_cluster_ops->leave(mddev); | 7284 | md_cluster_ops->leave(mddev); |
7283 | module_put(md_cluster_mod); | 7285 | module_put(md_cluster_mod); |
7284 | } | 7286 | } |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 018593197c4d..80fc89976915 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -203,6 +203,8 @@ extern int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors, | |||
203 | int is_new); | 203 | int is_new); |
204 | extern void md_ack_all_badblocks(struct badblocks *bb); | 204 | extern void md_ack_all_badblocks(struct badblocks *bb); |
205 | 205 | ||
206 | struct md_cluster_info; | ||
207 | |||
206 | struct mddev { | 208 | struct mddev { |
207 | void *private; | 209 | void *private; |
208 | struct md_personality *pers; | 210 | struct md_personality *pers; |
@@ -431,6 +433,7 @@ struct mddev { | |||
431 | unsigned long daemon_sleep; /* how many jiffies between updates? */ | 433 | unsigned long daemon_sleep; /* how many jiffies between updates? */ |
432 | unsigned long max_write_behind; /* write-behind mode */ | 434 | unsigned long max_write_behind; /* write-behind mode */ |
433 | int external; | 435 | int external; |
436 | int nodes; /* Maximum number of nodes in the cluster */ | ||
434 | } bitmap_info; | 437 | } bitmap_info; |
435 | 438 | ||
436 | atomic_t max_corr_read_errors; /* max read retries */ | 439 | atomic_t max_corr_read_errors; /* max read retries */ |
@@ -449,6 +452,7 @@ struct mddev { | |||
449 | struct work_struct flush_work; | 452 | struct work_struct flush_work; |
450 | struct work_struct event_work; /* used by dm to report failure event */ | 453 | struct work_struct event_work; /* used by dm to report failure event */ |
451 | void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); | 454 | void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); |
455 | struct md_cluster_info *cluster_info; | ||
452 | }; | 456 | }; |
453 | 457 | ||
454 | static inline int __must_check mddev_lock(struct mddev *mddev) | 458 | static inline int __must_check mddev_lock(struct mddev *mddev) |
@@ -676,4 +680,8 @@ static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev) | |||
676 | } | 680 | } |
677 | 681 | ||
678 | extern struct md_cluster_operations *md_cluster_ops; | 682 | extern struct md_cluster_operations *md_cluster_ops; |
683 | static inline int mddev_is_clustered(struct mddev *mddev) | ||
684 | { | ||
685 | return mddev->cluster_info && mddev->bitmap_info.nodes > 1; | ||
686 | } | ||
679 | #endif /* _MD_MD_H */ | 687 | #endif /* _MD_MD_H */ |