[BTRFS] Upgrade to BtrFS 1.0.1

CID 1419459, 1419378

CORE-13896
This commit is contained in:
Pierre Schweitzer 2017-10-16 20:05:33 +02:00
parent 194df1ba58
commit 4672b2ba5e
15 changed files with 329 additions and 152 deletions

View file

@ -2112,7 +2112,7 @@ end:
// update open FCBs // update open FCBs
// FIXME - speed this up(?) // FIXME - speed this up(?)
ExAcquireResourceSharedLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_shared(Vcb);
le = Vcb->all_fcbs.Flink; le = Vcb->all_fcbs.Flink;
while (le != &Vcb->all_fcbs) { while (le != &Vcb->all_fcbs) {
@ -2153,7 +2153,7 @@ end:
le = le->Flink; le = le->Flink;
} }
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} else } else
do_rollback(Vcb, &rollback); do_rollback(Vcb, &rollback);

View file

@ -1352,7 +1352,7 @@ void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_
return; return;
} }
ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(fcb->Vcb);
le = fcb->hardlinks.Flink; le = fcb->hardlinks.Flink;
while (le != &fcb->hardlinks) { while (le != &fcb->hardlinks) {
@ -1419,7 +1419,7 @@ void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_
le = le->Flink; le = le->Flink;
} }
ExReleaseResourceLite(&fcb->Vcb->fcb_lock); release_fcb_lock(fcb->Vcb);
} }
void mark_fcb_dirty(_In_ fcb* fcb) { void mark_fcb_dirty(_In_ fcb* fcb) {
@ -1698,14 +1698,14 @@ static NTSTATUS close_file(_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp) {
Vcb = fcb->Vcb; Vcb = fcb->Vcb;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
if (fileref) if (fileref)
free_fileref(fcb->Vcb, fileref); free_fileref(fcb->Vcb, fileref);
else else
free_fcb(Vcb, fcb); free_fcb(Vcb, fcb);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1804,10 +1804,10 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
KeSetTimer(&Vcb->flush_thread_timer, time, NULL); // trigger the timer early KeSetTimer(&Vcb->flush_thread_timer, time, NULL); // trigger the timer early
KeWaitForSingleObject(&Vcb->flush_thread_finished, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Vcb->flush_thread_finished, Executive, KernelMode, FALSE, NULL);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, Vcb->volume_fcb); free_fcb(Vcb, Vcb->volume_fcb);
free_fcb(Vcb, Vcb->dummy_fcb); free_fcb(Vcb, Vcb->dummy_fcb);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
if (Vcb->root_file) if (Vcb->root_file)
ObDereferenceObject(Vcb->root_file); ObDereferenceObject(Vcb->root_file);
@ -1817,9 +1817,9 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
chunk* c = CONTAINING_RECORD(le, chunk, list_entry); chunk* c = CONTAINING_RECORD(le, chunk, list_entry);
if (c->cache) { if (c->cache) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, c->cache); free_fcb(Vcb, c->cache);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
c->cache = NULL; c->cache = NULL;
} }
@ -1855,9 +1855,9 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
ExFreePool(c->devices); ExFreePool(c->devices);
if (c->cache) { if (c->cache) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, c->cache); free_fcb(Vcb, c->cache);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} }
ExDeleteResourceLite(&c->range_locks_lock); ExDeleteResourceLite(&c->range_locks_lock);
@ -1915,7 +1915,7 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
ZwClose(Vcb->flush_thread_handle); ZwClose(Vcb->flush_thread_handle);
} }
NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) { NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) {
LARGE_INTEGER newlength, time; LARGE_INTEGER newlength, time;
BTRFS_TIME now; BTRFS_TIME now;
NTSTATUS Status; NTSTATUS Status;
@ -1995,6 +1995,18 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _I
} }
fileref->fcb->deleted = TRUE; fileref->fcb->deleted = TRUE;
le = fileref->children.Flink;
while (le != &fileref->children) {
file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
if (fr2->fcb->ads) {
fr2->fcb->deleted = TRUE;
mark_fcb_dirty(fr2->fcb);
}
le = le->Flink;
}
} }
if (fileref->dc) { if (fileref->dc) {
@ -2024,11 +2036,25 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _I
mark_fcb_dirty(fileref->fcb); // so ROOT_ITEM gets updated mark_fcb_dirty(fileref->fcb); // so ROOT_ITEM gets updated
} else { } else {
LIST_ENTRY* le;
// FIXME - we need a lock here // FIXME - we need a lock here
RemoveEntryList(&fileref->fcb->subvol->list_entry); RemoveEntryList(&fileref->fcb->subvol->list_entry);
InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry); InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry);
le = fileref->children.Flink;
while (le != &fileref->children) {
file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
if (fr2->fcb->ads) {
fr2->fcb->deleted = TRUE;
mark_fcb_dirty(fr2->fcb);
}
le = le->Flink;
}
} }
} }
} else { } else {
@ -2209,18 +2235,18 @@ static NTSTATUS drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
locked = FALSE; locked = FALSE;
// fcb_lock needs to be acquired before fcb->Header.Resource // fcb_lock needs to be acquired before fcb->Header.Resource
ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(fcb->Vcb);
Status = delete_fileref(fileref, FileObject, Irp, &rollback); Status = delete_fileref(fileref, FileObject, Irp, &rollback);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ERR("delete_fileref returned %08x\n", Status); ERR("delete_fileref returned %08x\n", Status);
do_rollback(fcb->Vcb, &rollback); do_rollback(fcb->Vcb, &rollback);
ExReleaseResourceLite(&fcb->Vcb->fcb_lock); release_fcb_lock(fcb->Vcb);
ExReleaseResourceLite(&fcb->Vcb->tree_lock); ExReleaseResourceLite(&fcb->Vcb->tree_lock);
goto exit; goto exit;
} }
ExReleaseResourceLite(&fcb->Vcb->fcb_lock); release_fcb_lock(fcb->Vcb);
locked = FALSE; locked = FALSE;
@ -4522,19 +4548,19 @@ exit2:
if (Vcb->root_file) if (Vcb->root_file)
ObDereferenceObject(Vcb->root_file); ObDereferenceObject(Vcb->root_file);
else if (Vcb->root_fileref) { else if (Vcb->root_fileref) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, Vcb->root_fileref); free_fileref(Vcb, Vcb->root_fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} else if (root_fcb) { } else if (root_fcb) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, root_fcb); free_fcb(Vcb, root_fcb);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} }
if (Vcb->volume_fcb) { if (Vcb->volume_fcb) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, Vcb->volume_fcb); free_fcb(Vcb, Vcb->volume_fcb);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} }
ExDeleteResourceLite(&Vcb->tree_lock); ExDeleteResourceLite(&Vcb->tree_lock);

