ext4 分配节点ext4_alloc_inode

/*
 * Called inside transaction, so use GFP_NOFS
 */
static struct inode *ext4_alloc_inode(struct super_block *sb)
{
    struct ext4_inode_info *ei;

    ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS);
    if (!ei)
        return NULL;

    ei->vfs_inode.i_version = 1;
    spin_lock_init(&ei->i_raw_lock);
    INIT_LIST_HEAD(&ei->i_prealloc_list);
    spin_lock_init(&ei->i_prealloc_lock);
    ext4_es_init_tree(&ei->i_es_tree);
    rwlock_init(&ei->i_es_lock);
    INIT_LIST_HEAD(&ei->i_es_list);
    ei->i_es_all_nr = 0;
    ei->i_es_shk_nr = 0;
    ei->i_es_shrink_lblk = 0;
    ei->i_reserved_data_blocks = 0;
    ei->i_reserved_meta_blocks = 0;
    ei->i_allocated_meta_blocks = 0;
    ei->i_da_metadata_calc_len = 0;
    ei->i_da_metadata_calc_last_lblock = 0;
    spin_lock_init(&(ei->i_block_reservation_lock));
#ifdef CONFIG_QUOTA
    ei->i_reserved_quota = 0;
    memset(&ei->i_dquot, 0, sizeof(ei->i_dquot));
#endif
    ei->jinode = NULL;
    INIT_LIST_HEAD(&ei->i_rsv_conversion_list);
    spin_lock_init(&ei->i_completed_io_lock);
    ei->i_sync_tid = 0;
    ei->i_datasync_tid = 0;
    atomic_set(&ei->i_unwritten, 0);
    INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
    return &ei->vfs_inode;
}



/*
 * fourth extended file system inode data in memory
 */
struct ext4_inode_info {
    __le32    i_data[15];    /* unconverted */
    __u32    i_dtime;
    ext4_fsblk_t    i_file_acl;

    /*
     * i_block_group is the number of the block group which contains
     * this file's inode.  Constant across the lifetime of the inode,
     * it is ued for making block allocation decisions - we try to
     * place a file's data blocks near its inode block, and new inodes
     * near to their parent directory's inode.
     */
    ext4_group_t    i_block_group;
    ext4_lblk_t    i_dir_start_lookup;
#if (BITS_PER_LONG < 64)
    unsigned long    i_state_flags;        /* Dynamic state flags */
#endif
    unsigned long    i_flags;

    /*
     * Extended attributes can be read independently of the main file
     * data. Taking i_mutex even when reading would cause contention
     * between readers of EAs and writers of regular file data, so
     * instead we synchronize on xattr_sem when reading or changing
     * EAs.
     */
    struct rw_semaphore xattr_sem;

    struct list_head i_orphan;    /* unlinked but open inodes */

    /*
     * i_disksize keeps track of what the inode size is ON DISK, not
     * in memory.  During truncate, i_size is set to the new size by
     * the VFS prior to calling ext4_truncate(), but the filesystem won't
     * set i_disksize to 0 until the truncate is actually under way.
     *
     * The intent is that i_disksize always represents the blocks which
     * are used by this file.  This allows recovery to restart truncate
     * on orphans if we crash during truncate.  We actually write i_disksize
     * into the on-disk inode when writing inodes out, instead of i_size.
     *
     * The only time when i_disksize and i_size may be different is when
     * a truncate is in progress.  The only things which change i_disksize
     * are ext4_get_block (growth) and ext4_truncate (shrinkth).
     */
    loff_t    i_disksize;

    /*
     * i_data_sem is for serialising ext4_truncate() against
     * ext4_getblock().  In the 2.4 ext2 design, great chunks of inode's
     * data tree are chopped off during truncate. We can't do that in
     * ext4 because whenever we perform intermediate commits during
     * truncate, the inode and all the metadata blocks *must* be in a
     * consistent state which allows truncation of the orphans to restart
     * during recovery.  Hence we must fix the get_block-vs-truncate race
     * by other means, so we have i_data_sem.
     */
    struct rw_semaphore i_data_sem;
    /*
     * i_mmap_sem is for serializing page faults with truncate / punch hole
     * operations. We have to make sure that new page cannot be faulted in
     * a section of the inode that is being punched. We cannot easily use
     * i_data_sem for this since we need protection for the whole punch
     * operation and i_data_sem ranks below transaction start so we have
     * to occasionally drop it.
     */
    struct rw_semaphore i_mmap_sem;
    struct inode vfs_inode;
    struct jbd2_inode *jinode;

    spinlock_t i_raw_lock;    /* protects updates to the raw inode */

    /*
     * File creation time. Its function is same as that of
     * struct timespec i_{a,c,m}time in the generic inode.
     */
    struct timespec i_crtime;

