VirtualBox

Changeset 76641 in vbox for trunk/src/VBox/Runtime/common/fs


Ignore:
Timestamp:
Jan 4, 2019 9:16:24 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
127945
Message:

Runtime/fs/xfsvfs: Updates, working on inode parsing

File:
1 edited

Legend:

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

    r76616 r76641  
    55
    66/*
    7  * Copyright (C) 2018 Oracle Corporation
     7 * Copyright (C) 2018-2019 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    9999{
    100100    /** AVL tree node, indexed by the inode number. */
    101     AVLU32NODECORE    Core;
     101    AVLU64NODECORE    Core;
    102102    /** List node for the inode LRU list used for eviction. */
    103103    RTLISTNODE        NdLru;
     
    108108    /** Inode data. */
    109109    RTFSOBJINFO       ObjInfo;
    110     /** @todo */
     110    /** Inode data fork format. */
     111    uint8_t           enmFormat;
     112    /** Inode flags. */
     113    uint16_t          fFlags;
    111114} RTFSXFSINODE;
    112115/** Pointer to an in-memory inode. */
     
    185188    uint32_t            fXfsFlags;
    186189
     190    /** Size of one sector. */
     191    size_t              cbSector;
    187192    /** Size of one block. */
    188193    size_t              cbBlock;
     
    191196    /** Number of blocks per allocation group. */
    192197    XFSAGNUMBER         cBlocksPerAg;
     198    /** Number of blocks per allocation group as log2. */
     199    uint32_t            cAgBlocksLog;
     200    /** Number of allocation groups for this volume. */
     201    uint32_t            cAgs;
     202    /** inode of the root directory. */
     203    XFSINO              uInodeRoot;
     204    /** Inode size in bytes. */
     205    size_t              cbInode;
     206    /** Number of inodes per block. */
     207    uint32_t            cInodesPerBlock;
     208    /** Number of inodes per block as log2. */
     209    uint32_t            cInodesPerBlockLog;
    193210
    194211    /** @name Allocation group cache.
     
    207224    RTLISTANCHOR        LstInodeLru;
    208225    /** Root of the cached inode tree. */
    209     AVLU32TREE          InodeRoot;
     226    AVLU64TREE          InodeRoot;
    210227    /** Size of the cached inodes. */
    211228    size_t              cbInodes;
     
    235252 *
    236253 * @returns nothing.
     254 * @param   iAg                 The allocation group number for the given super block.
    237255 * @param   pSb                 Pointer to the superblock.
    238256 */
    239 static void rtFsXfsSb_Log(PCXFSSUPERBLOCK pSb)
     257static void rtFsXfsSb_Log(uint32_t iAg, PCXFSSUPERBLOCK pSb)
    240258{
    241259    if (LogIs2Enabled())
    242260    {
    243         Log2(("XFS: Superblock:\n"));
     261        Log2(("XFS: Superblock %#RX32:\n", iAg));
    244262        Log2(("XFS:   u32Magic                    %#RX32\n", RT_BE2H_U32(pSb->u32Magic)));
    245263        Log2(("XFS:   cbBlock                     %RU32\n", RT_BE2H_U32(pSb->cbBlock)));
     
    312330
    313331
    314 #if 0
     332/**
     333 * Logs a AG free space block.
     334 *
     335 * @returns nothing.
     336 * @param   iAg                 The allocation group number for the given free space block.
     337 * @param   pAgf                The AG free space block.
     338 */
     339static void rtFsXfsAgf_Log(uint32_t iAg, PCXFSAGF pAgf)
     340{
     341    if (LogIs2Enabled())
     342    {
     343        Log2(("XFS: AGF %#RX32:\n", iAg));
     344        Log2(("XFS:   u32Magic                    %#RX32\n", RT_BE2H_U32(pAgf->u32Magic)));
     345        Log2(("XFS:   uVersion                    %#RX32\n", RT_BE2H_U32(pAgf->uVersion)));
     346        Log2(("XFS:   uSeqNo                      %#RX32\n", RT_BE2H_U32(pAgf->uSeqNo)));
     347        Log2(("XFS:   cLengthBlocks               %#RX32\n", RT_BE2H_U32(pAgf->cLengthBlocks)));
     348        Log2(("XFS:   auRoots[0]                  %#RX32\n", RT_BE2H_U32(pAgf->auRoots[0])));
     349        Log2(("XFS:   auRoots[1]                  %#RX32\n", RT_BE2H_U32(pAgf->auRoots[1])));
     350        Log2(("XFS:   auRoots[2]                  %#RX32\n", RT_BE2H_U32(pAgf->auRoots[2])));
     351        Log2(("XFS:   acLvls[0]                   %RU32\n", RT_BE2H_U32(pAgf->acLvls[0])));
     352        Log2(("XFS:   acLvls[1]                   %RU32\n", RT_BE2H_U32(pAgf->acLvls[1])));
     353        Log2(("XFS:   acLvls[2]                   %RU32\n", RT_BE2H_U32(pAgf->acLvls[2])));
     354        Log2(("XFS:   idxFreeListFirst            %RU32\n", RT_BE2H_U32(pAgf->idxFreeListFirst)));
     355        Log2(("XFS:   idxFreeListLast             %RU32\n", RT_BE2H_U32(pAgf->idxFreeListLast)));
     356        Log2(("XFS:   cFreeListBlocks             %RU32\n", RT_BE2H_U32(pAgf->cFreeListBlocks)));
     357        Log2(("XFS:   cFreeBlocks                 %RU32\n", RT_BE2H_U32(pAgf->cFreeBlocks)));
     358        Log2(("XFS:   cFreeBlocksLongest          %RU32\n", RT_BE2H_U32(pAgf->cFreeBlocksLongest)));
     359        Log2(("XFS:   cBlocksBTrees               %RU32\n", RT_BE2H_U32(pAgf->cBlocksBTrees)));
     360        Log2(("XFS:   abUuid                      <todo>\n"));
     361        Log2(("XFS:   cBlocksRevMap               %RU32\n", RT_BE2H_U32(pAgf->cBlocksRevMap)));
     362        Log2(("XFS:   cBlocksRefcountBTree        %RU32\n", RT_BE2H_U32(pAgf->cBlocksRefcountBTree)));
     363        Log2(("XFS:   uRootRefcount               %#RX32\n", RT_BE2H_U32(pAgf->uRootRefcount)));
     364        Log2(("XFS:   cLvlRefcount                %RU32\n", RT_BE2H_U32(pAgf->cLvlRefcount)));
     365        Log2(("XFS:   uSeqNoLastWrite             %#RX64\n", RT_BE2H_U64(pAgf->uSeqNoLastWrite)));
     366        Log2(("XFS:   uChkSum                     %#RX32\n", RT_BE2H_U32(pAgf->uChkSum)));
     367    }
     368}
     369
     370
     371/**
     372 * Loads an AG inode information block.
     373 *
     374 * @returns nothing.
     375 * @param   iAg                 The allocation group number for the given inode information block.
     376 * @param   pAgi                The AG inode information block.
     377 */
     378static void rtFsXfsAgi_Log(uint32_t iAg, PCXFSAGI pAgi)
     379{
     380    if (LogIs2Enabled())
     381    {
     382        Log2(("XFS: AGI %#RX32:\n", iAg));
     383        Log2(("XFS:   u32Magic                    %#RX32\n", RT_BE2H_U32(pAgi->u32Magic)));
     384        Log2(("XFS:   uVersion                    %#RX32\n", RT_BE2H_U32(pAgi->uVersion)));
     385        Log2(("XFS:   uSeqNo                      %#RX32\n", RT_BE2H_U32(pAgi->uSeqNo)));
     386        Log2(("XFS:   cLengthBlocks               %#RX32\n", RT_BE2H_U32(pAgi->cLengthBlocks)));
     387        Log2(("XFS:   cInodesAlloc                %#RX32\n", RT_BE2H_U32(pAgi->cInodesAlloc)));
     388        Log2(("XFS:   uRootInode                  %#RX32\n", RT_BE2H_U32(pAgi->uRootInode)));
     389        Log2(("XFS:   cLvlsInode                  %RU32\n", RT_BE2H_U32(pAgi->cLvlsInode)));
     390        Log2(("XFS:   uInodeNew                   %#RX32\n", RT_BE2H_U32(pAgi->uInodeNew)));
     391        Log2(("XFS:   uInodeDir                   %#RX32\n", RT_BE2H_U32(pAgi->uInodeDir)));
     392        Log2(("XFS:   au32HashUnlinked[0..63]     <todo>\n"));
     393        Log2(("XFS:   abUuid                      <todo>\n"));
     394        Log2(("XFS:   uChkSum                     %#RX32\n", RT_BE2H_U32(pAgi->uChkSum)));
     395        Log2(("XFS:   uSeqNoLastWrite             %#RX64\n", RT_BE2H_U64(pAgi->uSeqNoLastWrite)));
     396        Log2(("XFS:   uRootFreeInode              %#RX32\n", RT_BE2H_U32(pAgi->uRootFreeInode)));
     397        Log2(("XFS:   cLvlsFreeInode              %RU32\n", RT_BE2H_U32(pAgi->cLvlsFreeInode)));
     398    }
     399}
     400
     401
    315402/**
    316403 * Logs a XFS filesystem inode.
     
    321408 * @param   pInode              Pointer to the inode.
    322409 */
    323 static void rtFsXfsInode_Log(PRTFSXFSVOL pThis, XFSINO iInode, PCXFSINODE pInode)
    324 {
     410static void rtFsXfsInode_Log(PRTFSXFSVOL pThis, XFSINO iInode, PCXFSINODECORE pInode)
     411{
     412    RT_NOREF(pThis);
     413
    325414    if (LogIs2Enabled())
    326415    {
    327 
    328     }
    329 }
    330 
    331 
     416        RTTIMESPEC Spec;
     417        char       sz[80];
     418
     419        Log2(("XFS: Inode %#RX64:\n", iInode));
     420        Log2(("XFS:   u16Magic                    %#RX16\n", RT_BE2H_U16(pInode->u16Magic)));
     421        Log2(("XFS:   fMode                       %#RX16\n", RT_BE2H_U16(pInode->fMode)));
     422        Log2(("XFS:   iVersion                    %#RX8\n", pInode->iVersion));
     423        Log2(("XFS:   enmFormat                   %#RX8\n", pInode->enmFormat));
     424        Log2(("XFS:   cOnLinks                    %RU16\n", RT_BE2H_U16(pInode->cOnLinks)));
     425        Log2(("XFS:   uUid                        %#RX32\n", RT_BE2H_U32(pInode->uUid)));
     426        Log2(("XFS:   uGid                        %#RX32\n", RT_BE2H_U32(pInode->uGid)));
     427        Log2(("XFS:   cLinks                      %#RX32\n", RT_BE2H_U32(pInode->cLinks)));
     428        Log2(("XFS:   uProjIdLow                  %#RX16\n", RT_BE2H_U16(pInode->uProjIdLow)));
     429        Log2(("XFS:   uProjIdHigh                 %#RX16\n", RT_BE2H_U16(pInode->uProjIdHigh)));
     430        Log2(("XFS:   cFlush                      %RU16\n", RT_BE2H_U16(pInode->cFlush)));
     431        Log2(("XFS:   TsLastAccessed              %#RX32:%#RX32 %s\n", RT_BE2H_U32(pInode->TsLastAccessed.cSecEpoch),
     432              RT_BE2H_U32(pInode->TsLastAccessed.cNanoSec),
     433              RTTimeSpecToString(RTTimeSpecAddNano(RTTimeSpecSetSeconds(&Spec, RT_BE2H_U32(pInode->TsLastAccessed.cSecEpoch)),
     434                                                   RT_BE2H_U32(pInode->TsLastAccessed.cNanoSec)),
     435                                 sz, sizeof(sz))));
     436        Log2(("XFS:   TsLastModified              %#RX32:%#RX32 %s\n", RT_BE2H_U32(pInode->TsLastModified.cSecEpoch),
     437              RT_BE2H_U32(pInode->TsLastModified.cNanoSec),
     438              RTTimeSpecToString(RTTimeSpecAddNano(RTTimeSpecSetSeconds(&Spec, RT_BE2H_U32(pInode->TsLastModified.cSecEpoch)),
     439                                                   RT_BE2H_U32(pInode->TsLastModified.cNanoSec)),
     440                                 sz, sizeof(sz))));
     441        Log2(("XFS:   TsCreatedModified           %#RX32:%#RX32 %s\n", RT_BE2H_U32(pInode->TsCreatedModified.cSecEpoch),
     442              RT_BE2H_U32(pInode->TsCreatedModified.cNanoSec),
     443              RTTimeSpecToString(RTTimeSpecAddNano(RTTimeSpecSetSeconds(&Spec, RT_BE2H_U32(pInode->TsCreatedModified.cSecEpoch)),
     444                                                   RT_BE2H_U32(pInode->TsCreatedModified.cNanoSec)),
     445                                 sz, sizeof(sz))));
     446        Log2(("XFS:   cbInode                     %#RX64\n", RT_BE2H_U64(pInode->cbInode)));
     447        Log2(("XFS:   cBlocks                     %#RX64\n", RT_BE2H_U64(pInode->cBlocks)));
     448        Log2(("XFS:   cExtentBlocksMin            %#RX32\n", RT_BE2H_U32(pInode->cExtentBlocksMin)));
     449        Log2(("XFS:   cExtentsData                %#RX32\n", RT_BE2H_U32(pInode->cExtentsData)));
     450        Log2(("XFS:   cExtentsAttr                %#RX16\n", RT_BE2H_U16(pInode->cExtentsAttr)));
     451        Log2(("XFS:   offAttrFork                 %#RX8\n", pInode->offAttrFork));
     452        Log2(("XFS:   enmFormatAttr               %#RX8\n", pInode->enmFormatAttr));
     453        Log2(("XFS:   fEvtMaskDmig                %#RX32\n", RT_BE2H_U32(pInode->fEvtMaskDmig)));
     454        Log2(("XFS:   uStateDmig                  %#RX16\n", RT_BE2H_U16(pInode->uStateDmig)));
     455        Log2(("XFS:   fFlags                      %#RX16\n", RT_BE2H_U16(pInode->fFlags)));
     456        Log2(("XFS:   cGeneration                 %#RX32\n", RT_BE2H_U32(pInode->cGeneration)));
     457        Log2(("XFS:   offBlockUnlinkedNext        %#RX32\n", RT_BE2H_U32(pInode->offBlockUnlinkedNext)));
     458        Log2(("XFS:   uChkSum                     %#RX32\n", RT_BE2H_U32(pInode->uChkSum)));
     459        Log2(("XFS:   cAttrChanges                %#RX64\n", RT_BE2H_U64(pInode->cAttrChanges)));
     460        Log2(("XFS:   uFlushSeqNo                 %#RX64\n", RT_BE2H_U64(pInode->uFlushSeqNo)));
     461        Log2(("XFS:   fFlags2                     %#RX64\n", RT_BE2H_U64(pInode->fFlags2)));
     462        Log2(("XFS:   cExtentCowMin               %#RX32\n", RT_BE2H_U32(pInode->cExtentCowMin)));
     463        Log2(("XFS:   TsCreation                  %#RX32:%#RX32 %s\n", RT_BE2H_U32(pInode->TsCreation.cSecEpoch),
     464              RT_BE2H_U32(pInode->TsCreation.cNanoSec),
     465              RTTimeSpecToString(RTTimeSpecAddNano(RTTimeSpecSetSeconds(&Spec, RT_BE2H_U32(pInode->TsCreation.cSecEpoch)),
     466                                                   RT_BE2H_U32(pInode->TsCreation.cNanoSec)),
     467                                 sz, sizeof(sz))));
     468        Log2(("XFS:   uInode                      %#RX64\n", RT_BE2H_U64(pInode->uInode)));
     469        Log2(("XFS:   abUuid                      <todo>\n"));
     470    }
     471}
     472
     473
     474#if 0
    332475/**
    333476 * Logs a XFS filesystem directory entry.
     
    371514{
    372515    return off >> pThis->cBlockShift;
     516}
     517
     518
     519/**
     520 * Splits the given absolute inode number into the AG number, block inside the AG
     521 * and the offset into the block where to find the inode structure.
     522 *
     523 * @returns nothing.
     524 * @param   pThis               The XFS volume instance.
     525 * @param   iInode              The inode to split.
     526 * @param   piAg                Where to store the AG number.
     527 * @param   puBlock             Where to store the block number inside the AG.
     528 * @param   poffBlock           Where to store the offset into the block.
     529 */
     530DECLINLINE(void) rtFsXfsInodeSplitAbs(PRTFSXFSVOL pThis, XFSINO iInode,
     531                                      uint32_t *piAg, uint32_t *puBlock,
     532                                      uint32_t *poffBlock)
     533{
     534    *poffBlock = iInode & (pThis->cInodesPerBlock - 1);
     535    iInode >>= pThis->cInodesPerBlockLog;
     536    *puBlock = iInode & (RT_BIT_32(pThis->cAgBlocksLog) - 1); /* Using the log2 value here as it is rounded. */
     537    iInode >>= RT_BIT_32(pThis->cAgBlocksLog) - 1;
     538    *piAg = (uint32_t)iInode;
    373539}
    374540
     
    628794    int rc = VINF_SUCCESS;
    629795
     796    AssertReturn(iAg < pThis->cAgs, VERR_VFS_BOGUS_FORMAT);
     797
    630798    /* Try to fetch the allocation group from the cache first. */
    631799    PRTFSXFSAG pAg = (PRTFSXFSAG)RTAvlU32Get(&pThis->AgRoot, iAg);
     
    636804        if (RT_LIKELY(pAg))
    637805        {
    638 #if 0 /** @todo */
    639             uint64_t          offRead =   rtFsExtBlockIdxToDiskOffset(pThis, pThis->cbBlock == _1K ? 2 : 1)
    640                                         + (uint64_t)iBlockGroup * pThis->cbBlkGrpDesc;
    641             EXTBLOCKGROUPDESC BlockGroupDesc;
    642             rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &BlockGroupDesc, pThis->cbBlkGrpDesc, NULL);
     806            uint64_t offRead = rtFsXfsBlockIdxToDiskOffset(pThis, iAg * pThis->cBlocksPerAg);
     807            XFSSUPERBLOCK Sb;
     808            rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &Sb, sizeof(Sb), NULL);
    643809            if (RT_SUCCESS(rc))
    644810            {
    645811#ifdef LOG_ENABLED
    646                 rtFsExtBlockGroup_Log(pThis, iBlockGroup, &BlockGroupDesc);
     812                rtFsXfsSb_Log(iAg, &Sb);
    647813#endif
    648                 pBlockGroup->iBlockInodeTbl =   RT_LE2H_U32(BlockGroupDesc.v32.offInodeTableLow)
    649                                               | ((pThis->cbBlkGrpDesc == sizeof(EXTBLOCKGROUPDESC64))
    650                                               ? (uint64_t)RT_LE2H_U32(BlockGroupDesc.v64.offInodeTableHigh) << 32
    651                                               : 0);
    652 
    653                 offRead = rtFsExtBlockIdxLowHighToDiskOffset(pThis, RT_LE2H_U32(BlockGroupDesc.v32.offBlockBitmapLow),
    654                                                              RT_LE2H_U32(BlockGroupDesc.v64.offBlockBitmapHigh));
    655                 rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &pBlockGroup->abBlockBitmap[0], pThis->cbBlockBitmap, NULL);
    656                 if (RT_SUCCESS(rc))
    657                 {
    658                     offRead = rtFsExtBlockIdxLowHighToDiskOffset(pThis, RT_LE2H_U32(BlockGroupDesc.v32.offInodeBitmapLow),
    659                                                                  RT_LE2H_U32(BlockGroupDesc.v64.offInodeBitmapHigh));
    660                     rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &pBlockGroup->pabInodeBitmap[0], pThis->cbInodeBitmap, NULL);
    661                     if (RT_SUCCESS(rc))
    662                     {
    663                         bool fIns = RTAvlU32Insert(&pThis->BlockGroupRoot, &pBlockGroup->Core);
    664                         Assert(fIns); RT_NOREF(fIns);
    665                     }
    666                 }
    667814            }
    668 #endif
    669815        }
    670816        else
     
    750896    {
    751897        /* Remove from the tree and free memory. */
    752         PAVLU32NODECORE pCore = RTAvlU32Remove(&pThis->InodeRoot, pInode->Core.Key);
     898        PAVLU64NODECORE pCore = RTAvlU64Remove(&pThis->InodeRoot, pInode->Core.Key);
    753899        Assert(pCore == &pInode->Core); RT_NOREF(pCore);
    754900        RTMemFree(pInode);
     
    765911 * @param   iInode              Inode number.
    766912 */
    767 static PRTFSXFSINODE rtFsXfsInode_GetNew(PRTFSXFSVOL pThis, uint32_t iInode)
     913static PRTFSXFSINODE rtFsXfsInode_GetNew(PRTFSXFSVOL pThis, XFSINO iInode)
    768914{
    769915    PRTFSXFSINODE pInode = NULL;
     
    778924        {
    779925            /* Remove the block group from the tree because it gets a new key. */
    780             PAVLU32NODECORE pCore = RTAvlU32Remove(&pThis->InodeRoot, pInode->Core.Key);
     926            PAVLU64NODECORE pCore = RTAvlU64Remove(&pThis->InodeRoot, pInode->Core.Key);
    781927            Assert(pCore == &pInode->Core); RT_NOREF(pCore);
    782928        }
     
    799945 * @param   ppInode             Where to store the inode on success.
    800946 */
    801 static int rtFsXfsInode_Load(PRTFSXFSVOL pThis, uint32_t iInode, PRTFSXFSINODE *ppInode)
     947static int rtFsXfsInode_Load(PRTFSXFSVOL pThis, XFSINO iInode, PRTFSXFSINODE *ppInode)
    802948{
    803949    int rc = VINF_SUCCESS;
    804950
    805951    /* Try to fetch the inode from the cache first. */
    806     PRTFSXFSINODE pInode = (PRTFSXFSINODE)RTAvlU32Get(&pThis->InodeRoot, iInode);
     952    PRTFSXFSINODE pInode = (PRTFSXFSINODE)RTAvlU64Get(&pThis->InodeRoot, iInode);
    807953    if (!pInode)
    808954    {
     
    811957        if (RT_LIKELY(pInode))
    812958        {
    813 #if 0 /** @todo */
    814             /* Calculate the block group and load that one first to get at the inode table location. */
    815             PRTFSEXTBLKGRP pBlockGroup = NULL;
    816             rc = rtFsEBlockGroupLoad(pThis, (iInode - 1) / pThis->cInodesPerGroup, &pBlockGroup);
     959            uint32_t iAg;
     960            uint32_t uBlock;
     961            uint32_t offBlock;
     962
     963            rtFsXfsInodeSplitAbs(pThis, iInode, &iAg, &uBlock, &offBlock);
     964
     965            uint64_t offRead = (iAg * pThis->cBlocksPerAg + uBlock) * pThis->cbBlock + offBlock;
     966            XFSINODECORE Inode;
     967            rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &Inode, RT_MIN(sizeof(Inode), pThis->cbInode), NULL);
    817968            if (RT_SUCCESS(rc))
    818969            {
    819                 uint32_t idxInodeInTbl = (iInode - 1) % pThis->cInodesPerGroup;
    820                 uint64_t offRead =   rtFsExtBlockIdxToDiskOffset(pThis, pBlockGroup->iBlockInodeTbl)
    821                                    + idxInodeInTbl * pThis->cbInode;
    822 
    823                 /* Release block group here already as it is not required. */
    824                 rtFsExtBlockGroupRelease(pThis, pBlockGroup);
    825 
    826                 EXTINODECOMB Inode;
    827                 rc = RTVfsFileReadAt(pThis->hVfsBacking, offRead, &Inode, RT_MIN(sizeof(Inode), pThis->cbInode), NULL);
    828                 if (RT_SUCCESS(rc))
     970#ifdef LOG_ENABLED
     971                rtFsXfsInode_Log(pThis, iInode, &Inode);
     972#endif
     973
     974                pInode->offInode            = offRead;
     975                pInode->fFlags              = RT_BE2H_U16(Inode.fFlags);
     976                pInode->enmFormat           = Inode.enmFormat;
     977                pInode->ObjInfo.cbObject    = RT_BE2H_U64(Inode.cbInode);
     978                pInode->ObjInfo.cbAllocated = RT_BE2H_U64(Inode.cBlocks) * pThis->cbBlock;
     979                RTTimeSpecSetSeconds(&pInode->ObjInfo.AccessTime, RT_BE2H_U32(Inode.TsLastAccessed.cSecEpoch));
     980                RTTimeSpecAddNano(&pInode->ObjInfo.AccessTime, RT_BE2H_U32(Inode.TsLastAccessed.cNanoSec));
     981                RTTimeSpecSetSeconds(&pInode->ObjInfo.ModificationTime, RT_BE2H_U32(Inode.TsLastModified.cSecEpoch));
     982                RTTimeSpecAddNano(&pInode->ObjInfo.ModificationTime, RT_BE2H_U32(Inode.TsLastModified.cNanoSec));
     983                RTTimeSpecSetSeconds(&pInode->ObjInfo.ChangeTime, RT_BE2H_U32(Inode.TsCreatedModified.cSecEpoch));
     984                RTTimeSpecAddNano(&pInode->ObjInfo.ChangeTime, RT_BE2H_U32(Inode.TsCreatedModified.cNanoSec));
     985                pInode->ObjInfo.Attr.enmAdditional = RTFSOBJATTRADD_UNIX;
     986                pInode->ObjInfo.Attr.u.Unix.uid    = RT_BE2H_U32(Inode.uUid);
     987                pInode->ObjInfo.Attr.u.Unix.gid    = RT_BE2H_U32(Inode.uGid);
     988                pInode->ObjInfo.Attr.u.Unix.cHardlinks = RT_BE2H_U16(Inode.cOnLinks); /** @todo: v2 inodes. */
     989                pInode->ObjInfo.Attr.u.Unix.INodeIdDevice = 0;
     990                pInode->ObjInfo.Attr.u.Unix.INodeId       = iInode;
     991                pInode->ObjInfo.Attr.u.Unix.fFlags        = 0;
     992                pInode->ObjInfo.Attr.u.Unix.GenerationId  = RT_BE2H_U32(Inode.cGeneration);
     993                pInode->ObjInfo.Attr.u.Unix.Device        = 0;
     994                if (Inode.iVersion >= 3)
    829995                {
    830 #ifdef LOG_ENABLED
    831                     rtFsExtInode_Log(pThis, iInode, &Inode);
    832 #endif
    833                     pInode->offInode            = offRead;
    834                     pInode->fFlags              = RT_LE2H_U32(Inode.Core.fFlags);
    835                     pInode->ObjInfo.cbObject    =   (uint64_t)RT_LE2H_U32(Inode.Core.cbSizeHigh) << 32
    836                                                   | (uint64_t)RT_LE2H_U32(Inode.Core.cbSizeLow);
    837                     pInode->ObjInfo.cbAllocated = (  (uint64_t)RT_LE2H_U16(Inode.Core.Osd2.Lnx.cBlocksHigh) << 32
    838                                                    | (uint64_t)RT_LE2H_U32(Inode.Core.cBlocksLow)) * pThis->cbBlock;
    839                     RTTimeSpecSetSeconds(&pInode->ObjInfo.AccessTime, RT_LE2H_U32(Inode.Core.u32TimeLastAccess));
    840                     RTTimeSpecSetSeconds(&pInode->ObjInfo.ModificationTime, RT_LE2H_U32(Inode.Core.u32TimeLastModification));
    841                     RTTimeSpecSetSeconds(&pInode->ObjInfo.ChangeTime, RT_LE2H_U32(Inode.Core.u32TimeLastChange));
    842                     pInode->ObjInfo.Attr.enmAdditional = RTFSOBJATTRADD_UNIX;
    843                     pInode->ObjInfo.Attr.u.Unix.uid    =   (uint32_t)RT_LE2H_U16(Inode.Core.Osd2.Lnx.uUidHigh) << 16
    844                                                          | (uint32_t)RT_LE2H_U16(Inode.Core.uUidLow);
    845                     pInode->ObjInfo.Attr.u.Unix.gid    =   (uint32_t)RT_LE2H_U16(Inode.Core.Osd2.Lnx.uGidHigh) << 16
    846                                                          | (uint32_t)RT_LE2H_U16(Inode.Core.uGidLow);
    847                     pInode->ObjInfo.Attr.u.Unix.cHardlinks = RT_LE2H_U16(Inode.Core.cHardLinks);
    848                     pInode->ObjInfo.Attr.u.Unix.INodeIdDevice = 0;
    849                     pInode->ObjInfo.Attr.u.Unix.INodeId       = iInode;
    850                     pInode->ObjInfo.Attr.u.Unix.fFlags        = 0;
    851                     pInode->ObjInfo.Attr.u.Unix.GenerationId  = RT_LE2H_U32(Inode.Core.u32Version);
    852                     pInode->ObjInfo.Attr.u.Unix.Device        = 0;
    853                     if (pThis->cbInode >= sizeof(EXTINODECOMB))
    854                         RTTimeSpecSetSeconds(&pInode->ObjInfo.BirthTime, RT_LE2H_U32(Inode.Extra.u32TimeCreation));
    855                     else
    856                         RTTimeSpecSetSeconds(&pInode->ObjInfo.BirthTime, RT_LE2H_U32(Inode.Core.u32TimeLastChange));
    857                     for (unsigned i = 0; i < RT_ELEMENTS(pInode->aiBlocks); i++)
    858                         pInode->aiBlocks[i] = RT_LE2H_U32(Inode.Core.au32Block[i]);
    859 
    860                     /* Fill in the mode. */
    861                     pInode->ObjInfo.Attr.fMode = 0;
    862                     uint32_t fInodeMode = RT_LE2H_U32(Inode.Core.fMode);
    863                     switch (EXT_INODE_MODE_TYPE_GET_TYPE(fInodeMode))
    864                     {
    865                         case EXT_INODE_MODE_TYPE_FIFO:
    866                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_FIFO;
    867                             break;
    868                         case EXT_INODE_MODE_TYPE_CHAR:
    869                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DEV_CHAR;
    870                             break;
    871                         case EXT_INODE_MODE_TYPE_DIR:
    872                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DIRECTORY;
    873                             break;
    874                         case EXT_INODE_MODE_TYPE_BLOCK:
    875                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DEV_BLOCK;
    876                             break;
    877                         case EXT_INODE_MODE_TYPE_REGULAR:
    878                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_FILE;
    879                             break;
    880                         case EXT_INODE_MODE_TYPE_SYMLINK:
    881                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_SYMLINK;
    882                             break;
    883                         case EXT_INODE_MODE_TYPE_SOCKET:
    884                             pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_SOCKET;
    885                             break;
    886                         default:
    887                             rc = VERR_VFS_BOGUS_FORMAT;
    888                     }
    889                     if (fInodeMode & EXT_INODE_MODE_EXEC_OTHER)
    890                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXOTH;
    891                     if (fInodeMode & EXT_INODE_MODE_WRITE_OTHER)
    892                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWOTH;
    893                     if (fInodeMode & EXT_INODE_MODE_READ_OTHER)
    894                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IROTH;
    895                     if (fInodeMode & EXT_INODE_MODE_EXEC_GROUP)
    896                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXGRP;
    897                     if (fInodeMode & EXT_INODE_MODE_WRITE_GROUP)
    898                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWGRP;
    899                     if (fInodeMode & EXT_INODE_MODE_READ_GROUP)
    900                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IRGRP;
    901                     if (fInodeMode & EXT_INODE_MODE_EXEC_OWNER)
    902                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXUSR;
    903                     if (fInodeMode & EXT_INODE_MODE_WRITE_OWNER)
    904                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWUSR;
    905                     if (fInodeMode & EXT_INODE_MODE_READ_OWNER)
    906                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IRUSR;
    907                     if (fInodeMode & EXT_INODE_MODE_STICKY)
    908                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISTXT;
    909                     if (fInodeMode & EXT_INODE_MODE_SET_GROUP_ID)
    910                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISGID;
    911                     if (fInodeMode & EXT_INODE_MODE_SET_USER_ID)
    912                         pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISUID;
     996                    RTTimeSpecSetSeconds(&pInode->ObjInfo.BirthTime, RT_BE2H_U32(Inode.TsCreation.cSecEpoch));
     997                    RTTimeSpecAddNano(&pInode->ObjInfo.BirthTime, RT_BE2H_U32(Inode.TsCreation.cNanoSec));
    913998                }
     999                else
     1000                    pInode->ObjInfo.BirthTime = pInode->ObjInfo.ChangeTime;
     1001
     1002                /* Fill in the mode. */
     1003                pInode->ObjInfo.Attr.fMode = 0;
     1004                uint16_t fInodeMode = RT_BE2H_U16(Inode.fMode);
     1005                switch (XFS_INODE_MODE_TYPE_GET_TYPE(fInodeMode))
     1006                {
     1007                    case XFS_INODE_MODE_TYPE_FIFO:
     1008                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_FIFO;
     1009                        break;
     1010                    case XFS_INODE_MODE_TYPE_CHAR:
     1011                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DEV_CHAR;
     1012                        break;
     1013                    case XFS_INODE_MODE_TYPE_DIR:
     1014                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DIRECTORY;
     1015                        break;
     1016                    case XFS_INODE_MODE_TYPE_BLOCK:
     1017                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_DEV_BLOCK;
     1018                        break;
     1019                    case XFS_INODE_MODE_TYPE_REGULAR:
     1020                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_FILE;
     1021                        break;
     1022                    case XFS_INODE_MODE_TYPE_SYMLINK:
     1023                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_SYMLINK;
     1024                        break;
     1025                    case XFS_INODE_MODE_TYPE_SOCKET:
     1026                        pInode->ObjInfo.Attr.fMode |= RTFS_TYPE_SOCKET;
     1027                        break;
     1028                    default:
     1029                        rc = VERR_VFS_BOGUS_FORMAT;
     1030                }
     1031                if (fInodeMode & XFS_INODE_MODE_EXEC_OTHER)
     1032                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXOTH;
     1033                if (fInodeMode & XFS_INODE_MODE_WRITE_OTHER)
     1034                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWOTH;
     1035                if (fInodeMode & XFS_INODE_MODE_READ_OTHER)
     1036                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IROTH;
     1037                if (fInodeMode & XFS_INODE_MODE_EXEC_GROUP)
     1038                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXGRP;
     1039                if (fInodeMode & XFS_INODE_MODE_WRITE_GROUP)
     1040                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWGRP;
     1041                if (fInodeMode & XFS_INODE_MODE_READ_GROUP)
     1042                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IRGRP;
     1043                if (fInodeMode & XFS_INODE_MODE_EXEC_OWNER)
     1044                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IXUSR;
     1045                if (fInodeMode & XFS_INODE_MODE_WRITE_OWNER)
     1046                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IWUSR;
     1047                if (fInodeMode & XFS_INODE_MODE_READ_OWNER)
     1048                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_IRUSR;
     1049                if (fInodeMode & XFS_INODE_MODE_STICKY)
     1050                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISTXT;
     1051                if (fInodeMode & XFS_INODE_MODE_SET_GROUP_ID)
     1052                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISGID;
     1053                if (fInodeMode & XFS_INODE_MODE_SET_USER_ID)
     1054                    pInode->ObjInfo.Attr.fMode |= RTFS_UNIX_ISUID;
    9141055            }
    915 #endif
    9161056        }
    9171057        else
     
    11351275        if (RT_SUCCESS(rc))
    11361276            pThis->offFile = off + cbRead;
    1137         Log6(("rtFsExtFile_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc));
     1277        Log6(("rtFsXfsFile_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc));
    11381278    }
    11391279    else
     
    17681908
    17691909
    1770 static DECLCALLBACK(int) rtFsXfsVolInodeTreeDestroy(PAVLU32NODECORE pCore, void *pvUser)
     1910static DECLCALLBACK(int) rtFsXfsVolInodeTreeDestroy(PAVLU64NODECORE pCore, void *pvUser)
    17711911{
    17721912    RT_NOREF(pvUser);
     
    18031943
    18041944    /* Destroy the inode tree. */
    1805     RTAvlU32Destroy(&pThis->InodeRoot, rtFsXfsVolInodeTreeDestroy, pThis);
     1945    RTAvlU64Destroy(&pThis->InodeRoot, rtFsXfsVolInodeTreeDestroy, pThis);
    18061946    pThis->InodeRoot = NULL;
    18071947    RTListInit(&pThis->LstInodeLru);
     
    18391979{
    18401980    PRTFSXFSVOL pThis = (PRTFSXFSVOL)pvThis;
    1841     int rc = rtFsXfsVol_OpenDirByInode(pThis, 0 /** @todo */, phVfsDir);
     1981    int rc = rtFsXfsVol_OpenDirByInode(pThis, pThis->uInodeRoot, phVfsDir);
    18421982    LogFlowFunc(("returns %Rrc\n", rc));
    18431983    return rc;
     
    18742014
    18752015
     2016/**
     2017 * Loads and parses the AGI block.
     2018 *
     2019 * @returns IPRT status code.
     2020 * @param   pThis               The XFS volume instance.
     2021 * @param   pErrInfo            Where to return additional error info.
     2022 */
     2023static int rtFsXfsVolLoadAgi(PRTFSXFSVOL pThis, PRTERRINFO pErrInfo)
     2024{
     2025    XFSAGI Agi;
     2026    int rc = RTVfsFileReadAt(pThis->hVfsBacking, 2 * pThis->cbSector, &Agi, sizeof(&Agi), NULL);
     2027    if (RT_SUCCESS(rc))
     2028    {
     2029#ifdef LOG_ENABLED
     2030        rtFsXfsAgi_Log(0, &Agi);
     2031#endif
     2032
     2033        /** @todo: Verification */
     2034        RT_NOREF(pErrInfo);
     2035    }
     2036
     2037    return rc;
     2038}
     2039
    18762040
    18772041/**
     
    18952059
    18962060#ifdef LOG_ENABLED
    1897     rtFsXfsSb_Log(&Sb);
     2061    rtFsXfsSb_Log(0, &Sb);
    18982062#endif
    18992063
    1900     /** @todo */
     2064    /** @todo: More verification */
     2065    pThis->cbSector           = RT_BE2H_U32(Sb.cbSector);
     2066    pThis->cbBlock            = RT_BE2H_U32(Sb.cbBlock);
     2067    pThis->cBlockShift        = Sb.cBlockSzLog;
     2068    pThis->cBlocksPerAg       = RT_BE2H_U32(Sb.cAgBlocks);
     2069    pThis->cAgs               = RT_BE2H_U32(Sb.cAg);
     2070    pThis->uInodeRoot         = RT_BE2H_U64(Sb.uInodeRoot);
     2071    pThis->cbInode            = RT_BE2H_U16(Sb.cbInode);
     2072    pThis->cInodesPerBlock    = RT_BE2H_U16(Sb.cInodesPerBlock);
     2073    pThis->cAgBlocksLog       = Sb.cAgBlocksLog;
     2074    pThis->cInodesPerBlockLog = Sb.cInodesPerBlockLog;
    19012075    return rc;
    19022076}
     
    19132087
    19142088    /*
    1915      * Create a VFS instance and initialize the data so rtFsExtVol_Close works.
     2089     * Create a VFS instance and initialize the data so rtFsXfsVol_Close works.
    19162090     */
    19172091    RTVFS       hVfs;
     
    19392113            rc = rtFsXfsVolLoadAndParseSuperblock(pThis, pErrInfo);
    19402114            if (RT_SUCCESS(rc))
     2115                rc = rtFsXfsVolLoadAgi(pThis, pErrInfo);
     2116            if (RT_SUCCESS(rc))
    19412117            {
    19422118                *phVfs = hVfs;
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