Index: trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69832)
+++ trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69840)
@@ -5606,5 +5606,5 @@
      *
      * Check the DOS signature first.  The PC-DOS 1.0 boot floppy does not have
-     * a signature and we ASSUME this is the case for all flopies formated by it.
+     * a signature and we ASSUME this is the case for all floppies formated by it.
      */
     if (Buf.BootSector.uSignature != FATBOOTSECTOR_SIGNATURE)
Index: trunk/src/VBox/Runtime/common/fs/filesystem.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/filesystem.cpp	(revision 69832)
+++ 	(revision )
@@ -1,118 +1,0 @@
-/* $Id$ */
-/** @file
- * IPRT Filesystem API (Filesystem) - generic code.
- */
-
-/*
- * Copyright (C) 2012-2017 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DEFAULT
-#include <iprt/types.h>
-#include <iprt/assert.h>
-#include <iprt/mem.h>
-#include <iprt/filesystem.h>
-#include <iprt/err.h>
-#include <iprt/asm.h>
-#include <iprt/string.h>
-#include <iprt/list.h>
-#include "internal/filesystem.h"
-
-
-/*********************************************************************************************************************************
-*   Global variables                                                                                                             *
-*********************************************************************************************************************************/
-
-/**
- * Supported volume formats.
- */
-static PCRTFILESYSTEMDESC g_aFsFmts[] =
-{
-    &g_rtFsExt
-};
-
-static int rtFsGetFormat(RTVFSFILE hVfsFile, PCRTFILESYSTEMDESC *ppFsDesc)
-{
-    int                   rc = VINF_SUCCESS;
-    uint32_t              uScoreMax = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
-    PCRTFILESYSTEMDESC    pFsFmtMatch = NULL;
-
-    for (unsigned i = 0; i < RT_ELEMENTS(g_aFsFmts); i++)
-    {
-        uint32_t uScore;
-        PCRTFILESYSTEMDESC pFsFmt = g_aFsFmts[i];
-
-        rc = pFsFmt->pfnProbe(hVfsFile, &uScore);
-        if (   RT_SUCCESS(rc)
-            && uScore > uScoreMax)
-        {
-            pFsFmtMatch = pFsFmt;
-            uScoreMax   = uScore;
-        }
-        else if (RT_FAILURE(rc))
-            break;
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        if (uScoreMax > RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED)
-        {
-            AssertPtr(pFsFmtMatch);
-            *ppFsDesc = pFsFmtMatch;
-        }
-        else
-            rc = VERR_NOT_SUPPORTED;
-    }
-
-    return rc;
-}
-
-RTDECL(int) RTFilesystemVfsFromFile(RTVFSFILE hVfsFile, PRTVFS phVfs)
-{
-    int rc = VINF_SUCCESS;
-    PCRTFILESYSTEMDESC pFsDesc = NULL;
-    RTVFS hVfs = NIL_RTVFS;
-    void *pvThis = NULL;
-
-    AssertPtrReturn(hVfsFile, VERR_INVALID_HANDLE);
-    AssertPtrReturn(phVfs, VERR_INVALID_POINTER);
-
-    rc = rtFsGetFormat(hVfsFile, &pFsDesc);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTVfsNew(&pFsDesc->VfsOps, pFsDesc->cbFs, NIL_RTVFS, NIL_RTVFSLOCK,
-                      &hVfs, &pvThis);
-        if (RT_SUCCESS(rc))
-        {
-            rc = pFsDesc->pfnInit(pvThis, hVfsFile);
-            if (RT_SUCCESS(rc))
-                *phVfs = hVfs;
-            else
-                RTVfsRelease(hVfs);
-        }
-    }
-
-    return rc;
-}
-
Index: trunk/src/VBox/Runtime/common/fs/filesystemext.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/filesystemext.cpp	(revision 69832)
+++ trunk/src/VBox/Runtime/common/fs/filesystemext.cpp	(revision 69840)
@@ -29,12 +29,14 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DEFAULT
-#include <iprt/types.h>
+#define LOG_GROUP RTLOGGROUP_FS
+#include <iprt/fsvfs.h>
+
 #include <iprt/assert.h>
