]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super1.c
Add information about reshape to --detail
[thirdparty/mdadm.git] / super1.c
index a503b945220a763df0c689d08a05f56af7c6e3b0..45c3d9562ab57b0c9ca0706a6b1770fc5d892462 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -28,8 +28,6 @@
  */
 
 #include "mdadm.h"
-#include <endian.h>
-#include "asm/byteorder.h"
 /*
  * The version-1 superblock :
  * All numeric fields are little-endian.
@@ -148,7 +146,8 @@ static void examine_super1(void *sbv)
        char *c;
 
        printf("          Magic : %08x\n", __le32_to_cpu(sb->magic));
-       printf("        Version : %02d.%02d\n", 1, __le32_to_cpu(sb->feature_map));
+       printf("        Version : %02d\n", 1);
+       printf("    Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map));
        printf("     Array UUID : ");
        for (i=0; i<16; i++) {
                if ((i&3)==0 && i != 0) printf(":");
@@ -192,8 +191,12 @@ static void examine_super1(void *sbv)
        }
        printf("\n");
        printf("\n");
+       if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+               printf("Internal Bitmap : %ld sectors from superblock\n",
+                      (long)__le32_to_cpu(sb->bitmap_offset));
+       }
        if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
-               printf("  Reshape pos'n : %llu%s\n", __le64_to_cpu(sb->reshape_position)/2,
+               printf("  Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
                       human_size(__le64_to_cpu(sb->reshape_position)<<9));
                if (__le32_to_cpu(sb->delta_disks)) {
                        printf("  Delta Devices : %d", __le32_to_cpu(sb->delta_disks));
@@ -350,7 +353,7 @@ static void uuid_from_super1(int uuid[4], void * sbv)
                cuuid[i] = super->set_uuid[i];
 }
 
-static void getinfo_super1(struct mdinfo *info, mddev_ident_t ident, void *sbv)
+static void getinfo_super1(struct mdinfo *info, void *sbv)
 {
        struct mdp_superblock_1 *sb = sbv;
        int working = 0;
@@ -365,6 +368,11 @@ static void getinfo_super1(struct mdinfo *info, mddev_ident_t ident, void *sbv)
        info->array.layout = __le32_to_cpu(sb->layout);
        info->array.md_minor = -1;
        info->array.ctime = __le64_to_cpu(sb->ctime);
+       info->array.utime = __le64_to_cpu(sb->utime);
+       info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512;
+
+       info->data_offset = __le64_to_cpu(sb->data_offset);
+       info->component_size = __le64_to_cpu(sb->size);
 
        info->disk.major = 0;
        info->disk.minor = 0;
@@ -391,8 +399,18 @@ static void getinfo_super1(struct mdinfo *info, mddev_ident_t ident, void *sbv)
 
        memcpy(info->uuid, sb->set_uuid, 16);
 
-       strncpy(ident->name, sb->set_name, 32);
-       ident->name[32] = 0;
+       strncpy(info->name, sb->set_name, 32);
+       info->name[32] = 0;
+
+       if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
+               info->reshape_active = 1;
+               info->reshape_progress = __le64_to_cpu(sb->reshape_position);
+               info->new_level = __le32_to_cpu(sb->new_level);
+               info->delta_disks = __le32_to_cpu(sb->delta_disks);
+               info->new_layout = __le32_to_cpu(sb->new_layout);
+               info->new_chunk = __le32_to_cpu(sb->new_chunk)<<9;
+       } else
+               info->reshape_active = 0;
 
        for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
                role = __le16_to_cpu(sb->dev_roles[i]);
@@ -450,6 +468,8 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update, char *dev
        }
        if (strcmp(update, "uuid") == 0)
                memcpy(sb->set_uuid, info->uuid, 16);
+       if (strcmp(update, "_reshape_progress")==0)
+               sb->reshape_position = __cpu_to_le64(info->reshape_progress);
 
        sb->sb_csum = calc_sb_1_csum(sb);
        return rv;
@@ -617,8 +637,8 @@ static int write_init_super1(struct supertype *st, void *sbv,
        int rfd;
        int rv;
 
-       unsigned long size;
-       unsigned long long dsize;
+       unsigned long size, space;
+       unsigned long long dsize, array_size;
        long long sb_offset;
 
 
@@ -678,7 +698,10 @@ static int write_init_super1(struct supertype *st, void *sbv,
         * 0: At least 8K, but less than 12K, from end of device
         * 1: At start of device
         * 2: 4K from start of device.
+        * Depending on the array size, we might leave extra space
+        * for a bitmap.
         */
