[FS_REC]
authorPierre Schweitzer <pierre@reactos.org>
Sat, 5 Mar 2016 13:01:11 +0000 (13:01 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 5 Mar 2016 13:01:11 +0000 (13:01 +0000)
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

reactos/drivers/filesystems/fs_rec/CMakeLists.txt
reactos/drivers/filesystems/fs_rec/btrfs.c [new file with mode: 0644]
reactos/drivers/filesystems/fs_rec/btrfs.h [new file with mode: 0644]
reactos/drivers/filesystems/fs_rec/fs_rec.c
reactos/drivers/filesystems/fs_rec/fs_rec.h

index 0cff511..4901c8b 100644 (file)
@@ -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 (file)
index 0000000..8ef2d87
--- /dev/null
@@ -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 <debug.h>
+
+/* 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 (file)
index 0000000..bccdfc0
--- /dev/null
@@ -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 <pshpack1.h>
+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 <poppack.h>
+
+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
index 9c2bb74..b564e4b 100644 (file)
@@ -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;
 }
index 207c17f..c440e4f 100644 (file)
@@ -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(