Skip to content

Commit

Permalink
remove oplock stuff until next version, when it can be tested properly
Browse files Browse the repository at this point in the history
  • Loading branch information
maharmstone committed Sep 4, 2017
1 parent 0319dbf commit b495e3a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 210 deletions.
35 changes: 2 additions & 33 deletions src/btrfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ tCcCopyReadEx fCcCopyReadEx;
tCcCopyWriteEx fCcCopyWriteEx;
tCcSetAdditionalCacheAttributesEx fCcSetAdditionalCacheAttributesEx;
tFsRtlUpdateDiskCounters fFsRtlUpdateDiskCounters;
tFsRtlCheckLockForOplockRequest fFsRtlCheckLockForOplockRequest;
BOOL diskacc = FALSE;
void *notification_entry = NULL, *notification_entry2 = NULL, *notification_entry3 = NULL;
ERESOURCE pdo_list_lock, mapping_lock;
Expand Down Expand Up @@ -529,13 +528,6 @@ static NTSTATUS drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Ir

Irp->IoStatus.Information = 0;

Status = FsRtlCheckOplock(fcb_oplock(fcb), Irp, NULL, NULL, NULL);

if (Status != STATUS_SUCCESS) {
Irp->IoStatus.Status = Status;
goto end;
}

fcb->Header.IsFastIoPossible = fast_io_possible(fcb);

