static int ioreq_map(struct ioreq *ioreq)

{

    XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;

    uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    int i, j, new_maps = 0;

    PersistentGrant *grant;

    /* domids and refs variables will contain the information necessary

     * to map the grants that are needed to fulfill this request.

     *

     * After mapping the needed grants, the page array will contain the

     * memory address of each granted page in the order specified in ioreq

     * (disregarding if it's a persistent grant or not).

     */



    if (ioreq->v.niov == 0 || ioreq->mapped == 1) {

        return 0;

    }

    if (ioreq->blkdev->feature_persistent) {

        for (i = 0; i < ioreq->v.niov; i++) {

            grant = g_tree_lookup(ioreq->blkdev->persistent_gnts,

                                    GUINT_TO_POINTER(ioreq->refs[i]));



            if (grant != NULL) {

                page[i] = grant->page;

                xen_be_printf(&ioreq->blkdev->xendev, 3,

                              "using persistent-grant %" PRIu32 "\n",

                              ioreq->refs[i]);

            } else {

                    /* Add the grant to the list of grants that

                     * should be mapped

                     */

                    domids[new_maps] = ioreq->domids[i];

                    refs[new_maps] = ioreq->refs[i];

                    page[i] = NULL;

                    new_maps++;

            }

        }

        /* Set the protection to RW, since grants may be reused later

         * with a different protection than the one needed for this request

         */

        ioreq->prot = PROT_WRITE | PROT_READ;

    } else {

        /* All grants in the request should be mapped */

        memcpy(refs, ioreq->refs, sizeof(refs));

        memcpy(domids, ioreq->domids, sizeof(domids));

        memset(page, 0, sizeof(page));

        new_maps = ioreq->v.niov;

    }



    if (batch_maps && new_maps) {

        ioreq->pages = xc_gnttab_map_grant_refs

            (gnt, new_maps, domids, refs, ioreq->prot);

        if (ioreq->pages == NULL) {

            xen_be_printf(&ioreq->blkdev->xendev, 0,

                          "can't map %d grant refs (%s, %d maps)\n",

                          new_maps, strerror(errno), ioreq->blkdev->cnt_map);

            return -1;

        }

        for (i = 0, j = 0; i < ioreq->v.niov; i++) {

            if (page[i] == NULL) {

                page[i] = ioreq->pages + (j++) * XC_PAGE_SIZE;

            }

        }

        ioreq->blkdev->cnt_map += new_maps;

    } else if (new_maps)  {

        for (i = 0; i < new_maps; i++) {

            ioreq->page[i] = xc_gnttab_map_grant_ref

                (gnt, domids[i], refs[i], ioreq->prot);

            if (ioreq->page[i] == NULL) {

                xen_be_printf(&ioreq->blkdev->xendev, 0,

                              "can't map grant ref %d (%s, %d maps)\n",

                              refs[i], strerror(errno), ioreq->blkdev->cnt_map);

                ioreq->mapped = 1;

                ioreq_unmap(ioreq);

                return -1;

            }

            ioreq->blkdev->cnt_map++;

        }

        for (i = 0, j = 0; i < ioreq->v.niov; i++) {

            if (page[i] == NULL) {

                page[i] = ioreq->page[j++];

            }

        }

    }

    if (ioreq->blkdev->feature_persistent) {

        while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants)

              && new_maps) {

            /* Go through the list of newly mapped grants and add as many

             * as possible to the list of persistently mapped grants.

             *

             * Since we start at the end of ioreq->page(s), we only need

             * to decrease new_maps to prevent this granted pages from

             * being unmapped in ioreq_unmap.

             */

            grant = g_malloc0(sizeof(*grant));

            new_maps--;

            if (batch_maps) {

                grant->page = ioreq->pages + (new_maps) * XC_PAGE_SIZE;

            } else {

                grant->page = ioreq->page[new_maps];

            }

            grant->blkdev = ioreq->blkdev;

            xen_be_printf(&ioreq->blkdev->xendev, 3,

                          "adding grant %" PRIu32 " page: %p\n",

                          refs[new_maps], grant->page);

            g_tree_insert(ioreq->blkdev->persistent_gnts,

                          GUINT_TO_POINTER(refs[new_maps]),

                          grant);

            ioreq->blkdev->persistent_gnt_count++;

        }

    }

    for (i = 0; i < ioreq->v.niov; i++) {

        ioreq->v.iov[i].iov_base += (uintptr_t)page[i];

    }

    ioreq->mapped = 1;

    ioreq->num_unmap = new_maps;

    return 0;

}