View file

@ -53,8 +53,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1 FILEVERSION 1,0,1,0
PRODUCTVERSION 1,0,0,1 PRODUCTVERSION 1,0,1,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -70,12 +70,12 @@ BEGIN
BLOCK "080904b0" BLOCK "080904b0"
BEGIN BEGIN
VALUE "FileDescription", "WinBtrfs" VALUE "FileDescription", "WinBtrfs"
VALUE "FileVersion", "1.0" VALUE "FileVersion", "1.0.1"
VALUE "InternalName", "btrfs" VALUE "InternalName", "btrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-17" VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-17"
VALUE "OriginalFilename", "btrfs.sys" VALUE "OriginalFilename", "btrfs.sys"
VALUE "ProductName", "WinBtrfs" VALUE "ProductName", "WinBtrfs"
VALUE "ProductVersion", "1.0" VALUE "ProductVersion", "1.0.1"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -170,6 +170,9 @@ typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
#define _Create_lock_level_(a) #define _Create_lock_level_(a)
#define _Lock_level_order_(a,b) #define _Lock_level_order_(a,b)
#define _Has_lock_level_(a) #define _Has_lock_level_(a)
#define _Requires_lock_not_held_(a)
#define _Acquires_exclusive_lock_(a)
#define _Acquires_shared_lock_(a)
#endif #endif
#endif #endif
@ -634,6 +637,9 @@ typedef struct {
UINT64 create_total_time; UINT64 create_total_time;
UINT64 open_fcb_calls; UINT64 open_fcb_calls;
UINT64 open_fcb_time; UINT64 open_fcb_time;
UINT64 open_fileref_child_calls;
UINT64 open_fileref_child_time;
UINT64 fcb_lock_time;
} debug_stats; } debug_stats;
#endif #endif
@ -890,6 +896,52 @@ typedef struct {
LIST_ENTRY list_entry; LIST_ENTRY list_entry;
} name_bit; } name_bit;
_Requires_lock_not_held_(Vcb->fcb_lock)
_Acquires_shared_lock_(Vcb->fcb_lock)
static __inline void acquire_fcb_lock_shared(device_extension* Vcb) {
#ifdef DEBUG_STATS
LARGE_INTEGER time1, time2;
if (ExAcquireResourceSharedLite(&Vcb->fcb_lock, FALSE))
return;
time1 = KeQueryPerformanceCounter(NULL);
#endif
ExAcquireResourceSharedLite(&Vcb->fcb_lock, TRUE);
#ifdef DEBUG_STATS
time2 = KeQueryPerformanceCounter(NULL);
Vcb->stats.fcb_lock_time += time2.QuadPart - time1.QuadPart;
#endif
}
_Requires_lock_not_held_(Vcb->fcb_lock)
_Acquires_exclusive_lock_(Vcb->fcb_lock)
static __inline void acquire_fcb_lock_exclusive(device_extension* Vcb) {
#ifdef DEBUG_STATS
LARGE_INTEGER time1, time2;
if (ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, FALSE))
return;
time1 = KeQueryPerformanceCounter(NULL);
#endif
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
#ifdef DEBUG_STATS
time2 = KeQueryPerformanceCounter(NULL);
Vcb->stats.fcb_lock_time += time2.QuadPart - time1.QuadPart;
#endif
}
_Requires_lock_held_(Vcb->fcb_lock)
_Releases_lock_(Vcb->fcb_lock)
static __inline void release_fcb_lock(device_extension* Vcb) {
ExReleaseResourceLite(&Vcb->fcb_lock);
}
static __inline void* map_user_buffer(PIRP Irp, ULONG priority) { static __inline void* map_user_buffer(PIRP Irp, ULONG priority) {
if (!Irp->MdlAddress) { if (!Irp->MdlAddress) {
return Irp->UserBuffer; return Irp->UserBuffer;
@ -1043,7 +1095,7 @@ WCHAR* file_desc(_In_ PFILE_OBJECT FileObject);
WCHAR* file_desc_fileref(_In_ file_ref* fileref); WCHAR* file_desc_fileref(_In_ file_ref* fileref);
void mark_fcb_dirty(_In_ fcb* fcb); void mark_fcb_dirty(_In_ fcb* fcb);
void mark_fileref_dirty(_In_ file_ref* fileref); void mark_fileref_dirty(_In_ file_ref* fileref);
NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback); NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback);
void chunk_lock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ UINT64 start, _In_ UINT64 length); void chunk_lock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ UINT64 start, _In_ UINT64 length);
void chunk_unlock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ UINT64 start, _In_ UINT64 length); void chunk_unlock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ UINT64 start, _In_ UINT64 length);
void init_device(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ BOOL get_nums); void init_device(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ BOOL get_nums);

View file

