|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 6/6] xencrsh: 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/xencrsh/frontend.c | 25 ++++++----
src/xencrsh/frontend.h | 10 +++-
src/xencrsh/pdo.c | 103 +++++++++++++++++++++++++++--------------
3 files changed, 92 insertions(+), 46 deletions(-)
diff --git a/src/xencrsh/frontend.c b/src/xencrsh/frontend.c
index 32ba1df..0cb4dd6 100644
--- a/src/xencrsh/frontend.c
+++ b/src/xencrsh/frontend.c
@@ -523,22 +523,29 @@ __ReadDiskInfo(
Status = StoreRead(NULL, Frontend->BackendPath,
"sectors", &Buffer);
if (NT_SUCCESS(Status)) {
- Frontend->SectorCount = _strtoui64(Buffer, NULL, 10);
+ Frontend->BlkifSectorCount = _strtoui64(Buffer, NULL, 10);
AustereFree(Buffer);
Updated = TRUE;
}
- if (Frontend->SectorCount == 0) {
- LogError("Invalid SectorCount!\n");
+ if (Frontend->BlkifSectorCount == 0) {
+ LogError("Invalid BlkifSectorCount!\n");
}
- if (Frontend->SectorSize == 0) {
+ if (Frontend->SectorSize < BLKIF_SECTOR_SIZE ||
+ (Frontend->SectorSize & (Frontend->SectorSize - 1)) != 0) {
LogError("Invalid SectorSize!\n");
+ Frontend->SectorSize = BLKIF_SECTOR_SIZE;
}
+ BitScanForward(&Frontend->SectorShift, Frontend->SectorSize);
+ Frontend->SectorShift -= BLKIF_SECTOR_SHIFT;
if (Updated) {
- LogVerbose("DiskInfo: %08x, %lld sectors of %d bytes (%lld KB or %lld
MB)\n",
- Frontend->DiskInfo, Frontend->SectorCount,
Frontend->SectorSize,
- (Frontend->SectorSize * Frontend->SectorCount) / 1024,
- (Frontend->SectorSize * Frontend->SectorCount) / (1024 *
1024));
+ LogVerbose("DiskInfo: %llu %luB blocks, %luB logical sectors (2^%lu), "
+ "info %08x\n",
+ Frontend->BlkifSectorCount,
+ BLKIF_SECTOR_SIZE,
+ Frontend->SectorSize,
+ Frontend->SectorShift,
+ Frontend->DiskInfo);
}
if (Frontend->DiskInfo & VDISK_READONLY) {
LogWarning("DiskInfo contains VDISK_READONLY flag!\n");
@@ -919,7 +926,7 @@ FrontendCreate(
Frontend->TargetId = TargetId;
Frontend->DeviceId = strtoul(DeviceId, NULL, 10);
Frontend->State = XENVBD_INITIALIZED;
- Frontend->SectorSize = 512; // default value
+ Frontend->SectorSize = BLKIF_SECTOR_SIZE; // default value
Frontend->FrontendPath = DriverFormat("device/vbd/%s", DeviceId);
if (Frontend->FrontendPath == NULL)
diff --git a/src/xencrsh/frontend.h b/src/xencrsh/frontend.h
index 2e2c305..5b0030a 100644
--- a/src/xencrsh/frontend.h
+++ b/src/xencrsh/frontend.h
@@ -39,6 +39,10 @@
#include "pdo.h"
#include "ring.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,
@@ -69,8 +73,12 @@ typedef struct _XENVBD_FRONTEND {
BOOLEAN DumpFile;
// Disk Info
+ // each "sector" here is of size BLKIF_SECTOR_SIZE
+ ULONG64 BlkifSectorCount;
+ // logical sector size as used by Windows for addressing
ULONG SectorSize;
- ULONG64 SectorCount;
+ // log2(sector size / BLKIF_SECTOR_SIZE)
+ ULONG SectorShift;
ULONG DiskInfo;
// Inquiry
diff --git a/src/xencrsh/pdo.c b/src/xencrsh/pdo.c
index 76c4d59..0335205 100644
--- a/src/xencrsh/pdo.c
+++ b/src/xencrsh/pdo.c
@@ -32,6 +32,8 @@
#include "pdo.h"
+#include <limits.h>
+
#include "driver.h"
#include "fdo.h"
#include "frontend.h"
@@ -53,6 +55,8 @@
#include "assert.h"
#include "util.h"
+#define SECTORS_PER_PAGE ((ULONG)(PAGE_SIZE / BLKIF_SECTOR_SIZE))
+
typedef struct _XENVBD_SG_INDEX {
ULONG Index;
ULONG Offset;
@@ -305,13 +309,6 @@ static FORCEINLINE ULONG __SectorSize(
ASSERT3U(Pdo->Frontend.SectorSize, !=, 0);
return Pdo->Frontend.SectorSize;
}
-static FORCEINLINE ULONG __SectorsPerPage(
- IN ULONG SectorSize
- )
-{
- ASSERT3U(SectorSize, !=, 0);
- return PAGE_SIZE / SectorSize;
-}
static FORCEINLINE VOID
__Operation(
IN UCHAR CdbOp,
@@ -402,12 +399,12 @@ PrepareReadWrite(
PSTOR_SCATTER_GATHER_LIST SGList;
XENVBD_SG_INDEX SGIndex;
- PXENVBD_SRBEXT SrbExt = GetSrbExt(Srb);
+ PXENVBD_FRONTEND Frontend = &Pdo->Frontend;
+ PXENVBD_SRBEXT SrbExt = GetSrbExt(Srb);
- const ULONG64 StartSector = Cdb_LogicalBlock(Srb);
- const ULONG NumSectors = Cdb_TransferBlock(Srb);
+ const ULONG64 StartSector = Cdb_LogicalBlock(Srb) <<
Frontend->SectorShift;
+ const ULONG NumSectors = Cdb_TransferBlock(Srb) <<
Frontend->SectorShift;
const ULONG SectorSize = __SectorSize(Pdo);
- const ULONG SectorsPerPage = __SectorsPerPage(SectorSize);
__Operation(Cdb_OperationEx(Srb), &Operation, &ReadOnly);
SGList = StorPortGetScatterGatherList(Pdo->Fdo, Srb);
@@ -439,13 +436,15 @@ PrepareReadWrite(
ULONG Type;
// get first sector, last sector and count
- FirstSector = (__Offset(PhysAddr) + SectorSize - 1) /
SectorSize;
- SectorsNow = __Min(NumSectors - SectorsDone, SectorsPerPage -
FirstSector);
+ FirstSector = (__Offset(PhysAddr) + BLKIF_SECTOR_SIZE - 1) /
+ BLKIF_SECTOR_SIZE;
+ SectorsNow = __Min(NumSectors - SectorsDone,
+ SECTORS_PER_PAGE - FirstSector);
LastSector = FirstSector + SectorsNow - 1;
- ASSERT3U((PhysLen / SectorSize), ==, SectorsNow);
- ASSERT3U((PhysLen & (SectorSize - 1)), ==, 0);
-
+ ASSERT3U((PhysLen / BLKIF_SECTOR_SIZE), ==, SectorsNow);
+ ASSERT3U((PhysLen & (BLKIF_SECTOR_SIZE - 1)), ==, 0);
+
// simples - grab Pfn of PhysAddr
Pfn = __Pfn(PhysAddr);
@@ -471,7 +470,7 @@ PrepareReadWrite(
// get first sector, last sector and count
FirstSector = 0;
- SectorsNow = __Min(NumSectors - SectorsDone, SectorsPerPage);
+ SectorsNow = __Min(NumSectors - SectorsDone,
SECTORS_PER_PAGE);
LastSector = SectorsNow - 1;
// map PhysAddr to 1 or 2 pages and lock for VirtAddr
@@ -489,19 +488,19 @@ PrepareReadWrite(
Request->Segments[Index2].Pfn[0] = __Pfn(PhysAddr);
#pragma warning(pop)
- if (PhysLen < SectorsNow * SectorSize) {
+ if (PhysLen < SectorsNow * BLKIF_SECTOR_SIZE) {
__GetPhysAddr(SGList, &SGIndex, &PhysAddr, &PhysLen);
Mdl->Size += sizeof(PFN_NUMBER);
Mdl->ByteCount = Mdl->ByteCount + PhysLen;
Request->Segments[Index2].Pfn[1] = __Pfn(PhysAddr);
}
- 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));
+
Length = __Min(Mdl->ByteCount, PAGE_SIZE);
- Buffer = MmMapLockedPagesSpecifyCache(Mdl, KernelMode,
+ Buffer = MmMapLockedPagesSpecifyCache(Mdl, KernelMode,
MmCached, NULL, FALSE,
HighPagePriority);
if (!Buffer) {
Pdo->NeedsWake = TRUE;
@@ -585,7 +584,7 @@ PrepareSyncCache(
Request->Operation = Operation;
Request->NrSegments = 0;
- Request->FirstSector = Cdb_LogicalBlock(Srb);
+ Request->FirstSector = Cdb_LogicalBlock(Srb) <<
Pdo->Frontend.SectorShift;
Request->NrSectors = 0;
__UpdateStats(Pdo, Operation);
@@ -743,13 +742,27 @@ PdoCompleteSubmittedRequest(
static FORCEINLINE BOOLEAN
__ValidateSectors(
- IN ULONG64 SectorCount,
- IN ULONG64 Start,
- IN ULONG Length
+ _In_ PXENVBD_FRONTEND Frontend,
+ _In_ ULONG64 StartLBA,
+ _In_ ULONG64 CountLBA
)
{
- // Deal with overflow
- return (Start < SectorCount) && ((Start + Length) < SectorCount);
+ ULONG64 BlkifSectorStart;
+ ULONG64 BlkifSectorEnd;
+
+ if (StartLBA > (ULLONG_MAX >> Frontend->SectorShift) ||
+ CountLBA > (ULLONG_MAX >> Frontend->SectorShift))
+ return FALSE;
+
+ BlkifSectorStart = StartLBA << Frontend->SectorShift;
+ BlkifSectorEnd = BlkifSectorStart + (CountLBA << Frontend->SectorShift);
+ if (BlkifSectorEnd < BlkifSectorStart)
+ return FALSE;
+
+ if (BlkifSectorEnd > Frontend->BlkifSectorCount)
+ return FALSE;
+
+ return TRUE;
}
static BOOLEAN
PdoReadWrite(
@@ -765,8 +778,13 @@ PdoReadWrite(
return TRUE;
}
// check valid sectors
- if (!__ValidateSectors(Pdo->Frontend.SectorCount, Cdb_LogicalBlock(Srb),
Cdb_TransferBlock(Srb))) {
- LogTrace("Target[%d] : Invalid Sectors (%lld, %lld, %d)\n",
Pdo->Frontend.TargetId, Pdo->Frontend.SectorCount, Cdb_LogicalBlock(Srb),
Cdb_TransferBlock(Srb));
+ if (!__ValidateSectors(&Pdo->Frontend,
+ Cdb_LogicalBlock(Srb),
+ Cdb_TransferBlock(Srb))) {
+ LogTrace("Target[%lu] : Invalid Sectors (%llu, %lu)\n",
+ Pdo->Frontend.TargetId,
+ Cdb_LogicalBlock(Srb),
+ Cdb_TransferBlock(Srb));
Srb->ScsiStatus = 0x40; // SCSI_ABORT
return TRUE; // Complete now
}
@@ -791,7 +809,18 @@ PdoSyncCache(
Srb->ScsiStatus = 0x40; // SCSI_ABORT;
return TRUE;
}
-
+ // check valid sectors
+ if (!__ValidateSectors(&Pdo->Frontend,
+ Cdb_LogicalBlock(Srb),
+ Cdb_TransferBlock(Srb))) {
+ LogTrace("Target[%lu] : Invalid Sectors (%llu, %lu)\n",
+ Pdo->Frontend.TargetId,
+ Cdb_LogicalBlock(Srb),
+ Cdb_TransferBlock(Srb));
+ Srb->ScsiStatus = 0x40; // SCSI_ABORT
+ return TRUE; // Complete now
+ }
+
PrepareSyncCache(Pdo, Srb);
PdoSubmitPrepared(Pdo);
return FALSE;
@@ -964,13 +993,14 @@ PdoReadCapacity(
IN PSCSI_REQUEST_BLOCK Srb
)
{
+ PXENVBD_FRONTEND Frontend = &Pdo->Frontend;
PREAD_CAPACITY_DATA Capacity = Srb->DataBuffer;
ULONG64 SectorCount;
ULONG SectorSize;
ULONG LastBlock;
-
- SectorCount = Pdo->Frontend.SectorCount;
- SectorSize = Pdo->Frontend.SectorSize;
+
+ SectorCount = Frontend->BlkifSectorCount >> Frontend->SectorShift;
+ SectorSize = Frontend->SectorSize;
if (SectorCount == (ULONG)SectorCount)
LastBlock = (ULONG)SectorCount - 1;
@@ -990,12 +1020,13 @@ PdoReadCapacity16(
IN PSCSI_REQUEST_BLOCK Srb
)
{
+ PXENVBD_FRONTEND Frontend = &Pdo->Frontend;
PREAD_CAPACITY_DATA_EX Capacity = Srb->DataBuffer;
ULONG64 SectorCount;
ULONG SectorSize;
- SectorCount = Pdo->Frontend.SectorCount;
- SectorSize = Pdo->Frontend.SectorSize;
+ SectorCount = Frontend->BlkifSectorCount >> Frontend->SectorShift;
+ SectorSize = Frontend->SectorSize;
if (Capacity) {
Capacity->LogicalBlockAddress.QuadPart = _byteswap_uint64(SectorCount
- 1);
--
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 |