|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 3/6] Align blkif protocol values to 512B sectors
With the deprecation of feature-large-sector-size, blkif.h now specifies
that all sector amounts in the protocol are in 512B units.
Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
src/xenvbd/frontend.c | 80 +++++++++++++++++++++++++++++--------------
src/xenvbd/frontend.h | 10 +++++-
src/xenvbd/ring.c | 56 ++++++++++++++----------------
src/xenvbd/target.c | 13 +++----
4 files changed, 97 insertions(+), 62 deletions(-)
diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 45a5f49..d8e3287 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -761,7 +761,7 @@ __Size(
__in PXENVBD_DISKINFO Info
)
{
- ULONG64 MBytes = (Info->SectorSize * Info->SectorCount) >>
20; // / (1024 * 1024);
+ ULONG64 MBytes = Info->BlkifSectorCount >> (20 -
BLKIF_SECTOR_SHIFT);
if (MBytes < 10240)
return (ULONG)MBytes;
@@ -773,7 +773,7 @@ __Units(
__in PXENVBD_DISKINFO Info
)
{
- ULONG64 MBytes = (Info->SectorSize * Info->SectorCount) >>
20; // / (1024 * 1024);
+ ULONG64 MBytes = Info->BlkifSectorCount >> (20 -
BLKIF_SECTOR_SHIFT);
if (MBytes < 10240)
return "MB";
@@ -856,46 +856,73 @@ FrontendReadDiskInfo(
)
{
BOOLEAN Changed;
+ PXENVBD_DISKINFO DiskInfo = &Frontend->DiskInfo;
Changed = FrontendReadDiskValue32(Frontend,
"info",
- &Frontend->DiskInfo.DiskInfo);
+ &DiskInfo->DiskInfo);
Changed |= FrontendReadDiskValue32(Frontend,
"sector-size",
- &Frontend->DiskInfo.SectorSize);
+ &DiskInfo->SectorSize);
Changed |= FrontendReadDiskValue32(Frontend,
"physical-sector-size",
- &Frontend->DiskInfo.PhysSectorSize);
+ &DiskInfo->PhysSectorSize);
Changed |= FrontendReadValue64(Frontend,
"sectors",
- &Frontend->DiskInfo.SectorCount);
+ &DiskInfo->BlkifSectorCount);
if (!Changed)
return;
- if (Frontend->DiskInfo.DiskInfo & VDISK_READONLY) {
- Warning("Target[%d] : DiskInfo contains VDISK_READONLY flag!\n",
Frontend->TargetId);
+ if (DiskInfo->DiskInfo & VDISK_READONLY) {
+ Warning("Target[%d] : DiskInfo contains VDISK_READONLY flag!\n",
+ Frontend->TargetId);
}
- if (Frontend->DiskInfo.DiskInfo & VDISK_CDROM) {
- Warning("Target[%d] : DiskInfo contains VDISK_CDROM flag!\n",
Frontend->TargetId);
+ if (DiskInfo->DiskInfo & VDISK_CDROM) {
+ Warning("Target[%d] : DiskInfo contains VDISK_CDROM flag!\n",
+ Frontend->TargetId);
}
- if (Frontend->DiskInfo.SectorSize == 0) {
- Error("Target[%d] : Invalid SectorSize!\n", Frontend->TargetId);
+ if (DiskInfo->SectorSize < BLKIF_SECTOR_SIZE ||
+ (DiskInfo->SectorSize & (DiskInfo->SectorSize - 1)) != 0) {
+ Error("Target[%d] : Invalid SectorSize %lu, defaulting to %u!\n",
+ Frontend->TargetId,
+ DiskInfo->SectorSize,
+ BLKIF_SECTOR_SIZE);
+ DiskInfo->SectorSize = BLKIF_SECTOR_SIZE;
}
- if (Frontend->DiskInfo.SectorCount == 0) {
- Error("Target[%d] : Invalid SectorCount!\n", Frontend->TargetId);
+ // infallible due to check above
+ BitScanForward(&DiskInfo->SectorShift, DiskInfo->SectorSize);
+ DiskInfo->SectorShift -= BLKIF_SECTOR_SHIFT;
+ if (DiskInfo->PhysSectorSize < DiskInfo->SectorSize ||
+ DiskInfo->PhysSectorSize % DiskInfo->SectorSize != 0) {
+ Error("Target[%d] : Invalid PhysSectorSize %lu, defaulting to %lu!\n",
+ Frontend->TargetId,
+ DiskInfo->PhysSectorSize,
+ DiskInfo->SectorSize);
+ DiskInfo->PhysSectorSize = DiskInfo->SectorSize;
}
- if (Frontend->DiskInfo.PhysSectorSize == 0) {
- Frontend->DiskInfo.PhysSectorSize = Frontend->DiskInfo.SectorSize;
+ if (DiskInfo->BlkifSectorCount == 0 ||
+ DiskInfo->BlkifSectorCount % (DiskInfo->PhysSectorSize >>
+ DiskInfo->SectorShift) != 0) {
+ Error("Target[%d] : Invalid BlkifSectorCount %llu!\n",
+ Frontend->TargetId,
+ DiskInfo->BlkifSectorCount);
}
// dump actual values
- Trace("Target[%d] : %lld sectors of %d bytes (%d)\n", Frontend->TargetId,
- Frontend->DiskInfo.SectorCount, Frontend->DiskInfo.SectorSize,
- Frontend->DiskInfo.PhysSectorSize);
- Trace("Target[%d] : %d %s (%08x)\n", Frontend->TargetId,
- __Size(&Frontend->DiskInfo), __Units(&Frontend->DiskInfo),
- Frontend->DiskInfo.DiskInfo);
+ Trace("Target[%d] : %llu %luB blocks, %luB logical sectors (2^%lu), "
+ "%luB physical sectors\n",
+ Frontend->TargetId,
+ DiskInfo->BlkifSectorCount,
+ BLKIF_SECTOR_SIZE,
+ DiskInfo->SectorSize,
+ DiskInfo->SectorShift,
+ DiskInfo->PhysSectorSize);
+ Trace("Target[%d] : %d %s (%08x)\n",
+ Frontend->TargetId,
+ __Size(&Frontend->DiskInfo),
+ __Units(&Frontend->DiskInfo),
+ DiskInfo->DiskInfo);
}
static FORCEINLINE VOID
@@ -1590,9 +1617,12 @@ FrontendDebugCallback(
XENBUS_DEBUG(Printf,
&Frontend->DebugInterface,
- "DiskInfo: %llu @ %u (%u) %08x\n",
- Frontend->DiskInfo.SectorCount,
+ "DiskInfo: %llu %luB blocks, %luB logical sectors (2^%lu), "
+ "%luB physical sectors, info %08x\n",
+ Frontend->DiskInfo.BlkifSectorCount,
+ BLKIF_SECTOR_SIZE,
Frontend->DiskInfo.SectorSize,
+ Frontend->DiskInfo.SectorShift,
Frontend->DiskInfo.PhysSectorSize,
Frontend->DiskInfo.DiskInfo);
}
@@ -1814,7 +1844,7 @@ FrontendCreate(
Frontend->TargetId = TargetId;
Frontend->DeviceId = strtoul(DeviceId, NULL, 10);
Frontend->State = XENVBD_INITIALIZED;
- Frontend->DiskInfo.SectorSize = 512; // default sector size
+ Frontend->DiskInfo.SectorSize = BLKIF_SECTOR_SIZE; // default sector size
Frontend->BackendDomain = DOMID_INVALID;
Frontend->MaxQueues = DriverGetMaxQueues();
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index dc7b55f..3c304f0 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -35,6 +35,10 @@
#include <ntddk.h>
+// This is the fixed size, in bytes, of a sector used in the blkif protocol.
+#define BLKIF_SECTOR_SHIFT 9
+#define BLKIF_SECTOR_SIZE (1U << BLKIF_SECTOR_SHIFT)
+
typedef enum _XENVBD_STATE {
XENVBD_STATE_INVALID,
XENVBD_INITIALIZED, // -> { CLOSED }
@@ -65,8 +69,12 @@ typedef struct _XENVBD_FEATURES {
} XENVBD_FEATURES, *PXENVBD_FEATURES;
typedef struct _XENVBD_DISKINFO {
- ULONG64 SectorCount;
+ // each "sector" here is of size BLKIF_SECTOR_SIZE
+ ULONG64 BlkifSectorCount;
+ // logical sector size as used by Windows for addressing
ULONG SectorSize;
+ // log2(sector size / BLKIF_SECTOR_SIZE)
+ ULONG SectorShift;
ULONG PhysSectorSize;
ULONG DiskInfo;
} XENVBD_DISKINFO, *PXENVBD_DISKINFO;
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 1e8f761..2a4eb56 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -125,6 +125,8 @@ struct _XENVBD_RING {
#define RING_POOL_TAG 'gnRX'
#define XEN_IO_PROTO_ABI "x86_64-abi"
+#define SECTORS_PER_PAGE ((ULONG)(PAGE_SIZE / BLKIF_SECTOR_SIZE))
+
static FORCEINLINE PVOID
__RingAllocate(
IN ULONG Length
@@ -181,15 +183,6 @@ __StatName(
}
}
-static FORCEINLINE ULONG
-__SectorsPerPage(
- IN ULONG SectorSize
- )
-{
- ASSERT3U(SectorSize, != , 0);
- return PAGE_SIZE / SectorSize;
-}
-
static FORCEINLINE VOID
__Operation(
IN UCHAR CdbOp,
@@ -213,7 +206,6 @@ __Operation(
static FORCEINLINE ULONG
__UseIndirect(
- IN ULONG SectorsPerPage,
IN ULONG MaxIndirectSegs,
IN ULONG SectorsLeft
)
@@ -221,7 +213,7 @@ __UseIndirect(
if (MaxIndirectSegs <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
return BLKIF_MAX_SEGMENTS_PER_REQUEST; // not supported
- if (SectorsLeft < BLKIF_MAX_SEGMENTS_PER_REQUEST * SectorsPerPage)
+ if (SectorsLeft < BLKIF_MAX_SEGMENTS_PER_REQUEST * SECTORS_PER_PAGE)
return BLKIF_MAX_SEGMENTS_PER_REQUEST; // first into a single
BLKIF_OP_{READ/WRITE}
return MaxIndirectSegs;
@@ -646,7 +638,6 @@ BlkifRingPrepareSegment(
PXENVBD_ADAPTER Adapter = TargetGetAdapter(Target);
const ULONG SectorSize =
FrontendGetDiskInfo(Ring->Frontend)->SectorSize;
- const ULONG SectorsPerPage = __SectorsPerPage(SectorSize);
Pfn = AdapterGetNextSGEntry(Adapter,
SrbExt,
@@ -658,11 +649,11 @@ BlkifRingPrepareSegment(
InterlockedIncrement(&Ring->Stats[XENVBD_STAT_SEGMENTS_GRANTED]);
// get first sector, last sector and count
- Segment->FirstSector = (UCHAR)((Offset + SectorSize - 1) / SectorSize);
- *SectorsNow = __min(SectorsLeft, SectorsPerPage -
Segment->FirstSector);
+ Segment->FirstSector = (UCHAR)((Offset + BLKIF_SECTOR_SIZE - 1) /
BLKIF_SECTOR_SIZE);
+ *SectorsNow = __min(SectorsLeft, SECTORS_PER_PAGE -
Segment->FirstSector);
Segment->LastSector = (UCHAR)(Segment->FirstSector + *SectorsNow - 1);
- ASSERT3U((Length / SectorSize), == , *SectorsNow);
+ ASSERT3U((Length / BLKIF_SECTOR_SIZE), == , *SectorsNow);
} else {
PXENVBD_BOUNCE Bounce;
PMDL Mdl;
@@ -672,7 +663,7 @@ BlkifRingPrepareSegment(
// get first sector, last sector and count
Segment->FirstSector = 0;
- *SectorsNow = __min(SectorsLeft, SectorsPerPage);
+ *SectorsNow = __min(SectorsLeft, SECTORS_PER_PAGE);
Segment->LastSector = (UCHAR)(*SectorsNow - 1);
Bounce = AdapterGetBounce(Adapter);
@@ -693,7 +684,7 @@ BlkifRingPrepareSegment(
Mdl->ByteOffset = Offset;
Bounce->SourcePfn[0] = Pfn;
- if (Length < *SectorsNow * SectorSize) {
+ if (Length < *SectorsNow * BLKIF_SECTOR_SIZE) {
Pfn = AdapterGetNextSGEntry(Adapter,
SrbExt,
Length,
@@ -705,9 +696,9 @@ BlkifRingPrepareSegment(
}
#pragma warning(pop)
- ASSERT((Mdl->ByteCount & (SectorSize - 1)) == 0);
+ ASSERT((Mdl->ByteCount & (BLKIF_SECTOR_SIZE - 1)) == 0);
ASSERT3U(Mdl->ByteCount, <= , PAGE_SIZE);
- ASSERT3U(*SectorsNow, == , (Mdl->ByteCount / SectorSize));
+ ASSERT3U(*SectorsNow, == , (Mdl->ByteCount / BLKIF_SECTOR_SIZE));
Bounce->SourcePtr = MmMapLockedPagesSpecifyCache(Mdl,
KernelMode,
@@ -753,15 +744,13 @@ BlkifRingPrepareReadWrite(
PXENVBD_RING Ring = BlkifRing->Ring;
PXENVBD_FRONTEND Frontend = Ring->Frontend;
PSCSI_REQUEST_BLOCK Srb = SrbExt->Srb;
- ULONG64 SectorStart = Cdb_LogicalBlock(Srb);
- ULONG SectorsLeft = Cdb_TransferBlock(Srb);
UCHAR Operation;
BOOLEAN ReadOnly;
LIST_ENTRY List;
-
- const ULONG SectorSize =
FrontendGetDiskInfo(Frontend)->SectorSize;
- const ULONG SectorsPerPage = __SectorsPerPage(SectorSize);
const ULONG MaxIndirect =
FrontendGetFeatures(Frontend)->Indirect;
+ const ULONG SectorShift =
FrontendGetDiskInfo(Frontend)->SectorShift;
+ ULONG64 SectorStart = Cdb_LogicalBlock(Srb) << SectorShift;
+ ULONG SectorsLeft = Cdb_TransferBlock(Srb) <<
SectorShift;
InitializeListHead(&List);
@@ -784,9 +773,7 @@ BlkifRingPrepareReadWrite(
Request->SrbExt = SrbExt;
- MaxSegments = __UseIndirect(SectorsPerPage,
- MaxIndirect,
- SectorsLeft);
+ MaxSegments = __UseIndirect(MaxIndirect, SectorsLeft);
Request->Operation = Operation;
Request->NrSegments = 0;
@@ -857,11 +844,14 @@ BlkifRingPrepareUnmap(
IN PXENVBD_SRBEXT SrbExt
)
{
+ PXENVBD_RING Ring = BlkifRing->Ring;
+ PXENVBD_FRONTEND Frontend = Ring->Frontend;
PSCSI_REQUEST_BLOCK Srb = SrbExt->Srb;
PUNMAP_LIST_HEADER Unmap = Srb->DataBuffer;
ULONG Count;
ULONG Index;
LIST_ENTRY List;
+ const ULONG SectorShift =
FrontendGetDiskInfo(Frontend)->SectorShift;
InitializeListHead(&List);
@@ -873,6 +863,8 @@ BlkifRingPrepareUnmap(
for (Index = 0; Index < Count; ++Index) {
PUNMAP_BLOCK_DESCRIPTOR Descr = &Unmap->Descriptors[Index];
PXENVBD_REQUEST Request;
+ ULONG64 FirstSector;
+ ULONG NrSectors;
Request = BlkifRingGetRequest(BlkifRing);
if (Request == NULL)
@@ -880,10 +872,13 @@ BlkifRingPrepareUnmap(
InsertTailList(&List, &Request->ListEntry);
SrbExt->RequestCount++;
+ FirstSector = _byteswap_uint64(*(PULONG64)Descr->StartingLba) <<
SectorShift;
+ NrSectors = _byteswap_ulong(*(PULONG)Descr->LbaCount) << SectorShift;
+
Request->SrbExt = SrbExt;
Request->Operation = BLKIF_OP_DISCARD;
- Request->FirstSector = _byteswap_uint64(*(PULONG64)Descr->StartingLba);
- Request->NrSectors = _byteswap_ulong(*(PULONG)Descr->LbaCount);
+ Request->FirstSector = FirstSector;
+ Request->NrSectors = NrSectors;
Request->Flags = 0;
}
@@ -909,6 +904,7 @@ BlkifRingPrepareSyncCache(
PXENVBD_REQUEST Request;
UCHAR Operation;
LIST_ENTRY List;
+ const ULONG SectorShift =
FrontendGetDiskInfo(Frontend)->SectorShift;
InitializeListHead(&List);
Srb->SrbStatus = SRB_STATUS_PENDING;
@@ -928,7 +924,7 @@ BlkifRingPrepareSyncCache(
Request->SrbExt = SrbExt;
Request->Operation = Operation;
- Request->FirstSector = Cdb_LogicalBlock(Srb);
+ Request->FirstSector = Cdb_LogicalBlock(Srb) << SectorShift;
BlkifRingQueueRequests(BlkifRing, &List);
return STATUS_SUCCESS;
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 102e8b8..128ae63 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -218,6 +218,7 @@ TargetReadWrite(
PXENVBD_SRBEXT SrbExt = Srb->SrbExtension;
PXENVBD_FRONTEND Frontend = Target->Frontend;
PXENVBD_RING Ring = FrontendGetRing(Frontend);
+ PXENVBD_DISKINFO DiskInfo = FrontendGetDiskInfo(Target->Frontend);
ULONG64 SectorCount;
ULONG64 SectorStart;
ULONG NumSectors;
@@ -227,14 +228,14 @@ TargetReadWrite(
goto fail1;
// disallow writes to read-only disks
- if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY &&
+ if (DiskInfo->DiskInfo & VDISK_READONLY &&
Cdb_OperationEx(Srb) == SCSIOP_WRITE)
goto fail2;
// check Sectors requested is on the disk
- SectorCount = FrontendGetDiskInfo(Frontend)->SectorCount;
- SectorStart = Cdb_LogicalBlock(Srb);
- NumSectors = Cdb_TransferBlock(Srb);
+ SectorCount = DiskInfo->BlkifSectorCount;
+ SectorStart = Cdb_LogicalBlock(Srb) << DiskInfo->SectorShift;
+ NumSectors = Cdb_TransferBlock(Srb) << DiskInfo->SectorShift;
if (SectorStart >= SectorCount)
goto fail3;
@@ -560,7 +561,7 @@ TargetReadCapacity(
if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0)
goto fail3;
- SectorCount = DiskInfo->SectorCount;
+ SectorCount = DiskInfo->BlkifSectorCount >> DiskInfo->SectorShift;
SectorSize = DiskInfo->SectorSize;
if (SectorCount == (ULONG)SectorCount)
@@ -611,7 +612,7 @@ TargetReadCapacity16(
if (Cdb_PMI(Srb) == 0 && Cdb_LogicalBlock(Srb) != 0)
goto fail3;
- SectorCount = DiskInfo->SectorCount;
+ SectorCount = DiskInfo->BlkifSectorCount >> DiskInfo->SectorShift;
SectorSize = DiskInfo->SectorSize;
PhysSectorSize = DiskInfo->PhysSectorSize;
--
2.54.0.windows.1
--
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |