There were two problems:
1) au_add_till_max returns ULLONG_MAX if b==0
Reason: in this case, a is not bigger then old but equal. This is the reason
for the very big values which confuse df.
2) If aufs is mounted in sum mode, but the source file systems have different
block sizes, the result of the statfs might not be useable.
In my case, I have a squashfs system as root with data but no free space (read
only file system) and a tmpfs. Both have very different block sizes. This could
even result in f_bfree>f_blocks.
=============
PLEASE REVIEW MY PATCH CAREFULLY.
It is my first kernel-code work. I think the changes in au_statfs_sum are quite
good, but au_add_muldiv_till_max is just a hack. I did not know how to handle an
overflow in the multiplication, and there an overflow is much more likely than
in the addition. Maybe bit-shifting is the way-to-go, but then you need to count
bits in bsize (mul and div), which is much more complicated, and you have to be
ready to shift in both ways.
Patches are against origin/aufs3.0 in aufs3-standalone, but I also tested it
with
the aufs2.2-38 branch in aufs2-standalone.
=============
Example:
/dev/loop0 17152 17152 0 100% /root/aufstest/_L1_root (squashfs; block size
131072)
tmp 253488 16 253472 1% /root/aufstest/_L2_tmp (tmpfs, block size 4096)
mount -t aufs -o dirs=/root/aufstest/_L2_tmp=rw:/root/aufstest/_L1_root=ro,sum
none _aufs
Result (without patch, something like):
none - - - ?% /root/aufstest/_aufs
Result (with patch):
none 270640 17168 253472 7% /root/aufstest/_aufs
output of "strace df -h _L1_root/ _L2_tmp/ _aufs 2>&1 | grep statfs":
before:
statfs64("_L1_root/", 84, {f_type=0x73717368, f_bsize=131072, f_blocks=134,
f_bfree=0, f_bavail=0, f_files=13, f_ffree=0, f_fsid={1792, 0}, f_namelen=256,
f_frsize=131072}) = 0
statfs64("_L2_tmp/", 84, {f_type=0x1021994, f_bsize=4096, f_blocks=63372,
f_bfree=63368, f_bavail=63368, f_files=63372, f_ffree=63364, f_fsid={0, 0},
f_namelen=255, f_frsize=4096}) = 0
statfs64("_aufs", 84, {f_type=0x61756673, f_bsize=4096, f_blocks=63506,
f_bfree=18446744073709551615, f_bavail=18446744073709551615, f_files=63385,
f_ffree=18446744073709551615, f_fsid={0, 0}, f_namelen=242, f_frsize=4096}) = 0
after:
statfs64("_L1_root/", 84, {f_type=0x73717368, f_bsize=131072, f_blocks=134,
f_bfree=0, f_bavail=0, f_files=13, f_ffree=0, f_fsid={1792, 0}, f_namelen=256,
f_frsize=131072}) = 0
statfs64("_L2_tmp/", 84, {f_type=0x1021994, f_bsize=4096, f_blocks=63372,
f_bfree=63368, f_bavail=63368, f_files=63372, f_ffree=63364, f_fsid={0, 0},
f_namelen=255, f_frsize=4096}) = 0
statfs64("_aufs", 84, {f_type=0x61756673, f_bsize=4096, f_blocks=67660,
f_bfree=63368, f_bavail=63368, f_files=63385, f_ffree=63364, f_fsid={0, 0},
f_namelen=242, f_frsize=4096}) = 0
My testcase (Makefile, to use in a new empty directory):
--------
all: 5stattest.stamp
fullclean: clean
$(RM) 1data/
$(RM) 2data.squashfs *.stamp
clean:
$(RM) 3mount.stamp 4dftest.stamp 5stattest.stamp
-umount ./_aufs
-umount ./_L1_root
-umount ./_L2_tmp
-rmdir _L1_root _L2_tmp _aufs
test ! -d _L1_root
test ! -d _L2_tmp
test ! -d _aufs
@echo "successful."
1data.stamp:
mkdir 1data/
dd if=/dev/urandom of=1data/a bs=512 count=1334
dd if=/dev/urandom of=1data/b bs=512 count=112
dd if=/dev/urandom of=1data/c bs=512 count=11322
dd if=/dev/urandom of=1data/d bs=512 count=4322
touch 1data.stamp
2data.squashfs: 1data.stamp
mksquashfs 1data/ 2data.squashfs
3mount.stamp: 2data.squashfs
mkdir _L1_root
mount -oloop 2data.squashfs _L1_root
mkdir _L2_tmp
mount -t tmpfs tmp _L2_tmp
mkdir _aufs
mount -t aufs -o dirs=$(PWD)/_L2_tmp=rw:$(PWD)/_L1_root=ro,sum none
_aufs
touch 3mount.stamp
4dftest.stamp: 3mount.stamp
df -h _aufs
echo test >_aufs/abc
df -h _aufs
touch 4dftest.stamp
5stattest.stamp: 4dftest.stamp
stat -c"%-14n %o %b %B" _L1_root _L2_tmp _aufs
strace df -h _L1_root/ _L2_tmp/ _aufs 2>&1 | grep statfs
touch 5stattest.stamp
-------
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d