aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2011-05-19 17:34:09 -0400
committerJoel Becker <jlbec@evilplan.org>2011-05-24 02:37:39 -0400
commit9f62e96084cd7ae6dedcfb4caf066ed6cc67e0d7 (patch)
tree67a07e9c4ab93c72e1847ab0974cb601ce234251 /fs/ocfs2
parent10fca35ff12ad2a7017bce6567cffe9da443d7a2 (diff)
ocfs2/dlm: dlm_is_lockres_migrateable() returns boolean
Patch cleans up the gunk added by commit 388c4bcb4e63e88fb1f312a2f5f9eb2623afcf5b. dlm_is_lockres_migrateable() now returns 1 if lockresource is deemed migrateable and 0 if not. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Signed-off-by: Joel Becker <jlbec@evilplan.org>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h12
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c135
2 files changed, 63 insertions, 84 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 4bdf7baee344..1aac42a29745 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -401,6 +401,18 @@ static inline int dlm_lvb_is_empty(char *lvb)
401 return 1; 401 return 1;
402} 402}
403 403
404static inline char *dlm_list_in_text(enum dlm_lockres_list idx)
405{
406 if (idx == DLM_GRANTED_LIST)
407 return "granted";
408 else if (idx == DLM_CONVERTING_LIST)
409 return "converting";
410 else if (idx == DLM_BLOCKED_LIST)
411 return "blocked";
412 else
413 return "unknown";
414}
415
404static inline struct list_head * 416static inline struct list_head *
405dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx) 417dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx)
406{ 418{
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 84d166328cf7..ec4994628948 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2339,65 +2339,55 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
2339 dlm_lockres_put(res); 2339 dlm_lockres_put(res);
2340} 2340}
2341 2341
2342/* Checks whether the lockres can be migrated. Returns 0 if yes, < 0 2342/*
2343 * if not. If 0, numlocks is set to the number of locks in the lockres. 2343 * A migrateable resource is one that is :
2344 * 1. locally mastered, and,
2345 * 2. zero local locks, and,
2346 * 3. one or more non-local locks, or, one or more references
2347 * Returns 1 if yes, 0 if not.
2344 */ 2348 */
2345static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, 2349static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
2346 struct dlm_lock_resource *res, 2350 struct dlm_lock_resource *res)
2347 int *numlocks,
2348 int *hasrefs)
2349{ 2351{
2350 int ret; 2352 enum dlm_lockres_list idx;
2351 int i; 2353 int nonlocal = 0, node_ref;
2352 int count = 0;
2353 struct list_head *queue; 2354 struct list_head *queue;
2354 struct dlm_lock *lock; 2355 struct dlm_lock *lock;
2356 u64 cookie;
2355 2357
2356 assert_spin_locked(&res->spinlock); 2358 assert_spin_locked(&res->spinlock);
2357 2359
2358 *numlocks = 0; 2360 if (res->owner != dlm->node_num)
2359 *hasrefs = 0; 2361 return 0;
2360
2361 ret = -EINVAL;
2362 if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
2363 mlog(0, "cannot migrate lockres with unknown owner!\n");
2364 goto leave;
2365 }
2366
2367 if (res->owner != dlm->node_num) {
2368 mlog(0, "cannot migrate lockres this node doesn't own!\n");
2369 goto leave;
2370 }
2371 2362
2372 ret = 0; 2363 for (idx = DLM_GRANTED_LIST; idx <= DLM_BLOCKED_LIST; idx++) {
2373 queue = &res->granted; 2364 queue = dlm_list_idx_to_ptr(res, idx);
2374 for (i = 0; i < 3; i++) {
2375 list_for_each_entry(lock, queue, list) { 2365 list_for_each_entry(lock, queue, list) {
2376 ++count; 2366 if (lock->ml.node != dlm->node_num) {
2377 if (lock->ml.node == dlm->node_num) { 2367 nonlocal++;
2378 mlog(0, "found a lock owned by this node still " 2368 continue;
2379 "on the %s queue! will not migrate this "
2380 "lockres\n", (i == 0 ? "granted" :
2381 (i == 1 ? "converting" :
2382 "blocked")));
2383 ret = -ENOTEMPTY;
2384 goto leave;
2385 } 2369 }
2370 cookie = be64_to_cpu(lock->ml.cookie);
2371 mlog(0, "%s: Not migrateable res %.*s, lock %u:%llu on "
2372 "%s list\n", dlm->name, res->lockname.len,
2373 res->lockname.name,
2374 dlm_get_lock_cookie_node(cookie),
2375 dlm_get_lock_cookie_seq(cookie),
2376 dlm_list_in_text(idx));
2377 return 0;
2386 } 2378 }
2387 queue++;
2388 } 2379 }
2389 2380
2390 *numlocks = count; 2381 if (!nonlocal) {
2391 2382 node_ref = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
2392 count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); 2383 if (node_ref >= O2NM_MAX_NODES)
2393 if (count < O2NM_MAX_NODES) 2384 return 0;
2394 *hasrefs = 1; 2385 }
2395 2386
2396 mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name, 2387 mlog(0, "%s: res %.*s, Migrateable\n", dlm->name, res->lockname.len,
2397 res->lockname.len, res->lockname.name, *numlocks, *hasrefs); 2388 res->lockname.name);
2398 2389
2399leave: 2390 return 1;
2400 return ret;
2401} 2391}
2402 2392
2403/* 2393/*
@@ -2416,7 +2406,6 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
2416 const char *name; 2406 const char *name;
2417 unsigned int namelen; 2407 unsigned int namelen;
2418 int mle_added = 0; 2408 int mle_added = 0;
2419 int numlocks, hasrefs;
2420 int wake = 0; 2409 int wake = 0;
2421 2410
2422 if (!dlm_grab(dlm)) 2411 if (!dlm_grab(dlm))
@@ -2427,19 +2416,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
2427 2416
2428 mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target); 2417 mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target);
2429 2418
2430 /* 2419 /* Ensure this lockres is a proper candidate for migration */
2431 * ensure this lockres is a proper candidate for migration
2432 */
2433 spin_lock(&res->spinlock); 2420 spin_lock(&res->spinlock);
2434 ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); 2421 ret = dlm_is_lockres_migrateable(dlm, res);
2435 if (ret < 0) {
2436 spin_unlock(&res->spinlock);
2437 goto leave;
2438 }
2439 spin_unlock(&res->spinlock); 2422 spin_unlock(&res->spinlock);
2440 2423
2441 /* no work to do */ 2424 /* No work to do */
2442 if (numlocks == 0 && !hasrefs) 2425 if (!ret)
2443 goto leave; 2426 goto leave;
2444 2427
2445 /* 2428 /*
@@ -2658,44 +2641,35 @@ leave:
2658 2641
2659 dlm_put(dlm); 2642 dlm_put(dlm);
2660 2643
2661 mlog(0, "returning %d\n", ret); 2644 mlog(0, "%s: Migrating %.*s to %u, returns %d\n", dlm->name, namelen,
2645 name, target, ret);
2662 return ret; 2646 return ret;
2663} 2647}
2664 2648
2665#define DLM_MIGRATION_RETRY_MS 100 2649#define DLM_MIGRATION_RETRY_MS 100
2666 2650
2667/* Should be called only after beginning the domain leave process. 2651/*
2652 * Should be called only after beginning the domain leave process.
2668 * There should not be any remaining locks on nonlocal lock resources, 2653 * There should not be any remaining locks on nonlocal lock resources,
2669 * and there should be no local locks left on locally mastered resources. 2654 * and there should be no local locks left on locally mastered resources.
2670 * 2655 *
2671 * Called with the dlm spinlock held, may drop it to do migration, but 2656 * Called with the dlm spinlock held, may drop it to do migration, but
2672 * will re-acquire before exit. 2657 * will re-acquire before exit.
2673 * 2658 *
2674 * Returns: 1 if dlm->spinlock was dropped/retaken, 0 if never dropped */ 2659 * Returns: 1 if dlm->spinlock was dropped/retaken, 0 if never dropped
2660 */
2675int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) 2661int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
2676{ 2662{
2677 int ret; 2663 int mig, ret;
2678 int lock_dropped = 0; 2664 int lock_dropped = 0;
2679 int numlocks, hasrefs;
2680 2665
2681 spin_lock(&res->spinlock); 2666 assert_spin_locked(&dlm->spinlock);
2682 if (res->owner != dlm->node_num) {
2683 if (!__dlm_lockres_unused(res)) {
2684 mlog(ML_ERROR, "%s:%.*s: this node is not master, "
2685 "trying to free this but locks remain\n",
2686 dlm->name, res->lockname.len, res->lockname.name);
2687 }
2688 spin_unlock(&res->spinlock);
2689 goto leave;
2690 }
2691 2667
2692 /* No need to migrate a lockres having no locks */ 2668 spin_lock(&res->spinlock);
2693 ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); 2669 mig = dlm_is_lockres_migrateable(dlm, res);
2694 if (ret >= 0 && numlocks == 0 && !hasrefs) {
2695 spin_unlock(&res->spinlock);
2696 goto leave;
2697 }
2698 spin_unlock(&res->spinlock); 2670 spin_unlock(&res->spinlock);
2671 if (!mig)
2672 goto leave;
2699 2673
2700 /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ 2674 /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */
2701 spin_unlock(&dlm->spinlock); 2675 spin_unlock(&dlm->spinlock);
@@ -2704,15 +2678,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
2704 ret = dlm_migrate_lockres(dlm, res, O2NM_MAX_NODES); 2678 ret = dlm_migrate_lockres(dlm, res, O2NM_MAX_NODES);
2705 if (ret >= 0) 2679 if (ret >= 0)
2706 break; 2680 break;
2707 if (ret == -ENOTEMPTY) { 2681 mlog(0, "%s: res %.*s, Migrate failed, retrying\n", dlm->name,
2708 mlog(ML_ERROR, "lockres %.*s still has local locks!\n", 2682 res->lockname.len, res->lockname.name);
2709 res->lockname.len, res->lockname.name);
2710 BUG();
2711 }
2712
2713 mlog(0, "lockres %.*s: migrate failed, "
2714 "retrying\n", res->lockname.len,
2715 res->lockname.name);
2716 msleep(DLM_MIGRATION_RETRY_MS); 2683 msleep(DLM_MIGRATION_RETRY_MS);
2717 } 2684 }
2718 spin_lock(&dlm->spinlock); 2685 spin_lock(&dlm->spinlock);