linux 文件删除过程浅析

1.Linux文件删除原理

Linux是通过link的数量控制文件删除的,只有当文件不存在任何链接时,该文件才会被删除,一般每个文件有两个link计数器: i_count 和 i_nlink,从VFS inode结构体中可以找到:

 
 
 
struct inode {
struct hlist_node i_hash; /* hash链表的指针 */
struct list_head i_list; /* backing dev IO list */
struct list_head i_sb_list; /* 超级块的inode链表 */
struct list_head i_dentry; /* 引用inode的目录项对象链表头 */
unsigned long i_ino; /* 索引节点号 */
atomic_t i_count; /* 引用计数器 */
unsigned int i_nlink; /* 硬链接数目 */
...

i_count: 引用计数器,文件被一进程引用,i_count数增加 ,可以认为是当前文件使用者的数量; 
i_nlink: 硬链接数目(可以理解为磁盘的引用计数器),创建硬链接对应的 i_nlink 就会增加

对于rm命令来说,实际就是减少磁盘的引用计数 i_nlink 。如果当文件被另外一个进程调用时,用户执行rm命令删除文件,再去cat文件内容时就会找不到文件,但是调用该删除文件的那个进程却仍然可以对文件进行正常的操作。这就是因为 i_nlink 为 0 ,但 i_count 并不为 0 。只有当 i_nlink 和 i_count 均为 0 时,文件才会被删除(这里的删除是指将文件名到 inode 的链接删除了,但文件在磁盘上的block数据块并未被删除)。

首先使用strace追踪rm命令,看看rm具体使用了哪些系统调用:

 
 
 
[root@ty ~]# strace rm test
execve("/bin/rm", ["rm", "test"], [/* 19 vars */]) = 0
brk(0) = 0x175c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1365a2f000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, { st_mode=S_IFREG|0644, st_size=62329, ...}) = 0
mmap(NULL, 62329, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1365a1f000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\355\201\2160\0\0\0"..., 832) = 832
fstat(3, { st_mode=S_IFREG|0755, st_size=1922152, ...}) = 0
... ...
brk(0) = 0x175c000
brk(0x177d000) = 0x177d000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, { st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0
mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f135fb8b000
close(3) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, { B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "test", { st_mode=S_IFREG|0644, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 0
unlinkat(AT_FDCWD, "test", 0) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?

由上发现最终调用unlinkat系统调用删除文件。 

2.系统调用unlinkat

unistd.h、unistd_64.h、unistd_32.h中定义系统调用号

 
 
 
#define __NR_link 9
#define __NR_unlink 10
...
#define __NR_unlinkat 456

两个函数定义在 Namei.c 文件中,如下:

 
 
 
SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
{
if ((flag & ~AT_REMOVEDIR) != 0)
return
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值