开发者

how are inode numbers generated in linux tmpfs?

It seems to me that tmpfs is not re-using inode numbers, but instead creates a new inode number via a +1 sequence everytime it needs a free inode.

Do you know how this is implemented / can you pin-point 开发者_JS百科me to some source code where i could check the algorithm that is used in tmpfs ?

I need to understand this in order to bypass a limitation in a caching system that uses the inode number as its cache key (hence leading to rare, but occuring collisions when inodes are re-used too often). tmpfs could save my day if I can prove that it keeps creating unique inode numbers.

Thank you for your help,

Jerome Wagner


I won't directly answer your question, so I apologize in advance for that.

The tmpfs idea is good, but I wouldn't have my program depend on a more or less obscure implementation detail for generating keys. Why don't you try another method, such as combining the inode number with some other information? Maybe modification date: it's impossible two files get the same inode number AND modification date at the time of key-generation, unless system date changes.

Cheers!


The bulk of the tmpfs code is in mm/shmem.c. New inodes are created by

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

but it delegates almost everything to the generic filesystem code.

In particular, the field i_ino is filled in in 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;
}

And it does indeed just use an incrementing counter (last_ino).

Most other filesystems use information from the on-disk files to later override the i_ino field.

Note that it's perfectly possible for this to wrap all the way around. The kernel also has a "generation" field that gets filled in various ways. mm/shmem.c uses the current time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