sys,dll: Cleanup, file times overhaul

This commit is contained in:
Bill Zissimopoulos 2016-12-23 15:30:39 -08:00
parent 6e52def53c
commit 69f6f661ba
9 changed files with 87 additions and 30 deletions

View File

@ -300,6 +300,7 @@ typedef struct
UINT64 CreationTime;
UINT64 LastAccessTime;
UINT64 LastWriteTime;
UINT64 ChangeTime;
} Basic;
struct
{

View File

@ -473,6 +473,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* @param LastWriteTime
* Last write time to apply to the file or directory. If the value 0 is sent, the last
* write time should not be changed.
* @param ChangeTime
* Change time to apply to the file or directory. If the value 0 is sent, the change time
* should not be changed.
* @param FileInfo [out]
* Pointer to a structure that will receive the file information on successful return
* from this call. This information includes file attributes, file times, etc.
@ -481,7 +484,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
*/
NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, UINT32 FileAttributes,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
FSP_FSCTL_FILE_INFO *FileInfo);
/**
* Set file/allocation size.

View File

@ -999,6 +999,7 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
Request->Req.SetInformation.Info.Basic.CreationTime,
Request->Req.SetInformation.Info.Basic.LastAccessTime,
Request->Req.SetInformation.Info.Basic.LastWriteTime,
Request->Req.SetInformation.Info.Basic.ChangeTime,
&FileInfo);
break;
case 19/*FileAllocationInformation*/:

View File

@ -1272,7 +1272,7 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, UINT32 FileAttributes,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
FSP_FSCTL_FILE_INFO *FileInfo)
{
struct fuse *f = FileSystem->UserContext;

View File

@ -111,10 +111,11 @@ static NTSTATUS FspFsvolCleanup(
Request->Req.Cleanup.UserContext2 = FileDesc->UserContext2;
Request->Req.Cleanup.Delete = DeletePending;
Request->Req.Cleanup.SetAllocationSize = SetAllocationSize;
Request->Req.Cleanup.SetArchiveBit = FileModified;
Request->Req.Cleanup.SetArchiveBit = FileModified && !FileDesc->DidSetFileAttributes;
Request->Req.Cleanup.SetLastAccessTime = !FileDesc->DidSetLastAccessTime;
Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime;
Request->Req.Cleanup.SetChangeTime = FileModified;
Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetBasicInfo) &&
!FileDesc->DidSetChangeTime;
FspFileNodeAcquireExclusive(FileNode, Pgio);
@ -136,9 +137,9 @@ static NTSTATUS FspFsvolCleanup(
return FSP_STATUS_IOQ_POST_BEST_EFFORT;
else
{
/* if the file is being resized invalidate the volume info */
if (FileNode->TruncateOnClose)
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
if (FileDesc->DidSetBasicInfo)
/* invalidate the parent dir info */
FspFileNodeInvalidateParentDirInfo(FileNode);
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
}
@ -155,12 +156,22 @@ NTSTATUS FspFsvolCleanupComplete(
/* if the file is being deleted do a change notification */
if (Request->Req.Cleanup.Delete)
{
FspFileNodeNotifyChange(FileNode,
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
FILE_ACTION_REMOVED);
/* if the file is being resized invalidate the volume info */
else if (FileNode->TruncateOnClose)
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
/* FspFileNodeNotifyChange also invalidates parent dir and volume info */
}
else
{
/* invalidate the parent dir info */
FspFileNodeInvalidateParentDirInfo(FileNode);
/* if the file is being resized invalidate the volume info */
if (FileNode->TruncateOnClose)
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
}
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
}

View File

@ -1197,11 +1197,12 @@ typedef struct
{
FSP_FILE_NODE *FileNode;
UINT64 UserContext2;
BOOLEAN CaseSensitive;
BOOLEAN HasTraversePrivilege;
BOOLEAN DeleteOnClose;
BOOLEAN DidSetLastAccessTime, DidSetLastWriteTime;
BOOLEAN DirectoryHasSuchFile;
UINT32
CaseSensitive:1, HasTraversePrivilege:1, DeleteOnClose:1,
DidSetBasicInfo:1,
DidSetFileAttributes:1,
DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1,
DirectoryHasSuchFile:1;
UNICODE_STRING DirectoryPattern;
UINT64 DirectoryOffset;
UINT64 DirInfo;
@ -1313,6 +1314,7 @@ ULONG FspFileNodeDirInfoChangeNumber(FSP_FILE_NODE *FileNode)
{
return FileNode->DirInfoChangeNumber;
}
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode);
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,

View File

@ -67,6 +67,9 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG DirInfoChangeNumber);
static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode);
static VOID FspFileNodeInvalidateDirInfoByName(PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING FileName);
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode);
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
@ -128,6 +131,8 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
// !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo)
// !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo)
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo)
#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfoByName)
#pragma alloc_text(PAGE, FspFileNodeInvalidateParentDirInfo)
// !#pragma alloc_text(PAGE, FspFileNodeReferenceStreamInfo)
// !#pragma alloc_text(PAGE, FspFileNodeSetStreamInfo)
// !#pragma alloc_text(PAGE, FspFileNodeTrySetStreamInfo)
@ -1649,6 +1654,40 @@ static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode)
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, DirInfo);
}
static VOID FspFileNodeInvalidateDirInfoByName(PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING FileName)
{
PAGED_CODE();
FSP_FILE_NODE *FileNode;
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
FileNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, FileName);
if (0 != FileNode)
FspFileNodeReference(FileNode);
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
if (0 != FileNode)
{
FspFileNodeInvalidateDirInfo(FileNode);
FspFileNodeDereference(FileNode);
}
}
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode)
{
PAGED_CODE();
if (sizeof(WCHAR) == FileNode->FileName.Length && L'\\' == FileNode->FileName.Buffer[0])
return; /* root does not have a parent */
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
UNICODE_STRING Parent, Suffix;
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
}
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
{
// !PAGED_CODE();
@ -1738,7 +1777,6 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
UNICODE_STRING Parent, Suffix;
FSP_FILE_NODE *ParentNode;
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
@ -1746,22 +1784,10 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
{
case FILE_ACTION_ADDED:
case FILE_ACTION_REMOVED:
//case FILE_ACTION_MODIFIED:
case FILE_ACTION_RENAMED_OLD_NAME:
case FILE_ACTION_RENAMED_NEW_NAME:
FspFsvolDeviceInvalidateVolumeInfo(FsvolDeviceObject);
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
ParentNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, &Parent);
if (0 != ParentNode)
FspFileNodeReference(ParentNode);
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
if (0 != ParentNode)
{
FspFileNodeInvalidateDirInfo(ParentNode);
FspFileNodeDereference(ParentNode);
}
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
break;
}

