[PATCH 40/88] SQAUSHME: blocklayoutdriver: NULL pointer reference when committing too many extents

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux