Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+89 -5
+74 -2
fs/dlm/lock.c
··· 5886 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 5961 int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 5890 5962 uint32_t flags, uint32_t lkid, char *lvb_in) 5891 5963 { ··· 6101 6029 struct dlm_args args; 6102 6030 int error; 6103 6031 6104 - hold_lkb(lkb); 6032 + hold_lkb(lkb); /* reference for the ls_orphans list */ 6105 6033 mutex_lock(&ls->ls_orphans_mutex); 6106 6034 list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); 6107 6035 mutex_unlock(&ls->ls_orphans_mutex); ··· 6289 6217 { 6290 6218 int error = 0; 6291 6219 6292 - if (nodeid != dlm_our_nodeid()) { 6220 + if (nodeid && (nodeid != dlm_our_nodeid())) { 6293 6221 error = send_purge(ls, nodeid, pid); 6294 6222 } else { 6295 6223 dlm_lock_recovery(ls);
+3
fs/dlm/lock.h
··· 49 49 int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 50 50 int mode, uint32_t flags, uint32_t lkid, char *lvb_in, 51 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 55 int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 53 56 uint32_t flags, uint32_t lkid, char *lvb_in); 54 57 int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
+11 -2
fs/dlm/user.c
··· 238 238 { 239 239 struct dlm_ls *ls; 240 240 struct dlm_user_args *ua; 241 + uint32_t lkid; 241 242 int error = -ENOMEM; 242 243 243 244 ls = dlm_find_lockspace_local(proc->lockspace); ··· 261 260 ua->bastaddr = params->bastaddr; 262 261 ua->xid = params->xid; 263 262 264 - if (params->flags & DLM_LKF_CONVERT) 263 + if (params->flags & DLM_LKF_CONVERT) { 265 264 error = dlm_user_convert(ls, ua, 266 265 params->mode, params->flags, 267 266 params->lkid, params->lvb, 268 267 (unsigned long) params->timeout); 269 - else { 268 + } else if (params->flags & DLM_LKF_ORPHAN) { 269 + error = dlm_user_adopt_orphan(ls, ua, 270 + params->mode, params->flags, 271 + params->name, params->namelen, 272 + (unsigned long) params->timeout, 273 + &lkid); 274 + if (!error) 275 + error = lkid; 276 + } else { 270 277 error = dlm_user_request(ls, ua, 271 278 params->mode, params->flags, 272 279 params->name, params->namelen,
+1 -1
include/uapi/linux/dlmconstants.h
··· 114 114 * 115 115 * DLM_LKF_ORPHAN 116 116 * 117 - * not yet implemented 117 + * Acquire an orphan lock. 118 118 * 119 119 * DLM_LKF_ALTPR 120 120 *