@@ -5,7 +5,7 @@ categories:
55 - 内核层
66abbrlink : f548d964
77date : 2024-12-24 16:05:00
8- updated : 2024-12-25 16:10 :00
8+ updated : 2024-12-25 17:30 :00
99---
1010
1111<meta name =" referrer " content =" no-referrer " />
@@ -85,7 +85,7 @@ dentry 将 inode 和 文件名关联起来,存储以下信息:
85851 . 用于标识 inode 的整数。
86862 . 表示文件名的字符串。
8787
88- dentry 是目录或文件路径的特定部分。例如,对于路径 ` /bin/vi ` ,为 ` / ` , ` bin ` 和 ` vi ` 创建共 3 个 dentry 对象。
88+ dentry 是目录或文件路径的特定部分。例如,对于路径 ` /bin/vi ` ,为 ` / ` 、 ` bin ` 和 ` vi ` 创建共 3 个 dentry 对象。
8989
9090dentry 在磁盘上有对应物,但对应关系不是直接的。每个文件系统都有特定的方式维护 dentry。
9191
@@ -373,6 +373,154 @@ struct buffer_head
3733731 . S_ISDIR(inode->i_mode):用于检查索引节点是否为目录。
3743742 . S_ISREG(inode->i_mode):用于检查索引节点是否为普通文件(非链接或设备文件)。
375375
376+ # inode
377+
378+ inode 是文件系统的元数据(它包含信息的信息)。inode 是磁盘上文件的唯一标识,保存文件的信息(uid、gid、访问权限、访问时间以及指向数据块的指针等)。重要的一点是,inode 不保存文件名信息,文件名由相关的 ` struct dentry ` 结构保存。
379+
380+ inode 用于引用磁盘上的文件。对于进程打开的文件,使用 ` struct file ` 结构。一个 inode 可以关联一个或多个 ` struct file ` 结构。多个进程可以打开同一个文件,一个进程可以多次打开同一个文件。
381+
382+ inode 既存在于内存中的 VFS 结构,也存在于磁盘中(UNIX、HFS 以及 NTFS 等)。VFS 中的 inode 由 ` struct inode ` 结构表示。和 VFS 中的其他结构一样,` struct inode ` 是通用结构,涵盖了所有支持的文件类型的选项,甚至包括那些没有关联磁盘实体的文件类型(例如 FAT 文件系统)。
383+
384+ ## inode 结构
385+
386+ ` struct inode ` 定义如下:
387+
388+ ``` c
389+ struct inode
390+ {
391+ umode_t i_mode; // i_uid 以及 i_gid:访问权限、uid 以及 gid。
392+ unsigned short i_opflags;
393+ kuid_t i_uid;
394+ kgid_t i_gid;
395+ unsigned int i_flags;
396+
397+ #ifdef CONFIG_FS_POSIX_ACL
398+ struct posix_acl *i_acl;
399+ struct posix_acl *i_default_acl;
400+ #endif
401+
402+ const struct inode_operations *i_op; // 指向结构 inode_operations 的指针。
403+ struct super_block *i_sb; // inode 所属的文件系统的超级块结构。
404+ struct address_space *i_mapping; // i_mapping->a_ops 包含指向 struct address_space_operations 的指针。
405+
406+ #ifdef CONFIG_SECURITY
407+ void *i_security;
408+ #endif
409+
410+ /* Stat data, not accessed from path walking */
411+ unsigned long i_ino; // inode 的编号(在文件系统内唯一标识 inode)。
412+ /*
413+ * Filesystems may only read i_nlink directly. They shall use the
414+ * following functions for modification:
415+ *
416+ * (set|clear|inc|drop)_nlink
417+ * inode_(inc|dec)_link_count
418+ */
419+
420+ // 使用此 inode 的名称条目(dentry)的数量;对于没有链接(既没有硬链接也没有符号链接)的文件系统,这个值总是设置为 1。
421+ union
422+ {
423+ const unsigned int i_nlink;
424+ unsigned int __i_nlink;
425+ };
426+
427+ dev_t i_rdev; // 挂载的文件系统所在的设备。
428+ loff_t i_size; // 文件/目录等的大小(以字节为单位)。
429+ struct timespec64 i_atime; // 访问时间。
430+ struct timespec64 i_mtime; // 修改时间。
431+ struct timespec64 i_ctime; // 创建时间。
432+ spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
433+ unsigned short i_bytes;
434+ u8 i_blkbits; // 块大小使用的比特数 == log2(块大小)。
435+ u8 i_write_hint;
436+ blkcnt_t i_blocks; // 文件使用的块数(所有块,不仅仅是数据块)。这仅由配额子系统使用。
437+
438+ #ifdef __NEED_I_SIZE_ORDERED
439+ seqcount_t i_size_seqcount;
440+ #endif
441+
442+ /* Misc */
443+ unsigned long i_state;
444+ struct rw_semaphore i_rwsem;
445+
446+ unsigned long dirtied_when; /* jiffies of first dirtying */
447+ unsigned long dirtied_time_when;
448+
449+ struct hlist_node i_hash;
450+ struct list_head i_io_list; /* backing dev IO list */
451+ #ifdef CONFIG_CGROUP_WRITEBACK
452+ struct bdi_writeback *i_wb; /* the associated cgroup wb */
453+
454+ /* foreign inode detection, see wbc_detach_inode() */
455+ int i_wb_frn_winner;
456+ u16 i_wb_frn_avg_time;
457+ u16 i_wb_frn_history;
458+ #endif
459+ struct list_head i_lru; /* inode LRU list */
460+ struct list_head i_sb_list;
461+ struct list_head i_wb_list; /* backing dev writeback list */
462+ union
463+ {
464+ struct hlist_head i_dentry;
465+ struct rcu_head i_rcu;
466+ };
467+ atomic64_t i_version;
468+ atomic64_t i_sequence; /* see futex */
469+ atomic_t i_count; // inode 计数器,指示有多少内核组件在使用它。
470+ atomic_t i_dio_count;
471+ atomic_t i_writecount;
472+ #if defined(CONFIG_IMA) || defined(CONFIG_FILE_LOCKING)
473+ atomic_t i_readcount; /* struct files open RO */
474+ #endif
475+ union
476+ {
477+ const struct file_operations *i_fop; // 指向结构 file_operations 的指针。former ->i_op->default_file_ops
478+ void (* free_inode)(struct inode * );
479+ };
480+ struct file_lock_context * i_flctx;
481+ struct address_space i_data;
482+ struct list_head i_devices;
483+ union
484+ {
485+ struct pipe_inode_info * i_pipe;
486+ struct cdev * i_cdev;
487+ char * i_link;
488+ unsigned i_dir_seq;
489+ };
490+
491+ __u32 i_generation;
492+
493+ #ifdef CONFIG_FSNOTIFY
494+ __u32 i_fsnotify_mask; /* all events this inode cares about */
495+ struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
496+ #endif
497+
498+ #ifdef CONFIG_FS_ENCRYPTION
499+ struct fscrypt_info *i_crypt_info;
500+ #endif
501+
502+ #ifdef CONFIG_FS_VERITY
503+ struct fsverity_info *i_verity_info;
504+ #endif
505+
506+ void *i_private; /* fs or device private pointer */
507+ } __randomize_layout;
508+ ```
509+
510+ 一些可用于处理 inode 的函数如下:
511+
512+ 1 . new_inode():创建新的 inode,将 i_nlink 字段设置为 1,并初始化 i_blkbits, i_sb 和 i_dev。
513+ 2 . insert_inode_hash():将 inode 添加到 inode 哈希表中。这个调用的一个有趣的效果是,如果 inode 被标记为脏,它将被写入磁盘。
514+ 3 . mark_inode_dirty():将 inode 标记为脏,稍后它将被写入磁盘。
515+ 4 . iget_locked():从磁盘加载具有给定编号的 inode,如果它尚未加载。
516+ 5 . unlock_new_inode():与 iget_locked() 一起使用,释放对 inode 的锁定。
517+ 6 . iput():告诉内核对 inode 的操作已经完成。若没有其他进程在使用,它将被销毁(如果被标记为脏,则写入磁盘后再销毁)。
518+ 7 . make_bad_inode():告诉内核该 inode 无法使用;通常在从磁盘读取 inode 时发现无法读取的情况下使用,表示该 inode 无效。
519+
520+ ## inode 操作
521+
522+ TODO
523+
376524# 参考文章
377525
3785261 . [ Linux Kernel Teaching — The Linux Kernel documentation] ( https://linux-kernel-labs.github.io/refs/heads/master/ )
0 commit comments