<code style="margin-right: 0.15em;margin-left: 0.15em;padding-right: 0.3em;padding-left: 0.3em;font-size: 0.85em;font-family: Consolas, Inconsolata, Courier, monospace;white-space: pre-wrap;border-width: 1px;border-style: solid;border-color: rgb(234, 234, 234);background-color: rgb(248, 248, 248);border-radius: 3px;display: inline;"><span style="font-size: 15px;">df</span>
df命令查看磁盘使用情况,发现磁盘已经满了。-bash-4.2$ df -ThFilesystem Type Size Used Avail Use% Mounted on/dev/vda1 ext4 30G 30G 0 100% /devtmpfs devtmpfs 489M 0 489M 0% /devtmpfs tmpfs 497M 0 497M 0% /dev/shmtmpfs tmpfs 497M 50M 447M 11% /runtmpfs tmpfs 497M 0 497M 0% /sys/fs/cgroup
2.执行 du 命令查看各个目录的磁盘占用情况,把各个目录文件的大小相加,发现并没有占满磁盘,有10多G空间莫名失踪。
-bash-4.2$ du -h --max-depth=1 /home16M /home/logs11G /home/serverdog11G /home
<span style="font-size: 15px;">lsof</span>
命令显示打开已删除的文件。将有问题的进程重启(或,清空),磁盘空间就会得到释放。-bash-4.2# lsof | grep deletemysqld 2470 mysql 4u REG 253,1 0 523577 /var/tmp/ibfTeQFn (deleted)mysqld 2470 mysql 5u REG 253,1 0 523579 /var/tmp/ibaHcIdW (deleted)mysqld 2470 mysql 6u REG 253,1 0 523581 /var/tmp/ibLjiALu (deleted)mysqld 2470 mysql 7u REG 253,1 0 523585 /var/tmp/ibCFnzTB (deleted)mysqld 2470 mysql 11u REG 253,1 0 523587 /var/tmp/ibCjuqva (deleted)
什么是虚拟文件系统(VFS:virtual filesystem)?
什么是通用文件模型?
超级块对象(superblock object)
索引节点对象(inode object)
文件对象(file object)
目录项对象(dentry object)
文件的概念
文件的表达
内存表达
磁盘表达
目录树的构建
软链接 vs 硬链接
文件 & 磁盘管理
索引节点状态
文件 & 进程管理
操作:
打开&删除
超级块对象(superblock object)
内存:文件系统安装时创建,存放文件系统的有关信息
磁盘:对应于存放在磁盘上的文件系统控制块(filesystem control block)
索引节点对象(inode object)
内存:访问时创建,存放关于具体文件的一般信息(
inode 结构
)
磁盘:对应于存放在磁盘上的文件控制块(file control block)
每个索引节点对象都有一个索引节点号,唯一地标识文件系统的文件
文件对象(file object)
内存:打开文件时创建,存放 打开文件 与进程之间进行交互的有关信息(
file 结构
)file 结构
)
打开文件信息,仅当进程访问文件期间存在于内核内存中。
目录项对象(dentry object)
内存:目录项一旦被读入内存,VFS就会将其转换成
dentry 结构
打开文件信息,仅当进程访问文件期间存在于内核内存中。
内存:目录项一旦被读入内存,VFS就会将其转换成dentry 结构
的目录项对象磁盘:特定文件系统以特定的方式存储在磁盘上
start_kernel vfs_caches_init mnt_init init_rootfs // 注册rootfs文件系统 init_mount_tree // 挂载rootfs文件系统 … rest_init kernel_thread(kernel_init, NULL, CLONE_FS);
<span style="font-size: 15px;color: rgb(68, 68, 68);">i_nlink</span>
字段为零时,说明没有硬链接指向该文件。* "in_use" - valid inode, i_count > 0, i_nlink > 0* "dirty" - as "in_use" but also dirty* "unused" - valid inode, i_count = 0
<code style="margin-right: 0.15em;margin-left: 0.15em;padding-right: 0.3em;padding-left: 0.3em;font-size: 0.85em;font-family: Consolas, Inconsolata, Courier, monospace;white-space: pre-wrap;border-width: 1px;border-style: solid;border-color: rgb(234, 234, 234);background-color: rgb(248, 248, 248);border-radius: 3px;display: inline;"><span style="font-size: 15px;">open()</span>
和 <span style="font-size: 15px;">close()</span>
操作建立和销毁文件对象,文件对象通过索引节点提供的 <span style="font-size: 15px;">iget</span>
和 <span style="font-size: 15px;">iput</span>
更新索引节点的i_count字段,以完成使用计数。open 操作使得 i_count 加一, close 操作使得 i_count 减一。在 close 操作时判断索引节点是否释放,如果 i_count = 0,则意味着不再有进程引用,将会从内存释放。文件与磁盘管理联系最紧密的操作,莫过于<span style="font-size: 15px;">touch</span>
和<span style="font-size: 15px;">rm</span>
open() 和
🎜close()🎜
🎜 操作建立和销毁文件对象,文件对象通过索引节点提供的 🎜🎜iget🎜
🎜 和 🎜🎜iput🎜
🎜 更新索引节点的i_count字段,以完成使用计数。open 操作使得 i_count 加一, close 操作使得 i_count 减一。在 close 操作时判断索引节点是否释放,如果 i_count = 0,则意味着不再有进程引用,将会从内存释放。🎜🎜🎜文件与磁盘管理联系最紧密的操作,莫过于🎜🎜touch🎜
🎜和🎜🎜rm🎜
🎜操作,而尤以后者最为关键。通过strace(或 dtruss),查看 rm 的实际的系统调用🎜🎜
# dtruss rm tmp...geteuid(0x0, 0x0, 0x0) = 0 0ioctl(0x0, 0x4004667A, 0x7FFEE06F09C4) = 0 0lstat64("tmp\0", 0x7FFEE06F0968, 0x0) = 0 0access("tmp\0", 0x2, 0x0) = 0 0unlink("tmp\0", 0x0, 0x0) = 0 0
可以发现 rm 实际是通过 unlink 完成的。unlink代表删除目录项,以及减少其索引节点的计数。由通用文件模型可知,父目录本身同样是一个文件,也就意味着目录项是其文件数据的一部分。删除目录项等价于从父目录的文件中删除数据,也就意味着首先要打开父目录的文件。那么,删除操作即可理解为:
删除命令(一个进程)使用 open 操作获得父目录文件对象
通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iget</span>
增加 目录文件的索引节点对象计数
读取目录文件数据
将目录文件数据转化为目录项对象
由于目录项包含文件的索引节点,类似的,需要通过 iget 增加文件的索引节点对象计数
删除目录的目录项
减少文件索引节点对象的硬链接计数i_nlink
通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iput</span>
结束对文件索引节点对象的操作,使用计数 i_count 减一
判断i_count是否为零,如果为零,则释放内存
然后,判断i_nlink是否为零,如果为零,则释放磁盘空间
通过 iput 结束对目录索引节点对象的操作。
回头来看遇到的问题,其实可以从两个角度来理解:
由于操作系统使用 Write back 的策略,意味着只有先释放内存,才有可能释放磁盘。
以上是从 lsof 开始,深入理解 Linux 虚拟文件系统的详细内容。更多信息请关注PHP中文网其他相关文章!