]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/dlm/lockspace.c
[ARM] pxa: fix redefinition of NR_IRQS
[linux-2.6-omap-h63xx.git] / fs / dlm / lockspace.c
index 56eae4e4a954f54289501552f2b0be841b5265d6..d910501de6d2ca9d4fc8ed1a1cda8d9a1aca1519 100644 (file)
@@ -212,19 +212,41 @@ void dlm_lockspace_exit(void)
        kset_unregister(dlm_kset);
 }
 
+static struct dlm_ls *find_ls_to_scan(void)
+{
+       struct dlm_ls *ls;
+
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               if (time_after_eq(jiffies, ls->ls_scan_time +
+                                           dlm_config.ci_scan_secs * HZ)) {
+                       spin_unlock(&lslist_lock);
+                       return ls;
+               }
+       }
+       spin_unlock(&lslist_lock);
+       return NULL;
+}
+
 static int dlm_scand(void *data)
 {
        struct dlm_ls *ls;
+       int timeout_jiffies = dlm_config.ci_scan_secs * HZ;
 
        while (!kthread_should_stop()) {
-               list_for_each_entry(ls, &lslist, ls_list) {
+               ls = find_ls_to_scan();
+               if (ls) {
                        if (dlm_lock_recovery_try(ls)) {
+                               ls->ls_scan_time = jiffies;
                                dlm_scan_rsbs(ls);
                                dlm_scan_timeout(ls);
                                dlm_unlock_recovery(ls);
+                       } else {
+                               ls->ls_scan_time += HZ;
                        }
+               } else {
+                       schedule_timeout_interruptible(timeout_jiffies);
                }
-               schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
        }
        return 0;
 }
@@ -378,6 +400,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        if (!try_module_get(THIS_MODULE))
                return -EINVAL;
 
+       if (!dlm_user_daemon_available()) {
+               module_put(THIS_MODULE);
+               return -EUNATCH;
+       }
+
        error = 0;
 
        spin_lock(&lslist_lock);
@@ -413,6 +440,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        ls->ls_lvblen = lvblen;
        ls->ls_count = 0;
        ls->ls_flags = 0;
+       ls->ls_scan_time = jiffies;
 
        if (flags & DLM_LSFL_TIMEWARN)
                set_bit(LSFL_TIMEWARN, &ls->ls_flags);
@@ -669,7 +697,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
 
        dlm_device_deregister(ls);
 
-       if (force < 3)
+       if (force < 3 && dlm_user_daemon_available())
                do_uevent(ls, 0);
 
        dlm_recoverd_stop(ls);
@@ -791,3 +819,20 @@ int dlm_release_lockspace(void *lockspace, int force)
        return error;
 }
 
+void dlm_stop_lockspaces(void)
+{
+       struct dlm_ls *ls;
+
+ restart:
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
+                       continue;
+               spin_unlock(&lslist_lock);
+               log_error(ls, "no userland control daemon, stopping lockspace");
+               dlm_ls_stop(ls);
+               goto restart;
+       }
+       spin_unlock(&lslist_lock);
+}
+