如何删除ext2文件系统中的文件

时间:2017-03-27 23:32:59

标签: filesystems ext2

我正在学习EXT2文件系统。我很担心删除文件如何适用于EXT2。我的理解是,在删除时,它实际上不会删除inode,而是将一些元数据标记为未使用。我的问题是,在删除时它会修改哪些元数据,以及文件系统如何知道该文件已被删除?感谢。

1 个答案:

答案 0 :(得分:0)

在Linux中,这是在fs / ext2 / inode.c文件的ext2_delete_inode函数周围实现的: http://lxr.free-electrons.com/source/fs/ext2/inode.c?v=2.6.32#L59

 56 /*
 57  * Called at the last iput() if i_nlink is zero.
 58  */
 59 void ext2_delete_inode (struct inode * inode)
 60 {
 61         truncate_inode_pages(&inode->i_data, 0);
  ..
 65         EXT2_I(inode)->i_dtime  = get_seconds();
 66         mark_inode_dirty(inode);
 67         ext2_write_inode(inode, inode_needs_sync(inode));
 68 
 69         inode->i_size = 0;
 70         if (inode->i_blocks)
 71                 ext2_truncate (inode);
 72         ext2_free_inode (inode);
 73 
 74         return;
  ..
 77 }

因此,它会从truncate_inode_pages中的页面缓存中移除页面,设置dtime(删除时间)并将inode标记为脏 - I_DIRTY which is combination of (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)

1601  * I_DIRTY_SYNC         Inode is dirty, but doesn't have to be written on
1602  *                      fdatasync().  i_atime is the usual cause.
1603  * I_DIRTY_DATASYNC     Data-related inode changes pending. We keep track of
1604  *                      these changes separately from I_DIRTY_SYNC so that we
1605  *                      don't have to write inode on fdatasync() when only
1606  *                      mtime has changed in it.
1607  * I_DIRTY_PAGES        Inode has dirty pages.  Inode itself may be clean.

然后编写修改的inode,将大小更改为零,截断从inode链接的所有块ext2_truncate()(数据块的实际标记为空闲在那里完成):{{3 }}

1025 void ext2_truncate(struct inode *inode)
1026 {
..
1059         n = ext2_block_to_path(inode, iblock, offsets, NULL);
 99 /*      ext2_block_to_path - parse the block number into array of offsets
105  *      To store the locations of file's data ext2 uses a data structure common
106  *      for UNIX filesystems - tree of pointers anchored in the inode, with
107  *      data blocks at leaves and indirect blocks in intermediate nodes.
108  *      This function translates the block number into path in that tree -
109  *      return value is the path length and @offsets[n] is the offset of
110  *      pointer to (n+1)th node in the nth one. If @block is out of range
111  *      (negative or too large) warning is printed and zero returned. */
1069         if (n == 1) {
1070                 ext2_free_data(inode, i_data+offsets[0],
1071                                         i_data + EXT2_NDIR_BLOCKS);
1072                 goto do_indirects;
1073         }
..
1082                 ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
..
1084         /* Clear the ends of indirect blocks on the shared branch */
1085         while (partial > chain) {
1086                 ext2_free_branches(inode,
1087                                    partial->p + 1,
1088                                    (__le32*)partial->bh->b_data+addr_per_block,
1089                                    (chain+n-1) - partial);
..
1094 do_indirects:
1095         /* Kill the remaining (whole) subtrees */
1096         switch (offsets[0]) {
1097                 default:
1098                         nr = i_data[EXT2_IND_BLOCK];
1099                         if (nr) {
1100                                 i_data[EXT2_IND_BLOCK] = 0;
1101                                 mark_inode_dirty(inode);
1102                                 ext2_free_branches(inode, &nr, &nr+1, 1);
1103                         }
1104                 case EXT2_IND_BLOCK:
1105                         nr = i_data[EXT2_DIND_BLOCK];
1106                         if (nr) {
1107                                 i_data[EXT2_DIND_BLOCK] = 0;
1108                                 mark_inode_dirty(inode);
1109                                 ext2_free_branches(inode, &nr, &nr+1, 2);
1110                         }
1111                 case EXT2_DIND_BLOCK:
1112                         nr = i_data[EXT2_TIND_BLOCK];
1113                         if (nr) {
1114                                 i_data[EXT2_TIND_BLOCK] = 0;
1115                                 mark_inode_dirty(inode);
1116                                 ext2_free_branches(inode, &nr, &nr+1, 3);
1117                         }
1118                 case EXT2_TIND_BLOCK:
1119                         ;
1120         }

(为什么EXT2_TIND_BLOCK未被清除?)

然后我们可以在内核内存中释放inode结构。

  

文件系统如何知道该文件已被删除?

检查位于ext2_iget函数:http://lxr.free-electrons.com/source/fs/ext2/inode.c?v=2.6.32#L1025

1251         /* We now have enough fields to check if the inode was active or not.
1252          * This is needed because nfsd might try to access dead inodes
1253          * the test is that same one that e2fsck uses
1254          * NeilBrown 1999oct15
1255          */
1256         if (inode->i_nlink == 0 && (inode->i_mode == 0 || ei->i_dtime)) {
1257                 /* this inode is deleted */
1258                 brelse (bh);
1259                 ret = -ESTALE;
1260                 goto bad_inode;
1261         }

因此,删除的inode是没有传入链接的inode(在任何目录http://lxr.free-electrons.com/source/fs/ext2/inode.c?v=2.6.32#L1251中都没有提到),并且具有零模式或非零删除时间。