mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: FspFileNodeNotifyChange: significant improvements
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user