VirtualBox

Changeset 41549 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Jun 1, 2012 5:29:05 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
78314
Message:

VFS/Filesystem: Convert the filesystem specific code to the VFS framework and make it work

Location:
trunk/src/VBox/Runtime/common
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dvm/dvm.cpp

    r40293 r41549  
    469469{
    470470    int rc = VINF_SUCCESS;
    471     bool fAllocated = false;
    472471    PRTDVMINTERNAL       pThis = hVolMgr;
    473472    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     
    478477                 VERR_INVALID_PARAMETER);
    479478
    480     while (   cb > 0
    481            && !fAllocated)
    482     {
    483         PRTDVMVOLUMEINTERNAL pVol;
    484         bool fVolFound = false;
    485         uint64_t cbIntersect;
    486         uint64_t offVol;
    487 
    488         /*
    489          * Search through all volumes. It is not possible to
    490          * get all start sectors and sizes of all volumes here
    491          * because volumes can be scattered around the disk for certain formats.
    492          * Linux LVM is one example, extents of logical volumes don't need to be
    493          * contigous on the medium.
    494          */
    495         RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode)
     479    /* Check whether the range is inuse by the volume manager metadata first. */
     480    rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
     481    if (RT_FAILURE(rc))
     482        return rc;
     483
     484    if (!*pfAllocated)
     485    {
     486        bool fAllocated = false;
     487
     488        while (   cb > 0
     489               && !fAllocated)
    496490        {
    497             bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off,
    498                                                                               cb, &offVol,
    499                                                                               &cbIntersect);
    500             if (fIntersect)
     491            PRTDVMVOLUMEINTERNAL pVol;
     492            bool fVolFound = false;
     493            uint64_t cbIntersect;
     494            uint64_t offVol;
     495
     496            /*
     497             * Search through all volumes. It is not possible to
     498             * get all start sectors and sizes of all volumes here
     499             * because volumes can be scattered around the disk for certain formats.
     500             * Linux LVM is one example, extents of logical volumes don't need to be
     501             * contigous on the medium.
     502             */
     503            RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode)
    501504            {
    502                 fVolFound = true;
    503                 if (pVol->pfnQueryBlockStatus)
     505                bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off,
     506                                                                                  cb, &offVol,
     507                                                                                  &cbIntersect);
     508                if (fIntersect)
    504509                {
    505                     bool fVolAllocated = true;
    506 
    507                     rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
    508                                                    &fVolAllocated);
    509                     if (RT_FAILURE(rc))
    510                         break;
     510                    fVolFound = true;
     511                    if (pVol->pfnQueryBlockStatus)
     512                    {
     513                        bool fVolAllocated = true;
     514
     515                        rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
     516                                                       &fVolAllocated);
     517                        if (RT_FAILURE(rc))
     518                            break;
     519                        else if (fVolAllocated)
     520                        {
     521                            fAllocated = true;
     522                            break;
     523                        }
     524                    }
     525                    else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))
     526                        fAllocated = true;
     527                    /* else, flag is set, continue. */
     528
     529                    cb  -= cbIntersect;
     530                    off += cbIntersect;
     531                    break;
    511532                }
    512                 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))
     533            }
     534
     535            if (!fVolFound)
     536            {
     537                if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
    513538                    fAllocated = true;
    514                 /* else, flag is set, continue. */
    515 
    516                 cb  -= cbIntersect;
    517                 off += cbIntersect;
    518                 break;
     539
     540                cb  -= pThis->DvmDisk.cbSector;
     541                off += pThis->DvmDisk.cbSector;
    519542            }
    520543        }
    521544
    522         if (!fVolFound)
    523         {
    524             if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
    525                 fAllocated = true;
    526 
    527             cb  -= pThis->DvmDisk.cbSector;
    528             off += pThis->DvmDisk.cbSector;
    529         }
    530     }
    531 
    532     *pfAllocated = fAllocated;
     545        *pfAllocated = fAllocated;
     546    }
    533547
    534548    return rc;
  • trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp

    r40949 r41549  
    343343}
    344344
     345static DECLCALLBACK(int) rtDvmFmtBsdLblQueryRangeUse(RTDVMFMT hVolMgrFmt,
     346                                                     uint64_t off, uint64_t cbRange,
     347                                                     bool *pfUsed)
     348{
     349    PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
     350
     351    if (off <= RTDVM_BSDLBL_LBA2BYTE(1, pThis->pDisk))
     352        *pfUsed = true;
     353    else
     354        *pfUsed = false;
     355
     356    return VINF_SUCCESS;
     357}
     358
    345359DECLCALLBACK(uint32_t) rtDvmFmtBsdLblGetValidVolumes(RTDVMFMT hVolMgrFmt)
    346360{
     
    513527    /* pfnClose */
    514528    rtDvmFmtBsdLblClose,
     529    /* pfnQueryRangeUse */
     530    rtDvmFmtBsdLblQueryRangeUse,
    515531    /* pfnGetValidVolumes */
    516532    rtDvmFmtBsdLblGetValidVolumes,
  • trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp

    r40949 r41549  
    342342}
    343343
     344static DECLCALLBACK(int) rtDvmFmtGptQueryRangeUse(RTDVMFMT hVolMgrFmt,
     345                                                  uint64_t off, uint64_t cbRange,
     346                                                  bool *pfUsed)
     347{
     348    PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
     349
     350    if (off < 33*pThis->pDisk->cbSector)
     351        *pfUsed = true;
     352    else
     353        *pfUsed = false;
     354
     355    return VINF_SUCCESS;
     356}
     357
    344358static DECLCALLBACK(uint32_t) rtDvmFmtGptGetValidVolumes(RTDVMFMT hVolMgrFmt)
    345359{
     
    531545    /* pfnClose */
    532546    rtDvmFmtGptClose,
     547    /* pfnQueryRangeUse */
     548    rtDvmFmtGptQueryRangeUse,
    533549    /* pfnGetValidVolumes */
    534550    rtDvmFmtGptGetValidVolumes,
  • trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp

    r40298 r41549  
    212212}
    213213
     214static DECLCALLBACK(int) rtDvmFmtMbrQueryRangeUse(RTDVMFMT hVolMgrFmt,
     215                                                  uint64_t off, uint64_t cbRange,
     216                                                  bool *pfUsed)
     217{
     218    PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
     219
     220    /* MBR uses the first sector only. */
     221    if (off < 512)
     222        *pfUsed = true;
     223    else
     224        *pfUsed = false;
     225
     226    return VINF_SUCCESS;
     227}
     228
    214229static DECLCALLBACK(uint32_t) rtDvmFmtMbrGetValidVolumes(RTDVMFMT hVolMgrFmt)
    215230{
     
    399414    /* pfnClose */
    400415    rtDvmFmtMbrClose,
     416    /* pfnQueryRangeUse */
     417    rtDvmFmtMbrQueryRangeUse,
    401418    /* pfnGetValidVolumes */
    402419    rtDvmFmtMbrGetValidVolumes,
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r41094 r41549  
    9393
    9494    Assert(pSgBuf->cSegs == 1);
    95     Assert(off < 0);
    9695    NOREF(fBlocking);
    9796
     
    149148
    150149    Assert(pSgBuf->cSegs == 1);
    151     Assert(off < 0);
    152150    NOREF(fBlocking);
    153151
  • trunk/src/VBox/Runtime/common/filesystem/filesystem.cpp

    r40038 r41549  
    4141
    4242/*******************************************************************************
    43 *   Structures and Typedefs                                                    *
    44 *******************************************************************************/
    45 
    46 /**
    47  * Medium descriptor.
    48  */
    49 typedef struct RTFILESYSTEMMEDIUMINT
    50 {
    51     /** Size of the medium in bytes. */
    52     uint64_t                cbMedium;
    53     /** Sector size. */
    54     uint64_t                cbSector;
    55     /** Read callback */
    56     PFNRTFILESYSTEMREAD     pfnRead;
    57     /** Write callback. */
    58     PFNRTFILESYSTEMWRITE    pfnWrite;
    59     /** Opaque user data. */
    60     void                    *pvUser;
    61 } RTFILESYSTEMMEDIUMINT;
    62 /** Pointer to a disk descriptor. */
    63 typedef RTFILESYSTEMMEDIUMINT *PRTFILESYSTEMMEDIUMINT;
    64 /** Pointer to a const descriptor. */
    65 typedef const RTFILESYSTEMMEDIUMINT *PCRTFILESYSTEMMEDIUMINT;
    66 
    67 /**
    68  * The internal filesystem object structure.
    69  */
    70 typedef struct RTFILESYSTEMINT
    71 {
    72     /** The filesytem object magic (RTFILESYSTEM_MAGIC). */
    73     uint32_t              u32Magic;
    74     /** Medium descriptor. */
    75     RTFILESYSTEMMEDIUMINT Medium;
    76     /** Filesystem format operations */
    77     PCRTFILESYSTEMFMTOPS  pcFsFmtOps;
    78     /** Filesystem format handle. */
    79     RTFILESYSTEMFMT       hFsFmt;
    80     /** Reference counter. */
    81     uint32_t volatile     cRefs;
    82 } RTFILESYSTEMINT;
    83 /** Pointer to an internal volume manager. */
    84 typedef RTFILESYSTEMINT *PRTFILESYSTEMINT;
    85 
    86 /*******************************************************************************
    8743*  Global variables                                                            *
    8844*******************************************************************************/
    89 extern RTFILESYSTEMFMTOPS g_rtFilesystemFmtExt;
    9045
    9146/**
    9247 * Supported volume formats.
    9348 */
    94 static PCRTFILESYSTEMFMTOPS g_aFilesystemFmts[] =
     49static PCRTFILESYSTEMDESC g_aFsFmts[] =
    9550{
    96     &g_rtFilesystemFmtExt
     51    &g_rtFsExt
    9752};
    9853
    99 DECLHIDDEN(uint64_t) rtFilesystemMediumGetSize(RTFILESYSTEMMEDIUM hMedium)
    100 {
    101     PRTFILESYSTEMMEDIUMINT pMedInt = hMedium;
    102     AssertPtrReturn(pMedInt, 0);
    103 
    104     return pMedInt->cbMedium;
    105 }
    106 
    107 DECLHIDDEN(int) rtFilesystemMediumRead(RTFILESYSTEMMEDIUM hMedium, uint64_t off,
    108                                        void *pvBuf, size_t cbRead)
    109 {
    110     PRTFILESYSTEMMEDIUMINT pMedInt = hMedium;
    111     AssertPtrReturn(pMedInt, VERR_INVALID_HANDLE);
    112 
    113     return pMedInt->pfnRead(pMedInt->pvUser, off, pvBuf, cbRead);
    114 }
    115 
    116 DECLHIDDEN(int) rtFilesystemMediumWrite(RTFILESYSTEMMEDIUM hMedium, uint64_t off,
    117                                         const void *pvBuf, size_t cbWrite)
    118 {
    119     PRTFILESYSTEMMEDIUMINT pMedInt = hMedium;
    120     AssertPtrReturn(pMedInt, VERR_INVALID_HANDLE);
    121 
    122     return pMedInt->pfnWrite(pMedInt->pvUser, off, pvBuf, cbWrite);
    123 }
    124 
    125 RTDECL(uint32_t) RTFilesystemRetain(RTFILESYSTEM hFs)
    126 {
    127     PRTFILESYSTEMINT pThis = hFs;
    128     AssertPtrReturn(pThis, UINT32_MAX);
    129     AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, UINT32_MAX);
    130 
    131     uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
    132     AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
    133     return cRefs;
    134 }
    135 
    136 /**
    137  * Destroys a volume manager handle.
    138  *
    139  * @param   pThis               The filesystem object to destroy.
    140  */
    141 static void rtFilesystemDestroy(PRTFILESYSTEMINT pThis)
    142 {
    143     if (pThis->hFsFmt != NIL_RTFILESYSTEMFMT)
    144     {
    145         AssertPtr(pThis->pcFsFmtOps);
    146 
    147         /* Let the backend do it's own cleanup first. */
    148         pThis->pcFsFmtOps->pfnClose(pThis->hFsFmt);
    149         pThis->hFsFmt = NIL_RTFILESYSTEMFMT;
    150     }
    151 
    152     pThis->Medium.cbMedium   = 0;
    153     pThis->Medium.pvUser   = NULL;
    154     pThis->Medium.pfnRead  = NULL;
    155     pThis->Medium.pfnWrite = NULL;
    156     pThis->u32Magic        = RTFILESYSTEM_MAGIC_DEAD;
    157     RTMemFree(pThis);
    158 }
    159 
    160 RTDECL(uint32_t) RTFilesystemRelease(RTFILESYSTEM hFs)
    161 {
    162     PRTFILESYSTEMINT pThis = hFs;
    163     if (pThis == NIL_RTFILESYSTEM)
    164         return 0;
    165     AssertPtrReturn(pThis, UINT32_MAX);
    166     AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, UINT32_MAX);
    167 
    168     uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
    169     AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
    170     if (cRefs == 0)
    171         rtFilesystemDestroy(pThis);
    172     return cRefs;
    173 }
    174 
    175 RTDECL(int) RTFilesystemOpen(PRTFILESYSTEM phFs, PFNRTFILESYSTEMREAD pfnRead,
    176                              PFNRTFILESYSTEMWRITE pfnWrite, uint64_t cbMedium,
    177                              uint64_t cbSector, void *pvUser, uint32_t fFlags)
     54static int rtFsGetFormat(RTVFSFILE hVfsFile, PCRTFILESYSTEMDESC *ppFsDesc)
    17855{
    17956    int                   rc = VINF_SUCCESS;
    18057    uint32_t              uScoreMax = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
    181     PCRTFILESYSTEMFMTOPS  pcFsFmtOpsMatch = NULL;
    182     PRTFILESYSTEMINT      pThis = NULL;
    183     AssertPtrReturn(phFs, VERR_INVALID_POINTER);
    184     AssertPtrReturn(pfnRead, VERR_INVALID_POINTER);
     58    PCRTFILESYSTEMDESC    pFsFmtMatch = NULL;
    18559
    186     pThis = (PRTFILESYSTEMINT)RTMemAllocZ(sizeof(RTFILESYSTEMINT));
    187     if (!pThis)
    188         return VERR_NO_MEMORY;
    189 
    190     pThis->u32Magic        = RTFILESYSTEM_MAGIC;
    191     pThis->Medium.cbMedium = cbMedium;
    192     pThis->Medium.cbSector = cbSector;
    193     pThis->Medium.pfnRead  = pfnRead;
    194     pThis->Medium.pfnWrite = pfnWrite;
    195     pThis->Medium.pvUser   = pvUser;
    196     pThis->cRefs           = 1;
    197 
    198     for (unsigned i = 0; i < RT_ELEMENTS(g_aFilesystemFmts); i++)
     60    for (unsigned i = 0; i < RT_ELEMENTS(g_aFsFmts); i++)
    19961    {
    20062        uint32_t uScore;
    201         PCRTFILESYSTEMFMTOPS pcFsFmtOps = g_aFilesystemFmts[i];
     63        PCRTFILESYSTEMDESC pFsFmt = g_aFsFmts[i];
    20264
    203         rc = pcFsFmtOps->pfnProbe(&pThis->Medium, &uScore);
     65        rc = pFsFmt->pfnProbe(hVfsFile, &uScore);
    20466        if (   RT_SUCCESS(rc)
    20567            && uScore > uScoreMax)
    20668        {
    207             pcFsFmtOpsMatch = pcFsFmtOps;
    208             uScoreMax       = uScore;
     69            pFsFmtMatch = pFsFmt;
     70            uScoreMax   = uScore;
    20971        }
    21072        else if (RT_FAILURE(rc))
     
    21678        if (uScoreMax > RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED)
    21779        {
    218             AssertPtr(pcFsFmtOpsMatch);
    219 
    220             /* Open the format. */
    221             rc = pcFsFmtOpsMatch->pfnOpen(&pThis->Medium, &pThis->hFsFmt);
    222             if (RT_SUCCESS(rc))
    223                 pThis->pcFsFmtOps = pcFsFmtOpsMatch;
     80            AssertPtr(pFsFmtMatch);
     81            *ppFsDesc = pFsFmtMatch;
    22482        }
    22583        else
     
    22785    }
    22886
     87    return rc;
     88}
     89
     90RTDECL(int) RTFilesystemVfsFromFile(RTVFSFILE hVfsFile, PRTVFS phVfs)
     91{
     92    int rc = VINF_SUCCESS;
     93    PCRTFILESYSTEMDESC pFsDesc = NULL;
     94    RTVFS hVfs = NIL_RTVFS;
     95    void *pvThis = NULL;
     96
     97    AssertPtrReturn(hVfsFile, VERR_INVALID_HANDLE);
     98    AssertPtrReturn(phVfs, VERR_INVALID_POINTER);
     99
     100    rc = rtFsGetFormat(hVfsFile, &pFsDesc);
    229101    if (RT_SUCCESS(rc))
    230         *phFs = pThis;
    231     else
    232         RTMemFree(pThis);
     102    {
     103        rc = RTVfsNew(&pFsDesc->VfsOps, pFsDesc->cbFs, NIL_RTVFS, NIL_RTVFSLOCK,
     104                      &hVfs, &pvThis);
     105        if (RT_SUCCESS(rc))
     106        {
     107            rc = pFsDesc->pfnInit(pvThis, hVfsFile);
     108            if (RT_SUCCESS(rc))
     109                *phVfs = hVfs;
     110            else
     111                RTVfsRelease(hVfs);
     112        }
     113    }
    233114
    234115    return rc;
    235116}
    236117
    237 RTDECL(const char *) RTFilesystemGetFormat(RTFILESYSTEM hFs)
    238 {
    239     PRTFILESYSTEMINT pThis = hFs;
    240     AssertPtrReturn(pThis, NULL);
    241     AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, NULL);
    242118
    243     return pThis->pcFsFmtOps->pcszFmt;
    244 }
    245 
    246 RTDECL(uint64_t) RTFilesystemGetBlockSize(RTFILESYSTEM hFs)
    247 {
    248     PRTFILESYSTEMINT pThis = hFs;
    249     AssertPtrReturn(pThis, 0);
    250     AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, 0);
    251 
    252     return pThis->pcFsFmtOps->pfnGetBlockSize(pThis->hFsFmt);
    253 }
    254 
    255 RTDECL(int) RTFilesystemQueryRangeUse(RTFILESYSTEM hFs, uint64_t offStart, size_t cb,
    256                                       bool *pfUsed)
    257 {
    258     PRTFILESYSTEMINT pThis = hFs;
    259     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    260     AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, VERR_INVALID_HANDLE);
    261     AssertPtrReturn(pfUsed, VERR_INVALID_POINTER);
    262     AssertReturn(offStart + cb <= pThis->Medium.cbMedium, VERR_OUT_OF_RANGE);
    263 
    264     return pThis->pcFsFmtOps->pfnQueryRangeUse(pThis->hFsFmt, offStart, cb, pfUsed);
    265 }
  • trunk/src/VBox/Runtime/common/filesystem/filesystemext.cpp

    r40038 r41549  
    3535#include <iprt/filesystem.h>
    3636#include <iprt/string.h>
     37#include <iprt/vfs.h>
    3738#include "internal/filesystem.h"
    3839
     
    151152 * Cached block group descriptor data.
    152153 */
    153 typedef struct RTFILESYSTEMFMTEXTBLKGRP
     154typedef struct RTFILESYSTEMEXTBLKGRP
    154155{
    155156    /** Start offset (in bytes and from the start of the disk). */
     
    160161     * and number of blocks per group). */
    161162    uint8_t     abBlockBitmap[1];
    162 } RTFILESYSTEMFMTEXTBLKGRP;
     163} RTFILESYSTEMEXTBLKGRP;
    163164/** Pointer to block group descriptor data. */
    164 typedef RTFILESYSTEMFMTEXTBLKGRP *PRTFILESYSTEMFMTEXTBLKGRP;
     165typedef RTFILESYSTEMEXTBLKGRP *PRTFILESYSTEMEXTBLKGRP;
    165166
    166167/**
    167168 * Ext2/3 filesystem data.
    168169 */
    169 typedef struct RTFILESYSTEMFMTINT
    170 {
    171     /** Handle to the underlying medium. */
    172     RTFILESYSTEMMEDIUM        hMedium;
     170typedef struct RTFILESYSTEMEXT
     171{
     172    /** VFS file handle. */
     173    RTVFSFILE                 hVfsFile;
    173174    /** Block number of the superblock. */
    174175    uint32_t                  iSbBlock;
     
    180181    unsigned                  cBlockGroups;
    181182    /** Cached block group descriptor data. */
    182     PRTFILESYSTEMFMTEXTBLKGRP pBlkGrpDesc;
    183 } RTFILESYSTEMFMTINT;
     183    PRTFILESYSTEMEXTBLKGRP    pBlkGrpDesc;
     184} RTFILESYSTEMEXT;
    184185/** Pointer to the ext filesystem data. */
    185 typedef RTFILESYSTEMFMTINT *PRTFILESYSTEMFMTINT;
     186typedef RTFILESYSTEMEXT *PRTFILESYSTEMEXT;
    186187
    187188/*******************************************************************************
     
    196197 * @param   iBlkGrp  Block group number to load.
    197198 */
    198 static int rtFilesystemExtLoadBlkGrpDesc(PRTFILESYSTEMFMTINT pThis, uint32_t iBlkGrp)
     199static int rtFsExtLoadBlkGrpDesc(PRTFILESYSTEMEXT pThis, uint32_t iBlkGrp)
    199200{
    200201    int rc = VINF_SUCCESS;
    201     PRTFILESYSTEMFMTEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
     202    PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;
    202203    uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;
    203204    BlockGroupDesc BlkDesc;
     
    210211    if (!pBlkGrpDesc)
    211212    {
    212         size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEMFMTEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);
    213         pBlkGrpDesc = (PRTFILESYSTEMFMTEXTBLKGRP)RTMemAllocZ(cbBlkDesc);
     213        size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEMEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);
     214        pBlkGrpDesc = (PRTFILESYSTEMEXTBLKGRP)RTMemAllocZ(cbBlkDesc);
    214215        if (!pBlkGrpDesc)
    215216            return VERR_NO_MEMORY;
    216217    }
    217218
    218     rc = rtFilesystemMediumRead(pThis->hMedium, offRead, &BlkDesc, sizeof(BlkDesc));
     219    rc = RTVfsFileReadAt(pThis->hVfsFile, offRead, &BlkDesc, sizeof(BlkDesc), NULL);
    219220    if (RT_SUCCESS(rc))
    220221    {
    221222        pBlkGrpDesc->offStart = pThis->iSbBlock + (uint64_t)iBlkGrp * pThis->cBlocksPerGroup * pThis->cbBlock;
    222223        pBlkGrpDesc->offLast  = pBlkGrpDesc->offStart + pThis->cBlocksPerGroup * pThis->cbBlock;
    223         rc = rtFilesystemMediumRead(pThis->hMedium, BlkDesc.offBlockBitmap * pThis->cbBlock,
    224                                     &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap);
     224        rc = RTVfsFileReadAt(pThis->hVfsFile, BlkDesc.offBlockBitmap * pThis->cbBlock,
     225                             &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap, NULL);
    225226    }
    226227
     
    230231}
    231232
    232 static DECLCALLBACK(int) rtFilesystemExtProbe(RTFILESYSTEMMEDIUM hMedium, uint32_t *puScore)
     233static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc,
     234                                     uint32_t offBlockStart, uint32_t cBlocks)
     235{
     236    bool fUsed = false;
     237
     238    while (cBlocks)
     239    {
     240        uint32_t idxByte = offBlockStart / 8;
     241        uint32_t iBit = offBlockStart % 8;
     242
     243        if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit))
     244        {
     245            fUsed = true;
     246            break;
     247        }
     248
     249        cBlocks--;
     250        offBlockStart++;
     251    }
     252
     253    return fUsed;
     254}
     255
     256
     257static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)
    233258{
    234259    int rc = VINF_SUCCESS;
    235     uint64_t cbMedium = rtFilesystemMediumGetSize(hMedium);
     260    uint64_t cbMedium = 0;
    236261
    237262    *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;
    238263
    239     if (cbMedium >= 2*sizeof(ExtSuperBlock))
    240     {
    241         ExtSuperBlock SuperBlock;
    242 
    243         rc = rtFilesystemMediumRead(hMedium, 1024, &SuperBlock, sizeof(ExtSuperBlock));
    244         if (RT_SUCCESS(rc))
     264    rc = RTVfsFileGetSize(hVfsFile, &cbMedium);
     265    if (RT_SUCCESS(rc))
     266    {
     267        if (cbMedium >= 2*sizeof(ExtSuperBlock))
    245268        {
     269            ExtSuperBlock SuperBlock;
     270
     271            rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
     272            if (RT_SUCCESS(rc))
     273            {
    246274#if defined(RT_BIGENDIAN)
    247             /** @todo: Convert to host endianess. */
     275                /** @todo: Convert to host endianess. */
    248276#endif
    249             if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)
    250                 *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;
     277                if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)
     278                    *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;
     279            }
    251280        }
    252281    }
     
    255284}
    256285
    257 static DECLCALLBACK(int) rtFilesystemExtOpen(RTFILESYSTEMMEDIUM hMedium, PRTFILESYSTEMFMT phFsFmt)
     286static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)
    258287{
    259288    int rc = VINF_SUCCESS;
    260     PRTFILESYSTEMFMTINT pThis;
     289    PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    261290    ExtSuperBlock SuperBlock;
    262291
    263     pThis = (PRTFILESYSTEMFMTINT)RTMemAllocZ(sizeof(RTFILESYSTEMFMTINT));
    264     if (!pThis)
    265         return VERR_NO_MEMORY;
    266 
    267     pThis->hMedium     = hMedium;
     292    pThis->hVfsFile    = hVfsFile;
    268293    pThis->pBlkGrpDesc = NULL;
    269294
    270     rc = rtFilesystemMediumRead(hMedium, 1024, &SuperBlock, sizeof(ExtSuperBlock));
     295    rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);
    271296    if (RT_SUCCESS(rc))
    272297    {
     
    284309
    285310            /* Load first block group descriptor. */
    286             rc = rtFilesystemExtLoadBlkGrpDesc(pThis, 0);
     311            rc = rtFsExtLoadBlkGrpDesc(pThis, 0);
    287312        }
    288313    }
    289314
    290     if (RT_SUCCESS(rc))
    291         *phFsFmt = pThis;
    292     else
    293     {
    294         if (pThis->pBlkGrpDesc)
    295             RTMemFree(pThis->pBlkGrpDesc);
    296         RTMemFree(pThis);
    297     }
    298 
    299315    return rc;
    300316}
    301317
    302 static DECLCALLBACK(int) rtFilesystemExtClose(RTFILESYSTEMFMT hFsFmt)
    303 {
    304     PRTFILESYSTEMFMTINT pThis = hFsFmt;
     318static DECLCALLBACK(void) rtFsExtDestroy(void *pvThis)
     319{
     320    PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
    305321
    306322    if (pThis->pBlkGrpDesc)
    307323        RTMemFree(pThis->pBlkGrpDesc);
    308     RTMemFree(pThis);
    309 
    310     return VINF_SUCCESS;
    311 }
    312 
    313 static DECLCALLBACK(uint64_t) rtFilesystemExtGetBlockSize(RTFILESYSTEMFMT hFsFmt)
    314 {
    315     PRTFILESYSTEMFMTINT pThis = hFsFmt;
    316 
    317     return pThis->cbBlock;
    318 }
    319 
    320 static bool rtFilesystemExtIsBlockRangeInUse(PRTFILESYSTEMFMTEXTBLKGRP pBlkGrpDesc,
    321                                              uint32_t offBlockStart,
    322                                              uint32_t cBlocks)
    323 {
    324     bool fUsed = false;
    325 
    326     while (cBlocks)
    327     {
    328         uint32_t idxByte = offBlockStart / 8;
    329         uint32_t iBit = offBlockStart % 8;
    330 
    331         if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit))
    332         {
    333             fUsed = true;
    334             break;
    335         }
    336 
    337         cBlocks--;
    338         offBlockStart++;
    339     }
    340 
    341     return fUsed;
    342 }
    343 
    344 static DECLCALLBACK(int) rtFilesystemExtQueryRangeUse(RTFILESYSTEMFMT hFsFmt, uint64_t offStart,
    345                                                       size_t cb, bool *pfUsed)
     324}
     325
     326static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
     327{
     328    return VERR_NOT_IMPLEMENTED;
     329}
     330
     331static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb,
     332                                             bool *pfUsed)
    346333{
    347334    int rc = VINF_SUCCESS;
    348     PRTFILESYSTEMFMTINT pThis = hFsFmt;
     335    uint64_t offStart = (uint64_t)off;
     336    PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;
     337
     338    *pfUsed = false;
    349339
    350340    while (cb > 0)
     
    360350        {
    361351            /* Load new block descriptor. */
    362             rc = rtFilesystemExtLoadBlkGrpDesc(pThis, iBlockGroup);
     352            rc = rtFsExtLoadBlkGrpDesc(pThis, iBlockGroup);
    363353            if (RT_FAILURE(rc))
    364354                break;
     
    366356
    367357        cbThis = RT_MIN(cb, pThis->pBlkGrpDesc->offLast - offStart + 1);
    368         fUsed = rtFilesystemExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart,
    369                                                  cbThis / pThis->cbBlock +
    370                                                  cbThis % pThis->cbBlock
    371                                                  ? 1
    372                                                  : 0);
     358        fUsed = rtFsExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart,
     359                                         cbThis / pThis->cbBlock +
     360                                         (cbThis % pThis->cbBlock ? 1 : 0));
    373361
    374362        if (fUsed)
     
    378366        }
    379367
    380         cb -= cbThis;
     368        cb       -= cbThis;
    381369        offStart += cbThis;
    382370    }
     
    385373}
    386374
    387 RTFILESYSTEMFMTOPS g_rtFilesystemFmtExt =
    388 {
    389     /* pcszFmt */
    390     "EXT",
    391     /* pfnProbe */
    392     rtFilesystemExtProbe,
    393     /* pfnOpen */
    394     rtFilesystemExtOpen,
    395     /* pfnClose */
    396     rtFilesystemExtClose,
    397     /* pfnGetBlockSize */
    398     rtFilesystemExtGetBlockSize,
    399     /* pfnQueryRangeUse */
    400     rtFilesystemExtQueryRangeUse
     375DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt =
     376{
     377    /** cbFs */
     378    sizeof(RTFILESYSTEMEXT),
     379    /** VfsOps */
     380    {
     381        /** uVersion. */
     382        RTVFSOPS_VERSION,
     383        /** fFeatures */
     384        0,
     385        /** pszName */
     386        "ExtVfsOps",
     387        /** pfnDestroy */
     388        rtFsExtDestroy,
     389        /** pfnOpenRoot */
     390        rtFsExtOpenRoot,
     391        /** pfnIsRangeInUse */
     392        rtFsExtIsRangeInUse,
     393        /** uEndMarker */
     394        RTVFSOPS_VERSION
     395    },
     396    /** pfnProbe */
     397    rtFsExtProbe,
     398    /** pfnInit */
     399    rtFsExtInit
    401400};
    402401
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r39083 r41549  
    15801580
    15811581/*
     1582 * F I L E S Y S T E M   R O O T
     1583 * F I L E S Y S T E M   R O O T
     1584 * F I L E S Y S T E M   R O O T
     1585 */
     1586
     1587
     1588RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
     1589                     PRTVFS phVfs, void **ppvInstance)
     1590{
     1591    /*
     1592     * Validate the input, be extra strict in strict builds.
     1593     */
     1594    AssertPtr(pVfsOps);
     1595    AssertReturn(pVfsOps->uVersion   == RTVFSOPS_VERSION, VERR_VERSION_MISMATCH);
     1596    AssertReturn(pVfsOps->uEndMarker == RTVFSOPS_VERSION, VERR_VERSION_MISMATCH);
     1597    Assert(cbInstance > 0);
     1598    AssertPtr(ppvInstance);
     1599    AssertPtr(phVfs);
     1600
     1601    /*
     1602     * Allocate the handle + instance data.
     1603     */
     1604    size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSINTERNAL), RTVFS_INST_ALIGNMENT)
     1605                        + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT);
     1606    RTVFSINTERNAL *pThis = (RTVFSINTERNAL *)RTMemAllocZ(cbThis);
     1607    if (!pThis)
     1608        return VERR_NO_MEMORY;
     1609
     1610    int rc = rtVfsObjInitNewObject(&pThis->Base, NULL, hVfs, hLock,
     1611                                   (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT));
     1612    if (RT_FAILURE(rc))
     1613    {
     1614        RTMemFree(pThis);
     1615        return rc;
     1616    }
     1617
     1618    pThis->uMagic = RTVFS_MAGIC;
     1619    pThis->pOps   = pVfsOps;
     1620
     1621    *phVfs       = pThis;
     1622    *ppvInstance = pThis->Base.pvThis;
     1623    return VINF_SUCCESS;
     1624}
     1625
     1626
     1627RTDECL(uint32_t)    RTVfsRetain(RTVFS hVfs)
     1628{
     1629    RTVFSINTERNAL *pThis = hVfs;
     1630    AssertPtrReturn(pThis, UINT32_MAX);
     1631    AssertReturn(pThis->uMagic == RTVFS_MAGIC, UINT32_MAX);
     1632    return rtVfsObjRetain(&pThis->Base);
     1633}
     1634
     1635
     1636RTDECL(uint32_t)    RTVfsRelease(RTVFS hVfs)
     1637{
     1638    RTVFSINTERNAL *pThis = hVfs;
     1639    if (pThis == NIL_RTVFS)
     1640        return 0;
     1641    AssertPtrReturn(pThis, UINT32_MAX);
     1642    AssertReturn(pThis->uMagic == RTVFS_MAGIC, UINT32_MAX);
     1643    return rtVfsObjRelease(&pThis->Base);
     1644}
     1645
     1646
     1647RTDECL(int)         RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb,
     1648                                      bool *pfUsed)
     1649{
     1650    RTVFSINTERNAL *pThis = hVfs;
     1651    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1652    AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE);
     1653
     1654    RTVfsLockAcquireWrite(pThis->Base.hLock);
     1655    int rc = pThis->pOps->pfnIsRangeInUse(pThis->Base.pvThis, off, cb, pfUsed);
     1656    RTVfsLockReleaseWrite(pThis->Base.hLock);
     1657
     1658    return rc;
     1659}
     1660
     1661
     1662/*
    15821663 *
    15831664 *  F I L E S Y S T E M   S T R E A M
     
    19862067
    19872068
     2069RTDECL(int) RTVfsIoStrmReadAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, void *pvBuf, size_t cbToRead,
     2070                              bool fBlocking, size_t *pcbRead)
     2071{
     2072    AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
     2073    if (pcbRead)
     2074        *pcbRead = 0;
     2075    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
     2076    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2077    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
     2078    AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER);
     2079    AssertReturn(pThis->fFlags & RTFILE_O_READ, VERR_ACCESS_DENIED);
     2080
     2081    RTSGSEG Seg = { pvBuf, cbToRead };
     2082    RTSGBUF SgBuf;
     2083    RTSgBufInit(&SgBuf, &Seg, 1);
     2084
     2085    RTVfsLockAcquireWrite(pThis->Base.hLock);
     2086    int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbRead);
     2087    RTVfsLockReleaseWrite(pThis->Base.hLock);
     2088    return rc;
     2089}
     2090
     2091
    19882092RTDECL(int) RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten)
    19892093{
     
    20032107    RTVfsLockAcquireWrite(pThis->Base.hLock);
    20042108    int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, &SgBuf, fBlocking, pcbWritten);
     2109    RTVfsLockReleaseWrite(pThis->Base.hLock);
     2110    return rc;
     2111}
     2112
     2113
     2114RTDECL(int) RTVfsIoStrmWriteAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, const void *pvBuf, size_t cbToWrite,
     2115                               bool fBlocking, size_t *pcbWritten)
     2116{
     2117    AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
     2118    if (pcbWritten)
     2119        *pcbWritten = 0;
     2120    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
     2121    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2122    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
     2123    AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER);
     2124    AssertReturn(pThis->fFlags & RTFILE_O_WRITE, VERR_ACCESS_DENIED);
     2125
     2126    RTSGSEG Seg = { (void *)pvBuf, cbToWrite };
     2127    RTSGBUF SgBuf;
     2128    RTSgBufInit(&SgBuf, &Seg, 1);
     2129
     2130    RTVfsLockAcquireWrite(pThis->Base.hLock);
     2131    int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbWritten);
    20052132    RTVfsLockReleaseWrite(pThis->Base.hLock);
    20062133    return rc;
     
    24202547
    24212548
    2422 /// @todo RTDECL(int) RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
    2423 /// @todo RTDECL(int) RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead);
     2549RTDECL(int)         RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
     2550{
     2551    AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
     2552    if (pcbWritten)
     2553        *pcbWritten = 0;
     2554    RTVFSFILEINTERNAL *pThis = hVfsFile;
     2555    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2556    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE);
     2557
     2558    int rc = RTVfsFileSeek(hVfsFile, off, RTFILE_SEEK_BEGIN, NULL);
     2559    if (RT_SUCCESS(rc))
     2560        rc = RTVfsIoStrmWriteAt(&pThis->Stream, off, pvBuf, cbToWrite, true /*fBlocking*/, pcbWritten);
     2561
     2562    return rc;
     2563}
     2564
     2565
     2566RTDECL(int)         RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     2567{
     2568    AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
     2569    if (pcbRead)
     2570        *pcbRead = 0;
     2571    RTVFSFILEINTERNAL *pThis = hVfsFile;
     2572    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2573    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE);
     2574
     2575    int rc = RTVfsFileSeek(hVfsFile, off, RTFILE_SEEK_BEGIN, NULL);
     2576    if (RT_SUCCESS(rc))
     2577        rc = RTVfsIoStrmReadAt(&pThis->Stream, off, pvBuf, cbToRead, true /*fBlocking*/, pcbRead);
     2578
     2579    return rc;
     2580}
    24242581
    24252582
     
    24752632    return rc;
    24762633}
     2634
     2635
     2636RTDECL(int) RTVfsFileGetSize(RTVFSFILE hVfsFile, uint64_t *pcbSize)
     2637{
     2638    RTVFSFILEINTERNAL *pThis = hVfsFile;
     2639    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2640    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE);
     2641    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
     2642
     2643    RTVfsLockAcquireWrite(pThis->Stream.Base.hLock);
     2644    int rc = pThis->pOps->pfnQuerySize(pThis->Stream.Base.pvThis, pcbSize);
     2645    RTVfsLockReleaseWrite(pThis->Stream.Base.hLock);
     2646
     2647    return rc;
     2648}
Note: See TracChangeset for help on using the changeset viewer.

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