aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dlm/lock.c76
-rw-r--r--fs/dlm/lock.h3
-rw-r--r--fs/dlm/user.c13
-rw-r--r--include/uapi/linux/dlmconstants.h2
4 files changed, 89 insertions, 5 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 83f3d5520307..35502d4046f5 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -5886,6 +5886,78 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
5886 return error; 5886 return error;
5887} 5887}
5888 5888
5889/*
5890 * The caller asks for an orphan lock on a given resource with a given mode.
5891 * If a matching lock exists, it's moved to the owner's list of locks and
5892 * the lkid is returned.
5893 */
5894
5895int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
5896 int mode, uint32_t flags, void *name, unsigned int namelen,
5897 unsigned long timeout_cs, uint32_t *lkid)
5898{
5899 struct dlm_lkb *lkb;
5900 struct dlm_user_args *ua;
5901 int found_other_mode = 0;
5902 int found = 0;
5903 int rv = 0;
5904
5905 mutex_lock(&ls->ls_orphans_mutex);
5906 list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) {
5907 if (lkb->lkb_resource->res_length != namelen)
5908 continue;
5909 if (memcmp(lkb->lkb_resource->res_name, name, namelen))
5910 continue;
5911 if (lkb->lkb_grmode != mode) {
5912 found_other_mode = 1;
5913 continue;
5914 }
5915
5916 found = 1;
5917 list_del_init(&lkb->lkb_ownqueue);
5918 lkb->lkb_flags &= ~DLM_IFL_ORPHAN;
5919 *lkid = lkb->lkb_id;
5920 break;
5921 }
5922 mutex_unlock(&ls->ls_orphans_mutex);
5923
5924 if (!found && found_other_mode) {
5925 rv = -EAGAIN;
5926 goto out;
5927 }
5928
5929 if (!found) {
5930 rv = -ENOENT;
5931 goto out;
5932 }
5933
5934 lkb->lkb_exflags = flags;
5935 lkb->lkb_ownpid = (int) current->pid;
5936
5937 ua = lkb->lkb_ua;
5938
5939 ua->proc = ua_tmp->proc;
5940 ua->xid = ua_tmp->xid;
5941 ua->castparam = ua_tmp->castparam;
5942 ua->castaddr = ua_tmp->castaddr;
5943 ua->bastparam = ua_tmp->bastparam;
5944 ua->bastaddr = ua_tmp->bastaddr;
5945 ua->user_lksb = ua_tmp->user_lksb;
5946
5947 /*
5948 * The lkb reference from the ls_orphans list was not
5949 * removed above, and is now considered the reference
5950 * for the proc locks list.
5951 */
5952
5953 spin_lock(&ua->proc->locks_spin);
5954 list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
5955 spin_unlock(&ua->proc->locks_spin);
5956 out:
5957 kfree(ua_tmp);
5958 return rv;
5959}
5960
5889int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 5961int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
5890 uint32_t flags, uint32_t lkid, char *lvb_in) 5962 uint32_t flags, uint32_t lkid, char *lvb_in)
5891{ 5963{
@@ -6029,7 +6101,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
6029 struct dlm_args args; 6101 struct dlm_args args;
6030 int error; 6102 int error;
6031 6103
6032 hold_lkb(lkb); 6104 hold_lkb(lkb); /* reference for the ls_orphans list */
6033 mutex_lock(&ls->ls_orphans_mutex); 6105 mutex_lock(&ls->ls_orphans_mutex);
6034 list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); 6106 list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
6035 mutex_unlock(&ls->ls_orphans_mutex); 6107 mutex_unlock(&ls->ls_orphans_mutex);
@@ -6217,7 +6289,7 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
6217{ 6289{
6218 int error = 0; 6290 int error = 0;
6219 6291
6220 if (nodeid != dlm_our_nodeid()) { 6292 if (nodeid && (nodeid != dlm_our_nodeid())) {
6221 error = send_purge(ls, nodeid, pid); 6293 error = send_purge(ls, nodeid, pid);
6222 } else { 6294 } else {
6223 dlm_lock_recovery(ls); 6295 dlm_lock_recovery(ls);
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 5e0c72e36a9b..ed8ebd3a8593 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -49,6 +49,9 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
49int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 49int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
50 int mode, uint32_t flags, uint32_t lkid, char *lvb_in, 50 int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
51 unsigned long timeout_cs); 51 unsigned long timeout_cs);
52int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
53 int mode, uint32_t flags, void *name, unsigned int namelen,
54 unsigned long timeout_cs, uint32_t *lkid);
52int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 55int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
53 uint32_t flags, uint32_t lkid, char *lvb_in); 56 uint32_t flags, uint32_t lkid, char *lvb_in);
54int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 57int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 142e21655eed..fb85f32e9eca 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -238,6 +238,7 @@ static int device_user_lock(struct dlm_user_proc *proc,
238{ 238{
239 struct dlm_ls *ls; 239 struct dlm_ls *ls;
240 struct dlm_user_args *ua; 240 struct dlm_user_args *ua;
241 uint32_t lkid;
241 int error = -ENOMEM; 242 int error = -ENOMEM;
242 243
243 ls = dlm_find_lockspace_local(proc->lockspace); 244 ls = dlm_find_lockspace_local(proc->lockspace);
@@ -260,12 +261,20 @@ static int device_user_lock(struct dlm_user_proc *proc,
260 ua->bastaddr = params->bastaddr; 261 ua->bastaddr = params->bastaddr;
261 ua->xid = params->xid; 262 ua->xid = params->xid;
262 263
263 if (params->flags & DLM_LKF_CONVERT) 264 if (params->flags & DLM_LKF_CONVERT) {
264 error = dlm_user_convert(ls, ua, 265 error = dlm_user_convert(ls, ua,
265 params->mode, params->flags, 266 params->mode, params->flags,
266 params->lkid, params->lvb, 267 params->lkid, params->lvb,
267 (unsigned long) params->timeout); 268 (unsigned long) params->timeout);
268 else { 269 } else if (params->flags & DLM_LKF_ORPHAN) {
270 error = dlm_user_adopt_orphan(ls, ua,
271 params->mode, params->flags,
272 params->name, params->namelen,
273 (unsigned long) params->timeout,
274 &lkid);
275 if (!error)
276 error = lkid;
277 } else {
269 error = dlm_user_request(ls, ua, 278 error = dlm_user_request(ls, ua,
270 params->mode, params->flags, 279 params->mode, params->flags,
271 params->name, params->namelen, 280 params->name, params->namelen,
diff --git a/include/uapi/linux/dlmconstants.h b/include/uapi/linux/dlmconstants.h
index 47bf08dc7566..2857bdc5b27b 100644
--- a/include/uapi/linux/dlmconstants.h
+++ b/include/uapi/linux/dlmconstants.h
@@ -114,7 +114,7 @@
114 * 114 *
115 * DLM_LKF_ORPHAN 115 * DLM_LKF_ORPHAN
116 * 116 *
117 * not yet implemented 117 * Acquire an orphan lock.
118 * 118 *
119 * DLM_LKF_ALTPR 119 * DLM_LKF_ALTPR
120 * 120 *