]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: If bitmap interferes with grow, report this.
authorNeilBrown <neilb@suse.de>
Thu, 28 Jan 2010 00:48:03 +0000 (11:48 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 28 Jan 2010 00:48:03 +0000 (11:48 +1100)
If a bitmap exists on an array, then current kernels cannot grow
that array.
So when we try to grow an array, test for EBUSY and if a bitmap is
present, report that the bitmap needs to be removed.

Resolves-Debian-Bug: 534571
Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c

diff --git a/Grow.c b/Grow.c
index 8d9853b22440b2fc00cf264a4f069b1d7e8afc82..efa8c47271439743ab53521ec1bb1994f78bb990 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -563,8 +563,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                } else
                        rv = ioctl(fd, SET_ARRAY_INFO, &array);
                if (rv != 0) {
+                       int err = errno;
                        fprintf(stderr, Name ": Cannot set device size for %s: %s\n",
-                               devname, strerror(errno));
+                               devname, strerror(err));
+                       if (err == EBUSY && 
+                           (array.state & (1<<MD_SB_BITMAP_PRESENT)))
+                               fprintf(stderr, "       Bitmap must be removed before size can be changed\n");
                        rv = 1;
                        goto release;
                }
@@ -666,8 +670,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        }
                        err = sysfs_set_str(sra, NULL, "level", c);
                        if (err) {
+                               err = errno;
                                fprintf(stderr, Name ": %s: could not set level to %s\n",
                                        devname, c);
+                               if (err == EBUSY && 
+                                   (array.state & (1<<MD_SB_BITMAP_PRESENT)))
+                                       fprintf(stderr, "       Bitmap must be removed before level can be changed\n");
                                rv = 1;
                                goto release;
                        }
@@ -733,9 +741,14 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        c = map_num(pers, level);
                        if (c) {
                                rv = sysfs_set_str(sra, NULL, "level", c);
-                               if (rv)
+                               if (rv) {
+                                       int err = errno;
                                        fprintf(stderr, Name ": %s: could not set level to %s\n",
                                                devname, c);
+                                       if (err == EBUSY && 
+                                           (array.state & (1<<MD_SB_BITMAP_PRESENT)))
+                                               fprintf(stderr, "       Bitmap must be removed before level can be changed\n");
+                               }
                        }
                } else if (!changed && !quiet)
                        fprintf(stderr, Name ": %s: no change requested\n",
@@ -1066,12 +1079,16 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                if (ochunk == nchunk && olayout == nlayout) {
                        array.raid_disks = ndisks;
                        if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
+                               int err = errno;
                                rv = 1;
                                fprintf(stderr, Name ": Cannot set device shape for %s: %s\n",
                                        devname, strerror(errno));
                                if (ndisks < odisks &&
                                    get_linux_version() < 2006030)
                                        fprintf(stderr, Name ": linux 2.6.30 or later required\n");
+                               if (err == EBUSY && 
+                                   (array.state & (1<<MD_SB_BITMAP_PRESENT)))
+                                       fprintf(stderr, "       Bitmap must be removed before shape can be changed\n");
 
                                break;
                        }
@@ -1079,17 +1096,21 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        /* set them all just in case some old 'new_*' value
                         * persists from some earlier problem
                         */
+                       int err;
                        if (sysfs_set_num(sra, NULL, "chunk_size", nchunk) < 0)
-                               rv = 1;
-                       if (sysfs_set_num(sra, NULL, "layout", nlayout) < 0)
-                               rv = 1;
-                       if (sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0)
-                               rv = 1;
+                               rv = 1, err = errno;
+                       if (!rv && sysfs_set_num(sra, NULL, "layout", nlayout) < 0)
+                               rv = 1, err = errno;
+                       if (!rv && sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0)
+                               rv = 1, err = errno;
                        if (rv) {
                                fprintf(stderr, Name ": Cannot set device shape for %s\n",
                                        devname);
                                if (get_linux_version() < 2006030)
                                        fprintf(stderr, Name ": linux 2.6.30 or later required\n");
+                               if (err == EBUSY && 
+                                   (array.state & (1<<MD_SB_BITMAP_PRESENT)))
+                                       fprintf(stderr, "       Bitmap must be removed before shape can be changed\n");
                                break;
                        }
                }