inode缓存的生命周期

it2025-02-06  8

inode state

/* Inode state bits.. */ #define I_DIRTY_SYNC          1 /* Not dirty enough for O_DATASYNC */ #define I_DIRTY_DATASYNC     2 /* Data-related inode changes pending */ #define I_DIRTY_PAGES          4 /* Data-related inode changes pending */ #define I_LOCK               8     涉及到的索引节点处于I/O传输中 #define I_FREEING          16     索引节点对象正在被释放 #define I_CLEAR               32     索引节点对象内容不再有意义

          I_NEW                              索引节点对象已经分配,但还没有用从磁盘索引节点读取的数据来填充

inode_unused

inode_in_use

s_dirty(sb)

 

s_inodes(sb)

 

inode_hashtabel

 

inode相关操作

destroy_inode 释放inode内存对象

put_inode 减少索引节点引用计数时调用 drop_inode delete_inode 删除索引节点在硬盘上的数据(包括修改所在块组的位图) clear_inode 重置inode内存对象中的数据,重置状态,解除和buffer_head的关联等等。     iput-->put_inode      -->(drop_inode 2.4内核没找到)      -->delete_inode | clear_inode      -->destroy_inode       ext2_delete_inode-->ext2_truncate,在这里释放文件的所有数据块   dget_locked __dget_locked  dget 增加dentry使用数 dput 减少dentry使用数   iget 增加inode中的使用数(usecount) iput 减少inode中的使用数(usecount),当usecount为0且link数为0时可以释放内存   pathwalk的过程中,dget和dput是成对调用的,最后返回的结果dentry只调用了dget,由使用此dentry的函数,在使用完成后调用dput。   open时也要获取dentry,这个dentry调用dget把使用数增加,在close时调用dput(fput->dput)减少使用数。   unlink时,调用op->unlink和d_delete,最后调用dput,op_unlink是各文件系统自己实现,主要是减少node中link数,并修改硬盘中名字空间和文件记录。d_delete判断dentry的使用数是否为1,如果为1,减少dentry中inode记录的使用数(负状态?),如果大于1,说明有人还在使用此dentry, 重置d_hash,让其他人再无法查询到该dentry。调用dput,如果没有人在使用,并且不能通过d_hash查到该dentry时,释放该dentry,如果还可以通过d_hash查到该dentry,把dentry加入freelist中(未使用状态?)   疑问:为什么不在d_delete函数中直接重置d_hash,这样在dput时就可以释放dentry了?   /** * d_invalidate - invalidate a dentry * @dentry: dentry to invalidate * * Try to invalidate the dentry if it turns out to be * possible. If there are other dentries that can be * reached through this one we can't delete it and we * return -EBUSY. On success we return 0. * * no dcache lock. */ int d_invalidate(struct dentry * dentry)     /* * This is dput * * This is complicated by the fact that we do not want to put * dentries that are no longer on any hash chain on the unused * list: we'd much rather just get rid of them immediately. * * However, that implies that we have to traverse the dentry * tree upwards to the parents which might _also_ now be * scheduled for deletion (it may have been only waiting for * its last child to go away). * * This tail recursion is done by hand as we don't want to depend * on the compiler to always get this right (gcc generally doesn't). * Real recursion would eat up our stack space. */ /* * dput - release a dentry * @dentry: dentry to release * * Release a dentry. This will drop the usage count and if appropriate * call the dentry unlink method as well as removing it from the queues and * releasing its resources. If the parent dentries were scheduled for release * they too may now get deleted. * * no dcache lock, please. */ void dput(struct dentry *dentry)   空闲状态   未使用状态   正在使用状态   负状态  

inode缓存的释放

__invalidate_device-->invalidate_inodes中会将不在使用的inode释放

shrink_slab-->shrinker->shrink(shrink_icache_memory)-->prune_icache会将不在使用的inode释放

最新回复(0)