File 0068-super1-make-internal-bitmap-size-calculations-more-c.patch of Package mdadm.7129
From 561ad5597bf472f8114260d144a5e8ba5c7246d5 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Thu, 10 Nov 2016 11:50:53 +0100
Subject: [PATCH 321/359] super1: make internal bitmap size calculations more
consistent
References: bsc#1081910
Determining internal bitmap size is performed using two different
functions (bitmap_sectors() and calc_bitmap_size()) and in
getinfo_super1() it is calculated in yet another way. Each of these
methods give slightly different results. The most accurate is
calc_bitmap_size() but it also has a rounding issue. So:
- fix the rounding issue in calc_bitmap_size() using bitmap_bits()
- replace usages of bitmap_sectors() and open-coded calculations with
calc_bitmap_size()
- remove bitmap_sectors()
- move bitmap_bits() to mdadm.h as inline - otherwise mdassemble won't
compile (it does not use bitmap.c)
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Coly Li <colyli@suse.de>
---
bitmap.c | 15 ---------------
mdadm.h | 9 ++++++++-
super1.c | 25 +++++++++----------------
3 files changed, 17 insertions(+), 32 deletions(-)
Index: mdadm-3.3.1/bitmap.c
===================================================================
--- mdadm-3.3.1.orig/bitmap.c
+++ mdadm-3.3.1/bitmap.c
@@ -108,21 +108,6 @@ int count_dirty_bits(char *buf, int num_
return num;
}
-/* calculate the size of the bitmap given the array size and bitmap chunksize */
-unsigned long long bitmap_bits(unsigned long long array_size,
- unsigned long chunksize)
-{
- return (array_size * 512 + chunksize - 1) / chunksize;
-}
-
-unsigned long bitmap_sectors(struct bitmap_super_s *bsb)
-{
- unsigned long long bits = bitmap_bits(__le64_to_cpu(bsb->sync_size),
- __le32_to_cpu(bsb->chunksize));
- int bits_per_sector = 8*512;
- return (bits + bits_per_sector - 1) / bits_per_sector;
-}
-
bitmap_info_t *bitmap_fd_read(int fd, int brief)
{
/* Note: fd might be open O_DIRECT, so we must be
Index: mdadm-3.3.1/mdadm.h
===================================================================
--- mdadm-3.3.1.orig/mdadm.h
+++ mdadm-3.3.1/mdadm.h
@@ -1327,7 +1327,14 @@ extern int CreateBitmap(char *filename,
extern int ExamineBitmap(char *filename, int brief, struct supertype *st);
extern int Write_rules(char *rule_name);
extern int bitmap_update_uuid(int fd, int *uuid, int swap);
-extern unsigned long bitmap_sectors(struct bitmap_super_s *bsb);
+
+/* calculate the size of the bitmap given the array size and bitmap chunksize */
+static inline unsigned long long
+bitmap_bits(unsigned long long array_size, unsigned long chunksize)
+{
+ return (array_size * 512 + chunksize - 1) / chunksize;
+}
+
extern int Dump_metadata(char *dev, char *dir, struct context *c,
struct supertype *st);
extern int Restore_metadata(char *dev, char *dir, struct context *c,
Index: mdadm-3.3.1/super1.c
===================================================================
--- mdadm-3.3.1.orig/super1.c
+++ mdadm-3.3.1/super1.c
@@ -162,7 +162,8 @@ static unsigned int calc_bitmap_size(bit
{
unsigned long long bits, bytes;
- bits = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
+ bits = bitmap_bits(__le64_to_cpu(bms->sync_size),
+ __le32_to_cpu(bms->chunksize));
bytes = (bits+7) >> 3;
bytes += sizeof(bitmap_super_t);
bytes = ROUND_UP(bytes, boundary);
@@ -973,11 +974,7 @@ static void getinfo_super1(struct supert
earliest = super_offset + (32+4)*2; /* match kernel */
if (info->bitmap_offset > 0) {
unsigned long long bmend = info->bitmap_offset;
- unsigned long long size = __le64_to_cpu(bsb->sync_size);
- size /= __le32_to_cpu(bsb->chunksize) >> 9;
- size = (size + 7) >> 3;
- size += sizeof(bitmap_super_t);
- size = ROUND_UP(size, 4096);
+ unsigned long long size = calc_bitmap_size(bsb, 4096);
size /= 512;
bmend += size;
if (bmend > earliest)
@@ -1225,11 +1222,8 @@ static int update_super1(struct supertyp
} else if (strcmp(update, "uuid") == 0) {
copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid);
- if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
- struct bitmap_super_s *bm;
- bm = (struct bitmap_super_s*)(st->sb+MAX_SB_SIZE);
- memcpy(bm->uuid, sb->set_uuid, 16);
- }
+ if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)
+ memcpy(bms->uuid, sb->set_uuid, 16);
} else if (strcmp(update, "no-bitmap") == 0) {
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
} else if (strcmp(update, "bbl") == 0) {
@@ -1238,15 +1232,14 @@ static int update_super1(struct supertyp
*/
unsigned long long sb_offset = __le64_to_cpu(sb->super_offset);
unsigned long long data_offset = __le64_to_cpu(sb->data_offset);
- long bitmap_offset = (long)(int32_t)__le32_to_cpu(sb->bitmap_offset);
+ long bitmap_offset = 0;
long bm_sectors = 0;
long space;
#ifndef MDASSEMBLE
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
- struct bitmap_super_s *bsb;
- bsb = (struct bitmap_super_s *)(((char*)sb)+MAX_SB_SIZE);
- bm_sectors = bitmap_sectors(bsb);
+ bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+ bm_sectors = calc_bitmap_size(bms, 4096) >> 9;
}
#endif
if (sb_offset < data_offset) {
@@ -2139,7 +2132,7 @@ static __u64 avail_size1(struct supertyp
/* hot-add. allow for actual size of bitmap */
struct bitmap_super_s *bsb;
bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
- bmspace = bitmap_sectors(bsb);
+ bmspace = calc_bitmap_size(bsb, 4096) >> 9;
}
#endif
/* Allow space for bad block log */