趣談Linux操做系統學習筆記:第二十八講

1、引子

磁盤→盤片→磁道→扇區(每一個 512 字節)node

ext* 定義文件系統的格式數據結構

2、inode 與塊的存儲

一、塊

二、不用給他分配一塊連續的空間

咱們能夠分散成一個個小塊進行存放函數

一、優勢

二、存在的問題

三、如何解決

三、inode裏面有哪些信息?

至於 inode 裏面有哪些信息,其實咱們在內核中就有定義。你能夠看下面這個數據結構。佈局

struct ext4_inode {
	__le16	i_mode;		/* File mode */
	__le16	i_uid;		/* Low 16 bits of Owner Uid */
	__le32	i_size_lo;	/* Size in bytes */
	__le32	i_atime;	/* Access time */
	__le32	i_ctime;	/* Inode Change 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_lo;	/* Blocks count */
	__le32	i_flags;	/* File flags */
......
	__le32	i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
	__le32	i_generation;	/* File version (for NFS) */
	__le32	i_file_acl_lo;	/* File ACL */
	__le32	i_size_high;
......
};

一、什麼是inode?性能

二、基本信息ui

三、時間相關信息spa

四、i_blocks_lo3d

五、i_blockorm

四、這些在 inode 裏面,應該保存在 i_block 裏面。

具體如何保存的呢?EXT4_N_BLOCKS 有以下的定義,blog

#define	EXT4_NDIR_BLOCKS		12
#define	EXT4_IND_BLOCK			EXT4_NDIR_BLOCKS
#define	EXT4_DIND_BLOCK			(EXT4_IND_BLOCK + 1)
#define	EXT4_TIND_BLOCK			(EXT4_DIND_BLOCK + 1)
#define	EXT4_N_BLOCKS			(EXT4_TIND_BLOCK + 1

一、如何保存?

二、文件比較大12塊放不下?

三、文件再大些

四、文件更大一些

五、存在問題

3、Extents

ext4 引入 Extents 概念, 能夠用於存放連續的數據塊

優勢:對於大文件的讀寫性能提升了,文件碎片也減小了

一、Extents是如何存儲?

ext4_extent_header

struct ext4_extent_header {
	__le16	eh_magic;	/* probably will support different formats */
	__le16	eh_entries;	/* number of valid entries */
	__le16	eh_max;		/* capacity of store in entries */
	__le16	eh_depth;	/* has tree real underlying blocks? */
	__le32	eh_generation;	/* generation of the tree */
};

  

/*
 * This is the extent on-disk structure.
 * It's used at the bottom of the tree.
 */
struct ext4_extent {
	__le32	ee_block;	/* first logical block extent covers */
	__le16	ee_len;		/* number of blocks covered by extent */
	__le16	ee_start_hi;	/* high 16 bits of physical block */
	__le32	ee_start_lo;	/* low 32 bits of physical block */
};
/*
 * This is index on-disk structure.
 * It's used at all the levels except the bottom.
 */
struct ext4_extent_idx {
	__le32	ei_block;	/* index covers logical blocks from 'block' */
	__le32	ei_leaf_lo;	/* pointer to the physical block of the next *
				 * level. leaf or next index could be there */
	__le16	ei_leaf_hi;	/* high 16 bits of physical block */
	__u16	ei_unused;
};

3、inode 位圖和塊位圖

要保存數據是, 應放在哪? 全掃一遍效率低

 一、位圖

二、塊組

上海虹橋火車站的廁位智能引導系統,不知道你有沒有見過?這個系統很厲害,咱們要想知道哪一個位置有沒有被佔用,不用挨個拉門,從這樣一個電子版上就能看到了

 

 do_sys_open

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
	if (force_o_largefile())
		flags |= O_LARGEFILE;


	return do_sys_open(AT_FDCWD, filename, flags, mode);
}

inode 操做的調用鏈

一、要打開一個文件,先要根據路徑找到文件夾、若是發現文件夾下面沒有這個文件,同時又設置了 O_CREAT
二、就說明咱們要在這個文件夾下面建立一個文件,那咱們就須要一個新inode

static int lookup_open(struct nameidata *nd, struct path *path,
			struct file *file,
			const struct open_flags *op,
			bool got_write, int *opened)
{
......
	if (!dentry->d_inode && (open_flag & O_CREAT)) {
......
		error = dir_inode->i_op->create(dir_inode, dentry, mode,
						open_flag & O_EXCL);
......
	}
......
}

想要建立新的 inode,咱們就要調用 dir_inode,
也就是文件夾的 inode 的 create 函數。它的具體定義是這樣

