[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 1/3] Decode SCSIOP_UNMAP correctly into BLKIF_OP_DISCARD requests
From: Owen Smith <owen.smith@xxxxxxxxxx> SCSIOP_UNMAP requests contain a list of extents to discard and each BLKIF_OP_DISCARD only handles a single extent. Break a SRB doen into multiple ring requests as neccessary. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/pdo.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 15 deletions(-) diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c index 9762944..c5b0b3f 100644 --- a/src/xenvbd/pdo.c +++ b/src/xenvbd/pdo.c @@ -1445,6 +1445,41 @@ PrepareSyncCache( return STATUS_SUCCESS; } +static FORCEINLINE ULONG64 +__Get8Bytes( + IN PUCHAR Bytes + ) +{ + return (ULONG64)Bytes[0] << 56 | + (ULONG64)Bytes[1] << 48 | + (ULONG64)Bytes[2] << 40 | + (ULONG64)Bytes[3] << 32 | + (ULONG64)Bytes[4] << 24 | + (ULONG64)Bytes[5] << 16 | + (ULONG64)Bytes[6] << 8 | + (ULONG64)Bytes[7]; +} + +static FORCEINLINE ULONG +__Get4Bytes( + IN PUCHAR Bytes + ) +{ + return (ULONG)Bytes[0] << 24 | + (ULONG)Bytes[1] << 16 | + (ULONG)Bytes[2] << 8 | + (ULONG)Bytes[3]; +} + +static FORCEINLINE USHORT +__Get2Bytes( + IN PUCHAR Bytes + ) +{ + return (USHORT)Bytes[0] << 8 | + (USHORT)Bytes[1]; +} + __checkReturn static NTSTATUS PrepareUnmap( @@ -1452,26 +1487,62 @@ PrepareUnmap( __in PSCSI_REQUEST_BLOCK Srb ) { - PXENVBD_SRBEXT SrbExt = GetSrbExt(Srb); - PXENVBD_REQUEST Request = __LookasideAlloc(&Pdo->RequestList); - if (Request == NULL) - return STATUS_UNSUCCESSFUL; + PXENVBD_SRBEXT SrbExt = GetSrbExt(Srb); + PUNMAP_LIST_HEADER Unmap = Srb->DataBuffer; + ULONG Count = __Get2Bytes(Unmap->DataLength) / __Get2Bytes(Unmap->BlockDescrDataLength); + ULONG Index; + LIST_ENTRY List; - SrbExt->Count = 1; - // mark the SRB as pending, completion will check for pending to detect failures + InitializeListHead(&List); Srb->SrbStatus = SRB_STATUS_PENDING; + SrbExt->Count = 0; - Request->Srb = Srb; - Request->Id = PdoGetTag(Pdo); - Request->Operation = BLKIF_OP_DISCARD; - Request->FirstSector = Cdb_LogicalBlock(Srb); - Request->NrSectors = Cdb_TransferBlock(Srb); - Request->Flags = 0; - InitializeListHead(&Request->Segments); + for (Index = 0; Index < Count; ++Index) { + PUNMAP_BLOCK_DESCRIPTOR Descr = &Unmap->Descriptors[Index]; + PXENVBD_REQUEST Request = __LookasideAlloc(&Pdo->RequestList); + if (Request == NULL) + goto fail1; - __PdoIncBlkifOpCount(Pdo, Request); - QueueAppend(&Pdo->PreparedReqs, &Request->Entry); + ++SrbExt->Count; + InsertTailList(&List, &Request->Entry); + + Request->Srb = Srb; + Request->Id = PdoGetTag(Pdo); + Request->Operation = BLKIF_OP_DISCARD; + Request->FirstSector = __Get8Bytes(Descr->StartingLba); + Request->NrSectors = __Get4Bytes(Descr->LbaCount); + Request->Flags = 0; + InitializeListHead(&Request->Segments); + } + + for (;;) { + PXENVBD_REQUEST Request; + PLIST_ENTRY Entry; + + Entry = RemoveHeadList(&List); + if (Entry == &List) + break; + + Request = CONTAINING_RECORD(Entry, XENVBD_REQUEST, Entry); + __PdoIncBlkifOpCount(Pdo, Request); + QueueAppend(&Pdo->PreparedReqs, &Request->Entry); + } return STATUS_SUCCESS; + +fail1: + for (;;) { + PXENVBD_REQUEST Request; + PLIST_ENTRY Entry; + + Entry = RemoveHeadList(&List); + if (Entry == &List) + break; + + Request = CONTAINING_RECORD(Entry, XENVBD_REQUEST, Entry); + __LookasideFree(&Pdo->RequestList, Request); + --SrbExt->Count; + } + return STATUS_NO_MEMORY; } //============================================================================= -- 2.1.0 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |