From: Pierre Schweitzer Date: Sat, 5 Mar 2016 13:01:11 +0000 (+0000) Subject: [FS_REC] X-Git-Tag: ReactOS-0.4.1~260 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=cfec64a66a595a4cfe340fc29b4e3ecab308ab83 [FS_REC] Implement support for recognizing the Btrfs volumes. Patch by Peter Hater. CORE-10892 #comment The fs_rec part has been committed, thanks! svn path=/trunk/; revision=70955 --- diff --git a/reactos/drivers/filesystems/fs_rec/CMakeLists.txt b/reactos/drivers/filesystems/fs_rec/CMakeLists.txt index 0cff511723f..4901c8b8ee0 100644 --- a/reactos/drivers/filesystems/fs_rec/CMakeLists.txt +++ b/reactos/drivers/filesystems/fs_rec/CMakeLists.txt @@ -1,6 +1,6 @@ - list(APPEND SOURCE blockdev.c + btrfs.c cdfs.c ext2.c fat.c diff --git a/reactos/drivers/filesystems/fs_rec/btrfs.c b/reactos/drivers/filesystems/fs_rec/btrfs.c new file mode 100644 index 00000000000..8ef2d875fec --- /dev/null +++ b/reactos/drivers/filesystems/fs_rec/btrfs.c @@ -0,0 +1,109 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS File System Recognizer + * FILE: drivers/filesystems/fs_rec/btrfs.c + * PURPOSE: Btrfs Recognizer + * PROGRAMMER: Peter Hater + * Pierre Schweitzer (pierre@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include "fs_rec.h" +#include "btrfs.h" + +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +BOOLEAN +NTAPI +FsRecIsBtrfsVolume(IN PBTRFS_SUPER_BLOCK SuperBlock) +{ + /* Just check for magic */ + return (SuperBlock->magic == BTRFS_MAGIC); +} + +NTSTATUS +NTAPI +FsRecBtrfsFsControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + NTSTATUS Status; + PDEVICE_OBJECT MountDevice; + PBTRFS_SUPER_BLOCK Spb = NULL; + ULONG SectorSize; + LARGE_INTEGER Offset; + BOOLEAN DeviceError = FALSE; + PAGED_CODE(); + + /* Get the I/O Stack and check the function type */ + Stack = IoGetCurrentIrpStackLocation(Irp); + switch (Stack->MinorFunction) + { + case IRP_MN_MOUNT_VOLUME: + + /* Assume failure */ + Status = STATUS_UNRECOGNIZED_VOLUME; + + /* Get the device object and request the sector size */ + MountDevice = Stack->Parameters.MountVolume.DeviceObject; + if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) + { + /* Try to read the superblock */ + Offset.QuadPart = BTRFS_SB_OFFSET; + if (FsRecReadBlock(MountDevice, + &Offset, + BTRFS_SB_SIZE, + SectorSize, + (PVOID)&Spb, + &DeviceError)) + { + /* Check if it's an actual BTRFS volume */ + if (FsRecIsBtrfsVolume(Spb)) + { + /* It is! */ + Status = STATUS_FS_DRIVER_REQUIRED; + } + } + + /* Free the boot sector if we have one */ + ExFreePool(Spb); + } + else + { + /* We have some sort of failure in the storage stack */ + DeviceError = TRUE; + } + + /* Check if we have an error on the stack */ + if (DeviceError) + { + /* Was this because of a floppy? */ + if (MountDevice->Characteristics & FILE_FLOPPY_DISKETTE) + { + /* Let the FS try anyway */ + Status = STATUS_FS_DRIVER_REQUIRED; + } + } + + break; + + case IRP_MN_LOAD_FILE_SYSTEM: + + /* Load the file system */ + Status = FsRecLoadFileSystem(DeviceObject, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\btrfs"); + break; + + default: + + /* Invalid request */ + Status = STATUS_INVALID_DEVICE_REQUEST; + } + + /* Return Status */ + return Status; +} diff --git a/reactos/drivers/filesystems/fs_rec/btrfs.h b/reactos/drivers/filesystems/fs_rec/btrfs.h new file mode 100644 index 00000000000..bccdfc0d7b1 --- /dev/null +++ b/reactos/drivers/filesystems/fs_rec/btrfs.h @@ -0,0 +1,31 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS File System Recognizer + * FILE: drivers/filesystems/fs_rec/btrfs.h + * PURPOSE: BTRFS Header File + * PROGRAMMER: Peter Hater + * Pierre Schweitzer (pierre@reactos.org) + */ + +#include +typedef struct { + UINT8 uuid[16]; +} BTRFS_UUID; + +typedef struct _BTRFS_SUPER_BLOCK { + UINT8 checksum[32]; + BTRFS_UUID uuid; + UINT64 sb_phys_addr; + UINT64 flags; + UINT64 magic; + // Partial +} BTRFS_SUPER_BLOCK, *PBTRFS_SUPER_BLOCK; +#include + +C_ASSERT(FIELD_OFFSET(BTRFS_SUPER_BLOCK, uuid) == 0x20); +C_ASSERT(FIELD_OFFSET(BTRFS_SUPER_BLOCK, sb_phys_addr) == 0x30); +C_ASSERT(FIELD_OFFSET(BTRFS_SUPER_BLOCK, magic) == 0x40); + +#define BTRFS_MAGIC 0x4d5f53665248425f +#define BTRFS_SB_OFFSET 0x10000 +#define BTRFS_SB_SIZE 0x1000 diff --git a/reactos/drivers/filesystems/fs_rec/fs_rec.c b/reactos/drivers/filesystems/fs_rec/fs_rec.c index 9c2bb744f59..b564e4b3a2a 100644 --- a/reactos/drivers/filesystems/fs_rec/fs_rec.c +++ b/reactos/drivers/filesystems/fs_rec/fs_rec.c @@ -164,6 +164,12 @@ FsRecFsControl(IN PDEVICE_OBJECT DeviceObject, Status = FsRecExt2FsControl(DeviceObject, Irp); break; + case FS_TYPE_BTRFS: + + /* Send BTRFS command */ + Status = FsRecBtrfsFsControl(DeviceObject, Irp); + break; + default: /* Unrecognized FS */ @@ -382,6 +388,16 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, FILE_DEVICE_DISK_FILE_SYSTEM); if (NT_SUCCESS(Status)) DeviceCount++; + /* Register BTRFS */ + Status = FsRecRegisterFs(DriverObject, + NULL, + NULL, + L"\\Btrfs", + L"\\FileSystem\\BtrfsRecognizer", + FS_TYPE_BTRFS, + FILE_DEVICE_DISK_FILE_SYSTEM); + if (NT_SUCCESS(Status)) DeviceCount++; + /* Return appropriate Status */ return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED; } diff --git a/reactos/drivers/filesystems/fs_rec/fs_rec.h b/reactos/drivers/filesystems/fs_rec/fs_rec.h index 207c17f6d9b..c440e4f063d 100644 --- a/reactos/drivers/filesystems/fs_rec/fs_rec.h +++ b/reactos/drivers/filesystems/fs_rec/fs_rec.h @@ -174,6 +174,7 @@ typedef enum _FILE_SYSTEM_TYPE FS_TYPE_CDFS, FS_TYPE_UDFS, FS_TYPE_EXT2, + FS_TYPE_BTRFS, } FILE_SYSTEM_TYPE, *PFILE_SYSTEM_TYPE; /* FS Recognizer State */ @@ -228,6 +229,13 @@ FsRecExt2FsControl( IN PIRP Irp ); +NTSTATUS +NTAPI +FsRecBtrfsFsControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +); + BOOLEAN NTAPI FsRecGetDeviceSectors(