const struct inode_operations ext4_dir_inode_operations = {
	.create		= ext4_create,
	.lookup		= ext4_lookup,
	.link		= ext4_link,
	.unlink		= ext4_unlink,
	.symlink	= ext4_symlink,
	.mkdir		= ext4_mkdir,
	.rmdir		= ext4_rmdir,
	.mknod		= ext4_mknod,
	.tmpfile	= ext4_tmpfile,
	.rename		= ext4_rename2,
	.setattr	= ext4_setattr,
	.getattr	= ext4_getattr,
	.listxattr	= ext4_listxattr,
	.get_acl	= ext4_get_acl,
	.set_acl	= ext4_set_acl,
	.fiemap         = ext4_fiemap,
};

接下來的調用鏈是這樣

 

struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
			       umode_t mode, const struct qstr *qstr,
			       __u32 goal, uid_t *owner, __u32 i_flags,
			       int handle_type, unsigned int line_no,
			       int nblocks)
{
......
inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
......
ino = ext4_find_next_zero_bit((unsigned long *)
					      inode_bitmap_bh->b_data,
					      EXT4_INODES_PER_GROUP(sb), ino);
......
}

 

4、文件系統的格式

一個位圖只能表示 2^15 個數據塊, 即 128MB

一、塊組

超級塊 ext4_super_block

 


一個 inode 位圖 + 一個 block 位圖, 稱爲塊組, 用數據結構 ext4_group_desc 表示, 裏面包含 inode 位圖, block 位圖和 inode 列表

 


這些塊組描述符構成列表, 另外用超級塊 ext4_super_block 描述整個文件系統; 第一個塊組前 1k 用於啓動引導

 


文件系統的組成

 

文件系統由引導塊 + N 個塊組組成; 每一個塊組由: 超級塊 + 塊組描述符表 + 塊位圖 + inode 位圖 + inode 列表 + 數據塊構成
超級塊和塊組描述符表都是全局信息; 默認超級塊和塊組描述符表再滅個租客都有備份; 若開啓 sparse_super, 則只在固定塊組中備份
採用 Meta Block Groups 特性, 避免塊組表浪費空間, 或限制文件系統的大小

 


- 將塊組分紅多個組(元塊組) 塊組描述符表只保存當前元塊組中塊組的信息, 並在元塊組內備份

struct ext4_super_block {
......
	__le32	s_blocks_count_lo;	/* Blocks count */
	__le32	s_r_blocks_count_lo;	/* Reserved blocks count */
	__le32	s_free_blocks_count_lo;	/* Free blocks count */
......
	__le32	s_blocks_count_hi;	/* Blocks count */
	__le32	s_r_blocks_count_hi;	/* Reserved blocks count */
	__le32	s_free_blocks_count_hi;	/* Free blocks count */
......
}

5、目錄的存儲格式

目錄也是文件, 也有 inode, inode 指向一個塊, 塊中保存各個文件信息, ext4_dir_entry 包括文件名和 inode, 默認按列表存

struct ext4_dir_entry {
	__le32	inode;			/* Inode number */
	__le16	rec_len;		/* Directory entry length */
	__le16	name_len;		/* Name length */
	char	name[EXT4_NAME_LEN];	/* File name */
};
struct ext4_dir_entry_2 {
	__le32	inode;			/* Inode number */
	__le16	rec_len;		/* Directory entry length */
	__u8	name_len;		/* Name length */
	__u8	file_type;
	char	name[EXT4_NAME_LEN];	/* File name */
};

第一項 "." 當前目錄; 第二項 ".." 上一級目錄

struct dx_root
{
	struct fake_dirent dot;
	char dot_name[4];
	struct fake_dirent dotdot;
	char dotdot_name[4];
	struct dx_root_info
	{
		__le32 reserved_zero;
		u8 hash_version;
		u8 info_length; /* 8 */
		u8 indirect_levels;
		u8 unused_flags;
	}
	info;
	struct dx_entry	entries[0];
};

可添加索引, 加快文件查找

struct dx_entry
{
	__le32 hash;
	__le32 block;
};

須要改變目錄塊格式, 加入索引樹: 用索引項 dx_entry 保存文件名哈希和塊的映射, 若該塊不是索引, 則裏面保存 ext4_dir_enry 列表, 逐項查找

6、軟連接和硬連接的存儲格式

一、連接即文件的別名: ln -s 建立軟連接; ln 建立硬連接
二、硬連接與原始文件共用一個 inode, 但不能跨文件系統
三、軟連接是一個文件, 有本身的 inode, 該文件內容指向另外一個文件, 可跨文件系統

7、總結時刻

這一節,咱們描述了複雜的應哦按上的文件系統,可是對於我們平時的應用來說,用的最多的是兩個概念,一個是inode、一個是數據塊

爲了表示圖中上半部分的那個簡單的樹形結構,在文件系統上的佈局就像圖的下半部分同樣,不管是文件夾仍是文件,都有一個inode,inode裏面的會指向數據塊,對於文件夾的數據塊,裏面是一個表,是下一層的文件和inode的對應關係,文件的數據塊裏面存放的是真正的數據

相關文章
相關標籤/搜索