[sheepdog] [PATCH v4 3/3] sheep: look up whole range of bitmap

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Sun Mar 8 05:08:35 CET 2015


Older sheepdog didn't have a functionality of recycling VID, so the
get_vdi_bitmap_range() can detect correct range of bitmap. But newer
sheepdog recycles VID. It can produce situations like below:

The first state of VID bitmap:
0 0 1* 1* 1 0 0 0
1 is a VID bit of working VDI, 1* is a bit of snapshot. Assume the
above 1 and 1* are used for VDI named "A" and its snapshots.

Then, a user tries to create VDI "B". sd_hash_vdi() returns VID which
conflicts with existing bits for A.
0 0 1* 1* 1 0 0 0
       ^
       |
       sd_hash_vdi() returns VID which conflicts with the
       above bit.

So B acquires the left most free bit
0 0 1* 1* 1 1 0 0
            ^
            |
            B acquires this bit.

Then, the user deletes A and its snapshots. All of the family members
are deleted. The bitmap becomes like below
0 0 0 0 0 1 0 0
      ^
      |
      B's original VID sd_hash_vdi() calculates.

Now sheep fails to lookup VID of B, because the VID calculated by
sd_hash_vdi() is zero.

This is the reason of the looking up whole range of bitmap. Of course
it is ugly and costly. But its cost is equal or less than "dog vdi
list"'s one.

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 sheep/vdi.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

v4:
 - handle a case of recycled VID problem for deleted snapshot family, too

v3:
 - handle a case of recycled VID problem for lookup

diff --git a/sheep/vdi.c b/sheep/vdi.c
index ea64719..de35dc6 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -1496,12 +1496,67 @@ int vdi_lookup(const struct vdi_iocb *iocb, struct vdi_info *info)
 	sd_debug("%s left %lx right %lx, %x", iocb->name, left, right, ret);
 	switch (ret) {
 	case SD_RES_NO_VDI:
+		/*
+		 * Why is the below heavy fill_vdi_info() required?
+		 *
+		 * Older sheepdog didn't have a functionality of recycling VID,
+		 * so the above get_vdi_bitmap_range() can detect correct range
+		 * of bitmap.
+		 *
+		 * But newer sheepdog (1.0 <=) recycles VID. It can produce
+		 * situations like below:
+		 *
+		 * The first state of VID bitmap:
+		 * 0 0 1* 1* 1 0 0 0
+		 * 1 is a VID bit of working VDI, 1* is a bit of snapshot.
+		 * Assume the above 1 and 1* are used for VDI named "A" and
+		 * its snapshots.
+		 *
+		 * Then, a user tries to create VDI "B". sd_hash_vdi() returns
+		 * VID which conflicts with existing bits for A.
+		 * 0 0 1* 1* 1 0 0 0
+		 *        ^
+		 *        |
+		 *        sd_hash_vdi() returns VID which conflicts with the
+		 *        above bit.
+		 *
+		 * So B acquires the left most free bit
+		 * 0 0 1* 1* 1 1 0 0
+		 *             ^
+		 *             |
+		 *             B acquires this bit.
+		 *
+		 * Then, the user deletes A and its snapshots. All of the family
+		 * members are deleted. The bitmap becomes like below
+		 * 0 0 0 0 0 1 0 0
+		 *       ^
+		 *       |
+		 *       B's original VID sd_hash_vdi() calculates.
+		 *
+		 * Now sheep fails to lookup VID of B, because the VID
+		 * calculated by sd_hash_vdi().
+		 *
+		 * This is the reason of the below fill_vdi_info(). Of course it
+		 * is ugly and costly. But its cost is equal or less than
+		 * "dog vdi list"'s one.
+		 */
+		return fill_vdi_info(1, SD_NR_VDIS - 1, iocb, info);
 	case SD_RES_FULL_VDI:
 		return ret;
 	case SD_RES_SUCCESS:
 		break;
 	}
-	return fill_vdi_info(left, right, iocb, info);
+
+	ret = fill_vdi_info(left, right, iocb, info);
+	if (ret == SD_RES_NO_VDI)
+		/*
+		 * The below fill_vdi_info() is required because of the VID
+		 * recycling. The detail is described in the above lengthy
+		 * comment.
+		 */
+		return fill_vdi_info(1, SD_NR_VDIS - 1, iocb, info);
+
+	return ret;
 }
 
 static int notify_vdi_add(uint32_t vdi_id, uint32_t nr_copies, uint32_t old_vid,
-- 
1.9.1




More information about the sheepdog mailing list