@ -1418,6 +1418,13 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv
return STATUS_OBJECT_PATH_NOT_FOUND; return STATUS_OBJECT_PATH_NOT_FOUND;
} }
// if path starts with two backslashes, ignore one of them
if (fnus2.Length >= 2 * sizeof(WCHAR) && fnus2.Buffer[1] == '\\') {
fnus2.Buffer++;
fnus2.Length -= sizeof(WCHAR);
fnus2.MaximumLength -= sizeof(WCHAR);
}
if (fnus2.Length == sizeof(WCHAR)) { if (fnus2.Length == sizeof(WCHAR)) {
if (Vcb->root_fileref->open_count == 0 && !(Vcb->Vpb->Flags & VPB_MOUNTED)) // don't allow root to be opened on unmounted FS if (Vcb->root_fileref->open_count == 0 && !(Vcb->Vpb->Flags & VPB_MOUNTED)) // don't allow root to be opened on unmounted FS
return STATUS_DEVICE_NOT_READY; return STATUS_DEVICE_NOT_READY;
@ -1487,8 +1494,19 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv
name_bit* nb = CONTAINING_RECORD(le, name_bit, list_entry); name_bit* nb = CONTAINING_RECORD(le, name_bit, list_entry);
BOOL lastpart = le->Flink == &parts || (has_stream && le->Flink->Flink == &parts); BOOL lastpart = le->Flink == &parts || (has_stream && le->Flink->Flink == &parts);
BOOL streampart = has_stream && le->Flink == &parts; BOOL streampart = has_stream && le->Flink == &parts;
#ifdef DEBUG_STATS
LARGE_INTEGER time1, time2;
#endif
#ifdef DEBUG_STATS
time1 = KeQueryPerformanceCounter(NULL);
#endif
Status = open_fileref_child(Vcb, sf, &nb->us, case_sensitive, lastpart, streampart, pooltype, &sf2, Irp); Status = open_fileref_child(Vcb, sf, &nb->us, case_sensitive, lastpart, streampart, pooltype, &sf2, Irp);
#ifdef DEBUG_STATS
time2 = KeQueryPerformanceCounter(NULL);
Vcb->stats.open_fileref_child_calls++;
Vcb->stats.open_fileref_child_time += time2.QuadPart - time1.QuadPart;
#endif
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
if (Status == STATUS_OBJECT_PATH_NOT_FOUND || Status == STATUS_OBJECT_NAME_NOT_FOUND) if (Status == STATUS_OBJECT_PATH_NOT_FOUND || Status == STATUS_OBJECT_NAME_NOT_FOUND)
TRACE("open_fileref_child returned %08x\n", Status); TRACE("open_fileref_child returned %08x\n", Status);
@ -1655,6 +1673,9 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr
if (parfileref->fcb == Vcb->dummy_fcb) if (parfileref->fcb == Vcb->dummy_fcb)
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
if (options & FILE_DIRECTORY_FILE && IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY)
return STATUS_INVALID_PARAMETER;
Status = RtlUnicodeToUTF8N(NULL, 0, &utf8len, fpus->Buffer, fpus->Length); Status = RtlUnicodeToUTF8N(NULL, 0, &utf8len, fpus->Buffer, fpus->Length);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ERR("RtlUnicodeToUTF8N returned %08x\n", Status); ERR("RtlUnicodeToUTF8N returned %08x\n", Status);
@ -1701,9 +1722,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr
TRACE("requested attributes = %x\n", IrpSp->Parameters.Create.FileAttributes); TRACE("requested attributes = %x\n", IrpSp->Parameters.Create.FileAttributes);
IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE; defda = 0;
defda = FILE_ATTRIBUTE_ARCHIVE;
if (utf8[0] == '.') if (utf8[0] == '.')
defda |= FILE_ATTRIBUTE_HIDDEN; defda |= FILE_ATTRIBUTE_HIDDEN;
@ -1714,6 +1733,11 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr
} else } else
IrpSp->Parameters.Create.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; IrpSp->Parameters.Create.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
if (!(IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
defda |= FILE_ATTRIBUTE_ARCHIVE;
}
TRACE("defda = %x\n", defda); TRACE("defda = %x\n", defda);
if (IrpSp->Parameters.Create.FileAttributes == FILE_ATTRIBUTE_NORMAL) if (IrpSp->Parameters.Create.FileAttributes == FILE_ATTRIBUTE_NORMAL)
@ -2235,7 +2259,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_
*pfileref = fileref; *pfileref = fileref;
send_notification_fileref(parfileref, options & FILE_DIRECTORY_FILE ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_ADDED, &fileref->dc->name); send_notification_fileref(parfileref, FILE_NOTIFY_CHANGE_STREAM_NAME, FILE_ACTION_ADDED_STREAM, &fileref->dc->name);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -2279,6 +2303,9 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R
if (Vcb->readonly) if (Vcb->readonly)
return STATUS_MEDIA_WRITE_PROTECTED; return STATUS_MEDIA_WRITE_PROTECTED;
if (options & FILE_DELETE_ON_CLOSE && IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_READONLY)
return STATUS_CANNOT_DELETE;
dsus.Buffer = datasuf; dsus.Buffer = datasuf;
dsus.Length = dsus.MaximumLength = (USHORT)wcslen(datasuf) * sizeof(WCHAR); dsus.Length = dsus.MaximumLength = (USHORT)wcslen(datasuf) * sizeof(WCHAR);
fpus.Buffer = NULL; fpus.Buffer = NULL;
@ -2836,7 +2863,7 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
goto exit; goto exit;
} }
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
if (options & FILE_OPEN_BY_FILE_ID) { if (options & FILE_OPEN_BY_FILE_ID) {
if (fn.Length == sizeof(UINT64) && related && RequestedDisposition == FILE_OPEN) { if (fn.Length == sizeof(UINT64) && related && RequestedDisposition == FILE_OPEN) {
@ -2857,13 +2884,13 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
} else { } else {
WARN("FILE_OPEN_BY_FILE_ID only supported for inodes\n"); WARN("FILE_OPEN_BY_FILE_ID only supported for inodes\n");
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
} else { } else {
if (related && fn.Length != 0 && fn.Buffer[0] == '\\') { if (related && fn.Length != 0 && fn.Buffer[0] == '\\') {
Status = STATUS_OBJECT_NAME_INVALID; Status = STATUS_INVALID_PARAMETER;
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -2922,7 +2949,7 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
Irp->Tail.Overlay.AuxiliaryBuffer = (void*)data; Irp->Tail.Overlay.AuxiliaryBuffer = (void*)data;
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -2937,23 +2964,23 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
Status = STATUS_OBJECT_NAME_COLLISION; Status = STATUS_OBJECT_NAME_COLLISION;
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
} else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
if (RequestedDisposition == FILE_OPEN || RequestedDisposition == FILE_OVERWRITE) { if (RequestedDisposition == FILE_OPEN || RequestedDisposition == FILE_OVERWRITE) {
TRACE("file doesn't exist, returning STATUS_OBJECT_NAME_NOT_FOUND\n"); TRACE("file doesn't exist, returning STATUS_OBJECT_NAME_NOT_FOUND\n");
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
} else if (Status == STATUS_OBJECT_PATH_NOT_FOUND) { } else if (Status == STATUS_OBJECT_PATH_NOT_FOUND) {
TRACE("open_fileref returned %08x\n", Status); TRACE("open_fileref returned %08x\n", Status);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} else { } else {
ERR("open_fileref returned %08x\n", Status); ERR("open_fileref returned %08x\n", Status);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -2961,7 +2988,7 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
file_ref* sf; file_ref* sf;
BOOL readonly; BOOL readonly;
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
if (RequestedDisposition == FILE_SUPERSEDE || RequestedDisposition == FILE_OVERWRITE || RequestedDisposition == FILE_OVERWRITE_IF) { if (RequestedDisposition == FILE_SUPERSEDE || RequestedDisposition == FILE_OVERWRITE || RequestedDisposition == FILE_OVERWRITE_IF) {
LARGE_INTEGER zero; LARGE_INTEGER zero;
@ -2972,9 +2999,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
if (fileref->fcb->type == BTRFS_TYPE_DIRECTORY || is_subvol_readonly(fileref->fcb->subvol, Irp)) { if (fileref->fcb->type == BTRFS_TYPE_DIRECTORY || is_subvol_readonly(fileref->fcb->subvol, Irp)) {
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -2982,9 +3009,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
if (Vcb->readonly) { if (Vcb->readonly) {
Status = STATUS_MEDIA_WRITE_PROTECTED; Status = STATUS_MEDIA_WRITE_PROTECTED;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -2993,9 +3020,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
if (!MmCanFileBeTruncated(&fileref->fcb->nonpaged->segment_object, &zero)) { if (!MmCanFileBeTruncated(&fileref->fcb->nonpaged->segment_object, &zero)) {
Status = STATUS_USER_MAPPED_FILE; Status = STATUS_USER_MAPPED_FILE;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3012,9 +3039,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
TRACE("SeAccessCheck failed, returning %08x\n", Status); TRACE("SeAccessCheck failed, returning %08x\n", Status);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3031,9 +3058,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
TRACE("could not open as deletion pending\n"); TRACE("could not open as deletion pending\n");
Status = STATUS_DELETE_PENDING; Status = STATUS_DELETE_PENDING;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3043,6 +3070,16 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
readonly = (!fileref->fcb->ads && fileref->fcb->atts & FILE_ATTRIBUTE_READONLY) || (fileref->fcb->ads && fileref->parent->fcb->atts & FILE_ATTRIBUTE_READONLY) || readonly = (!fileref->fcb->ads && fileref->fcb->atts & FILE_ATTRIBUTE_READONLY) || (fileref->fcb->ads && fileref->parent->fcb->atts & FILE_ATTRIBUTE_READONLY) ||
is_subvol_readonly(fileref->fcb->subvol, Irp) || fileref->fcb == Vcb->dummy_fcb || Vcb->readonly; is_subvol_readonly(fileref->fcb->subvol, Irp) || fileref->fcb == Vcb->dummy_fcb || Vcb->readonly;
if (options & FILE_DELETE_ON_CLOSE && (fileref == Vcb->root_fileref || readonly)) {
Status = STATUS_CANNOT_DELETE;
acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref);
release_fcb_lock(Vcb);
goto exit;
}
if (readonly) { if (readonly) {
ACCESS_MASK allowed; ACCESS_MASK allowed;
@ -3070,25 +3107,14 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
} else if (granted_access & ~allowed) { } else if (granted_access & ~allowed) {
Status = Vcb->readonly ? STATUS_MEDIA_WRITE_PROTECTED : STATUS_ACCESS_DENIED; Status = Vcb->readonly ? STATUS_MEDIA_WRITE_PROTECTED : STATUS_ACCESS_DENIED;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
} }
if (options & FILE_DELETE_ON_CLOSE && (fileref == Vcb->root_fileref || Vcb->readonly ||
is_subvol_readonly(fileref->fcb->subvol, Irp) || readonly)) {
Status = STATUS_CANNOT_DELETE;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock);
goto exit;
}
if ((fileref->fcb->type == BTRFS_TYPE_SYMLINK || fileref->fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT) && !(options & FILE_OPEN_REPARSE_POINT)) { if ((fileref->fcb->type == BTRFS_TYPE_SYMLINK || fileref->fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT) && !(options & FILE_OPEN_REPARSE_POINT)) {
REPARSE_DATA_BUFFER* data; REPARSE_DATA_BUFFER* data;
@ -3112,9 +3138,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
Irp->Tail.Overlay.AuxiliaryBuffer = (void*)data; Irp->Tail.Overlay.AuxiliaryBuffer = (void*)data;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3124,9 +3150,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
if (options & FILE_NON_DIRECTORY_FILE && !(fileref->fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT)) { if (options & FILE_NON_DIRECTORY_FILE && !(fileref->fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT)) {
Status = STATUS_FILE_IS_A_DIRECTORY; Status = STATUS_FILE_IS_A_DIRECTORY;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3134,9 +3160,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
TRACE("returning STATUS_NOT_A_DIRECTORY (type = %u, %S)\n", fileref->fcb->type, file_desc_fileref(fileref)); TRACE("returning STATUS_NOT_A_DIRECTORY (type = %u, %S)\n", fileref->fcb->type, file_desc_fileref(fileref));
Status = STATUS_NOT_A_DIRECTORY; Status = STATUS_NOT_A_DIRECTORY;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3150,9 +3176,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
else else
WARN("IoCheckShareAccess failed, returning %08x\n", Status); WARN("IoCheckShareAccess failed, returning %08x\n", Status);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3167,9 +3193,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3186,13 +3212,24 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
if (!fileref->fcb->ads && (IrpSp->Parameters.Create.FileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != ((fileref->fcb->atts & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))) {
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref);
release_fcb_lock(Vcb);
Status = STATUS_ACCESS_DENIED;
goto exit;
}
if (fileref->fcb->ads) { if (fileref->fcb->ads) {
Status = stream_set_end_of_file_information(Vcb, 0, fileref->fcb, fileref, FALSE); Status = stream_set_end_of_file_information(Vcb, 0, fileref->fcb, fileref, FALSE);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
@ -3200,9 +3237,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3213,9 +3250,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3229,15 +3266,17 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
} }
if (!fileref->fcb->ads) { if (!fileref->fcb->ads) {
LIST_ENTRY* le;
if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) { if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) {
ULONG offset; ULONG offset;
FILE_FULL_EA_INFORMATION* eainfo; FILE_FULL_EA_INFORMATION* eainfo;
@ -3248,9 +3287,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3285,9 +3324,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3304,6 +3343,41 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
fileref->fcb->ealen = 0; fileref->fcb->ealen = 0;
} }
} }
// remove streams and send notifications
le = fileref->fcb->dir_children_index.Flink;
while (le != &fileref->fcb->dir_children_index) {
dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_index);
LIST_ENTRY* le2 = le->Flink;
if (dc->index == 0) {
if (!dc->fileref) {
file_ref* fr2;
Status = open_fileref_child(Vcb, fileref, &dc->name, TRUE, TRUE, TRUE, PagedPool, &fr2, NULL);
if (!NT_SUCCESS(Status))
WARN("open_fileref_child returned %08x\n", Status);
}
if (dc->fileref) {
send_notification_fcb(fileref, FILE_NOTIFY_CHANGE_STREAM_NAME, FILE_ACTION_REMOVED_STREAM, &dc->name);
Status = delete_fileref(dc->fileref, NULL, NULL, rollback);
if (!NT_SUCCESS(Status)) {
ERR("delete_fileref returned %08x\n", Status);
acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref);
release_fcb_lock(Vcb);
goto exit;
}
}
} else
break;
le = le2;
}
} }
KeQuerySystemTime(&time); KeQuerySystemTime(&time);
@ -3355,9 +3429,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3379,9 +3453,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fileref); free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto exit; goto exit;
} }
@ -3467,8 +3541,8 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
#ifdef DEBUG_STATS #ifdef DEBUG_STATS
open_type = 2; open_type = 2;
#endif #endif
Status = file_create(Irp, DeviceObject->DeviceExtension, FileObject, related, loaded_related, &fn, RequestedDisposition, options, rollback); Status = file_create(Irp, Vcb, FileObject, related, loaded_related, &fn, RequestedDisposition, options, rollback);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
Irp->IoStatus.Information = NT_SUCCESS(Status) ? FILE_CREATED : 0; Irp->IoStatus.Information = NT_SUCCESS(Status) ? FILE_CREATED : 0;
} }
@ -3478,9 +3552,9 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
exit: exit:
if (loaded_related) { if (loaded_related) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, related); free_fileref(Vcb, related);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} }
if (Status == STATUS_SUCCESS) { if (Status == STATUS_SUCCESS) {

View file

@ -628,7 +628,7 @@ static NTSTATUS query_directory(PIRP Irp) {
return STATUS_NO_MORE_FILES; return STATUS_NO_MORE_FILES;
ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
ExAcquireResourceSharedLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_shared(Vcb);
TRACE("%S\n", file_desc(IrpSp->FileObject)); TRACE("%S\n", file_desc(IrpSp->FileObject));
@ -658,8 +658,6 @@ static NTSTATUS query_directory(PIRP Irp) {
TRACE(" unknown flags: %u\n", flags); TRACE(" unknown flags: %u\n", flags);
} }
initial = !ccb->query_string.Buffer;
if (IrpSp->Flags & SL_RESTART_SCAN) { if (IrpSp->Flags & SL_RESTART_SCAN) {
ccb->query_dir_offset = 0; ccb->query_dir_offset = 0;
@ -667,8 +665,13 @@ static NTSTATUS query_directory(PIRP Irp) {
RtlFreeUnicodeString(&ccb->query_string); RtlFreeUnicodeString(&ccb->query_string);
ccb->query_string.Buffer = NULL; ccb->query_string.Buffer = NULL;
} }
ccb->has_wildcard = FALSE;
ccb->specific_file = FALSE;
} }
initial = !ccb->query_string.Buffer;
if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) { if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) {
TRACE("QD filename: %.*S\n", IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR), IrpSp->Parameters.QueryDirectory.FileName->Buffer); TRACE("QD filename: %.*S\n", IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR), IrpSp->Parameters.QueryDirectory.FileName->Buffer);
@ -906,7 +909,7 @@ end:
ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock); ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock);
end2: end2:
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);
TRACE("returning %08x\n", Status); TRACE("returning %08x\n", Status);

