Commit 8322b6fd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dlm update from David Teigland:
 "This set includes one feature, which allows locks that have been
  orphaned to be reacquired"

* tag 'dlm-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
  dlm: adopt orphan locks
parents 1366f5d3 2ab4bd8e
Loading
Loading
Loading
Loading
+74 −2
Original line number Diff line number Diff line
@@ -5886,6 +5886,78 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
	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,
		    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;
	int error;

	hold_lkb(lkb);
	hold_lkb(lkb); /* reference for the ls_orphans list */
	mutex_lock(&ls->ls_orphans_mutex);
	list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
	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;

	if (nodeid != dlm_our_nodeid()) {
	if (nodeid && (nodeid != dlm_our_nodeid())) {
		error = send_purge(ls, nodeid, pid);
	} else {
		dlm_lock_recovery(ls);
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
	int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
	unsigned long timeout_cs);
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);
int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
	uint32_t flags, uint32_t lkid, char *lvb_in);
int dlm_user_cancel(struct dlm_ls *ls,  struct dlm_user_args *ua_tmp,
+11 −2
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ static int device_user_lock(struct dlm_user_proc *proc,
{
	struct dlm_ls *ls;
	struct dlm_user_args *ua;
	uint32_t lkid;
	int error = -ENOMEM;

	ls = dlm_find_lockspace_local(proc->lockspace);
@@ -260,12 +261,20 @@ static int device_user_lock(struct dlm_user_proc *proc,
	ua->bastaddr = params->bastaddr;
	ua->xid = params->xid;

	if (params->flags & DLM_LKF_CONVERT)
	if (params->flags & DLM_LKF_CONVERT) {
		error = dlm_user_convert(ls, ua,
				         params->mode, params->flags,
				         params->lkid, params->lvb,
					 (unsigned long) params->timeout);
	else {
	} else if (params->flags & DLM_LKF_ORPHAN) {
		error = dlm_user_adopt_orphan(ls, ua,
					 params->mode, params->flags,
					 params->name, params->namelen,
					 (unsigned long) params->timeout,
					 &lkid);
		if (!error)
			error = lkid;
	} else {
		error = dlm_user_request(ls, ua,
					 params->mode, params->flags,
					 params->name, params->namelen,
+1 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@
 *
 * DLM_LKF_ORPHAN
 *
 * not yet implemented
 * Acquire an orphan lock.
 *
 * DLM_LKF_ALTPR
 *