Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140307
b: refs/heads/master
c: c2cd4a4
h: refs/heads/master
i:
  140305: b522fae
  140303: d2744ef
v: v3
  • Loading branch information
Sunil Mushran authored and Mark Fasheh committed Apr 3, 2009
1 parent d69de10 commit 4bd1480
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f77a9a78c3a1d995b3bf948dbcad5c4a1b2302d5
refs/heads/master: c2cd4a44333034203cb198915e2b75c3227d41bf
148 changes: 85 additions & 63 deletions trunk/fs/ocfs2/dlm/dlmmaster.c
Original file line number Diff line number Diff line change
Expand Up @@ -3207,12 +3207,87 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
return ret;
}

/*
* Sets the owner of the lockres, associated to the mle, to UNKNOWN
*/
static struct dlm_lock_resource *dlm_reset_mleres_owner(struct dlm_ctxt *dlm,
struct dlm_master_list_entry *mle)
{
struct dlm_lock_resource *res;
unsigned int hash;

/* Find the lockres associated to the mle and set its owner to UNK */
hash = dlm_lockid_hash(mle->u.mlename.name, mle->u.mlename.len);
res = __dlm_lookup_lockres(dlm, mle->u.mlename.name, mle->u.mlename.len,
hash);
if (res) {
spin_unlock(&dlm->master_lock);

/* move lockres onto recovery list */
spin_lock(&res->spinlock);
dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
dlm_move_lockres_to_recovery_list(dlm, res);
spin_unlock(&res->spinlock);
dlm_lockres_put(res);

/* about to get rid of mle, detach from heartbeat */
__dlm_mle_detach_hb_events(dlm, mle);

/* dump the mle */
spin_lock(&dlm->master_lock);
__dlm_put_mle(mle);
spin_unlock(&dlm->master_lock);
}

return res;
}

static void dlm_clean_migration_mle(struct dlm_ctxt *dlm,
struct dlm_master_list_entry *mle)
{
__dlm_mle_detach_hb_events(dlm, mle);

spin_lock(&mle->spinlock);
__dlm_unlink_mle(dlm, mle);
atomic_set(&mle->woken, 1);
spin_unlock(&mle->spinlock);

wake_up(&mle->wq);
}

static void dlm_clean_block_mle(struct dlm_ctxt *dlm,
struct dlm_master_list_entry *mle, u8 dead_node)
{
int bit;

BUG_ON(mle->type != DLM_MLE_BLOCK);

spin_lock(&mle->spinlock);
bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
if (bit != dead_node) {
mlog(0, "mle found, but dead node %u would not have been "
"master\n", dead_node);
spin_unlock(&mle->spinlock);
} else {
/* Must drop the refcount by one since the assert_master will
* never arrive. This may result in the mle being unlinked and
* freed, but there may still be a process waiting in the
* dlmlock path which is fine. */
mlog(0, "node %u was expected master\n", dead_node);
atomic_set(&mle->woken, 1);
spin_unlock(&mle->spinlock);
wake_up(&mle->wq);

/* Do not need events any longer, so detach from heartbeat */
__dlm_mle_detach_hb_events(dlm, mle);
__dlm_put_mle(mle);
}
}

void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
{
struct dlm_master_list_entry *mle, *next;
struct dlm_lock_resource *res;
unsigned int hash;

mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
top:
Expand All @@ -3236,30 +3311,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
* need to clean up if the dead node would have
* been the master. */
if (mle->type == DLM_MLE_BLOCK) {
int bit;

spin_lock(&mle->spinlock);
bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
if (bit != dead_node) {
mlog(0, "mle found, but dead node %u would "
"not have been master\n", dead_node);
spin_unlock(&mle->spinlock);
} else {
/* must drop the refcount by one since the
* assert_master will never arrive. this
* may result in the mle being unlinked and
* freed, but there may still be a process
* waiting in the dlmlock path which is fine. */
mlog(0, "node %u was expected master\n",
dead_node);
atomic_set(&mle->woken, 1);
spin_unlock(&mle->spinlock);
wake_up(&mle->wq);
/* do not need events any longer, so detach
* from heartbeat */
__dlm_mle_detach_hb_events(dlm, mle);
__dlm_put_mle(mle);
}
dlm_clean_block_mle(dlm, mle, dead_node);
continue;
}

Expand All @@ -3280,51 +3332,21 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)

/* if we have reached this point, this mle needs to
* be removed from the list and freed. */

/* remove from the list early. NOTE: unlinking
* list_head while in list_for_each_safe */
__dlm_mle_detach_hb_events(dlm, mle);
spin_lock(&mle->spinlock);
__dlm_unlink_mle(dlm, mle);
atomic_set(&mle->woken, 1);
spin_unlock(&mle->spinlock);
wake_up(&mle->wq);
dlm_clean_migration_mle(dlm, mle);

mlog(0, "%s: node %u died during migration from "
"%u to %u!\n", dlm->name, dead_node,
mle->master, mle->new_master);
/* if there is a lockres associated with this
* mle, find it and set its owner to UNKNOWN */
hash = dlm_lockid_hash(mle->u.mlename.name, mle->u.mlename.len);
res = __dlm_lookup_lockres(dlm, mle->u.mlename.name,
mle->u.mlename.len, hash);
if (res) {
/* unfortunately if we hit this rare case, our
* lock ordering is messed. we need to drop
* the master lock so that we can take the
* lockres lock, meaning that we will have to
* restart from the head of list. */
spin_unlock(&dlm->master_lock);

/* move lockres onto recovery list */
spin_lock(&res->spinlock);
dlm_set_lockres_owner(dlm, res,
DLM_LOCK_RES_OWNER_UNKNOWN);
dlm_move_lockres_to_recovery_list(dlm, res);
spin_unlock(&res->spinlock);
dlm_lockres_put(res);

/* about to get rid of mle, detach from heartbeat */
__dlm_mle_detach_hb_events(dlm, mle);

/* dump the mle */
spin_lock(&dlm->master_lock);
__dlm_put_mle(mle);
spin_unlock(&dlm->master_lock);

/* If we find a lockres associated with the mle, we've
* hit this rare case that messes up our lock ordering.
* If so, we need to drop the master lock so that we can
* take the lockres lock, meaning that we will have to
* restart from the head of list. */
res = dlm_reset_mleres_owner(dlm, mle);
if (res)
/* restart */
goto top;
}

/* this may be the last reference */
__dlm_put_mle(mle);
Expand Down

0 comments on commit 4bd1480

Please sign in to comment.