Filesystems 如何在ext2文件系统中删除文件

Filesystems 如何在ext2文件系统中删除文件,filesystems,ext2,Filesystems,Ext2,我正在学习EXT2文件系统。我对EXT2如何删除文件感到困惑。我的理解是,在删除时,它实际上并不删除inode,而是将一些元数据标记为未使用。我的问题是,删除时它会修改哪些元数据,文件系统如何知道文件已被删除?谢谢。在Linux中,这是围绕fs/ext2/inode.c文件的ext2\u delete\u inode函数实现的: 因此,它在中从页面缓存中删除页面,设置dtime(删除时间)并将inode标记为dirty-: 然后写入修改后的inode,将它的大小更改为零,使用ext2\u tr

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

在Linux中,这是围绕fs/ext2/inode.c文件的
ext2\u delete\u inode
函数实现的:

因此,它在中从页面缓存中删除页面,设置dtime(删除时间)并将inode标记为dirty-:

然后写入修改后的inode,将它的大小更改为零,使用
ext2\u truncate()
截断从inode链接的所有块(实际将数据块标记为空闲):

(为什么
EXT2\u TIND\u BLOCK
未清除?)

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

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

检查位于
ext2\u iget
功能中:

因此,已删除的inode是指没有传入链接(在任何目录中都没有提及)且具有零模式或非零删除时间的inode。

同时检查:Linux Ext2fs Undeletion mini HOWTO-Aaron Crane,1999,特别是“10.恢复数据块”部分。ext2的其他版本(ext3/ext4)可能有不同的过程:“为什么恢复删除的ext3文件很困难”,2005;以及man e2undel的“注意事项”(“发生的情况是:ext2..数据块可用,将..inode标记为可用,设置删除时间,使dir中的文件名无效”)
 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 }
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.
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         }
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         }