Changeset 41549 in vbox
- Timestamp:
- Jun 1, 2012 5:29:05 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 78314
- Location:
- trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/filesystem.h
r40036 r41549 27 27 #define ___iprt_filesystem_h 28 28 29 #include <iprt/cdefs.h> 29 30 #include <iprt/types.h> 31 #include <iprt/vfs.h> 30 32 31 33 RT_C_DECLS_BEGIN 32 34 33 /** @defgroup grp_filesystem IPRT Filesystem 35 /** @defgroup grp_filesystem IPRT Filesystem VFS 34 36 * @{ 35 37 */ 36 38 37 /** Handle to a filesystem. */38 typedef struct RTFILESYSTEMINT *RTFILESYSTEM;39 /** A pointer to a filesystem handle. */40 typedef RTFILESYSTEM *PRTFILESYSTEM;41 /** NIL filesystem handle. */42 #define NIL_RTFILESYSTEM ((RTFILESYSTEM)~0)43 44 39 /** 45 * Callback to read data from the underlying medium of the filesystem. 40 * Detect the filesystem in the image given by the VFS file handle 41 * and create a new VFS object. 46 42 * 47 43 * @returns IPRT status code. 48 * @param pvUser Opaque user data passed on creation. 49 * @param off Offset to start reading from. 50 * @param pvBuf Where to store the read data. 51 * @param cbRead How many bytes to read. 44 * @retval VERR_NOT_SUPPORTED if the filesystem is not recognized. 45 * @param hVfsFile The file to use as the filesystem medium. 46 * @param phVfs Where to store the VFS handle on success. 52 47 */ 53 typedef DECLCALLBACK(int) FNRTFILESYSTEMREAD(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead); 54 /** Pointer to a read callback. */ 55 typedef FNRTFILESYSTEMREAD *PFNRTFILESYSTEMREAD; 56 57 /** 58 * Callback to write data to the underlying medium of the filesystem. 59 * 60 * @returns IPRT status code. 61 * @param pvUser Opaque user data passed on creation. 62 * @param off Offset to start writing to. 63 * @param pvBuf The data to write. 64 * @param cbRead How many bytes to write. 65 */ 66 typedef DECLCALLBACK(int) FNRTFILESYSTEMWRITE(void *pvUser, uint64_t off, const void *pvBuf, size_t cbWrite); 67 /** Pointer to a read callback. */ 68 typedef FNRTFILESYSTEMWRITE *PFNRTFILESYSTEMWRITE; 69 70 /** 71 * Probes for and opens a filesystem from the given medium. 72 * 73 * @returns IPRT status code. 74 * @retval VERR_NOT_SUPPORTED if the filesystem on the given medium is unsupported. 75 * @param phFs Where to store the handle to the filesystem object on success. 76 * @param pfnRead Read callback for the medium. 77 * @param pfnWrite Write callback for the medium. 78 * @param cbMedium Size of the whole medium. 79 * @param cbSector Size of one sector on the medium. 80 * @param pvUser Opaque user data used in the read/write callbacks. 81 * @param fFlags Flags to open the filesystem with. 82 */ 83 RTDECL(int) RTFilesystemOpen(PRTFILESYSTEM phFs, PFNRTFILESYSTEMREAD pfnRead, 84 PFNRTFILESYSTEMWRITE pfnWrite, uint64_t cbMedium, 85 uint64_t cbSector, void *pvUser, uint32_t fFlags); 86 87 /** 88 * Retain a given filesystem object. 89 * 90 * @returns New reference count on success, UINT32_MAX on failure. 91 * @param hFs The filesystem object handle. 92 */ 93 RTDECL(uint32_t) RTFilesystemRetain(RTFILESYSTEM hFs); 94 95 /** 96 * Releases a given volume manager. 97 * 98 * @returns New reference count on success (0 if closed), UINT32_MAX on failure. 99 * @param hFs The filesystem object handle. 100 */ 101 RTDECL(uint32_t) RTFilesystemRelease(RTFILESYSTEM hFs); 102 103 /** 104 * Returns the format name of the used filesystem. 105 * 106 * @returns Name of the filesystem format used. 107 * @param hFs The filesystem object handle. 108 */ 109 RTDECL(const char *) RTFilesystemGetFormat(RTFILESYSTEM hFs); 110 111 /** 112 * Returns the smallest accessible unit of the filesystem. 113 * 114 * @returns Block size of the given filesystem or 0 on failure. 115 * @param hFs The filesystem object handle. 116 */ 117 RTDECL(uint64_t) RTFilesystemGetBlockSize(RTFILESYSTEM hFs); 118 119 /** 120 * Queries whether the given range on the medium is used by the filesystem. 121 * 122 * @returns IPRT status code. 123 * @param hFs The filesystem object handle. 124 * @param offStart The start offset on the medium to check for. 125 * @param cb Size of the range to check for. 126 * @param pfUsed Where to store whether the range is in use by the filesystem 127 * on success. 128 */ 129 RTDECL(int) RTFilesystemQueryRangeUse(RTFILESYSTEM hFs, uint64_t offStart, 130 size_t cb, bool *pfUsed); 48 RTDECL(int) RTFilesystemVfsFromFile(RTVFSFILE hVfsFile, PRTVFS phVfs); 131 49 132 50 /** @} */ -
trunk/include/iprt/mangling.h
r41169 r41549 514 514 # define RTFileWrite RT_MANGLER(RTFileWrite) 515 515 # define RTFileWriteAt RT_MANGLER(RTFileWriteAt) 516 # define RTFilesystemOpen RT_MANGLER(RTFilesystemOpen) 517 # define RTFilesystemRetain RT_MANGLER(RTFilesystemRetain) 518 # define RTFilesystemRelease RT_MANGLER(RTFilesystemRelease) 519 # define RTFilesystemGetFormat RT_MANGLER(RTFilesystemGetFormat) 520 # define RTFilesystemGetBlockSize RT_MANGLER(RTFilesystemGetBlockSize) 521 # define RTFilesystemQueryRangeUse RT_MANGLER(RTFilesystemQueryRangeUse) 516 # define RTFilesystemVfsFromFile RT_MANGLER(RTFilesystemVfsFromFile) 522 517 # define RTFsQueryProperties RT_MANGLER(RTFsQueryProperties) 523 518 # define RTFsQuerySerial RT_MANGLER(RTFsQuerySerial) … … 1684 1679 # define RTVfsIoStrmQueryInfo RT_MANGLER(RTVfsIoStrmQueryInfo) 1685 1680 # define RTVfsIoStrmRead RT_MANGLER(RTVfsIoStrmRead) 1681 # define RTVfsIoStrmReadAt RT_MANGLER(RTVfsIoStrmReadAt) 1686 1682 # define RTVfsIoStrmRelease RT_MANGLER(RTVfsIoStrmRelease) 1687 1683 # define RTVfsIoStrmRetain RT_MANGLER(RTVfsIoStrmRetain) … … 1693 1689 # define RTVfsIoStrmValidateUtf8Encoding RT_MANGLER(RTVfsIoStrmValidateUtf8Encoding) 1694 1690 # define RTVfsIoStrmWrite RT_MANGLER(RTVfsIoStrmWrite) 1691 # define RTVfsIoStrmWriteAt RT_MANGLER(RTVfsIoStrmWriteAt) 1695 1692 # define RTVfsIoStrmZeroFill RT_MANGLER(RTVfsIoStrmZeroFill) 1696 1693 # define RTVfsLockAcquireReadSlow RT_MANGLER(RTVfsLockAcquireReadSlow) -
trunk/include/iprt/vfs.h
r37596 r41549 118 118 char *pszMountPoint, size_t cbMountPoint); 119 119 120 /** 121 * Checks whether a given range is in use by the virtual filesystem. 122 * 123 * @returns IPRT status code. 124 * @param hVfs VFS handle. 125 * @param off Start offset to check. 126 * @param cb Number of bytes to check. 127 * @param pfUsed Where to store the result. 128 */ 129 RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, 130 bool *pfUsed); 120 131 121 132 /** @defgroup grp_vfs_dir VFS Base Object API … … 521 532 */ 522 533 RTDECL(int) RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead); 534 RTDECL(int) RTVfsIoStrmReadAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead); 523 535 524 536 /** … … 539 551 */ 540 552 RTDECL(int) RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten); 553 RTDECL(int) RTVfsIoStrmWriteAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten); 541 554 542 555 /** -
trunk/include/iprt/vfslowlevel.h
r36555 r41549 187 187 DECLCALLBACKMEMBER(int, pfnOpenRoot)(void *pvThis, PRTVFSDIR phVfsDir); 188 188 189 /** 190 * Checks whether a given range in the underlying medium 191 * is in use by the virtual filesystem. 192 * 193 * @returns IPRT status code. 194 * @param pvThis The implementation specific data. 195 * @param off Start offset to check. 196 * @param cb Number of bytes to check. 197 * @param pfUsed Where to store whether the given range is in use. 198 */ 199 DECLCALLBACKMEMBER(int, pfnIsRangeInUse)(void *pvThis, RTFOFF off, size_t cb, 200 bool *pfUsed); 201 189 202 /** @todo There will be more methods here to optimize opening and 190 203 * querying. */ … … 220 233 /** @} */ 221 234 235 /** 236 * Creates a new VFS handle. 237 * 238 * @returns IPRT status code 239 * @param pVfs Ops The VFS operations. 240 * @param cbInstance The size of the instance data. 241 * @param hVfs The VFS handle to associate this VFS with. 242 * NIL_VFS is ok. 243 * @param hLock Handle to a custom lock to be used with the new 244 * object. The reference is consumed. NIL and 245 * special lock handles are fine. 246 * @param phVfs Where to return the new handle. 247 * @param ppvInstance Where to return the pointer to the instance data 248 * (size is @a cbInstance). 249 */ 250 RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 251 PRTVFS phVfs, void **ppvInstance); 222 252 223 253 /** -
trunk/src/VBox/Runtime/Makefile.kmk
r41477 r41549 281 281 common/dvm/dvmgpt.cpp \ 282 282 common/dvm/dvmmbr.cpp \ 283 common/dvm/dvmvfs.cpp \ 283 284 common/err/errinfo.cpp \ 284 285 common/err/errmsg.cpp \ -
trunk/src/VBox/Runtime/common/dvm/dvm.cpp
r40293 r41549 469 469 { 470 470 int rc = VINF_SUCCESS; 471 bool fAllocated = false;472 471 PRTDVMINTERNAL pThis = hVolMgr; 473 472 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); … … 478 477 VERR_INVALID_PARAMETER); 479 478 480 while ( cb > 0 481 && !fAllocated) 482 { 483 PRTDVMVOLUMEINTERNAL pVol; 484 bool fVolFound = false; 485 uint64_t cbIntersect; 486 uint64_t offVol; 487 488 /* 489 * Search through all volumes. It is not possible to 490 * get all start sectors and sizes of all volumes here 491 * because volumes can be scattered around the disk for certain formats. 492 * Linux LVM is one example, extents of logical volumes don't need to be 493 * contigous on the medium. 494 */ 495 RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode) 479 /* Check whether the range is inuse by the volume manager metadata first. */ 480 rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated); 481 if (RT_FAILURE(rc)) 482 return rc; 483 484 if (!*pfAllocated) 485 { 486 bool fAllocated = false; 487 488 while ( cb > 0 489 && !fAllocated) 496 490 { 497 bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off, 498 cb, &offVol, 499 &cbIntersect); 500 if (fIntersect) 491 PRTDVMVOLUMEINTERNAL pVol; 492 bool fVolFound = false; 493 uint64_t cbIntersect; 494 uint64_t offVol; 495 496 /* 497 * Search through all volumes. It is not possible to 498 * get all start sectors and sizes of all volumes here 499 * because volumes can be scattered around the disk for certain formats. 500 * Linux LVM is one example, extents of logical volumes don't need to be 501 * contigous on the medium. 502 */ 503 RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode) 501 504 { 502 fVolFound = true; 503 if (pVol->pfnQueryBlockStatus) 505 bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off, 506 cb, &offVol, 507 &cbIntersect); 508 if (fIntersect) 504 509 { 505 bool fVolAllocated = true; 506 507 rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, 508 &fVolAllocated); 509 if (RT_FAILURE(rc)) 510 break; 510 fVolFound = true; 511 if (pVol->pfnQueryBlockStatus) 512 { 513 bool fVolAllocated = true; 514 515 rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, 516 &fVolAllocated); 517 if (RT_FAILURE(rc)) 518 break; 519 else if (fVolAllocated) 520 { 521 fAllocated = true; 522 break; 523 } 524 } 525 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED)) 526 fAllocated = true; 527 /* else, flag is set, continue. */ 528 529 cb -= cbIntersect; 530 off += cbIntersect; 531 break; 511 532 } 512 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED)) 533 } 534 535 if (!fVolFound) 536 { 537 if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 513 538 fAllocated = true; 514 /* else, flag is set, continue. */ 515 516 cb -= cbIntersect; 517 off += cbIntersect; 518 break; 539 540 cb -= pThis->DvmDisk.cbSector; 541 off += pThis->DvmDisk.cbSector; 519 542 } 520 543 } 521 544 522 if (!fVolFound) 523 { 524 if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 525 fAllocated = true; 526 527 cb -= pThis->DvmDisk.cbSector; 528 off += pThis->DvmDisk.cbSector; 529 } 530 } 531 532 *pfAllocated = fAllocated; 545 *pfAllocated = fAllocated; 546 } 533 547 534 548 return rc; -
trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
r40949 r41549 343 343 } 344 344 345 static DECLCALLBACK(int) rtDvmFmtBsdLblQueryRangeUse(RTDVMFMT hVolMgrFmt, 346 uint64_t off, uint64_t cbRange, 347 bool *pfUsed) 348 { 349 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 350 351 if (off <= RTDVM_BSDLBL_LBA2BYTE(1, pThis->pDisk)) 352 *pfUsed = true; 353 else 354 *pfUsed = false; 355 356 return VINF_SUCCESS; 357 } 358 345 359 DECLCALLBACK(uint32_t) rtDvmFmtBsdLblGetValidVolumes(RTDVMFMT hVolMgrFmt) 346 360 { … … 513 527 /* pfnClose */ 514 528 rtDvmFmtBsdLblClose, 529 /* pfnQueryRangeUse */ 530 rtDvmFmtBsdLblQueryRangeUse, 515 531 /* pfnGetValidVolumes */ 516 532 rtDvmFmtBsdLblGetValidVolumes, -
trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp
r40949 r41549 342 342 } 343 343 344 static DECLCALLBACK(int) rtDvmFmtGptQueryRangeUse(RTDVMFMT hVolMgrFmt, 345 uint64_t off, uint64_t cbRange, 346 bool *pfUsed) 347 { 348 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 349 350 if (off < 33*pThis->pDisk->cbSector) 351 *pfUsed = true; 352 else 353 *pfUsed = false; 354 355 return VINF_SUCCESS; 356 } 357 344 358 static DECLCALLBACK(uint32_t) rtDvmFmtGptGetValidVolumes(RTDVMFMT hVolMgrFmt) 345 359 { … … 531 545 /* pfnClose */ 532 546 rtDvmFmtGptClose, 547 /* pfnQueryRangeUse */ 548 rtDvmFmtGptQueryRangeUse, 533 549 /* pfnGetValidVolumes */ 534 550 rtDvmFmtGptGetValidVolumes, -
trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp
r40298 r41549 212 212 } 213 213 214 static DECLCALLBACK(int) rtDvmFmtMbrQueryRangeUse(RTDVMFMT hVolMgrFmt, 215 uint64_t off, uint64_t cbRange, 216 bool *pfUsed) 217 { 218 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 219 220 /* MBR uses the first sector only. */ 221 if (off < 512) 222 *pfUsed = true; 223 else 224 *pfUsed = false; 225 226 return VINF_SUCCESS; 227 } 228 214 229 static DECLCALLBACK(uint32_t) rtDvmFmtMbrGetValidVolumes(RTDVMFMT hVolMgrFmt) 215 230 { … … 399 414 /* pfnClose */ 400 415 rtDvmFmtMbrClose, 416 /* pfnQueryRangeUse */ 417 rtDvmFmtMbrQueryRangeUse, 401 418 /* pfnGetValidVolumes */ 402 419 rtDvmFmtMbrGetValidVolumes, -
trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp
r41094 r41549 93 93 94 94 Assert(pSgBuf->cSegs == 1); 95 Assert(off < 0);96 95 NOREF(fBlocking); 97 96 … … 149 148 150 149 Assert(pSgBuf->cSegs == 1); 151 Assert(off < 0);152 150 NOREF(fBlocking); 153 151 -
trunk/src/VBox/Runtime/common/filesystem/filesystem.cpp
r40038 r41549 41 41 42 42 /******************************************************************************* 43 * Structures and Typedefs *44 *******************************************************************************/45 46 /**47 * Medium descriptor.48 */49 typedef struct RTFILESYSTEMMEDIUMINT50 {51 /** Size of the medium in bytes. */52 uint64_t cbMedium;53 /** Sector size. */54 uint64_t cbSector;55 /** Read callback */56 PFNRTFILESYSTEMREAD pfnRead;57 /** Write callback. */58 PFNRTFILESYSTEMWRITE pfnWrite;59 /** Opaque user data. */60 void *pvUser;61 } RTFILESYSTEMMEDIUMINT;62 /** Pointer to a disk descriptor. */63 typedef RTFILESYSTEMMEDIUMINT *PRTFILESYSTEMMEDIUMINT;64 /** Pointer to a const descriptor. */65 typedef const RTFILESYSTEMMEDIUMINT *PCRTFILESYSTEMMEDIUMINT;66 67 /**68 * The internal filesystem object structure.69 */70 typedef struct RTFILESYSTEMINT71 {72 /** The filesytem object magic (RTFILESYSTEM_MAGIC). */73 uint32_t u32Magic;74 /** Medium descriptor. */75 RTFILESYSTEMMEDIUMINT Medium;76 /** Filesystem format operations */77 PCRTFILESYSTEMFMTOPS pcFsFmtOps;78 /** Filesystem format handle. */79 RTFILESYSTEMFMT hFsFmt;80 /** Reference counter. */81 uint32_t volatile cRefs;82 } RTFILESYSTEMINT;83 /** Pointer to an internal volume manager. */84 typedef RTFILESYSTEMINT *PRTFILESYSTEMINT;85 86 /*******************************************************************************87 43 * Global variables * 88 44 *******************************************************************************/ 89 extern RTFILESYSTEMFMTOPS g_rtFilesystemFmtExt;90 45 91 46 /** 92 47 * Supported volume formats. 93 48 */ 94 static PCRTFILESYSTEM FMTOPS g_aFilesystemFmts[] =49 static PCRTFILESYSTEMDESC g_aFsFmts[] = 95 50 { 96 &g_rtF ilesystemFmtExt51 &g_rtFsExt 97 52 }; 98 53 99 DECLHIDDEN(uint64_t) rtFilesystemMediumGetSize(RTFILESYSTEMMEDIUM hMedium) 100 { 101 PRTFILESYSTEMMEDIUMINT pMedInt = hMedium; 102 AssertPtrReturn(pMedInt, 0); 103 104 return pMedInt->cbMedium; 105 } 106 107 DECLHIDDEN(int) rtFilesystemMediumRead(RTFILESYSTEMMEDIUM hMedium, uint64_t off, 108 void *pvBuf, size_t cbRead) 109 { 110 PRTFILESYSTEMMEDIUMINT pMedInt = hMedium; 111 AssertPtrReturn(pMedInt, VERR_INVALID_HANDLE); 112 113 return pMedInt->pfnRead(pMedInt->pvUser, off, pvBuf, cbRead); 114 } 115 116 DECLHIDDEN(int) rtFilesystemMediumWrite(RTFILESYSTEMMEDIUM hMedium, uint64_t off, 117 const void *pvBuf, size_t cbWrite) 118 { 119 PRTFILESYSTEMMEDIUMINT pMedInt = hMedium; 120 AssertPtrReturn(pMedInt, VERR_INVALID_HANDLE); 121 122 return pMedInt->pfnWrite(pMedInt->pvUser, off, pvBuf, cbWrite); 123 } 124 125 RTDECL(uint32_t) RTFilesystemRetain(RTFILESYSTEM hFs) 126 { 127 PRTFILESYSTEMINT pThis = hFs; 128 AssertPtrReturn(pThis, UINT32_MAX); 129 AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, UINT32_MAX); 130 131 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 132 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 133 return cRefs; 134 } 135 136 /** 137 * Destroys a volume manager handle. 138 * 139 * @param pThis The filesystem object to destroy. 140 */ 141 static void rtFilesystemDestroy(PRTFILESYSTEMINT pThis) 142 { 143 if (pThis->hFsFmt != NIL_RTFILESYSTEMFMT) 144 { 145 AssertPtr(pThis->pcFsFmtOps); 146 147 /* Let the backend do it's own cleanup first. */ 148 pThis->pcFsFmtOps->pfnClose(pThis->hFsFmt); 149 pThis->hFsFmt = NIL_RTFILESYSTEMFMT; 150 } 151 152 pThis->Medium.cbMedium = 0; 153 pThis->Medium.pvUser = NULL; 154 pThis->Medium.pfnRead = NULL; 155 pThis->Medium.pfnWrite = NULL; 156 pThis->u32Magic = RTFILESYSTEM_MAGIC_DEAD; 157 RTMemFree(pThis); 158 } 159 160 RTDECL(uint32_t) RTFilesystemRelease(RTFILESYSTEM hFs) 161 { 162 PRTFILESYSTEMINT pThis = hFs; 163 if (pThis == NIL_RTFILESYSTEM) 164 return 0; 165 AssertPtrReturn(pThis, UINT32_MAX); 166 AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, UINT32_MAX); 167 168 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); 169 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 170 if (cRefs == 0) 171 rtFilesystemDestroy(pThis); 172 return cRefs; 173 } 174 175 RTDECL(int) RTFilesystemOpen(PRTFILESYSTEM phFs, PFNRTFILESYSTEMREAD pfnRead, 176 PFNRTFILESYSTEMWRITE pfnWrite, uint64_t cbMedium, 177 uint64_t cbSector, void *pvUser, uint32_t fFlags) 54 static int rtFsGetFormat(RTVFSFILE hVfsFile, PCRTFILESYSTEMDESC *ppFsDesc) 178 55 { 179 56 int rc = VINF_SUCCESS; 180 57 uint32_t uScoreMax = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED; 181 PCRTFILESYSTEMFMTOPS pcFsFmtOpsMatch = NULL; 182 PRTFILESYSTEMINT pThis = NULL; 183 AssertPtrReturn(phFs, VERR_INVALID_POINTER); 184 AssertPtrReturn(pfnRead, VERR_INVALID_POINTER); 58 PCRTFILESYSTEMDESC pFsFmtMatch = NULL; 185 59 186 pThis = (PRTFILESYSTEMINT)RTMemAllocZ(sizeof(RTFILESYSTEMINT)); 187 if (!pThis) 188 return VERR_NO_MEMORY; 189 190 pThis->u32Magic = RTFILESYSTEM_MAGIC; 191 pThis->Medium.cbMedium = cbMedium; 192 pThis->Medium.cbSector = cbSector; 193 pThis->Medium.pfnRead = pfnRead; 194 pThis->Medium.pfnWrite = pfnWrite; 195 pThis->Medium.pvUser = pvUser; 196 pThis->cRefs = 1; 197 198 for (unsigned i = 0; i < RT_ELEMENTS(g_aFilesystemFmts); i++) 60 for (unsigned i = 0; i < RT_ELEMENTS(g_aFsFmts); i++) 199 61 { 200 62 uint32_t uScore; 201 PCRTFILESYSTEM FMTOPS pcFsFmtOps = g_aFilesystemFmts[i];63 PCRTFILESYSTEMDESC pFsFmt = g_aFsFmts[i]; 202 64 203 rc = p cFsFmtOps->pfnProbe(&pThis->Medium, &uScore);65 rc = pFsFmt->pfnProbe(hVfsFile, &uScore); 204 66 if ( RT_SUCCESS(rc) 205 67 && uScore > uScoreMax) 206 68 { 207 p cFsFmtOpsMatch = pcFsFmtOps;208 uScoreMax 69 pFsFmtMatch = pFsFmt; 70 uScoreMax = uScore; 209 71 } 210 72 else if (RT_FAILURE(rc)) … … 216 78 if (uScoreMax > RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED) 217 79 { 218 AssertPtr(pcFsFmtOpsMatch); 219 220 /* Open the format. */ 221 rc = pcFsFmtOpsMatch->pfnOpen(&pThis->Medium, &pThis->hFsFmt); 222 if (RT_SUCCESS(rc)) 223 pThis->pcFsFmtOps = pcFsFmtOpsMatch; 80 AssertPtr(pFsFmtMatch); 81 *ppFsDesc = pFsFmtMatch; 224 82 } 225 83 else … … 227 85 } 228 86 87 return rc; 88 } 89 90 RTDECL(int) RTFilesystemVfsFromFile(RTVFSFILE hVfsFile, PRTVFS phVfs) 91 { 92 int rc = VINF_SUCCESS; 93 PCRTFILESYSTEMDESC pFsDesc = NULL; 94 RTVFS hVfs = NIL_RTVFS; 95 void *pvThis = NULL; 96 97 AssertPtrReturn(hVfsFile, VERR_INVALID_HANDLE); 98 AssertPtrReturn(phVfs, VERR_INVALID_POINTER); 99 100 rc = rtFsGetFormat(hVfsFile, &pFsDesc); 229 101 if (RT_SUCCESS(rc)) 230 *phFs = pThis; 231 else 232 RTMemFree(pThis); 102 { 103 rc = RTVfsNew(&pFsDesc->VfsOps, pFsDesc->cbFs, NIL_RTVFS, NIL_RTVFSLOCK, 104 &hVfs, &pvThis); 105 if (RT_SUCCESS(rc)) 106 { 107 rc = pFsDesc->pfnInit(pvThis, hVfsFile); 108 if (RT_SUCCESS(rc)) 109 *phVfs = hVfs; 110 else 111 RTVfsRelease(hVfs); 112 } 113 } 233 114 234 115 return rc; 235 116 } 236 117 237 RTDECL(const char *) RTFilesystemGetFormat(RTFILESYSTEM hFs)238 {239 PRTFILESYSTEMINT pThis = hFs;240 AssertPtrReturn(pThis, NULL);241 AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, NULL);242 118 243 return pThis->pcFsFmtOps->pcszFmt;244 }245 246 RTDECL(uint64_t) RTFilesystemGetBlockSize(RTFILESYSTEM hFs)247 {248 PRTFILESYSTEMINT pThis = hFs;249 AssertPtrReturn(pThis, 0);250 AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, 0);251 252 return pThis->pcFsFmtOps->pfnGetBlockSize(pThis->hFsFmt);253 }254 255 RTDECL(int) RTFilesystemQueryRangeUse(RTFILESYSTEM hFs, uint64_t offStart, size_t cb,256 bool *pfUsed)257 {258 PRTFILESYSTEMINT pThis = hFs;259 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);260 AssertReturn(pThis->u32Magic == RTFILESYSTEM_MAGIC, VERR_INVALID_HANDLE);261 AssertPtrReturn(pfUsed, VERR_INVALID_POINTER);262 AssertReturn(offStart + cb <= pThis->Medium.cbMedium, VERR_OUT_OF_RANGE);263 264 return pThis->pcFsFmtOps->pfnQueryRangeUse(pThis->hFsFmt, offStart, cb, pfUsed);265 } -
trunk/src/VBox/Runtime/common/filesystem/filesystemext.cpp
r40038 r41549 35 35 #include <iprt/filesystem.h> 36 36 #include <iprt/string.h> 37 #include <iprt/vfs.h> 37 38 #include "internal/filesystem.h" 38 39 … … 151 152 * Cached block group descriptor data. 152 153 */ 153 typedef struct RTFILESYSTEM FMTEXTBLKGRP154 typedef struct RTFILESYSTEMEXTBLKGRP 154 155 { 155 156 /** Start offset (in bytes and from the start of the disk). */ … … 160 161 * and number of blocks per group). */ 161 162 uint8_t abBlockBitmap[1]; 162 } RTFILESYSTEM FMTEXTBLKGRP;163 } RTFILESYSTEMEXTBLKGRP; 163 164 /** Pointer to block group descriptor data. */ 164 typedef RTFILESYSTEM FMTEXTBLKGRP *PRTFILESYSTEMFMTEXTBLKGRP;165 typedef RTFILESYSTEMEXTBLKGRP *PRTFILESYSTEMEXTBLKGRP; 165 166 166 167 /** 167 168 * Ext2/3 filesystem data. 168 169 */ 169 typedef struct RTFILESYSTEM FMTINT170 { 171 /** Handle to the underlying medium. */172 RT FILESYSTEMMEDIUM hMedium;170 typedef struct RTFILESYSTEMEXT 171 { 172 /** VFS file handle. */ 173 RTVFSFILE hVfsFile; 173 174 /** Block number of the superblock. */ 174 175 uint32_t iSbBlock; … … 180 181 unsigned cBlockGroups; 181 182 /** Cached block group descriptor data. */ 182 PRTFILESYSTEM FMTEXTBLKGRPpBlkGrpDesc;183 } RTFILESYSTEM FMTINT;183 PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc; 184 } RTFILESYSTEMEXT; 184 185 /** Pointer to the ext filesystem data. */ 185 typedef RTFILESYSTEM FMTINT *PRTFILESYSTEMFMTINT;186 typedef RTFILESYSTEMEXT *PRTFILESYSTEMEXT; 186 187 187 188 /******************************************************************************* … … 196 197 * @param iBlkGrp Block group number to load. 197 198 */ 198 static int rtF ilesystemExtLoadBlkGrpDesc(PRTFILESYSTEMFMTINT pThis, uint32_t iBlkGrp)199 static int rtFsExtLoadBlkGrpDesc(PRTFILESYSTEMEXT pThis, uint32_t iBlkGrp) 199 200 { 200 201 int rc = VINF_SUCCESS; 201 PRTFILESYSTEM FMTEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc;202 PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc = pThis->pBlkGrpDesc; 202 203 uint64_t offRead = (pThis->iSbBlock + 1) * pThis->cbBlock; 203 204 BlockGroupDesc BlkDesc; … … 210 211 if (!pBlkGrpDesc) 211 212 { 212 size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEM FMTEXTBLKGRP, abBlockBitmap[cbBlockBitmap]);213 pBlkGrpDesc = (PRTFILESYSTEM FMTEXTBLKGRP)RTMemAllocZ(cbBlkDesc);213 size_t cbBlkDesc = RT_OFFSETOF(RTFILESYSTEMEXTBLKGRP, abBlockBitmap[cbBlockBitmap]); 214 pBlkGrpDesc = (PRTFILESYSTEMEXTBLKGRP)RTMemAllocZ(cbBlkDesc); 214 215 if (!pBlkGrpDesc) 215 216 return VERR_NO_MEMORY; 216 217 } 217 218 218 rc = rtFilesystemMediumRead(pThis->hMedium, offRead, &BlkDesc, sizeof(BlkDesc));219 rc = RTVfsFileReadAt(pThis->hVfsFile, offRead, &BlkDesc, sizeof(BlkDesc), NULL); 219 220 if (RT_SUCCESS(rc)) 220 221 { 221 222 pBlkGrpDesc->offStart = pThis->iSbBlock + (uint64_t)iBlkGrp * pThis->cBlocksPerGroup * pThis->cbBlock; 222 223 pBlkGrpDesc->offLast = pBlkGrpDesc->offStart + pThis->cBlocksPerGroup * pThis->cbBlock; 223 rc = rtFilesystemMediumRead(pThis->hMedium, BlkDesc.offBlockBitmap * pThis->cbBlock,224 &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap);224 rc = RTVfsFileReadAt(pThis->hVfsFile, BlkDesc.offBlockBitmap * pThis->cbBlock, 225 &pBlkGrpDesc->abBlockBitmap[0], cbBlockBitmap, NULL); 225 226 } 226 227 … … 230 231 } 231 232 232 static DECLCALLBACK(int) rtFilesystemExtProbe(RTFILESYSTEMMEDIUM hMedium, uint32_t *puScore) 233 static bool rtFsExtIsBlockRangeInUse(PRTFILESYSTEMEXTBLKGRP pBlkGrpDesc, 234 uint32_t offBlockStart, uint32_t cBlocks) 235 { 236 bool fUsed = false; 237 238 while (cBlocks) 239 { 240 uint32_t idxByte = offBlockStart / 8; 241 uint32_t iBit = offBlockStart % 8; 242 243 if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit)) 244 { 245 fUsed = true; 246 break; 247 } 248 249 cBlocks--; 250 offBlockStart++; 251 } 252 253 return fUsed; 254 } 255 256 257 static DECLCALLBACK(int) rtFsExtProbe(RTVFSFILE hVfsFile, uint32_t *puScore) 233 258 { 234 259 int rc = VINF_SUCCESS; 235 uint64_t cbMedium = rtFilesystemMediumGetSize(hMedium);260 uint64_t cbMedium = 0; 236 261 237 262 *puScore = RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED; 238 263 239 if (cbMedium >= 2*sizeof(ExtSuperBlock)) 240 { 241 ExtSuperBlock SuperBlock; 242 243 rc = rtFilesystemMediumRead(hMedium, 1024, &SuperBlock, sizeof(ExtSuperBlock)); 244 if (RT_SUCCESS(rc)) 264 rc = RTVfsFileGetSize(hVfsFile, &cbMedium); 265 if (RT_SUCCESS(rc)) 266 { 267 if (cbMedium >= 2*sizeof(ExtSuperBlock)) 245 268 { 269 ExtSuperBlock SuperBlock; 270 271 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL); 272 if (RT_SUCCESS(rc)) 273 { 246 274 #if defined(RT_BIGENDIAN) 247 /** @todo: Convert to host endianess. */275 /** @todo: Convert to host endianess. */ 248 276 #endif 249 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE) 250 *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED; 277 if (SuperBlock.u16Signature == RTFILESYSTEM_EXT2_SIGNATURE) 278 *puScore = RTFILESYSTEM_MATCH_SCORE_SUPPORTED; 279 } 251 280 } 252 281 } … … 255 284 } 256 285 257 static DECLCALLBACK(int) rtF ilesystemExtOpen(RTFILESYSTEMMEDIUM hMedium, PRTFILESYSTEMFMT phFsFmt)286 static DECLCALLBACK(int) rtFsExtInit(void *pvThis, RTVFSFILE hVfsFile) 258 287 { 259 288 int rc = VINF_SUCCESS; 260 PRTFILESYSTEM FMTINT pThis;289 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis; 261 290 ExtSuperBlock SuperBlock; 262 291 263 pThis = (PRTFILESYSTEMFMTINT)RTMemAllocZ(sizeof(RTFILESYSTEMFMTINT)); 264 if (!pThis) 265 return VERR_NO_MEMORY; 266 267 pThis->hMedium = hMedium; 292 pThis->hVfsFile = hVfsFile; 268 293 pThis->pBlkGrpDesc = NULL; 269 294 270 rc = rtFilesystemMediumRead(hMedium, 1024, &SuperBlock, sizeof(ExtSuperBlock));295 rc = RTVfsFileReadAt(hVfsFile, 1024, &SuperBlock, sizeof(ExtSuperBlock), NULL); 271 296 if (RT_SUCCESS(rc)) 272 297 { … … 284 309 285 310 /* Load first block group descriptor. */ 286 rc = rtF ilesystemExtLoadBlkGrpDesc(pThis, 0);311 rc = rtFsExtLoadBlkGrpDesc(pThis, 0); 287 312 } 288 313 } 289 314 290 if (RT_SUCCESS(rc))291 *phFsFmt = pThis;292 else293 {294 if (pThis->pBlkGrpDesc)295 RTMemFree(pThis->pBlkGrpDesc);296 RTMemFree(pThis);297 }298 299 315 return rc; 300 316 } 301 317 302 static DECLCALLBACK( int) rtFilesystemExtClose(RTFILESYSTEMFMT hFsFmt)303 { 304 PRTFILESYSTEM FMTINT pThis = hFsFmt;318 static DECLCALLBACK(void) rtFsExtDestroy(void *pvThis) 319 { 320 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis; 305 321 306 322 if (pThis->pBlkGrpDesc) 307 323 RTMemFree(pThis->pBlkGrpDesc); 308 RTMemFree(pThis); 309 310 return VINF_SUCCESS; 311 } 312 313 static DECLCALLBACK(uint64_t) rtFilesystemExtGetBlockSize(RTFILESYSTEMFMT hFsFmt) 314 { 315 PRTFILESYSTEMFMTINT pThis = hFsFmt; 316 317 return pThis->cbBlock; 318 } 319 320 static bool rtFilesystemExtIsBlockRangeInUse(PRTFILESYSTEMFMTEXTBLKGRP pBlkGrpDesc, 321 uint32_t offBlockStart, 322 uint32_t cBlocks) 323 { 324 bool fUsed = false; 325 326 while (cBlocks) 327 { 328 uint32_t idxByte = offBlockStart / 8; 329 uint32_t iBit = offBlockStart % 8; 330 331 if (pBlkGrpDesc->abBlockBitmap[idxByte] & RT_BIT(iBit)) 332 { 333 fUsed = true; 334 break; 335 } 336 337 cBlocks--; 338 offBlockStart++; 339 } 340 341 return fUsed; 342 } 343 344 static DECLCALLBACK(int) rtFilesystemExtQueryRangeUse(RTFILESYSTEMFMT hFsFmt, uint64_t offStart, 345 size_t cb, bool *pfUsed) 324 } 325 326 static DECLCALLBACK(int) rtFsExtOpenRoot(void *pvThis, PRTVFSDIR phVfsDir) 327 { 328 return VERR_NOT_IMPLEMENTED; 329 } 330 331 static DECLCALLBACK(int) rtFsExtIsRangeInUse(void *pvThis, RTFOFF off, size_t cb, 332 bool *pfUsed) 346 333 { 347 334 int rc = VINF_SUCCESS; 348 PRTFILESYSTEMFMTINT pThis = hFsFmt; 335 uint64_t offStart = (uint64_t)off; 336 PRTFILESYSTEMEXT pThis = (PRTFILESYSTEMEXT)pvThis; 337 338 *pfUsed = false; 349 339 350 340 while (cb > 0) … … 360 350 { 361 351 /* Load new block descriptor. */ 362 rc = rtF ilesystemExtLoadBlkGrpDesc(pThis, iBlockGroup);352 rc = rtFsExtLoadBlkGrpDesc(pThis, iBlockGroup); 363 353 if (RT_FAILURE(rc)) 364 354 break; … … 366 356 367 357 cbThis = RT_MIN(cb, pThis->pBlkGrpDesc->offLast - offStart + 1); 368 fUsed = rtFilesystemExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart, 369 cbThis / pThis->cbBlock + 370 cbThis % pThis->cbBlock 371 ? 1 372 : 0); 358 fUsed = rtFsExtIsBlockRangeInUse(pThis->pBlkGrpDesc, offBlockRelStart, 359 cbThis / pThis->cbBlock + 360 (cbThis % pThis->cbBlock ? 1 : 0)); 373 361 374 362 if (fUsed) … … 378 366 } 379 367 380 cb -= cbThis;368 cb -= cbThis; 381 369 offStart += cbThis; 382 370 } … … 385 373 } 386 374 387 RTFILESYSTEMFMTOPS g_rtFilesystemFmtExt = 388 { 389 /* pcszFmt */ 390 "EXT", 391 /* pfnProbe */ 392 rtFilesystemExtProbe, 393 /* pfnOpen */ 394 rtFilesystemExtOpen, 395 /* pfnClose */ 396 rtFilesystemExtClose, 397 /* pfnGetBlockSize */ 398 rtFilesystemExtGetBlockSize, 399 /* pfnQueryRangeUse */ 400 rtFilesystemExtQueryRangeUse 375 DECL_HIDDEN_CONST(RTFILESYSTEMDESC) const g_rtFsExt = 376 { 377 /** cbFs */ 378 sizeof(RTFILESYSTEMEXT), 379 /** VfsOps */ 380 { 381 /** uVersion. */ 382 RTVFSOPS_VERSION, 383 /** fFeatures */ 384 0, 385 /** pszName */ 386 "ExtVfsOps", 387 /** pfnDestroy */ 388 rtFsExtDestroy, 389 /** pfnOpenRoot */ 390 rtFsExtOpenRoot, 391 /** pfnIsRangeInUse */ 392 rtFsExtIsRangeInUse, 393 /** uEndMarker */ 394 RTVFSOPS_VERSION 395 }, 396 /** pfnProbe */ 397 rtFsExtProbe, 398 /** pfnInit */ 399 rtFsExtInit 401 400 }; 402 401 -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r39083 r41549 1580 1580 1581 1581 /* 1582 * F I L E S Y S T E M R O O T 1583 * F I L E S Y S T E M R O O T 1584 * F I L E S Y S T E M R O O T 1585 */ 1586 1587 1588 RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 1589 PRTVFS phVfs, void **ppvInstance) 1590 { 1591 /* 1592 * Validate the input, be extra strict in strict builds. 1593 */ 1594 AssertPtr(pVfsOps); 1595 AssertReturn(pVfsOps->uVersion == RTVFSOPS_VERSION, VERR_VERSION_MISMATCH); 1596 AssertReturn(pVfsOps->uEndMarker == RTVFSOPS_VERSION, VERR_VERSION_MISMATCH); 1597 Assert(cbInstance > 0); 1598 AssertPtr(ppvInstance); 1599 AssertPtr(phVfs); 1600 1601 /* 1602 * Allocate the handle + instance data. 1603 */ 1604 size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSINTERNAL), RTVFS_INST_ALIGNMENT) 1605 + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT); 1606 RTVFSINTERNAL *pThis = (RTVFSINTERNAL *)RTMemAllocZ(cbThis); 1607 if (!pThis) 1608 return VERR_NO_MEMORY; 1609 1610 int rc = rtVfsObjInitNewObject(&pThis->Base, NULL, hVfs, hLock, 1611 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1612 if (RT_FAILURE(rc)) 1613 { 1614 RTMemFree(pThis); 1615 return rc; 1616 } 1617 1618 pThis->uMagic = RTVFS_MAGIC; 1619 pThis->pOps = pVfsOps; 1620 1621 *phVfs = pThis; 1622 *ppvInstance = pThis->Base.pvThis; 1623 return VINF_SUCCESS; 1624 } 1625 1626 1627 RTDECL(uint32_t) RTVfsRetain(RTVFS hVfs) 1628 { 1629 RTVFSINTERNAL *pThis = hVfs; 1630 AssertPtrReturn(pThis, UINT32_MAX); 1631 AssertReturn(pThis->uMagic == RTVFS_MAGIC, UINT32_MAX); 1632 return rtVfsObjRetain(&pThis->Base); 1633 } 1634 1635 1636 RTDECL(uint32_t) RTVfsRelease(RTVFS hVfs) 1637 { 1638 RTVFSINTERNAL *pThis = hVfs; 1639 if (pThis == NIL_RTVFS) 1640 return 0; 1641 AssertPtrReturn(pThis, UINT32_MAX); 1642 AssertReturn(pThis->uMagic == RTVFS_MAGIC, UINT32_MAX); 1643 return rtVfsObjRelease(&pThis->Base); 1644 } 1645 1646 1647 RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, 1648 bool *pfUsed) 1649 { 1650 RTVFSINTERNAL *pThis = hVfs; 1651 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1652 AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1653 1654 RTVfsLockAcquireWrite(pThis->Base.hLock); 1655 int rc = pThis->pOps->pfnIsRangeInUse(pThis->Base.pvThis, off, cb, pfUsed); 1656 RTVfsLockReleaseWrite(pThis->Base.hLock); 1657 1658 return rc; 1659 } 1660 1661 1662 /* 1582 1663 * 1583 1664 * F I L E S Y S T E M S T R E A M … … 1986 2067 1987 2068 2069 RTDECL(int) RTVfsIoStrmReadAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, void *pvBuf, size_t cbToRead, 2070 bool fBlocking, size_t *pcbRead) 2071 { 2072 AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER); 2073 if (pcbRead) 2074 *pcbRead = 0; 2075 RTVFSIOSTREAMINTERNAL *pThis = hVfsIos; 2076 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2077 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE); 2078 AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER); 2079 AssertReturn(pThis->fFlags & RTFILE_O_READ, VERR_ACCESS_DENIED); 2080 2081 RTSGSEG Seg = { pvBuf, cbToRead }; 2082 RTSGBUF SgBuf; 2083 RTSgBufInit(&SgBuf, &Seg, 1); 2084 2085 RTVfsLockAcquireWrite(pThis->Base.hLock); 2086 int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbRead); 2087 RTVfsLockReleaseWrite(pThis->Base.hLock); 2088 return rc; 2089 } 2090 2091 1988 2092 RTDECL(int) RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten) 1989 2093 { … … 2003 2107 RTVfsLockAcquireWrite(pThis->Base.hLock); 2004 2108 int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, &SgBuf, fBlocking, pcbWritten); 2109 RTVfsLockReleaseWrite(pThis->Base.hLock); 2110 return rc; 2111 } 2112 2113 2114 RTDECL(int) RTVfsIoStrmWriteAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, const void *pvBuf, size_t cbToWrite, 2115 bool fBlocking, size_t *pcbWritten) 2116 { 2117 AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER); 2118 if (pcbWritten) 2119 *pcbWritten = 0; 2120 RTVFSIOSTREAMINTERNAL *pThis = hVfsIos; 2121 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2122 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE); 2123 AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER); 2124 AssertReturn(pThis->fFlags & RTFILE_O_WRITE, VERR_ACCESS_DENIED); 2125 2126 RTSGSEG Seg = { (void *)pvBuf, cbToWrite }; 2127 RTSGBUF SgBuf; 2128 RTSgBufInit(&SgBuf, &Seg, 1); 2129 2130 RTVfsLockAcquireWrite(pThis->Base.hLock); 2131 int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbWritten); 2005 2132 RTVfsLockReleaseWrite(pThis->Base.hLock); 2006 2133 return rc; … … 2420 2547 2421 2548 2422 /// @todo RTDECL(int) RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten); 2423 /// @todo RTDECL(int) RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead); 2549 RTDECL(int) RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten) 2550 { 2551 AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER); 2552 if (pcbWritten) 2553 *pcbWritten = 0; 2554 RTVFSFILEINTERNAL *pThis = hVfsFile; 2555 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2556 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE); 2557 2558 int rc = RTVfsFileSeek(hVfsFile, off, RTFILE_SEEK_BEGIN, NULL); 2559 if (RT_SUCCESS(rc)) 2560 rc = RTVfsIoStrmWriteAt(&pThis->Stream, off, pvBuf, cbToWrite, true /*fBlocking*/, pcbWritten); 2561 2562 return rc; 2563 } 2564 2565 2566 RTDECL(int) RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead) 2567 { 2568 AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER); 2569 if (pcbRead) 2570 *pcbRead = 0; 2571 RTVFSFILEINTERNAL *pThis = hVfsFile; 2572 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2573 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE); 2574 2575 int rc = RTVfsFileSeek(hVfsFile, off, RTFILE_SEEK_BEGIN, NULL); 2576 if (RT_SUCCESS(rc)) 2577 rc = RTVfsIoStrmReadAt(&pThis->Stream, off, pvBuf, cbToRead, true /*fBlocking*/, pcbRead); 2578 2579 return rc; 2580 } 2424 2581 2425 2582 … … 2475 2632 return rc; 2476 2633 } 2634 2635 2636 RTDECL(int) RTVfsFileGetSize(RTVFSFILE hVfsFile, uint64_t *pcbSize) 2637 { 2638 RTVFSFILEINTERNAL *pThis = hVfsFile; 2639 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2640 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, VERR_INVALID_HANDLE); 2641 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); 2642 2643 RTVfsLockAcquireWrite(pThis->Stream.Base.hLock); 2644 int rc = pThis->pOps->pfnQuerySize(pThis->Stream.Base.pvThis, pcbSize); 2645 RTVfsLockReleaseWrite(pThis->Stream.Base.hLock); 2646 2647 return rc; 2648 } -
trunk/src/VBox/Runtime/include/internal/dvm.h
r40137 r41549 122 122 123 123 /** 124 * Returns whether the given range is in use by the volume manager. 125 * 126 * @returns IPRT status code. 127 * @param hVolMgrFmt The format specific volume manager handle. 128 * @param offStart Start offset of the range. 129 * @param cbRange Size of the range to check in bytes. 130 * @param pfUsed Where to store whether the range is in use by the 131 * volume manager. 132 */ 133 DECLCALLBACKMEMBER(int, pfnQueryRangeUse)(RTDVMFMT hVolMgrFmt, 134 uint64_t off, uint64_t cbRange, 135 bool *pfUsed); 136 137 /** 124 138 * Gets the number of valid volumes in the map. 125 139 * -
trunk/src/VBox/Runtime/include/internal/filesystem.h
r40029 r41549 31 31 #include <iprt/err.h> 32 32 #include <iprt/assert.h> 33 #include <iprt/vfslowlevel.h> 33 34 #include "internal/magics.h" 34 35 35 36 RT_C_DECLS_BEGIN 36 37 37 /** A filesystem format handle. */ 38 typedef struct RTFILESYSTEMFMTINT *RTFILESYSTEMFMT; 39 /** Pointer to a filesystem format handle. */ 40 typedef RTFILESYSTEMFMT *PRTFILESYSTEMFMT; 41 /** NIL filesystem format handle. */ 42 #define NIL_RTFILESYSTEMFMT ((RTFILESYSTEMFMT)~0) 38 /******************************************************************************* 39 * Structures and Typedefs * 40 *******************************************************************************/ 43 41 44 /** A medium handle. */45 typedef struct RTFILESYSTEMMEDIUMINT *RTFILESYSTEMMEDIUM;46 /** Pointer to a medium handle. */47 typedef RTFILESYSTEMMEDIUM *PRTFILESYSTEMMEDIUM;42 /** Filesystem format specific initialization structure. */ 43 typedef DECLCALLBACK(int) FNRTFILESYSTEMINIT(void *pvThis, RTVFSFILE hVfsFile); 44 /** Pointer to a format specific initialization structure. */ 45 typedef FNRTFILESYSTEMINIT *PFNRTFILESYSTEMINIT; 48 46 49 /** Score to indicate that the backend can't handle the format at all */50 47 #define RTFILESYSTEM_MATCH_SCORE_UNSUPPORTED 0 51 /** Score to indicate that a backend supports the format 52 * but there can be other backends. */ 53 #define RTFILESYSTEM_MATCH_SCORE_SUPPORTED (UINT32_MAX/2) 54 /** Score to indicate a perfect match. */ 55 #define RTFILESYSTEM_MATCH_SCORE_PERFECT UINT32_MAX 48 #define RTFILESYSTEM_MATCH_SCORE_SUPPORTED UINT32_MAX 56 49 57 50 /** 58 * Filesystem format operations.51 * Filesystem descriptor. 59 52 */ 60 typedef struct RTFILESYSTEM FMTOPS53 typedef struct RTFILESYSTEMDESC 61 54 { 62 /** Name of the format. */ 63 const char *pcszFmt; 55 /** Size of the filesystem specific state in bytes. */ 56 size_t cbFs; 57 /** Pointer to the VFS vtable. */ 58 RTVFSOPS VfsOps; 64 59 65 60 /** 66 * Probes the given disk for known structures.61 * Probes the underlying for a known filesystem. 67 62 * 68 63 * @returns IPRT status code. 69 * @param h Medium Medium handle.70 * @param puScore 64 * @param hVfsFile VFS file handle of the underlying medium. 65 * @param puScore Where to store the match score on success. 71 66 */ 72 DECLCALLBACKMEMBER(int, pfnProbe) (RTFILESYSTEMMEDIUM hMedium, uint32_t *puScore);67 DECLCALLBACKMEMBER(int, pfnProbe) (RTVFSFILE hVfsFile, uint32_t *puScore); 73 68 74 69 /** 75 * Opens the format to set up all structures.70 * Initializes the given filesystem state. 76 71 * 77 72 * @returns IPRT status code. 78 * @param hMedium Medium handle.79 * @param phFileSysFmt Where to store the filesystem format instance on success.73 * @param pvThis Uninitialized filesystem state. 74 * @param hVfsFile VFS file handle of the underlying medium. 80 75 */ 81 DECLCALLBACKMEMBER(int, pfn Open)(RTFILESYSTEMMEDIUM hMedium, PRTFILESYSTEMFMT phFsFmt);76 DECLCALLBACKMEMBER(int, pfnInit) (void *pvThis, RTVFSFILE hVfsFile); 82 77 83 /** 84 * Closes the filesystem format. 85 * 86 * @returns IPRT status code. 87 * @param hFsFmt The format specific filesystem handle. 88 */ 89 DECLCALLBACKMEMBER(int, pfnClose)(RTFILESYSTEMFMT hFsFmt); 78 } RTFILESYSTEMDESC; 79 /** Pointer to a filesystem descriptor. */ 80 typedef RTFILESYSTEMDESC *PRTFILESYSTEMDESC; 81 typedef const RTFILESYSTEMDESC *PCRTFILESYSTEMDESC; 90 82 91 /** 92 * Returns block size of the given filesystem. 93 * 94 * @returns Block size of filesystem. 95 * @param hFsFmt The format specific filesystem handle. 96 */ 97 DECLCALLBACKMEMBER(uint64_t, pfnGetBlockSize)(RTFILESYSTEMFMT hFsFmt); 98 99 /** 100 * Query the use of the given range in the filesystem. 101 * 102 * @returns IPRT status code. 103 * @param hFsFmt The format specific filesystem handle. 104 * @param offStart Start offset to check. 105 * @param cb Size of the range to check. 106 * @param pfUsed Where to store whether the range is in use 107 * by the filesystem. 108 */ 109 DECLCALLBACKMEMBER(int, pfnQueryRangeUse)(RTFILESYSTEMFMT hFsFmt, uint64_t offStart, 110 size_t cb, bool *pfUsed); 111 112 } RTFILESYSTEMFMTOPS; 113 /** Pointer to a filesystem format ops table. */ 114 typedef RTFILESYSTEMFMTOPS *PRTFILESYSTEMFMTOPS; 115 /** Pointer to a const filesystem format ops table. */ 116 typedef const RTFILESYSTEMFMTOPS *PCRTFILESYSTEMFMTOPS; 117 118 /** Converts a LBA number to the byte offset. */ 119 #define RTFILESYSTEM_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector) 120 /** Converts a Byte offset to the LBA number. */ 121 #define RTFILESYSTEM_BYTE2LBA(off, disk) ((off) / (disk)->cbSector) 122 123 /** 124 * Return size of the medium in bytes. 125 * 126 * @returns Size of the medium in bytes. 127 * @param hMedium The medium handle. 128 */ 129 DECLHIDDEN(uint64_t) rtFilesystemMediumGetSize(RTFILESYSTEMMEDIUM hMedium); 130 131 /** 132 * Read from the medium at the given offset. 133 * 134 * @returns IPRT status code. 135 * @param hMedium The medium handle to read from. 136 * @param off Start offset. 137 * @param pvBuf Destination buffer. 138 * @param cbRead How much to read. 139 */ 140 DECLHIDDEN(int) rtFilesystemMediumRead(RTFILESYSTEMMEDIUM hMedium, uint64_t off, 141 void *pvBuf, size_t cbRead); 142 143 /** 144 * Write to the disk at the given offset. 145 * 146 * @returns IPRT status code. 147 * @param hMedium The medium handle to write to. 148 * @param off Start offset. 149 * @param pvBuf Source buffer. 150 * @param cbWrite How much to write. 151 */ 152 DECLHIDDEN(int) rtFilesystemMediumWrite(RTFILESYSTEMMEDIUM hMedium, uint64_t off, 153 const void *pvBuf, size_t cbWrite); 83 extern DECLHIDDEN(RTFILESYSTEMDESC const) g_rtFsExt; 154 84 155 85 RT_C_DECLS_END -
trunk/src/VBox/Runtime/include/internal/magics.h
r40855 r41549 59 59 /** The value of RTFILEAIOREQINT::u32Magic. (Stephen Edwin King) */ 60 60 #define RTFILEAIOREQ_MAGIC UINT32_C(0x19470921) 61 /** The value of RTFILESYSTEMINT::u32Magic. (John Scalzi) */62 #define RTFILESYSTEM_MAGIC UINT32_C(0x19690510)63 /** The value of RTFILESYSTEMINT::u32Magic after close. */64 #define RTFILESYSTEM_MAGIC_DEAD (~RTFILESYSTEM_MAGIC)65 61 /** The value of RTENVINTERNAL::u32Magic. (Rumiko Takahashi) */ 66 62 #define RTENV_MAGIC UINT32_C(0x19571010) -
trunk/src/VBox/Runtime/testcase/tstRTFilesystem.cpp
r40029 r41549 30 30 *******************************************************************************/ 31 31 #include <iprt/filesystem.h> 32 32 #include <iprt/vfs.h> 33 33 #include <iprt/err.h> 34 34 #include <iprt/test.h> … … 41 41 *******************************************************************************/ 42 42 43 static int filesystemDiskRead(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead) 44 { 45 RTFILE hFile = (RTFILE)pvUser; 46 47 return RTFileReadAt(hFile, off, pvBuf, cbRead, NULL); 48 } 49 50 static int filesystemDiskWrite(void *pvUser, uint64_t off, const void *pvBuf, size_t cbWrite) 51 { 52 RTFILE hFile = (RTFILE)pvUser; 53 54 return RTFileWriteAt(hFile, off, pvBuf, cbWrite, NULL); 55 } 56 57 static int tstRTFilesystem(RTTEST hTest, RTFILE hFile, uint64_t cb) 43 static int tstRTFilesystem(RTTEST hTest, RTVFSFILE hVfsFile) 58 44 { 59 45 int rc = VINF_SUCCESS; 46 RTVFS hVfs = NIL_RTVFS; 60 47 61 48 RTTestSubF(hTest, "Create filesystem object"); 62 RTFILESYSTEM hFs; 63 rc = RTFilesystem Open(&hFs, filesystemDiskRead, filesystemDiskWrite, cb, 512, hFile, 0 /* fFlags */);49 50 rc = RTFilesystemVfsFromFile(hVfsFile, &hVfs); 64 51 if (RT_FAILURE(rc)) 65 52 { 66 RTTestIFailed("RTFilesystem Open-> %Rrc", rc);53 RTTestIFailed("RTFilesystemVfsFromFile -> %Rrc", rc); 67 54 return rc; 68 55 } 69 70 RTTestIPrintf(RTTESTLVL_ALWAYS, "Successfully opened filesystem with format: %s.\n",71 RTFilesystemGetFormat(hFs));72 RTTestIPrintf(RTTESTLVL_ALWAYS, "Block size is: %llu.\n",73 RTFilesystemGetBlockSize(hFs));74 56 75 57 /* Check all blocks. */ … … 77 59 uint32_t cBlocksUsed = 0; 78 60 uint32_t cBlocksUnused = 0; 61 uint64_t cbFs = 0; 79 62 80 while (off < cb) 63 rc = RTVfsFileGetSize(hVfsFile, &cbFs); 64 if (RT_FAILURE(rc)) 65 { 66 RTTestIFailed("RTVfsFileGetSize -> %Rrc", rc); 67 return rc; 68 } 69 70 while (off < cbFs) 81 71 { 82 72 bool fUsed = false; 83 73 84 rc = RT FilesystemQueryRangeUse(hFs, off, 1024, &fUsed);74 rc = RTVfsIsRangeInUse(hVfs, off, 1024, &fUsed); 85 75 if (RT_FAILURE(rc)) 86 76 { 87 RTTestIFailed("RT FileSysQueryRangeUse -> %Rrc", rc);77 RTTestIFailed("RTVfsIsRangeInUse -> %Rrc", rc); 88 78 break; 89 79 } … … 101 91 cBlocksUsed, cBlocksUnused); 102 92 103 RT FilesystemRelease(hFs);93 RTVfsRelease(hVfs); 104 94 105 95 return rc; … … 128 118 /* Open image. */ 129 119 RTFILE hFile; 130 uint64_t cb = 0;120 RTVFSFILE hVfsFile; 131 121 rc = RTFileOpen(&hFile, argv[1], RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ); 132 122 if (RT_FAILURE(rc)) … … 136 126 } 137 127 138 rc = RTFileGetSize(hFile, &cb); 139 if ( RT_FAILURE(rc) 140 || cb % 512 != 0) /* Assume 512 byte sector size. */ 128 rc = RTVfsFileFromRTFile(hFile, 0, false, &hVfsFile); 129 if (RT_FAILURE(rc)) 141 130 { 142 RTTestIFailed("RT FileGetSize -> %Rrc", rc);131 RTTestIFailed("RTVfsFileFromRTFile -> %Rrc", rc); 143 132 return RTTestSummaryAndDestroy(hTest); 144 133 } 145 134 146 rc = tstRTFilesystem(hTest, h File, cb);135 rc = tstRTFilesystem(hTest, hVfsFile); 147 136 148 137 RTTESTI_CHECK(rc == VINF_SUCCESS); 138 139 RTVfsFileRelease(hVfsFile); 149 140 150 141 /*
Note:
See TracChangeset
for help on using the changeset viewer.