inode实际上是否指向磁盘中的地址?

Linux文件系统中的inode如何实际指向磁盘上的块? 它是否包含一个从0到2 ^ 63 – 1的64位可寻址数字? 或者inode结构和实际磁盘地址之间是否有一层?

答案是视情况而定

不同的文件系统不同地存储inode信息。 有些会将实际的文件内容存储在索引节点结构中,如果大小足够小的话,有些会将虚拟或实际的块号码存储为32或64位数字,有时甚至是另一种编码,有些会将偏移量存储在磁盘空间中,将存储更复杂的信息来处理跨越许多块的大文件…

您可以在Internet上找到各种文件系统的详细信息,了解文件系统性能非常有趣。

请享用!

正如在ext2 inodes的osdev wiki中所说 :

像块一样,每个inode都有一个数字地址。 需要注意的是,与块地址不同,inode地址从1开始。

每个inode包含12个直接指针,一个单独的间接指针,一个双重间接块指针和一个三重间接指针。 直接的空间“溢出”到单一的间接空间中,溢出到双重间接空间中,溢出到三重间接空间中。

直接块指针:有12个直接块指针。 如果有效,则该值不为零。 每个指针都是包含此inode数据的块的块地址。

单一间接块指针:如果一个文件需要多于12个块,则分配一个单独的块来存储其内容所需的其余数据块的块地址。 这个单独的块被称为间接块,因为它在inode和它的数据之间增加了一个额外的步骤(一个间接级别)。 存储在块中的块地址全部是32位,并且该块中存储的地址的容量是块大小的函数。 该间接块的地址被存储在“单一间接块指针”字段中的inode中。

双向间接块指针:如果一个文件的块数多于12个直接指针和间接块,则使用双重间接块。 双间接块是上述间接块的扩展,现在我们在inode和数据块之间有两个中间块。 inode结构有一个“双向间接块指针”字段,如果需要的话指向这个块。

三重间接块指针:最后,如果一个文件需要更多的空间,它可以使用三重间接块。 再次,这是双重间接块的延伸。 因此,一个三重间接块包含双重间接块的地址,其中包含单个间接块的地址,其中包含数据块的地址。 inode结构有一个“Triply Indirect Block Pointer”字段,指向这个块(如果存在的话)。

inode关系

正如你可能知道的那样,在VFS中使用的linux中有一个逻辑inode。
VFS inode数据结构保存有关磁盘上文件或目录的信息。

 struct inode { kdev_t i_dev; unsigned long i_ino; umode_t i_mode; nlink_t i_nlink; uid_t i_uid; gid_t i_gid; kdev_t i_rdev; off_t i_size; time_t i_atime; time_t i_mtime; time_t i_ctime; unsigned long i_blksize; unsigned long i_blocks; unsigned long i_version; unsigned long i_nrpages; struct semaphore i_sem; struct inode_operations *i_op; struct super_block *i_sb; struct wait_queue *i_wait; struct file_lock *i_flock; struct vm_area_struct *i_mmap; struct page *i_pages; struct dquot *i_dquot[MAXQUOTAS]; struct inode *i_next, *i_prev; struct inode *i_hash_next, *i_hash_prev; struct inode *i_bound_to, *i_bound_by; struct inode *i_mount; unsigned short i_count; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; unsigned char i_pipe; unsigned char i_sock; unsigned char i_seek; unsigned char i_update; unsigned short i_writecount; union { struct pipe_inode_info pipe_i; struct minix_inode_info minix_i; struct ext_inode_info ext_i; struct ext2_inode_info ext2_i; struct hpfs_inode_info hpfs_i; struct msdos_inode_info msdos_i; struct umsdos_inode_info umsdos_i; struct iso_inode_info isofs_i; struct nfs_inode_info nfs_i; struct xiafs_inode_info xiafs_i; struct sysv_inode_info sysv_i; struct affs_inode_info affs_i; struct ufs_inode_info ufs_i; struct socket socket_i; void *generic_ip; } u; }; 

有关ext4 fs,请参阅https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout

根据我对ext4的理解,磁盘被分成多个块。 存储在inode中的地址基本上是块号。 所以,实际的地址是block_number * block_size。

“一般来说,虽然实际大小计算为2 ^(10 + sb.s_log_block_size)个字节,但块大小将为4KiB(与x86上的页面大小相同,并且块大小为默认块大小)

谢谢