From c27e4e80aab97eeb786d3c6ee6403074d3ffb147 Mon Sep 17 00:00:00 2001
From: Hans van Kranenburg <hans@knorrie.org>
Date: Fri, 22 Mar 2019 00:03:20 +0100
Subject: [PATCH] space-calculator: quickfix crash when using raid5

Andrei Borzenkov reported that when using raid5 in the options, the
program crashes:

  File "/home/bor/src/python-btrfs/bin/btrfs/volumes.py", line 192,
      in chunk_length_to_dev_extent_length
    dev_extent_length = raw_data_bytes // num_data_stripes
ZeroDivisionError: integer division or modulo by zero

The way this space calculator works is a little bit naughty. By
constructing some fake replacements for the official Chunk, Stripe etc
classes, we fool the usage report module and have it believe it's
looking at an actual filesystem.

In order to do so, we need to present at least one fake chunk of each
chosen profile (for data, metadata etc) to it, so it can take over from
there and do a simulation filling up the rest of the raw space.

The FakeChunk had num_stripes = 1 hardcoded, which obviously is fragile.
In the specific case of RAID5, it crashes because the nparity is
subtracted from num_stripes, which makes it 0.

---- >8 ----

Newer python-btrfs code gets a proper fix that's >120 lines of changes
and is more future-proof. However, to just make the functionality work
with minimal changes, we can increase num_stripes a bit so that it will
never hit zero when subtracting nparity.
---
 bin/btrfs-space-calculator | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bin/btrfs-space-calculator b/bin/btrfs-space-calculator
index cb7f8f6..7586c7d 100755
--- a/bin/btrfs-space-calculator
+++ b/bin/btrfs-space-calculator
@@ -54,8 +54,8 @@ class FakeChunk(object):
     def __init__(self, flags):
         self.type = flags
         self.length = 1
-        self.stripes = [FakeStripe()]
-        self.num_stripes = 1
+        self.stripes = [FakeStripe()] * 4
+        self.num_stripes = 4
 
 
 class FakeFileSystem(object):
-- 
2.11.0

