]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: 4kn support for bad block log
authorTomasz Majchrzak <tomasz.majchrzak@intel.com>
Tue, 29 Nov 2016 13:02:35 +0000 (14:02 +0100)
committerJes Sorensen <Jes.Sorensen@redhat.com>
Fri, 2 Dec 2016 16:03:13 +0000 (11:03 -0500)
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
super-intel.c

index 560d21732590b1494985b5c9228fc4bf83f29eab..0407d43071f014ab4fcc1a6ae6af0a4eb260588c 100644 (file)
@@ -1526,6 +1526,7 @@ void convert_to_4k(struct intel_super *super)
        struct imsm_super *mpb = super->anchor;
        struct imsm_disk *disk;
        int i;
+       __u32 bbm_log_size = __le32_to_cpu(mpb->bbm_log_size);
 
        for (i = 0; i < mpb->num_disks ; i++) {
                disk = __get_imsm_disk(mpb, i);
@@ -1554,6 +1555,24 @@ void convert_to_4k(struct intel_super *super)
                        set_pba_of_lba0(map, pba_of_lba0(map)/IMSM_4K_DIV);
                }
        }
+       if (bbm_log_size) {
+               struct bbm_log *log = (void *)mpb +
+                       __le32_to_cpu(mpb->mpb_size) - bbm_log_size;
+               __u32 i;
+
+               for (i = 0; i < log->entry_count; i++) {
+                       struct bbm_log_entry *entry =
+                               &log->marked_block_entries[i];
+
+                       __u8 count = entry->marked_count + 1;
+                       unsigned long long sector =
+                               __le48_to_cpu(&entry->defective_block_start);
+
+                       entry->defective_block_start =
+                               __cpu_to_le48(sector/IMSM_4K_DIV);
+                       entry->marked_count = max(count/IMSM_4K_DIV, 1) - 1;
+               }
+       }
 
        mpb->check_sum = __gen_imsm_checksum(mpb);
 }
@@ -1635,6 +1654,7 @@ void convert_from_4k(struct intel_super *super)
        struct imsm_super *mpb = super->anchor;
        struct imsm_disk *disk;
        int i;
+       __u32 bbm_log_size = __le32_to_cpu(mpb->bbm_log_size);
 
        for (i = 0; i < mpb->num_disks ; i++) {
                disk = __get_imsm_disk(mpb, i);
@@ -1664,6 +1684,24 @@ void convert_from_4k(struct intel_super *super)
                        set_pba_of_lba0(map, pba_of_lba0(map)*IMSM_4K_DIV);
                }
        }
+       if (bbm_log_size) {
+               struct bbm_log *log = (void *)mpb +
+                       __le32_to_cpu(mpb->mpb_size) - bbm_log_size;
+               __u32 i;
+
+               for (i = 0; i < log->entry_count; i++) {
+                       struct bbm_log_entry *entry =
+                               &log->marked_block_entries[i];
+
+                       __u8 count = entry->marked_count + 1;
+                       unsigned long long sector =
+                               __le48_to_cpu(&entry->defective_block_start);
+
+                       entry->defective_block_start =
+                               __cpu_to_le48(sector*IMSM_4K_DIV);
+                       entry->marked_count = count*IMSM_4K_DIV - 1;
+               }
+       }
 
        mpb->check_sum = __gen_imsm_checksum(mpb);
 }