diff options
-rw-r--r-- | fs/ocfs2/stackglue.c | 209 |
1 files changed, 144 insertions, 65 deletions
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 51c2546b328d..e35dde6217f5 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c | |||
@@ -197,21 +197,19 @@ static void o2dlm_unlock_ast_wrapper(void *astarg, enum dlm_status status) | |||
197 | lproto->lp_unlock_ast(astarg, error); | 197 | lproto->lp_unlock_ast(astarg, error); |
198 | } | 198 | } |
199 | 199 | ||
200 | int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn, | 200 | static int o2cb_dlm_lock(struct ocfs2_cluster_connection *conn, |
201 | int mode, | 201 | int mode, |
202 | union ocfs2_dlm_lksb *lksb, | 202 | union ocfs2_dlm_lksb *lksb, |
203 | u32 flags, | 203 | u32 flags, |
204 | void *name, | 204 | void *name, |
205 | unsigned int namelen, | 205 | unsigned int namelen, |
206 | void *astarg) | 206 | void *astarg) |
207 | { | 207 | { |
208 | enum dlm_status status; | 208 | enum dlm_status status; |
209 | int o2dlm_mode = mode_to_o2dlm(mode); | 209 | int o2dlm_mode = mode_to_o2dlm(mode); |
210 | int o2dlm_flags = flags_to_o2dlm(flags); | 210 | int o2dlm_flags = flags_to_o2dlm(flags); |
211 | int ret; | 211 | int ret; |
212 | 212 | ||
213 | BUG_ON(lproto == NULL); | ||
214 | |||
215 | status = dlmlock(conn->cc_lockspace, o2dlm_mode, &lksb->lksb_o2dlm, | 213 | status = dlmlock(conn->cc_lockspace, o2dlm_mode, &lksb->lksb_o2dlm, |
216 | o2dlm_flags, name, namelen, | 214 | o2dlm_flags, name, namelen, |
217 | o2dlm_lock_ast_wrapper, astarg, | 215 | o2dlm_lock_ast_wrapper, astarg, |
@@ -220,43 +218,80 @@ int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn, | |||
220 | return ret; | 218 | return ret; |
221 | } | 219 | } |
222 | 220 | ||
223 | int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn, | 221 | int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn, |
224 | union ocfs2_dlm_lksb *lksb, | 222 | int mode, |
225 | u32 flags, | 223 | union ocfs2_dlm_lksb *lksb, |
226 | void *astarg) | 224 | u32 flags, |
225 | void *name, | ||
226 | unsigned int namelen, | ||
227 | void *astarg) | ||
228 | { | ||
229 | BUG_ON(lproto == NULL); | ||
230 | |||
231 | return o2cb_dlm_lock(conn, mode, lksb, flags, | ||
232 | name, namelen, astarg); | ||
233 | } | ||
234 | |||
235 | static int o2cb_dlm_unlock(struct ocfs2_cluster_connection *conn, | ||
236 | union ocfs2_dlm_lksb *lksb, | ||
237 | u32 flags, | ||
238 | void *astarg) | ||
227 | { | 239 | { |
228 | enum dlm_status status; | 240 | enum dlm_status status; |
229 | int o2dlm_flags = flags_to_o2dlm(flags); | 241 | int o2dlm_flags = flags_to_o2dlm(flags); |
230 | int ret; | 242 | int ret; |
231 | 243 | ||
232 | BUG_ON(lproto == NULL); | ||
233 | |||
234 | status = dlmunlock(conn->cc_lockspace, &lksb->lksb_o2dlm, | 244 | status = dlmunlock(conn->cc_lockspace, &lksb->lksb_o2dlm, |
235 | o2dlm_flags, o2dlm_unlock_ast_wrapper, astarg); | 245 | o2dlm_flags, o2dlm_unlock_ast_wrapper, astarg); |
236 | ret = dlm_status_to_errno(status); | 246 | ret = dlm_status_to_errno(status); |
237 | return ret; | 247 | return ret; |
238 | } | 248 | } |
239 | 249 | ||
240 | int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | 250 | int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn, |
251 | union ocfs2_dlm_lksb *lksb, | ||
252 | u32 flags, | ||
253 | void *astarg) | ||
254 | { | ||
255 | BUG_ON(lproto == NULL); | ||
256 | |||
257 | return o2cb_dlm_unlock(conn, lksb, flags, astarg); | ||
258 | } | ||
259 | |||
260 | static int o2cb_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | ||
241 | { | 261 | { |
242 | return dlm_status_to_errno(lksb->lksb_o2dlm.status); | 262 | return dlm_status_to_errno(lksb->lksb_o2dlm.status); |
243 | } | 263 | } |
244 | 264 | ||
265 | int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | ||
266 | { | ||
267 | return o2cb_dlm_lock_status(lksb); | ||
268 | } | ||
269 | |||
245 | /* | 270 | /* |
246 | * Why don't we cast to ocfs2_meta_lvb? The "clean" answer is that we | 271 | * Why don't we cast to ocfs2_meta_lvb? The "clean" answer is that we |
247 | * don't cast at the glue level. The real answer is that the header | 272 | * don't cast at the glue level. The real answer is that the header |
248 | * ordering is nigh impossible. | 273 | * ordering is nigh impossible. |
249 | */ | 274 | */ |
250 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb) | 275 | static void *o2cb_dlm_lvb(union ocfs2_dlm_lksb *lksb) |
251 | { | 276 | { |
252 | return (void *)(lksb->lksb_o2dlm.lvb); | 277 | return (void *)(lksb->lksb_o2dlm.lvb); |
253 | } | 278 | } |
254 | 279 | ||
255 | void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb) | 280 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb) |
281 | { | ||
282 | return o2cb_dlm_lvb(lksb); | ||
283 | } | ||
284 | |||
285 | static void o2cb_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb) | ||
256 | { | 286 | { |
257 | dlm_print_one_lock(lksb->lksb_o2dlm.lockid); | 287 | dlm_print_one_lock(lksb->lksb_o2dlm.lockid); |
258 | } | 288 | } |
259 | 289 | ||
290 | void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb) | ||
291 | { | ||
292 | o2cb_dlm_dump_lksb(lksb); | ||
293 | } | ||
294 | |||
260 | /* | 295 | /* |
261 | * Called from the dlm when it's about to evict a node. This is how the | 296 | * Called from the dlm when it's about to evict a node. This is how the |
262 | * classic stack signals node death. | 297 | * classic stack signals node death. |
@@ -271,6 +306,62 @@ static void o2dlm_eviction_cb(int node_num, void *data) | |||
271 | conn->cc_recovery_handler(node_num, conn->cc_recovery_data); | 306 | conn->cc_recovery_handler(node_num, conn->cc_recovery_data); |
272 | } | 307 | } |
273 | 308 | ||
309 | static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn) | ||
310 | { | ||
311 | int rc = 0; | ||
312 | u32 dlm_key; | ||
313 | struct dlm_ctxt *dlm; | ||
314 | struct o2dlm_private *priv; | ||
315 | struct dlm_protocol_version dlm_version; | ||
316 | |||
317 | BUG_ON(conn == NULL); | ||
318 | |||
319 | /* for now we only have one cluster/node, make sure we see it | ||
320 | * in the heartbeat universe */ | ||
321 | if (!o2hb_check_local_node_heartbeating()) { | ||
322 | rc = -EINVAL; | ||
323 | goto out; | ||
324 | } | ||
325 | |||
326 | priv = kzalloc(sizeof(struct o2dlm_private), GFP_KERNEL); | ||
327 | if (!priv) { | ||
328 | rc = -ENOMEM; | ||
329 | goto out_free; | ||
330 | } | ||
331 | |||
332 | /* This just fills the structure in. It is safe to pass conn. */ | ||
333 | dlm_setup_eviction_cb(&priv->op_eviction_cb, o2dlm_eviction_cb, | ||
334 | conn); | ||
335 | |||
336 | conn->cc_private = priv; | ||
337 | |||
338 | /* used by the dlm code to make message headers unique, each | ||
339 | * node in this domain must agree on this. */ | ||
340 | dlm_key = crc32_le(0, conn->cc_name, conn->cc_namelen); | ||
341 | dlm_version.pv_major = conn->cc_version.pv_major; | ||
342 | dlm_version.pv_minor = conn->cc_version.pv_minor; | ||
343 | |||
344 | dlm = dlm_register_domain(conn->cc_name, dlm_key, &dlm_version); | ||
345 | if (IS_ERR(dlm)) { | ||
346 | rc = PTR_ERR(dlm); | ||
347 | mlog_errno(rc); | ||
348 | goto out_free; | ||
349 | } | ||
350 | |||
351 | conn->cc_version.pv_major = dlm_version.pv_major; | ||
352 | conn->cc_version.pv_minor = dlm_version.pv_minor; | ||
353 | conn->cc_lockspace = dlm; | ||
354 | |||
355 | dlm_register_eviction_cb(dlm, &priv->op_eviction_cb); | ||
356 | |||
357 | out_free: | ||
358 | if (rc && conn->cc_private) | ||
359 | kfree(conn->cc_private); | ||
360 | |||
361 | out: | ||
362 | return rc; | ||
363 | } | ||
364 | |||
274 | int ocfs2_cluster_connect(const char *group, | 365 | int ocfs2_cluster_connect(const char *group, |
275 | int grouplen, | 366 | int grouplen, |
276 | void (*recovery_handler)(int node_num, | 367 | void (*recovery_handler)(int node_num, |
@@ -280,10 +371,6 @@ int ocfs2_cluster_connect(const char *group, | |||
280 | { | 371 | { |
281 | int rc = 0; | 372 | int rc = 0; |
282 | struct ocfs2_cluster_connection *new_conn; | 373 | struct ocfs2_cluster_connection *new_conn; |
283 | u32 dlm_key; | ||
284 | struct dlm_ctxt *dlm; | ||
285 | struct o2dlm_private *priv; | ||
286 | struct dlm_protocol_version dlm_version; | ||
287 | 374 | ||
288 | BUG_ON(group == NULL); | 375 | BUG_ON(group == NULL); |
289 | BUG_ON(conn == NULL); | 376 | BUG_ON(conn == NULL); |
@@ -294,13 +381,6 @@ int ocfs2_cluster_connect(const char *group, | |||
294 | goto out; | 381 | goto out; |
295 | } | 382 | } |
296 | 383 | ||
297 | /* for now we only have one cluster/node, make sure we see it | ||
298 | * in the heartbeat universe */ | ||
299 | if (!o2hb_check_local_node_heartbeating()) { | ||
300 | rc = -EINVAL; | ||
301 | goto out; | ||
302 | } | ||
303 | |||
304 | new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection), | 384 | new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection), |
305 | GFP_KERNEL); | 385 | GFP_KERNEL); |
306 | if (!new_conn) { | 386 | if (!new_conn) { |
@@ -316,64 +396,53 @@ int ocfs2_cluster_connect(const char *group, | |||
316 | /* Start the new connection at our maximum compatibility level */ | 396 | /* Start the new connection at our maximum compatibility level */ |
317 | new_conn->cc_version = lproto->lp_max_version; | 397 | new_conn->cc_version = lproto->lp_max_version; |
318 | 398 | ||
319 | priv = kzalloc(sizeof(struct o2dlm_private), GFP_KERNEL); | 399 | rc = o2cb_cluster_connect(new_conn); |
320 | if (!priv) { | 400 | if (rc) { |
321 | rc = -ENOMEM; | ||
322 | goto out_free; | ||
323 | } | ||
324 | |||
325 | /* This just fills the structure in. It is safe to use new_conn. */ | ||
326 | dlm_setup_eviction_cb(&priv->op_eviction_cb, o2dlm_eviction_cb, | ||
327 | new_conn); | ||
328 | |||
329 | new_conn->cc_private = priv; | ||
330 | |||
331 | /* used by the dlm code to make message headers unique, each | ||
332 | * node in this domain must agree on this. */ | ||
333 | dlm_key = crc32_le(0, group, grouplen); | ||
334 | dlm_version.pv_major = new_conn->cc_version.pv_major; | ||
335 | dlm_version.pv_minor = new_conn->cc_version.pv_minor; | ||
336 | |||
337 | dlm = dlm_register_domain(group, dlm_key, &dlm_version); | ||
338 | if (IS_ERR(dlm)) { | ||
339 | rc = PTR_ERR(dlm); | ||
340 | mlog_errno(rc); | 401 | mlog_errno(rc); |
341 | goto out_free; | 402 | goto out_free; |
342 | } | 403 | } |
343 | 404 | ||
344 | new_conn->cc_version.pv_major = dlm_version.pv_major; | ||
345 | new_conn->cc_version.pv_minor = dlm_version.pv_minor; | ||
346 | new_conn->cc_lockspace = dlm; | ||
347 | |||
348 | dlm_register_eviction_cb(dlm, &priv->op_eviction_cb); | ||
349 | |||
350 | *conn = new_conn; | 405 | *conn = new_conn; |
351 | 406 | ||
352 | out_free: | 407 | out_free: |
353 | if (rc) { | 408 | if (rc) |
354 | kfree(new_conn->cc_private); | ||
355 | kfree(new_conn); | 409 | kfree(new_conn); |
356 | } | ||
357 | 410 | ||
358 | out: | 411 | out: |
359 | return rc; | 412 | return rc; |
360 | } | 413 | } |
361 | 414 | ||
362 | 415 | ||
363 | int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn) | 416 | static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn) |
364 | { | 417 | { |
365 | struct dlm_ctxt *dlm = conn->cc_lockspace; | 418 | struct dlm_ctxt *dlm = conn->cc_lockspace; |
366 | struct o2dlm_private *priv = conn->cc_private; | 419 | struct o2dlm_private *priv = conn->cc_private; |
367 | 420 | ||
368 | dlm_unregister_eviction_cb(&priv->op_eviction_cb); | 421 | dlm_unregister_eviction_cb(&priv->op_eviction_cb); |
369 | dlm_unregister_domain(dlm); | 422 | conn->cc_private = NULL; |
370 | |||
371 | kfree(priv); | 423 | kfree(priv); |
372 | kfree(conn); | 424 | |
425 | dlm_unregister_domain(dlm); | ||
426 | conn->cc_lockspace = NULL; | ||
373 | 427 | ||
374 | return 0; | 428 | return 0; |
375 | } | 429 | } |
376 | 430 | ||
431 | int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn) | ||
432 | { | ||
433 | int ret; | ||
434 | |||
435 | BUG_ON(conn == NULL); | ||
436 | |||
437 | ret = o2cb_cluster_disconnect(conn); | ||
438 | |||
439 | /* XXX Should we free it anyway? */ | ||
440 | if (!ret) | ||
441 | kfree(conn); | ||
442 | |||
443 | return ret; | ||
444 | } | ||
445 | |||
377 | static void o2hb_stop(const char *group) | 446 | static void o2hb_stop(const char *group) |
378 | { | 447 | { |
379 | int ret; | 448 | int ret; |
@@ -406,15 +475,20 @@ static void o2hb_stop(const char *group) | |||
406 | * | 475 | * |
407 | * Other stacks will eventually provide a NULL ->hangup() pointer. | 476 | * Other stacks will eventually provide a NULL ->hangup() pointer. |
408 | */ | 477 | */ |
478 | static void o2cb_cluster_hangup(const char *group, int grouplen) | ||
479 | { | ||
480 | o2hb_stop(group); | ||
481 | } | ||
482 | |||
409 | void ocfs2_cluster_hangup(const char *group, int grouplen) | 483 | void ocfs2_cluster_hangup(const char *group, int grouplen) |
410 | { | 484 | { |
411 | BUG_ON(group == NULL); | 485 | BUG_ON(group == NULL); |
412 | BUG_ON(group[grouplen] != '\0'); | 486 | BUG_ON(group[grouplen] != '\0'); |
413 | 487 | ||
414 | o2hb_stop(group); | 488 | o2cb_cluster_hangup(group, grouplen); |
415 | } | 489 | } |
416 | 490 | ||
417 | int ocfs2_cluster_this_node(unsigned int *node) | 491 | static int o2cb_cluster_this_node(unsigned int *node) |
418 | { | 492 | { |
419 | int node_num; | 493 | int node_num; |
420 | 494 | ||
@@ -429,6 +503,11 @@ int ocfs2_cluster_this_node(unsigned int *node) | |||
429 | return 0; | 503 | return 0; |
430 | } | 504 | } |
431 | 505 | ||
506 | int ocfs2_cluster_this_node(unsigned int *node) | ||
507 | { | ||
508 | return o2cb_cluster_this_node(node); | ||
509 | } | ||
510 | |||
432 | void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) | 511 | void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) |
433 | { | 512 | { |
434 | BUG_ON(proto != NULL); | 513 | BUG_ON(proto != NULL); |