diff options
-rw-r--r-- | fs/dlm/lock.c | 76 | ||||
-rw-r--r-- | fs/dlm/lock.h | 3 | ||||
-rw-r--r-- | fs/dlm/user.c | 13 | ||||
-rw-r--r-- | include/uapi/linux/dlmconstants.h | 2 |
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 | |||
5895 | int 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 | |||
5889 | int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | 5961 | int 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, | |||
49 | int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | 49 | int 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); |
52 | int 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); | ||
52 | int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | 55 | int 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); |
54 | int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | 57 | int 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 | * |