    /* mballoc */
    struct list_head i_prealloc_list;
    spinlock_t i_prealloc_lock;

    /* extents status tree */
    struct ext4_es_tree i_es_tree;
    rwlock_t i_es_lock;
    struct list_head i_es_list;
    unsigned int i_es_all_nr;    /* protected by i_es_lock */
    unsigned int i_es_shk_nr;    /* protected by i_es_lock */
    ext4_lblk_t i_es_shrink_lblk;    /* Offset where we start searching for
                       extents to shrink. Protected by
                       i_es_lock  */

    /* ialloc */
    ext4_group_t    i_last_alloc_group;

    /* allocation reservation info for delalloc */
    /* In case of bigalloc, these refer to clusters rather than blocks */
    unsigned int i_reserved_data_blocks;
    unsigned int i_reserved_meta_blocks;
    unsigned int i_allocated_meta_blocks;
    ext4_lblk_t i_da_metadata_calc_last_lblock;
    int i_da_metadata_calc_len;

    /* on-disk additional length */
    __u16 i_extra_isize;

    /* Indicate the inline data space. */
    u16 i_inline_off;
    u16 i_inline_size;

#ifdef CONFIG_QUOTA
    /* quota space reservation, managed internally by quota code */
    qsize_t i_reserved_quota;
#endif

    /* Lock protecting lists below */
    spinlock_t i_completed_io_lock;
    /*
     * Completed IOs that need unwritten extents handling and have
     * transaction reserved
     */
    struct list_head i_rsv_conversion_list;
    struct work_struct i_rsv_conversion_work;
    atomic_t i_unwritten; /* Nr. of inflight conversions pending */

    spinlock_t i_block_reservation_lock;

    /*
     * Transactions that contain inode's metadata needed to complete
     * fsync and fdatasync, respectively.
     */
    tid_t i_sync_tid;
    tid_t i_datasync_tid;

#ifdef CONFIG_QUOTA
    struct dquot *i_dquot[MAXQUOTAS];
#endif

    /* Precomputed uuid+inum+igen checksum for seeding inode checksums */
    __u32 i_csum_seed;

    kprojid_t i_projid;
};






<think>我们正在讨论Linux内核中的new_inode函数。这个函数通常在fs/inode.c文件中定义。它的作用是创建一个新的inode结构并初始化其基本字段。 在Linux内核中,new_inode函数通常由文件系统实现使用,用于分配一个新的inode对象。该函数会调用inode_cachep(inode对象的slab缓存)来分配内存,并初始化inode的一些基本字段(如i_state设置为0,即新状态)。 下面是一个典型的new_inode函数实现(以Linux内核版本5.x为例)的简化表示: ```c struct inode *new_inode(struct super_block *sb) { struct inode *inode; inode = alloc_inode(sb); // 实际分配inode对象 if (inode) { spin_lock(&inode->i_lock); inode->i_state = 0; // 初始状态为0 spin_unlock(&inode->i_lock); // 其他初始化... } return inode; } ``` 注意:实际的内核代码可能更复杂,但核心逻辑是分配并初始化一个新的inode。 然而,需要注意的是,不同的内核版本可能有所变化,而且不同的文件系统可能有自己的分配inode的函数(例如ext4_new_inode)。但new_inode是一个通用函数,供那些没有特殊需求的文件系统使用。 因此,new_inode函数定义在fs/inode.c文件中。 §§相关问题§§ 1. new_inode函数在哪些情况下会被调用? 2. alloc_inode函数的作用是什么? 3. 文件系统如何自定义inode的创建? 4. inode结构中的i_state字段有哪些可能的状态? 5. 为什么在分配inode后需要加锁?</think>`new_inode`函数在Linux内核源代码中定义于`fs/inode.c`文件中。该函数负责创建并初始化一个新的`struct inode`对象,用于表示文件系统中的索引节点。其核心实现逻辑如下(基于Linux 5.x内核): ```c struct inode *new_inode(struct super_block *sb) { struct inode *inode; inode = alloc_inode(sb); // 从slab缓存分配内存 if (inode) { spin_lock(&inode->i_lock); // 获取自旋锁 inode->i_state = 0; // 初始化状态为0 (未使用状态) spin_unlock(&inode->i_lock); // 释放锁 inode_sb_list_add(inode); // 添加到超级块的inode链表 } return inode; } ``` ### 关键说明: 1. **调用位置**:文件系统实现中(如ext4的`ext4_new_inode()`)会调用此函数 2. **内存管理**:通过`alloc_inode()`从`inode_cachep` slab分配器获取内存 3. **初始化**: - 设置`i_state = 0`(清除I_NEW等标志) - 初始化引用计数`i_count` - 加入超级块的inode链表 4. **锁机制**:使用自旋锁`i_lock`保证多核安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值