其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个”块”(block)。
硬盘的每个分区是被划分为⼀个个的”块”。⼀个”块”的⼤⼩是由格式化的时候确定的,并且不可以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个”块”。”块”是⽂件存取的最⼩单位。
注意:
其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有⼀块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的⼀种格式化。但是Linux的设备都是以⽂件形式存在,那是怎么分区的呢?
柱⾯是分区的最⼩单位,我们可以利⽤参考柱⾯号码的⽅式来进⾏分区,其本质就是设置每个区的起始柱⾯和结束柱⾯号码。此时我们可以将硬盘上的柱⾯(分区)进⾏平铺,将其想象成⼀个⼤的平⾯,如下图所⽰:
注意:
之前我们说过文件=数据+属性,我们使用ls -l的时候看到的除了看到文件名,还能看到文件元数据(属性)。
[root@localhost linux]# ls -l
总用量12
-rwxr-xr-x. 1 root root 7438 "12月31 14:56" a.out
-rw-r--r--. 1 root root 654 "12月31 14:56" test.c
每⾏包含7列:
ls-l读取存储在磁盘上的⽂件信息,然后显⽰出来
其实这个信息除了通过这种⽅式来读取,还有⼀个stat命令能够看到更多信息
wks@hcss-ecs-ab43:~/code/signal23$ stat sig.c
File: sig.c
Size: 914 Blocks: 8 IO Block: 4096 regular file
Device: fc01h/64513d Inode: 408125 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ wks) Gid: ( 1000/ wks)
Access: 2024-12-30 23:00:52.279144447 +0800
Modify: 2024-12-30 23:00:17.386385482 +0800
Change: 2024-12-30 23:00:17.386385482 +0800
Birth: 2024-12-29 17:34:47.804387835 +0800
到这我们要思考⼀个问题,⽂件数据都储存在”块”中,那么很显然,我们还必须找到⼀个地⽅储存⽂件的元信息(属性信息),⽐如⽂件的创建者、⽂件的创建⽇期、⽂件的⼤⼩等等。这种储存⽂件元信息的区域就叫做inode,中⽂译名为”索引节点”。
每⼀个⽂件都有对应的inode,⾥⾯包含了与该⽂件有关的⼀些信息。为了能解释清楚inode,我们需 要是深⼊了解⼀下⽂件系统。
注意:
所以⼀个⽂件的属性inode⻓什么样⼦呢?
/*
* Structure of an inode on the disk
*/
struct ext2_inode
{
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Creation time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks; /* Blocks count */
__le32 i_flags; /* File flags */
union
{
struct
{
__le32 l_i_reserved1;
} linux1;
struct
{
__le32 h_i_translator;
} hurd1;
struct
{
__le32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__le32 i_block[EXT2_N_BLOCKS]; /* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl; /* File ACL */
__le32 i_dir_acl; /* Directory ACL */
__le32 i_faddr; /* Fragment address */
union
{
struct
{
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct
{
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__le16 h_i_mode_high;
__le16 h_i_uid_high;
__le16 h_i_gid_high;
__le32 h_i_author;
} hurd2;
struct
{
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
备注:
EXT2_N_BLOCKS = 15
再次注意:
到⽬前为⽌,相信⼤家还有两个问题:
在Ext系列文件系统中块的组织和查找