+       array_size = __le64_to_cpu(sb->size);
        switch(st->minor_version) {
        case 0:
                sb_offset = dsize;
@@ -686,18 +709,29 @@ static int write_init_super1(struct supertype *st, void *sbv,
                sb_offset &= ~(4*2-1);
                sb->super_offset = __cpu_to_le64(sb_offset);
                sb->data_offset = __cpu_to_le64(0);
-               sb->data_size = __cpu_to_le64(sb_offset);
+               if (sb_offset-64*2 >= array_size && array_size > 8*1024*1024*2)
+                       sb->data_size = __cpu_to_le64(sb_offset-64*2);
+               else
+                       sb->data_size = __cpu_to_le64(sb_offset);
                break;
        case 1:
                sb->super_offset = __cpu_to_le64(0);
-               sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */
-               sb->data_size = __cpu_to_le64(dsize - 4*2);
+               if (dsize - 64*2 >= array_size && array_size > 8*1024*1024*2)
+                       space = 64*2;
+               else
+                       space = 4*2;
+               sb->data_offset = __cpu_to_le64(space); /* leave space for super and bitmap */
+               sb->data_size = __cpu_to_le64(dsize - space);
                break;
        case 2:
                sb_offset = 4*2;
+               if (dsize - 4*2 - 64*2 >= array_size && array_size > 8*1024*1024*2)
+                       space = 64*2;
+               else
+                       space = 4*2;
                sb->super_offset = __cpu_to_le64(sb_offset);
-               sb->data_offset = __cpu_to_le64(sb_offset+4*2);
-               sb->data_size = __cpu_to_le64(dsize - 4*2 - 4*2);
+               sb->data_offset = __cpu_to_le64(sb_offset+space);
+               sb->data_size = __cpu_to_le64(dsize - 4*2 - space);
                break;
        default:
                return -EINVAL;
@@ -892,7 +926,8 @@ static struct supertype *match_metadata_desc1(char *arg)
        st->ss = &super1;
        st->max_devs = 384;
        if (strcmp(arg, "1") == 0 ||
-           strcmp(arg, "1.0") == 0) {
+           strcmp(arg, "1.0") == 0 ||
+           strcmp(arg, "default/large") == 0) {
                st->minor_version = 0;
                return st;
        }
@@ -918,6 +953,14 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
        if (devsize < 24)
                return 0;
 
+       /* if the device is bigger than 8Gig, save 64k for bitmap usage,
+        * if biffer than 200Gig, save 128k
+        */
+       if (devsize > 200*1024*1024*2)
+               devsize -= 128*2;
+       else if (devsize > 8*1024*1024*2)
+               devsize -= 64*2;
+
        switch(st->minor_version) {
        case 0:
                /* at end */
@@ -934,7 +977,8 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
 
 static int
 add_internal_bitmap1(struct supertype *st, void *sbv,
-                    int chunk, int delay, int write_behind, unsigned long long size, int may_change, int major)
+                    int chunk, int delay, int write_behind, unsigned long long size,
+                    int may_change, int major)
 {
        /*
         * If not may_change, then this is a 'Grow', and the bitmap
@@ -968,6 +1012,8 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
                chunk = min_chunk;
        else if (chunk < min_chunk)
                return 0; /* chunk size too small */
+       if (chunk == 0) /* rounding problem */
+               return 0;
 
        sb->bitmap_offset = __cpu_to_le32(2);
 
@@ -989,16 +1035,18 @@ void locate_bitmap1(struct supertype *st, int fd, void *sbv)
 {
        unsigned long long offset;
        struct mdp_superblock_1 *sb;
+       int mustfree = 0;
 
-       if (!sbv)
-               if (st->ss->load_super(st, fd, sbv, NULL))
+       if (!sbv) {
+               if (st->ss->load_super(st, fd, &sbv, NULL))
                        return; /* no error I hope... */
-
+               mustfree = 1;
+       }
        sb = sbv;
 
        offset = __le64_to_cpu(sb->super_offset);
        offset += (long) __le32_to_cpu(sb->bitmap_offset);
-       if (!sbv)
+       if (mustfree)
                free(sb);
        lseek64(fd, offset<<9, 0);
 }
@@ -1014,7 +1062,9 @@ int write_bitmap1(struct supertype *st, int fd, void *sbv)
 
        locate_bitmap1(st, fd, sbv);
 
-       write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t));
+       if (write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)) !=
+           sizeof(bitmap_super_t))
+               return -2;
        towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
        towrite = (towrite+7) >> 3; /* bits to bytes */
        memset(buf, 0xff, sizeof(buf));