[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.