aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlmglue.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-02-01 17:39:35 -0500
committerMark Fasheh <mfasheh@suse.com>2008-04-18 11:56:04 -0400
commit4670c46ded9a18268d1265417ff4ac72145a7917 (patch)
tree4f70822ddee389a9c8ed572b215a3355c20db3a1 /fs/ocfs2/dlmglue.c
parent8f2c9c1b16bf6ed0903b29c49d56fa0109a390e4 (diff)
ocfs2: Introduce the new ocfs2_cluster_connect/disconnect() API.
This step introduces a cluster stack agnostic API for initializing and exiting. fs/ocfs2/dlmglue.c no longer uses o2cb/o2dlm knowledge to connect to the stack. It is all handled in stackglue.c. heartbeat.c no longer needs to know how it gets called. ocfs2_do_node_down() is now a clean recovery trigger. The big gotcha is the ordering of initializations and de-initializations done underneath ocfs2_cluster_connect(). ocfs2_dlm_init() used to do all o2dlm initialization in one block. Thus, the o2dlm functionality of ocfs2_cluster_connect() is very straightforward. ocfs2_dlm_shutdown(), however, did a few things between de-registration of the eviction callback and actually shutting down the domain. Now de-registration and shutdown of the domain are wrapped within the single ocfs2_cluster_disconnect() call. I've checked the code paths to make sure we can safely tear down things in ocfs2_dlm_shutdown() before calling ocfs2_cluster_disconnect(). The filesystem has already set itself to ignore the callback. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r--fs/ocfs2/dlmglue.c97
1 files changed, 48 insertions, 49 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 459037653e5a..6652a48cbe0f 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -27,7 +27,6 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/highmem.h> 28#include <linux/highmem.h>
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/crc32.h>
31#include <linux/kthread.h> 30#include <linux/kthread.h>
32#include <linux/pagemap.h> 31#include <linux/pagemap.h>
33#include <linux/debugfs.h> 32#include <linux/debugfs.h>
@@ -259,31 +258,6 @@ static struct ocfs2_lock_res_ops ocfs2_flock_lops = {
259 .flags = 0, 258 .flags = 0,
260}; 259};
261 260
262/*
263 * This is the filesystem locking protocol version.
264 *
265 * Whenever the filesystem does new things with locks (adds or removes a
266 * lock, orders them differently, does different things underneath a lock),
267 * the version must be changed. The protocol is negotiated when joining
268 * the dlm domain. A node may join the domain if its major version is
269 * identical to all other nodes and its minor version is greater than
270 * or equal to all other nodes. When its minor version is greater than
271 * the other nodes, it will run at the minor version specified by the
272 * other nodes.
273 *
274 * If a locking change is made that will not be compatible with older
275 * versions, the major number must be increased and the minor version set
276 * to zero. If a change merely adds a behavior that can be disabled when
277 * speaking to older versions, the minor version must be increased. If a
278 * change adds a fully backwards compatible change (eg, LVB changes that
279 * are just ignored by older versions), the version does not need to be
280 * updated.
281 */
282const struct dlm_protocol_version ocfs2_locking_protocol = {
283 .pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
284 .pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
285};
286
287static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) 261static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
288{ 262{
289 return lockres->l_type == OCFS2_LOCK_TYPE_META || 263 return lockres->l_type == OCFS2_LOCK_TYPE_META ||
@@ -886,7 +860,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
886 lockres_or_flags(lockres, OCFS2_LOCK_BUSY); 860 lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
887 spin_unlock_irqrestore(&lockres->l_lock, flags); 861 spin_unlock_irqrestore(&lockres->l_lock, flags);
888 862
889 ret = ocfs2_dlm_lock(osb->dlm, 863 ret = ocfs2_dlm_lock(osb->cconn,
890 level, 864 level,
891 &lockres->l_lksb, 865 &lockres->l_lksb,
892 dlm_flags, 866 dlm_flags,
@@ -1085,7 +1059,7 @@ again:
1085 lockres->l_name, lockres->l_level, level); 1059 lockres->l_name, lockres->l_level, level);
1086 1060
1087 /* call dlm_lock to upgrade lock now */ 1061 /* call dlm_lock to upgrade lock now */
1088 ret = ocfs2_dlm_lock(osb->dlm, 1062 ret = ocfs2_dlm_lock(osb->cconn,
1089 level, 1063 level,
1090 &lockres->l_lksb, 1064 &lockres->l_lksb,
1091 lkm_flags, 1065 lkm_flags,
@@ -1492,7 +1466,7 @@ int ocfs2_file_lock(struct file *file, int ex, int trylock)
1492 lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BUSY, 0); 1466 lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BUSY, 0);
1493 spin_unlock_irqrestore(&lockres->l_lock, flags); 1467 spin_unlock_irqrestore(&lockres->l_lock, flags);
1494 1468
1495 ret = ocfs2_dlm_lock(osb->dlm, level, &lockres->l_lksb, lkm_flags, 1469 ret = ocfs2_dlm_lock(osb->cconn, level, &lockres->l_lksb, lkm_flags,
1496 lockres->l_name, OCFS2_LOCK_ID_MAX_LEN - 1, 1470 lockres->l_name, OCFS2_LOCK_ID_MAX_LEN - 1,
1497 lockres); 1471 lockres);
1498 if (ret) { 1472 if (ret) {
@@ -2485,8 +2459,7 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
2485int ocfs2_dlm_init(struct ocfs2_super *osb) 2459int ocfs2_dlm_init(struct ocfs2_super *osb)
2486{ 2460{
2487 int status = 0; 2461 int status = 0;
2488 u32 dlm_key; 2462 struct ocfs2_cluster_connection *conn = NULL;
2489 struct dlm_ctxt *dlm = NULL;
2490 2463
2491 mlog_entry_void(); 2464 mlog_entry_void();
2492 2465
@@ -2508,26 +2481,21 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
2508 goto bail; 2481 goto bail;
2509 } 2482 }
2510 2483
2511 /* used by the dlm code to make message headers unique, each
2512 * node in this domain must agree on this. */
2513 dlm_key = crc32_le(0, osb->uuid_str, strlen(osb->uuid_str));
2514
2515 /* for now, uuid == domain */ 2484 /* for now, uuid == domain */
2516 dlm = dlm_register_domain(osb->uuid_str, dlm_key, 2485 status = ocfs2_cluster_connect(osb->uuid_str,
2517 &osb->osb_locking_proto); 2486 strlen(osb->uuid_str),
2518 if (IS_ERR(dlm)) { 2487 ocfs2_do_node_down, osb,
2519 status = PTR_ERR(dlm); 2488 &conn);
2489 if (status) {
2520 mlog_errno(status); 2490 mlog_errno(status);
2521 goto bail; 2491 goto bail;
2522 } 2492 }
2523 2493
2524 dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
2525
2526local: 2494local:
2527 ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb); 2495 ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
2528 ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb); 2496 ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
2529 2497
2530 osb->dlm = dlm; 2498 osb->cconn = conn;
2531 2499
2532 status = 0; 2500 status = 0;
2533bail: 2501bail:
@@ -2545,10 +2513,14 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb)
2545{ 2513{
2546 mlog_entry_void(); 2514 mlog_entry_void();
2547 2515
2548 dlm_unregister_eviction_cb(&osb->osb_eviction_cb);
2549
2550 ocfs2_drop_osb_locks(osb); 2516 ocfs2_drop_osb_locks(osb);
2551 2517
2518 /*
2519 * Now that we have dropped all locks and ocfs2_dismount_volume()
2520 * has disabled recovery, the DLM won't be talking to us. It's
2521 * safe to tear things down before disconnecting the cluster.
2522 */
2523
2552 if (osb->dc_task) { 2524 if (osb->dc_task) {
2553 kthread_stop(osb->dc_task); 2525 kthread_stop(osb->dc_task);
2554 osb->dc_task = NULL; 2526 osb->dc_task = NULL;
@@ -2557,8 +2529,8 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb)
2557 ocfs2_lock_res_free(&osb->osb_super_lockres); 2529 ocfs2_lock_res_free(&osb->osb_super_lockres);
2558 ocfs2_lock_res_free(&osb->osb_rename_lockres); 2530 ocfs2_lock_res_free(&osb->osb_rename_lockres);
2559 2531
2560 dlm_unregister_domain(osb->dlm); 2532 ocfs2_cluster_disconnect(osb->cconn);
2561 osb->dlm = NULL; 2533 osb->cconn = NULL;
2562 2534
2563 ocfs2_dlm_shutdown_debug(osb); 2535 ocfs2_dlm_shutdown_debug(osb);
2564 2536
@@ -2689,7 +2661,7 @@ static int ocfs2_drop_lock(struct ocfs2_super *osb,
2689 2661
2690 mlog(0, "lock %s\n", lockres->l_name); 2662 mlog(0, "lock %s\n", lockres->l_name);
2691 2663
2692 ret = ocfs2_dlm_unlock(osb->dlm, &lockres->l_lksb, lkm_flags, 2664 ret = ocfs2_dlm_unlock(osb->cconn, &lockres->l_lksb, lkm_flags,
2693 lockres); 2665 lockres);
2694 if (ret) { 2666 if (ret) {
2695 ocfs2_log_dlm_error("ocfs2_dlm_unlock", ret, lockres); 2667 ocfs2_log_dlm_error("ocfs2_dlm_unlock", ret, lockres);
@@ -2823,7 +2795,7 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
2823 if (lvb) 2795 if (lvb)
2824 dlm_flags |= DLM_LKF_VALBLK; 2796 dlm_flags |= DLM_LKF_VALBLK;
2825 2797
2826 ret = ocfs2_dlm_lock(osb->dlm, 2798 ret = ocfs2_dlm_lock(osb->cconn,
2827 new_level, 2799 new_level,
2828 &lockres->l_lksb, 2800 &lockres->l_lksb,
2829 dlm_flags, 2801 dlm_flags,
@@ -2882,7 +2854,7 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb,
2882 mlog_entry_void(); 2854 mlog_entry_void();
2883 mlog(0, "lock %s\n", lockres->l_name); 2855 mlog(0, "lock %s\n", lockres->l_name);
2884 2856
2885 ret = ocfs2_dlm_unlock(osb->dlm, &lockres->l_lksb, 2857 ret = ocfs2_dlm_unlock(osb->cconn, &lockres->l_lksb,
2886 DLM_LKF_CANCEL, lockres); 2858 DLM_LKF_CANCEL, lockres);
2887 if (ret) { 2859 if (ret) {
2888 ocfs2_log_dlm_error("ocfs2_dlm_unlock", ret, lockres); 2860 ocfs2_log_dlm_error("ocfs2_dlm_unlock", ret, lockres);
@@ -3193,7 +3165,34 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres,
3193 return UNBLOCK_CONTINUE_POST; 3165 return UNBLOCK_CONTINUE_POST;
3194} 3166}
3195 3167
3168/*
3169 * This is the filesystem locking protocol. It provides the lock handling
3170 * hooks for the underlying DLM. It has a maximum version number.
3171 * The version number allows interoperability with systems running at
3172 * the same major number and an equal or smaller minor number.
3173 *
3174 * Whenever the filesystem does new things with locks (adds or removes a
3175 * lock, orders them differently, does different things underneath a lock),
3176 * the version must be changed. The protocol is negotiated when joining
3177 * the dlm domain. A node may join the domain if its major version is
3178 * identical to all other nodes and its minor version is greater than
3179 * or equal to all other nodes. When its minor version is greater than
3180 * the other nodes, it will run at the minor version specified by the
3181 * other nodes.
3182 *
3183 * If a locking change is made that will not be compatible with older
3184 * versions, the major number must be increased and the minor version set
3185 * to zero. If a change merely adds a behavior that can be disabled when
3186 * speaking to older versions, the minor version must be increased. If a
3187 * change adds a fully backwards compatible change (eg, LVB changes that
3188 * are just ignored by older versions), the version does not need to be
3189 * updated.
3190 */
3196static struct ocfs2_locking_protocol lproto = { 3191static struct ocfs2_locking_protocol lproto = {
3192 .lp_max_version = {
3193 .pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
3194 .pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
3195 },
3197 .lp_lock_ast = ocfs2_locking_ast, 3196 .lp_lock_ast = ocfs2_locking_ast,
3198 .lp_blocking_ast = ocfs2_blocking_ast, 3197 .lp_blocking_ast = ocfs2_blocking_ast,
3199 .lp_unlock_ast = ocfs2_unlock_ast, 3198 .lp_unlock_ast = ocfs2_unlock_ast,