aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/device.c60
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";
45static struct list_head user_ls_list; 45static struct list_head user_ls_list;
46static struct mutex user_ls_lock; 46static struct mutex user_ls_lock;
47 47
48/* Lock infos are stored in here indexed by lock ID */
49static DEFINE_IDR(lockinfo_idr);
50static rwlock_t lockinfo_lock;
51
52/* Flags in li_flags */ 48/* Flags in li_flags */
53#define LI_FLAG_COMPLETE 1 49#define LI_FLAG_COMPLETE 1
54#define LI_FLAG_FIRSTLOCK 2 50#define LI_FLAG_FIRSTLOCK 2
@@ -99,6 +95,10 @@ struct user_ls {
99 atomic_t ls_refcnt; 95 atomic_t ls_refcnt;
100 long ls_flags; 96 long ls_flags;
101 97
98 /* Lock infos are stored in here indexed by lock ID */
99 struct idr lockinfo_idr;
100 rwlock_t lockinfo_lock;
101
102 /* Passed into misc_register() */ 102 /* Passed into misc_register() */
103 struct miscdevice ls_miscinfo; 103 struct miscdevice ls_miscinfo;
104 struct list_head ls_list; 104 struct list_head ls_list;
@@ -240,13 +240,13 @@ static void put_file_info(struct file_info *f)
240 kfree(f); 240 kfree(f);
241} 241}
242 242
243static void release_lockinfo(struct lock_info *li) 243static void release_lockinfo(struct user_ls *ls, struct lock_info *li)
244{ 244{
245 put_file_info(li->li_file); 245 put_file_info(li->li_file);
246 246
247 write_lock(&lockinfo_lock); 247 write_lock(&ls->lockinfo_lock);
248 idr_remove(&lockinfo_idr, li->li_lksb.sb_lkid); 248 idr_remove(&ls->lockinfo_idr, li->li_lksb.sb_lkid);
249 write_unlock(&lockinfo_lock); 249 write_unlock(&ls->lockinfo_lock);
250 250
251 if (li->li_lksb.sb_lvbptr) 251 if (li->li_lksb.sb_lvbptr)
252 kfree(li->li_lksb.sb_lvbptr); 252 kfree(li->li_lksb.sb_lvbptr);
@@ -255,46 +255,46 @@ static void release_lockinfo(struct lock_info *li)
255 module_put(THIS_MODULE); 255 module_put(THIS_MODULE);
256} 256}
257 257
258static struct lock_info *get_lockinfo(uint32_t lockid) 258static struct lock_info *get_lockinfo(struct user_ls *ls, uint32_t lockid)
259{ 259{
260 struct lock_info *li; 260 struct lock_info *li;
261 261
262 read_lock(&lockinfo_lock); 262 read_lock(&ls->lockinfo_lock);
263 li = idr_find(&lockinfo_idr, lockid); 263 li = idr_find(&ls->lockinfo_idr, lockid);
264 read_unlock(&lockinfo_lock); 264 read_unlock(&ls->lockinfo_lock);
265 265
266 return li; 266 return li;
267} 267}
268 268
269static int add_lockinfo(struct lock_info *li) 269static int add_lockinfo(struct user_ls *ls, struct lock_info *li)
270{ 270{
271 int n; 271 int n;
272 int r; 272 int r;
273 int ret = -EINVAL; 273 int ret = -EINVAL;
274 274
275 write_lock(&lockinfo_lock); 275 write_lock(&ls->lockinfo_lock);
276 276
277 if (idr_find(&lockinfo_idr, li->li_lksb.sb_lkid)) 277 if (idr_find(&ls->lockinfo_idr, li->li_lksb.sb_lkid))
278 goto out_up; 278 goto out_up;
279 279
280 ret = -ENOMEM; 280 ret = -ENOMEM;
281 r = idr_pre_get(&lockinfo_idr, GFP_KERNEL); 281 r = idr_pre_get(&ls->lockinfo_idr, GFP_KERNEL);
282 if (!r) 282 if (!r)
283 goto out_up; 283 goto out_up;
284 284
285 r = idr_get_new_above(&lockinfo_idr, li, li->li_lksb.sb_lkid, &n); 285 r = idr_get_new_above(&ls->lockinfo_idr, li, li->li_lksb.sb_lkid, &n);
286 if (r) 286 if (r)
287 goto out_up; 287 goto out_up;
288 288
289 if (n != li->li_lksb.sb_lkid) { 289 if (n != li->li_lksb.sb_lkid) {
290 idr_remove(&lockinfo_idr, n); 290 idr_remove(&ls->lockinfo_idr, n);
291 goto out_up; 291 goto out_up;
292 } 292 }
293 293
294 ret = 0; 294 ret = 0;
295 295
296 out_up: 296 out_up:
297 write_unlock(&lockinfo_lock); 297 write_unlock(&ls->lockinfo_lock);
298 298
299 return ret; 299 return ret;
300} 300}
@@ -358,6 +358,9 @@ static int register_lockspace(char *name, struct user_ls **ls, int flags)
358 return status; 358 return status;
359 } 359 }
360 360
361 idr_init(&newls->lockinfo_idr);
362 rwlock_init(&newls->lockinfo_lock);
363
361 snprintf((char*)newls->ls_miscinfo.name, namelen, "%s_%s", 364 snprintf((char*)newls->ls_miscinfo.name, namelen, "%s_%s",
362 name_prefix, name); 365 name_prefix, name);
363 366
@@ -486,13 +489,13 @@ static void ast_routine(void *param)
486 list_del(&li->li_ownerqueue); 489 list_del(&li->li_ownerqueue);
487 clear_bit(LI_FLAG_ONLIST, &li->li_flags); 490 clear_bit(LI_FLAG_ONLIST, &li->li_flags);
488 spin_unlock(&li->li_file->fi_li_lock); 491 spin_unlock(&li->li_file->fi_li_lock);
489 release_lockinfo(li); 492 release_lockinfo(li->li_file->fi_ls, li);
490 return; 493 return;
491 } 494 }
492 /* Free unlocks & queries */ 495 /* Free unlocks & queries */
493 if (li->li_lksb.sb_status == -DLM_EUNLOCK || 496 if (li->li_lksb.sb_status == -DLM_EUNLOCK ||
494 li->li_cmd == DLM_USER_QUERY) { 497 li->li_cmd == DLM_USER_QUERY) {
495 release_lockinfo(li); 498 release_lockinfo(li->li_file->fi_ls, li);
496 } 499 }
497 } else { 500 } else {
498 /* Synchronous request, just wake up the caller */ 501 /* Synchronous request, just wake up the caller */
@@ -641,7 +644,7 @@ static int dlm_close(struct inode *inode, struct file *file)
641 old_li->li_lksb.sb_lkid, status); 644 old_li->li_lksb.sb_lkid, status);
642 645
643 /* But tidy our references in it */ 646 /* But tidy our references in it */
644 release_lockinfo(old_li); 647 release_lockinfo(old_li->li_file->fi_ls, old_li);
645 continue; 648 continue;
646 } 649 }
647 650
@@ -662,7 +665,7 @@ static int dlm_close(struct inode *inode, struct file *file)
662 665
663 /* Unlock suceeded, free the lock_info struct. */ 666 /* Unlock suceeded, free the lock_info struct. */
664 if (status == 0) 667 if (status == 0)
665 release_lockinfo(old_li); 668 release_lockinfo(old_li->li_file->fi_ls, old_li);
666 } 669 }
667 670
668 remove_wait_queue(&li.li_waitq, &wq); 671 remove_wait_queue(&li.li_waitq, &wq);
@@ -920,7 +923,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd,
920 unless we are adopting an orphaned persistent lock */ 923 unless we are adopting an orphaned persistent lock */
921 if (kparams->flags & DLM_LKF_CONVERT) { 924 if (kparams->flags & DLM_LKF_CONVERT) {
922 925
923 li = get_lockinfo(kparams->lkid); 926 li = get_lockinfo(fi->fi_ls, kparams->lkid);
924 927
925 /* If this is a persistent lock we will have to create a 928 /* If this is a persistent lock we will have to create a
926 lockinfo again */ 929 lockinfo again */
@@ -938,7 +941,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd,
938 fail we want rid of it */ 941 fail we want rid of it */
939 init_completion(&li->li_firstcomp); 942 init_completion(&li->li_firstcomp);
940 set_bit(LI_FLAG_FIRSTLOCK, &li->li_flags); 943 set_bit(LI_FLAG_FIRSTLOCK, &li->li_flags);
941 add_lockinfo(li); 944 add_lockinfo(fi->fi_ls, li);
942 945
943 /* TODO: do a query to get the current state ?? */ 946 /* TODO: do a query to get the current state ?? */
944 } 947 }
@@ -1014,7 +1017,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd,
1014 list_add(&li->li_ownerqueue, &fi->fi_li_list); 1017 list_add(&li->li_ownerqueue, &fi->fi_li_list);
1015 set_bit(LI_FLAG_ONLIST, &li->li_flags); 1018 set_bit(LI_FLAG_ONLIST, &li->li_flags);
1016 spin_unlock(&fi->fi_li_lock); 1019 spin_unlock(&fi->fi_li_lock);
1017 if (add_lockinfo(li)) 1020 if (add_lockinfo(fi->fi_ls, li))
1018 printk(KERN_WARNING "Add lockinfo failed\n"); 1021 printk(KERN_WARNING "Add lockinfo failed\n");
1019 1022
1020 complete(&li->li_firstcomp); 1023 complete(&li->li_firstcomp);
@@ -1025,7 +1028,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd,
1025 1028
1026 out_err: 1029 out_err:
1027 if (test_bit(LI_FLAG_FIRSTLOCK, &li->li_flags)) 1030 if (test_bit(LI_FLAG_FIRSTLOCK, &li->li_flags))
1028 release_lockinfo(li); 1031 release_lockinfo(fi->fi_ls, li);
1029 return status; 1032 return status;
1030 1033
1031} 1034}
@@ -1037,7 +1040,7 @@ static int do_user_unlock(struct file_info *fi, uint8_t cmd,
1037 int status; 1040 int status;
1038 int convert_cancel = 0; 1041 int convert_cancel = 0;
1039 1042
1040 li = get_lockinfo(kparams->lkid); 1043 li = get_lockinfo(fi->fi_ls, kparams->lkid);
1041 if (!li) { 1044 if (!li) {
1042 li = allocate_lockinfo(fi, cmd, kparams); 1045 li = allocate_lockinfo(fi, cmd, kparams);
1043 if (!li) 1046 if (!li)
@@ -1209,7 +1212,6 @@ static int __init dlm_device_init(void)
1209 1212
1210 INIT_LIST_HEAD(&user_ls_list); 1213 INIT_LIST_HEAD(&user_ls_list);
1211 mutex_init(&user_ls_lock); 1214 mutex_init(&user_ls_lock);
1212 rwlock_init(&lockinfo_lock);
1213 1215
1214 ctl_device.name = "dlm-control"; 1216 ctl_device.name = "dlm-control";
1215 ctl_device.fops = &_dlm_ctl_fops; 1217 ctl_device.fops = &_dlm_ctl_fops;