···2020 int ci_tcp_port;2121 int ci_buffer_size;2222 int ci_rsbtbl_size;2323- int ci_lkbtbl_size;2423 int ci_dirtbl_size;2524 int ci_recover_timer;2625 int ci_toss_secs;
···580580581581static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)582582{583583- struct dlm_lkb *lkb, *tmp;584584- uint32_t lkid = 0;585585- uint16_t bucket;583583+ struct dlm_lkb *lkb;584584+ int rv, id;586585587586 lkb = dlm_allocate_lkb(ls);588587 if (!lkb)···595596 INIT_LIST_HEAD(&lkb->lkb_time_list);596597 INIT_LIST_HEAD(&lkb->lkb_astqueue);597598598598- get_random_bytes(&bucket, sizeof(bucket));599599- bucket &= (ls->ls_lkbtbl_size - 1);599599+ retry:600600+ rv = idr_pre_get(&ls->ls_lkbidr, GFP_NOFS);601601+ if (!rv)602602+ return -ENOMEM;600603601601- write_lock(&ls->ls_lkbtbl[bucket].lock);604604+ spin_lock(&ls->ls_lkbidr_spin);605605+ rv = idr_get_new_above(&ls->ls_lkbidr, lkb, 1, &id);606606+ if (!rv)607607+ lkb->lkb_id = id;608608+ spin_unlock(&ls->ls_lkbidr_spin);602609603603- /* counter can roll over so we must verify lkid is not in use */610610+ if (rv == -EAGAIN)611611+ goto retry;604612605605- while (lkid == 0) {606606- lkid = (bucket << 16) | ls->ls_lkbtbl[bucket].counter++;607607-608608- list_for_each_entry(tmp, &ls->ls_lkbtbl[bucket].list,609609- lkb_idtbl_list) {610610- if (tmp->lkb_id != lkid)611611- continue;612612- lkid = 0;613613- break;614614- }613613+ if (rv < 0) {614614+ log_error(ls, "create_lkb idr error %d", rv);615615+ return rv;615616 }616616-617617- lkb->lkb_id = lkid;618618- list_add(&lkb->lkb_idtbl_list, &ls->ls_lkbtbl[bucket].list);619619- write_unlock(&ls->ls_lkbtbl[bucket].lock);620617621618 *lkb_ret = lkb;622619 return 0;623620}624621625625-static struct dlm_lkb *__find_lkb(struct dlm_ls *ls, uint32_t lkid)626626-{627627- struct dlm_lkb *lkb;628628- uint16_t bucket = (lkid >> 16);629629-630630- list_for_each_entry(lkb, &ls->ls_lkbtbl[bucket].list, lkb_idtbl_list) {631631- if (lkb->lkb_id == lkid)632632- return lkb;633633- }634634- return NULL;635635-}636636-637622static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)638623{639624 struct dlm_lkb *lkb;640640- uint16_t bucket = (lkid >> 16);641625642642- if (bucket >= ls->ls_lkbtbl_size)643643- return -EBADSLT;644644-645645- read_lock(&ls->ls_lkbtbl[bucket].lock);646646- lkb = __find_lkb(ls, lkid);626626+ spin_lock(&ls->ls_lkbidr_spin);627627+ lkb = idr_find(&ls->ls_lkbidr, lkid);647628 if (lkb)648629 kref_get(&lkb->lkb_ref);649649- read_unlock(&ls->ls_lkbtbl[bucket].lock);630630+ spin_unlock(&ls->ls_lkbidr_spin);650631651632 *lkb_ret = lkb;652633 return lkb ? 0 : -ENOENT;···647668648669static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)649670{650650- uint16_t bucket = (lkb->lkb_id >> 16);671671+ uint32_t lkid = lkb->lkb_id;651672652652- write_lock(&ls->ls_lkbtbl[bucket].lock);673673+ spin_lock(&ls->ls_lkbidr_spin);653674 if (kref_put(&lkb->lkb_ref, kill_lkb)) {654654- list_del(&lkb->lkb_idtbl_list);655655- write_unlock(&ls->ls_lkbtbl[bucket].lock);675675+ idr_remove(&ls->ls_lkbidr, lkid);676676+ spin_unlock(&ls->ls_lkbidr_spin);656677657678 detach_lkb(lkb);658679···662683 dlm_free_lkb(lkb);663684 return 1;664685 } else {665665- write_unlock(&ls->ls_lkbtbl[bucket].lock);686686+ spin_unlock(&ls->ls_lkbidr_spin);666687 return 0;667688 }668689}
+51-59
fs/dlm/lockspace.c
···472472 spin_lock_init(&ls->ls_rsbtbl[i].lock);473473 }474474475475- size = dlm_config.ci_lkbtbl_size;476476- ls->ls_lkbtbl_size = size;477477-478478- ls->ls_lkbtbl = vmalloc(sizeof(struct dlm_lkbtable) * size);479479- if (!ls->ls_lkbtbl)480480- goto out_rsbfree;481481- for (i = 0; i < size; i++) {482482- INIT_LIST_HEAD(&ls->ls_lkbtbl[i].list);483483- rwlock_init(&ls->ls_lkbtbl[i].lock);484484- ls->ls_lkbtbl[i].counter = 1;485485- }475475+ idr_init(&ls->ls_lkbidr);476476+ spin_lock_init(&ls->ls_lkbidr_spin);486477487478 size = dlm_config.ci_dirtbl_size;488479 ls->ls_dirtbl_size = size;···596605 out_dirfree:597606 vfree(ls->ls_dirtbl);598607 out_lkbfree:599599- vfree(ls->ls_lkbtbl);600600- out_rsbfree:608608+ idr_destroy(&ls->ls_lkbidr);601609 vfree(ls->ls_rsbtbl);602610 out_lsfree:603611 if (do_unreg)···631641 return error;632642}633643634634-/* Return 1 if the lockspace still has active remote locks,635635- * 2 if the lockspace still has active local locks.636636- */637637-static int lockspace_busy(struct dlm_ls *ls)644644+static int lkb_idr_is_local(int id, void *p, void *data)638645{639639- int i, lkb_found = 0;640640- struct dlm_lkb *lkb;646646+ struct dlm_lkb *lkb = p;641647642642- /* NOTE: We check the lockidtbl here rather than the resource table.643643- This is because there may be LKBs queued as ASTs that have been644644- unlinked from their RSBs and are pending deletion once the AST has645645- been delivered */648648+ if (!lkb->lkb_nodeid)649649+ return 1;650650+ return 0;651651+}646652647647- for (i = 0; i < ls->ls_lkbtbl_size; i++) {648648- read_lock(&ls->ls_lkbtbl[i].lock);649649- if (!list_empty(&ls->ls_lkbtbl[i].list)) {650650- lkb_found = 1;651651- list_for_each_entry(lkb, &ls->ls_lkbtbl[i].list,652652- lkb_idtbl_list) {653653- if (!lkb->lkb_nodeid) {654654- read_unlock(&ls->ls_lkbtbl[i].lock);655655- return 2;656656- }657657- }658658- }659659- read_unlock(&ls->ls_lkbtbl[i].lock);653653+static int lkb_idr_is_any(int id, void *p, void *data)654654+{655655+ return 1;656656+}657657+658658+static int lkb_idr_free(int id, void *p, void *data)659659+{660660+ struct dlm_lkb *lkb = p;661661+662662+ dlm_del_ast(lkb);663663+664664+ if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)665665+ dlm_free_lvb(lkb->lkb_lvbptr);666666+667667+ dlm_free_lkb(lkb);668668+ return 0;669669+}670670+671671+/* NOTE: We check the lkbidr here rather than the resource table.672672+ This is because there may be LKBs queued as ASTs that have been unlinked673673+ from their RSBs and are pending deletion once the AST has been delivered */674674+675675+static int lockspace_busy(struct dlm_ls *ls, int force)676676+{677677+ int rv;678678+679679+ spin_lock(&ls->ls_lkbidr_spin);680680+ if (force == 0) {681681+ rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);682682+ } else if (force == 1) {683683+ rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls);684684+ } else {685685+ rv = 0;660686 }661661- return lkb_found;687687+ spin_unlock(&ls->ls_lkbidr_spin);688688+ return rv;662689}663690664691static int release_lockspace(struct dlm_ls *ls, int force)665692{666666- struct dlm_lkb *lkb;667693 struct dlm_rsb *rsb;668694 struct list_head *head;669695 int i, busy, rv;670696671671- busy = lockspace_busy(ls);697697+ busy = lockspace_busy(ls, force);672698673699 spin_lock(&lslist_lock);674700 if (ls->ls_create_count == 1) {675675- if (busy > force)701701+ if (busy) {676702 rv = -EBUSY;677677- else {703703+ } else {678704 /* remove_lockspace takes ls off lslist */679705 ls->ls_create_count = 0;680706 rv = 0;···730724 vfree(ls->ls_dirtbl);731725732726 /*733733- * Free all lkb's on lkbtbl[] lists.727727+ * Free all lkb's in idr734728 */735729736736- for (i = 0; i < ls->ls_lkbtbl_size; i++) {737737- head = &ls->ls_lkbtbl[i].list;738738- while (!list_empty(head)) {739739- lkb = list_entry(head->next, struct dlm_lkb,740740- lkb_idtbl_list);730730+ idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);731731+ idr_remove_all(&ls->ls_lkbidr);732732+ idr_destroy(&ls->ls_lkbidr);741733742742- list_del(&lkb->lkb_idtbl_list);743743-744744- dlm_del_ast(lkb);745745-746746- if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)747747- dlm_free_lvb(lkb->lkb_lvbptr);748748-749749- dlm_free_lkb(lkb);750750- }751751- }752734 dlm_astd_resume();753753-754754- vfree(ls->ls_lkbtbl);755735756736 /*757737 * Free all rsb's on rsbtbl[] lists