From: Zhang Jingwang <yyalone@xxxxxxxxx> If there are too many extents to commit, xdr buffer will be used up. So we check the return value and encode as many extents as possible to xdr buffer, leaving the rest in the bl_commit list. Signed-off-by: Zhang Jingwang <yyalone@xxxxxxxxx> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfs/blocklayout/extents.c | 29 ++++++++++++++++------------- 1 files changed, 16 insertions(+), 13 deletions(-) diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c index 98452ca..09a7c5c 100644 --- a/fs/nfs/blocklayout/extents.c +++ b/fs/nfs/blocklayout/extents.c @@ -745,7 +745,7 @@ encode_pnfs_block_layoutupdate(struct pnfs_block_layout *bl, { sector_t start, end; struct pnfs_block_short_extent *lce, *save; - unsigned int count; + unsigned int count = 0; struct bl_layoutupdate_data *bld = arg->layoutdriver_data; struct list_head *ranges = &bld->ranges; __be32 *p, *xdr_start; @@ -760,29 +760,32 @@ encode_pnfs_block_layoutupdate(struct pnfs_block_layout *bl, * entire block to be marked WRITTEN before it can be added. */ spin_lock(&bl->bl_ext_lock); - list_splice_init(&bl->bl_commit, ranges); - count = bl->bl_count; - bl->bl_count = 0; /* Want to adjust for possible truncate */ /* We now want to adjust argument range */ - spin_unlock(&bl->bl_ext_lock); - dprintk("%s found %i ranges\n", __func__, count); /* XDR encode the ranges found */ - xdr_start = p = xdr_reserve_space(xdr, 8); - p++; - WRITE32(count); - list_for_each_entry_safe(lce, save, ranges, bse_node) { + xdr_start = xdr_reserve_space(xdr, 8); + if (!xdr_start) + goto out; + list_for_each_entry_safe(lce, save, &bl->bl_commit, bse_node) { p = xdr_reserve_space(xdr, 7 * 4 + sizeof(lce->bse_devid.data)); - + if (!p) + break; WRITE_DEVID(&lce->bse_devid); WRITE64(lce->bse_f_offset << 9); WRITE64(lce->bse_length << 9); WRITE64(0LL); WRITE32(PNFS_BLOCK_READWRITE_DATA); + list_del(&lce->bse_node); + list_add_tail(&lce->bse_node, ranges); + bl->bl_count--; + count++; } - - *xdr_start = cpu_to_be32((xdr->p - xdr_start - 1) * 4); + xdr_start[0] = cpu_to_be32((xdr->p - xdr_start - 1) * 4); + xdr_start[1] = cpu_to_be32(count); +out: + spin_unlock(&bl->bl_ext_lock); + dprintk("%s found %i ranges\n", __func__, count); return 0; } -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html