Skip to content

Commit

Permalink
Merge tag 'dlm-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/teigland/linux-dlm

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
  • Loading branch information
torvalds committed Dec 11, 2014
2 parents 1366f5d + 2ab4bd8 commit 8322b6f
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 5 deletions.
76 changes: 74 additions & 2 deletions fs/dlm/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions fs/dlm/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 11 additions & 2 deletions fs/dlm/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion include/uapi/linux/dlmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
*
* DLM_LKF_ORPHAN
*
* not yet implemented
* Acquire an orphan lock.
*
* DLM_LKF_ALTPR
*
Expand Down

0 comments on commit 8322b6f

Please sign in to comment.