diff options
| -rw-r--r-- | fs/dlm/lockspace.c | 24 | ||||
| -rw-r--r-- | fs/dlm/lockspace.h | 1 | ||||
| -rw-r--r-- | fs/dlm/user.c | 61 | ||||
| -rw-r--r-- | fs/dlm/user.h | 1 |
4 files changed, 85 insertions, 2 deletions
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 56eae4e4a954..ba672fe0a601 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
| @@ -378,6 +378,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 378 | if (!try_module_get(THIS_MODULE)) | 378 | if (!try_module_get(THIS_MODULE)) |
| 379 | return -EINVAL; | 379 | return -EINVAL; |
| 380 | 380 | ||
| 381 | if (!dlm_user_daemon_available()) { | ||
| 382 | module_put(THIS_MODULE); | ||
| 383 | return -EUNATCH; | ||
| 384 | } | ||
| 385 | |||
| 381 | error = 0; | 386 | error = 0; |
| 382 | 387 | ||
| 383 | spin_lock(&lslist_lock); | 388 | spin_lock(&lslist_lock); |
| @@ -669,7 +674,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
| 669 | 674 | ||
| 670 | dlm_device_deregister(ls); | 675 | dlm_device_deregister(ls); |
| 671 | 676 | ||
| 672 | if (force < 3) | 677 | if (force < 3 && dlm_user_daemon_available()) |
| 673 | do_uevent(ls, 0); | 678 | do_uevent(ls, 0); |
| 674 | 679 | ||
| 675 | dlm_recoverd_stop(ls); | 680 | dlm_recoverd_stop(ls); |
| @@ -791,3 +796,20 @@ int dlm_release_lockspace(void *lockspace, int force) | |||
| 791 | return error; | 796 | return error; |
| 792 | } | 797 | } |
| 793 | 798 | ||
| 799 | void dlm_stop_lockspaces(void) | ||
| 800 | { | ||
| 801 | struct dlm_ls *ls; | ||
| 802 | |||
| 803 | restart: | ||
| 804 | spin_lock(&lslist_lock); | ||
| 805 | list_for_each_entry(ls, &lslist, ls_list) { | ||
| 806 | if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) | ||
| 807 | continue; | ||
| 808 | spin_unlock(&lslist_lock); | ||
| 809 | log_error(ls, "no userland control daemon, stopping lockspace"); | ||
| 810 | dlm_ls_stop(ls); | ||
| 811 | goto restart; | ||
| 812 | } | ||
| 813 | spin_unlock(&lslist_lock); | ||
| 814 | } | ||
| 815 | |||
diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h index 891eabbdd021..f879f87901f8 100644 --- a/fs/dlm/lockspace.h +++ b/fs/dlm/lockspace.h | |||
| @@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id); | |||
| 20 | struct dlm_ls *dlm_find_lockspace_local(void *id); | 20 | struct dlm_ls *dlm_find_lockspace_local(void *id); |
| 21 | struct dlm_ls *dlm_find_lockspace_device(int minor); | 21 | struct dlm_ls *dlm_find_lockspace_device(int minor); |
| 22 | void dlm_put_lockspace(struct dlm_ls *ls); | 22 | void dlm_put_lockspace(struct dlm_ls *ls); |
| 23 | void dlm_stop_lockspaces(void); | ||
| 23 | 24 | ||
| 24 | #endif /* __LOCKSPACE_DOT_H__ */ | 25 | #endif /* __LOCKSPACE_DOT_H__ */ |
| 25 | 26 | ||
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 6542110c0da4..81627b502a56 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | 27 | ||
| 28 | static const char name_prefix[] = "dlm"; | 28 | static const char name_prefix[] = "dlm"; |
| 29 | static const struct file_operations device_fops; | 29 | static const struct file_operations device_fops; |
| 30 | static atomic_t dlm_monitor_opened; | ||
| 31 | static int dlm_monitor_unused = 1; | ||
| 30 | 32 | ||
| 31 | #ifdef CONFIG_COMPAT | 33 | #ifdef CONFIG_COMPAT |
| 32 | 34 | ||
| @@ -890,6 +892,26 @@ static unsigned int device_poll(struct file *file, poll_table *wait) | |||
| 890 | return 0; | 892 | return 0; |
| 891 | } | 893 | } |
| 892 | 894 | ||
| 895 | int dlm_user_daemon_available(void) | ||
| 896 | { | ||
| 897 | /* dlm_controld hasn't started (or, has started, but not | ||
| 898 | properly populated configfs) */ | ||
| 899 | |||
| 900 | if (!dlm_our_nodeid()) | ||
| 901 | return 0; | ||
| 902 | |||
| 903 | /* This is to deal with versions of dlm_controld that don't | ||
| 904 | know about the monitor device. We assume that if the | ||
| 905 | dlm_controld was started (above), but the monitor device | ||
| 906 | was never opened, that it's an old version. dlm_controld | ||
| 907 | should open the monitor device before populating configfs. */ | ||
| 908 | |||
| 909 | if (dlm_monitor_unused) | ||
| 910 | return 1; | ||
| 911 | |||
| 912 | return atomic_read(&dlm_monitor_opened) ? 1 : 0; | ||
| 913 | } | ||
| 914 | |||
| 893 | static int ctl_device_open(struct inode *inode, struct file *file) | 915 | static int ctl_device_open(struct inode *inode, struct file *file) |
| 894 | { | 916 | { |
| 895 | cycle_kernel_lock(); | 917 | cycle_kernel_lock(); |
| @@ -902,6 +924,20 @@ static int ctl_device_close(struct inode *inode, struct file *file) | |||
| 902 | return 0; | 924 | return 0; |
| 903 | } | 925 | } |
| 904 | 926 | ||
| 927 | static int monitor_device_open(struct inode *inode, struct file *file) | ||
| 928 | { | ||
| 929 | atomic_inc(&dlm_monitor_opened); | ||
| 930 | dlm_monitor_unused = 0; | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int monitor_device_close(struct inode *inode, struct file *file) | ||
| 935 | { | ||
| 936 | if (atomic_dec_and_test(&dlm_monitor_opened)) | ||
| 937 | dlm_stop_lockspaces(); | ||
| 938 | return 0; | ||
| 939 | } | ||
| 940 | |||
| 905 | static const struct file_operations device_fops = { | 941 | static const struct file_operations device_fops = { |
| 906 | .open = device_open, | 942 | .open = device_open, |
| 907 | .release = device_close, | 943 | .release = device_close, |
| @@ -925,19 +961,42 @@ static struct miscdevice ctl_device = { | |||
| 925 | .minor = MISC_DYNAMIC_MINOR, | 961 | .minor = MISC_DYNAMIC_MINOR, |
| 926 | }; | 962 | }; |
| 927 | 963 | ||
| 964 | static const struct file_operations monitor_device_fops = { | ||
| 965 | .open = monitor_device_open, | ||
| 966 | .release = monitor_device_close, | ||
| 967 | .owner = THIS_MODULE, | ||
| 968 | }; | ||
| 969 | |||
| 970 | static struct miscdevice monitor_device = { | ||
| 971 | .name = "dlm-monitor", | ||
| 972 | .fops = &monitor_device_fops, | ||
| 973 | .minor = MISC_DYNAMIC_MINOR, | ||
| 974 | }; | ||
| 975 | |||
| 928 | int __init dlm_user_init(void) | 976 | int __init dlm_user_init(void) |
| 929 | { | 977 | { |
| 930 | int error; | 978 | int error; |
| 931 | 979 | ||
| 980 | atomic_set(&dlm_monitor_opened, 0); | ||
| 981 | |||
| 932 | error = misc_register(&ctl_device); | 982 | error = misc_register(&ctl_device); |
| 933 | if (error) | 983 | if (error) { |
| 934 | log_print("misc_register failed for control device"); | 984 | log_print("misc_register failed for control device"); |
| 985 | goto out; | ||
| 986 | } | ||
| 935 | 987 | ||
| 988 | error = misc_register(&monitor_device); | ||
| 989 | if (error) { | ||
| 990 | log_print("misc_register failed for monitor device"); | ||
| 991 | misc_deregister(&ctl_device); | ||
| 992 | } | ||
| 993 | out: | ||
| 936 | return error; | 994 | return error; |
| 937 | } | 995 | } |
| 938 | 996 | ||
| 939 | void dlm_user_exit(void) | 997 | void dlm_user_exit(void) |
| 940 | { | 998 | { |
| 941 | misc_deregister(&ctl_device); | 999 | misc_deregister(&ctl_device); |
| 1000 | misc_deregister(&monitor_device); | ||
| 942 | } | 1001 | } |
| 943 | 1002 | ||
diff --git a/fs/dlm/user.h b/fs/dlm/user.h index c528b6b2991b..35eb6a13d616 100644 --- a/fs/dlm/user.h +++ b/fs/dlm/user.h | |||
| @@ -13,5 +13,6 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type); | |||
| 13 | int dlm_user_init(void); | 13 | int dlm_user_init(void); |
| 14 | void dlm_user_exit(void); | 14 | void dlm_user_exit(void); |
| 15 | int dlm_device_deregister(struct dlm_ls *ls); | 15 | int dlm_device_deregister(struct dlm_ls *ls); |
| 16 | int dlm_user_daemon_available(void); | ||
| 16 | 17 | ||
| 17 | #endif | 18 | #endif |
