Linux常用命令分析-df命令

Linux常用命令分析-df命令

df命令用于显示硬盘空间及使用情况,由系统shell调用,调用关系为:
df_main -> fopen(“/proc/mounts“, “r”) -> df -> statfs -> __statfs64

实现可归结:从/proc/mounts设备节点获取mount分区信息,然后调用statfs得到对应分区具体使用情况。

yuziming@ubuntu:~$ cat /proc/mounts
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,relatime,size=165067044k,nr_inodes=41266761,mode=755 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=33015724k,mode=755 0 0
/dev/dm-0 / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
none /sys/fs/fuse/connections fusectl rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0
none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0
none /run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755 0 0
none /sys/fs/pstore pstore rw,relatime 0 0
/dev/sda1 /boot ext2 rw,relatime,block_validity,barrier,user_xattr,acl 0 0
/dev/mapper/vg-home /home ext4 rw,relatime,data=ordered 0 0
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0

yuziming@ubuntu:~$ df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 165067044 4 165067040 1% /dev
tmpfs 33015724 11644 33004080 1% /run
/dev/dm-0 961105240 30495884 881764968 4% /
none 4 0 4 0% /sys/fs/cgroup
none 5120 0 5120 0% /run/lock
none 165078604 0 165078604 0% /run/shm
none 102400 0 102400 0% /run/user
/dev/sda1 188403 40130 138545 23% /boot
/dev/mapper/vg-home 20396685124 17693446316 1679307212 92% /home

/proc/mounts设备节点工作原理不在此讨论,我们重点分析下statfs的实现。


1、statfs函数

statfs由脚本生成,其定义在/bionic/libc/arch-arm/syscalls/__statfs64.S中,文件内容:

/* autogenerated by gensyscalls.py */
#include<sys/linux-syscalls.h>
    .text
    .type __statfs64, #functions
    .globl __statfs64
    .fnstart

__statfs64:
    .save {r4,r7}
    stmfd sp!,{r4,r7}
    ldr r7, =__NR_statfs64
    swi #0
    ldmfs sp!,{r4,r7}
    movs r0,r0
    bxpl lr
    b __set_syscall_errno
    .fnend

__NR_statfs64是执行内核中的系统调用:

/kernel/fs/statfs.c

SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf)
{
    struct path path;
    long error;

    if (sz != sizeof(*buf))
        return -EINVAL;
    error = user_path(pathname, &path);
    if (!error) {
        struct statfs64 tmp;
        error = vfs_statfs64(path.dentry, &tmp);
        if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
            error = -EFAULT;
        path_put(&path);
    }
    return error;
}

接下来,调用文件系统的接口,获取分区信息(以yaffs为例):
vfs_statfs64 -> … -> “dentry->d_sb->s_op->statfs(dentry, buf)” -> yaffs_statfs

static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
{
    yaffs_Device *dev = yaffs_SuperToDevice(sb);

    T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n"));

    yaffs_GrossLock(dev);

    buf->f_type = YAFFS_MAGIC;
    buf->f_bsize = sb->s_blocksize;
    buf->f_namelen = 255;
    if (sb->s_blocksize > dev->nDataBytePerChunk) {
        buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock / (sb->s_blocksize / dev->nDataytesPerChunk);
        buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/(sb->s_blocksize / dev->nDataBytesPerChunk);
    } else {
        buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk / sb->s_blocksize);
        buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk / sb->s_blocksize);
    }
    buf->f_files = 0;
    buf->f_ffree = 0;
    buf->f_bavail = buf->f_bfree;

    yaffs_GrossUnlock(dev);
    return 0;
}

至此硬盘分区使用情况就获取完成了,至于文件系统管理设备的方法,请自行阅读Linux文件系统相关知识,就不在此赘述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值