ReactOS 0.4.17-dev-1190-g4c812f4
cleanup.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2016 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/cleanup.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
24 * UPDATE HISTORY:
25 */
26
27/* INCLUDES *****************************************************************/
28
29#include "ntfs.h"
30
31#define NDEBUG
32#include <debug.h>
33
34/* FUNCTIONS ****************************************************************/
35
36/*
37 * FUNCTION: Cleans up a file
38 */
42 BOOLEAN CanWait)
43{
45 BOOLEAN DeletePending = FALSE;
46
47 DPRINT("NtfsCleanupFile(DeviceExt %p, FileObject %p, CanWait %u)\n",
48 DeviceExt,
50 CanWait);
51
52 Fcb = (PNTFS_FCB)(FileObject->FsContext);
53 if (!Fcb)
54 return STATUS_SUCCESS;
55
56 if (Fcb->Flags & FCB_IS_VOLUME)
57 {
59
60 if (Fcb->OpenHandleCount != 0)
61 {
62 // Remove share access when handled
63 }
64 }
65 else
66 {
68 {
69 return STATUS_PENDING;
70 }
71
73
74 if (Fcb->ShareAccess.OpenCount > 0)
75 {
77 }
78
79 /* A file marked for deletion goes on the last handle. Truncate it first, so the cache
80 * manager drops its pages while there are still clusters to write them back to. */
81 if (Fcb->OpenHandleCount == 0 &&
83 {
84 DeletePending = TRUE;
85
87 {
91 }
92 }
93
94 /* Give back what writes reserved past the end of the file */
95 if (Fcb->OpenHandleCount == 0 &&
96 !DeletePending &&
98 !(DeviceExt->Flags & VCB_VOLUME_DISMOUNTED) &&
99 Fcb->RFCB.AllocationSize.QuadPart > (LONGLONG)ROUND_UP(Fcb->RFCB.FileSize.QuadPart, DeviceExt->NtfsInfo.BytesPerCluster))
100 {
102
104 if (!NT_SUCCESS(Status))
105 {
106 DPRINT1("Couldn't trim the allocation of '%wS' (Status %lx)\n", Fcb->ObjectName, Status);
107 }
108 else
109 {
111 }
112 }
113
115
116 /* Only once the cache map is gone. Freeing the record while a section still refers to
117 * it faults Mm on the next page-in. */
118 if (DeletePending)
119 {
121
122 MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForDelete);
123
124 /* Something may have been created in the directory since the delete
125 * was requested; freeing it now would orphan that child */
128 {
130
132 ExAcquireResourceSharedLite(&DeviceExt->IndexResource, TRUE);
134 ExReleaseResourceLite(&DeviceExt->IndexResource);
136
137 if (NT_SUCCESS(Status) && !Empty)
139 }
140
141 if (NT_SUCCESS(Status))
143
144 /* A cached FCB for a path that no longer exists would make it look present */
145 if (NT_SUCCESS(Status))
146 NtfsRemoveFCBFromTable(DeviceExt, Fcb);
147
148 if (!NT_SUCCESS(Status))
149 {
150 DPRINT1("ERROR: Failed to delete '%wS' (MFT record %I64u), Status %lx\n",
152 }
153
154 Fcb->Flags &= ~FCB_DELETE_PENDING;
155 }
156
157 if (Fcb->OpenHandleCount != 0)
158 {
159 // Remove share access when handled
160 }
161
163
165 }
166
167 return STATUS_SUCCESS;
168}
169
172{
173 PDEVICE_EXTENSION DeviceExtension;
177
178 DPRINT("NtfsCleanup() called\n");
179
180 DeviceObject = IrpContext->DeviceObject;
182 {
183 DPRINT("Cleaning up file system\n");
184 IrpContext->Irp->IoStatus.Information = 0;
185 return STATUS_SUCCESS;
186 }
187
188 FileObject = IrpContext->FileObject;
189 DeviceExtension = DeviceObject->DeviceExtension;
190
191 if (!ExAcquireResourceExclusiveLite(&DeviceExtension->DirResource,
193 {
194 return NtfsMarkIrpContextForQueue(IrpContext);
195 }
196
197 /* The handle is going away, and so are the locks it took */
199 {
200 FsRtlFastUnlockAll(&((PNTFS_FCB)FileObject->FsContext)->FileLock,
202 IoGetRequestorProcess(IrpContext->Irp),
203 NULL);
204 }
205
206 Status = NtfsCleanupFile(DeviceExtension, FileObject, BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT));
207
208 ExReleaseResourceLite(&DeviceExtension->DirResource);
209
210 if (Status == STATUS_PENDING)
211 {
212 return NtfsMarkIrpContextForQueue(IrpContext);
213 }
214
215 IrpContext->Irp->IoStatus.Information = 0;
216 return Status;
217}
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
@ Empty
Definition: npfs.h:126
NTSTATUS NtfsCleanup(PNTFS_IRP_CONTEXT IrpContext)
Definition: cleanup.c:171
NTSTATUS NtfsCleanupFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CanWait)
Definition: cleanup.c:40
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:652
#define VCB_VOLUME_DISMOUNTED
Definition: ntfs.h:148
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:505
struct _FCB * PNTFS_FCB
#define FCB_IS_VOLUME
Definition: ntfs.h:585
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1027
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
Status
Definition: gdiplustypes.h:24
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
NTSTATUS NtfsIsDirectoryEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ ULONGLONG MftIndex, _Out_ PBOOLEAN Empty)
Definition: mft.c:4554
NTSTATUS NtfsDeleteFileRecord(PDEVICE_EXTENSION DeviceExt, ULONGLONG MftIndex, BOOLEAN CaseSensitive)
Definition: mft.c:3470
NTSTATUS NtfsTrimAllocation(_In_ PNTFS_FCB Fcb)
Definition: mft.c:842
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:144
VOID NtfsRemoveFCBFromTable(_In_ PNTFS_VCB Vcb, _In_ PNTFS_FCB Fcb)
Definition: fcb.c:270
BOOLEAN NTAPI NtfsIsRegularFileObject(_In_ PFILE_OBJECT FileObject)
Definition: fcb.c:153
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3477
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1814
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4413
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:175
PFILE_OBJECT FileObject
Definition: ntfs.h:564
ULONG Flags
Definition: ntfs.h:556
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:563
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:618
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1009
ULONGLONG MFTIndex
Definition: ntfs.h:622
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
WCHAR * ObjectName
Definition: ntfs.h:603
ULONG OpenHandleCount
Definition: ntfs.h:619
ERESOURCE MainResource
Definition: ntfs.h:607
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
IO_STATUS_BLOCK IoStatus
ULONG OpenCount
Definition: iotypes.h:525
#define STATUS_PENDING
Definition: telnetd.h:14
int64_t LONGLONG
Definition: typedefs.h:68
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998