Status = STATUS_SUCCESS;
Expand Down Expand Up @@ -1458,8 +1450,6 @@ void free_fcb(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_exten
if (fcb->list_entry_all.Flink)
RemoveEntryList(&fcb->list_entry_all);

FsRtlUninitializeOplock(fcb_oplock(fcb));

ExDeleteResourceLite(&fcb->nonpaged->resource);
ExDeleteResourceLite(&fcb->nonpaged->paging_resource);
ExDeleteResourceLite(&fcb->nonpaged->dir_children_lock);
Expand Down Expand Up @@ -1611,6 +1601,8 @@ static NTSTATUS close_file(_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp) {
LONG open_files;
device_extension* Vcb;

UNUSED(Irp);

TRACE("FileObject = %p\n", FileObject);

fcb = FileObject->FsContext;
Expand All @@ -1628,13 +1620,6 @@ static NTSTATUS close_file(_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp) {
// FIXME - make sure notification gets sent if file is being deleted

if (ccb) {
if (!(FileObject->Flags & FO_CLEANUP_COMPLETE)) {
TRACE("file was not cleaned up\n");

// This forces the FileObject to be cleaned up - see fastfat
FsRtlCheckOplockEx(fcb_oplock(fcb), Irp, 0, NULL, NULL, NULL);
}

if (ccb->query_string.Buffer)
RtlFreeUnicodeString(&ccb->query_string);

Expand Down Expand Up @@ -2123,10 +2108,6 @@ static NTSTATUS drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
goto exit;
}

Status = FsRtlCheckOplock(fcb_oplock(fcb), Irp, NULL, NULL, NULL);
if (Status != STATUS_SUCCESS)
goto exit;

// We have to use the pointer to Vcb stored in the fcb, as we can receive cleanup
// messages belonging to other devices.

Expand Down Expand Up @@ -4817,14 +4798,6 @@ static NTSTATUS drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp

TRACE("lock control\n");

Status = FsRtlCheckOplock(fcb_oplock(fcb), Irp, NULL, NULL, NULL);

if (Status != STATUS_SUCCESS) {
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
goto exit;
}

Status = FsRtlProcessFileLock(&fcb->lock, Irp, NULL);

fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
Expand Down Expand Up @@ -5435,16 +5408,12 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi

RtlInitUnicodeString(&name, L"CcSetAdditionalCacheAttributesEx");
fCcSetAdditionalCacheAttributesEx = (tCcSetAdditionalCacheAttributesEx)MmGetSystemRoutineAddress(&name);

RtlInitUnicodeString(&name, L"FsRtlCheckLockForOplockRequest");
fFsRtlCheckLockForOplockRequest = (tFsRtlCheckLockForOplockRequest)MmGetSystemRoutineAddress(&name);
} else {
fPsUpdateDiskCounters = NULL;
fCcCopyReadEx = NULL;
fCcCopyWriteEx = NULL;
fCcSetAdditionalCacheAttributesEx = NULL;
fFsRtlUpdateDiskCounters = NULL;
fFsRtlCheckLockForOplockRequest = NULL;
}

drvobj = DriverObject;
Expand Down
7 changes: 1 addition & 6 deletions src/btrfs_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ typedef struct _fcb {
BOOL inode_item_changed;
enum prop_compression_type prop_compression;
LIST_ENTRY xattrs;
OPLOCK oplock; // stored in Header in Windows 8 and above

LIST_ENTRY dir_children_index;
LIST_ENTRY dir_children_hash;
Expand Down Expand Up @@ -283,8 +282,6 @@ typedef struct _fcb {
LIST_ENTRY list_entry_dirty;
} fcb;

#define fcb_oplock(f) (f->Header.Version >= FSRTL_FCB_HEADER_V2 ? &f->Header.Oplock : &f->oplock)

typedef struct {
ERESOURCE fileref_lock;
ERESOURCE children_lock;
Expand Down Expand Up @@ -1471,7 +1468,7 @@ NTSTATUS read_send_buffer(device_extension* Vcb, PFILE_OBJECT FileObject, void*
// based on function in sys/sysmacros.h
#define makedev(major, minor) (((minor) & 0xFF) | (((major) & 0xFFF) << 8) | (((UINT64)((minor) & ~0xFF)) << 12) | (((UINT64)((major) & ~0xFFF)) << 32))

#define fast_io_possible(fcb) (!FsRtlOplockIsFastIoPossible(fcb_oplock(fcb)) ? FastIoIsNotPossible : (!FsRtlAreThereCurrentFileLocks(&fcb->lock) && !fcb->Vcb->readonly ? FastIoIsPossible : FastIoIsQuestionable))
#define fast_io_possible(fcb) (!FsRtlAreThereCurrentFileLocks(&fcb->lock) && !fcb->Vcb->readonly ? FastIoIsPossible : FastIoIsQuestionable)

static __inline void print_open_trees(device_extension* Vcb) {
LIST_ENTRY* le = Vcb->trees.Flink;
Expand Down Expand Up @@ -1643,8 +1640,6 @@ typedef VOID (*tCcSetAdditionalCacheAttributesEx)(PFILE_OBJECT FileObject, ULONG

typedef VOID (*tFsRtlUpdateDiskCounters)(ULONG64 BytesRead, ULONG64 BytesWritten);

typedef BOOLEAN (*tFsRtlCheckLockForOplockRequest)(PFILE_LOCK FileLock, PLARGE_INTEGER AllocationSize);

#ifndef _MSC_VER

#undef RtlIsNtDdiVersionAvailable
Expand Down
32 changes: 0 additions & 32 deletions src/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ fcb* create_fcb(device_extension* Vcb, POOL_TYPE pool_type) {
InitializeListHead(&fcb->dir_children_hash);
InitializeListHead(&fcb->dir_children_hash_uc);

FsRtlInitializeOplock(fcb_oplock(fcb));

return fcb;
}

Expand Down Expand Up @@ -3161,36 +3159,6 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur
} else
IoSetShareAccess(granted_access, IrpSp->Parameters.Create.ShareAccess, FileObject, &fileref->fcb->share_access);

if (fileref->open_count > 0) {
Status = FsRtlCheckOplock(fcb_oplock(fileref->fcb), Irp, NULL, NULL, NULL);

if (!NT_SUCCESS(Status)) {
ERR("FsRtlCheckOplock returned %08x\n", Status);

IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);

ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock);

goto exit;
}
}

Status = FsRtlCheckOplockEx(fcb_oplock(fileref->fcb), Irp, OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY, NULL, NULL, NULL);

if (!NT_SUCCESS(Status)) {
ERR("FsRtlCheckOplockEx returned %08x\n", Status);

IoRemoveShareAccess(FileObject, &fileref->fcb->share_access);

ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
free_fileref(Vcb, fileref);
ExReleaseResourceLite(&Vcb->fcb_lock);

goto exit;
}

if (granted_access & FILE_WRITE_DATA || options & FILE_DELETE_ON_CLOSE) {
if (!MmFlushImageSection(&fileref->fcb->nonpaged->segment_object, MmFlushForWrite)) {
Status = (options & FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
Expand Down
9 changes: 0 additions & 9 deletions src/fileinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2602,15 +2602,6 @@ NTSTATUS drv_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
goto end;
}

if (fcb != Vcb->volume_fcb) {
Status = FsRtlCheckOplock(fcb_oplock(fcb), Irp, NULL, NULL, NULL);

if (Status != STATUS_SUCCESS)
goto end;

fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
}

Status = STATUS_NOT_IMPLEMENTED;

TRACE("set information\n");
Expand Down
132 changes: 18 additions & 114 deletions src/fsctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
extern LIST_ENTRY VcbList;
extern ERESOURCE global_loading_lock;
extern PDRIVER_OBJECT drvobj;
extern tFsRtlCheckLockForOplockRequest fFsRtlCheckLockForOplockRequest;

static void mark_subvol_dirty(device_extension* Vcb, root* r);

Expand Down Expand Up @@ -4761,150 +4760,55 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP
return Status;
}

static NTSTATUS oplock_request(device_extension* Vcb, PIRP* Pirp) {
PIRP Irp = *Pirp;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
REQUEST_OPLOCK_INPUT_BUFFER* roib = Irp->AssociatedIrp.SystemBuffer;
NTSTATUS Status;
ULONG code = IrpSp->Parameters.FileSystemControl.FsControlCode;
PFILE_OBJECT FileObject = IrpSp->FileObject;
fcb* fcb;
ccb* ccb;
file_ref* fileref;
ULONG oplock_count = 0;
BOOL tree_locked = FALSE;

TRACE("(%p, %p)\n", Vcb, *Pirp);

fcb = FileObject->FsContext;
if (!fcb) {
ERR("fcb was NULL\n");
return STATUS_INVALID_PARAMETER;
}

ccb = FileObject->FsContext2;
if (!ccb) {
ERR("ccb was NULL\n");
return STATUS_INVALID_PARAMETER;
}

fileref = ccb->fileref;
if (!fileref) {
ERR("fileref was NULL\n");
return STATUS_INVALID_PARAMETER;
}

if (code == FSCTL_REQUEST_OPLOCK) {
if (IrpSp->Parameters.FileSystemControl.InputBufferLength < sizeof(REQUEST_OPLOCK_INPUT_BUFFER)) {
WARN("input buffer length was %u, expected %u\n", IrpSp->Parameters.FileSystemControl.InputBufferLength, sizeof(REQUEST_OPLOCK_INPUT_BUFFER));
return STATUS_BUFFER_TOO_SMALL;
}

if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(REQUEST_OPLOCK_OUTPUT_BUFFER)) {
WARN("output buffer length was %u, expected %u\n", IrpSp->Parameters.FileSystemControl.OutputBufferLength, sizeof(REQUEST_OPLOCK_OUTPUT_BUFFER));
return STATUS_BUFFER_TOO_SMALL;
}

if (!(roib->Flags & (REQUEST_OPLOCK_INPUT_FLAG_REQUEST | REQUEST_OPLOCK_INPUT_FLAG_ACK)))
return STATUS_INVALID_PARAMETER;
}

if (fcb->type == BTRFS_TYPE_DIRECTORY && (code != FSCTL_REQUEST_OPLOCK || !FsRtlOplockIsSharedRequest(Irp))) {
TRACE("requesting oplock on directory that is not read or read-handle\n");
return STATUS_INVALID_PARAMETER;
}

if (code == FSCTL_REQUEST_OPLOCK_LEVEL_1 || code == FSCTL_REQUEST_BATCH_OPLOCK || code == FSCTL_REQUEST_FILTER_OPLOCK ||
code == FSCTL_REQUEST_OPLOCK_LEVEL_2 || (code == FSCTL_REQUEST_OPLOCK && roib->Flags & REQUEST_OPLOCK_INPUT_FLAG_REQUEST)) {

ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
tree_locked = TRUE;

ExAcquireResourceExclusiveLite(fcb->Header.Resource, TRUE);

if (FsRtlOplockIsSharedRequest(Irp)) {
if (fcb->type != BTRFS_TYPE_DIRECTORY) {
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8))
oplock_count = (ULONG)!fFsRtlCheckLockForOplockRequest(&fcb->lock, &fcb->Header.AllocationSize);
else
oplock_count = (ULONG)FsRtlAreThereCurrentOrInProgressFileLocks(&fcb->lock);
}
} else
oplock_count = 0;
} else if (code == FSCTL_OPLOCK_BREAK_ACKNOWLEDGE || code == FSCTL_OPBATCH_ACK_CLOSE_PENDING || code == FSCTL_OPLOCK_BREAK_NOTIFY ||
code == FSCTL_OPLOCK_BREAK_ACK_NO_2 || code == FSCTL_REQUEST_OPLOCK)
ExAcquireResourceSharedLite(fcb->Header.Resource, TRUE);
else
return STATUS_INVALID_PARAMETER;

if (fileref->delete_on_close && (code == FSCTL_REQUEST_FILTER_OPLOCK || code == FSCTL_REQUEST_BATCH_OPLOCK ||
(code == FSCTL_REQUEST_OPLOCK && roib->RequestedOplockLevel & OPLOCK_LEVEL_CACHE_HANDLE))
)
return STATUS_DELETE_PENDING;

Status = FsRtlOplockFsctrl(fcb_oplock(fcb), Irp, oplock_count);

*Pirp = NULL; // don't complete Irp

fcb->Header.IsFastIoPossible = fast_io_possible(fcb);

ExReleaseResourceLite(fcb->Header.Resource);

if (tree_locked)
ExReleaseResourceLite(&Vcb->tree_lock);

return Status;
}

NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp, UINT32 type) {
PIRP Irp = *Pirp;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status;

switch (type) {
case FSCTL_REQUEST_OPLOCK:
TRACE("FSCTL_REQUEST_OPLOCK\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_REQUEST_OPLOCK\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_REQUEST_OPLOCK_LEVEL_1:
TRACE("FSCTL_REQUEST_OPLOCK_LEVEL_1\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_REQUEST_OPLOCK_LEVEL_1\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_REQUEST_OPLOCK_LEVEL_2:
TRACE("FSCTL_REQUEST_OPLOCK_LEVEL_2\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_REQUEST_OPLOCK_LEVEL_2\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_REQUEST_BATCH_OPLOCK:
TRACE("FSCTL_REQUEST_BATCH_OPLOCK\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_REQUEST_BATCH_OPLOCK\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
TRACE("FSCTL_OPLOCK_BREAK_ACKNOWLEDGE\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_OPLOCK_BREAK_ACKNOWLEDGE\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_OPLOCK_BREAK_ACK_NO_2:
TRACE("FSCTL_OPLOCK_BREAK_ACK_NO_2\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_OPLOCK_BREAK_ACK_NO_2\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
TRACE("FSCTL_OPBATCH_ACK_CLOSE_PENDING\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_OPBATCH_ACK_CLOSE_PENDING\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_OPLOCK_BREAK_NOTIFY:
TRACE("FSCTL_OPLOCK_BREAK_NOTIFY\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_OPLOCK_BREAK_NOTIFY\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_REQUEST_FILTER_OPLOCK:
TRACE("FSCTL_REQUEST_FILTER_OPLOCK\n");
Status = oplock_request(DeviceObject->DeviceExtension, Pirp);
WARN("STUB: FSCTL_REQUEST_FILTER_OPLOCK\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;

case FSCTL_LOCK_VOLUME:
Expand Down
9 changes: 0 additions & 9 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -3321,15 +3321,6 @@ NTSTATUS drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
if (Irp->Flags & IRP_PAGING_IO)
wait = TRUE;

if (!(Irp->Flags & IRP_PAGING_IO)) {
Status = FsRtlCheckOplock(fcb_oplock(fcb), Irp, NULL, NULL, NULL);

if (Status != STATUS_SUCCESS)
goto exit;

fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
}

if (!ExIsResourceAcquiredSharedLite(fcb->Header.Resource)) {
if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
Status = STATUS_PENDING;
Expand Down
Loading

0 comments on commit b495e3a

Please sign in to comment.