[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH v2 1/3] Prepare SCSIOP_UNMAP correctly
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 down into multiple ring requests as necessary. Changes for v2: * use byteswap intrinsics Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/pdo.c | 69 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c index 9762944..3f18621 100644 --- a/src/xenvbd/pdo.c +++ b/src/xenvbd/pdo.c @@ -1452,26 +1452,60 @@ 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 = _byteswap_ushort((*(PUSHORT)Unmap->DataLength) / + (*(PUSHORT)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); + SrbExt->Count = 0; Srb->SrbStatus = SRB_STATUS_PENDING; - 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; + + ++SrbExt->Count; + InsertTailList(&List, &Request->Entry); + + Request->Srb = Srb; + Request->Id = PdoGetTag(Pdo); + Request->Operation = BLKIF_OP_DISCARD; + Request->FirstSector = _byteswap_uint64(*(PULONG64)Descr->StartingLba); + Request->NrSectors = _byteswap_ulong(*(PULONG)Descr->LbaCount); + Request->Flags = 0; + InitializeListHead(&Request->Segments); + } + + while (!IsListEmpty(&List)) { + PXENVBD_REQUEST Request; + PLIST_ENTRY Entry; + + Entry = RemoveHeadList(&List); + ASSERT3P(Entry, !=, &List); + Request = CONTAINING_RECORD(Entry, XENVBD_REQUEST, Entry); + __PdoIncBlkifOpCount(Pdo, Request); + QueueAppend(&Pdo->PreparedReqs, &Request->Entry); + } - __PdoIncBlkifOpCount(Pdo, Request); - QueueAppend(&Pdo->PreparedReqs, &Request->Entry); return STATUS_SUCCESS; + +fail1: + while (!IsListEmpty(&List)) { + PXENVBD_REQUEST Request; + PLIST_ENTRY Entry; + + Entry = RemoveHeadList(&List); + ASSERT3P(Entry, !=, &List); + Request = CONTAINING_RECORD(Entry, XENVBD_REQUEST, Entry); + __LookasideFree(&Pdo->RequestList, Request); + --SrbExt->Count; + } + return STATUS_NO_MEMORY; } //============================================================================= -- 1.9.4.msysgit.1 _______________________________________________ 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 |