]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super0.c
Fix memory leak
[thirdparty/mdadm.git] / super0.c
index 4a165f9b7f30830dd47f53f5ef4018cf89dada0f..f3d0c07cc74750363c9a1b353d1a0f3a39b83053 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -387,6 +387,8 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info, char *map)
        } else
                info->reshape_active = 0;
 
+       info->recovery_blocked = info->reshape_active;
+
        sprintf(info->name, "%d", sb->md_minor);
        /* work_disks is calculated rather than read directly */
        for (i=0; i < MD_SB_DISKS; i++)
@@ -570,6 +572,10 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                sb->state &= ~(1<<MD_SB_BITMAP_PRESENT);
        } else if (strcmp(update, "_reshape_progress")==0)
                sb->reshape_position = info->reshape_progress;
+       else if (strcmp(update, "writemostly")==0)
+               sb->state |= (1<<MD_DISK_WRITEMOSTLY);
+       else if (strcmp(update, "readwrite")==0)
+               sb->state &= ~(1<<MD_DISK_WRITEMOSTLY);
        else
                rv = -1;
 
@@ -688,6 +694,8 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
        dk->minor = dinfo->minor;
        dk->raid_disk = dinfo->raid_disk;
        dk->state = dinfo->state;
+       /* In case our source disk was writemostly, don't copy that bit */
+       dk->state &= ~(1<<MD_DISK_WRITEMOSTLY);
 
        sb->this_disk = sb->disks[dinfo->number];
        sb->sb_csum = calc_sb0_csum(sb);
@@ -1115,6 +1123,13 @@ static int validate_geometry0(struct supertype *st, int level,
 {
        unsigned long long ldsize;
        int fd;
+       unsigned int tbmax = 4;
+
+       /* prior to linux 3.1, a but limits usable device size to 2TB.
+        * It was introduced in 2.6.29, but we won't worry about that detail
+        */
+       if (get_linux_version() < 3001000)
+               tbmax = 2;
 
        if (level == LEVEL_CONTAINER) {
                if (verbose)
@@ -1127,9 +1142,10 @@ static int validate_geometry0(struct supertype *st, int level,
                                MD_SB_DISKS);
                return 0;
        }
-       if (size > (0x7fffffffULL<<9)) {
+       if (size >= tbmax * 2ULL*1024*1024*1024) {
                if (verbose)
-                       fprintf(stderr, Name ": 0.90 metadata supports at most 2 terrabytes per device\n");
+                       fprintf(stderr, Name ": 0.90 metadata supports at most "
+                               "%d terabytes per device\n", tbmax);
                return 0;
        }
        if (chunk && *chunk == UnSet)
@@ -1154,8 +1170,6 @@ static int validate_geometry0(struct supertype *st, int level,
 
        if (ldsize < MD_RESERVED_SECTORS * 512)
                return 0;
-       if (size > (0x7fffffffULL<<9))
-               return 0;
        *freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
        return 1;
 }