int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, struct xdr_stream *xdr, void *data) { struct gssx_res_accept_sec_context *res = data; u32 value_follows; int err; struct page *scratch; scratch = alloc_page(GFP_KERNEL); if (!scratch) return -ENOMEM; xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE); /* res->status */ err = gssx_dec_status(xdr, &res->status); if (err) goto out_free; /* res->context_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) goto out_free; if (value_follows) { err = gssx_dec_ctx(xdr, res->context_handle); if (err) goto out_free; } else { res->context_handle = NULL; } /* res->output_token */ err = gssx_dec_bool(xdr, &value_follows); if (err) goto out_free; if (value_follows) { err = gssx_dec_buffer(xdr, res->output_token); if (err) goto out_free; } else { res->output_token = NULL; } /* res->delegated_cred_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) goto out_free; if (value_follows) { /* we do not support upcall servers sending this data. */ err = -EINVAL; goto out_free; } /* res->options */ err = gssx_dec_option_array(xdr, &res->options); out_free: __free_page(scratch); return err; }
/* * Unmarshall layout and store it in pnfslay. */ struct pnfs_layout_segment * objlayout_alloc_lseg(struct pnfs_layout_hdr *pnfslay, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags) { int status = -ENOMEM; struct xdr_stream stream; struct xdr_buf buf = { .pages = lgr->layoutp->pages, .page_len = lgr->layoutp->len, .buflen = lgr->layoutp->len, .len = lgr->layoutp->len, }; struct page *scratch; struct pnfs_layout_segment *lseg; dprintk("%s: Begin pnfslay %p\n", __func__, pnfslay); scratch = alloc_page(gfp_flags); if (!scratch) goto err_nofree; xdr_init_decode(&stream, &buf, NULL); xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); status = objio_alloc_lseg(&lseg, pnfslay, &lgr->range, &stream, gfp_flags); if (unlikely(status)) { dprintk("%s: objio_alloc_lseg Return err %d\n", __func__, status); goto err; } __free_page(scratch); dprintk("%s: Return %p\n", __func__, lseg); return lseg; err: __free_page(scratch); err_nofree: dprintk("%s: Err Return=>%d\n", __func__, status); return ERR_PTR(status); } /* * Free a layout segement */ void objlayout_free_lseg(struct pnfs_layout_segment *lseg) { dprintk("%s: freeing layout segment %p\n", __func__, lseg); if (unlikely(!lseg)) return; objio_free_lseg(lseg); }
struct nfs4_deviceid_node * bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, gfp_t gfp_mask) { struct nfs4_deviceid_node *node = NULL; struct pnfs_block_volume *volumes; struct pnfs_block_dev *top; struct xdr_stream xdr; struct xdr_buf buf; struct page *scratch; int nr_volumes, ret, i; __be32 *p; scratch = alloc_page(gfp_mask); if (!scratch) goto out; xdr_init_decode_pages(&xdr, &buf, pdev->pages, pdev->pglen); xdr_set_scratch_buffer(&xdr, page_address(scratch), PAGE_SIZE); p = xdr_inline_decode(&xdr, sizeof(__be32)); if (!p) goto out_free_scratch; nr_volumes = be32_to_cpup(p++); volumes = kcalloc(nr_volumes, sizeof(struct pnfs_block_volume), gfp_mask); if (!volumes) goto out_free_scratch; for (i = 0; i < nr_volumes; i++) { ret = nfs4_block_decode_volume(&xdr, &volumes[i]); if (ret < 0) goto out_free_volumes; } top = kzalloc(sizeof(*top), gfp_mask); if (!top) goto out_free_volumes; ret = bl_parse_deviceid(server, top, volumes, nr_volumes - 1, gfp_mask); if (ret) { bl_free_device(top); kfree(top); goto out_free_volumes; } node = &top->node; nfs4_init_deviceid_node(node, server, &pdev->dev_id); out_free_volumes: kfree(volumes); out_free_scratch: __free_page(scratch); out: return node; }