statfs example
- The statfs() system call returns information about a mounted filesystem.
- int statfs(const char path, struct statfs buf);
- path is the pathname of any file within the mounted filesystem.
struct statfs {
__fsword_t f_type; /* Type of filesystem (see below) */
__fsword_t f_bsize; /* Optimal transfer block size */
fsblkcnt_t f_blocks; /* Total data blocks in filesystem */
fsblkcnt_t f_bfree; /* Free blocks in filesystem */
fsblkcnt_t f_bavail; /* Free blocks available to
unprivileged user */
fsfilcnt_t f_files; /* Total file nodes in filesystem */
fsfilcnt_t f_ffree; /* Free file nodes in filesystem */
fsid_t f_fsid; /* Filesystem ID */
__fsword_t f_namelen; /* Maximum length of filenames */
__fsword_t f_frsize; /* Fragment size (since Linux 2.6) */
__fsword_t f_flags; /* Mount flags of filesystem
(since Linux 2.6.36) */
__fsword_t f_spare[xxx];
/* Padding bytes reserved for future use */
};
f_bsize: Optimal transfer block size
f_blocks:Total data blocks in filesystem
f_bfree: Free blocks in filesystem
f_bavail:ree blocks available to unprivileged user
example 320GB
- 此顆HDD (320GB),切成/dev/sda1及/dev/sda2
- 硬碟HDD SZIE定義 320GB = 320 x 1000000000 byte = 298Gbyte
- /dev/sda1可使用的大小為 319.5GB (319558778880 byte = 304755 Mbyte = 297.6 Gbyte)
- 319558778880大小同fdisk -l /dev/sda1大小
- dumpe2fs /dev/sda1 得到大小 319558778880 byte (78017280 * 4096),此為實際可以用的block空間
- parted /dev/sda 得到size 320GB = 320x1000000000 byte = 298Gbyte
swap 512Mbyte = 536870912 byte
parted 及 fdisk
# parted -s /dev/sda print free
Model: ATA MAXTOR STM332082 (scsi)
Disk /dev/sda: 320GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
17.4kB 1049kB 1031kB Free Space
1 1049kB 320GB 320GB ext4 primary
2 320GB 320GB 513MB linux-swap(v1) linux-swap
320GB 320GB 335kB Free Space
# fdisk -l /dev/sda
Disk /dev/sda: 320.0 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 38914 312571223+ ee EFI GPT
# fdisk -l /dev/sda1
Disk /dev/sda1: 319.5 GB, 319558778880 bytes
255 heads, 63 sectors/track, 38850 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk /dev/sda1 doesn't contain a valid partition table
- statfs 得到total size 319459942400 (77993150 * 4096) = 304660.7Mbyte = 297.5Gbyte
- 比dumpe2fs得到size 少了 98836480 (94.25Mbyte)
- statfs 得到free size 32232423424
df算法
Total data blocks in filesystem
(f_blocks*f_bsize + 512) / 1024
= 311972600.5 Kbyte (1K-blocks) 全部的量297.5Gbyte
Total data blocks in filesystem - Free blocks in filesystem =使用量
((f_blocks - f_bfree)*f_bsize + 512 ) / 1024
= 280495624.5 Kbyte (Used) 全部使用的量 267.5Gbyte
由於bavial為非root量會比較少
Free blocks available to unprivileged user
(f_bavail*f_bsize+512)/1024
= 15873520 Kbyte (Available)剩下可使用量15.13Gbyte
used %
block_used = (f_blocks - f_bfree) = 70123906 (x4K =
block_total = (block_used + f_bavail) = 74092286 (x4K = 296369144Kbyte = 282.6Gbyte )
# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 18432 13332 5100 72% /
devtmpfs 295904 4 295900 0% /dev
tmpfs 295996 1324 294672 0% /tmp
tmpfs 295996 0 295996 0% /dev/shm
/dev/mtdblock6 29624 29624 0 100% /usr
/dev/mtdblock8 5120 3496 1624 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2048 224 1824 11% /mnt/nand
/dev/mtdblock10 2048 196 1852 10% /mnt/log
/dev/sda1 311972600 280495624 15873520 95% /media/sda1
# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 18.0M 13.0M 5.0M 72% /
devtmpfs 289.0M 4.0K 289.0M 0% /dev
tmpfs 289.1M 1.3M 287.8M 0% /tmp
tmpfs 289.1M 0 289.1M 0% /dev/shm
/dev/mtdblock6 28.9M 28.9M 0 100% /usr
/dev/mtdblock8 5.0M 3.4M 1.6M 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2.0M 224.0K 1.8M 11% /mnt/nand
/dev/mtdblock10 2.0M 196.0K 1.8M 10% /mnt/log
/dev/sda1 297.5G 267.5G 15.1G 95% /media/sda1
- f_blocks : Total data blocks in filesystem
- f_bavail :Free blocks available to unprivileged user
- f_bfree :Free blocks in filesystem
f_bfree比f_bavail多,但只有f_bavail才是能使用量
# ./test-statfs
mount_path:/media/sda1
dev_path:/dev/sda1
f_blocks :077993150
f_bsize :000004096
f_bavail :003968380
f_bfree :007869244
Filesystem 4K-blocks Used Available Use% Mounted on
/dev/sda1 311972600 280495624 15873520 95% /media/sda1
- dumpe2fs
Block count: 78017280
Reserved block count: 3900864
Free blocks: 57976020
Free inodes: 303839
dumpe2fs
# ./dumpe2fs
dumpe2fs 1.41.11 (14-Mar-2010)
Usage: ./dumpe2fs [-bfhixV] [-o superblock=<num>] [-o blocksize=<num>] device
# ./dumpe2fs /dev/sda1
dumpe2fs 1.41.11 (14-Mar-2010)
Filesystem volume name: <none>
Last mounted on: /media/sda1
Filesystem UUID: 27f84dc8-e61a-4c12-80e9-b17813a87891
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: unsigned_directory_hash
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 304768
Block count: 78017280
Reserved block count: 3900864
Free blocks: 57976020
Free inodes: 303839
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 1005
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 128
Inode blocks per group: 8
Flex block group size: 16
Filesystem created: Fri Dec 11 18:43:08 2015
Last mount time: Thu Jan 1 00:00:48 1970
Last write time: Thu Jan 1 00:00:48 1970
Mount count: 4
Maximum mount count: 24
Last checked: Fri Dec 11 18:43:08 2015
Check interval: 15552000 (6 months)
Next check after: Wed Jun 8 18:43:08 2016
Lifetime writes: 77 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 04e4fbde-8a6f-4a63-a5ae-37d10975ac73
Journal backup: inode blocks
Journal features: (none)
Journal size: 128M
Journal length: 32768
Journal sequence: 0x0000c1d2
Journal start: 61
320G 試算
# mkfs.ext4 -q -T largefile /dev/sda1
#
# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 18432 13348 5084 72% /
devtmpfs 295904 4 295900 0% /dev
tmpfs 295996 1652 294344 1% /tmp
tmpfs 295996 0 295996 0% /dev/shm
/dev/mtdblock6 29624 29624 0 100% /usr
/dev/mtdblock8 5120 3496 1624 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2048 228 1820 11% /mnt/nand
/dev/mtdblock10 2048 196 1852 10% /mnt/log
/dev/sda1 311972600 195416 296173728 0% /media/sda1
# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 18.0M 13.0M 5.0M 72% /
devtmpfs 289.0M 4.0K 289.0M 0% /dev
tmpfs 289.1M 1.6M 287.4M 1% /tmp
tmpfs 289.1M 0 289.1M 0% /dev/shm
/dev/mtdblock6 28.9M 28.9M 0 100% /usr
/dev/mtdblock8 5.0M 3.4M 1.6M 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2.0M 228.0K 1.8M 11% /mnt/nand
/dev/mtdblock10 2.0M 196.0K 1.8M 10% /mnt/log
/dev/sda1 297.5G 190.8M 282.5G 0% /media/sda1
- dumpe2fs
# ./dumpe2fs /dev/sda1
dumpe2fs 1.41.11 (14-Mar-2010)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 875b5629-d22e-4036-b1ed-2bfb7bf39e7d
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: unsigned_directory_hash
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 304768
Block count: 78017280
Reserved block count: 3900864
Free blocks: 77944296
Free inodes: 304757
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 1005
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 128
Inode blocks per group: 8
Flex block group size: 16
f_blocks size: 77993150 x 4096 = 297.52 Gbyte
f_bfree size : 77944296 x 4096 = 297.33 Gbyte
f_bavail size: 74043432 x 4096 = 282.45 Gbyte
# ./test-statfs /media/sda1
mount_path:/media/sda1
dev_path:/dev/sda1
f_blocks :077993150
f_bsize :000004096
f_bavail :074043432
f_bfree :077944296
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 311972600 195416 296173728 0% /media/sda1
BKT 計算
- 320G會開啟456個bkt
- f_blocks (297.52 Gbyte ) / 600M = 507.7 Bkt
- --bkt (506.7BKT)
- bkt-= BKT_RESERVE_IDX_SPACE_BKT_NUM (50) (456BKT)
- 456BKT錄滿會佔 267.42Gbyte
- (600M + 557K) * 456 = 267.42Gbyte
used % = ( block_used*100 + 0.5xblock_total) / block_total
block_used = (f_blocks - f_bfree)
block_total = (block_used + f_bavail)
item | 格化式之後 | 錄滿 | 變量 |
---|---|---|---|
f_blocks | 77993150 (297.52 Gbyte) | 77993150 (297.52 Gbyte) | 相同 |
f_bfree | 77944296 (297.33 Gbyte) | 7869244 ( 30.01 Gbyte) | 減少 267.32Gbyte |
f_bavail | 74043432 (282.45 Gbyte) | 3968380 ( 15.13 Gbyte) | 減少 267.32Gbyte |
used | 0.19 Gbyte | 267.51 Gbyte | 增加 267.32Gbyte |
total | 282.64 Gbyte | 282.64 Gbyte | 相同 |
used % | 0% | 95% | 增加95%, 268.5Gbyte |
增加的量為 BKT寫滿量 (267.42GByte)
used % = (19 + 141.32) / 282.64 = 0.56 % = 0%
used % = (26751 + 141.32) / 282.64 = 0.56 % = 95.14%
顯示滿100%算法
282.64 - 267.51 = 15.13 (Gbyte)
total -= 15.13 => 267.51 Gbyte
used % = (19 + 133.75) / 267.51 = 0.57 % = 0%
used % = (26751 + 133.75) / 267.51 = 100.4 % = 100%
2TB HDD example
- 2TB HDD = 21000100010001000 byte = 1862.645149230957 Gbyte = 1.81Tbyte
- dumpe2fs size (488253184 * 4096 = 1999885041664 = 1862.53Gbyte)
- dumpe2fs Free blocks: 488051925 (同statfs f_bfree)
- dumpe2fs block 488253184 比 statfs 488101932 多了 151252個block (多了590Mbyte)
- statfs f_block size 1861Gbyte ( 488101932 x 4096 = 1999265513472 byte )
當未建立bkt時 f_bfree等於 dumpe2fs free block量
dumpe2fs
Block count: 488253184
Reserved block count: 24412659
Free blocks: 488051925
Block size: 4096
- f_blocks: 488101932 (1861.96Gbyte)
- f_bavail: 463639266 (1768.6Gbyte)
- f_bfree: 488051925 (1861.7Gbyte)
- 總HDD BLOCK空間 1861.96Gbyte,,有1861.7G的free ,但只有 1768.6G可以使用 (少了93.3Gbyte)
# mkfs.ext4 -q -T largefile /dev/sda1
# mount /dev/sda1 /media/sda1
# ./test-statfs
mount_path:/media/sda1
dev_path:/dev/sda1
f_blocks :488101932
f_bsize :000004096
f_bavail :463639266
f_bfree :488051925
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 1952407728 200028 1854557064 0% /media/sda1
#
# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 18432 13324 5108 72% /
devtmpfs 295904 4 295900 0% /dev
tmpfs 295996 1296 294700 0% /tmp
tmpfs 295996 0 295996 0% /dev/shm
/dev/mtdblock6 29616 29616 0 100% /usr
/dev/mtdblock7 5120 3492 1628 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2048 224 1824 11% /mnt/nand
/dev/mtdblock10 2048 196 1852 10% /mnt/log
/dev/sda1 1952407728 200028 1854557064 0% /media/sda1
# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 18.0M 13.0M 5.0M 72% /
devtmpfs 289.0M 4.0K 289.0M 0% /dev
tmpfs 289.1M 1.3M 287.8M 0% /tmp
tmpfs 289.1M 0 289.1M 0% /dev/shm
/dev/mtdblock6 28.9M 28.9M 0 100% /usr
/dev/mtdblock7 5.0M 3.4M 1.6M 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2.0M 224.0K 1.8M 11% /mnt/nand
/dev/mtdblock10 2.0M 196.0K 1.8M 10% /mnt/log
/dev/sda1 1.8T 195.3M 1.7T 0% /media/sda1
#
- 建立bkt之後
- f_blocks不變
- f_bavail 少了 3498 block (463639266 - 463635768) (13992Kbyte)
- f_bfree 少了 3498 block (488051925 - 488048427 )
- df下的 used 增加 13992Kbyte (214020 - 200028) ,等於f_bavail 及 f_bfree的量
-rw-r--r-- 1 root root 629145600 Dec 9 16:18 00003176.bkt
-rw-r--r-- 1 root root 0 Dec 9 16:18 00003176.idx
-rw-r--r-- 1 root root 1117976 Dec 9 16:18 bktmgr.udf
drwxr-xr-x 3 root root 4096 Dec 9 17:36 cfg
drwx------ 2 root root 16384 Dec 9 16:18 lost+found
-rw-r--r-- 1 root root 88 Dec 15 11:06 topmgr.udf
# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 18432 13320 5112 72% /
devtmpfs 295904 4 295900 0% /dev
tmpfs 295996 1284 294712 0% /tmp
tmpfs 295996 0 295996 0% /dev/shm
/dev/mtdblock6 29616 29616 0 100% /usr
/dev/mtdblock7 5120 3492 1628 68% /opt/dvr_rdk/dvr_board
/dev/mtdblock9 2048 224 1824 11% /mnt/nand
/dev/mtdblock10 2048 196 1852 10% /mnt/log
/dev/sda1 1952407728 214020 1854543072 0% /media/sda1
# ./test-statfs
mount_path:/media/sda1
dev_path:/dev/sda1
f_blocks :488101932
f_bsize :000004096
f_bavail :463635768
f_bfree :488048427
- 2TB dumpe2fs
#
# ./dumpe2fs /dev/sda1
dumpe2fs 1.41.11 (14-Mar-2010)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 6aa991cc-8cc4-482e-8ace-e5d42e95433b
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: unsigned_directory_hash
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 1907328
Block count: 488253184
Reserved block count: 24412659
Free blocks: 488051925
Free inodes: 1907317
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 907
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 128
Inode blocks per group: 8
Flex block group size: 16
Filesystem created: Tue Dec 15 14:03:00 2015
Last mount time: Tue Dec 15 14:03:47 2015
Last write time: Tue Dec 15 14:03:47 2015
Mount count: 1
Maximum mount count: 24
Last checked: Tue Dec 15 14:03:00 2015
Check interval: 15552000 (6 months)
Next check after: Sun Jun 12 14:03:00 2016
Lifetime writes: 610 MB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: ad8fc829-1efe-4487-819d-1f4a2ac1eac4
Journal backup: inode blocks
Journal features: (none)
Journal size: 128M
Journal length: 32768
Journal sequence: 0x00000001
Journal start: 0
example source
參考 busybox 的df.c修改過來
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/vfs.h>
#define SIZE_KB 1024
#define SIZE_MB (SIZE_KB*SIZE_KB)
static unsigned long kscale(unsigned long b, unsigned long bs)
{
return (b * (unsigned long long) bs + 1024/2) / 1024;
}
void bkt_1(char *mount_point,char *dev_path){
struct statfs s;
unsigned long blocks_used;
unsigned blocks_percent_used;
if(statfs(mount_point,&s) != 0){
printf("fail statfs");
return;
}
printf("f_blocks :%09lu\n",(unsigned long)s.f_blocks);
printf("f_bsize :%09lu\n",(unsigned long)s.f_bsize);
printf("f_bavail :%09lu\n",(unsigned long)s.f_bavail);
printf("f_bfree :%09lu\n",(unsigned long)s.f_bfree);
printf("Filesystem %-15sUsed Available %s Mounted on\n",
"1K-blocks", "Use%");
blocks_used = s.f_blocks - s.f_bfree;
blocks_percent_used = 0;
if (blocks_used + s.f_bavail) {
blocks_percent_used = (blocks_used * 100ULL + (blocks_used + s.f_bavail)/2) / (blocks_used + s.f_bavail);
}
printf("\n%-20s" + 1, dev_path);
printf(" %9lu %9lu %9lu %3u%% %s\n",
kscale(s.f_blocks, s.f_bsize),
kscale(s.f_blocks - s.f_bfree, s.f_bsize),
kscale(s.f_bavail, s.f_bsize),
blocks_percent_used, mount_point);
}
int main(void){
char mount_path[128];
char dev_path[128];
snprintf(mount_path,sizeof(mount_path),"%s","/media/sda1");
printf("mount_path:%s\n",mount_path);
snprintf(dev_path,sizeof(dev_path),"%s","/dev/sda1");
printf("dev_path:%s\n",dev_path);
bkt_1(mount_path,dev_path);
return 0;
}
格式化問題
# umount -l /media/sda1
# mount
rootfs on / type rootfs (rw)
/dev/root on / type jffs2 (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=295904k,nr_inodes=73976,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620)
/dev/mtdblock6 on /usr type cramfs (ro,relatime)
/dev/mtdblock8 on /opt/dvr_rdk/dvr_board type jffs2 (ro,relatime)
/dev/mtdblock9 on /mnt/nand type jffs2 (rw,relatime)
/dev/mtdblock10 on /mnt/log type jffs2 (rw,relatime)
# mkfs.ext4 -q -T largefile /dev/sda1
/dev/sda1 is apparently in use by the system; will not make a filesystem here!
#
即使umoun成功且無swapoff,也是無法format,,
2529 root 0 SW [kworker/0:0]
3232 root 0 SW [kworker/0:2]
3233 root 0 SW [flush-mtd-unmap]
3240 root 161m S /opt/dvr_rdk/dvr_board/bin/media
3293 root 3180 S -sh
3296 root 0 SW [flush-8:0]
3299 root 0 Z [telnetd]
3300 root 3508 S telnetd
3303 root 3180 S -sh
3305 root 3180 R ps
# /bin/busybox fuser -m /dev/sda1
3303 3300 3293 3240 676 11
# kill 3240
# kill 676
# /bin/busybox fuser -m /dev/sda1
3303 3300 3293 11
# mkfs.ext4 -q -T largefile /dev/sda1
#
kill 相關的process (media , upgrade , boa , dvrmain, ..等),就可以format
- fuser
/bin/busybox fuser -v
fuser: invalid option -- 'v'
BusyBox v1.16.1 (2013-07-17 17:28:26 CST) multi-call binary.
Usage: fuser [OPTIONS] FILE or PORT/PROTO
Find processes which use FILEs or PORTs
Options:
-m Find processes which use same fs as FILEs
-4 Search only IPv4 space
-6 Search only IPv6 space
-s Silent: just exit with 0 if any processes are found
-k Kill found processes (otherwise display PIDs)
-SIGNAL Signal to send (default: TERM)