【问题标题】:how are inode numbers generated in linux tmpfs?linux tmpfs中的inode编号是如何生成的?
【发布时间】:2010-12-10 17:40:40
【问题描述】:

在我看来,tmpfs 并没有重复使用 inode 编号,而是在每次需要空闲 inode 时通过 +1 序列创建一个新的 inode 编号。

您知道这是如何实现的吗/您能否指出我可以检查 tmpfs 中使用的算法的一些源代码?

我需要了解这一点,以便绕过使用 inode 编号作为其缓存键的缓存系统中的限制(因此会导致罕见的,但当 inode 被频繁重复使用时会发生冲突)。如果我能证明 tmpfs 可以不断创建唯一的 inode 编号,那么它可以节省我的时间。

感谢您的帮助,

杰罗姆·瓦格纳

【问题讨论】:

    标签: linux filesystems


    【解决方案1】:

    我不会直接回答你的问题,所以我提前道歉。

    tmpfs 的想法很好,但我不会让我的程序依赖于或多或少模糊的实现细节来生成密钥。您为什么不尝试另一种方法,例如将 inode 编号与其他一些信息结合起来?可能是修改日期:除非系统日期发生变化,否则两个文件在生成密钥时不可能获得相同的 inode 编号和修改日期。

    干杯!

    【讨论】:

    • 我同意依赖这样的 impl。细节似乎不合理和未来的证据。事实是密钥已经依赖于 (inode, mtime) 但由于 mtime 有 1 秒的粒度,我已经学会了碰撞确实发生的艰难方式。在密钥中使用文件名和文件大小也会降低冲突的可能性。我认为最好的方法是在释放 inode 时删除缓存(使用来自内核的某种通知)。在开发和测试真正的修复程序之前,tmpfs 'hack' 可以为我的问题带来快速而肮脏的解决方案。感谢您的建议
    • 好吧,很抱歉告诉你你已经知道并测试了 xD
    【解决方案2】:

    大部分 tmpfs 代码在 mm/shmem.c 中。新的 inode 由

    创建
    static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,
                                     int mode, dev_t dev, unsigned long flags)
    

    但它将几乎所有内容都委托给通用文件系统代码。

    特别是i_ino字段填写fs/inode.c:

    /**
     *      new_inode       - obtain an inode
     *      @sb: superblock
     *
     *      Allocates a new inode for given superblock. The default gfp_mask
     *      for allocations related to inode->i_mapping is GFP_HIGHUSER_MOVABLE.
     *      If HIGHMEM pages are unsuitable or it is known that pages allocated
     *      for the page cache are not reclaimable or migratable,
     *      mapping_set_gfp_mask() must be called with suitable flags on the
     *      newly created inode's mapping
     *
     */
    struct inode *new_inode(struct super_block *sb)
    {
            /*
             * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
             * error if st_ino won't fit in target struct field. Use 32bit counter
             * here to attempt to avoid that.
             */
            static unsigned int last_ino;
            struct inode *inode;
    
            spin_lock_prefetch(&inode_lock);
    
            inode = alloc_inode(sb);
            if (inode) {
                    spin_lock(&inode_lock);
                    __inode_add_to_lists(sb, NULL, inode);
                    inode->i_ino = ++last_ino;
                    inode->i_state = 0;
                    spin_unlock(&inode_lock);
            }
            return inode;
    }
    

    它确实只是使用递增计数器 (last_ino)。

    大多数其他文件系统使用磁盘文件中的信息来覆盖i_ino 字段。

    请注意,它完全有可能一直环绕。内核还有一个“代”字段,可以通过各种方式填充。 mm/shmem.c 使用当前时间。

    【讨论】:

    • 感谢您挖掘这个。你说的“一路环绕”是什么意思?
    • 溢出时归零
    猜你喜欢
    • 1970-01-01
    • 2012-05-17
    • 2010-10-23
    • 2016-05-09
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    相关资源
    最近更新 更多