sys: FspFileNodeNotifyChange: significant improvements

This commit is contained in:
Bill Zissimopoulos 2016-12-27 21:30:56 -08:00
parent f0a0787f6b
commit 5824a24bf4
6 changed files with 78 additions and 44 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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)