static int ioreq_map(struct ioreq *ioreq)

{

    XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;

    uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    int i, j, new_maps = 0;

    PersistentGrant *grant;

    















    if (ioreq->v.niov == 0 || ioreq->mapped == 1) {

        return 0;

    }

    if (ioreq->blkdev->feature_persistent) {

        for (i = 0; i < ioreq->v.niov; i++) {

            grant = g_tree_lookup(ioreq->blkdev->persistent_gnts,

                                    GUINT_TO_POINTER(ioreq->refs[i]));



            if (grant != NULL) {

                page[i] = grant->page;

                xen_be_printf(&ioreq->blkdev->xendev, 3,

                              "using persistent-grant %" PRIu32 "\n",

                              ioreq->refs[i]);

            } else {

                    





                    domids[new_maps] = ioreq->domids[i];

                    refs[new_maps] = ioreq->refs[i];

                    page[i] = NULL;

                    new_maps++;

            }

        }

        





        ioreq->prot = PROT_WRITE | PROT_READ;

    } else {

        

        memcpy(refs, ioreq->refs, sizeof(refs));

        memcpy(domids, ioreq->domids, sizeof(domids));

        memset(page, 0, sizeof(page));

        new_maps = ioreq->v.niov;

    }



    if (batch_maps && new_maps) {

        ioreq->pages = xc_gnttab_map_grant_refs

            (gnt, new_maps, domids, refs, ioreq->prot);

        if (ioreq->pages == NULL) {

            xen_be_printf(&ioreq->blkdev->xendev, 0,

                          "can't map %d grant refs (%s, %d maps)\n",

                          new_maps, strerror(errno), ioreq->blkdev->cnt_map);

            return -1;

        }

        for (i = 0, j = 0; i < ioreq->v.niov; i++) {

            if (page[i] == NULL) {

                page[i] = ioreq->pages + (j++) * XC_PAGE_SIZE;

            }

        }

        ioreq->blkdev->cnt_map += new_maps;

    } else if (new_maps)  {

        for (i = 0; i < new_maps; i++) {

            ioreq->page[i] = xc_gnttab_map_grant_ref

                (gnt, domids[i], refs[i], ioreq->prot);

            if (ioreq->page[i] == NULL) {

                xen_be_printf(&ioreq->blkdev->xendev, 0,

                              "can't map grant ref %d (%s, %d maps)\n",

                              refs[i], strerror(errno), ioreq->blkdev->cnt_map);

                ioreq->mapped = 1;

                ioreq_unmap(ioreq);

                return -1;

            }

            ioreq->blkdev->cnt_map++;

        }

        for (i = 0, j = 0; i < ioreq->v.niov; i++) {

            if (page[i] == NULL) {

                page[i] = ioreq->page[j++];

            }

        }

    }

    if (ioreq->blkdev->feature_persistent) {

        while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants)

              && new_maps) {

            













            grant = g_malloc0(sizeof(*grant));

            new_maps--;

            if (batch_maps) {

                grant->page = ioreq->pages + (new_maps) * XC_PAGE_SIZE;

            } else {

                grant->page = ioreq->page[new_maps];

            }

            grant->blkdev = ioreq->blkdev;

            xen_be_printf(&ioreq->blkdev->xendev, 3,

                          "adding grant %" PRIu32 " page: %p\n",

                          refs[new_maps], grant->page);

            g_tree_insert(ioreq->blkdev->persistent_gnts,

                          GUINT_TO_POINTER(refs[new_maps]),

                          grant);

            ioreq->blkdev->persistent_gnt_count++;

        }

    }

    for (i = 0; i < ioreq->v.niov; i++) {

        ioreq->v.iov[i].iov_base += (uintptr_t)page[i];

    }

    ioreq->mapped = 1;

    ioreq->num_unmap = new_maps;

    return 0;

}

    if (ioreq->blkdev->feature_persistent) {
static int FUNC_0(struct VAR_0 *VAR_0)

{

    XenGnttab gnt = VAR_0->blkdev->xendev.gnttabdev;

    uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    void *VAR_1[BLKIF_MAX_SEGMENTS_PER_REQUEST];

    int VAR_2, VAR_3, VAR_4 = 0;

    PersistentGrant *grant;

    















    if (VAR_0->v.niov == 0 || VAR_0->mapped == 1) {

        return 0;

    }

    if (VAR_0->blkdev->feature_persistent) {

        for (VAR_2 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) {

            grant = g_tree_lookup(VAR_0->blkdev->persistent_gnts,

                                    GUINT_TO_POINTER(VAR_0->refs[VAR_2]));



            if (grant != NULL) {

                VAR_1[VAR_2] = grant->VAR_1;

                xen_be_printf(&VAR_0->blkdev->xendev, 3,

                              "using persistent-grant %" PRIu32 "\n",

                              VAR_0->refs[VAR_2]);

            } else {

                    





                    domids[VAR_4] = VAR_0->domids[VAR_2];

                    refs[VAR_4] = VAR_0->refs[VAR_2];

                    VAR_1[VAR_2] = NULL;

                    VAR_4++;

            }

        }

        





        VAR_0->prot = PROT_WRITE | PROT_READ;

    } else {

        

        memcpy(refs, VAR_0->refs, sizeof(refs));

        memcpy(domids, VAR_0->domids, sizeof(domids));

        memset(VAR_1, 0, sizeof(VAR_1));

        VAR_4 = VAR_0->v.niov;

    }



    if (batch_maps && VAR_4) {

        VAR_0->pages = xc_gnttab_map_grant_refs

            (gnt, VAR_4, domids, refs, VAR_0->prot);

        if (VAR_0->pages == NULL) {

            xen_be_printf(&VAR_0->blkdev->xendev, 0,

                          "can't map %d grant refs (%s, %d maps)\n",

                          VAR_4, strerror(errno), VAR_0->blkdev->cnt_map);

            return -1;

        }

        for (VAR_2 = 0, VAR_3 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) {

            if (VAR_1[VAR_2] == NULL) {

                VAR_1[VAR_2] = VAR_0->pages + (VAR_3++) * XC_PAGE_SIZE;

            }

        }

        VAR_0->blkdev->cnt_map += VAR_4;

    } else if (VAR_4)  {

        for (VAR_2 = 0; VAR_2 < VAR_4; VAR_2++) {

            VAR_0->VAR_1[VAR_2] = xc_gnttab_map_grant_ref

                (gnt, domids[VAR_2], refs[VAR_2], VAR_0->prot);

            if (VAR_0->VAR_1[VAR_2] == NULL) {

                xen_be_printf(&VAR_0->blkdev->xendev, 0,

                              "can't map grant ref %d (%s, %d maps)\n",

                              refs[VAR_2], strerror(errno), VAR_0->blkdev->cnt_map);

                VAR_0->mapped = 1;

                ioreq_unmap(VAR_0);

                return -1;

            }

            VAR_0->blkdev->cnt_map++;

        }

        for (VAR_2 = 0, VAR_3 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) {

            if (VAR_1[VAR_2] == NULL) {

                VAR_1[VAR_2] = VAR_0->VAR_1[VAR_3++];

            }

        }

    }

    if (VAR_0->blkdev->feature_persistent) {

        while ((VAR_0->blkdev->persistent_gnt_count < VAR_0->blkdev->max_grants)

              && VAR_4) {

            













            grant = g_malloc0(sizeof(*grant));

            VAR_4--;

            if (batch_maps) {

                grant->VAR_1 = VAR_0->pages + (VAR_4) * XC_PAGE_SIZE;

            } else {

                grant->VAR_1 = VAR_0->VAR_1[VAR_4];

            }

            grant->blkdev = VAR_0->blkdev;

            xen_be_printf(&VAR_0->blkdev->xendev, 3,

                          "adding grant %" PRIu32 " VAR_1: %p\n",

                          refs[VAR_4], grant->VAR_1);

            g_tree_insert(VAR_0->blkdev->persistent_gnts,

                          GUINT_TO_POINTER(refs[VAR_4]),

                          grant);

            VAR_0->blkdev->persistent_gnt_count++;

        }

    }

    for (VAR_2 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) {

        VAR_0->v.iov[VAR_2].iov_base += (uintptr_t)VAR_1[VAR_2];

    }

    VAR_0->mapped = 1;

    VAR_0->num_unmap = VAR_4;

    return 0;

}

static int FUNC_0(struct VAR_0 *VAR_0)
{ XenGnttab gnt = VAR_0->blkdev->xendev.gnttabdev; uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST]; uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; void *VAR_1[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int VAR_2, VAR_3, VAR_4 = 0; PersistentGrant *grant; if (VAR_0->v.niov == 0 || VAR_0->mapped == 1) { return 0; } if (VAR_0->blkdev->feature_persistent) { for (VAR_2 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) { grant = g_tree_lookup(VAR_0->blkdev->persistent_gnts,
GUINT_TO_POINTER(VAR_0->refs[VAR_2])); if (grant != NULL) { VAR_1[VAR_2] = grant->VAR_1; xen_be_printf(&VAR_0->blkdev->xendev, 3,
"using persistent-grant %" PRIu32 "\n",
VAR_0->refs[VAR_2]); } else { domids[VAR_4] = VAR_0->domids[VAR_2]; refs[VAR_4] = VAR_0->refs[VAR_2]; VAR_1[VAR_2] = NULL; VAR_4++; } } VAR_0->prot = PROT_WRITE | PROT_READ; } else { memcpy(refs, VAR_0->refs, sizeof(refs)); memcpy(domids, VAR_0->domids, sizeof(domids)); memset(VAR_1, 0, sizeof(VAR_1)); VAR_4 = VAR_0->v.niov; } if (batch_maps && VAR_4) { VAR_0->pages = xc_gnttab_map_grant_refs
(gnt, VAR_4, domids, refs, VAR_0->prot); if (VAR_0->pages == NULL) { xen_be_printf(&VAR_0->blkdev->xendev, 0,
"can't map %d grant refs (%s, %d maps)\n",
VAR_4, strerror(errno), VAR_0->blkdev->cnt_map); return -1; } for (VAR_2 = 0, VAR_3 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) { if (VAR_1[VAR_2] == NULL) { VAR_1[VAR_2] = VAR_0->pages + (VAR_3++) * XC_PAGE_SIZE; } } VAR_0->blkdev->cnt_map += VAR_4; } else if (VAR_4)  { for (VAR_2 = 0; VAR_2 < VAR_4; VAR_2++) { VAR_0->VAR_1[VAR_2] = xc_gnttab_map_grant_ref
(gnt, domids[VAR_2], refs[VAR_2], VAR_0->prot); if (VAR_0->VAR_1[VAR_2] == NULL) { xen_be_printf(&VAR_0->blkdev->xendev, 0,
"can't map grant ref %d (%s, %d maps)\n",
refs[VAR_2], strerror(errno), VAR_0->blkdev->cnt_map); VAR_0->mapped = 1; ioreq_unmap(VAR_0); return -1; } VAR_0->blkdev->cnt_map++; } for (VAR_2 = 0, VAR_3 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) { if (VAR_1[VAR_2] == NULL) { VAR_1[VAR_2] = VAR_0->VAR_1[VAR_3++]; } } } if (VAR_0->blkdev->feature_persistent) { while ((VAR_0->blkdev->persistent_gnt_count < VAR_0->blkdev->max_grants)
&& VAR_4) { grant = g_malloc0(sizeof(*grant)); VAR_4--; if (batch_maps) { grant->VAR_1 = VAR_0->pages + (VAR_4) * XC_PAGE_SIZE; } else { grant->VAR_1 = VAR_0->VAR_1[VAR_4]; } grant->blkdev = VAR_0->blkdev; xen_be_printf(&VAR_0->blkdev->xendev, 3,
"adding grant %" PRIu32 " VAR_1: %p\n",
refs[VAR_4], grant->VAR_1); g_tree_insert(VAR_0->blkdev->persistent_gnts,
GUINT_TO_POINTER(refs[VAR_4]),
grant); VAR_0->blkdev->persistent_gnt_count++; } } for (VAR_2 = 0; VAR_2 < VAR_0->v.niov; VAR_2++) { VAR_0->v.iov[VAR_2].iov_base += (uintptr_t)VAR_1[VAR_2]; } VAR_0->mapped = 1; VAR_0->num_unmap = VAR_4; return 0; }