svn commit: trunk/busybox/miscutils

vda at busybox.net vda at busybox.net
Fri Sep 28 13:38:08 UTC 2007


Author: vda
Date: 2007-09-28 06:38:08 -0700 (Fri, 28 Sep 2007)
New Revision: 20083

Log:
hdparm: more robust (re overflows) code. +38 bytes.



Modified:
   trunk/busybox/miscutils/hdparm.c


Changeset:
Modified: trunk/busybox/miscutils/hdparm.c
===================================================================
--- trunk/busybox/miscutils/hdparm.c	2007-09-28 11:37:38 UTC (rev 20082)
+++ trunk/busybox/miscutils/hdparm.c	2007-09-28 13:38:08 UTC (rev 20083)
@@ -1353,35 +1353,34 @@
 		buf[i] &= 1;
 }
 
-static unsigned long long dev_size_mb(/*int fd*/ void)
+static unsigned dev_size_mb(/*int fd*/ void)
 {
 	union {
 		unsigned long long blksize64;
 		unsigned blksize32;
 	} u;
 
-	if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // returns bytes
-		return u.blksize64 / (1024 * 1024);
+	if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
+		u.blksize64 /= (1024 * 1024);
+	} else {
+		xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
+		u.blksize64 = u.blksize32 / (2 * 1024);
 	}
-	xioctl(fd, BLKGETSIZE, &u.blksize32); // returns sectors
-	return u.blksize32 / (2 * 1024);
+	if (u.blksize64 > UINT_MAX)
+		return UINT_MAX;
+	return u.blksize64;
 }
 
-static void print_timing(unsigned long m, unsigned elapsed_us)
+static void print_timing(unsigned m, unsigned elapsed_us)
 {
 	unsigned sec = elapsed_us / 1000000;
 	unsigned hs = (elapsed_us % 1000000) / 10000;
 
-	printf("%5lu MB in %u.%02u seconds = %lu kB/s\n",
+	printf("%5u MB in %u.%02u seconds = %u kB/s\n",
 		m, sec, hs,
-		/* Trying to not overflow 32-bit arith in m * CONST
-		 * by keeping CONST not so big. But elapsed_us / CONST2 
-		 * also should not introduce big errors. Currently,
-		 * 16000us is ~1.6% of 1 second.
-		 * "+ 1" prevents div-by-0. */
-		(m * (1024 * 1000000 / (16*1024))) / (elapsed_us / (16*1024) + 1)
-		// ~= (m * 1024 * 1000000) / elapsed_us
-		// = (m * 1024) / (elapsed_us / 1000000)
+		/* + 1 prevents div-by-0 */
+		(unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us + 1))
+		// ~= (m * 1024) / (elapsed_us / 1000000)
 		// = kb / elapsed_sec
 	);
 }
@@ -1392,19 +1391,14 @@
  */
 {
 	unsigned max_iterations, iterations;
-	unsigned start; /* don't need to be long long */
+	unsigned start; /* doesn't need to be long long */
 	unsigned elapsed, elapsed2;
-	unsigned long total_MB;
+	unsigned total_MB;
 	char *buf = xmalloc(TIMING_BUF_BYTES);
 
 	if (mlock(buf, TIMING_BUF_BYTES))
 		bb_perror_msg_and_die("mlock");
 
-	/* Don't want to read past the end! */
-	max_iterations = UINT_MAX;
-	if (!cache)
-		max_iterations = dev_size_mb() / TIMING_BUF_MB;
-
 	/* Clear out the device request queues & give them time to complete.
 	 * NB: *small* delay. User is expected to have a clue and to not run
 	 * heavy io in parallel with measurements. */
@@ -1422,10 +1416,14 @@
 	/* Now do the timing */
 	iterations = 0;
 	/* Max time to run (small for cache, avoids getting
-	 * huge total_MB which can overlow on print_timing) */
+	 * huge total_MB which can overlow unsigned type) */
 	elapsed2 = 510000; /* cache */
-	if (!cache)
+	max_iterations = UINT_MAX;
+	if (!cache) {
 		elapsed2 = 3000000; /* not cache */
+		/* Don't want to read past the end! */
+		max_iterations = dev_size_mb() / TIMING_BUF_MB;
+	}
 	start = monotonic_us();
 	do {
 		if (cache)
@@ -1434,7 +1432,7 @@
 		elapsed = (unsigned)monotonic_us() - start;
 		++iterations;
 	} while (elapsed < elapsed2 && iterations < max_iterations);
-	total_MB = (unsigned long)iterations * TIMING_BUF_MB;
+	total_MB = iterations * TIMING_BUF_MB;
 	//printf(" elapsed:%u iterations:%u ", elapsed, iterations);
 	if (cache) {
 		/* Cache: remove lseek() and monotonic_us() overheads




More information about the busybox-cvs mailing list