+#include <iprt/log.h>
 #include <iprt/mem.h>
-#include <iprt/filesystem.h>
 #include <iprt/string.h>
 #include <iprt/vfs.h>
-#include "internal/filesystem.h"
+#include <iprt/vfslowlevel.h>
+#include <iprt/formats/ext2.h>
 
 
@@ -42,111 +44,4 @@
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
-
-/*
- * The filesystem structures are from http://wiki.osdev.org/Ext2 and
- * http://www.nongnu.org/ext2-doc/ext2.html
- */
-
-/**
- * Ext superblock.
- *
- * Everything is stored little endian on the disk.
- */
-#pragma pack(1)
-typedef struct ExtSuperBlock
-{
-    /** Total number of inodes in the filesystem. */
-    uint32_t    cInodesTotal;
-    /** Total number of blocks in the filesystem. */
-    uint32_t    cBlocksTotal;
-    /** Number of blocks reserved for the super user. */
-    uint32_t    cBlocksRsvdForSuperUser;
-    /** Total number of unallocated blocks. */
-    uint32_t    cBlocksUnallocated;
-    /** Total number of unallocated inodes. */
-    uint32_t    cInodesUnallocated;
-    /** Block number of block containing the superblock. */
-    uint32_t    iBlockOfSuperblock;
-    /** Number of bits to shift 1024 to the left to get the block size */
-    uint32_t    cBitsShiftLeftBlockSize;
-    /** Number of bits to shift 1024 to the left to get the fragment size */
-    uint32_t    cBitsShiftLeftFragmentSize;
-    /** Number of blocks in each block group. */
-    uint32_t    cBlocksPerGroup;
-    /** Number of fragments in each block group. */
-    uint32_t    cFragmentsPerBlockGroup;
-    /** Number of inodes in each block group. */
-    uint32_t    cInodesPerBlockGroup;
-    /** Last mount time. */
-    uint32_t    u32LastMountTime;
-    /** Last written time. */
-    uint32_t    u32LastWrittenTime;
-    /** Number of times the volume was mounted since the last check. */
-    uint16_t    cMountsSinceLastCheck;
-    /** Number of mounts allowed before a consistency check. */
-    uint16_t    cMaxMountsUntilCheck;
-    /** Signature to identify a ext2 volume. */
-    uint16_t    u16Signature;
-    /** State of the filesystem (clean/errors) */
-    uint16_t    u16FilesystemState;
-    /** What to do on an error. */
-    uint16_t    u16ActionOnError;
-    /** Minor version field. */
-    uint16_t    u16VersionMinor;
-    /** Time of last check. */
-    uint32_t    u32LastCheckTime;
-    /** Interval between consistency checks. */
-    uint32_t    u32CheckInterval;
-    /** Operating system ID of the filesystem creator. */
-    uint32_t    u32OsIdCreator;
-    /** Major version field. */
-    uint32_t    u32VersionMajor;
-    /** User ID that is allowed to use reserved blocks. */
-    uint16_t    u16UidReservedBlocks;
-    /** Group ID that is allowed to use reserved blocks. */
-    uint16_t    u16GidReservedBlocks;
-    /** Reserved fields. */
-    uint8_t     abReserved[940];
-} ExtSuperBlock;
-#pragma pack()
-AssertCompileSize(ExtSuperBlock, 1024);
-/** Pointer to an ext super block. */
-typedef ExtSuperBlock *PExtSuperBlock;
-
-/** Ext2 signature. */
-#define RTFILESYSTEM_EXT2_SIGNATURE    (0xef53)
-/** Clean filesystem state. */
-#define RTFILESYSTEM_EXT2_STATE_CLEAN  (0x0001)
-/** Error filesystem state. */
-#define RTFILESYSTEM_EXT2_STATE_ERRORS (0x0002)
-
-/**
- * Block group descriptor.
- */
-#pragma pack(1)
-typedef struct BlockGroupDesc
-{
-    /** Block address of the block bitmap. */
-    uint32_t    offBlockBitmap;
-    /** Block address of the inode bitmap. */
-    uint32_t    offInodeBitmap;
-    /** Start block address of the inode table. */
-    uint32_t    offInodeTable;
-    /** Number of unallocated blocks in group. */
-    uint16_t    cBlocksUnallocated;
-    /** Number of unallocated inodes in group. */
-    uint16_t    cInodesUnallocated;
-    /** Number of directories in the group. */
-    uint16_t    cDirectories;
-    /** Padding. */
-    uint16_t    u16Padding;
-    /** Reserved. */
-    uint8_t     abReserved[12];
-} BlockGroupDesc;
-#pragma pack()
-AssertCompileSize(BlockGroupDesc, 32);
-/** Pointer to an ext block group descriptor. */
-typedef BlockGroupDesc *PBlockGroupDesc;
-
 /**
  * Cached block group descriptor data.
@@ -187,7 +82,4 @@
 
 
-/*********************************************************************************************************************************
-*   Methods                                                                                                                      *
-*********************************************************************************************************************************/
 
 /**
@@ -203,5 +95,5 @@
     PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
     uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
-    BlockGroupDesc BlkDesc;
+    EXT2BLOCKGROUPDESC BlkDesc;
     size_t cbBlockBitmap;
 
@@ -232,6 +124,5 @@
 }
 
-static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc,
-                                     uint32_t offBlockStart, size_t cBlocks)
+static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, uint32_t offBlockStart, size_t cBlocks)
 {
     bool fUsed = false;
@@ -256,70 +147,8 @@
 
 
-static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)
-{
-    int rc = VINF_SUCCESS;
-    uint64_t cbMedium = 0;
-
-    *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
-
-    rc = RTVfsFileGetSize(hVfsFile, &cbMedium);
-    if (RT_SUCCESS(rc))
-    {
-        if (cbMedium >= 2*sizeof(ExtSuperBlock))
-        {
-            ExtSuperBlock SuperBlock;
-
-            rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
-            if (RT_SUCCESS(rc))
-            {
-#if defined(RT_BIGENDIAN)
-                /** @todo Convert to host endianess. */
-#endif
-                if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)
-                    *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;
-            }
-        }
-    }
-
-    return rc;
-}
-
-static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)
-{
-    int rc = VINF_SUCCESS;
-    PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
-    ExtSuperBlock SuperBlock;
-
-    pThis->hVfsFile    = hVfsFile;
-    pThis->pBlkGrpDesc = NULL;
-
-    rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
-    if (RT_SUCCESS(rc))
-    {
-#if defined(RT_BIGENDIAN)
-        /** @todo Convert to host endianess. */
-#endif
-        if (SuperBlock.u16FilesystemState == RTFILESYSTEM_EXT2_STATE_ERRORS)
-            rc = VERR_FILESYSTEM_CORRUPT;
-        else
-        {
-            pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;
-            pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;
-            pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;
-            pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;
-
-            /* Load first block group descriptor. */
-            rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
-        }
-    }
-
-    return rc;
-}
-
-
 /**
  * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}
  */