View file

@ -188,7 +188,7 @@ static NTSTATUS set_disposition_information(device_extension* Vcb, PIRP Irp, PFI
if (!fileref) if (!fileref)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE); ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE);
@ -235,7 +235,7 @@ static NTSTATUS set_disposition_information(device_extension* Vcb, PIRP Irp, PFI
end: end:
ExReleaseResourceLite(fcb->Header.Resource); ExReleaseResourceLite(fcb->Header.Resource);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
// send notification that directory is about to be deleted // send notification that directory is about to be deleted
if (NT_SUCCESS(Status) && fdi->DeleteFile && fcb->type == BTRFS_TYPE_DIRECTORY) { if (NT_SUCCESS(Status) && fdi->DeleteFile && fcb->type == BTRFS_TYPE_DIRECTORY) {
@ -1348,7 +1348,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB
} }
ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE); ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE);
if (fcb->ads) { if (fcb->ads) {
@ -1885,7 +1885,7 @@ end:
do_rollback(Vcb, &rollback); do_rollback(Vcb, &rollback);
ExReleaseResourceLite(fcb->Header.Resource); ExReleaseResourceLite(fcb->Header.Resource);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);
return Status; return Status;
@ -1913,7 +1913,7 @@ NTSTATUS stream_set_end_of_file_information(device_extension* Vcb, UINT16 end, f
TRACE("extending stream to %llx bytes\n", end); TRACE("extending stream to %llx bytes\n", end);
if (end > fcb->adsmaxlen) { if (end > fcb->adsmaxlen) {
ERR("error - xattr too long (%llu > %u)\n", end, fcb->adsmaxlen); ERR("error - xattr too long (%u > %u)\n", end, fcb->adsmaxlen);
return STATUS_DISK_FULL; return STATUS_DISK_FULL;
} }
@ -2009,7 +2009,7 @@ static NTSTATUS set_end_of_file_information(device_extension* Vcb, PIRP Irp, PFI
set_size = TRUE; set_size = TRUE;
} }
filter = FILE_NOTIFY_CHANGE_SIZE; filter = FILE_NOTIFY_CHANGE_STREAM_SIZE;
if (!ccb->user_set_write_time) { if (!ccb->user_set_write_time) {
KeQuerySystemTime(&time); KeQuerySystemTime(&time);
@ -2020,7 +2020,7 @@ static NTSTATUS set_end_of_file_information(device_extension* Vcb, PIRP Irp, PFI
mark_fcb_dirty(fileref->parent->fcb); mark_fcb_dirty(fileref->parent->fcb);
} }
send_notification_fcb(fileref->parent, filter, FILE_ACTION_MODIFIED, &fileref->dc->name); send_notification_fcb(fileref->parent, filter, FILE_ACTION_MODIFIED_STREAM, &fileref->dc->name);
goto end; goto end;
} }
@ -2182,7 +2182,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE
} }
ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE); ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE);
if (fcb->type == BTRFS_TYPE_DIRECTORY) { if (fcb->type == BTRFS_TYPE_DIRECTORY) {
@ -2451,7 +2451,7 @@ end:
do_rollback(Vcb, &rollback); do_rollback(Vcb, &rollback);
ExReleaseResourceLite(fcb->Header.Resource); ExReleaseResourceLite(fcb->Header.Resource);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);
return Status; return Status;
@ -3472,7 +3472,7 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_
len = bytes_needed; len = bytes_needed;
} }
} else { } else {
ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(fcb->Vcb);
if (IsListEmpty(&fcb->hardlinks)) { if (IsListEmpty(&fcb->hardlinks)) {
bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) + fileref->dc->name.Length - sizeof(WCHAR); bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) + fileref->dc->name.Length - sizeof(WCHAR);
@ -3565,7 +3565,7 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_
} }
} }
ExReleaseResourceLite(&fcb->Vcb->fcb_lock); release_fcb_lock(fcb->Vcb);
} }
fli->BytesNeeded = bytes_needed; fli->BytesNeeded = bytes_needed;

