sys: FSP_FILE_NODE/FSP_FILE_DESC: improve DeleteOnClose/DeletePending handling

This commit is contained in:
Bill Zissimopoulos 2016-02-03 11:50:50 -08:00
parent 93e3e37960
commit 72e0d5a96b
3 changed files with 16 additions and 21 deletions

View File

@ -451,7 +451,6 @@ NTSTATUS FspFsvolCreateComplete(
FSP_FILE_NODE *FileNode = FileDesc->FileNode; FSP_FILE_NODE *FileNode = FileDesc->FileNode;
FSP_FILE_NODE *OpenedFileNode; FSP_FILE_NODE *OpenedFileNode;
UNICODE_STRING ReparseFileName; UNICODE_STRING ReparseFileName;
BOOLEAN DeleteOnClose;
if (FspFsctlTransactCreateKind == Request->Kind) if (FspFsctlTransactCreateKind == Request->Kind)
{ {
@ -526,13 +525,11 @@ NTSTATUS FspFsvolCreateComplete(
FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes,
FILE_ATTRIBUTE_DIRECTORY); FILE_ATTRIBUTE_DIRECTORY);
FileDesc->UserContext2 = Response->Rsp.Create.Opened.UserContext2; FileDesc->UserContext2 = Response->Rsp.Create.Opened.UserContext2;
FileDesc->DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE);
DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE);
/* open the FileNode */ /* open the FileNode */
OpenedFileNode = FspFileNodeOpen(FileNode, FileObject, OpenedFileNode = FspFileNodeOpen(FileNode, FileObject,
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess, Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
DeleteOnClose,
&Result); &Result);
if (0 == OpenedFileNode) if (0 == OpenedFileNode)
{ {
@ -572,7 +569,7 @@ NTSTATUS FspFsvolCreateComplete(
BOOLEAN FlushImage = BOOLEAN FlushImage =
!FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) && !FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) &&
(FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) || (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
DeleteOnClose); BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE));
Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage);
} }

View File

@ -562,14 +562,10 @@ typedef struct
FSP_FILE_NODE_NONPAGED *NonPaged; FSP_FILE_NODE_NONPAGED *NonPaged;
/* interlocked access */ /* interlocked access */
LONG RefCount; LONG RefCount;
UINT32 DeletePending;
/* locked access (ContextTable lock) */ /* locked access (ContextTable lock) */
LONG OpenCount; LONG OpenCount;
SHARE_ACCESS ShareAccess; SHARE_ACCESS ShareAccess;
struct
{
UINT32 DeleteOnClose:1;
UINT32 DeletePending:1;
} Flags;
/* locked under Header.Resource */ /* locked under Header.Resource */
UINT64 InfoExpirationTime; UINT64 InfoExpirationTime;
UINT32 FileAttributes; UINT32 FileAttributes;
@ -592,6 +588,7 @@ typedef struct
{ {
FSP_FILE_NODE *FileNode; FSP_FILE_NODE *FileNode;
UINT64 UserContext2; UINT64 UserContext2;
BOOLEAN DeleteOnClose;
} FSP_FILE_DESC; } FSP_FILE_DESC;
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
ULONG ExtraSize, FSP_FILE_NODE **PFileNode); ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
@ -616,7 +613,7 @@ VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
UINT32 GrantedAccess, UINT32 ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult); UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);

View File

@ -17,7 +17,7 @@ VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
UINT32 GrantedAccess, UINT32 ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult); UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
@ -228,7 +228,7 @@ VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner)
} }
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
UINT32 GrantedAccess, UINT32 ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult) UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult)
{ {
/* /*
* Attempt to insert our FileNode into the volume device's generic table. * Attempt to insert our FileNode into the volume device's generic table.
@ -240,7 +240,7 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FILE_NODE *OpenedFileNode; FSP_FILE_NODE *OpenedFileNode;
BOOLEAN Inserted; BOOLEAN Inserted, DeletePending;
NTSTATUS Result; NTSTATUS Result;
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
@ -269,7 +269,9 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
*/ */
ASSERT(OpenedFileNode != FileNode); ASSERT(OpenedFileNode != FileNode);
if (OpenedFileNode->Flags.DeletePending) DeletePending = 0 != OpenedFileNode->DeletePending;
MemoryBarrier();
if (DeletePending)
{ {
Result = STATUS_DELETE_PENDING; Result = STATUS_DELETE_PENDING;
goto exit; goto exit;
@ -310,9 +312,6 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
{ {
FspFileNodeReference(OpenedFileNode); FspFileNodeReference(OpenedFileNode);
OpenedFileNode->OpenCount++; OpenedFileNode->OpenCount++;
if (DeleteOnClose)
OpenedFileNode->Flags.DeleteOnClose = TRUE;
} }
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
@ -331,13 +330,15 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
BOOLEAN Deleted = FALSE, DeletePending; BOOLEAN Deleted = FALSE, DeletePending;
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
if (FileNode->Flags.DeleteOnClose) if (FileDesc->DeleteOnClose)
FileNode->Flags.DeletePending = TRUE; FileNode->DeletePending = TRUE;
DeletePending = 0 != FileNode->Flags.DeletePending; DeletePending = 0 != FileNode->DeletePending;
MemoryBarrier();
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess); IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
if (0 == --FileNode->OpenCount) if (0 == --FileNode->OpenCount)