View File

@ -951,6 +951,7 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
Request->Req.SetInformation.Info.Basic.CreationTime = Info->CreationTime.QuadPart;
Request->Req.SetInformation.Info.Basic.LastAccessTime = Info->LastAccessTime.QuadPart;
Request->Req.SetInformation.Info.Basic.LastWriteTime = Info->LastWriteTime.QuadPart;
Request->Req.SetInformation.Info.Basic.ChangeTime = Info->ChangeTime.QuadPart;
}
else
{
@ -973,9 +974,15 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo, FALSE);
if ((UINT32)-1 != Request->Req.SetInformation.Info.Basic.FileAttributes)
{
FileDesc->DidSetFileAttributes = TRUE;
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
}
if (0 != Request->Req.SetInformation.Info.Basic.CreationTime)
{
FileDesc->DidSetCreationTime = TRUE;
NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
}
if (0 != Request->Req.SetInformation.Info.Basic.LastAccessTime)
{
FileDesc->DidSetLastAccessTime = TRUE;
@ -986,6 +993,10 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
FileDesc->DidSetLastWriteTime = TRUE;
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
}
if (0 != Request->Req.SetInformation.Info.Basic.ChangeTime)
FileDesc->DidSetChangeTime = TRUE;
FileDesc->DidSetBasicInfo = TRUE;
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED);
}

View File

@ -1118,7 +1118,7 @@ static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode0, UINT32 FileAttributes,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
FSP_FSCTL_FILE_INFO *FileInfo)
{
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
@ -1136,6 +1136,8 @@ static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
FileNode->FileInfo.LastAccessTime = LastAccessTime;
if (0 != LastWriteTime)
FileNode->FileInfo.LastWriteTime = LastWriteTime;
if (0 != ChangeTime)
FileNode->FileInfo.ChangeTime = ChangeTime;
MemfsFileNodeGetFileInfo(FileNode, FileInfo);