View file

@ -7289,6 +7289,8 @@ NTSTATUS do_write(device_extension* Vcb, PIRP Irp) {
#ifdef DEBUG_STATS #ifdef DEBUG_STATS
static void print_stats(device_extension* Vcb) { static void print_stats(device_extension* Vcb) {
LARGE_INTEGER freq;
ERR("READ STATS:\n"); ERR("READ STATS:\n");
ERR("number of reads: %llu\n", Vcb->stats.num_reads); ERR("number of reads: %llu\n", Vcb->stats.num_reads);
ERR("data read: %llu bytes\n", Vcb->stats.data_read); ERR("data read: %llu bytes\n", Vcb->stats.data_read);
@ -7297,7 +7299,9 @@ static void print_stats(device_extension* Vcb) {
ERR("disk time taken: %llu\n", Vcb->stats.read_disk_time); ERR("disk time taken: %llu\n", Vcb->stats.read_disk_time);
ERR("other time taken: %llu\n", Vcb->stats.read_total_time - Vcb->stats.read_csum_time - Vcb->stats.read_disk_time); ERR("other time taken: %llu\n", Vcb->stats.read_total_time - Vcb->stats.read_csum_time - Vcb->stats.read_disk_time);
ERR("OPEN STATS:\n"); KeQueryPerformanceCounter(&freq);
ERR("OPEN STATS (freq = %llu):\n", freq.QuadPart);
ERR("number of opens: %llu\n", Vcb->stats.num_opens); ERR("number of opens: %llu\n", Vcb->stats.num_opens);
ERR("total time taken: %llu\n", Vcb->stats.open_total_time); ERR("total time taken: %llu\n", Vcb->stats.open_total_time);
ERR("number of overwrites: %llu\n", Vcb->stats.num_overwrites); ERR("number of overwrites: %llu\n", Vcb->stats.num_overwrites);
@ -7305,6 +7309,9 @@ static void print_stats(device_extension* Vcb) {
ERR("number of creates: %llu\n", Vcb->stats.num_creates); ERR("number of creates: %llu\n", Vcb->stats.num_creates);
ERR("calls to open_fcb: %llu\n", Vcb->stats.open_fcb_calls); ERR("calls to open_fcb: %llu\n", Vcb->stats.open_fcb_calls);
ERR("time spent in open_fcb: %llu\n", Vcb->stats.open_fcb_time); ERR("time spent in open_fcb: %llu\n", Vcb->stats.open_fcb_time);
ERR("calls to open_fileref_child: %llu\n", Vcb->stats.open_fileref_child_calls);
ERR("time spent in open_fileref_child: %llu\n", Vcb->stats.open_fileref_child_time);
ERR("time spent waiting for fcb_lock: %llu\n", Vcb->stats.fcb_lock_time);
ERR("total time taken: %llu\n", Vcb->stats.create_total_time); ERR("total time taken: %llu\n", Vcb->stats.create_total_time);
RtlZeroMemory(&Vcb->stats, sizeof(debug_stats)); RtlZeroMemory(&Vcb->stats, sizeof(debug_stats));

View file

@ -1002,10 +1002,10 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo
rootfcb->inode_item_changed = TRUE; rootfcb->inode_item_changed = TRUE;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
InsertTailList(&r->fcbs, &rootfcb->list_entry); InsertTailList(&r->fcbs, &rootfcb->list_entry);
InsertTailList(&Vcb->all_fcbs, &rootfcb->list_entry_all); InsertTailList(&Vcb->all_fcbs, &rootfcb->list_entry_all);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
rootfcb->Header.IsFastIoPossible = fast_io_possible(rootfcb); rootfcb->Header.IsFastIoPossible = fast_io_possible(rootfcb);
rootfcb->Header.AllocationSize.QuadPart = 0; rootfcb->Header.AllocationSize.QuadPart = 0;
@ -1049,9 +1049,9 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo
if (!fr) { if (!fr) {
ERR("out of memory\n"); ERR("out of memory\n");
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, rootfcb); free_fcb(Vcb, rootfcb);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
goto end; goto end;
@ -1073,9 +1073,9 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo
fr->fcb->hash_ptrs = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG); fr->fcb->hash_ptrs = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG);
if (!fr->fcb->hash_ptrs) { if (!fr->fcb->hash_ptrs) {
ERR("out of memory\n"); ERR("out of memory\n");
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fr); free_fileref(Vcb, fr);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
goto end; goto end;
} }
@ -1085,9 +1085,9 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo
fr->fcb->hash_ptrs_uc = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG); fr->fcb->hash_ptrs_uc = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG);
if (!fr->fcb->hash_ptrs_uc) { if (!fr->fcb->hash_ptrs_uc) {
ERR("out of memory\n"); ERR("out of memory\n");
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fr); free_fileref(Vcb, fr);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
goto end; goto end;
} }
@ -1155,9 +1155,9 @@ end:
end2: end2:
if (fr) { if (fr) {
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, fr); free_fileref(Vcb, fr);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
} }
return Status; return Status;
@ -2194,15 +2194,15 @@ static NTSTATUS lock_volume(device_extension* Vcb, PIRP Irp) {
if (Vcb->locked) if (Vcb->locked)
return STATUS_SUCCESS; return STATUS_SUCCESS;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) { if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) {
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
goto end; goto end;
} }
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
if (Vcb->balance.thread && KeReadStateEvent(&Vcb->balance.event)) { if (Vcb->balance.thread && KeReadStateEvent(&Vcb->balance.event)) {
ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE); ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
@ -2377,6 +2377,7 @@ static NTSTATUS invalidate_volumes(PIRP Irp) {
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ERR("do_write returned %08x\n", Status); ERR("do_write returned %08x\n", Status);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);
ExFreePool(newvpb);
goto end; goto end;
} }
@ -3742,7 +3743,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data
name.Length = name.MaximumLength = bmn->namelen; name.Length = name.MaximumLength = bmn->namelen;
name.Buffer = bmn->name; name.Buffer = bmn->name;
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
Status = find_file_in_dir(&name, parfcb, &subvol, &inode, &dc, TRUE); Status = find_file_in_dir(&name, parfcb, &subvol, &inode, &dc, TRUE);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) { if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) {
@ -3982,7 +3983,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
end: end:
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExFreePool(utf8.Buffer); ExFreePool(utf8.Buffer);
@ -4429,11 +4430,11 @@ static NTSTATUS get_subvol_path(device_extension* Vcb, UINT64 id, WCHAR* out, UL
return STATUS_INTERNAL_ERROR; return STATUS_INTERNAL_ERROR;
} }
ExAcquireResourceSharedLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_shared(Vcb);
Status = open_fileref_by_inode(Vcb, r, r->root_item.objid, &fr, Irp); Status = open_fileref_by_inode(Vcb, r, r->root_item.objid, &fr, Irp);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ERR("open_fileref_by_inode returned %08x\n", Status); ERR("open_fileref_by_inode returned %08x\n", Status);
return Status; return Status;
} }
@ -4451,7 +4452,7 @@ static NTSTATUS get_subvol_path(device_extension* Vcb, UINT64 id, WCHAR* out, UL
free_fileref(Vcb, fr); free_fileref(Vcb, fr);
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
return Status; return Status;
} }

