aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.com>2014-03-29 11:20:02 -0400
committerGoldwyn Rodrigues <rgoldwyn@suse.com>2015-02-23 08:28:42 -0500
commitc4ce867fdad200dfd8aa8cbe1eabc26c14c51635 (patch)
tree529e265c90fbc91a3d4fe8a327f9d7ff9a284890
parentedb39c9deda87da5aad9c090e2e8eaf8470c852c (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.c9
-rw-r--r--drivers/md/md-cluster.c65
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/md.h8
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
2187static ssize_t metadata_show(struct mddev *mddev, char *page) 2191static 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
30struct 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
29static void sync_ast(void *arg) 37static 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
56static struct dlm_lock_resource *lockres_init(dlm_lockspace_t *lockspace, 64static 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
127static 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
117static int join(struct mddev *mddev, int nodes) 139static 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;
167err:
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
122static int leave(struct mddev *mddev) 175static 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
7280void md_cluster_stop(struct mddev *mddev) 7280void 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);
204extern void md_ack_all_badblocks(struct badblocks *bb); 204extern void md_ack_all_badblocks(struct badblocks *bb);
205 205
206struct md_cluster_info;
207
206struct mddev { 208struct 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
454static inline int __must_check mddev_lock(struct mddev *mddev) 458static 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
678extern struct md_cluster_operations *md_cluster_ops; 682extern struct md_cluster_operations *md_cluster_ops;
683static 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 */