[mdadm PATCH] Incremental: Use ->validate_geometry instead of ->avail_size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since mdadm 3.3 is has not been correct to call ->avail_size if
metadata hasn't been read from the device.  ->validate_geometry
should be used instead.

Unfortunately array_try_spare() didn't get the memo, and it can crash
when adding a spare with no metdata.

So change it to use ->validate_geometry().

Only one place remains that uses ->avail_size(), and that is safe.

Also fix a comment with a typo.

Reported-and-tested-by: Bjørnar Ness <bjornar.ness@xxxxxxxxx>
Fixes: 641da7459192 ("super1: separate to version of _avail_space1().")
Signed-off-by: NeilBrown <neilb@xxxxxxxx>
---
 Incremental.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index 91301eb5e609..0beab163e642 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -870,7 +870,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
 		struct supertype *st2;
 		struct domainlist *dl = NULL;
 		struct mdinfo *sra;
-		unsigned long long devsize;
+		unsigned long long devsize, freesize = 0;
 		struct spare_criteria sc = {0, 0};
 
 		if (is_subarray(mp->metadata))
@@ -942,10 +942,13 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
 			close(mdfd);
 		}
 		if ((sra->component_size > 0 &&
-		     st2->ss->avail_size(st2, devsize,
-					 sra->devs ? sra->devs->data_offset :
-					 INVALID_SECTORS) <
-		     sra->component_size) ||
+		     st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout,
+						sra->array.raid_disks, &sra->array.chunk_size,
+						sra->component_size,
+						sra->devs ? sra->devs->data_offset : INVALID_SECTORS,
+						devname, &freesize, sra->consistency_policy,
+						0) &&
+		     freesize < sra->component_size) ||
 		    (sra->component_size == 0 && devsize < sc.min_size)) {
 			if (verbose > 1)
 				pr_err("not adding %s to %s as it is too small\n",
@@ -1265,7 +1268,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
 	 * what arrays might be candidates.
 	 */
 	if (st) {
-		/* just try try 'array' or 'partition' based on this metadata */
+		/* just try to add 'array' or 'partition' based on this metadata */
 		if (st->ss->add_to_super)
 			return array_try_spare(devname, dfdp, pol, target, bare,
 					       st, verbose);
-- 
2.14.0.rc0.dirty

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux