mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: FspFileNodeNotifyChange: significant improvements
This commit is contained in:
parent
f0a0787f6b
commit
5824a24bf4
@ -138,8 +138,12 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (FileDesc->DidSetMetadata)
|
if (FileDesc->DidSetMetadata)
|
||||||
/* invalidate the parent dir info */
|
{
|
||||||
|
if (0 == FileNode->MainFileNode)
|
||||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||||
|
else
|
||||||
|
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
|
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
|
||||||
}
|
}
|
||||||
@ -153,24 +157,46 @@ NTSTATUS FspFsvolCleanupComplete(
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
|
ULONG NotifyFilter, NotifyAction;
|
||||||
|
|
||||||
/* if the file is being deleted do a change notification */
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
|
/* do the appropriate change notification; also invalidate dirinfo/etc. caches */
|
||||||
if (Request->Req.Cleanup.Delete)
|
if (Request->Req.Cleanup.Delete)
|
||||||
{
|
{
|
||||||
FspFileNodeNotifyChange(FileNode,
|
NotifyFilter = FileNode->IsDirectory ?
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME;
|
||||||
FILE_ACTION_REMOVED);
|
NotifyAction = FILE_ACTION_REMOVED;
|
||||||
|
|
||||||
/* FspFileNodeNotifyChange also invalidates parent dir and volume info */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* invalidate the parent dir info */
|
/* do change notification for any metadata changes */
|
||||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
NotifyFilter = 0;
|
||||||
|
if (Request->Req.Cleanup.SetAllocationSize)
|
||||||
|
NotifyFilter |= FILE_NOTIFY_CHANGE_SIZE;
|
||||||
|
if (Request->Req.Cleanup.SetArchiveBit)
|
||||||
|
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
|
||||||
|
#if 0
|
||||||
|
if (Request->Req.Cleanup.SetLastAccessTime)
|
||||||
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
||||||
|
#endif
|
||||||
|
if (Request->Req.Cleanup.SetLastWriteTime)
|
||||||
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||||
|
NotifyAction = FILE_ACTION_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the file is being resized invalidate the volume info */
|
if (0 != NotifyFilter)
|
||||||
if (FileNode->TruncateOnClose)
|
FspFileNodeNotifyChange(FileNode, NotifyFilter, NotifyAction, TRUE);
|
||||||
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
|
else
|
||||||
|
{
|
||||||
|
if (FileDesc->DidSetMetadata)
|
||||||
|
{
|
||||||
|
if (0 == FileNode->MainFileNode)
|
||||||
|
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||||
|
else
|
||||||
|
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
|
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
|
||||||
|
@ -1024,7 +1024,8 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE);
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,
|
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,
|
||||||
FILE_ACTION_MODIFIED);
|
FILE_ACTION_MODIFIED,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||||
|
|
||||||
@ -1115,7 +1116,8 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
|
|||||||
if (FILE_CREATED == Response->IoStatus.Information)
|
if (FILE_CREATED == Response->IoStatus.Information)
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_ADDED);
|
FILE_ACTION_ADDED,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
|
||||||
|
@ -1344,7 +1344,9 @@ ULONG FspFileNodeStreamInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
|||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
return FileNode->StreamInfoChangeNumber;
|
return FileNode->StreamInfoChangeNumber;
|
||||||
}
|
}
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action);
|
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
||||||
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
||||||
|
BOOLEAN InvalidateCaches);
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||||
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||||
|
@ -74,9 +74,9 @@ BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer,
|
|||||||
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
||||||
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||||
ULONG StreamInfoChangeNumber);
|
ULONG StreamInfoChangeNumber);
|
||||||
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
||||||
ULONG Filter, ULONG Action);
|
BOOLEAN InvalidateCaches);
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||||
@ -1746,7 +1746,7 @@ BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULON
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
@ -1767,8 +1767,8 @@ static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
|||||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
|
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
||||||
ULONG Filter, ULONG Action)
|
BOOLEAN InvalidateCaches)
|
||||||
{
|
{
|
||||||
/* FileNode must be acquired (exclusive or shared) Main */
|
/* FileNode must be acquired (exclusive or shared) Main */
|
||||||
|
|
||||||
@ -1778,19 +1778,6 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
UNICODE_STRING Parent, Suffix;
|
UNICODE_STRING Parent, Suffix;
|
||||||
|
|
||||||
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
|
|
||||||
|
|
||||||
switch (Action)
|
|
||||||
{
|
|
||||||
case FILE_ACTION_ADDED:
|
|
||||||
case FILE_ACTION_REMOVED:
|
|
||||||
case FILE_ACTION_RENAMED_OLD_NAME:
|
|
||||||
case FILE_ACTION_RENAMED_NEW_NAME:
|
|
||||||
FspFsvolDeviceInvalidateVolumeInfo(FsvolDeviceObject);
|
|
||||||
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
{
|
{
|
||||||
if (FlagOn(Filter, FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME))
|
if (FlagOn(Filter, FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME))
|
||||||
@ -1804,26 +1791,41 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
|||||||
{
|
{
|
||||||
case FILE_ACTION_ADDED:
|
case FILE_ACTION_ADDED:
|
||||||
Action = FILE_ACTION_ADDED_STREAM;
|
Action = FILE_ACTION_ADDED_STREAM;
|
||||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
break;
|
break;
|
||||||
case FILE_ACTION_REMOVED:
|
case FILE_ACTION_REMOVED:
|
||||||
Action = FILE_ACTION_REMOVED_STREAM;
|
Action = FILE_ACTION_REMOVED_STREAM;
|
||||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
break;
|
break;
|
||||||
case FILE_ACTION_MODIFIED:
|
case FILE_ACTION_MODIFIED:
|
||||||
Action = FILE_ACTION_MODIFIED_STREAM;
|
Action = FILE_ACTION_MODIFIED_STREAM;
|
||||||
//FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Filter)
|
if (0 != Filter)
|
||||||
|
{
|
||||||
|
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
|
||||||
|
|
||||||
|
if (InvalidateCaches)
|
||||||
|
{
|
||||||
|
FspFsvolDeviceInvalidateVolumeInfo(FsvolDeviceObject);
|
||||||
|
if (0 == FileNode->MainFileNode)
|
||||||
|
{
|
||||||
|
if (sizeof(WCHAR) == FileNode->FileName.Length && L'\\' == FileNode->FileName.Buffer[0])
|
||||||
|
; /* root does not have a parent */
|
||||||
|
else
|
||||||
|
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
FspNotifyReportChange(
|
FspNotifyReportChange(
|
||||||
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList,
|
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList,
|
||||||
&FileNode->FileName,
|
&FileNode->FileName,
|
||||||
(USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer),
|
(USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer),
|
||||||
0, Filter, Action);
|
0, Filter, Action);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
||||||
{
|
{
|
||||||
|
@ -906,7 +906,7 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
|
|||||||
/* mark the file object as modified */
|
/* mark the file object as modified */
|
||||||
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
||||||
|
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -997,7 +997,7 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
|
|||||||
FileDesc->DidSetChangeTime = TRUE;
|
FileDesc->DidSetChangeTime = TRUE;
|
||||||
|
|
||||||
FileDesc->DidSetMetadata = TRUE;
|
FileDesc->DidSetMetadata = TRUE;
|
||||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED);
|
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -1047,7 +1047,7 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
|
|||||||
/* mark the file object as modified -- FastFat does this only for Allocation though! */
|
/* mark the file object as modified -- FastFat does this only for Allocation though! */
|
||||||
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
||||||
|
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -1394,7 +1394,8 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
|||||||
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_RENAMED_OLD_NAME);
|
FILE_ACTION_RENAMED_OLD_NAME,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
NewFileName.Length = NewFileName.MaximumLength =
|
NewFileName.Length = NewFileName.MaximumLength =
|
||||||
Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR);
|
Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR);
|
||||||
@ -1405,7 +1406,8 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
|||||||
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_RENAMED_NEW_NAME);
|
FILE_ACTION_RENAMED_NEW_NAME,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
FspIopRequestContext(Request, RequestFileNode) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
||||||
|
@ -487,7 +487,7 @@ NTSTATUS FspFsvolWriteComplete(
|
|||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo, TRUE);
|
||||||
|
|
||||||
if (OriginalFileSize != Response->Rsp.Write.FileInfo.FileSize)
|
if (OriginalFileSize != Response->Rsp.Write.FileInfo.FileSize)
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
||||||
|
|
||||||
/* update the current file offset if synchronous I/O (and not paging I/O) */
|
/* update the current file offset if synchronous I/O (and not paging I/O) */
|
||||||
if (SynchronousIo && !PagingIo)
|
if (SynchronousIo && !PagingIo)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user