VirtualBox

Changeset 76216 in vbox for trunk/src


Ignore:
Timestamp:
Dec 13, 2018 7:26:25 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
127483
Message:

Runtime/fs: Started restructurin the ext2 filesystem code to indicate that it will be used for ext3/ext4 later on

Location:
trunk/src/VBox/Runtime
Files:
2 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r76115 r76216  
    438438        common/err/RTErrConvertFromErrno.cpp \
    439439        common/err/RTErrConvertToErrno.cpp \
    440         common/fs/ext2vfs.cpp \
     440        common/fs/extvfs.cpp \
    441441        common/fs/fatvfs.cpp \
    442442        common/fs/isovfs.cpp \
  • trunk/src/VBox/Runtime/common/fs/extvfs.cpp

    r76215 r76216  
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333
    3434#include <iprt/assert.h>
     35#include <iprt/file.h>
    3536#include <iprt/log.h>
    3637#include <iprt/mem.h>
     
    3839#include <iprt/vfs.h>
    3940#include <iprt/vfslowlevel.h>
    40 #include <iprt/formats/ext2.h>
     41#include <iprt/formats/ext.h>
    4142
    4243
     
    4748 * Cached block group descriptor data.
    4849 */
    49 typedef struct RTFILESYSTEMEXTBLKGRP
     50typedef struct RTFSEXTBLKGRP
    5051{
    5152    /** Start offset (in bytes and from the start of the disk). */
     
    5657     * and number of blocks per group). */
    5758    uint8_t     abBlockBitmap[1];
    58 } RTFILESYSTEMEXTBLKGRP;
     59} RTFSEXTBLKGRP;
    5960/** Pointer to block group descriptor data. */
    60 typedef RTFILESYSTEMEXTBLKGRP *PRTFILESYSTEMEXTBLKGRP;
    61 
    62 /**
    63  * Ext2/3 filesystem data.
    64  */
    65 typedef struct RTFILESYSTEMEXT
    66 {
    67     /** VFS file handle. */
    68     RTVFSFILE                 hVfsFile;
     61typedef RTFSEXTBLKGRP *PRTFSEXTBLKGRP;
     62
     63/**
     64 * Ext2/3/4 filesystem volume.
     65 */
     66typedef struct RTFSEXTVOL
     67{
     68    /** Handle to itself. */
     69    RTVFS               hVfsSelf;
     70    /** The file, partition, or whatever backing the ext volume. */
     71    RTVFSFILE           hVfsBacking;
     72    /** The size of the backing thingy. */
     73    uint64_t            cbBacking;
     74    /** The formatted size of the volume. */
     75    uint64_t            cbVolume;
     76    /** cbVolume expressed as a cluster count. */
     77    uint64_t            cClusters;
     78
     79    /** RTVFSMNT_F_XXX. */
     80    uint32_t            fMntFlags;
     81    /** RTFSEXTVFS_F_XXX (currently none defined). */
     82    uint32_t            fExtFlags;
     83
     84    /** The (logical) sector size. */
     85    uint32_t            cbSector;
     86
     87    /** The (logical) cluster size. */
     88    uint32_t            cbCluster;
     89
    6990    /** Block number of the superblock. */
    70     uint32_t                  iSbBlock;
     91    uint32_t            iSbBlock;
    7192    /** Size of one block. */
    72     size_t                    cbBlock;
     93    size_t              cbBlock;
    7394    /** Number of blocks in one group. */
    74     unsigned                  cBlocksPerGroup;
     95    unsigned            cBlocksPerGroup;
    7596    /** Number of blocks groups in the volume. */
    76     unsigned                  cBlockGroups;
     97    unsigned            cBlockGroups;
    7798    /** Cached block group descriptor data. */
    78     PRTFILESYSTEMEXTBLKGRP    pBlkGrpDesc;
    79 } RTFILESYSTEMEXT;
     99    PRTFSEXTBLKGRP      pBlkGrpDesc;
     100} RTFSEXTVOL;
    80101/** Pointer to the ext filesystem data. */
    81 typedef RTFILESYSTEMEXT *PRTFILESYSTEMEXT;
     102typedef RTFSEXTVOL *PRTFSEXTVOL;
    82103
    83104
     
    90111 * @param   iBlkGrp  Block group number to load.
    91112 */
    92 static int rtFsExtLoadBlkGrpDesc(PRTFILESYSTEMEXT pThis, uint32_t iBlkGrp)
     113static int rtFsExtLoadBlkGrpDesc(PRTFSEXTVOL pThis, uint32_t iBlkGrp)
    93114{
    94115    size_t cbBlockBitmap = pThis->cBlocksPerGroup / 8;
     
    96117        cbBlockBitmap++;
    97118
    98     PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
     119    PRTFSEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
    99120    if (!pBlkGrpDesc)
    100121    {
    101         size_t cbBlkDesc = RT_UOFFSETOF_DYN(RTFILESYSTEMEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);
    102         pBlkGrpDesc = (PRTFILESYSTEMEXTBLKGRP)RTMemAllocZ(cbBlkDesc);
     122        size_t cbBlkDesc = RT_UOFFSETOF_DYN(RTFSEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);
     123        pBlkGrpDesc = (PRTFSEXTBLKGRP)RTMemAllocZ(cbBlkDesc);
    103124        if (!pBlkGrpDesc)
    104125            return VERR_NO_MEMORY;
    105126    }
    106127
    107     uint64_t            offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
    108     EXT2BLOCKGROUPDESC  BlkDesc;
    109     int rc = RTVfsFileReadAt(pThis->hVfsFile, offRead, &BlkDesc, sizeof(BlkDesc), NULL);
     128    uint64_t           offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
     129    EXTBLOCKGROUPDESC  BlkDesc;
     130    int rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &BlkDesc, sizeof(BlkDesc), NULL);
    110131    if (RT_SUCCESS(rc))
    111132    {
    112133        pBlkGrpDesc->offStart = pThis->iSbBlock + (uint64_t)iBlkGrp * pThis->cBlocksPerGroup * pThis->cbBlock;
    113134        pBlkGrpDesc->offLast  = pBlkGrpDesc->offStart + pThis->cBlocksPerGroup * pThis->cbBlock;
    114         rc = RTVfsFileReadAt(pThis->hVfsFile, BlkDesc.offBlockBitmap * pThis->cbBlock,
     135        rc = RTVfsFileReadAt(pThis->hVfsBacking, BlkDesc.offBlockBitmap * pThis->cbBlock,
    115136                             &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap, NULL);
    116137    }
     
    121142
    122143
    123 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, uint32_t offBlockStart, size_t cBlocks)
     144static bool rtFsExtIsBlockRangeInUse(PRTFSEXTBLKGRP pBlkGrpDesc, uint32_t offBlockStart, size_t cBlocks)
    124145{
    125146    while (cBlocks)
     
    142163 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}
    143164 */
    144 static DECLCALLBACK(int) rtFsExt2Vol_Close(void *pvThis)
    145 {
    146     PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
     165static DECLCALLBACK(int) rtFsExtVol_Close(void *pvThis)
     166{
     167    PRTFSEXTVOL pThis = (PRTFSEXTVOL)pvThis;
    147168
    148169    if (pThis->pBlkGrpDesc)
     
    156177 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}
    157178 */
    158 static DECLCALLBACK(int) rtFsExt2Vol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     179static DECLCALLBACK(int) rtFsExtVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    159180{
    160181    RT_NOREF(pvThis, pObjInfo, enmAddAttr);
     
    166187 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnOpenRoot}
    167188 */
    168 static DECLCALLBACK(int) rtFsExt2_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
     189static DECLCALLBACK(int) rtFsExtVol_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
    169190{
    170191    NOREF(pvThis);
     
    177198 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryRangeState}
    178199 */
    179 static DECLCALLBACK(int) rtFsExt2_QueryRangeState(void *pvThis, uint64_t off, size_t cb, bool *pfUsed)
    180 {
    181     int                 rc    = VINF_SUCCESS;
    182     PRTFILESYSTEMEXT    pThis = (PRTFILESYSTEMEXT)pvThis;
     200static DECLCALLBACK(int) rtFsExtVol_QueryRangeState(void *pvThis, uint64_t off, size_t cb, bool *pfUsed)
     201{
     202    int            rc    = VINF_SUCCESS;
     203    PRTFSEXTVOL    pThis = (PRTFSEXTVOL)pvThis;
    183204
    184205    *pfUsed = false;
     
    216237
    217238
    218 DECL_HIDDEN_CONST(const RTVFSOPS) g_rtFsExt2VolOps =
     239DECL_HIDDEN_CONST(const RTVFSOPS) g_rtFsExtVolOps =
    219240{
    220241    /* .Obj = */
     
    222243        /* .uVersion = */       RTVFSOBJOPS_VERSION,
    223244        /* .enmType = */        RTVFSOBJTYPE_VFS,
    224         /* .pszName = */        "Ext2Vol",
    225         /* .pfnClose = */       rtFsExt2Vol_Close,
    226         /* .pfnQueryInfo = */   rtFsExt2Vol_QueryInfo,
     245        /* .pszName = */        "ExtVol",
     246        /* .pfnClose = */       rtFsExtVol_Close,
     247        /* .pfnQueryInfo = */   rtFsExtVol_QueryInfo,
    227248        /* .uEndMarker = */     RTVFSOBJOPS_VERSION
    228249    },
    229250    /* .uVersion = */           RTVFSOPS_VERSION,
    230251    /* .fFeatures = */          0,
    231     /* .pfnOpenRoot = */        rtFsExt2_OpenRoot,
    232     /* .pfnQueryRangeState = */ rtFsExt2_QueryRangeState,
     252    /* .pfnOpenRoot = */        rtFsExtVol_OpenRoot,
     253    /* .pfnQueryRangeState = */ rtFsExtVol_QueryRangeState,
    233254    /* .uEndMarker = */         RTVFSOPS_VERSION
    234255};
    235256
    236257
    237 RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo)
     258RTDECL(int) RTFsExtVolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo)
    238259{
    239260    AssertPtrReturn(phVfs, VERR_INVALID_POINTER);
     
    244265    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
    245266
    246     PRTFILESYSTEMEXT pThis;
    247     int rc = RTVfsNew(&g_rtFsExt2VolOps, sizeof(*pThis), NIL_RTVFS, RTVFSLOCK_CREATE_RW, phVfs, (void **)&pThis);
     267    PRTFSEXTVOL pThis;
     268    int rc = RTVfsNew(&g_rtFsExtVolOps, sizeof(*pThis), NIL_RTVFS, RTVFSLOCK_CREATE_RW, phVfs, (void **)&pThis);
    248269    if (RT_SUCCESS(rc))
    249270    {
    250         pThis->hVfsFile    = hVfsFileIn;
     271        pThis->hVfsBacking = hVfsFileIn;
    251272        pThis->pBlkGrpDesc = NULL;
    252273
    253         EXT2SUPERBLOCK SuperBlock;
    254         rc = RTVfsFileReadAt(hVfsFileIn, 1024, &SuperBlock, sizeof(EXT2SUPERBLOCK), NULL);
     274        EXTSUPERBLOCK SuperBlock;
     275        rc = RTVfsFileReadAt(hVfsFileIn, 1024, &SuperBlock, sizeof(EXTSUPERBLOCK), NULL);
    255276        if (RT_SUCCESS(rc))
    256277        {
     
    258279            /** @todo Convert to host endianess. */
    259280#endif
    260             if (SuperBlock.u16FilesystemState == EXT2_STATE_ERRORS)
    261                 rc = RTERRINFO_LOG_SET(pErrInfo, VERR_FILESYSTEM_CORRUPT, "EXT2_STATE_ERRORS");
     281            if (SuperBlock.u16FilesystemState == EXT_STATE_ERRORS)
     282                rc = RTERRINFO_LOG_SET(pErrInfo, VERR_FILESYSTEM_CORRUPT, "EXT_STATE_ERRORS");
    262283            else
    263284            {
     
    287308}
    288309
     310
     311/**
     312 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate}
     313 */
     314static DECLCALLBACK(int) rtVfsChainExtVol_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
     315                                                   PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo)
     316{
     317    RT_NOREF(pProviderReg);
     318
     319    /*
     320     * Basic checks.
     321     */
     322    if (pElement->enmTypeIn != RTVFSOBJTYPE_FILE)
     323        return pElement->enmTypeIn == RTVFSOBJTYPE_INVALID ? VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT : VERR_VFS_CHAIN_TAKES_FILE;
     324    if (   pElement->enmType != RTVFSOBJTYPE_VFS
     325        && pElement->enmType != RTVFSOBJTYPE_DIR)
     326        return VERR_VFS_CHAIN_ONLY_DIR_OR_VFS;
     327    if (pElement->cArgs > 1)
     328        return VERR_VFS_CHAIN_AT_MOST_ONE_ARG;
     329
     330    /*
     331     * Parse the flag if present, save in pElement->uProvider.
     332     */
     333    bool fReadOnly = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ;
     334    if (pElement->cArgs > 0)
     335    {
     336        const char *psz = pElement->paArgs[0].psz;
     337        if (*psz)
     338        {
     339            if (!strcmp(psz, "ro"))
     340                fReadOnly = true;
     341            else if (!strcmp(psz, "rw"))
     342                fReadOnly = false;
     343            else
     344            {
     345                *poffError = pElement->paArgs[0].offSpec;
     346                return RTErrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Expected 'ro' or 'rw' as argument");
     347            }
     348        }
     349    }
     350
     351    pElement->uProvider = fReadOnly ? RTVFSMNT_F_READ_ONLY : 0;
     352    return VINF_SUCCESS;
     353}
     354
     355
     356/**
     357 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
     358 */
     359static DECLCALLBACK(int) rtVfsChainExtVol_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
     360                                                      PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
     361                                                      PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo)
     362{
     363    RT_NOREF(pProviderReg, pSpec, poffError);
     364
     365    int         rc;
     366    RTVFSFILE   hVfsFileIn = RTVfsObjToFile(hPrevVfsObj);
     367    if (hVfsFileIn != NIL_RTVFSFILE)
     368    {
     369        RTVFS hVfs;
     370        rc = RTFsFatVolOpen(hVfsFileIn, (uint32_t)pElement->uProvider, (uint32_t)(pElement->uProvider >> 32), &hVfs, pErrInfo);
     371        RTVfsFileRelease(hVfsFileIn);
     372        if (RT_SUCCESS(rc))
     373        {
     374            *phVfsObj = RTVfsObjFromVfs(hVfs);
     375            RTVfsRelease(hVfs);
     376            if (*phVfsObj != NIL_RTVFSOBJ)
     377                return VINF_SUCCESS;
     378            rc = VERR_VFS_CHAIN_CAST_FAILED;
     379        }
     380    }
     381    else
     382        rc = VERR_VFS_CHAIN_CAST_FAILED;
     383    return rc;
     384}
     385
     386
     387/**
     388 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement}
     389 */
     390static DECLCALLBACK(bool) rtVfsChainExtVol_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg,
     391                                                           PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
     392                                                           PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement)
     393{
     394    RT_NOREF(pProviderReg, pSpec, pReuseSpec);
     395    if (   pElement->paArgs[0].uProvider == pReuseElement->paArgs[0].uProvider
     396        || !pReuseElement->paArgs[0].uProvider)
     397        return true;
     398    return false;
     399}
     400
     401
     402/** VFS chain element 'ext'. */
     403static RTVFSCHAINELEMENTREG g_rtVfsChainExtVolReg =
     404{
     405    /* uVersion = */            RTVFSCHAINELEMENTREG_VERSION,
     406    /* fReserved = */           0,
     407    /* pszName = */             "ext",
     408    /* ListEntry = */           { NULL, NULL },
     409    /* pszHelp = */             "Open a EXT file system, requires a file object on the left side.\n"
     410                                "First argument is an optional 'ro' (read-only) or 'rw' (read-write) flag.\n",
     411    /* pfnValidate = */         rtVfsChainExtVol_Validate,
     412    /* pfnInstantiate = */      rtVfsChainExtVol_Instantiate,
     413    /* pfnCanReuseElement = */  rtVfsChainExtVol_CanReuseElement,
     414    /* uEndMarker = */          RTVFSCHAINELEMENTREG_VERSION
     415};
     416
     417RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainExtVolReg, rtVfsChainExtVolReg);
     418
  • trunk/src/VBox/Runtime/common/vfs/vfsmount.cpp

    r73097 r76216  
    4545#include <iprt/formats/iso9660.h>
    4646#include <iprt/formats/udf.h>
    47 #include <iprt/formats/ext2.h>
     47#include <iprt/formats/ext.h>
    4848
    4949
     
    352352
    353353/**
    354  * Check if the given bootsector is an HPFS boot sector.
     354 * Check if the given bootsector is an ext2/3/4 super block.
    355355 *
    356356 * @returns true if NTFS, false if not.
    357357 * @param   pSuperBlock         The ext2 superblock.
    358358 */
    359 static bool rtVfsMountIsExt2(PCEXT2SUPERBLOCK pSuperBlock)
    360 {
    361     if (RT_LE2H_U16(pSuperBlock->u16Signature) != EXT2_SIGNATURE)
     359static bool rtVfsMountIsExt(PCEXTSUPERBLOCK pSuperBlock)
     360{
     361    if (RT_LE2H_U16(pSuperBlock->u16Signature) != EXT_SIGNATURE)
    362362        return false;
    363363
     
    365365    if (cShift > 54)
    366366    {
    367         Log2(("rtVfsMountIsExt2: cBitsShiftLeftBlockSize=%#x: out of range\n", cShift));
     367        Log2(("rtVfsMountIsExt: cBitsShiftLeftBlockSize=%#x: out of range\n", cShift));
    368368        return false;
    369369    }
     
    372372    if (cShift > 54)
    373373    {
    374         Log2(("rtVfsMountIsExt2: cBitsShiftLeftFragmentSize=%#x: out of range\n", cShift));
     374        Log2(("rtVfsMountIsExt: cBitsShiftLeftFragmentSize=%#x: out of range\n", cShift));
    375375        return false;
    376376    }
     
    435435    }
    436436
    437     AssertCompile(sizeof(*pBuf) >= 1024 + sizeof(EXT2SUPERBLOCK));
    438     if (rtVfsMountIsExt2((PCEXT2SUPERBLOCK)&pBuf->ab[1024]))
    439     {
    440         Log(("RTVfsMount: Detected ISO-9660 or UDF.\n"));
    441         return RTFsExt2VolOpen(hVfsFileIn, fFlags, 0 /*fExt2Flags*/, phVfs, pErrInfo);
     437    AssertCompile(sizeof(*pBuf) >= 1024 + sizeof(EXTSUPERBLOCK));
     438    if (rtVfsMountIsExt((PCEXTSUPERBLOCK)&pBuf->ab[1024]))
     439    {
     440        Log(("RTVfsMount: Detected EXT2/3/4.\n"));
     441        return RTFsExtVolOpen(hVfsFileIn, fFlags, 0 /*fExt2Flags*/, phVfs, pErrInfo);
    442442    }
    443443
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