return (a*1000000)+(b*1000)+c;
}
-long long parse_size(char *size)
+unsigned long long parse_size(char *size)
{
/* parse 'size' which should be a number optionally
* followed by 'K', 'M', or 'G'.
* Without a suffix, K is assumed.
* Number returned is in sectors (half-K)
- * -1 returned on error.
+ * INVALID_SECTORS returned on error.
*/
char *c;
long long s = strtoll(size, &c, 10);
s *= 1024 * 1024 * 2;
break;
}
- }
+ } else
+ s = INVALID_SECTORS;
if (*c)
- s = -1;
+ s = INVALID_SECTORS;
return s;
}
/* there must be one of the 'copies' form 'first' */
int n = copies;
int cnt = 0;
+ int this = first;
while (n--) {
- if (avail[first])
+ if (avail[this])
cnt++;
- first = (first+1) % raid_disks;
+ this = (this+1) % raid_disks;
}
if (cnt == 0)
return 0;
-
+ first = (first+(layout&255)) % raid_disks;
} while (first != 0);
return 1;
return buf;
}
-char *human_size_brief(long long bytes)
+char *human_size_brief(long long bytes, int prefix)
{
static char buf[30];
+ /* We convert bytes to either centi-M{ega,ibi}bytes or
+ * centi-G{igi,ibi}bytes, with appropriate rounding,
+ * and then print 1/100th of those as a decimal.
+ * We allow upto 2048Megabytes before converting to
+ * gigabytes, as that shows more precision and isn't
+ * too large a number.
+ * Terabytes are not yet handled.
+ *
+ * If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc.
+ * If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc.
+ */
+
if (bytes < 5000*1024)
- snprintf(buf, sizeof(buf), "%ld.%02ldKiB",
- (long)(bytes>>10), (long)(((bytes&1023)*100+512)/1024)
- );
- else if (bytes < 2*1024LL*1024LL*1024LL)
- snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
- (long)(bytes>>20),
- (long)((bytes&0xfffff)+0x100000/200)/(0x100000/100)
- );
+ buf[0] = 0;
+ else if (prefix == IEC) {
+ if (bytes < 2*1024LL*1024LL*1024LL) {
+ long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
+ cMiB/100 , cMiB % 100);
+ } else {
+ long cGiB = (bytes / ( (1LL<<30) / 200LL ) +1) /2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
+ cGiB/100 , cGiB % 100);
+ }
+ }
+ else if (prefix == JEDEC) {
+ if (bytes < 2*1024LL*1024LL*1024LL) {
+ long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldMB",
+ cMB/100, cMB % 100);
+ } else {
+ long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldGB",
+ cGB/100 , cGB % 100);
+ }
+ }
else
- snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
- (long)(bytes>>30),
- (long)(((bytes>>10)&0xfffff)+0x100000/200)/(0x100000/100)
- );
+ buf[0] = 0;
+
return buf;
}
}
return disks;
}
+
+/* Checks if paths point to the same device
+ * Returns 0 if they do.
+ * Returns 1 if they don't.
+ * Returns -1 if something went wrong,
+ * e.g. paths are empty or the files
+ * they point to don't exist */
+int compare_paths (char* path1, char* path2)
+{
+ struct stat st1,st2;
+
+ if (path1 == NULL || path2 == NULL)
+ return -1;
+ if (stat(path1,&st1) != 0)
+ return -1;
+ if (stat(path2,&st2) != 0)
+ return -1;
+ if ((st1.st_ino == st2.st_ino) && (st1.st_dev == st2.st_dev))
+ return 0;
+ return 1;
+}