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

Reply via email to