[BTRFS] Fix booting with runtime checks
[reactos.git] / drivers / filesystems / cdfs_new / shutdown.c
1 /*++
2
3 Copyright (c) 1997-2006 Microsoft Corporation
4
5 Module Name:
6
7 Shutdown.c
8
9 Abstract:
10
11 This module implements the shutdown routine for CDFS called by
12 the dispatch driver.
13
14
15 --*/
16
17 #include "cdprocs.h"
18
19 //
20 // The Bug check file id for this module
21 //
22
23 #define BugCheckFileId (CDFS_BUG_CHECK_SHUTDOWN)
24
25 #ifdef ALLOC_PRAGMA
26 #pragma alloc_text(PAGE, CdCommonShutdown)
27 #endif
28
29 _Requires_lock_held_(_Global_critical_region_)
30 NTSTATUS
31 CdCommonShutdown (
32 _Inout_ PIRP_CONTEXT IrpContext,
33 _Inout_ PIRP Irp
34 )
35
36 /*++
37
38 Routine Description:
39
40 This is the common routine for handling shutdown operation called
41 by both the fsd and fsp threads
42
43 Arguments:
44
45 Irp - Supplies the Irp to process
46
47 Return Value:
48
49 NTSTATUS - The return status for the operation
50
51 --*/
52
53 {
54 KEVENT Event;
55 PLIST_ENTRY Links;
56 PVCB Vcb;
57 PIRP NewIrp;
58 IO_STATUS_BLOCK Iosb;
59 BOOLEAN VcbPresent;
60 NTSTATUS Status;
61
62 PAGED_CODE();
63
64 //
65 // Make sure we don't get any pop-ups.
66 //
67
68 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS );
69
70 //
71 // Initialize an event for doing calls down to
72 // our target device objects.
73 //
74
75 KeInitializeEvent( &Event, NotificationEvent, FALSE );
76
77 //
78 // Indicate that shutdown has started.
79 //
80
81 SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN );
82
83 //
84 // Get everyone else out of the way
85 //
86
87 CdAcquireCdData( IrpContext );
88
89 //
90 // Now walk through all the mounted Vcb's and shutdown the target
91 // device objects.
92 //
93
94 Links = CdData.VcbQueue.Flink;
95
96 while (Links != &CdData.VcbQueue) {
97
98 Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks );
99
100 //
101 // Move to the next link now since the current Vcb may be deleted.
102 //
103
104 Links = Links->Flink;
105
106 //
107 // If we have already been called before for this volume
108 // (and yes this does happen), skip this volume as no writes
109 // have been allowed since the first shutdown.
110 //
111
112 if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) ||
113 (Vcb->VcbCondition != VcbMounted)) {
114
115 continue;
116 }
117
118 CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
119
120 CdPurgeVolume( IrpContext, Vcb, FALSE );
121
122 //
123 // Build an irp for this volume stack - our own irp is probably too small and
124 // each stack may have a different stack size.
125 //
126
127 NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
128 Vcb->TargetDeviceObject,
129 NULL,
130 0,
131 NULL,
132 &Event,
133 &Iosb );
134
135 if (NewIrp != NULL) {
136
137 Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp );
138
139 if (Status == STATUS_PENDING) {
140
141 (VOID)KeWaitForSingleObject( &Event,
142 Executive,
143 KernelMode,
144 FALSE,
145 NULL );
146 }
147
148 KeClearEvent( &Event );
149 }
150
151 SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN );
152
153 //
154 // Attempt to punch the volume down.
155 //
156
157 VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE );
158
159 if (VcbPresent) {
160
161 CdReleaseVcb( IrpContext, Vcb );
162 }
163 }
164
165
166 CdReleaseCdData( IrpContext );
167
168 IoUnregisterFileSystem( CdData.FileSystemDeviceObject );
169 IoDeleteDevice( CdData.FileSystemDeviceObject );
170 #ifdef __REACTOS__
171 IoUnregisterFileSystem( CdData.HddFileSystemDeviceObject );
172 IoDeleteDevice( CdData.HddFileSystemDeviceObject );
173 #endif
174
175 CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
176 return STATUS_SUCCESS;
177 }
178
179