From 2a5966a6517e3e99062c5796200389fb591091f6 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Fri, 21 Aug 2015 17:54:11 +0200 Subject: Adding RAID 5+0 support, memory fixes and improovements for big disks --- myraid.py | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'myraid.py') diff --git a/myraid.py b/myraid.py index 75402d9..4a6ad6a 100644 --- a/myraid.py +++ b/myraid.py @@ -79,6 +79,7 @@ class MyRaid(): self.raid_disk_count = 0 self.raid_layout = 'ls' self.raid_disks = [] + self.nested_subraid = 2 def get_raid_start(self): return self.raid_start @@ -182,7 +183,7 @@ class MyRaid(): if raid_type in ['1','5', '5+0']: result = ''.join( [ '0x%011x %c\n'%( addr, MyRaid.xor_blocks(self.raid_disks, addr, self.raid_sector_size)[0]) - for addr in range(start, end, self.raid_sector_size) + for addr in xrange(start, end, self.raid_sector_size) ]) else: result = None @@ -195,7 +196,7 @@ class MyRaid(): """Returns actual RAID data""" if raid_type == '0': segment_no = offset / self.raid_chunk_size - segment_off = offset % self.raid_chunk_size + segment_off = offset % self.raid_chunk_size stripe_no = segment_no / self.raid_disk_count par_disk = -1 data_disk = segment_no % self.raid_disk_count @@ -213,7 +214,7 @@ class MyRaid(): elif raid_type == '5': segment_no = offset / self.raid_chunk_size - segment_off = offset % self.raid_chunk_size + segment_off = offset % self.raid_chunk_size stripe_no = segment_no / (self.raid_disk_count-1) if self.raid_layout in ['ls','la']: @@ -229,8 +230,35 @@ class MyRaid(): data_disk = data_disk + 1 off_disk = self.raid_start + stripe_no * self.raid_chunk_size + segment_off - # Note : self make shorter read than asked but convince the reader to be chunck aligned, which is great + # Note : could make error-free shorter reads than asked but convince the reader to be chunck aligned, which is great for perf size2 = min(size, (segment_no+1) * self.raid_chunk_size - offset) + + elif raid_type == '5+0': + subraid_disk_count = self.raid_disk_count / self.nested_subraid + segment_no = offset / self.raid_chunk_size + segment_off = offset % self.raid_chunk_size + stripe_no = segment_no / (self.raid_disk_count - self.nested_subraid) # segment_no / 12 + subraid_no = (segment_no / (subraid_disk_count-1) ) % self.nested_subraid # (segment_no/6) mod 2 + + if self.raid_layout in ['ls','la']: + subraid_par_disk = (subraid_disk_count-1) - (stripe_no % subraid_disk_count) + else: # self.raid_layout in ['rs','ra']: + subraid_par_disk = stripe_no % subraid_disk_count + + if self.raid_layout in ['ls','rs']: + subraid_data_disk = (subraid_par_disk+1 + (segment_no % (subraid_disk_count-1)) ) % subraid_disk_count + else: # self.raid_layout in ['la','ra']: + subraid_data_disk = segment_no % (subraid_disk_count-1) + if subraid_data_disk >= subraid_par_disk: + subraid_data_disk = subraid_data_disk + 1 + + par_disk = subraid_no * subraid_disk_count + subraid_par_disk + data_disk = subraid_no * subraid_disk_count + subraid_data_disk + + off_disk = self.raid_start + stripe_no * self.raid_chunk_size + segment_off + # Note : could make error-free shorter reads than asked but convince the reader to be chunck aligned, which is great for perf + size2 = min(size, (segment_no+1) * self.raid_chunk_size - offset) + else: raise Exception('Unimplemented read_raid_result() for raid_type == %s', raid_type) @@ -253,7 +281,7 @@ class MyRaid(): other_fds.remove(data_fd) data_arr = [] - for s in range(off_disk, off_disk+size2, self.raid_sector_size): + for s in xrange(off_disk, off_disk+size2, self.raid_sector_size): if self.d.is_readable(self.raid_disk_order[data_disk],s,self.raid_sector_size): # Current sector is readable from data disk, read it logging.debug('-> 0x%011x : readable'%s) -- cgit v1.2.3