VirtualBox

Changeset 69840 in vbox


Ignore:
Timestamp:
Nov 27, 2017 3:19:30 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119281
Message:

IPRT: VFS volume mouning cleanup, replacing RTFilesystemVfsFromFile with RTVfsMountVol.

  • RTVfsMountVol will do basic file system recognizion and call the right file system volume open API.
  • Moved ext2 definitions to iprt/formats/ext2.h, dropping unnecessary pragma pack(1) and adjusted names.
  • Added RTFsExt2VolOpen.
  • Removed iprt/filesystem.h.
  • Removed include/internal/filesystem.h.
  • Nothing has been tested yet! :-)
Location:
trunk
Files:
1 added
3 deleted
9 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/formats/ext2.h

    r69803 r69840  
    2525 */
    2626
     27#ifndef ___iprt_formats_ext2_h
     28#define ___iprt_formats_ext2_h
    2729
    28 /*********************************************************************************************************************************
    29 *   Header Files                                                                                                                 *
    30 *********************************************************************************************************************************/
    31 #define LOG_GROUP LOG_GROUP_DEFAULT
    3230#include <iprt/types.h>
    33 #include <iprt/assert.h>
    34 #include <iprt/mem.h>
    35 #include <iprt/filesystem.h>
    36 #include <iprt/string.h>
    37 #include <iprt/vfs.h>
    38 #include "internal/filesystem.h"
     31#include <iprt/assertcompile.h>
    3932
    40 
    41 /*********************************************************************************************************************************
    42 *   Structures and Typedefs                                                                                                      *
    43 *********************************************************************************************************************************/
    4433
    4534/*
     
    4938
    5039/**
    51  * Ext superblock.
     40 * Ext2 superblock.
    5241 *
    5342 * Everything is stored little endian on the disk.
    5443 */
    55 #pragma pack(1)
    56 typedef struct ExtSuperBlock
     44typedef struct EXT2SUPERBLOCK
    5745{
    5846    /** Total number of inodes in the filesystem. */
     
    8674    /** Number of mounts allowed before a consistency check. */
    8775    uint16_t    cMaxMountsUntilCheck;
    88     /** Signature to identify a ext2 volume. */
     76    /** Signature to identify a ext2 volume (EXT2_SIGNATURE). */
    8977    uint16_t    u16Signature;
    9078    /** State of the filesystem (clean/errors) */
     
    10896    /** Reserved fields. */
    10997    uint8_t     abReserved[940];
    110 } ExtSuperBlock;
    111 #pragma pack()
    112 AssertCompileSize(ExtSuperBlock, 1024);
    113 /** Pointer to an ext super block. */
    114 typedef ExtSuperBlock *PExtSuperBlock;
     98} EXT2SUPERBLOCK;
     99AssertCompileSize(EXT2SUPERBLOCK, 1024);
     100/** Pointer to an ext2 super block. */
     101typedef EXT2SUPERBLOCK *PEXT2SUPERBLOCK;
     102/** Pointer to a const ext2 super block. */
     103typedef EXT2SUPERBLOCK const *PCEXT2SUPERBLOCK;
    115104
    116105/** Ext2 signature. */
    117 #define RTFILESYSTEM_EXT2_SIGNATURE    (0xef53)
     106#define EXT2_SIGNATURE      UINT16_C(0xef53)
    118107/** Clean filesystem state. */
    119 #define RTFILESYSTEM_EXT2_STATE_CLEAN  (0x0001)
     108#define EXT2_STATE_CLEAN    UINT16_C(0x0001)
    120109/** Error filesystem state. */
    121 #define RTFILESYSTEM_EXT2_STATE_ERRORS (0x0002)
     110#define EXT2_STATE_ERRORS   UINT16_C(0x0002)
    122111
    123112/**
    124113 * Block group descriptor.
    125114 */
    126 #pragma pack(1)
    127 typedef struct BlockGroupDesc
     115typedef struct EXT2BLOCKGROUPDESC
    128116{
    129117    /** Block address of the block bitmap. */
     
    143131    /** Reserved. */
    144132    uint8_t     abReserved[12];
    145 } BlockGroupDesc;
    146 #pragma pack()
    147 AssertCompileSize(BlockGroupDesc, 32);
     133} EXT2BLOCKGROUPDESC;
     134AssertCompileSize(EXT2BLOCKGROUPDESC, 32);
    148135/** Pointer to an ext block group descriptor. */
    149 typedef BlockGroupDesc *PBlockGroupDesc;
     136typedef EXT2BLOCKGROUPDESC *PEXT2BLOCKGROUPDESC;
    150137
    151 /**
    152  * Cached block group descriptor data.
    153  */
    154 typedef struct RTFILESYSTEMEXTBLKGRP
    155 {
    156     /** Start offset (in bytes and from the start of the disk). */
    157     uint64_t    offStart;
    158     /** Last offset in the block group (inclusive). */
    159     uint64_t    offLast;
    160     /** Block bitmap - variable in size (depends on the block size
    161      * and number of blocks per group). */
    162     uint8_t     abBlockBitmap[1];
    163 } RTFILESYSTEMEXTBLKGRP;
    164 /** Pointer to block group descriptor data. */
    165 typedef RTFILESYSTEMEXTBLKGRP *PRTFILESYSTEMEXTBLKGRP;
     138#endif
    166139
    167 /**
    168  * Ext2/3 filesystem data.
    169  */
    170 typedef struct RTFILESYSTEMEXT
    171 {
    172     /** VFS file handle. */
    173     RTVFSFILE                 hVfsFile;
    174     /** Block number of the superblock. */
    175     uint32_t                  iSbBlock;
    176     /** Size of one block. */
    177     size_t                    cbBlock;
    178     /** Number of blocks in one group. */
    179     unsigned                  cBlocksPerGroup;
    180     /** Number of blocks groups in the volume. */
    181     unsigned                  cBlockGroups;
    182     /** Cached block group descriptor data. */
    183     PRTFILESYSTEMEXTBLKGRP    pBlkGrpDesc;
    184 } RTFILESYSTEMEXT;
    185 /** Pointer to the ext filesystem data. */
    186 typedef RTFILESYSTEMEXT *PRTFILESYSTEMEXT;
    187 
    188 
    189 /*********************************************************************************************************************************
    190 *   Methods                                                                                                                      *
    191 *********************************************************************************************************************************/
    192 
    193 /**
    194  * Loads the block descriptor of the given block group from the medium.
    195  *
    196  * @returns IPRT status code.
    197  * @param   pThis    EXT filesystem instance data.
    198  * @param   iBlkGrp  Block group number to load.
    199  */
    200 static int rtFsExtLoadBlkGrpDesc(PRTFILESYSTEMEXT pThis, uint32_t iBlkGrp)
    201 {
    202     int rc = VINF_SUCCESS;
    203     PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
    204     uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
    205     BlockGroupDesc BlkDesc;
    206     size_t cbBlockBitmap;
    207 
    208     cbBlockBitmap = pThis->cBlocksPerGroup / 8;
    209     if (pThis->cBlocksPerGroup % 8)
    210         cbBlockBitmap++;
    211 
    212     if (!pBlkGrpDesc)
    213     {
    214         size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEMEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);
    215         pBlkGrpDesc = (PRTFILESYSTEMEXTBLKGRP)RTMemAllocZ(cbBlkDesc);
    216         if (!pBlkGrpDesc)
    217             return VERR_NO_MEMORY;
    218     }
    219 
    220     rc = RTVfsFileReadAt(pThis->hVfsFile, offRead, &BlkDesc, sizeof(BlkDesc), NULL);
    221     if (RT_SUCCESS(rc))
    222     {
    223         pBlkGrpDesc->offStart = pThis->iSbBlock + (uint64_t)iBlkGrp * pThis->cBlocksPerGroup * pThis->cbBlock;
    224         pBlkGrpDesc->offLast  = pBlkGrpDesc->offStart + pThis->cBlocksPerGroup * pThis->cbBlock;
    225         rc = RTVfsFileReadAt(pThis->hVfsFile, BlkDesc.offBlockBitmap * pThis->cbBlock,
    226                              &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap, NULL);
    227     }
    228 
    229     pThis->pBlkGrpDesc = pBlkGrpDesc;
    230 
    231     return rc;
    232 }
    233 
    234 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc,
    235                                      uint32_t offBlockStart, size_t cBlocks)
    236 {
    237     bool fUsed = false;
    238 
    239     while (cBlocks)
    240     {
    241         uint32_t idxByte = offBlockStart / 8;
    242         uint32_t iBit = offBlockStart % 8;
    243 
    244         if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit))
    245         {
    246             fUsed = true;
    247             break;
    248         }
    249 
    250         cBlocks--;
    251         offBlockStart++;
    252     }
    253 
    254     return fUsed;
    255 }
    256 
    257 
    258 static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)
    259 {
    260     int rc = VINF_SUCCESS;
    261     uint64_t cbMedium = 0;
    262 
    263     *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
    264 
    265     rc = RTVfsFileGetSize(hVfsFile, &cbMedium);
    266     if (RT_SUCCESS(rc))
    267     {
    268         if (cbMedium >= 2*sizeof(ExtSuperBlock))
    269         {
    270             ExtSuperBlock SuperBlock;
    271 
    272             rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
    273             if (RT_SUCCESS(rc))
    274             {
    275 #if defined(RT_BIGENDIAN)
    276                 /** @todo Convert to host endianess. */
    277 #endif
    278                 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)
    279                     *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;
    280             }
    281         }
    282     }
    283 
    284     return rc;
    285 }
    286 
    287 static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)
    288 {
    289     int rc = VINF_SUCCESS;
    290     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    291     ExtSuperBlock SuperBlock;
    292 
    293     pThis->hVfsFile    = hVfsFile;
    294     pThis->pBlkGrpDesc = NULL;
    295 
    296     rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
    297     if (RT_SUCCESS(rc))
    298     {
    299 #if defined(RT_BIGENDIAN)
    300         /** @todo Convert to host endianess. */
    301 #endif
    302         if (SuperBlock.u16FilesystemState == RTFILESYSTEM_EXT2_STATE_ERRORS)
    303             rc = VERR_FILESYSTEM_CORRUPT;
    304         else
    305         {
    306             pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;
    307             pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;
    308             pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;
    309             pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;
    310 
    311             /* Load first block group descriptor. */
    312             rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
    313         }
    314     }
    315 
    316     return rc;
    317 }
    318 
    319 
    320 /**
    321  * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}
    322  */
    323 static DECLCALLBACK(int) rtFsExtVol_Close(void *pvThis)
    324 {
    325     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    326 
    327     if (pThis->pBlkGrpDesc)
    328         RTMemFree(pThis->pBlkGrpDesc);
    329 
    330     return VINF_SUCCESS;
    331 }
    332 
    333 
    334 /**
    335  * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}
    336  */
    337 static DECLCALLBACK(int) rtFsExtVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    338 {
    339     RT_NOREF(pvThis, pObjInfo, enmAddAttr);
    340     return VERR_WRONG_TYPE;
    341 }
    342 
    343 
    344 static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
    345 {
    346     NOREF(pvThis);
    347     NOREF(phVfsDir);
    348     return VERR_NOT_IMPLEMENTED;
    349 }
    350 
    351 static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb,
    352                                              bool *pfUsed)
    353 {
    354     int rc = VINF_SUCCESS;
    355     uint64_t offStart = (uint64_t)off;
    356     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    357 
    358     *pfUsed = false;
    359 
    360     while (cb > 0)
    361     {
    362         bool fUsed;
    363         uint32_t offBlockStart = (uint32_t)(offStart / pThis->cbBlock);
    364         uint32_t iBlockGroup = (offBlockStart - pThis->iSbBlock) / pThis->cBlocksPerGroup;
    365         uint32_t offBlockRelStart = offBlockStart - iBlockGroup * pThis->cBlocksPerGroup;
    366         size_t cbThis = 0;
    367 
    368         if (   offStart < pThis->pBlkGrpDesc->offStart
    369             || offStart > pThis->pBlkGrpDesc->offLast)
    370         {
    371             /* Load new block descriptor. */
    372             rc = rtFsExtLoadBlkGrpDesc(pThis, iBlockGroup);
    373             if (RT_FAILURE(rc))
    374                 break;
    375         }
    376 
    377         cbThis = RT_MIN(cb, pThis->pBlkGrpDesc->offLast - offStart + 1);
    378         fUsed = rtFsExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart,
    379                                          cbThis / pThis->cbBlock +
    380                                          (cbThis % pThis->cbBlock ? 1 : 0));
    381 
    382         if (fUsed)
    383         {
    384             *pfUsed = true;
    385             break;
    386         }
    387 
    388         cb       -= cbThis;
    389         offStart += cbThis;
    390     }
    391 
    392     return rc;
    393 }
    394 
    395 
    396 DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt =
    397 {
    398     /* .cbFs = */       sizeof(RTFILESYSTEMEXT),
    399     /* .VfsOps = */
    400     {
    401         /* .Obj = */
    402         {
    403             /* .uVersion = */       RTVFSOBJOPS_VERSION,
    404             /* .enmType = */        RTVFSOBJTYPE_VFS,
    405             /* .pszName = */        "ExtVol",
    406             /* .pfnClose = */       rtFsExtVol_Close,
    407             /* .pfnQueryInfo = */   rtFsExtVol_QueryInfo,
    408             /* .uEndMarker = */     RTVFSOBJOPS_VERSION
    409         },
    410         /* .uVersion = */           RTVFSOPS_VERSION,
    411         /* .fFeatures = */          0,
    412         /* .pfnOpenRoot = */        rtFsExtOpenRoot,
    413         /* .pfnIsRangeInUse = */    rtFsExtIsRangeInUse,
    414         /* .uEndMarker = */         RTVFSOPS_VERSION
    415     },
    416     /* .pfnProbe = */   rtFsExtProbe,
    417     /* .pfnInit = */    rtFsExtInit
    418 };
    419 
  • trunk/include/iprt/fsvfs.h

    r69013 r69840  
    3333RT_C_DECLS_BEGIN
    3434
    35 /** @defgroup grp_rt_fs_fat  FAT VFS File System
     35/** @defgroup grp_rt_fs_vfs  VFS File System Implementations
    3636 * @ingroup grp_rt_fs
    3737 * @{
     
    119119
    120120
     121
     122/**
     123 * Opens an EXT2 file system volume.
     124 *
     125 * @returns IPRT status code.
     126 * @param   hVfsFileIn      The file or device backing the volume.
     127 * @param   fMntFlags       RTVFSMNT_F_XXX.
     128 * @param   fExt2Flags      Reserved, MBZ.
     129 * @param   phVfs           Where to return the virtual file system handle.
     130 * @param   pErrInfo        Where to return additional error information.
     131 */
     132RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo);
     133
     134
     135
    121136/** @name RTFSISO9660_F_XXX - ISO 9660 mount flags.
    122137 * @{ */
  • trunk/include/iprt/mangling.h

    r69813 r69840  
    948948# define RTFsQueryType                                  RT_MANGLER(RTFsQueryType)
    949949# define RTFsTypeName                                   RT_MANGLER(RTFsTypeName)
     950# define RTFsExt2VolOpen                                RT_MANGLER(RTFsExt2VolOpen)
    950951# define RTFsFatVolOpen                                 RT_MANGLER(RTFsFatVolOpen)
    951952# define RTFsFatVolFormat                               RT_MANGLER(RTFsFatVolFormat)
     
    25522553# define RTVfsOpenRoot                                  RT_MANGLER(RTVfsOpenRoot)
    25532554# define RTVfsQuerPathInfo                              RT_MANGLER(RTVfsQueryPathInfo)
     2555# define RTVfsMountVol                                  RT_MANGLER(RTVfsMountVol)
    25542556# define RTVfsRetain                                    RT_MANGLER(RTVfsRetain)
    25552557# define RTVfsRetainDebug                               RT_MANGLER(RTVfsRetainDebug)
  • trunk/include/iprt/vfs.h

    r69818 r69840  
    113113RTDECL(uint32_t)    RTVfsRetainDebug(RTVFS hVfs, RT_SRC_POS_DECL);
    114114RTDECL(uint32_t)    RTVfsRelease(RTVFS hVfs);
     115
     116/** @name RTVFSMNT_F_XXX - Flags for RTVfsMount
     117 * @{ */
     118/** Mount read-only. */
     119#define RTVFSMNT_F_READ_ONLY            RT_BIT_32(0)
     120/** Purpose is . */
     121#define RTVFSMNT_F_FOR_RANGE_IN_USE     RT_BIT_32(1)
     122/** Valid mask. */
     123#define RTVFSMNT_F_VALID_MASK           UINT32_C(0x00000003)
     124/** @} */
     125
     126/**
     127 * Does the file system detection and mounting.
     128 *
     129 * @returns IPRT status code.
     130 * @retval  VERR_VFS_UNSUPPORTED_FORMAT if not recognized as a support file
     131 *          system.
     132 * @param   hVfsFileIn      The file handle of the volume.
     133 * @param   fFlags          RTVFSMTN_F_XXX.
     134 * @param   phVfs           Where to return the VFS handle on success.
     135 * @param   pErrInfo        Where to return additional error information.
     136 *                          Optional.
     137 */
     138RTDECL(int)         RTVfsMountVol(RTVFSFILE hVfsFileIn, uint32_t fFlags, PRTVFS phVfs, PRTERRINFO pErrInfo);
     139
    115140RTDECL(int)         RTVfsAttach(RTVFS hVfs, const char *pszMountPoint, uint32_t fFlags, RTVFS hVfsAttach);
    116141RTDECL(int)         RTVfsDetach(RTVFS hVfs, const char *pszMountPoint, RTVFS hVfsToDetach, PRTVFS *phVfsDetached);
     
    144169 */
    145170RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, bool *pfUsed);
     171
    146172
    147173/** @defgroup grp_vfs_obj           VFS Base Object API
  • trunk/src/VBox/Runtime/Makefile.kmk

    r69795 r69840  
    429429        common/err/RTErrConvertFromErrno.cpp \
    430430        common/err/RTErrConvertToErrno.cpp \
    431         common/fs/filesystem.cpp \
    432431        common/fs/filesystemext.cpp \
    433432        common/fs/fatvfs.cpp \
     
    621620        common/vfs/vfsmemory.cpp \
    622621        common/vfs/vfsmisc.cpp \
     622        common/vfs/vfsmount.cpp \
    623623        common/vfs/vfsmsg.cpp \
    624624        common/vfs/vfsprogress.cpp \
  • trunk/src/VBox/Runtime/common/fs/fatvfs.cpp

    r69832 r69840  
    56065606     *
    56075607     * Check the DOS signature first.  The PC-DOS 1.0 boot floppy does not have
    5608      * a signature and we ASSUME this is the case for all flopies formated by it.
     5608     * a signature and we ASSUME this is the case for all floppies formated by it.
    56095609     */
    56105610    if (Buf.BootSector.uSignature != FATBOOTSECTOR_SIGNATURE)
  • trunk/src/VBox/Runtime/common/fs/filesystemext.cpp

    r69111 r69840  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #define LOG_GROUP LOG_GROUP_DEFAULT
    32 #include <iprt/types.h>
     31#define LOG_GROUP RTLOGGROUP_FS
     32#include <iprt/fsvfs.h>
     33
    3334#include <iprt/assert.h>
     35#include <iprt/log.h>
    3436#include <iprt/mem.h>
    35 #include <iprt/filesystem.h>
    3637#include <iprt/string.h>
    3738#include <iprt/vfs.h>
    38 #include "internal/filesystem.h"
     39#include <iprt/vfslowlevel.h>
     40#include <iprt/formats/ext2.h>
    3941
    4042
     
    4244*   Structures and Typedefs                                                                                                      *
    4345*********************************************************************************************************************************/
    44 
    45 /*
    46  * The filesystem structures are from http://wiki.osdev.org/Ext2 and
    47  * http://www.nongnu.org/ext2-doc/ext2.html
    48  */
    49 
    50 /**
    51  * Ext superblock.
    52  *
    53  * Everything is stored little endian on the disk.
    54  */
    55 #pragma pack(1)
    56 typedef struct ExtSuperBlock
    57 {
    58     /** Total number of inodes in the filesystem. */
    59     uint32_t    cInodesTotal;
    60     /** Total number of blocks in the filesystem. */
    61     uint32_t    cBlocksTotal;
    62     /** Number of blocks reserved for the super user. */
    63     uint32_t    cBlocksRsvdForSuperUser;
    64     /** Total number of unallocated blocks. */
    65     uint32_t    cBlocksUnallocated;
    66     /** Total number of unallocated inodes. */
    67     uint32_t    cInodesUnallocated;
    68     /** Block number of block containing the superblock. */
    69     uint32_t    iBlockOfSuperblock;
    70     /** Number of bits to shift 1024 to the left to get the block size */
    71     uint32_t    cBitsShiftLeftBlockSize;
    72     /** Number of bits to shift 1024 to the left to get the fragment size */
    73     uint32_t    cBitsShiftLeftFragmentSize;
    74     /** Number of blocks in each block group. */
    75     uint32_t    cBlocksPerGroup;
    76     /** Number of fragments in each block group. */
    77     uint32_t    cFragmentsPerBlockGroup;
    78     /** Number of inodes in each block group. */
    79     uint32_t    cInodesPerBlockGroup;
    80     /** Last mount time. */
    81     uint32_t    u32LastMountTime;
    82     /** Last written time. */
    83     uint32_t    u32LastWrittenTime;
    84     /** Number of times the volume was mounted since the last check. */
    85     uint16_t    cMountsSinceLastCheck;
    86     /** Number of mounts allowed before a consistency check. */
    87     uint16_t    cMaxMountsUntilCheck;
    88     /** Signature to identify a ext2 volume. */
    89     uint16_t    u16Signature;
    90     /** State of the filesystem (clean/errors) */
    91     uint16_t    u16FilesystemState;
    92     /** What to do on an error. */
    93     uint16_t    u16ActionOnError;
    94     /** Minor version field. */
    95     uint16_t    u16VersionMinor;
    96     /** Time of last check. */
    97     uint32_t    u32LastCheckTime;
    98     /** Interval between consistency checks. */
    99     uint32_t    u32CheckInterval;
    100     /** Operating system ID of the filesystem creator. */
    101     uint32_t    u32OsIdCreator;
    102     /** Major version field. */
    103     uint32_t    u32VersionMajor;
    104     /** User ID that is allowed to use reserved blocks. */
    105     uint16_t    u16UidReservedBlocks;
    106     /** Group ID that is allowed to use reserved blocks. */
    107     uint16_t    u16GidReservedBlocks;
    108     /** Reserved fields. */
    109     uint8_t     abReserved[940];
    110 } ExtSuperBlock;
    111 #pragma pack()
    112 AssertCompileSize(ExtSuperBlock, 1024);
    113 /** Pointer to an ext super block. */
    114 typedef ExtSuperBlock *PExtSuperBlock;
    115 
    116 /** Ext2 signature. */
    117 #define RTFILESYSTEM_EXT2_SIGNATURE    (0xef53)
    118 /** Clean filesystem state. */
    119 #define RTFILESYSTEM_EXT2_STATE_CLEAN  (0x0001)
    120 /** Error filesystem state. */
    121 #define RTFILESYSTEM_EXT2_STATE_ERRORS (0x0002)
    122 
    123 /**
    124  * Block group descriptor.
    125  */
    126 #pragma pack(1)
    127 typedef struct BlockGroupDesc
    128 {
    129     /** Block address of the block bitmap. */
    130     uint32_t    offBlockBitmap;
    131     /** Block address of the inode bitmap. */
    132     uint32_t    offInodeBitmap;
    133     /** Start block address of the inode table. */
    134     uint32_t    offInodeTable;
    135     /** Number of unallocated blocks in group. */
    136     uint16_t    cBlocksUnallocated;
    137     /** Number of unallocated inodes in group. */
    138     uint16_t    cInodesUnallocated;
    139     /** Number of directories in the group. */
    140     uint16_t    cDirectories;
    141     /** Padding. */
    142     uint16_t    u16Padding;
    143     /** Reserved. */
    144     uint8_t     abReserved[12];
    145 } BlockGroupDesc;
    146 #pragma pack()
    147 AssertCompileSize(BlockGroupDesc, 32);
    148 /** Pointer to an ext block group descriptor. */
    149 typedef BlockGroupDesc *PBlockGroupDesc;
    150 
    15146/**
    15247 * Cached block group descriptor data.
     
    18782
    18883
    189 /*********************************************************************************************************************************
    190 *   Methods                                                                                                                      *
    191 *********************************************************************************************************************************/
    19284
    19385/**
     
    20395    PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
    20496    uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
    205     BlockGroupDesc BlkDesc;
     97    EXT2BLOCKGROUPDESC BlkDesc;
    20698    size_t cbBlockBitmap;
    20799
     
    232124}
    233125
    234 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc,
    235                                      uint32_t offBlockStart, size_t cBlocks)
     126static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, uint32_t offBlockStart, size_t cBlocks)
    236127{
    237128    bool fUsed = false;
     
    256147
    257148
    258 static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)
    259 {
    260     int rc = VINF_SUCCESS;
    261     uint64_t cbMedium = 0;
    262 
    263     *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
    264 
    265     rc = RTVfsFileGetSize(hVfsFile, &cbMedium);
    266     if (RT_SUCCESS(rc))
    267     {
    268         if (cbMedium >= 2*sizeof(ExtSuperBlock))
    269         {
    270             ExtSuperBlock SuperBlock;
    271 
    272             rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
    273             if (RT_SUCCESS(rc))
    274             {
    275 #if defined(RT_BIGENDIAN)
    276                 /** @todo Convert to host endianess. */
    277 #endif
    278                 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)
    279                     *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;
    280             }
    281         }
    282     }
    283 
    284     return rc;
    285 }
    286 
    287 static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)
    288 {
    289     int rc = VINF_SUCCESS;
    290     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    291     ExtSuperBlock SuperBlock;
    292 
    293     pThis->hVfsFile    = hVfsFile;
    294     pThis->pBlkGrpDesc = NULL;
    295 
    296     rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
    297     if (RT_SUCCESS(rc))
    298     {
    299 #if defined(RT_BIGENDIAN)
    300         /** @todo Convert to host endianess. */
    301 #endif
    302         if (SuperBlock.u16FilesystemState == RTFILESYSTEM_EXT2_STATE_ERRORS)
    303             rc = VERR_FILESYSTEM_CORRUPT;
    304         else
    305         {
    306             pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;
    307             pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;
    308             pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;
    309             pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;
    310 
    311             /* Load first block group descriptor. */
    312             rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
    313         }
    314     }
    315 
    316     return rc;
    317 }
    318 
    319 
    320149/**
    321150 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}
    322151 */
    323 static DECLCALLBACK(int) rtFsExtVol_Close(void *pvThis)
     152static DECLCALLBACK(int) rtFsExt2Vol_Close(void *pvThis)
    324153{
    325154    PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
     
    335164 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}
    336165 */
    337 static DECLCALLBACK(int) rtFsExtVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     166static DECLCALLBACK(int) rtFsExt2Vol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    338167{
    339168    RT_NOREF(pvThis, pObjInfo, enmAddAttr);
     
    342171
    343172
    344 static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
     173/**
     174 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnOpenRoot}
     175 */
     176static DECLCALLBACK(int) rtFsExt2_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
    345177{
    346178    NOREF(pvThis);
     
    349181}
    350182
    351 static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb,
    352                                              bool *pfUsed)
     183
     184/**
     185 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnIsRangeInUse}
     186 */
     187static DECLCALLBACK(int) rtFsExt2_IsRangeInUse(void *pvThis, RTFOFF off, size_t cb, bool *pfUsed)
    353188{
    354189    int rc = VINF_SUCCESS;
     
    394229
    395230
    396 DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt =
    397 {
    398     /* .cbFs = */       sizeof(RTFILESYSTEMEXT),
    399     /* .VfsOps = */
    400     {
    401         /* .Obj = */
     231DECL_HIDDEN_CONST(const RTVFSOPS) g_rtFsExt2VolOps =
     232{
     233    /* .Obj = */
     234    {
     235        /* .uVersion = */       RTVFSOBJOPS_VERSION,
     236        /* .enmType = */        RTVFSOBJTYPE_VFS,
     237        /* .pszName = */        "Ext2Vol",
     238        /* .pfnClose = */       rtFsExt2Vol_Close,
     239        /* .pfnQueryInfo = */   rtFsExt2Vol_QueryInfo,
     240        /* .uEndMarker = */     RTVFSOBJOPS_VERSION
     241    },
     242    /* .uVersion = */           RTVFSOPS_VERSION,
     243    /* .fFeatures = */          0,
     244    /* .pfnOpenRoot = */        rtFsExt2_OpenRoot,
     245    /* .pfnIsRangeInUse = */    rtFsExt2_IsRangeInUse,
     246    /* .uEndMarker = */         RTVFSOPS_VERSION
     247};
     248
     249
     250RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo)
     251{
     252    AssertPtrReturn(phVfs, VERR_INVALID_POINTER);
     253    AssertReturn(!(fMntFlags & RTVFSMNT_F_VALID_MASK), VERR_INVALID_FLAGS);
     254    AssertReturn(!fExtFlags, VERR_INVALID_FLAGS);
     255
     256    uint32_t cRefs = RTVfsFileRetain(hVfsFileIn);
     257    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     258
     259    PRTFILESYSTEMEXT pThis;
     260    int rc = RTVfsNew(&g_rtFsExt2VolOps, sizeof(*pThis), NIL_RTVFS, RTVFSLOCK_CREATE_RW, phVfs, (void **)&pThis);
     261    if (RT_SUCCESS(rc))
     262    {
     263        pThis->hVfsFile    = hVfsFileIn;
     264        pThis->pBlkGrpDesc = NULL;
     265
     266        EXT2SUPERBLOCK SuperBlock;
     267        rc = RTVfsFileReadAt(hVfsFileIn, 1024, &SuperBlock, sizeof(EXT2SUPERBLOCK), NULL);
     268        if (RT_SUCCESS(rc))
    402269        {
    403             /* .uVersion = */       RTVFSOBJOPS_VERSION,
    404             /* .enmType = */        RTVFSOBJTYPE_VFS,
    405             /* .pszName = */        "ExtVol",
    406             /* .pfnClose = */       rtFsExtVol_Close,
    407             /* .pfnQueryInfo = */   rtFsExtVol_QueryInfo,
    408             /* .uEndMarker = */     RTVFSOBJOPS_VERSION
    409         },
    410         /* .uVersion = */           RTVFSOPS_VERSION,
    411         /* .fFeatures = */          0,
    412         /* .pfnOpenRoot = */        rtFsExtOpenRoot,
    413         /* .pfnIsRangeInUse = */    rtFsExtIsRangeInUse,
    414         /* .uEndMarker = */         RTVFSOPS_VERSION
    415     },
    416     /* .pfnProbe = */   rtFsExtProbe,
    417     /* .pfnInit = */    rtFsExtInit
    418 };
    419 
     270#if defined(RT_BIGENDIAN)
     271            /** @todo Convert to host endianess. */
     272#endif
     273            if (SuperBlock.u16FilesystemState == EXT2_STATE_ERRORS)
     274                rc = RTERRINFO_LOG_SET(pErrInfo, VERR_FILESYSTEM_CORRUPT, "EXT2_STATE_ERRORS");
     275            else
     276            {
     277                pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;
     278                pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;
     279                pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;
     280                pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;
     281
     282                /* Load first block group descriptor. */
     283                rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
     284            }
     285            if (RT_SUCCESS(rc))
     286            {
     287                return VINF_SUCCESS;
     288            }
     289        }
     290        else
     291            rc = RTERRINFO_LOG_SET(pErrInfo, rc, "Error reading super block");
     292
     293        RTVfsRelease(*phVfs);
     294        *phVfs = NIL_RTVFS;
     295    }
     296    else
     297        RTVfsFileRelease(hVfsFileIn);
     298
     299    return rc;
     300}
     301
  • trunk/src/VBox/Runtime/testcase/tstRTFilesystem.cpp

    r69111 r69840  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #include <iprt/filesystem.h>
    3231#include <iprt/vfs.h>
    3332#include <iprt/err.h>
     
    4847    RTTestSubF(hTest, "Create filesystem object");
    4948
    50     rc = RTFilesystemVfsFromFile(hVfsFile, &hVfs);
     49    rc = RTVfsMountVol(hVfsFile,  RTVFSMNT_F_READ_ONLY | RTVFSMNT_F_FOR_RANGE_IN_USE, &hVfs, NULL);
    5150    if (RT_FAILURE(rc))
    5251    {
    53         RTTestIFailed("RTFilesystemVfsFromFile -> %Rrc", rc);
     52        RTTestIFailed("RTVfsMountVol -> %Rrc", rc);
    5453        return rc;
    5554    }
  • trunk/src/VBox/Runtime/testcase/tstRTVfs.cpp

    r69111 r69840  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #include <iprt/filesystem.h>
    3231#include <iprt/vfs.h>
    3332#include <iprt/err.h>
  • trunk/src/VBox/Storage/testcase/vbox-img.cpp

    r69616 r69840  
    3636#include <iprt/assert.h>
    3737#include <iprt/dvm.h>
    38 #include <iprt/filesystem.h>
    3938#include <iprt/vfs.h>
    4039
     
    13601359static int handleCompact(HandlerArg *a)
    13611360{
    1362     int rc = VINF_SUCCESS;
    13631361    PVDISK pDisk = NULL;
    1364     const char *pszFilename = NULL;
    1365     bool fFilesystemAware = false;
    13661362    VDINTERFACEQUERYRANGEUSE VDIfQueryRangeUse;
    13671363    PVDINTERFACE pIfsCompact = NULL;
     
    13721368    static const RTGETOPTDEF s_aOptions[] =
    13731369    {
    1374         { "--filename",        'f', RTGETOPT_REQ_STRING },
    1375         { "--filesystemaware", 'a', RTGETOPT_REQ_NOTHING }
     1370        { "--filename",          'f', RTGETOPT_REQ_STRING },
     1371        { "--filesystemaware",   'a', RTGETOPT_REQ_NOTHING },
     1372        { "--file-system-aware", 'a', RTGETOPT_REQ_NOTHING },
    13761373    };
     1374
     1375    const char *pszFilename      = NULL;
     1376    bool        fFilesystemAware = false;
     1377    bool        fVerbose         = true;
     1378
    13771379    int ch;
    13781380    RTGETOPTUNION ValueUnion;
     
    14051407    char *pszFormat = NULL;
    14061408    VDTYPE enmType = VDTYPE_INVALID;
    1407     rc = VDGetFormat(NULL, NULL, pszFilename, &pszFormat, &enmType);
     1409    int rc = VDGetFormat(NULL, NULL, pszFilename, &pszFormat, &enmType);
    14081410    if (RT_FAILURE(rc))
    14091411        return errorSyntax("Format autodetect failed: %Rrc\n", rc);
     
    14191421        return errorRuntime("Error while opening the image: %Rrf (%Rrc)\n", rc, rc);
    14201422
     1423    /*
     1424     * If --file-system-aware, we first ask the disk volume manager (DVM) to
     1425     * find the volumes on the disk.
     1426     */
    14211427    if (   RT_SUCCESS(rc)
    14221428        && fFilesystemAware)
     
    14341440                    && RTDvmMapGetValidVolumes(hDvm) > 0)
    14351441                {
    1436                     /* Get all volumes and set the block query status callback. */
     1442                    /*
     1443                     * Enumerate the volumes: Try finding a file system interpreter and
     1444                     * set the block query status callback to work with the FS.
     1445                     */
     1446                    uint32_t    iVol = 0;
    14371447                    RTDVMVOLUME hVol;
    14381448                    rc = RTDvmMapQueryFirstVolume(hDvm, &hVol);
     
    14411451                    while (RT_SUCCESS(rc))
    14421452                    {
     1453                        if (fVerbose)
     1454                        {
     1455                            char *pszVolName;
     1456                            rc = RTDvmVolumeQueryName(hVol, &pszVolName);
     1457                            if (RT_FAILURE(rc))
     1458                                pszVolName = NULL;
     1459                            RTMsgInfo("Vol%u: %Rhcb %u %s%s%s\n", iVol, RTDvmVolumeGetSize(hVol),
     1460                                      RTDvmVolumeTypeGetDescr(RTDvmVolumeGetType(hVol)),
     1461                                      pszVolName ? " " : "", pszVolName ? pszVolName : "");
     1462                            RTStrFree(pszVolName);
     1463                        }
     1464
    14431465                        RTVFSFILE hVfsFile;
    14441466                        rc = RTDvmVolumeCreateVfsFile(hVol, RTFILE_O_READWRITE, &hVfsFile);
    14451467                        if (RT_FAILURE(rc))
     1468                        {
     1469                            errorRuntime("RTDvmVolumeCreateVfsFile failed: %Rrc\n");
    14461470                            break;
     1471                        }
    14471472
    14481473                        /* Try to detect the filesystem in this volume. */
     1474                        RTERRINFOSTATIC ErrInfo;
    14491475                        RTVFS hVfs;
    1450                         rc = RTFilesystemVfsFromFile(hVfsFile, &hVfs);
    1451                         if (rc == VERR_NOT_SUPPORTED)
    1452                         {
    1453                             /* Release the file handle and continue.*/
    1454                             RTVfsFileRelease(hVfsFile);
    1455                         }
    1456                         else if (RT_FAILURE(rc))
    1457                             break;
    1458                         else
     1476                        rc = RTVfsMountVol(hVfsFile, RTVFSMNT_F_READ_ONLY | RTVFSMNT_F_FOR_RANGE_IN_USE, &hVfs,
     1477                                           RTErrInfoInitStatic(&ErrInfo));
     1478                        RTVfsFileRelease(hVfsFile);
     1479                        if (RT_SUCCESS(rc))
    14591480                        {
    14601481                            PVBOXIMGVFS pVBoxImgVfs = (PVBOXIMGVFS)RTMemAllocZ(sizeof(VBOXIMGVFS));
    14611482                            if (!pVBoxImgVfs)
     1483                            {
     1484                                RTVfsRelease(hVfs);
    14621485                                rc = VERR_NO_MEMORY;
    1463                             else
    1464                             {
    1465                                 pVBoxImgVfs->hVfs = hVfs;
    1466                                 pVBoxImgVfs->pNext = pVBoxImgVfsHead;
    1467                                 pVBoxImgVfsHead = pVBoxImgVfs;
    1468                                 RTDvmVolumeSetQueryBlockStatusCallback(hVol, vboximgQueryBlockStatus, hVfs);
     1486                                break;
    14691487                            }
     1488                            pVBoxImgVfs->hVfs = hVfs;
     1489                            pVBoxImgVfs->pNext = pVBoxImgVfsHead;
     1490                            pVBoxImgVfsHead = pVBoxImgVfs;
     1491                            RTDvmVolumeSetQueryBlockStatusCallback(hVol, vboximgQueryBlockStatus, hVfs);
    14701492                        }
    1471 
     1493                        else if (rc != VERR_NOT_SUPPORTED)
     1494                        {
     1495                            if (RTErrInfoIsSet(&ErrInfo.Core))
     1496                                errorRuntime("RTVfsMountVol failed: %s\n", ErrInfo.Core.pszMsg);
     1497                            break;
     1498                        }
     1499                        else if (fVerbose && RTErrInfoIsSet(&ErrInfo.Core))
     1500                            RTMsgInfo("Unsupported file system: %s", ErrInfo.Core.pszMsg);
     1501
     1502                        /*
     1503                         * Advance.  (Releasing hVol here is fine since RTDvmVolumeCreateVfsFile
     1504                         * retained a reference and the hVfs a reference of it again.)
     1505                         */
    14721506                        RTDVMVOLUME hVolNext = NIL_RTDVMVOLUME;
    14731507                        if (RT_SUCCESS(rc))
    14741508                            rc = RTDvmMapQueryNextVolume(hDvm, hVol, &hVolNext);
    1475 
    1476                         /*
    1477                          * Release the volume handle, the file handle has a reference
    1478                          * to keep it open.
    1479                          */
    14801509                        RTDvmVolumeRelease(hVol);
    14811510                        hVol = hVolNext;
     1511                        iVol++;
    14821512                    }
    14831513
     
    14961526                else if (rc == VERR_NOT_FOUND)
    14971527                {
     1528                    RTPrintf("No known volume format on disk found\n");
    14981529                    rc = VINF_SUCCESS;
    1499                     RTPrintf("No known volume format on disk found\n");
    15001530                }
    15011531                else
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette