mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
sys: FspFileNodeNotifyChange: significant improvements
This commit is contained in:
parent
f0a0787f6b
commit
5824a24bf4
@ -138,8 +138,12 @@ static NTSTATUS FspFsvolCleanup(
|
||||
else
|
||||
{
|
||||
if (FileDesc->DidSetMetadata)
|
||||
/* invalidate the parent dir info */
|
||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||
{
|
||||
if (0 == FileNode->MainFileNode)
|
||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||
else
|
||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
|
||||
}
|
||||
@ -153,24 +157,46 @@ NTSTATUS FspFsvolCleanupComplete(
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
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)
|
||||
{
|
||||
FspFileNodeNotifyChange(FileNode,
|
||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
FILE_ACTION_REMOVED);
|
||||
|
||||
/* FspFileNodeNotifyChange also invalidates parent dir and volume info */
|
||||
NotifyFilter = FileNode->IsDirectory ?
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME;
|
||||
NotifyAction = FILE_ACTION_REMOVED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* invalidate the parent dir info */
|
||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||
/* do change notification for any metadata changes */
|
||||
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 (FileNode->TruncateOnClose)
|
||||
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
|
||||
if (0 != NotifyFilter)
|
||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, NotifyAction, TRUE);
|
||||
else
|
||||
{
|
||||
if (FileDesc->DidSetMetadata)
|
||||
{
|
||||
if (0 == FileNode->MainFileNode)
|
||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
||||
else
|
||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||
}
|
||||
}
|
||||
|
||||
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
|
||||
|
@ -1024,7 +1024,8 @@ NTSTATUS FspFsvolCreateComplete(
|
||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE);
|
||||
FspFileNodeNotifyChange(FileNode,
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,
|
||||
FILE_ACTION_MODIFIED);
|
||||
FILE_ACTION_MODIFIED,
|
||||
FALSE);
|
||||
|
||||
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)
|
||||
FspFileNodeNotifyChange(FileNode,
|
||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
FILE_ACTION_ADDED);
|
||||
FILE_ACTION_ADDED,
|
||||
TRUE);
|
||||
|
||||
FspFileNodeRelease(FileNode, Main);
|
||||
|
||||
|
@ -1344,7 +1344,9 @@ ULONG FspFileNodeStreamInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
||||
FileNode = FileNode->MainFileNode;
|
||||
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 FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||
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);
|
||||
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||
ULONG StreamInfoChangeNumber);
|
||||
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
||||
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);
|
||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||
@ -1746,7 +1746,7 @@ BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULON
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
||||
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
@ -1767,8 +1767,8 @@ static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
|
||||
}
|
||||
|
||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
||||
ULONG Filter, ULONG Action)
|
||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
||||
BOOLEAN InvalidateCaches)
|
||||
{
|
||||
/* 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);
|
||||
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 (FlagOn(Filter, FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME))
|
||||
@ -1804,25 +1791,40 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
||||
{
|
||||
case FILE_ACTION_ADDED:
|
||||
Action = FILE_ACTION_ADDED_STREAM;
|
||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||
break;
|
||||
case FILE_ACTION_REMOVED:
|
||||
Action = FILE_ACTION_REMOVED_STREAM;
|
||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||
break;
|
||||
case FILE_ACTION_MODIFIED:
|
||||
Action = FILE_ACTION_MODIFIED_STREAM;
|
||||
//FspFileNodeInvalidateStreamInfo(FileNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList,
|
||||
&FileNode->FileName,
|
||||
(USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer),
|
||||
0, Filter, Action);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
||||
|
@ -906,7 +906,7 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
|
||||
/* mark the file object as 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;
|
||||
@ -997,7 +997,7 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
|
||||
FileDesc->DidSetChangeTime = TRUE;
|
||||
|
||||
FileDesc->DidSetMetadata = TRUE;
|
||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED);
|
||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED, FALSE);
|
||||
}
|
||||
|
||||
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! */
|
||||
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;
|
||||
@ -1394,7 +1394,8 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
||||
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
||||
FspFileNodeNotifyChange(FileNode,
|
||||
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 =
|
||||
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! */
|
||||
FspFileNodeNotifyChange(FileNode,
|
||||
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, RequestDeviceObject) = 0;
|
||||
|
@ -487,7 +487,7 @@ NTSTATUS FspFsvolWriteComplete(
|
||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo, TRUE);
|
||||
|
||||
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) */
|
||||
if (SynchronousIo && !PagingIo)
|
||||
|
Loading…
x
Reference in New Issue
Block a user