Skip to content

Commit

Permalink
Enable >=16TB (up to 7 exa byte) zvol creation (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
imtiazdc authored Apr 14, 2020
1 parent 6f81efa commit 271ea63
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 15 deletions.
6 changes: 6 additions & 0 deletions ZFSin/zfs/include/sys/wzvol.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ ScsiOpReadCapacity(
IN PSCSI_REQUEST_BLOCK Srb
);

UCHAR
ScsiOpReadCapacity16(
IN pHW_HBA_EXT DevExt,
IN PSCSI_REQUEST_BLOCK Srb
);

UCHAR
ScsiOpRead(
IN pHW_HBA_EXT DevExt,
Expand Down
73 changes: 58 additions & 15 deletions ZFSin/zfs/module/zfs/zfs_windows_zvol_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,17 @@ ScsiExecuteMain(
status = ScsiOpReadCapacity(pHBAExt, pSrb);
break;

case SCSIOP_READ_CAPACITY16:
status = ScsiOpReadCapacity16(pHBAExt, pSrb);
break;

case SCSIOP_READ:
case SCSIOP_READ16:
status = ScsiOpRead(pHBAExt, pSrb, pResult);
break;

case SCSIOP_WRITE:
case SCSIOP_WRITE16:
status = ScsiOpWrite(pHBAExt, pSrb, pResult);
break;

Expand Down Expand Up @@ -460,21 +466,49 @@ ScsiOpReadCapacity(
//blockSize = MP_BLOCK_SIZE;
blockSize = zv->zv_volblocksize;

readCapacity->BytesPerBlock =
(((PUCHAR)&blockSize)[0] << 24) | (((PUCHAR)&blockSize)[1] << 16) |
(((PUCHAR)&blockSize)[2] << 8) | ((PUCHAR)&blockSize)[3];

maxBlocks = zv->zv_volsize / blockSize;
if ((zv->zv_volsize / blockSize) > ULONG_MAX)
maxBlocks = ULONG_MAX;
else
maxBlocks = (zv->zv_volsize / blockSize) - 1;

dprintf("Block Size: 0x%x Total Blocks: 0x%x\n", blockSize, maxBlocks);

readCapacity->LogicalBlockAddress =
(((PUCHAR)&maxBlocks)[0] << 24) | (((PUCHAR)&maxBlocks)[1] << 16) |
(((PUCHAR)&maxBlocks)[2] << 8) | ((PUCHAR)&maxBlocks)[3];
REVERSE_BYTES(&readCapacity->BytesPerBlock, &blockSize);
REVERSE_BYTES(&readCapacity->LogicalBlockAddress, &maxBlocks);

return SRB_STATUS_SUCCESS;
} // End ScsiOpReadCapacity.

/**************************************************************************************************/
/* */
/**************************************************************************************************/
UCHAR
ScsiOpReadCapacity16(
__in pHW_HBA_EXT pHBAExt,
__in PSCSI_REQUEST_BLOCK pSrb
)
{
PREAD_CAPACITY16_DATA readCapacity = pSrb->DataBuffer;
ULONGLONG maxBlocks = 0;
ULONG blockSize = 0;
UNREFERENCED_PARAMETER(pHBAExt);

zvol_state_t * zv = wzvol_find_target(pSrb->TargetId, pSrb->Lun);
if (NULL == zv) {
dprintf("Unable to get zv context for device %d:%d:%d\n",
pSrb->PathId, pSrb->TargetId, pSrb->Lun);
pSrb->DataTransferLength = 0;
return SRB_STATUS_NO_DEVICE;
}
RtlZeroMemory((PUCHAR)pSrb->DataBuffer, pSrb->DataTransferLength);
blockSize = zv->zv_volblocksize;
maxBlocks = (zv->zv_volsize / blockSize) - 1;

dprintf("Block Size: 0x%x Total Blocks: 0x%llx\n", blockSize, maxBlocks);
REVERSE_BYTES(&readCapacity->BytesPerBlock, &blockSize);
REVERSE_BYTES_QUAD(&readCapacity->LogicalBlockAddress.QuadPart, &maxBlocks);
return SRB_STATUS_SUCCESS;
}

/**************************************************************************************************/
/* */
/**************************************************************************************************/
Expand Down Expand Up @@ -644,7 +678,7 @@ wzvol_WkRtn(__in PVOID pWkParms) // Parm list pointer.
PSCSI_REQUEST_BLOCK pSrb = pWkRtnParms->pSrb;
PCDB pCdb = (PCDB)pSrb->Cdb;
PHW_SRB_EXTENSION pSrbExt = (PHW_SRB_EXTENSION)pSrb->SrbExtension;
ULONGLONG startingSector, sectorOffset;
ULONGLONG startingSector=0ULL, sectorOffset=0ULL;
ULONG lclStatus;
UCHAR status;

Expand All @@ -667,14 +701,23 @@ wzvol_WkRtn(__in PVOID pWkParms) // Parm list pointer.
goto Done;
}

startingSector = pCdb->CDB10.LogicalBlockByte3 |
pCdb->CDB10.LogicalBlockByte2 << 8 |
pCdb->CDB10.LogicalBlockByte1 << 16 |
pCdb->CDB10.LogicalBlockByte0 << 24;
if (pSrb->CdbLength == 10) {
startingSector = (ULONG)pCdb->CDB10.LogicalBlockByte3 |
pCdb->CDB10.LogicalBlockByte2 << 8 |
pCdb->CDB10.LogicalBlockByte1 << 16 |
pCdb->CDB10.LogicalBlockByte0 << 24;
}
else if (pSrb->CdbLength == 16) {
REVERSE_BYTES_QUAD(&startingSector, pCdb->CDB16.LogicalBlock);
}
else {
status = SRB_STATUS_ERROR;
goto Done;
}

sectorOffset = startingSector * zv->zv_volblocksize;

dprintf("MpWkRtn Action: %X, starting sector: 0x%X, sector offset: 0x%X\n", pWkRtnParms->Action, startingSector, sectorOffset);
dprintf("MpWkRtn Action: %X, starting sector: 0x%llX, sector offset: 0x%llX\n", pWkRtnParms->Action, startingSector, sectorOffset);
dprintf("MpWkRtn pSrb: 0x%p, pSrb->DataBuffer: 0x%p\n", pSrb, pSrb->DataBuffer);

if (sectorOffset >= zv->zv_volsize) { // Starting sector beyond the bounds?
Expand Down

0 comments on commit 271ea63

Please sign in to comment.