I'm trying to programatically calculate the number of files that can fit on a drive. The drive uses LUKS/ext4 and has a block size of 4096. Below is a df printout of the drive.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/vg_server-lv_storage 7260987808 6258809672 633341120 91% /storage
The issue I'm running into is finding a command that accuratly calculates the space a file takes up on this disk. For example:
[root@server ~]# ls -l test.t
-rw-r--r-- 1 root root 2 May 27 11:34 test.t
[root@server ~]# ls -l test2.t
-rw-r--r-- 1 root root 6301 Jul 18 2011 test2.t
"ls" reports 2 bytes and 6301 bytes.
[root@server ~]# stat test.t
File: `test.t'
Size: 2 Blocks: 8 IO Block: 4096 regular file
Device: fd03h/64771d Inode: 20185186 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2013-05-27 11:34:55.244368861 -0400
Modify: 2013-05-27 11:34:47.560446365 -0400
Change: 2013-05-27 11:34:47.654445417 -0400
[root@server ~]# stat test2.t
File: `test2.t'
Size: 6301 Blocks: 16 IO Block: 4096 regular file
Device: fd05h/64773d Inode: 177345663 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2013-05-27 11:06:28.363664283 -0400
Modify: 2011-07-18 16:18:56.000000000 -0400
Change: 2013-05-12 17:05:09.968897077 -0400
"stat" reports 8 blocks in use (in 512 increments, so 8*512 = 4096) and 16 blocks (8192).
[root@server ~]# find . -xdev -printf '%p %k %b\n' |grep test.t
./test.t 4 8
[root@server ~]# find . -xdev -printf '%p %k %b\n' |grep test2.t
./test2.t 8 16
"find" reports 4K/8 blocks (also in 512 incremennts, so 4096) and 8K/16 blocks. So far so good.
"df", the commnand I'm using to determine available 1K blocks (7260987808 above) reports a different number for the second test.
[root@server ~]# /bin/df -P |grep lv_storage; cp /root/test.t /storage/ttt.txt;/bin/df -P |grep lv_storage; rm /storage/ttt.txt; /bin/df -P |grep lv_storage;
/dev/mapper/vg_server-lv_storage 7260987808 6258809672 633341120 91% /storage
/dev/mapper/vg_server-lv_storage 7260987808 6258809680 633341112 91% /storage
/dev/mapper/vg_server-lv_storage 7260987808 6258809672 633341120 91% /storage
[root@server ~]# /bin/df -P |grep lv_storage; cp /root/test2.t /storage/ttt.txt;/bin/df -P |grep lv_storage; rm /storage/ttt.txt; /bin/df -P |grep lv_storage;
/dev/mapper/vg_server-lv_storage 7260987808 6258809672 633341120 91% /storage
/dev/mapper/vg_server-lv_storage 7260987808 6258809684 633341108 91% /storage
/dev/mapper/vg_server-lv_storage 7260987808 6258809672 633341120 91% /storage
This shows 633341120-633341112 = 8 for the first file.
Then shows 633341120-633341108 = 12 for the first file. WRONG. That should be 16.
I thought this was just a problem with df, perhaps some safety reserve to keep people from filling drives, but when I calculated out the number of files that would fit on the drive using find's %k, then subtracted some padding to be safe, it over-filled the drive and rsync errored out.
For reference, %k is defined as:
%k The amount of disk space used for this file in 1K blocks. Since disk space is allocated in multiples of the filesystem block size this is usually greater than %s/1024, but it can also be
smaller if the file is a sparse file.
Any ideas?