-static DECLCALLBACK(int) rtFsExtVol_Close(void *pvThis)
+static DECLCALLBACK(int) rtFsExt2Vol_Close(void *pvThis)
 {
     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
@@ -335,5 +164,5 @@
  * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}
  */
-static DECLCALLBACK(int) rtFsExtVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
+static DECLCALLBACK(int) rtFsExt2Vol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
 {
     RT_NOREF(pvThis, pObjInfo, enmAddAttr);
@@ -342,5 +171,8 @@
 
 
-static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
+/**
+ * @interface_method_impl{RTVFSOBJOPS::Obj,pfnOpenRoot}
+ */
+static DECLCALLBACK(int) rtFsExt2_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
 {
     NOREF(pvThis);
@@ -349,6 +181,9 @@
 }
 
-static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb,
-                                             bool *pfUsed)
+
+/**
+ * @interface_method_impl{RTVFSOBJOPS::Obj,pfnIsRangeInUse}
+ */
+static DECLCALLBACK(int) rtFsExt2_IsRangeInUse(void *pvThis, RTFOFF off, size_t cb, bool *pfUsed)
 {
     int rc = VINF_SUCCESS;
@@ -394,26 +229,73 @@
 
 
-DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt =
-{
-    /* .cbFs = */       sizeof(RTFILESYSTEMEXT),
-    /* .VfsOps = */
-    {
-        /* .Obj = */
+DECL_HIDDEN_CONST(const RTVFSOPS) g_rtFsExt2VolOps =
+{
+    /* .Obj = */
+    {
+        /* .uVersion = */       RTVFSOBJOPS_VERSION,
+        /* .enmType = */        RTVFSOBJTYPE_VFS,
+        /* .pszName = */        "Ext2Vol",
+        /* .pfnClose = */       rtFsExt2Vol_Close,
+        /* .pfnQueryInfo = */   rtFsExt2Vol_QueryInfo,
+        /* .uEndMarker = */     RTVFSOBJOPS_VERSION
+    },
+    /* .uVersion = */           RTVFSOPS_VERSION,
+    /* .fFeatures = */          0,
+    /* .pfnOpenRoot = */        rtFsExt2_OpenRoot,
+    /* .pfnIsRangeInUse = */    rtFsExt2_IsRangeInUse,
+    /* .uEndMarker = */         RTVFSOPS_VERSION
+};
+
+
+RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo)
+{
+    AssertPtrReturn(phVfs, VERR_INVALID_POINTER);
+    AssertReturn(!(fMntFlags & RTVFSMNT_F_VALID_MASK), VERR_INVALID_FLAGS);
+    AssertReturn(!fExtFlags, VERR_INVALID_FLAGS);
+
+    uint32_t cRefs = RTVfsFileRetain(hVfsFileIn);
+    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
+
+    PRTFILESYSTEMEXT pThis;
+    int rc = RTVfsNew(&g_rtFsExt2VolOps, sizeof(*pThis), NIL_RTVFS, RTVFSLOCK_CREATE_RW, phVfs, (void **)&pThis);
+    if (RT_SUCCESS(rc))
+    {
+        pThis->hVfsFile    = hVfsFileIn;
+        pThis->pBlkGrpDesc = NULL;
+
+        EXT2SUPERBLOCK SuperBlock;
+        rc = RTVfsFileReadAt(hVfsFileIn, 1024, &SuperBlock, sizeof(EXT2SUPERBLOCK), NULL);
+        if (RT_SUCCESS(rc))
         {
-            /* .uVersion = */       RTVFSOBJOPS_VERSION,
-            /* .enmType = */        RTVFSOBJTYPE_VFS,
-            /* .pszName = */        "ExtVol",
-            /* .pfnClose = */       rtFsExtVol_Close,
-            /* .pfnQueryInfo = */   rtFsExtVol_QueryInfo,
-            /* .uEndMarker = */     RTVFSOBJOPS_VERSION
-        },
-        /* .uVersion = */           RTVFSOPS_VERSION,
-        /* .fFeatures = */          0,
-        /* .pfnOpenRoot = */        rtFsExtOpenRoot,
-        /* .pfnIsRangeInUse = */    rtFsExtIsRangeInUse,
-        /* .uEndMarker = */         RTVFSOPS_VERSION
-    },
-    /* .pfnProbe = */   rtFsExtProbe,
-    /* .pfnInit = */    rtFsExtInit
-};
-
+#if defined(RT_BIGENDIAN)
+            /** @todo Convert to host endianess. */
+#endif
+            if (SuperBlock.u16FilesystemState == EXT2_STATE_ERRORS)
+                rc = RTERRINFO_LOG_SET(pErrInfo, VERR_FILESYSTEM_CORRUPT, "EXT2_STATE_ERRORS");
+            else
+            {
+                pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;
+                pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;
+                pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;
+                pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;
+
+                /* Load first block group descriptor. */
+                rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
+            }
+            if (RT_SUCCESS(rc))
+            {
+                return VINF_SUCCESS;
+            }
+        }
+        else
+            rc = RTERRINFO_LOG_SET(pErrInfo, rc, "Error reading super block");
+
+        RTVfsRelease(*phVfs);
+        *phVfs = NIL_RTVFS;
+    }
+    else
+        RTVfsFileRelease(hVfsFileIn);
+
+    return rc;
+}
+
