diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 88d946466083..412ab0808c59 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3356,6 +3356,14 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb) { struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug; + /* + * Drain the readers before the cluster stack goes away: the + * locking_state reader resolves ocfs2_dlm_lvb() through the + * stack. Every caller removes the parent directory later. + */ + debugfs_lookup_and_remove("locking_state", osb->osb_debug_root); + debugfs_lookup_and_remove("locking_filter", osb->osb_debug_root); + if (dlm_debug) ocfs2_put_dlm_debug(dlm_debug); } @@ -3370,8 +3378,6 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) goto local; } - ocfs2_dlm_init_debug(osb); - /* launch downconvert thread */ osb->dc_task = kthread_run(ocfs2_downconvert_thread, osb, "ocfs2dc-%s", osb->uuid_str); @@ -3411,9 +3417,10 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) ocfs2_orphan_scan_lock_res_init(&osb->osb_orphan_scan.os_lockres, osb); osb->cconn = conn; + if (conn) + ocfs2_dlm_init_debug(osb); bail: if (status < 0) { - ocfs2_dlm_shutdown_debug(osb); if (osb->dc_task) kthread_stop(osb->dc_task); } @@ -3443,10 +3450,11 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb, ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres); if (osb->cconn) { + /* The disconnect below may release the selected stack. */ + ocfs2_dlm_shutdown_debug(osb); + ocfs2_cluster_disconnect(osb->cconn, hangup_pending); osb->cconn = NULL; - - ocfs2_dlm_shutdown_debug(osb); } }