【问题标题】:How removing a file in ext2 file system work如何在 ext2 文件系统中删除文件
【发布时间】:2017-08-20 20:30:09
【问题描述】:

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

【问题讨论】:

    标签: filesystems ext2


    【解决方案1】:

    在 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,将大小改为0,截断所有从inode链接到ext2_truncate()的块(数据块的实际标记为空闲在那里完成):http://lxr.free-electrons.com/source/fs/ext2/inode.c?v=2.6.32#L1025 p>

    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#L1251

    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(在任何目录 i_nlink 中都没有提及)并且具有零模式或非零删除时间。

    【讨论】:

    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 2015-07-07
    • 2017-08-26
    • 1970-01-01
    • 2011-11-08
    • 2020-06-01
    相关资源
    最近更新 更多