]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Increment version for clustered bitmaps
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index fe42b2b04584fab4279a032df2b512f6b9f78878..80d7b223e8ac0700ce9d43c7abc070ec5d36561c 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -297,6 +297,9 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                        "  between different architectures.  Consider upgrading the Linux kernel.\n");
        }
 
+       if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0)
+               major = BITMAP_MAJOR_CLUSTERED;
+
        if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
                if (errno == ENOMEM)
                        pr_err("Memory allocation failure.\n");
@@ -330,8 +333,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                        }
                        return 0;
                }
-               pr_err("Internal bitmap already present on %s\n",
-                       devname);
+               pr_err("%s bitmap already present on %s\n", s->bitmap_file, devname);
                return 1;
        }
 
@@ -375,7 +377,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                free(st);
                return 1;
        }
-       if (strcmp(s->bitmap_file, "internal") == 0) {
+       if (strcmp(s->bitmap_file, "internal") == 0 ||
+           strcmp(s->bitmap_file, "clustered") == 0) {
                int rv;
                int d;
                int offset_setable = 0;
@@ -384,6 +387,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                        pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name);
                        return 1;
                }
+               st->nodes = c->nodes;
+               st->cluster_name = c->homecluster;
                mdi = sysfs_read(fd, NULL, GET_BITMAP_LOCATION);
                if (mdi)
                        offset_setable = 1;
@@ -410,7 +415,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                                                    bitmapsize, offset_setable,
                                                    major)
                                                )
-                                               st->ss->write_bitmap(st, fd2);
+                                               st->ss->write_bitmap(st, fd2, NoUpdate);
                                        else {
                                                pr_err("failed to create internal bitmap - chunksize problem.\n");
                                                close(fd2);
@@ -426,6 +431,8 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                        rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
                                                  mdi->bitmap_offset);
                } else {
+                       if (strcmp(s->bitmap_file, "clustered") == 0)
+                               array.state |= (1<<MD_SB_CLUSTERED);
                        array.state |= (1<<MD_SB_BITMAP_PRESENT);
                        rv = ioctl(fd, SET_ARRAY_INFO, &array);
                }
@@ -612,10 +619,8 @@ static void unfreeze(struct supertype *st)
 
                if (sra &&
                    sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0
-                   && strcmp(buf, "frozen\n") == 0) {
-                       printf("unfreeze\n");
+                   && strcmp(buf, "frozen\n") == 0)
                        sysfs_set_str(sra, NULL, "sync_action", "idle");
-               }
                sysfs_free(sra);
        }
 }
@@ -850,7 +855,8 @@ int reshape_prepare_fdlist(char *devname,
        for (sd = sra->devs; sd; sd = sd->next) {
                if (sd->disk.state & (1<<MD_DISK_FAULTY))
                        continue;
-               if (sd->disk.state & (1<<MD_DISK_SYNC)) {
+               if (sd->disk.state & (1<<MD_DISK_SYNC) &&
+                   sd->disk.raid_disk < raid_disks) {
                        char *dn = map_dev(sd->disk.major,
                                           sd->disk.minor, 1);
                        fdlist[sd->disk.raid_disk]
@@ -1776,8 +1782,8 @@ int Grow_reshape(char *devname, int fd,
                                                   "raid5");
                                if (!rv) {
                                        raid0_takeover = 1;
-                                       /* get array parametes after takeover
-                                        * to chane one parameter at time only
+                                       /* get array parameters after takeover
+                                        * to change one parameter at time only
                                         */
                                        rv = ioctl(fd, GET_ARRAY_INFO, &array);
                                }
@@ -2539,7 +2545,7 @@ static void update_cache_size(char *container, struct mdinfo *sra,
        /* make sure there is room for 'blocks' with a bit to spare */
        if (cache < 16 + blocks / disks)
                cache = 16 + blocks / disks;
-       cache /= (4096/512); /* Covert from sectors to pages */
+       cache /= (4096/512); /* Convert from sectors to pages */
 
        if (sra->cache_size < cache)
                subarray_set_num(container, sra, "stripe_cache_size",
@@ -3184,7 +3190,7 @@ started:
        d = reshape_prepare_fdlist(devname, sra, odisks,
                                   nrdisks, blocks, backup_file,
                                   fdlist, offsets);
-       if (d < 0) {
+       if (d < odisks) {
                goto release;
        }
        if ((st->ss->manage_reshape == NULL) ||
@@ -3196,7 +3202,7 @@ started:
                                       devname);
                                pr_err(" Please provide one with \"--backup=...\"\n");
                                goto release;
-                       } else if (sra->array.spare_disks == 0) {
+                       } else if (d == odisks) {
                                pr_err("%s: Cannot grow - need a spare or backup-file to backup critical section\n", devname);
                                goto release;
                        }
@@ -3844,9 +3850,11 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
                 * So we need these extra tests.
                 */
                if (completed == 0 && advancing
+                   && strncmp(action, "idle", 4) == 0
                    && info->reshape_progress > 0)
                        break;
                if (completed == 0 && !advancing
+                   && strncmp(action, "idle", 4) == 0
                    && info->reshape_progress < (info->component_size
                                                 * reshape->after.data_disks))
                        break;
@@ -3856,27 +3864,30 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
        }
        /* Some kernels reset 'sync_completed' to zero,
         * we need to have real point we are in md.
-        * But only if array is actually still reshaping,
-        * not stopped.
+        * So in that case, read 'reshape_position' from sysfs.
         */
        if (completed == 0) {
+               unsigned long long reshapep;
                char action[20];
                if (sysfs_get_str(info, NULL, "sync_action",
                                  action, 20) > 0 &&
-                   strncmp(action, "reshape", 7) == 0)
-                       completed = max_progress;
-       }
-
-       /* some kernels can give an incorrectly high 'completed' number */
-       completed /= (info->new_chunk/512);
-       completed *= (info->new_chunk/512);
-       /* Convert 'completed' back in to a 'progress' number */
-       completed *= reshape->after.data_disks;
-       if (!advancing) {
-               completed = info->component_size * reshape->after.data_disks
-                       - completed;
+                   strncmp(action, "idle", 4) == 0 &&
+                   sysfs_get_ll(info, NULL,
+                                "reshape_position", &reshapep) == 0)
+                       *reshape_completed = reshapep;
+       } else {
+               /* some kernels can give an incorrectly high
+                * 'completed' number, so round down */
+               completed /= (info->new_chunk/512);
+               completed *= (info->new_chunk/512);
+               /* Convert 'completed' back in to a 'progress' number */
+               completed *= reshape->after.data_disks;
+               if (!advancing)
+                       completed = (info->component_size
+                                    * reshape->after.data_disks
+                                    - completed);
+               *reshape_completed = completed;
        }
-       *reshape_completed = completed;
 
        close(fd);
 
@@ -3896,7 +3907,6 @@ check_progress:
         * it was just a device failure that leaves us degraded but
         * functioning.
         */
-       strcpy(buf, "hi");
        if (sysfs_get_str(info, NULL, "reshape_position", buf, sizeof(buf)) < 0
            || strncmp(buf, "none", 4) != 0) {
                /* The abort might only be temporary.  Wait up to 10