mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 11:38:39 -05:00 
			
		
		
		
	sys: FspFileNodeNotifyChange: significant improvements
This commit is contained in:
		| @@ -138,8 +138,12 @@ static NTSTATUS FspFsvolCleanup( | |||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         if (FileDesc->DidSetMetadata) |         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! */ |         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,25 +1791,40 @@ 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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user