From: Robin Dong <san...@taobao.com>

In disk mode, we calculate number of md vnode by using "nr = disk_space / 
WEIGHT_MIN",
when disk_space is smaller than WEIGHT_MIN (4G currently), the 'nr' will be 
zero.

Imaging a sheep daemon who has two data paths. One data path has 8GB space, but
another data path has only 1GB space. The nr_disk is 2 and all the vnode in 
md.vroot
is for the 8GB data path. Then the larger data path get a disk fail and be 
removed
from md hashing ring, now the md.vroot has no vnode but nr_disk is 1. When the 
code
routine comes to md_get_object_dir_nolock(), it will call oid_to_vdisk() and 
get NULL
result which will make sheep daemon coredump.
To fix this problem, we should calculate number of vnode by DIV_ROUND_UP in 
disk mode.

Signed-off-by: Robin Dong <san...@taobao.com>
---
 include/sheep.h | 2 +-
 sheep/md.c      | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 785883e..e062372 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -216,7 +216,7 @@ node_disk_to_vnodes(const struct sd_node *n, struct rb_root 
*vroot)
                if (!n->disks[j].disk_id)
                        continue;
                hval = fnv_64a_64(node_hval, n->disks[j].disk_id);
-               disk_vnodes = n->disks[j].disk_space / WEIGHT_MIN;
+               disk_vnodes = DIV_ROUND_UP(n->disks[j].disk_space, WEIGHT_MIN);
                total += disk_vnodes;
                for (int k = 0; k < disk_vnodes; k++) {
                        hval = sd_hash_next(hval);
diff --git a/sheep/md.c b/sheep/md.c
index b95e032..7d45213 100644
--- a/sheep/md.c
+++ b/sheep/md.c
@@ -77,7 +77,7 @@ static void create_vdisks(const struct disk *disk)
        if (is_cluster_diskmode(&sys->cinfo)) {
                node_hval = sd_hash(&n->nid, offsetof(typeof(n->nid), io_addr));
                hval = fnv_64a_64(node_hval, hval);
-               nr = disk->space / WEIGHT_MIN;
+               nr = DIV_ROUND_UP(disk->space, WEIGHT_MIN);
                if (0 == n->nid.port)
                        return;
        } else
@@ -110,7 +110,7 @@ static void remove_vdisks(const struct disk *disk)
        if (is_cluster_diskmode(&sys->cinfo)) {
                node_hval = sd_hash(&n->nid, offsetof(typeof(n->nid), io_addr));
                hval = fnv_64a_64(node_hval, hval);
-               nr = disk->space / WEIGHT_MIN;
+               nr = DIV_ROUND_UP(disk->space, WEIGHT_MIN);
        } else
                nr = vdisk_number(disk);
 
-- 
1.7.12.4

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to