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"; | |||
45 | static struct list_head user_ls_list; | 45 | static struct list_head user_ls_list; |
46 | static struct mutex user_ls_lock; | 46 | static struct mutex user_ls_lock; |
47 | 47 | ||
48 | /* Lock infos are stored in here indexed by lock ID */ | ||
49 | static DEFINE_IDR(lockinfo_idr); | ||
50 | static 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 | ||
243 | static void release_lockinfo(struct lock_info *li) | 243 | static 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 | ||
258 | static struct lock_info *get_lockinfo(uint32_t lockid) | 258 | static 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 | ||
269 | static int add_lockinfo(struct lock_info *li) | 269 | static 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; |