[PATCH] corrupted free inodes list
- From: Mikulas Patocka <mikulas artax karlin mff cuni cz>
- To: mc-devel gnome org
- Subject: [PATCH] corrupted free inodes list
- Date: Wed, 20 Dec 2006 02:15:38 +0100 (CET)
Hi
I've found on three machines (I wonder that no one noticed it so far) that
mc displays incorrect information on inode count, for example:
| Filesystem: / |
| Device: /dev/md0 |
| Type: ext2 |
| Free space: 161G (0%) of 552G |
| Free nodes: 32864471 (-27%) of 364380
| Filesystem: /home |
| Device: /dev/md0 |
| Type: xfs |
| Free space: 15G (13%) of 117G |
| Free nodes: 64702776 (-31%) of 669767
| Filesystem: COMMON:/ |
| Device: DISK1-P2:/ |
| Type: SPADFS |
| Free space: 36G (40%) of 88G |
| Free nodes: 74794575 (-5%) of 1850848
--- the bug is obviously caused by integer overflow when multiplying by
100. When I further investigated the code, I found that it stores free
space and free inode count only in "int" variable --- it will cause
problems with devices with more than 2^31 blocks (they already exists, but
I don't have such). --- so I fixed both block and inode display to use
double instead --- after aplying the patch, the output looks sane:
| Filesystem: HOME:/ |
| Device: DISK1-P2:/ |
| Type: SPADFS |
| Free space: 36G (40%) of 88G |
| Free nodes: 71M (40%) of 177M |
--- maybe you could change double to "long long" but I'm not sure if it
exists on all machines --- a configure test would probably be needed.
Mikulas
diff -u -r x/mc-4.6.1/src/info.c mc-4.6.1/src/info.c
--- x/mc-4.6.1/src/info.c 2006-12-20 02:53:44.000000000 +0200
+++ mc-4.6.1/src/info.c 2006-12-20 03:08:30.000000000 +0200
@@ -99,13 +99,15 @@
case 16:
widget_move (&info->widget, 16, 3);
- if (myfs_stats.nfree >0 && myfs_stats.nodes > 0)
- printw (const_cast(char *, _("Free nodes: %d (%d%%) of %d")),
- myfs_stats.nfree,
- myfs_stats.total
- ? 100 * myfs_stats.nfree / myfs_stats.nodes : 0,
- myfs_stats.nodes);
- else
+ if (myfs_stats.nfree >0 && myfs_stats.nodes > 0){
+ char buffer1 [6], buffer2[6];
+ size_trunc_len (buffer1, 5, myfs_stats.nfree, 0);
+ size_trunc_len (buffer2, 5, myfs_stats.nodes, 0);
+ printw (const_cast(char *, _("Free nodes: %s (%d%%) of %s")),
+ buffer1,
+ (int)(100 * myfs_stats.nfree / myfs_stats.nodes),
+ buffer2);
+ } else
addstr (_("No node information"));
case 15:
@@ -114,8 +116,9 @@
char buffer1 [6], buffer2[6];
size_trunc_len (buffer1, 5, myfs_stats.avail, 1);
size_trunc_len (buffer2, 5, myfs_stats.total, 1);
- printw (const_cast(char *, _("Free space: %s (%d%%) of %s")), buffer1, myfs_stats.total ?
- (int)(100 * (double)myfs_stats.avail / myfs_stats.total) : 0,
+ printw (const_cast(char *, _("Free space: %s (%d%%) of %s")),
+ buffer1,
+ (int)(100 * myfs_stats.avail / myfs_stats.total),
buffer2);
} else
addstr (_("No space information"));
diff -u -r x/mc-4.6.1/src/mountlist.c mc-4.6.1/src/mountlist.c
--- x/mc-4.6.1/src/mountlist.c 2006-12-20 02:53:44.000000000 +0200
+++ mc-4.6.1/src/mountlist.c 2006-12-20 02:57:20.000000000 +0200
@@ -132,11 +132,11 @@
struct fs_usage
{
- long fsu_blocks; /* Total blocks. */
- long fsu_bfree; /* Free blocks available to superuser. */
- long fsu_bavail; /* Free blocks available to non-superuser. */
- long fsu_files; /* Total file nodes. */
- long fsu_ffree; /* Free file nodes. */
+ double fsu_blocks; /* Total blocks. */
+ double fsu_bfree; /* Free blocks available to superuser. */
+ double fsu_bavail; /* Free blocks available to non-superuser. */
+ double fsu_files; /* Total file nodes. */
+ double fsu_ffree; /* Free file nodes. */
};
static int get_fs_usage (char *path, struct fs_usage *fsp);
@@ -663,8 +663,8 @@
BLOCKS FROMSIZE-byte blocks, rounding away from zero.
TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */
-static long
-fs_adjust_blocks (long blocks, int fromsize, int tosize)
+static double
+fs_adjust_blocks (double blocks, int fromsize, int tosize)
{
if (tosize <= 0)
abort ();
@@ -676,7 +676,7 @@
else if (fromsize > tosize) /* E.g., from 2048 to 512. */
return blocks * (fromsize / tosize);
else /* E.g., from 256 to 512. */
- return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize);
+ return blocks / (tosize / fromsize);
}
#if defined(_AIX) && defined(_I386)
diff -u -r X/MC-4.6.1/SRC/MOUNTLIST.H MC-4.6.1/SRC/MOUNTLIST.H
--- x/mc-4.6.1/src/mountlist.h 2006-12-20 02:53:44.000000000 +0200
+++ mc-4.6.1/src/mountlist.h 2006-12-20 02:57:38.000000000 +0200
@@ -24,10 +24,10 @@
char *typename;
const char *mpoint;
const char *device;
- int avail;
- int total;
- int nfree;
- int nodes;
+ double avail;
+ double total;
+ double nfree;
+ double nodes;
};
void init_my_statfs (void);
diff -u -r X/MC-4.6.1/SRC/UTIL.C MC-4.6.1/SRC/UTIL.C
--- x/mc-4.6.1/src/util.c 2006-12-20 02:53:44.000000000 +0200
+++ mc-4.6.1/src/util.c 2006-12-20 03:02:49.000000000 +0200
@@ -314,7 +314,7 @@
* 0=bytes, 1=Kbytes, 2=Mbytes, etc.
*/
void
-size_trunc_len (char *buffer, int len, off_t size, int units)
+size_trunc_len (char *buffer, int len, double size, int units)
{
/* Avoid taking power for every file. */
static const off_t power10 [] =
@@ -329,7 +329,7 @@
len = 9;
for (j = units; suffix [j] != NULL; j++) {
- if (size == 0) {
+ if (size < 0.5) {
if (j == units) {
/* Empty files will print "0" even with minimal width. */
g_snprintf (buffer, len + 1, "0");
@@ -342,13 +342,13 @@
break;
}
- if (size < power10 [len - (j > 0)]) {
+ if (size < power10 [len - (j > 0)] && size <= MAXULONG) {
g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, suffix[j]);
break;
}
/* Powers of 1024, with rounding. */
- size = (size + 512) >> 10;
+ size = (size + 512) / 1024;
}
}
diff -u -r x/mc-4.6.1/src/util.h mc-4.6.1/src/util.h
--- x/mc-4.6.1/src/util.h 2006-12-20 02:53:44.000000000 +0200
+++ mc-4.6.1/src/util.h 2006-12-20 03:02:59.000000000 +0200
@@ -47,7 +47,7 @@
* not including trailing 0. BUFFER should be at least LEN+1 long.
*
* Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */
-void size_trunc_len (char *buffer, int len, off_t size, int units);
+void size_trunc_len (char *buffer, int len, double size, int units);
int is_exe (mode_t mode);
const char *string_perm (mode_t mode_bits);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]