Changeset 76641 in vbox
- Timestamp:
- Jan 4, 2019 9:16:24 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127945
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/formats/xfs.h
r76618 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 … … 387 387 388 388 389 /** 390 * XFS timestamp structure. 391 */ 392 typedef struct XFSTIMESTAMP 393 { 394 /** 0x00: The second part of the timestamp since the epoch. */ 395 int32_t cSecEpoch; 396 /** 0x04: Nanosecond part of the timestamp. */ 397 int32_t cNanoSec; 398 } XFSTIMESTAMP; 399 /** Pointer to a XFS timestamp. */ 400 typedef XFSTIMESTAMP *PXFSTIMESTAMP; 401 /** Poiner to a const CFS timestamp. */ 402 typedef const XFSTIMESTAMP *PCXFSTIMESTAMP; 403 404 405 /** 406 * The inode core structure. 407 */ 408 typedef struct XFSINODECORE 409 { 410 /** 0x00: Magic value. */ 411 uint16_t u16Magic; 412 /** 0x02: File mode and access bits (XFS_INODE_MODE_XXX). */ 413 uint16_t fMode; 414 /** 0x04: Inode version. */ 415 int8_t iVersion; 416 /** 0x05: The format of the data fork. */ 417 int8_t enmFormat; 418 /** 0x06: Number of links to this inode from directories for v1 inodes. */ 419 uint16_t cOnLinks; 420 /** 0x08: Owners UID. */ 421 uint32_t uUid; 422 /** 0x0c: Owners GID. */ 423 uint32_t uGid; 424 /** 0x10: The number of links to this inode for v2 inodes. */ 425 uint32_t cLinks; 426 /** 0x14: Project ID for v2 inodes (not used for v1, low 16bits). */ 427 uint16_t uProjIdLow; 428 /** 0x16: Project ID for v2 inodes (not used for v1, high 16bits). */ 429 uint16_t uProjIdHigh; 430 /** 0x18: Padding. */ 431 uint8_t abPad0[6]; 432 /** 0x1e: Flush counter. */ 433 uint16_t cFlush; 434 /** 0x20: Last accessed timestamp. */ 435 XFSTIMESTAMP TsLastAccessed; 436 /** 0x28: Last modified timestamp. */ 437 XFSTIMESTAMP TsLastModified; 438 /** 0x30: Inode created/modified timestamp. */ 439 XFSTIMESTAMP TsCreatedModified; 440 /** 0x38: Number of bytes in the file. */ 441 uint64_t cbInode; 442 /** 0x40: Number of direct and B-Tree blocks used for the forks. */ 443 uint64_t cBlocks; 444 /** 0x48: Minimum exten size for the inode. */ 445 uint32_t cExtentBlocksMin; 446 /** 0x4c: Number of extents in the data fork. */ 447 uint32_t cExtentsData; 448 /** 0x50: Number of extents in the attribute fork. */ 449 uint16_t cExtentsAttr; 450 /** 0x52: Offset of the attribute fork from the start of the inode. */ 451 uint8_t offAttrFork; 452 /** 0x53: Attribute fork format. */ 453 int8_t enmFormatAttr; 454 /** 0x54: DMIG event mask. */ 455 uint32_t fEvtMaskDmig; 456 /** 0x58: DMIG state info. */ 457 uint16_t uStateDmig; 458 /** 0x5a: Inode flags. */ 459 uint16_t fFlags; 460 /** 0x5c: Generation number. */ 461 uint32_t cGeneration; 462 /** 0x60: AGI unlinked list pointer. */ 463 uint32_t offBlockUnlinkedNext; 464 /** The following fields are for v3 inodes only. */ 465 /** 0x64: The CRC of the inode. */ 466 uint32_t uChkSum; 467 /** 0x68: Number of attribute changes. */ 468 uint64_t cAttrChanges; 469 /** 0x70: Last flush sequence number. */ 470 uint64_t uFlushSeqNo; 471 /** 0x78: Additional flags. */ 472 uint64_t fFlags2; 473 /** 0x80: Basic COW extent size. */ 474 uint32_t cExtentCowMin; 475 /** 0x84: Padding for future expansion. */ 476 uint8_t abPad1[12]; 477 /** 0x90: Inode creation timestamp. */ 478 XFSTIMESTAMP TsCreation; 479 /** 0x98: The inode number. */ 480 uint64_t uInode; 481 /** 0x100: Filesystem UUID the inode belongs to. */ 482 uint8_t abUuid[16]; 483 } XFSINODECORE; 484 AssertCompileSizeAlignment(XFSINODECORE, 8); 485 /** Pointer to a inode core. */ 486 typedef XFSINODECORE *PXFSINODECORE; 487 /** Pointer to a const inode core. */ 488 typedef const XFSINODECORE *PCXFSINODECORE; 489 490 /** Inode magic. */ 491 #define XFS_INODE_MAGIC RT_MAKE_U16_FROM_U8('N', 'I') 492 493 /** @name XFS_INODE_MODE_XXX - File mode 494 * @{ */ 495 /** Others can execute the file. */ 496 #define XFS_INODE_MODE_EXEC_OTHER RT_BIT(0) 497 /** Others can write to the file. */ 498 #define XFS_INODE_MODE_WRITE_OTHER RT_BIT(1) 499 /** Others can read the file. */ 500 #define XFS_INODE_MODE_READ_OTHER RT_BIT(2) 501 /** Members of the same group can execute the file. */ 502 #define XFS_INODE_MODE_EXEC_GROUP RT_BIT(3) 503 /** Members of the same group can write to the file. */ 504 #define XFS_INODE_MODE_WRITE_GROUP RT_BIT(4) 505 /** Members of the same group can read the file. */ 506 #define XFS_INODE_MODE_READ_GROUP RT_BIT(5) 507 /** Owner can execute the file. */ 508 #define XFS_INODE_MODE_EXEC_OWNER RT_BIT(6) 509 /** Owner can write to the file. */ 510 #define XFS_INODE_MODE_WRITE_OWNER RT_BIT(7) 511 /** Owner can read the file. */ 512 #define XFS_INODE_MODE_READ_OWNER RT_BIT(8) 513 /** Sticky file mode. */ 514 #define XFS_INODE_MODE_STICKY RT_BIT(9) 515 /** File is set GID. */ 516 #define XFS_INODE_MODE_SET_GROUP_ID RT_BIT(10) 517 /** File is set UID. */ 518 #define XFS_INODE_MODE_SET_USER_ID RT_BIT(11) 519 /** @} */ 520 521 /** @name XFS_INODE_MODE_TYPE_XXX - File type 522 * @{ */ 523 /** Inode represents a FIFO. */ 524 #define XFS_INODE_MODE_TYPE_FIFO UINT16_C(0x1000) 525 /** Inode represents a character device. */ 526 #define XFS_INODE_MODE_TYPE_CHAR UINT16_C(0x2000) 527 /** Inode represents a directory. */ 528 #define XFS_INODE_MODE_TYPE_DIR UINT16_C(0x4000) 529 /** Inode represents a block device. */ 530 #define XFS_INODE_MODE_TYPE_BLOCK UINT16_C(0x6000) 531 /** Inode represents a regular file. */ 532 #define XFS_INODE_MODE_TYPE_REGULAR UINT16_C(0x8000) 533 /** Inode represents a symlink. */ 534 #define XFS_INODE_MODE_TYPE_SYMLINK UINT16_C(0xa000) 535 /** Inode represents a socket. */ 536 #define XFS_INODE_MODE_TYPE_SOCKET UINT16_C(0xc000) 537 /** Returns the inode type from the combined mode field. */ 538 #define XFS_INODE_MODE_TYPE_GET_TYPE(a_Mode) ((a_Mode) & 0xf000) 539 /** @} */ 540 541 /** @name XFS_INODE_FORMAT_XXX - Inode data fork format. 542 * @{ */ 543 /** Device node data. */ 544 #define XFS_INODE_FORMAT_DEV 0 545 /** Inline data. */ 546 #define XFS_INODE_FORMAT_LOCAL 1 547 /** Array of extent descriptors. */ 548 #define XFS_INODE_FORMAT_EXTENTS 2 549 /** Data fork contains root of B-Tree. */ 550 #define XFS_INODE_FORMAT_BTREE 3 551 /** Data fork contains UUID. */ 552 #define XFS_INODE_FORMAT_UUID 4 553 /** @} */ 554 555 /** @name XFS_INODE_F_XXX - Inode flags. 556 * @{ */ 557 /** File data blocks are stored in the real-time device area. */ 558 #define XFS_INODE_F_RTDEV RT_BIT(0) 559 /** File space has been pre-allocated. */ 560 #define XFS_INODE_F_PREALLOC RT_BIT(1) 561 /** Use new real-time bitmap format. */ 562 #define XFS_INODE_F_NEWRTBITMAP RT_BIT(2) 563 /** Inode is immutable. */ 564 #define XFS_INODE_F_IMMUTABLE RT_BIT(3) 565 /** Inode is append only.. */ 566 #define XFS_INODE_F_APPEND RT_BIT(4) 567 /** Inode is written synchronously. */ 568 #define XFS_INODE_F_SYNC RT_BIT(5) 569 /** The last accessed timestamp is not updated. */ 570 #define XFS_INODE_F_NOATIME RT_BIT(6) 571 /** The inode is not dumpable via dump(1). */ 572 #define XFS_INODE_F_NODUMP RT_BIT(7) 573 /** Create with real-time bit set. */ 574 #define XFS_INODE_F_RTINHERIT RT_BIT(8) 575 /** Create with parents project ID. */ 576 #define XFS_INODE_F_PROJIDINHERIT RT_BIT(9) 577 /** Deny symlink creation. */ 578 #define XFS_INODE_F_NOSYMLINKS RT_BIT(10) 579 /** Inode extent size allocator hint. */ 580 #define XFS_INODE_F_EXTSIZEHINT RT_BIT(11) 581 /** Inode extent size is inherited. */ 582 #define XFS_INODE_F_EXTSIZEINHERIT RT_BIT(12) 583 /** Do not defrag/reorganize the inode. */ 584 #define XFS_INODE_F_NODEFRAG RT_BIT(13) 585 /** Use filestream allocator. */ 586 #define XFS_INODE_F_FILESTREAM RT_BIT(14) 587 /** @} */ 588 589 /** @name XFS_INODE_F2_XXX - Inode flags number 2 (XFSINODECORE::fFlags2). 590 * @{ */ 591 /** Use DAX for the inode. */ 592 #define XFS_INODE_F2_DAX RT_BIT_64(0) 593 /** Blocks use reference counting for sharing. */ 594 #define XFS_INODE_F2_REFLINK RT_BIT_64(1) 595 /** Inode COW extent size hint is valid. */ 596 #define XFS_INODE_F2_COWEXTSIZEHINT RT_BIT_64(2) 597 /** @} */ 598 599 600 /** 601 * Inode B-Tree record. 602 */ 603 typedef struct XFSINODEBTREEREC 604 { 605 /** 0x00: Starting inode number. */ 606 uint32_t uInodeStart; 607 /** 0x04: Version dependent data. */ 608 union 609 { 610 /** Full (old) version. */ 611 struct 612 { 613 /** 0x04: Number of free inodes. */ 614 uint32_t cInodesFree; 615 } Full; 616 /** Sparse (new) version. */ 617 struct 618 { 619 /** 0x04: Hole mask for sparse chunks. */ 620 uint16_t bmHoles; 621 /** 0x06: Total number of inodes. */ 622 uint8_t cInodes; 623 /** 0x07: Number of free inodes. */ 624 uint8_t cInodesFree; 625 } Sparse; 626 } u; 627 /** 0x08: Free inode mask. */ 628 uint64_t bmInodesFree; 629 } XFSINODEBTREEREC; 630 /** Pointer to an inode B-Tree record. */ 631 typedef XFSINODEBTREEREC *PXFSINODEBTREEREC; 632 /** Pointer to a const inode B-Tree record. */ 633 typedef const XFSINODEBTREEREC *PCXFSINODEBTREEREC; 634 635 389 636 /** @} */ 390 637 -
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.