Changeset 76641 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Jan 4, 2019 9:16:24 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127945
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/xfsvfs.cpp
r76616 r76641 5 5 6 6 /* 7 * Copyright (C) 2018 Oracle Corporation7 * Copyright (C) 2018-2019 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 99 99 { 100 100 /** AVL tree node, indexed by the inode number. */ 101 AVLU 32NODECORE Core;101 AVLU64NODECORE Core; 102 102 /** List node for the inode LRU list used for eviction. */ 103 103 RTLISTNODE NdLru; … … 108 108 /** Inode data. */ 109 109 RTFSOBJINFO ObjInfo; 110 /** @todo */ 110 /** Inode data fork format. */ 111 uint8_t enmFormat; 112 /** Inode flags. */ 113 uint16_t fFlags; 111 114 } RTFSXFSINODE; 112 115 /** Pointer to an in-memory inode. */ … … 185 188 uint32_t fXfsFlags; 186 189 190 /** Size of one sector. */ 191 size_t cbSector; 187 192 /** Size of one block. */ 188 193 size_t cbBlock; … … 191 196 /** Number of blocks per allocation group. */ 192 197 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; 193 210 194 211 /** @name Allocation group cache. … … 207 224 RTLISTANCHOR LstInodeLru; 208 225 /** Root of the cached inode tree. */ 209 AVLU 32TREE InodeRoot;226 AVLU64TREE InodeRoot; 210 227 /** Size of the cached inodes. */ 211 228 size_t cbInodes; … … 235 252 * 236 253 * @returns nothing. 254 * @param iAg The allocation group number for the given super block. 237 255 * @param pSb Pointer to the superblock. 238 256 */ 239 static void rtFsXfsSb_Log( PCXFSSUPERBLOCK pSb)257 static void rtFsXfsSb_Log(uint32_t iAg, PCXFSSUPERBLOCK pSb) 240 258 { 241 259 if (LogIs2Enabled()) 242 260 { 243 Log2(("XFS: Superblock :\n"));261 Log2(("XFS: Superblock %#RX32:\n", iAg)); 244 262 Log2(("XFS: u32Magic %#RX32\n", RT_BE2H_U32(pSb->u32Magic))); 245 263 Log2(("XFS: cbBlock %RU32\n", RT_BE2H_U32(pSb->cbBlock))); … … 312 330 313 331 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 */ 339 static 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 */ 378 static 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 315 402 /** 316 403 * Logs a XFS filesystem inode. … … 321 408 * @param pInode Pointer to the inode. 322 409 */ 323 static void rtFsXfsInode_Log(PRTFSXFSVOL pThis, XFSINO iInode, PCXFSINODE pInode) 324 { 410 static void rtFsXfsInode_Log(PRTFSXFSVOL pThis, XFSINO iInode, PCXFSINODECORE pInode) 411 { 412 RT_NOREF(pThis); 413 325 414 if (LogIs2Enabled()) 326 415 { 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 332 475 /** 333 476 * Logs a XFS filesystem directory entry. … … 371 514 { 372 515 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 */ 530 DECLINLINE(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; 373 539 } 374 540 … … 628 794 int rc = VINF_SUCCESS; 629 795 796 AssertReturn(iAg < pThis->cAgs, VERR_VFS_BOGUS_FORMAT); 797 630 798 /* Try to fetch the allocation group from the cache first. */ 631 799 PRTFSXFSAG pAg = (PRTFSXFSAG)RTAvlU32Get(&pThis->AgRoot, iAg); … … 636 804 if (RT_LIKELY(pAg)) 637 805 { 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); 643 809 if (RT_SUCCESS(rc)) 644 810 { 645 811 #ifdef LOG_ENABLED 646 rtFs ExtBlockGroup_Log(pThis, iBlockGroup, &BlockGroupDesc);812 rtFsXfsSb_Log(iAg, &Sb); 647 813 #endif 648 pBlockGroup->iBlockInodeTbl = RT_LE2H_U32(BlockGroupDesc.v32.offInodeTableLow)649 | ((pThis->cbBlkGrpDesc == sizeof(EXTBLOCKGROUPDESC64))650 ? (uint64_t)RT_LE2H_U32(BlockGroupDesc.v64.offInodeTableHigh) << 32651 : 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 }667 814 } 668 #endif669 815 } 670 816 else … … 750 896 { 751 897 /* Remove from the tree and free memory. */ 752 PAVLU 32NODECORE pCore = RTAvlU32Remove(&pThis->InodeRoot, pInode->Core.Key);898 PAVLU64NODECORE pCore = RTAvlU64Remove(&pThis->InodeRoot, pInode->Core.Key); 753 899 Assert(pCore == &pInode->Core); RT_NOREF(pCore); 754 900 RTMemFree(pInode); … … 765 911 * @param iInode Inode number. 766 912 */ 767 static PRTFSXFSINODE rtFsXfsInode_GetNew(PRTFSXFSVOL pThis, uint32_tiInode)913 static PRTFSXFSINODE rtFsXfsInode_GetNew(PRTFSXFSVOL pThis, XFSINO iInode) 768 914 { 769 915 PRTFSXFSINODE pInode = NULL; … … 778 924 { 779 925 /* Remove the block group from the tree because it gets a new key. */ 780 PAVLU 32NODECORE pCore = RTAvlU32Remove(&pThis->InodeRoot, pInode->Core.Key);926 PAVLU64NODECORE pCore = RTAvlU64Remove(&pThis->InodeRoot, pInode->Core.Key); 781 927 Assert(pCore == &pInode->Core); RT_NOREF(pCore); 782 928 } … … 799 945 * @param ppInode Where to store the inode on success. 800 946 */ 801 static int rtFsXfsInode_Load(PRTFSXFSVOL pThis, uint32_tiInode, PRTFSXFSINODE *ppInode)947 static int rtFsXfsInode_Load(PRTFSXFSVOL pThis, XFSINO iInode, PRTFSXFSINODE *ppInode) 802 948 { 803 949 int rc = VINF_SUCCESS; 804 950 805 951 /* Try to fetch the inode from the cache first. */ 806 PRTFSXFSINODE pInode = (PRTFSXFSINODE)RTAvlU 32Get(&pThis->InodeRoot, iInode);952 PRTFSXFSINODE pInode = (PRTFSXFSINODE)RTAvlU64Get(&pThis->InodeRoot, iInode); 807 953 if (!pInode) 808 954 { … … 811 957 if (RT_LIKELY(pInode)) 812 958 { 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); 817 968 if (RT_SUCCESS(rc)) 818 969 { 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) 829 995 { 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)); 913 998 } 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; 914 1055 } 915 #endif916 1056 } 917 1057 else … … 1135 1275 if (RT_SUCCESS(rc)) 1136 1276 pThis->offFile = off + cbRead; 1137 Log6(("rtFs ExtFile_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)); 1138 1278 } 1139 1279 else … … 1768 1908 1769 1909 1770 static DECLCALLBACK(int) rtFsXfsVolInodeTreeDestroy(PAVLU 32NODECORE pCore, void *pvUser)1910 static DECLCALLBACK(int) rtFsXfsVolInodeTreeDestroy(PAVLU64NODECORE pCore, void *pvUser) 1771 1911 { 1772 1912 RT_NOREF(pvUser); … … 1803 1943 1804 1944 /* Destroy the inode tree. */ 1805 RTAvlU 32Destroy(&pThis->InodeRoot, rtFsXfsVolInodeTreeDestroy, pThis);1945 RTAvlU64Destroy(&pThis->InodeRoot, rtFsXfsVolInodeTreeDestroy, pThis); 1806 1946 pThis->InodeRoot = NULL; 1807 1947 RTListInit(&pThis->LstInodeLru); … … 1839 1979 { 1840 1980 PRTFSXFSVOL pThis = (PRTFSXFSVOL)pvThis; 1841 int rc = rtFsXfsVol_OpenDirByInode(pThis, 0 /** @todo */, phVfsDir);1981 int rc = rtFsXfsVol_OpenDirByInode(pThis, pThis->uInodeRoot, phVfsDir); 1842 1982 LogFlowFunc(("returns %Rrc\n", rc)); 1843 1983 return rc; … … 1874 2014 1875 2015 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 */ 2023 static 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 1876 2040 1877 2041 /** … … 1895 2059 1896 2060 #ifdef LOG_ENABLED 1897 rtFsXfsSb_Log( &Sb);2061 rtFsXfsSb_Log(0, &Sb); 1898 2062 #endif 1899 2063 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; 1901 2075 return rc; 1902 2076 } … … 1913 2087 1914 2088 /* 1915 * Create a VFS instance and initialize the data so rtFs ExtVol_Close works.2089 * Create a VFS instance and initialize the data so rtFsXfsVol_Close works. 1916 2090 */ 1917 2091 RTVFS hVfs; … … 1939 2113 rc = rtFsXfsVolLoadAndParseSuperblock(pThis, pErrInfo); 1940 2114 if (RT_SUCCESS(rc)) 2115 rc = rtFsXfsVolLoadAgi(pThis, pErrInfo); 2116 if (RT_SUCCESS(rc)) 1941 2117 { 1942 2118 *phVfs = hVfs;
Note:
See TracChangeset
for help on using the changeset viewer.