]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: Support setting max size for size change operation
authorAdam Kwolek <adam.kwolek@intel.com>
Fri, 13 Apr 2012 14:52:05 +0000 (16:52 +0200)
committerNeilBrown <neilb@suse.de>
Tue, 17 Apr 2012 02:33:38 +0000 (12:33 +1000)
Add support for setting max size for size change operation using
imsm_get_free_size() function for computing maximum available space.

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
super-intel.c

index 7cc0ed5f532b03be705bdd2ed42e85f81a1ba04d..1f472344c280063329abe064c94f20f8b91a9a5e 100644 (file)
@@ -9953,7 +9953,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
         */
        current_size = info.custom_array_size / 2 / data_disks;
 
-       if ((current_size != geo->size) && (geo->size > 0)) {
+       if ((current_size != geo->size) && (geo->size >= 0)) {
                if (change != -1) {
                        fprintf(stderr,
                                Name " Error. Size change should be the only "
@@ -9968,7 +9968,27 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
                                super->current_vol, st->devnum);
                        goto analyse_change_exit;
                }
-               geo->size *= 2;
+               if (geo->size == 0) {
+                       /* requested size change to the maximum available size
+                        */
+                       unsigned long long freesize;
+                       int rv;
+
+                       rv =  imsm_get_free_size(st, dev->vol.map->num_members,
+                                                0, chunk, &freesize);
+                       if (rv == 0) {
+                               fprintf(stderr, Name " Error. Cannot find "
+                                       "maximum available space.\n");
+                               change = -1;
+                               goto analyse_change_exit;
+                       }
+                       geo->size = freesize + current_size;
+
+                       /* round to chunk size */
+                       geo->size &= ~(chunk-1);
+               } else
+                       geo->size *= 2;
+
                if ((direction == ROLLBACK_METADATA_CHANGES)) {
                        /* accept size for rollback only
                        */