Changeset 69840 in vbox
- Timestamp:
- Nov 27, 2017 3:19:30 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119281
- Location:
- trunk
- Files:
-
- 1 added
- 3 deleted
- 9 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/formats/ext2.h
r69803 r69840 25 25 */ 26 26 27 #ifndef ___iprt_formats_ext2_h 28 #define ___iprt_formats_ext2_h 27 29 28 /*********************************************************************************************************************************29 * Header Files *30 *********************************************************************************************************************************/31 #define LOG_GROUP LOG_GROUP_DEFAULT32 30 #include <iprt/types.h> 33 #include <iprt/assert.h> 34 #include <iprt/mem.h> 35 #include <iprt/filesystem.h> 36 #include <iprt/string.h> 37 #include <iprt/vfs.h> 38 #include "internal/filesystem.h" 31 #include <iprt/assertcompile.h> 39 32 40 41 /*********************************************************************************************************************************42 * Structures and Typedefs *43 *********************************************************************************************************************************/44 33 45 34 /* … … 49 38 50 39 /** 51 * Ext superblock.40 * Ext2 superblock. 52 41 * 53 42 * Everything is stored little endian on the disk. 54 43 */ 55 #pragma pack(1) 56 typedef struct ExtSuperBlock 44 typedef struct EXT2SUPERBLOCK 57 45 { 58 46 /** Total number of inodes in the filesystem. */ … … 86 74 /** Number of mounts allowed before a consistency check. */ 87 75 uint16_t cMaxMountsUntilCheck; 88 /** Signature to identify a ext2 volume . */76 /** Signature to identify a ext2 volume (EXT2_SIGNATURE). */ 89 77 uint16_t u16Signature; 90 78 /** State of the filesystem (clean/errors) */ … … 108 96 /** Reserved fields. */ 109 97 uint8_t abReserved[940]; 110 } ExtSuperBlock; 111 #pragma pack() 112 AssertCompileSize(ExtSuperBlock, 1024); 113 /** Pointer to an ext super block. */ 114 typedef ExtSuperBlock *PExtSuperBlock; 98 } EXT2SUPERBLOCK; 99 AssertCompileSize(EXT2SUPERBLOCK, 1024); 100 /** Pointer to an ext2 super block. */ 101 typedef EXT2SUPERBLOCK *PEXT2SUPERBLOCK; 102 /** Pointer to a const ext2 super block. */ 103 typedef EXT2SUPERBLOCK const *PCEXT2SUPERBLOCK; 115 104 116 105 /** Ext2 signature. */ 117 #define RTFILESYSTEM_EXT2_SIGNATURE(0xef53)106 #define EXT2_SIGNATURE UINT16_C(0xef53) 118 107 /** Clean filesystem state. */ 119 #define RTFILESYSTEM_EXT2_STATE_CLEAN(0x0001)108 #define EXT2_STATE_CLEAN UINT16_C(0x0001) 120 109 /** Error filesystem state. */ 121 #define RTFILESYSTEM_EXT2_STATE_ERRORS(0x0002)110 #define EXT2_STATE_ERRORS UINT16_C(0x0002) 122 111 123 112 /** 124 113 * Block group descriptor. 125 114 */ 126 #pragma pack(1) 127 typedef struct BlockGroupDesc 115 typedef struct EXT2BLOCKGROUPDESC 128 116 { 129 117 /** Block address of the block bitmap. */ … … 143 131 /** Reserved. */ 144 132 uint8_t abReserved[12]; 145 } BlockGroupDesc; 146 #pragma pack() 147 AssertCompileSize(BlockGroupDesc, 32); 133 } EXT2BLOCKGROUPDESC; 134 AssertCompileSize(EXT2BLOCKGROUPDESC, 32); 148 135 /** Pointer to an ext block group descriptor. */ 149 typedef BlockGroupDesc *PBlockGroupDesc;136 typedef EXT2BLOCKGROUPDESC *PEXT2BLOCKGROUPDESC; 150 137 151 /** 152 * Cached block group descriptor data. 153 */ 154 typedef struct RTFILESYSTEMEXTBLKGRP 155 { 156 /** Start offset (in bytes and from the start of the disk). */ 157 uint64_t offStart; 158 /** Last offset in the block group (inclusive). */ 159 uint64_t offLast; 160 /** Block bitmap - variable in size (depends on the block size 161 * and number of blocks per group). */ 162 uint8_t abBlockBitmap[1]; 163 } RTFILESYSTEMEXTBLKGRP; 164 /** Pointer to block group descriptor data. */ 165 typedef RTFILESYSTEMEXTBLKGRP *PRTFILESYSTEMEXTBLKGRP; 138 #endif 166 139 167 /**168 * Ext2/3 filesystem data.169 */170 typedef struct RTFILESYSTEMEXT171 {172 /** VFS file handle. */173 RTVFSFILE hVfsFile;174 /** Block number of the superblock. */175 uint32_t iSbBlock;176 /** Size of one block. */177 size_t cbBlock;178 /** Number of blocks in one group. */179 unsigned cBlocksPerGroup;180 /** Number of blocks groups in the volume. */181 unsigned cBlockGroups;182 /** Cached block group descriptor data. */183 PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc;184 } RTFILESYSTEMEXT;185 /** Pointer to the ext filesystem data. */186 typedef RTFILESYSTEMEXT *PRTFILESYSTEMEXT;187 188 189 /*********************************************************************************************************************************190 * Methods *191 *********************************************************************************************************************************/192 193 /**194 * Loads the block descriptor of the given block group from the medium.195 *196 * @returns IPRT status code.197 * @param pThis EXT filesystem instance data.198 * @param iBlkGrp Block group number to load.199 */200 static int rtFsExtLoadBlkGrpDesc(PRTFILESYSTEMEXT pThis, uint32_t iBlkGrp)201 {202 int rc = VINF_SUCCESS;203 PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;204 uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock;205 BlockGroupDesc BlkDesc;206 size_t cbBlockBitmap;207 208 cbBlockBitmap = pThis->cBlocksPerGroup / 8;209 if (pThis->cBlocksPerGroup % 8)210 cbBlockBitmap++;211 212 if (!pBlkGrpDesc)213 {214 size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEMEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);215 pBlkGrpDesc = (PRTFILESYSTEMEXTBLKGRP)RTMemAllocZ(cbBlkDesc);216 if (!pBlkGrpDesc)217 return VERR_NO_MEMORY;218 }219 220 rc = RTVfsFileReadAt(pThis->hVfsFile, offRead, &BlkDesc, sizeof(BlkDesc), NULL);221 if (RT_SUCCESS(rc))222 {223 pBlkGrpDesc->offStart = pThis->iSbBlock + (uint64_t)iBlkGrp * pThis->cBlocksPerGroup * pThis->cbBlock;224 pBlkGrpDesc->offLast = pBlkGrpDesc->offStart + pThis->cBlocksPerGroup * pThis->cbBlock;225 rc = RTVfsFileReadAt(pThis->hVfsFile, BlkDesc.offBlockBitmap * pThis->cbBlock,226 &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap, NULL);227 }228 229 pThis->pBlkGrpDesc = pBlkGrpDesc;230 231 return rc;232 }233 234 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc,235 uint32_t offBlockStart, size_t cBlocks)236 {237 bool fUsed = false;238 239 while (cBlocks)240 {241 uint32_t idxByte = offBlockStart / 8;242 uint32_t iBit = offBlockStart % 8;243 244 if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit))245 {246 fUsed = true;247 break;248 }249 250 cBlocks--;251 offBlockStart++;252 }253 254 return fUsed;255 }256 257 258 static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)259 {260 int rc = VINF_SUCCESS;261 uint64_t cbMedium = 0;262 263 *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;264 265 rc = RTVfsFileGetSize(hVfsFile, &cbMedium);266 if (RT_SUCCESS(rc))267 {268 if (cbMedium >= 2*sizeof(ExtSuperBlock))269 {270 ExtSuperBlock SuperBlock;271 272 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);273 if (RT_SUCCESS(rc))274 {275 #if defined(RT_BIGENDIAN)276 /** @todo Convert to host endianess. */277 #endif278 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)279 *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;280 }281 }282 }283 284 return rc;285 }286 287 static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)288 {289 int rc = VINF_SUCCESS;290 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;291 ExtSuperBlock SuperBlock;292 293 pThis->hVfsFile = hVfsFile;294 pThis->pBlkGrpDesc = NULL;295 296 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);297 if (RT_SUCCESS(rc))298 {299 #if defined(RT_BIGENDIAN)300 /** @todo Convert to host endianess. */301 #endif302 if (SuperBlock.u16FilesystemState == RTFILESYSTEM_EXT2_STATE_ERRORS)303 rc = VERR_FILESYSTEM_CORRUPT;304 else305 {306 pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;307 pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;308 pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;309 pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;310 311 /* Load first block group descriptor. */312 rc = rtFsExtLoadBlkGrpDesc(pThis, 0);313 }314 }315 316 return rc;317 }318 319 320 /**321 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}322 */323 static DECLCALLBACK(int) rtFsExtVol_Close(void *pvThis)324 {325 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;326 327 if (pThis->pBlkGrpDesc)328 RTMemFree(pThis->pBlkGrpDesc);329 330 return VINF_SUCCESS;331 }332 333 334 /**335 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}336 */337 static DECLCALLBACK(int) rtFsExtVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)338 {339 RT_NOREF(pvThis, pObjInfo, enmAddAttr);340 return VERR_WRONG_TYPE;341 }342 343 344 static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir)345 {346 NOREF(pvThis);347 NOREF(phVfsDir);348 return VERR_NOT_IMPLEMENTED;349 }350 351 static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb,352 bool *pfUsed)353 {354 int rc = VINF_SUCCESS;355 uint64_t offStart = (uint64_t)off;356 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;357 358 *pfUsed = false;359 360 while (cb > 0)361 {362 bool fUsed;363 uint32_t offBlockStart = (uint32_t)(offStart / pThis->cbBlock);364 uint32_t iBlockGroup = (offBlockStart - pThis->iSbBlock) / pThis->cBlocksPerGroup;365 uint32_t offBlockRelStart = offBlockStart - iBlockGroup * pThis->cBlocksPerGroup;366 size_t cbThis = 0;367 368 if ( offStart < pThis->pBlkGrpDesc->offStart369 || offStart > pThis->pBlkGrpDesc->offLast)370 {371 /* Load new block descriptor. */372 rc = rtFsExtLoadBlkGrpDesc(pThis, iBlockGroup);373 if (RT_FAILURE(rc))374 break;375 }376 377 cbThis = RT_MIN(cb, pThis->pBlkGrpDesc->offLast - offStart + 1);378 fUsed = rtFsExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart,379 cbThis / pThis->cbBlock +380 (cbThis % pThis->cbBlock ? 1 : 0));381 382 if (fUsed)383 {384 *pfUsed = true;385 break;386 }387 388 cb -= cbThis;389 offStart += cbThis;390 }391 392 return rc;393 }394 395 396 DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt =397 {398 /* .cbFs = */ sizeof(RTFILESYSTEMEXT),399 /* .VfsOps = */400 {401 /* .Obj = */402 {403 /* .uVersion = */ RTVFSOBJOPS_VERSION,404 /* .enmType = */ RTVFSOBJTYPE_VFS,405 /* .pszName = */ "ExtVol",406 /* .pfnClose = */ rtFsExtVol_Close,407 /* .pfnQueryInfo = */ rtFsExtVol_QueryInfo,408 /* .uEndMarker = */ RTVFSOBJOPS_VERSION409 },410 /* .uVersion = */ RTVFSOPS_VERSION,411 /* .fFeatures = */ 0,412 /* .pfnOpenRoot = */ rtFsExtOpenRoot,413 /* .pfnIsRangeInUse = */ rtFsExtIsRangeInUse,414 /* .uEndMarker = */ RTVFSOPS_VERSION415 },416 /* .pfnProbe = */ rtFsExtProbe,417 /* .pfnInit = */ rtFsExtInit418 };419 -
trunk/include/iprt/fsvfs.h
r69013 r69840 33 33 RT_C_DECLS_BEGIN 34 34 35 /** @defgroup grp_rt_fs_ fat FAT VFS File System35 /** @defgroup grp_rt_fs_vfs VFS File System Implementations 36 36 * @ingroup grp_rt_fs 37 37 * @{ … … 119 119 120 120 121 122 /** 123 * Opens an EXT2 file system volume. 124 * 125 * @returns IPRT status code. 126 * @param hVfsFileIn The file or device backing the volume. 127 * @param fMntFlags RTVFSMNT_F_XXX. 128 * @param fExt2Flags Reserved, MBZ. 129 * @param phVfs Where to return the virtual file system handle. 130 * @param pErrInfo Where to return additional error information. 131 */ 132 RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo); 133 134 135 121 136 /** @name RTFSISO9660_F_XXX - ISO 9660 mount flags. 122 137 * @{ */ -
trunk/include/iprt/mangling.h
r69813 r69840 948 948 # define RTFsQueryType RT_MANGLER(RTFsQueryType) 949 949 # define RTFsTypeName RT_MANGLER(RTFsTypeName) 950 # define RTFsExt2VolOpen RT_MANGLER(RTFsExt2VolOpen) 950 951 # define RTFsFatVolOpen RT_MANGLER(RTFsFatVolOpen) 951 952 # define RTFsFatVolFormat RT_MANGLER(RTFsFatVolFormat) … … 2552 2553 # define RTVfsOpenRoot RT_MANGLER(RTVfsOpenRoot) 2553 2554 # define RTVfsQuerPathInfo RT_MANGLER(RTVfsQueryPathInfo) 2555 # define RTVfsMountVol RT_MANGLER(RTVfsMountVol) 2554 2556 # define RTVfsRetain RT_MANGLER(RTVfsRetain) 2555 2557 # define RTVfsRetainDebug RT_MANGLER(RTVfsRetainDebug) -
trunk/include/iprt/vfs.h
r69818 r69840 113 113 RTDECL(uint32_t) RTVfsRetainDebug(RTVFS hVfs, RT_SRC_POS_DECL); 114 114 RTDECL(uint32_t) RTVfsRelease(RTVFS hVfs); 115 116 /** @name RTVFSMNT_F_XXX - Flags for RTVfsMount 117 * @{ */ 118 /** Mount read-only. */ 119 #define RTVFSMNT_F_READ_ONLY RT_BIT_32(0) 120 /** Purpose is . */ 121 #define RTVFSMNT_F_FOR_RANGE_IN_USE RT_BIT_32(1) 122 /** Valid mask. */ 123 #define RTVFSMNT_F_VALID_MASK UINT32_C(0x00000003) 124 /** @} */ 125 126 /** 127 * Does the file system detection and mounting. 128 * 129 * @returns IPRT status code. 130 * @retval VERR_VFS_UNSUPPORTED_FORMAT if not recognized as a support file 131 * system. 132 * @param hVfsFileIn The file handle of the volume. 133 * @param fFlags RTVFSMTN_F_XXX. 134 * @param phVfs Where to return the VFS handle on success. 135 * @param pErrInfo Where to return additional error information. 136 * Optional. 137 */ 138 RTDECL(int) RTVfsMountVol(RTVFSFILE hVfsFileIn, uint32_t fFlags, PRTVFS phVfs, PRTERRINFO pErrInfo); 139 115 140 RTDECL(int) RTVfsAttach(RTVFS hVfs, const char *pszMountPoint, uint32_t fFlags, RTVFS hVfsAttach); 116 141 RTDECL(int) RTVfsDetach(RTVFS hVfs, const char *pszMountPoint, RTVFS hVfsToDetach, PRTVFS *phVfsDetached); … … 144 169 */ 145 170 RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, bool *pfUsed); 171 146 172 147 173 /** @defgroup grp_vfs_obj VFS Base Object API -
trunk/src/VBox/Runtime/Makefile.kmk
r69795 r69840 429 429 common/err/RTErrConvertFromErrno.cpp \ 430 430 common/err/RTErrConvertToErrno.cpp \ 431 common/fs/filesystem.cpp \432 431 common/fs/filesystemext.cpp \ 433 432 common/fs/fatvfs.cpp \ … … 621 620 common/vfs/vfsmemory.cpp \ 622 621 common/vfs/vfsmisc.cpp \ 622 common/vfs/vfsmount.cpp \ 623 623 common/vfs/vfsmsg.cpp \ 624 624 common/vfs/vfsprogress.cpp \ -
trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
r69832 r69840 5606 5606 * 5607 5607 * Check the DOS signature first. The PC-DOS 1.0 boot floppy does not have 5608 * a signature and we ASSUME this is the case for all flop ies formated by it.5608 * a signature and we ASSUME this is the case for all floppies formated by it. 5609 5609 */ 5610 5610 if (Buf.BootSector.uSignature != FATBOOTSECTOR_SIGNATURE) -
trunk/src/VBox/Runtime/common/fs/filesystemext.cpp
r69111 r69840 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #define LOG_GROUP LOG_GROUP_DEFAULT 32 #include <iprt/types.h> 31 #define LOG_GROUP RTLOGGROUP_FS 32 #include <iprt/fsvfs.h> 33 33 34 #include <iprt/assert.h> 35 #include <iprt/log.h> 34 36 #include <iprt/mem.h> 35 #include <iprt/filesystem.h>36 37 #include <iprt/string.h> 37 38 #include <iprt/vfs.h> 38 #include "internal/filesystem.h" 39 #include <iprt/vfslowlevel.h> 40 #include <iprt/formats/ext2.h> 39 41 40 42 … … 42 44 * Structures and Typedefs * 43 45 *********************************************************************************************************************************/ 44 45 /*46 * The filesystem structures are from http://wiki.osdev.org/Ext2 and47 * http://www.nongnu.org/ext2-doc/ext2.html48 */49 50 /**51 * Ext superblock.52 *53 * Everything is stored little endian on the disk.54 */55 #pragma pack(1)56 typedef struct ExtSuperBlock57 {58 /** Total number of inodes in the filesystem. */59 uint32_t cInodesTotal;60 /** Total number of blocks in the filesystem. */61 uint32_t cBlocksTotal;62 /** Number of blocks reserved for the super user. */63 uint32_t cBlocksRsvdForSuperUser;64 /** Total number of unallocated blocks. */65 uint32_t cBlocksUnallocated;66 /** Total number of unallocated inodes. */67 uint32_t cInodesUnallocated;68 /** Block number of block containing the superblock. */69 uint32_t iBlockOfSuperblock;70 /** Number of bits to shift 1024 to the left to get the block size */71 uint32_t cBitsShiftLeftBlockSize;72 /** Number of bits to shift 1024 to the left to get the fragment size */73 uint32_t cBitsShiftLeftFragmentSize;74 /** Number of blocks in each block group. */75 uint32_t cBlocksPerGroup;76 /** Number of fragments in each block group. */77 uint32_t cFragmentsPerBlockGroup;78 /** Number of inodes in each block group. */79 uint32_t cInodesPerBlockGroup;80 /** Last mount time. */81 uint32_t u32LastMountTime;82 /** Last written time. */83 uint32_t u32LastWrittenTime;84 /** Number of times the volume was mounted since the last check. */85 uint16_t cMountsSinceLastCheck;86 /** Number of mounts allowed before a consistency check. */87 uint16_t cMaxMountsUntilCheck;88 /** Signature to identify a ext2 volume. */89 uint16_t u16Signature;90 /** State of the filesystem (clean/errors) */91 uint16_t u16FilesystemState;92 /** What to do on an error. */93 uint16_t u16ActionOnError;94 /** Minor version field. */95 uint16_t u16VersionMinor;96 /** Time of last check. */97 uint32_t u32LastCheckTime;98 /** Interval between consistency checks. */99 uint32_t u32CheckInterval;100 /** Operating system ID of the filesystem creator. */101 uint32_t u32OsIdCreator;102 /** Major version field. */103 uint32_t u32VersionMajor;104 /** User ID that is allowed to use reserved blocks. */105 uint16_t u16UidReservedBlocks;106 /** Group ID that is allowed to use reserved blocks. */107 uint16_t u16GidReservedBlocks;108 /** Reserved fields. */109 uint8_t abReserved[940];110 } ExtSuperBlock;111 #pragma pack()112 AssertCompileSize(ExtSuperBlock, 1024);113 /** Pointer to an ext super block. */114 typedef ExtSuperBlock *PExtSuperBlock;115 116 /** Ext2 signature. */117 #define RTFILESYSTEM_EXT2_SIGNATURE (0xef53)118 /** Clean filesystem state. */119 #define RTFILESYSTEM_EXT2_STATE_CLEAN (0x0001)120 /** Error filesystem state. */121 #define RTFILESYSTEM_EXT2_STATE_ERRORS (0x0002)122 123 /**124 * Block group descriptor.125 */126 #pragma pack(1)127 typedef struct BlockGroupDesc128 {129 /** Block address of the block bitmap. */130 uint32_t offBlockBitmap;131 /** Block address of the inode bitmap. */132 uint32_t offInodeBitmap;133 /** Start block address of the inode table. */134 uint32_t offInodeTable;135 /** Number of unallocated blocks in group. */136 uint16_t cBlocksUnallocated;137 /** Number of unallocated inodes in group. */138 uint16_t cInodesUnallocated;139 /** Number of directories in the group. */140 uint16_t cDirectories;141 /** Padding. */142 uint16_t u16Padding;143 /** Reserved. */144 uint8_t abReserved[12];145 } BlockGroupDesc;146 #pragma pack()147 AssertCompileSize(BlockGroupDesc, 32);148 /** Pointer to an ext block group descriptor. */149 typedef BlockGroupDesc *PBlockGroupDesc;150 151 46 /** 152 47 * Cached block group descriptor data. … … 187 82 188 83 189 /*********************************************************************************************************************************190 * Methods *191 *********************************************************************************************************************************/192 84 193 85 /** … … 203 95 PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc; 204 96 uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock; 205 BlockGroupDescBlkDesc;97 EXT2BLOCKGROUPDESC BlkDesc; 206 98 size_t cbBlockBitmap; 207 99 … … 232 124 } 233 125 234 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, 235 uint32_t offBlockStart, size_t cBlocks) 126 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, uint32_t offBlockStart, size_t cBlocks) 236 127 { 237 128 bool fUsed = false; … … 256 147 257 148 258 static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore)259 {260 int rc = VINF_SUCCESS;261 uint64_t cbMedium = 0;262 263 *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED;264 265 rc = RTVfsFileGetSize(hVfsFile, &cbMedium);266 if (RT_SUCCESS(rc))267 {268 if (cbMedium >= 2*sizeof(ExtSuperBlock))269 {270 ExtSuperBlock SuperBlock;271 272 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);273 if (RT_SUCCESS(rc))274 {275 #if defined(RT_BIGENDIAN)276 /** @todo Convert to host endianess. */277 #endif278 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE)279 *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED;280 }281 }282 }283 284 return rc;285 }286 287 static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile)288 {289 int rc = VINF_SUCCESS;290 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis;291 ExtSuperBlock SuperBlock;292 293 pThis->hVfsFile = hVfsFile;294 pThis->pBlkGrpDesc = NULL;295 296 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL);297 if (RT_SUCCESS(rc))298 {299 #if defined(RT_BIGENDIAN)300 /** @todo Convert to host endianess. */301 #endif302 if (SuperBlock.u16FilesystemState == RTFILESYSTEM_EXT2_STATE_ERRORS)303 rc = VERR_FILESYSTEM_CORRUPT;304 else305 {306 pThis->iSbBlock = SuperBlock.iBlockOfSuperblock;307 pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize;308 pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup;309 pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup;310 311 /* Load first block group descriptor. */312 rc = rtFsExtLoadBlkGrpDesc(pThis, 0);313 }314 }315 316 return rc;317 }318 319 320 149 /** 321 150 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose} 322 151 */ 323 static DECLCALLBACK(int) rtFsExt Vol_Close(void *pvThis)152 static DECLCALLBACK(int) rtFsExt2Vol_Close(void *pvThis) 324 153 { 325 154 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis; … … 335 164 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo} 336 165 */ 337 static DECLCALLBACK(int) rtFsExt Vol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)166 static DECLCALLBACK(int) rtFsExt2Vol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 338 167 { 339 168 RT_NOREF(pvThis, pObjInfo, enmAddAttr); … … 342 171 343 172 344 static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir) 173 /** 174 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnOpenRoot} 175 */ 176 static DECLCALLBACK(int) rtFsExt2_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir) 345 177 { 346 178 NOREF(pvThis); … … 349 181 } 350 182 351 static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb, 352 bool *pfUsed) 183 184 /** 185 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnIsRangeInUse} 186 */ 187 static DECLCALLBACK(int) rtFsExt2_IsRangeInUse(void *pvThis, RTFOFF off, size_t cb, bool *pfUsed) 353 188 { 354 189 int rc = VINF_SUCCESS; … … 394 229 395 230 396 DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt = 397 { 398 /* .cbFs = */ sizeof(RTFILESYSTEMEXT), 399 /* .VfsOps = */ 400 { 401 /* .Obj = */ 231 DECL_HIDDEN_CONST(const RTVFSOPS) g_rtFsExt2VolOps = 232 { 233 /* .Obj = */ 234 { 235 /* .uVersion = */ RTVFSOBJOPS_VERSION, 236 /* .enmType = */ RTVFSOBJTYPE_VFS, 237 /* .pszName = */ "Ext2Vol", 238 /* .pfnClose = */ rtFsExt2Vol_Close, 239 /* .pfnQueryInfo = */ rtFsExt2Vol_QueryInfo, 240 /* .uEndMarker = */ RTVFSOBJOPS_VERSION 241 }, 242 /* .uVersion = */ RTVFSOPS_VERSION, 243 /* .fFeatures = */ 0, 244 /* .pfnOpenRoot = */ rtFsExt2_OpenRoot, 245 /* .pfnIsRangeInUse = */ rtFsExt2_IsRangeInUse, 246 /* .uEndMarker = */ RTVFSOPS_VERSION 247 }; 248 249 250 RTDECL(int) RTFsExt2VolOpen(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fExtFlags, PRTVFS phVfs, PRTERRINFO pErrInfo) 251 { 252 AssertPtrReturn(phVfs, VERR_INVALID_POINTER); 253 AssertReturn(!(fMntFlags & RTVFSMNT_F_VALID_MASK), VERR_INVALID_FLAGS); 254 AssertReturn(!fExtFlags, VERR_INVALID_FLAGS); 255 256 uint32_t cRefs = RTVfsFileRetain(hVfsFileIn); 257 AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE); 258 259 PRTFILESYSTEMEXT pThis; 260 int rc = RTVfsNew(&g_rtFsExt2VolOps, sizeof(*pThis), NIL_RTVFS, RTVFSLOCK_CREATE_RW, phVfs, (void **)&pThis); 261 if (RT_SUCCESS(rc)) 262 { 263 pThis->hVfsFile = hVfsFileIn; 264 pThis->pBlkGrpDesc = NULL; 265 266 EXT2SUPERBLOCK SuperBlock; 267 rc = RTVfsFileReadAt(hVfsFileIn, 1024, &SuperBlock, sizeof(EXT2SUPERBLOCK), NULL); 268 if (RT_SUCCESS(rc)) 402 269 { 403 /* .uVersion = */ RTVFSOBJOPS_VERSION, 404 /* .enmType = */ RTVFSOBJTYPE_VFS, 405 /* .pszName = */ "ExtVol", 406 /* .pfnClose = */ rtFsExtVol_Close, 407 /* .pfnQueryInfo = */ rtFsExtVol_QueryInfo, 408 /* .uEndMarker = */ RTVFSOBJOPS_VERSION 409 }, 410 /* .uVersion = */ RTVFSOPS_VERSION, 411 /* .fFeatures = */ 0, 412 /* .pfnOpenRoot = */ rtFsExtOpenRoot, 413 /* .pfnIsRangeInUse = */ rtFsExtIsRangeInUse, 414 /* .uEndMarker = */ RTVFSOPS_VERSION 415 }, 416 /* .pfnProbe = */ rtFsExtProbe, 417 /* .pfnInit = */ rtFsExtInit 418 }; 419 270 #if defined(RT_BIGENDIAN) 271 /** @todo Convert to host endianess. */ 272 #endif 273 if (SuperBlock.u16FilesystemState == EXT2_STATE_ERRORS) 274 rc = RTERRINFO_LOG_SET(pErrInfo, VERR_FILESYSTEM_CORRUPT, "EXT2_STATE_ERRORS"); 275 else 276 { 277 pThis->iSbBlock = SuperBlock.iBlockOfSuperblock; 278 pThis->cbBlock = 1024 << SuperBlock.cBitsShiftLeftBlockSize; 279 pThis->cBlocksPerGroup = SuperBlock.cBlocksPerGroup; 280 pThis->cBlockGroups = SuperBlock.cBlocksTotal / pThis->cBlocksPerGroup; 281 282 /* Load first block group descriptor. */ 283 rc = rtFsExtLoadBlkGrpDesc(pThis, 0); 284 } 285 if (RT_SUCCESS(rc)) 286 { 287 return VINF_SUCCESS; 288 } 289 } 290 else 291 rc = RTERRINFO_LOG_SET(pErrInfo, rc, "Error reading super block"); 292 293 RTVfsRelease(*phVfs); 294 *phVfs = NIL_RTVFS; 295 } 296 else 297 RTVfsFileRelease(hVfsFileIn); 298 299 return rc; 300 } 301 -
trunk/src/VBox/Runtime/testcase/tstRTFilesystem.cpp
r69111 r69840 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #include <iprt/filesystem.h>32 31 #include <iprt/vfs.h> 33 32 #include <iprt/err.h> … … 48 47 RTTestSubF(hTest, "Create filesystem object"); 49 48 50 rc = RT FilesystemVfsFromFile(hVfsFile, &hVfs);49 rc = RTVfsMountVol(hVfsFile, RTVFSMNT_F_READ_ONLY | RTVFSMNT_F_FOR_RANGE_IN_USE, &hVfs, NULL); 51 50 if (RT_FAILURE(rc)) 52 51 { 53 RTTestIFailed("RT FilesystemVfsFromFile-> %Rrc", rc);52 RTTestIFailed("RTVfsMountVol -> %Rrc", rc); 54 53 return rc; 55 54 } -
trunk/src/VBox/Runtime/testcase/tstRTVfs.cpp
r69111 r69840 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #include <iprt/filesystem.h>32 31 #include <iprt/vfs.h> 33 32 #include <iprt/err.h> -
trunk/src/VBox/Storage/testcase/vbox-img.cpp
r69616 r69840 36 36 #include <iprt/assert.h> 37 37 #include <iprt/dvm.h> 38 #include <iprt/filesystem.h>39 38 #include <iprt/vfs.h> 40 39 … … 1360 1359 static int handleCompact(HandlerArg *a) 1361 1360 { 1362 int rc = VINF_SUCCESS;1363 1361 PVDISK pDisk = NULL; 1364 const char *pszFilename = NULL;1365 bool fFilesystemAware = false;1366 1362 VDINTERFACEQUERYRANGEUSE VDIfQueryRangeUse; 1367 1363 PVDINTERFACE pIfsCompact = NULL; … … 1372 1368 static const RTGETOPTDEF s_aOptions[] = 1373 1369 { 1374 { "--filename", 'f', RTGETOPT_REQ_STRING }, 1375 { "--filesystemaware", 'a', RTGETOPT_REQ_NOTHING } 1370 { "--filename", 'f', RTGETOPT_REQ_STRING }, 1371 { "--filesystemaware", 'a', RTGETOPT_REQ_NOTHING }, 1372 { "--file-system-aware", 'a', RTGETOPT_REQ_NOTHING }, 1376 1373 }; 1374 1375 const char *pszFilename = NULL; 1376 bool fFilesystemAware = false; 1377 bool fVerbose = true; 1378 1377 1379 int ch; 1378 1380 RTGETOPTUNION ValueUnion; … … 1405 1407 char *pszFormat = NULL; 1406 1408 VDTYPE enmType = VDTYPE_INVALID; 1407 rc = VDGetFormat(NULL, NULL, pszFilename, &pszFormat, &enmType);1409 int rc = VDGetFormat(NULL, NULL, pszFilename, &pszFormat, &enmType); 1408 1410 if (RT_FAILURE(rc)) 1409 1411 return errorSyntax("Format autodetect failed: %Rrc\n", rc); … … 1419 1421 return errorRuntime("Error while opening the image: %Rrf (%Rrc)\n", rc, rc); 1420 1422 1423 /* 1424 * If --file-system-aware, we first ask the disk volume manager (DVM) to 1425 * find the volumes on the disk. 1426 */ 1421 1427 if ( RT_SUCCESS(rc) 1422 1428 && fFilesystemAware) … … 1434 1440 && RTDvmMapGetValidVolumes(hDvm) > 0) 1435 1441 { 1436 /* Get all volumes and set the block query status callback. */ 1442 /* 1443 * Enumerate the volumes: Try finding a file system interpreter and 1444 * set the block query status callback to work with the FS. 1445 */ 1446 uint32_t iVol = 0; 1437 1447 RTDVMVOLUME hVol; 1438 1448 rc = RTDvmMapQueryFirstVolume(hDvm, &hVol); … … 1441 1451 while (RT_SUCCESS(rc)) 1442 1452 { 1453 if (fVerbose) 1454 { 1455 char *pszVolName; 1456 rc = RTDvmVolumeQueryName(hVol, &pszVolName); 1457 if (RT_FAILURE(rc)) 1458 pszVolName = NULL; 1459 RTMsgInfo("Vol%u: %Rhcb %u %s%s%s\n", iVol, RTDvmVolumeGetSize(hVol), 1460 RTDvmVolumeTypeGetDescr(RTDvmVolumeGetType(hVol)), 1461 pszVolName ? " " : "", pszVolName ? pszVolName : ""); 1462 RTStrFree(pszVolName); 1463 } 1464 1443 1465 RTVFSFILE hVfsFile; 1444 1466 rc = RTDvmVolumeCreateVfsFile(hVol, RTFILE_O_READWRITE, &hVfsFile); 1445 1467 if (RT_FAILURE(rc)) 1468 { 1469 errorRuntime("RTDvmVolumeCreateVfsFile failed: %Rrc\n"); 1446 1470 break; 1471 } 1447 1472 1448 1473 /* Try to detect the filesystem in this volume. */ 1474 RTERRINFOSTATIC ErrInfo; 1449 1475 RTVFS hVfs; 1450 rc = RTFilesystemVfsFromFile(hVfsFile, &hVfs); 1451 if (rc == VERR_NOT_SUPPORTED) 1452 { 1453 /* Release the file handle and continue.*/ 1454 RTVfsFileRelease(hVfsFile); 1455 } 1456 else if (RT_FAILURE(rc)) 1457 break; 1458 else 1476 rc = RTVfsMountVol(hVfsFile, RTVFSMNT_F_READ_ONLY | RTVFSMNT_F_FOR_RANGE_IN_USE, &hVfs, 1477 RTErrInfoInitStatic(&ErrInfo)); 1478 RTVfsFileRelease(hVfsFile); 1479 if (RT_SUCCESS(rc)) 1459 1480 { 1460 1481 PVBOXIMGVFS pVBoxImgVfs = (PVBOXIMGVFS)RTMemAllocZ(sizeof(VBOXIMGVFS)); 1461 1482 if (!pVBoxImgVfs) 1483 { 1484 RTVfsRelease(hVfs); 1462 1485 rc = VERR_NO_MEMORY; 1463 else 1464 { 1465 pVBoxImgVfs->hVfs = hVfs; 1466 pVBoxImgVfs->pNext = pVBoxImgVfsHead; 1467 pVBoxImgVfsHead = pVBoxImgVfs; 1468 RTDvmVolumeSetQueryBlockStatusCallback(hVol, vboximgQueryBlockStatus, hVfs); 1486 break; 1469 1487 } 1488 pVBoxImgVfs->hVfs = hVfs; 1489 pVBoxImgVfs->pNext = pVBoxImgVfsHead; 1490 pVBoxImgVfsHead = pVBoxImgVfs; 1491 RTDvmVolumeSetQueryBlockStatusCallback(hVol, vboximgQueryBlockStatus, hVfs); 1470 1492 } 1471 1493 else if (rc != VERR_NOT_SUPPORTED) 1494 { 1495 if (RTErrInfoIsSet(&ErrInfo.Core)) 1496 errorRuntime("RTVfsMountVol failed: %s\n", ErrInfo.Core.pszMsg); 1497 break; 1498 } 1499 else if (fVerbose && RTErrInfoIsSet(&ErrInfo.Core)) 1500 RTMsgInfo("Unsupported file system: %s", ErrInfo.Core.pszMsg); 1501 1502 /* 1503 * Advance. (Releasing hVol here is fine since RTDvmVolumeCreateVfsFile 1504 * retained a reference and the hVfs a reference of it again.) 1505 */ 1472 1506 RTDVMVOLUME hVolNext = NIL_RTDVMVOLUME; 1473 1507 if (RT_SUCCESS(rc)) 1474 1508 rc = RTDvmMapQueryNextVolume(hDvm, hVol, &hVolNext); 1475 1476 /*1477 * Release the volume handle, the file handle has a reference1478 * to keep it open.1479 */1480 1509 RTDvmVolumeRelease(hVol); 1481 1510 hVol = hVolNext; 1511 iVol++; 1482 1512 } 1483 1513 … … 1496 1526 else if (rc == VERR_NOT_FOUND) 1497 1527 { 1528 RTPrintf("No known volume format on disk found\n"); 1498 1529 rc = VINF_SUCCESS; 1499 RTPrintf("No known volume format on disk found\n");1500 1530 } 1501 1531 else
Note:
See TracChangeset
for help on using the changeset viewer.