diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 19:02:12 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 19:02:12 -0500 |
| commit | 8322b6fddfd2cee41a7732284e5f04750511f4b2 (patch) | |
| tree | ebff5f6c0d43aa82c7e36cfb5cfd40be050db8a2 | |
| parent | 1366f5d3129f2abde606214de7afc3dd61781fa3 (diff) | |
| parent | 2ab4bd8ea3a6954bc79a9bbeb291cd6c2d6213a7 (diff) | |
Merge tag 'dlm-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/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
| -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 | * |
