Changeset 15786 in vbox for trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
- Timestamp:
- Jan 5, 2009 12:43:36 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r15785 r15786 1070 1070 { 1071 1071 rc = VERR_VD_IMAGE_READ_ONLY; 1072 goto out fail;1072 goto out; 1073 1073 } 1074 1074 … … 1076 1076 { 1077 1077 rc = VERR_INVALID_PARAMETER; 1078 goto out fail;1078 goto out; 1079 1079 } 1080 1080 … … 1091 1091 Assert(!(cbToWrite % 512)); 1092 1092 1093 if (!IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock])) 1094 { 1095 /* Block is either free or zero. */ 1096 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_ZEROES) 1097 && ( pImage->paBlocks[uBlock] == VDI_IMAGE_BLOCK_ZERO 1098 || cbToWrite == getImageBlockSize(&pImage->Header))) 1099 { 1100 /* If the destination block is unallocated at this point, it's 1101 * either a zero block or a block which hasn't been used so far 1102 * (which also means that it's a zero block. Don't need to write 1103 * anything to this block if the data consists of just zeroes. */ 1104 Assert(!(cbToWrite % 4)); 1105 Assert(cbToWrite * 8 <= UINT32_MAX); 1106 if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)cbToWrite * 8) == -1) 1093 do 1094 { 1095 if (!IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock])) 1096 { 1097 /* Block is either free or zero. */ 1098 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_ZEROES) 1099 && ( pImage->paBlocks[uBlock] == VDI_IMAGE_BLOCK_ZERO 1100 || cbToWrite == getImageBlockSize(&pImage->Header))) 1107 1101 { 1108 pImage->paBlocks[uBlock] = VDI_IMAGE_BLOCK_ZERO; 1109 goto out; 1102 /* If the destination block is unallocated at this point, it's 1103 * either a zero block or a block which hasn't been used so far 1104 * (which also means that it's a zero block. Don't need to write 1105 * anything to this block if the data consists of just zeroes. */ 1106 Assert(!(cbToWrite % 4)); 1107 Assert(cbToWrite * 8 <= UINT32_MAX); 1108 if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)cbToWrite * 8) == -1) 1109 { 1110 pImage->paBlocks[uBlock] = VDI_IMAGE_BLOCK_ZERO; 1111 break; 1112 } 1110 1113 } 1111 } 1112 1113 if (cbToWrite == getImageBlockSize(&pImage->Header)) 1114 { 1115 /* Full block write to previously unallocated block. 1116 * Allocate block and write data. */ 1117 Assert(!offWrite); 1118 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 1119 uint64_t u64Offset = (uint64_t)cBlocksAllocated * pImage->cbTotalBlockData 1120 + (pImage->offStartData + pImage->offStartBlockData); 1114 1115 if (cbToWrite == getImageBlockSize(&pImage->Header)) 1116 { 1117 /* Full block write to previously unallocated block. 1118 * Allocate block and write data. */ 1119 Assert(!offWrite); 1120 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 1121 uint64_t u64Offset = (uint64_t)cBlocksAllocated * pImage->cbTotalBlockData 1122 + (pImage->offStartData + pImage->offStartBlockData); 1123 rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL); 1124 if (RT_FAILURE(rc)) 1125 goto out; 1126 pImage->paBlocks[uBlock] = cBlocksAllocated; 1127 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1); 1128 1129 rc = vdiUpdateBlockInfo(pImage, uBlock); 1130 if (RT_FAILURE(rc)) 1131 goto out; 1132 1133 *pcbPreRead = 0; 1134 *pcbPostRead = 0; 1135 } 1136 else 1137 { 1138 /* Trying to do a partial write to an unallocated block. Don't do 1139 * anything except letting the upper layer know what to do. */ 1140 *pcbPreRead = offWrite % getImageBlockSize(&pImage->Header); 1141 *pcbPostRead = getImageBlockSize(&pImage->Header) - cbToWrite - *pcbPreRead; 1142 rc = VERR_VD_BLOCK_FREE; 1143 } 1144 } 1145 else 1146 { 1147 /* Block present in image file, write relevant data. */ 1148 uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData 1149 + (pImage->offStartData + pImage->offStartBlockData + offWrite); 1121 1150 rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL); 1122 if (RT_FAILURE(rc)) 1123 goto outfail; 1124 pImage->paBlocks[uBlock] = cBlocksAllocated; 1125 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1); 1126 1127 rc = vdiUpdateBlockInfo(pImage, uBlock); 1128 if (RT_FAILURE(rc)) 1129 goto outfail; 1130 1131 *pcbPreRead = 0; 1132 *pcbPostRead = 0; 1133 } 1134 else 1135 { 1136 /* Trying to do a partial write to an unallocated block. Don't do 1137 * anything except letting the upper layer know what to do. */ 1138 *pcbPreRead = offWrite % getImageBlockSize(&pImage->Header); 1139 *pcbPostRead = getImageBlockSize(&pImage->Header) - cbToWrite - *pcbPreRead; 1140 rc = VERR_VD_BLOCK_FREE; 1141 } 1142 } 1143 else 1144 { 1145 /* Block present in image file, write relevant data. */ 1146 uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData 1147 + (pImage->offStartData + pImage->offStartBlockData + offWrite); 1148 rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL); 1149 } 1150 1151 out: 1151 } 1152 } while (0); 1153 1152 1154 if (pcbWriteProcess) 1153 1155 *pcbWriteProcess = cbToWrite; 1154 1156 1155 out fail:1157 out: 1156 1158 LogFlowFunc(("returns %Rrc\n", rc)); 1157 1159 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.