Bug #7178
Updated by Andrew Stormont about 6 years ago
There is a flaw in the algorithm tmpfs uses to calculate available space. It assumes that tm_anonmax is always more than tm_anonmem and this is not always the case, for example, when remounting a full tmpfs filesystem with a smaller "size". The filesystem is full but statvfs reports that all memory is available. See in the example below how the capacity actually increases:
<pre>
# df -h /tmp/
Filesystem Size Used Available Capacity Mounted on
swap 1.0G 903M 121M 89% /tmp
# mount -o remount,size=512m /tmp
# df -h /tmp/
Filesystem Size Used Available Capacity Mounted on
swap 32G 903M 31G 3% /tmp
# mount -o remount,size=1024m /tmp
# df -h /tmp/
Filesystem Size Used Available Capacity Mounted on
swap 1.0G 903M 121M 89% /tmp
</pre>
The fix is simple one-line change (minus the copyright):
<pre>
diff --git a/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c b/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c
index f22cc3e..1611d63 100644
--- a/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c
+++ b/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright 2016 RackTop Systems.
*/
#include <sys/types.h>
@@ -589,7 +590,7 @@ tmp_statvfs(struct vfs *vfsp, struct statvfs64 *sbp)
* If tm_anonmax for this mount is less than the available swap space
* (minus the amount tmpfs can't use), use that instead
*/
- if (blocks > tmpfs_minfree)
+ if (blocks > tmpfs_minfree && tm->tm_anonmax > tm->tm_anonmem)
sbp->f_bfree = MIN(blocks - tmpfs_minfree,
tm->tm_anonmax - tm->tm_anonmem);
else
</pre>
Edit:
There are also issues with the way f_free and f_files are calculated. Both values should be based on tm_anonmax but this isn't the case currently.