diff options
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/device.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/fs/dlm/device.c b/fs/dlm/device.c index 47798fe46d72..825bbc0a09c0 100644 --- a/fs/dlm/device.c +++ b/fs/dlm/device.c @@ -45,10 +45,6 @@ static const char *name_prefix="dlm"; static struct list_head user_ls_list; static struct mutex user_ls_lock; -/* Lock infos are stored in here indexed by lock ID */ -static DEFINE_IDR(lockinfo_idr); -static rwlock_t lockinfo_lock; - /* Flags in li_flags */ #define LI_FLAG_COMPLETE 1 #define LI_FLAG_FIRSTLOCK 2 @@ -99,6 +95,10 @@ struct user_ls { atomic_t ls_refcnt; long ls_flags; + /* Lock infos are stored in here indexed by lock ID */ + struct idr lockinfo_idr; + rwlock_t lockinfo_lock; + /* Passed into misc_register() */ struct miscdevice ls_miscinfo; struct list_head ls_list; @@ -240,13 +240,13 @@ static void put_file_info(struct file_info *f) kfree(f); } -static void release_lockinfo(struct lock_info *li) +static void release_lockinfo(struct user_ls *ls, struct lock_info *li) { put_file_info(li->li_file); - write_lock(&lockinfo_lock); - idr_remove(&lockinfo_idr, li->li_lksb.sb_lkid); - write_unlock(&lockinfo_lock); + write_lock(&ls->lockinfo_lock); + idr_remove(&ls->lockinfo_idr, li->li_lksb.sb_lkid); + write_unlock(&ls->lockinfo_lock); if (li->li_lksb.sb_lvbptr) kfree(li->li_lksb.sb_lvbptr); @@ -255,46 +255,46 @@ static void release_lockinfo(struct lock_info *li) module_put(THIS_MODULE); } -static struct lock_info *get_lockinfo(uint32_t lockid) +static struct lock_info *get_lockinfo(struct user_ls *ls, uint32_t lockid) { struct lock_info *li; - read_lock(&lockinfo_lock); - li = idr_find(&lockinfo_idr, lockid); - read_unlock(&lockinfo_lock); + read_lock(&ls->lockinfo_lock); + li = idr_find(&ls->lockinfo_idr, lockid); + read_unlock(&ls->lockinfo_lock); return li; } -static int add_lockinfo(struct lock_info *li) +static int add_lockinfo(struct user_ls *ls, struct lock_info *li) { int n; int r; int ret = -EINVAL; - write_lock(&lockinfo_lock); + write_lock(&ls->lockinfo_lock); - if (idr_find(&lockinfo_idr, li->li_lksb.sb_lkid)) + if (idr_find(&ls->lockinfo_idr, li->li_lksb.sb_lkid)) goto out_up; ret = -ENOMEM; - r = idr_pre_get(&lockinfo_idr, GFP_KERNEL); + r = idr_pre_get(&ls->lockinfo_idr, GFP_KERNEL); if (!r) goto out_up; - r = idr_get_new_above(&lockinfo_idr, li, li->li_lksb.sb_lkid, &n); + r = idr_get_new_above(&ls->lockinfo_idr, li, li->li_lksb.sb_lkid, &n); if (r) goto out_up; if (n != li->li_lksb.sb_lkid) { - idr_remove(&lockinfo_idr, n); + idr_remove(&ls->lockinfo_idr, n); goto out_up; } ret = 0; out_up: - write_unlock(&lockinfo_lock); + write_unlock(&ls->lockinfo_lock); return ret; } @@ -358,6 +358,9 @@ static int register_lockspace(char *name, struct user_ls **ls, int flags) return status; } + idr_init(&newls->lockinfo_idr); + rwlock_init(&newls->lockinfo_lock); + snprintf((char*)newls->ls_miscinfo.name, namelen, "%s_%s", name_prefix, name); @@ -486,13 +489,13 @@ static void ast_routine(void *param) list_del(&li->li_ownerqueue); clear_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&li->li_file->fi_li_lock); - release_lockinfo(li); + release_lockinfo(li->li_file->fi_ls, li); return; } /* Free unlocks & queries */ if (li->li_lksb.sb_status == -DLM_EUNLOCK || li->li_cmd == DLM_USER_QUERY) { - release_lockinfo(li); + release_lockinfo(li->li_file->fi_ls, li); } } else { /* Synchronous request, just wake up the caller */ @@ -641,7 +644,7 @@ static int dlm_close(struct inode *inode, struct file *file) old_li->li_lksb.sb_lkid, status); /* But tidy our references in it */ - release_lockinfo(old_li); + release_lockinfo(old_li->li_file->fi_ls, old_li); continue; } @@ -662,7 +665,7 @@ static int dlm_close(struct inode *inode, struct file *file) /* Unlock suceeded, free the lock_info struct. */ if (status == 0) - release_lockinfo(old_li); + release_lockinfo(old_li->li_file->fi_ls, old_li); } remove_wait_queue(&li.li_waitq, &wq); @@ -920,7 +923,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, unless we are adopting an orphaned persistent lock */ if (kparams->flags & DLM_LKF_CONVERT) { - li = get_lockinfo(kparams->lkid); + li = get_lockinfo(fi->fi_ls, kparams->lkid); /* If this is a persistent lock we will have to create a lockinfo again */ @@ -938,7 +941,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, fail we want rid of it */ init_completion(&li->li_firstcomp); set_bit(LI_FLAG_FIRSTLOCK, &li->li_flags); - add_lockinfo(li); + add_lockinfo(fi->fi_ls, li); /* TODO: do a query to get the current state ?? */ } @@ -1014,7 +1017,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, list_add(&li->li_ownerqueue, &fi->fi_li_list); set_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&fi->fi_li_lock); - if (add_lockinfo(li)) + if (add_lockinfo(fi->fi_ls, li)) printk(KERN_WARNING "Add lockinfo failed\n"); complete(&li->li_firstcomp); @@ -1025,7 +1028,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, out_err: if (test_bit(LI_FLAG_FIRSTLOCK, &li->li_flags)) - release_lockinfo(li); + release_lockinfo(fi->fi_ls, li); return status; } @@ -1037,7 +1040,7 @@ static int do_user_unlock(struct file_info *fi, uint8_t cmd, int status; int convert_cancel = 0; - li = get_lockinfo(kparams->lkid); + li = get_lockinfo(fi->fi_ls, kparams->lkid); if (!li) { li = allocate_lockinfo(fi, cmd, kparams); if (!li) @@ -1209,7 +1212,6 @@ static int __init dlm_device_init(void) INIT_LIST_HEAD(&user_ls_list); mutex_init(&user_ls_lock); - rwlock_init(&lockinfo_lock); ctl_device.name = "dlm-control"; ctl_device.fops = &_dlm_ctl_fops; |