pnfs/blocklayout: allocate separate pages for the layoutcommit payload

Instead of overflowing the XDR send buffer with our extent list allocate
pages and pre-encode the layoutupdate payload into them.  We optimistically
allocate a single page use alloc_page and only switch to vmalloc when we
have more extents outstanding.  Currently there is only a single testcase
(xfstests generic/113) which can reproduce large enough extent lists for
this to occur.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
Christoph Hellwig
2014-09-10 17:36:30 -07:00
committed by Trond Myklebust
parent d4b18c3e00
commit 34dc93c2fc
3 changed files with 92 additions and 35 deletions

View File

@@ -500,21 +500,16 @@ bl_return_range(struct pnfs_layout_hdr *lo,
err = ext_tree_remove(bl, range->iomode & IOMODE_RW, offset, end);
}
static void
bl_encode_layoutcommit(struct pnfs_layout_hdr *lo, struct xdr_stream *xdr,
const struct nfs4_layoutcommit_args *arg)
static int
bl_prepare_layoutcommit(struct nfs4_layoutcommit_args *arg)
{
dprintk("%s enter\n", __func__);
ext_tree_encode_commit(BLK_LO2EXT(lo), xdr);
return ext_tree_prepare_commit(arg);
}
static void
bl_cleanup_layoutcommit(struct nfs4_layoutcommit_data *lcdata)
{
struct pnfs_layout_hdr *lo = NFS_I(lcdata->args.inode)->layout;
dprintk("%s enter\n", __func__);
ext_tree_mark_committed(BLK_LO2EXT(lo), lcdata->res.status);
ext_tree_mark_committed(&lcdata->args, lcdata->res.status);
}
static int
@@ -670,7 +665,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = {
.alloc_lseg = bl_alloc_lseg,
.free_lseg = bl_free_lseg,
.return_range = bl_return_range,
.encode_layoutcommit = bl_encode_layoutcommit,
.prepare_layoutcommit = bl_prepare_layoutcommit,
.cleanup_layoutcommit = bl_cleanup_layoutcommit,
.set_layoutdriver = bl_set_layoutdriver,
.alloc_deviceid_node = bl_alloc_deviceid_node,