[Ocfs2-devel] [PATCH] o2dlm: check lockres validity in createlock
Wengang Wang
wen.gang.wang at oracle.com
Tue May 10 21:52:18 PDT 2011
Sorry,
the ML_NOTICE log is for debugging purpose and should be removed.
thanks,
wengang.
On 11-05-11 07:47, Wengang Wang wrote:
> When we are to purge a lockres, we check if it's unused.
> the check includes
> 1. no locks attached to the lockres.
> 2. not dirty.
> 3. not in recovery.
> 4. no interested nodes in refmap.
> If the the above four are satisfied, we are going to purge it(remove it
> from hash table).
>
> While, when a "create lock" is in progress especially when lockres is owned
> remotely(spinlocks are dropped when networking), the lockres can satisfy above
> four condition. If it's put to purge list, it can be purged out from hash table
> when we are still accessing on it(sending request to owner for example). That's
> not what we want.
>
> I have met such a problem (orabug 12405575).
> The lockres is in the purge list already(there is a delay for real purge work)
> and the create lock request comes. When we are sending network message to the
> owner in dlmlock_remote(), the owner crashed. So we get DLM_RECOVERING as return
> value and retries dlmlock_remote(). And before the owner crash, we have purged
> the lockres. So the lockres become stale(on lockres->onwer). Thus the code calls
> dlmlock_remote() infinitely.
>
> fix 1
> This patch tries to fix it by checking if the lockres is still valid(in hash table)
> before make request on it for each retry. It passed regression test.
>
> fix 2
> Another approch(not in this patch) is that we remove the lockres from purge list if
> it's there in dlm_get_lock_resource() which is called for only createlock case. So
> that the lockres can't be purged when we are in progress of createlock.
> I didn't test it.
>
> I think fix 1 is the safer and fix 2 is the better. I choosed fix 1.
>
> Sunil, what's your comment?
>
> Signed-off-by: Wengang Wang <wen.gang.wang at oracle.com>
> ---
> fs/ocfs2/dlm/dlmlock.c | 28 ++++++++++++++++++++++++++++
> 1 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
> index 8d39e0f..02abaa1 100644
> --- a/fs/ocfs2/dlm/dlmlock.c
> +++ b/fs/ocfs2/dlm/dlmlock.c
> @@ -570,6 +570,7 @@ enum dlm_status dlmlock(struct dlm_ctxt *dlm, int mode,
> struct dlm_lock_resource *res = NULL;
> struct dlm_lock *lock = NULL;
> int convert = 0, recovery = 0;
> + bool lockres_purged = false;
>
> /* yes this function is a mess.
> * TODO: clean this up. lots of common code in the
> @@ -681,6 +682,7 @@ retry_convert:
> if (!recovery)
> dlm_wait_for_recovery(dlm);
>
> +lookup_res:
> /* find or create the lock resource */
> res = dlm_get_lock_resource(dlm, name, namelen, flags);
> if (!res) {
> @@ -698,6 +700,32 @@ retry_convert:
> lock->astdata = data;
>
> retry_lock:
> + /* there is a chance that the lockres is already be purged out
> + * from the hash table and it can become a stale one. obviously
> + * accessing on a stale lockres is not what we want. the case
> + * we ever see is the owner dead(recovery didn't take care of
> + * this lockres since it's not in hashtable), and the code keep
> + * sending request to the dead node and getting DLM_RECOVERING
> + * and then retrying infinitely.
> + * we check if the lockres has been purged here and redo the
> + * lookup if it has been to avoid infinite loop.
> + */
> + lockres_purged = false;
> + spin_lock(&dlm->spinlock);
> + spin_lock(&res->spinlock);
> + if (unlikely(hlist_unhashed(&res->hash_node))) {
> + lockres_purged = true;
> + }
> + spin_unlock(&res->spinlock);
> + spin_unlock(&dlm->spinlock);
> + if (lockres_purged) {
> + dlm_lock_detach_lockres(lock);
> + mlog(ML_NOTICE, "going to relookup lockres %.*s\n", res->lockname.len, res->lockname.name);
> + dlm_lockres_put(res);
> + res = NULL;
> + goto lookup_res;
> + }
> +
> if (flags & LKM_VALBLK) {
> mlog(0, "LKM_VALBLK passed by caller\n");
>
> --
> 1.7.2.3
>
>
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel at oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel
More information about the Ocfs2-devel
mailing list