Allow percentage setting for size=

Sometimes it's useful to set this to a particular size of a device.
Allowing percentages makes this more easy, as one does not have to
do the math outside of fio and pass in as environment variables
or custom job files.

To use, simply add a

	size=15%

or whatever is needed, then fio will use 15% of the total size of
the device(s) or file(s) given. Percentage can be from 1 to 100.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
diff --git a/parse.c b/parse.c
index 97ea4aa..ef23fbe 100644
--- a/parse.c
+++ b/parse.c
@@ -118,7 +118,8 @@
 	}
 }
 
-static unsigned long long __get_mult_bytes(const char *p, void *data)
+static unsigned long long __get_mult_bytes(const char *p, void *data,
+					   int *percent)
 {
 	unsigned int kb_base = fio_get_kb_base(data);
 	unsigned long long ret = 1;
@@ -158,6 +159,10 @@
 		pow = 2;
 	else if (!strcmp("k", c) || !strcmp("kb", c))
 		pow = 1;
+	else if (!strcmp("%", c)) {
+		*percent = 1;
+		return ret;
+	}
 
 	while (pow--)
 		ret *= (unsigned long long) mult;
@@ -166,12 +171,13 @@
 	return ret;
 }
 
-static unsigned long long get_mult_bytes(const char *str, int len, void *data)
+static unsigned long long get_mult_bytes(const char *str, int len, void *data,
+					 int *percent)
 {
 	const char *p = str;
 
 	if (len < 2)
-		return __get_mult_bytes(str, data);
+		return __get_mult_bytes(str, data, percent);
 
         /*
          * Go forward until we hit a non-digit
@@ -182,10 +188,10 @@
 		p++;
 	}
 
-	if (!isalpha((int) *p))
+	if (!isalpha((int) *p) && (*p != '%'))
 		p = NULL;
 
-	return __get_mult_bytes(p, data);
+	return __get_mult_bytes(p, data, percent);
 }
 
 /*
@@ -208,9 +214,16 @@
 	if (*val == LONG_MAX && errno == ERANGE)
 		return 1;
 
-	if (kilo)
-		*val *= get_mult_bytes(str, len, data);
-	else
+	if (kilo) {
+		unsigned long long mult;
+		int perc = 0;
+
+		mult = get_mult_bytes(str, len, data, &perc);
+		if (perc)
+			*val = -1ULL - *val;
+		else
+			*val *= mult;
+	} else
 		*val *= get_mult_time(str[len - 1]);
 
 	return 0;