|
@@ -5886,6 +5886,78 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * The caller asks for an orphan lock on a given resource with a given mode.
|
|
|
|
+ * If a matching lock exists, it's moved to the owner's list of locks and
|
|
|
|
+ * the lkid is returned.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|
|
|
+ int mode, uint32_t flags, void *name, unsigned int namelen,
|
|
|
|
+ unsigned long timeout_cs, uint32_t *lkid)
|
|
|
|
+{
|
|
|
|
+ struct dlm_lkb *lkb;
|
|
|
|
+ struct dlm_user_args *ua;
|
|
|
|
+ int found_other_mode = 0;
|
|
|
|
+ int found = 0;
|
|
|
|
+ int rv = 0;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&ls->ls_orphans_mutex);
|
|
|
|
+ list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) {
|
|
|
|
+ if (lkb->lkb_resource->res_length != namelen)
|
|
|
|
+ continue;
|
|
|
|
+ if (memcmp(lkb->lkb_resource->res_name, name, namelen))
|
|
|
|
+ continue;
|
|
|
|
+ if (lkb->lkb_grmode != mode) {
|
|
|
|
+ found_other_mode = 1;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ found = 1;
|
|
|
|
+ list_del_init(&lkb->lkb_ownqueue);
|
|
|
|
+ lkb->lkb_flags &= ~DLM_IFL_ORPHAN;
|
|
|
|
+ *lkid = lkb->lkb_id;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ mutex_unlock(&ls->ls_orphans_mutex);
|
|
|
|
+
|
|
|
|
+ if (!found && found_other_mode) {
|
|
|
|
+ rv = -EAGAIN;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!found) {
|
|
|
|
+ rv = -ENOENT;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lkb->lkb_exflags = flags;
|
|
|
|
+ lkb->lkb_ownpid = (int) current->pid;
|
|
|
|
+
|
|
|
|
+ ua = lkb->lkb_ua;
|
|
|
|
+
|
|
|
|
+ ua->proc = ua_tmp->proc;
|
|
|
|
+ ua->xid = ua_tmp->xid;
|
|
|
|
+ ua->castparam = ua_tmp->castparam;
|
|
|
|
+ ua->castaddr = ua_tmp->castaddr;
|
|
|
|
+ ua->bastparam = ua_tmp->bastparam;
|
|
|
|
+ ua->bastaddr = ua_tmp->bastaddr;
|
|
|
|
+ ua->user_lksb = ua_tmp->user_lksb;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The lkb reference from the ls_orphans list was not
|
|
|
|
+ * removed above, and is now considered the reference
|
|
|
|
+ * for the proc locks list.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ spin_lock(&ua->proc->locks_spin);
|
|
|
|
+ list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
|
|
|
|
+ spin_unlock(&ua->proc->locks_spin);
|
|
|
|
+ out:
|
|
|
|
+ kfree(ua_tmp);
|
|
|
|
+ return rv;
|
|
|
|
+}
|
|
|
|
+
|
|
int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|
int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|
uint32_t flags, uint32_t lkid, char *lvb_in)
|
|
uint32_t flags, uint32_t lkid, char *lvb_in)
|
|
{
|
|
{
|
|
@@ -6029,7 +6101,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
|
struct dlm_args args;
|
|
struct dlm_args args;
|
|
int error;
|
|
int error;
|
|
|
|
|
|
- hold_lkb(lkb);
|
|
|
|
|
|
+ hold_lkb(lkb); /* reference for the ls_orphans list */
|
|
mutex_lock(&ls->ls_orphans_mutex);
|
|
mutex_lock(&ls->ls_orphans_mutex);
|
|
list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
|
|
list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
|
|
mutex_unlock(&ls->ls_orphans_mutex);
|
|
mutex_unlock(&ls->ls_orphans_mutex);
|
|
@@ -6217,7 +6289,7 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
|
|
{
|
|
{
|
|
int error = 0;
|
|
int error = 0;
|
|
|
|
|
|
- if (nodeid != dlm_our_nodeid()) {
|
|
|
|
|
|
+ if (nodeid && (nodeid != dlm_our_nodeid())) {
|
|
error = send_purge(ls, nodeid, pid);
|
|
error = send_purge(ls, nodeid, pid);
|
|
} else {
|
|
} else {
|
|
dlm_lock_recovery(ls);
|
|
dlm_lock_recovery(ls);
|