View file

@ -161,7 +161,7 @@ static NTSTATUS pnp_cancel_remove_device(PDEVICE_OBJECT DeviceObject) {
ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) { if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) {
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
@ -175,7 +175,7 @@ static NTSTATUS pnp_cancel_remove_device(PDEVICE_OBJECT DeviceObject) {
} }
end: end:
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -187,7 +187,7 @@ NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE); ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); acquire_fcb_lock_exclusive(Vcb);
if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) { if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) {
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
@ -216,7 +216,7 @@ NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
end: end:
ExReleaseResourceLite(&Vcb->fcb_lock); release_fcb_lock(Vcb);
ExReleaseResourceLite(&Vcb->tree_lock); ExReleaseResourceLite(&Vcb->tree_lock);

View file

@ -3209,17 +3209,6 @@ NTSTATUS do_read(PIRP Irp, BOOLEAN wait, ULONG* bytes_read) {
return STATUS_PENDING; return STATUS_PENDING;
} }
if (!(Irp->Flags & IRP_PAGING_IO) && FileObject->SectionObjectPointer->DataSectionObject) {
IO_STATUS_BLOCK iosb;
CcFlushCache(FileObject->SectionObjectPointer, &IrpSp->Parameters.Read.ByteOffset, length, &iosb);
if (!NT_SUCCESS(iosb.Status)) {
ERR("CcFlushCache returned %08x\n", iosb.Status);
return iosb.Status;
}
}
if (fcb->ads) if (fcb->ads)
Status = read_stream(fcb, data, start, length, bytes_read); Status = read_stream(fcb, data, start, length, bytes_read);
else else
@ -3325,6 +3314,16 @@ NTSTATUS drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
if (Irp->Flags & IRP_PAGING_IO) if (Irp->Flags & IRP_PAGING_IO)
wait = TRUE; wait = TRUE;
if (!(Irp->Flags & IRP_PAGING_IO) && FileObject->SectionObjectPointer->DataSectionObject) {
IO_STATUS_BLOCK iosb;
CcFlushCache(FileObject->SectionObjectPointer, &IrpSp->Parameters.Read.ByteOffset, IrpSp->Parameters.Read.Length, &iosb);
if (!NT_SUCCESS(iosb.Status)) {
ERR("CcFlushCache returned %08x\n", iosb.Status);
return iosb.Status;
}
}
if (!ExIsResourceAcquiredSharedLite(fcb->Header.Resource)) { if (!ExIsResourceAcquiredSharedLite(fcb->Header.Resource)) {
if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) { if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
Status = STATUS_PENDING; Status = STATUS_PENDING;

View file

@ -289,6 +289,10 @@ NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
// IFSTest insists on this, for some reason...
if (Irp->UserBuffer)
return STATUS_INVALID_PARAMETER;
fcb = FileObject->FsContext; fcb = FileObject->FsContext;
ccb = FileObject->FsContext2; ccb = FileObject->FsContext2;
@ -297,9 +301,7 @@ NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
// It isn't documented what permissions FSCTL_SET_REPARSE_POINT needs, but CreateSymbolicLinkW if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA))) {
// creates a file with FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE.
if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_ATTRIBUTES)) {
WARN("insufficient privileges\n"); WARN("insufficient privileges\n");
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
} }
@ -333,7 +335,13 @@ NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
if (buflen < sizeof(ULONG)) { if (buflen < sizeof(ULONG)) {
WARN("buffer was not long enough to hold tag\n"); WARN("buffer was not long enough to hold tag\n");
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_BUFFER_SIZE;
goto end;
}
Status = FsRtlValidateReparsePointBuffer(buflen, rdb);
if (!NT_SUCCESS(Status)) {
ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status);
goto end; goto end;
} }

