mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: FspFileNodeRename: acquire resource of descendant file nodes when renaming them
This commit is contained in:
parent
5a5a1008de
commit
5773c6eab7
@ -348,7 +348,8 @@ typedef struct
|
|||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
} QueryStreamInformation;
|
} QueryStreamInformation;
|
||||||
} Req;
|
} Req;
|
||||||
FSP_FSCTL_TRANSACT_BUF FileName; /* {Create,Cleanup,SetInformation/{...},QueryDirectory} */
|
FSP_FSCTL_TRANSACT_BUF FileName;
|
||||||
|
/* Create,Cleanup,SetInformation{Disposition,Rename},FileSystemControl{ReparsePoint} */
|
||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||||
} FSP_FSCTL_TRANSACT_REQ;
|
} FSP_FSCTL_TRANSACT_REQ;
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -514,13 +514,13 @@ NTSTATUS FspNotifyFullReportChange(
|
|||||||
#define FspNotifyCleanupAll(NS, NL)\
|
#define FspNotifyCleanupAll(NS, NL)\
|
||||||
FsRtlNotifyCleanupAll(NS, NL)
|
FsRtlNotifyCleanupAll(NS, NL)
|
||||||
#define FspNotifyChangeDirectory(NS, NL, FC, FN, WT, CF, I)\
|
#define FspNotifyChangeDirectory(NS, NL, FC, FN, WT, CF, I)\
|
||||||
FspNotifyFullChangeDirectory(NS, NL, FC, (PSTRING)FN, WT, FALSE, CF, I, 0, 0)
|
FspNotifyFullChangeDirectory(NS, NL, FC, (PSTRING)(FN), WT, FALSE, CF, I, 0, 0)
|
||||||
#define FspNotifyCleanup(NS, NL, FC)\
|
#define FspNotifyCleanup(NS, NL, FC)\
|
||||||
FsRtlNotifyCleanup(NS, NL, FC)
|
FsRtlNotifyCleanup(NS, NL, FC)
|
||||||
#define FspNotifyDeletePending(NS, NL, FC)\
|
#define FspNotifyDeletePending(NS, NL, FC)\
|
||||||
FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0)
|
FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0)
|
||||||
#define FspNotifyReportChange(NS, NL, FN, FO, SN, F, A)\
|
#define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\
|
||||||
FspNotifyFullReportChange(NS, NL, (PSTRING)FN, FO, (PSTRING)SN, 0, F, A, 0)
|
FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0)
|
||||||
|
|
||||||
/* utility: synchronous work queue */
|
/* utility: synchronous work queue */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -1026,6 +1026,27 @@ VOID FspFileNodeConvertExclusiveToSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
|
|||||||
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
|
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);
|
||||||
|
static inline
|
||||||
|
VOID FspFileNodeAcquireSharedForeign(FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
if (0 != FileNode->MainFileNode)
|
||||||
|
FileNode = FileNode->MainFileNode;
|
||||||
|
ExAcquireResourceSharedLite(FileNode->Header.Resource, TRUE);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspFileNodeAcquireExclusiveForeign(FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
if (0 != FileNode->MainFileNode)
|
||||||
|
FileNode = FileNode->MainFileNode;
|
||||||
|
ExAcquireResourceExclusiveLite(FileNode->Header.Resource, TRUE);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspFileNodeReleaseForeign(FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
if (0 != FileNode->MainFileNode)
|
||||||
|
FileNode = FileNode->MainFileNode;
|
||||||
|
ExReleaseResourceLite(FileNode->Header.Resource);
|
||||||
|
}
|
||||||
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, NTSTATUS *PResult);
|
UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult);
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
@ -803,6 +803,25 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
|||||||
|
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* FspFileNodeRename may block, because it attempts to acquire the Main
|
||||||
|
* resource of descendant file nodes. FspFileNodeRename is called at the
|
||||||
|
* completion path of IRP_MJ_SET_INFORMATION[Rename] and an IRP completion
|
||||||
|
* path should not block, with the notable exception of Rename.
|
||||||
|
*
|
||||||
|
* The original reason that Rename completion is allowed to block was that
|
||||||
|
* it was observed that IoCompleteRequest of a Rename could sometimes
|
||||||
|
* trigger a recursive call into the FSD (likely due to a filter). WinFsp
|
||||||
|
* was modified to accommodate this by allowing this recursive call to
|
||||||
|
* proceed on a different thread.
|
||||||
|
*
|
||||||
|
* Since WinFsp can already accommodate blocking on Rename completions,
|
||||||
|
* it is safe to acquire the Main resource of descendant file nodes.
|
||||||
|
*
|
||||||
|
* Note also that there can only be one rename at a time because of the
|
||||||
|
* device's FileRenameResource.
|
||||||
|
*/
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
@ -862,6 +881,9 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
|||||||
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
||||||
ASSERT(DescendantFileNode->FileName.Length >= FileNameLength);
|
ASSERT(DescendantFileNode->FileName.Length >= FileNameLength);
|
||||||
|
|
||||||
|
if (0 != DescendantFileNodeIndex)
|
||||||
|
FspFileNodeAcquireExclusiveForeign(DescendantFileNode);
|
||||||
|
|
||||||
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &DescendantFileNode->FileName, &Deleted);
|
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &DescendantFileNode->FileName, &Deleted);
|
||||||
ASSERT(Deleted);
|
ASSERT(Deleted);
|
||||||
|
|
||||||
@ -888,6 +910,9 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
|||||||
FspFsvolDeviceInsertContextByName(FsvolDeviceObject, &DescendantFileNode->FileName, DescendantFileNode,
|
FspFsvolDeviceInsertContextByName(FsvolDeviceObject, &DescendantFileNode->FileName, DescendantFileNode,
|
||||||
&DescendantFileNode->ContextByNameElementStorage, &Inserted);
|
&DescendantFileNode->ContextByNameElementStorage, &Inserted);
|
||||||
ASSERT(Inserted);
|
ASSERT(Inserted);
|
||||||
|
|
||||||
|
if (0 != DescendantFileNodeIndex)
|
||||||
|
FspFileNodeReleaseForeign(DescendantFileNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user