nfs: new subdir Documentation/filesystems/nfs
[safe/jmp/linux-2.6] / fs / dlm / recoverd.c
index 650536a..fd677c8 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
 
 
 /* If the start for which we're re-enabling locking (seq) has been superseded
-   by a newer stop (ls_recover_seq), we need to leave locking disabled. */
+   by a newer stop (ls_recover_seq), we need to leave locking disabled.
+
+   We suspend dlm_recv threads here to avoid the race where dlm_recv a) sees
+   locking stopped and b) adds a message to the requestqueue, but dlm_recoverd
+   enables locking and clears the requestqueue between a and b. */
 
 static int enable_locking(struct dlm_ls *ls, uint64_t seq)
 {
        int error = -EINTR;
 
+       down_write(&ls->ls_recv_active);
+
        spin_lock(&ls->ls_recover_lock);
        if (ls->ls_recover_seq == seq) {
                set_bit(LSFL_RUNNING, &ls->ls_flags);
+               /* unblocks processes waiting to enter the dlm */
                up_write(&ls->ls_in_recovery);
                error = 0;
        }
        spin_unlock(&ls->ls_recover_lock);
+
+       up_write(&ls->ls_recv_active);
        return error;
 }
 
@@ -58,17 +67,18 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
        dlm_astd_resume();
 
        /*
-        * This list of root rsb's will be the basis of most of the recovery
-        * routines.
+        * Free non-master tossed rsb's.  Master rsb's are kept on toss
+        * list and put on root list to be included in resdir recovery.
         */
 
-       dlm_create_root_list(ls);
+       dlm_clear_toss_list(ls);
 
        /*
-        * Free all the tossed rsb's so we don't have to recover them.
+        * This list of root rsb's will be the basis of most of the recovery
+        * routines.
         */
 
-       dlm_clear_toss_list(ls);
+       dlm_create_root_list(ls);
 
        /*
         * Add or remove nodes from the lockspace's ls_nodes list.
@@ -77,7 +87,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_members(ls, rv, &neg);
        if (error) {
-               log_error(ls, "recover_members failed %d", error);
+               log_debug(ls, "recover_members failed %d", error);
                goto fail;
        }
        start = jiffies;
@@ -89,7 +99,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_directory(ls);
        if (error) {
-               log_error(ls, "recover_directory failed %d", error);
+               log_debug(ls, "recover_directory failed %d", error);
                goto fail;
        }
 
@@ -99,7 +109,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_directory_wait(ls);
        if (error) {
-               log_error(ls, "recover_directory_wait failed %d", error);
+               log_debug(ls, "recover_directory_wait failed %d", error);
                goto fail;
        }
 
@@ -129,7 +139,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_masters(ls);
                if (error) {
-                       log_error(ls, "recover_masters failed %d", error);
+                       log_debug(ls, "recover_masters failed %d", error);
                        goto fail;
                }
 
@@ -139,13 +149,13 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_locks(ls);
                if (error) {
-                       log_error(ls, "recover_locks failed %d", error);
+                       log_debug(ls, "recover_locks failed %d", error);
                        goto fail;
                }
 
                error = dlm_recover_locks_wait(ls);
                if (error) {
-                       log_error(ls, "recover_locks_wait failed %d", error);
+                       log_debug(ls, "recover_locks_wait failed %d", error);
                        goto fail;
                }
 
@@ -166,7 +176,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_locks_wait(ls);
                if (error) {
-                       log_error(ls, "recover_locks_wait failed %d", error);
+                       log_debug(ls, "recover_locks_wait failed %d", error);
                        goto fail;
                }
        }
@@ -184,27 +194,29 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
        dlm_set_recover_status(ls, DLM_RS_DONE);
        error = dlm_recover_done_wait(ls);
        if (error) {
-               log_error(ls, "recover_done_wait failed %d", error);
+               log_debug(ls, "recover_done_wait failed %d", error);
                goto fail;
        }
 
        dlm_clear_members_gone(ls);
 
+       dlm_adjust_timeouts(ls);
+
        error = enable_locking(ls, rv->seq);
        if (error) {
-               log_error(ls, "enable_locking failed %d", error);
+               log_debug(ls, "enable_locking failed %d", error);
                goto fail;
        }
 
        error = dlm_process_requestqueue(ls);
        if (error) {
-               log_error(ls, "process_requestqueue failed %d", error);
+               log_debug(ls, "process_requestqueue failed %d", error);
                goto fail;
        }
 
        error = dlm_recover_waiters_post(ls);
        if (error) {
-               log_error(ls, "recover_waiters_post failed %d", error);
+               log_debug(ls, "recover_waiters_post failed %d", error);
                goto fail;
        }
 
@@ -245,6 +257,7 @@ static void do_ls_recovery(struct dlm_ls *ls)
        if (rv) {
                ls_recover(ls, rv);
                kfree(rv->nodeids);
+               kfree(rv->new);
                kfree(rv);
        }
 }