View file

@ -913,8 +913,7 @@ void mountmgr_thread(_In_ void* context) {
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08x\n", Status); ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08x\n", Status);
else if (mmps.Size > 0) {
if (mmps.Size > 0) {
MOUNTMGR_MOUNT_POINTS* mmps2; MOUNTMGR_MOUNT_POINTS* mmps2;
mmps2 = ExAllocatePoolWithTag(NonPagedPool, mmps.Size, ALLOC_TAG); mmps2 = ExAllocatePoolWithTag(NonPagedPool, mmps.Size, ALLOC_TAG);

View file

@ -983,9 +983,9 @@ static BOOL allow_degraded_mount(BTRFS_UUID* uuid) {
ZwClose(h); ZwClose(h);
end:
ExFreePool(kvfi); ExFreePool(kvfi);
end:
ExFreePool(path.Buffer); ExFreePool(path.Buffer);
return degraded; return degraded;

View file

@ -4335,6 +4335,11 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} _SEH2_END; } _SEH2_END;
if (changed_length) {
send_notification_fcb(fcb->ads ? fileref->parent : fileref, fcb->ads ? FILE_NOTIFY_CHANGE_STREAM_SIZE : FILE_NOTIFY_CHANGE_SIZE,
fcb->ads ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED, fcb->ads && fileref->dc ? &fileref->dc->name : NULL);
}
goto end; goto end;
} }
@ -4553,7 +4558,9 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void
fileref->parent->fcb->inode_item_changed = TRUE; fileref->parent->fcb->inode_item_changed = TRUE;
if (changed_length) if (changed_length)
filter |= FILE_NOTIFY_CHANGE_SIZE; filter |= FILE_NOTIFY_CHANGE_STREAM_SIZE;
filter |= FILE_NOTIFY_CHANGE_STREAM_WRITE;
} }
if (!ccb->user_set_write_time) { if (!ccb->user_set_write_time) {
@ -4585,7 +4592,8 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
if (filter != 0) if (filter != 0)
send_notification_fcb(fcb->ads ? fileref->parent : fileref, filter, FILE_ACTION_MODIFIED, fcb->ads && fileref->dc ? &fileref->dc->name : NULL); send_notification_fcb(fcb->ads ? fileref->parent : fileref, filter, fcb->ads ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED,
fcb->ads && fileref->dc ? &fileref->dc->name : NULL);
end: end:
if (NT_SUCCESS(Status) && FileObject->Flags & FO_SYNCHRONOUS_IO && !paging_io) { if (NT_SUCCESS(Status) && FileObject->Flags & FO_SYNCHRONOUS_IO && !paging_io) {