--- initial
+++ final
@@ -1,124 +1,124 @@
 static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, struct dlm_lock *lock, struct dlm_lockstatus *lksb, int flags, int *call_ast, int master_node) {
   enum dlm_status status;
   int actions = 0;
   int in_use;
   u8 owner;
   mlog(0, "master_node = %d, valblk = %d\n", master_node, flags & LKM_VALBLK);
   if (master_node)
     BUG_ON(res->owner != dlm->node_num);
   else
     BUG_ON(res->owner == dlm->node_num);
   spin_lock(&dlm->ast_lock);
   /* We want to be sure that we're not freeing a lock
    * that still has AST's pending... */
   in_use = !list_empty(&lock->ast_list);
   spin_unlock(&dlm->ast_lock);
   if (in_use && !(flags & LKM_CANCEL)) {
     mlog(ML_ERROR,
          "lockres %.*s: Someone is calling dlmunlock "
          "while waiting for an ast!",
          res->lockname.len, res->lockname.name);
     return DLM_BADPARAM;
   }
   spin_lock(&res->spinlock);
   if (res->state & DLM_LOCK_RES_IN_PROGRESS) {
     if (master_node && !(flags & LKM_CANCEL)) {
       mlog(ML_ERROR, "lockres in progress!\n");
       spin_unlock(&res->spinlock);
       return DLM_FORWARD;
     }
     /* ok for this to sleep if not in a network handler */
     __dlm_wait_on_lockres(res);
     res->state |= DLM_LOCK_RES_IN_PROGRESS;
   }
   spin_lock(&lock->spinlock);
   if (res->state & DLM_LOCK_RES_RECOVERING) {
     status = DLM_RECOVERING;
     goto leave;
   }
   if (res->state & DLM_LOCK_RES_MIGRATING) {
     status = DLM_MIGRATING;
     goto leave;
   }
   /* see above for what the spec says about
    * LKM_CANCEL and the lock queue state */
   if (flags & LKM_CANCEL)
     status = dlm_get_cancel_actions(dlm, res, lock, lksb, &actions);
   else
     status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
   if (status != DLM_NORMAL && (status != DLM_CANCELGRANT || !master_node)) goto leave;
   /* By now this has been masked out of cancel requests. */
   if (flags & LKM_VALBLK) {
     /* make the final update to the lvb */
     if (master_node)
       memcpy(res->lvb, lksb->lvb, DLM_LVB_LEN);
     else
       flags |= LKM_PUT_LVB; /* let the send function
                              * handle it. */
   }
   if (!master_node) {
     owner = res->owner;
     /* drop locks and send message */
     if (flags & LKM_CANCEL)
       lock->cancel_pending = 1;
     else
       lock->unlock_pending = 1;
     spin_unlock(&lock->spinlock);
     spin_unlock(&res->spinlock);
     status = dlm_send_remote_unlock_request(dlm, res, lock, lksb, flags, owner);
     spin_lock(&res->spinlock);
     spin_lock(&lock->spinlock);
     /* if the master told us the lock was already granted,
      * let the ast handle all of these actions */
     if (status == DLM_CANCELGRANT) {
       actions &= ~(DLM_UNLOCK_REMOVE_LOCK | DLM_UNLOCK_REGRANT_LOCK | DLM_UNLOCK_CLEAR_CONVERT_TYPE);
     } else if (status == DLM_RECOVERING || status == DLM_MIGRATING || status == DLM_FORWARD || status == DLM_NOLOCKMGR) {
       /* must clear the actions because this unlock
        * is about to be retried.  cannot free or do
        * any list manipulation. */
       mlog(0, "%s:%.*s: clearing actions, %s\n", dlm->name, res->lockname.len, res->lockname.name, status == DLM_RECOVERING ? "recovering" : (status == DLM_MIGRATING ? "migrating" : (status == DLM_FORWARD ? "forward" : "nolockmanager")));
       actions = 0;
     }
     if (flags & LKM_CANCEL)
       lock->cancel_pending = 0;
     else
       lock->unlock_pending = 0;
   }
   /* get an extra ref on lock.  if we are just switching
    * lists here, we dont want the lock to go away. */
   dlm_lock_get(lock);
   if (actions & DLM_UNLOCK_REMOVE_LOCK) {
     list_del_init(&lock->list);
     dlm_lock_put(lock);
   }
   if (actions & DLM_UNLOCK_REGRANT_LOCK) {
     dlm_lock_get(lock);
     list_add_tail(&lock->list, &res->granted);
   }
   if (actions & DLM_UNLOCK_CLEAR_CONVERT_TYPE) {
     mlog(0, "clearing convert_type at %smaster node\n", master_node ? "" : "non-");
     lock->ml.convert_type = LKM_IVMODE;
   }
   /* remove the extra ref on lock */
   dlm_lock_put(lock);
 leave:
   res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
   if (!dlm_lock_on_list(&res->converting, lock))
     BUG_ON(lock->ml.convert_type != LKM_IVMODE);
   else
     BUG_ON(lock->ml.convert_type == LKM_IVMODE);
   spin_unlock(&lock->spinlock);
   spin_unlock(&res->spinlock);
   wake_up(&res->wq);
   /* let the caller's final dlm_lock_put handle the actual kfree */
   if (actions & DLM_UNLOCK_FREE_LOCK) {
     /* this should always be coupled with list removal */
     BUG_ON(!(actions & DLM_UNLOCK_REMOVE_LOCK));
-    mlog(0, "lock %u:%llu should be gone now! refs=%d\n", dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), atomic_read(&lock->lock_refs.refcount) - 1);
+    mlog(0, "lock %u:%llu should be gone now! refs=%d\n", dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), kref_read(&lock->lock_refs) - 1);
     dlm_lock_put(lock);
   }
   if (actions & DLM_UNLOCK_CALL_AST) *call_ast = 1;
   /* if cancel or unlock succeeded, lvb work is done */
   if (status == DLM_NORMAL) lksb->flags &= ~(DLM_LKSB_PUT_LVB | DLM_LKSB_GET_LVB);
   return status;
 }<sep>@@
expression e; 
@@
-               atomic_read(&e.refcount)
+               kref_read(&e)