Linux.ext4文件系统.inode和extent

Linux内核学习:EXT4 INode在磁盘上的读写 目录 1 关于Ext4系统的一些概念 1.1 Inode与Data Block 1.2 关于上述概念的规律 2 查找Inode在磁盘的位置 2.1 关于Inode操作的数据结构 2.2 Ext4在磁盘上Inode分配的策略分析 2.3.1目录的Inode分配策略 2.3.2文件的inode分配策略 2.3 Inode分配情况 2.3.1 磁盘块上的Inode分配 3 ex... 阅读详情
  • 最近在看ext4系统的extent相关内容
  • 对于文件系统,每个文件会对应一系列磁盘块,通过在inode中有序的存放磁盘块号,也就保存下了<文件逻辑块号, 磁盘块号>的映射关系
  • 一个文件的逻辑块号必然是连续的,而磁盘块号则不必连续
  • 通常一个block大小为4KB,所以一个比较大的文件,就需要存相当多的块号——而这是一个十分笨拙的办法
  • 对于很大的文件,有一种解决办法就是间接存放块号,也就是说inode中有部分块号指向的block不是存放这个file的数据,而是存放块号——即一种间接寻址的逻辑。通常会包括三级,一部分直接指向文件的数据块,一部分指向存有块号的块,一部分指向存有“存有块号的块的块号”的块,哈哈
  • 而ext4采用的办法是使用extent来保存<文件逻辑块号, 磁盘块号>的映射关系:一个extent对应一系列连续的块号,故可以想到,一个extent最基本的几个域有——文件逻辑块号,起始磁盘块号,块数量
  • ext4中一个inode可以直接存放4个extent
  • 对于很大的文件,ext4采用extent_tree的方式,其本质同样是一种间接寻址的关系
  • 那接下来就详细道来

术语简介

  • 磁盘块:块设备对磁盘的一个抽象,对于文件系统而言,磁盘就是一个一个连续的块,每个块通常大小为4KB,并且磁盘块有序编码,每个块对应有一个磁盘块号
  • 文件逻辑块号:从逻辑上讲,一个文件可以看做一系列连续的数据块,每个数据块的大小和磁盘块大小相同;
    • 从物理上讲,一个文件可以对应磁盘上若干个磁盘块,这些磁盘块可以在物理上不连续。
    • 逻辑快号和磁盘块号的对应关系,很像虚拟地址和物理地址的关系:文件给你的感觉就是连续的数据,也就是连续的逻辑块,但实际上文件对应的磁盘块是可以不连续的,也就是不连续的物理块
  • inode:保存文件的元数据,元数据可以描述一个文件
    • 很可惜inode里没有一下子就能想到的filename。关于filename下一节会讲到
    • 一个inode最基本也最重要的信息就两个
      • 用来标识inode的inode号,每个inode都不一样
      • 用来指明这个文件对应着哪些磁盘块的信息——即逻辑块号和磁盘块号的对应关系

从文件名到磁盘块

  • 前面有提到,inode存放文件元数据,但是并没有存放filename——那么ext4是如何把一个filename和一个inode绑定在一起呢?
  • 也就是说存在一个filename和inode号之间的对应关系,而这个关系也是存放在一个文件里——目录文件。如根目录/就是一个文件,这个文件也对应一个inode,文件的数据就是根目录下的文件名和对应的inode号

简略的过程

  • 基于文件系统,我们看到的就是一个个文件,比如我现在有一个文件/home/niugen/testfile
$ pwd
/home/niugen
$ echo 'This is a test file for learning ext4' > testfile
$ cat testfile
This is a test file for learning ext4
  1. 当我们输入cat testfile时,cat命令接收到testfile参数,进而根据当前工作目录计算出这个文件的绝对路径为/home/niugen/testfile
  2. 解析这个路径,首先是/即根目录,根目录这个文件对应的inode号固定为2,所以可以直接找到根目录的inode
  3. 根据根目录的inode中存放的磁盘块号信息,可以知道数据存放在哪些磁盘块中,于是从这些磁盘块里读出数据
  4. 目录文件的数据,简单的看来就是一个表,有两列,一列是文件名,一列是对应的inode号。对于根目录,文件名就是常见的dev、usr、home等等,于是找到了home对应的inode号
  5. 于是读出了/home这个文件的inode,发现这也是一个目录文件,继续读出数据,找到niugen对应的inode号
  6. 于是读出了/home/niugen这个文件的inode,发现这还是一个目录文件,继续读出数据,找到testfile对应的inode号
  7. 于是读出了/home/niugen/testfile这个文件的inode,发现这是一个普通文件,可以使用cat命令,于是读出数据并打印在屏幕上

实际的过程

  • 以上过程也就是核心部分了
  • 关于根目录的inode号——Why is root directory always stored in inode two?
  • 实际中不可能对于每个路径都要读取路径上所有的目录文件来层层深入最终找到目标文件,故在内存中会有目录文件的缓存,称为DEntry。这个数据结构是内存数据结构,用来存放一个文件路径(如/home)和其对应的数据信息(文件名和inode号的表)。
  • Linux对文件系统有一个统一的抽象模型,即VFS,主要有四种数据结构:
    • 超级快对象 Superblock:文件系统信息
    • 索引节点对象 Inode:文件元数据
    • 目录项对象 DEntry:提供目录缓存
    • 文件对象 File:进程视角,用来描述打开的文件
  • VFS的这四种数据结构都是内存数据结构
    • 对于具体的文件系统比如Ext4,在挂载的时候根据其磁盘布局来构造出这四种数据结构
    • 应用程序(如cat命令)均基于VFS提供的文件操作接口进行编程,每种具体的文件系统的实现,如ext4、fat32、ntfs等,需要对其特有的磁盘数据结构进行封装来实现VFS的这四种数据结构
  • VFS不是本文重点,本文重点是探索EXT4文件系统的磁盘数据结构的实现

inode结构体

  • 数据类型介绍
    • __le16 字节小端序的2字节大小
    • __le32 字节小端序的4字节大小

Ext2中的inode

  • 首先介绍一下ext2中的inode结构体:ext2_inode
    • 最重要的字段:i_block[EXT2_N_BLOCKS],存放磁盘块号
    • ext2_inode的大小为128字节,一个4KB的块可以存放32个inode
struct ext2_inode{
	__le16 i_mode;  //文件类型和访问权限
	__le16 i_uid;   //拥有者id
	__le32 i_size;  //文件大小,单位byte
	__le32 i_atime,i_ctime,i_mtime,i_dtime; //时间相关信息
	__le16 i_gid;  //用户组id
	__le16 i_links_count; //硬链接计数器
	__le32 i_blocks; //文件数据块数
	__le32 i_flags;  //标志
	union osd1;      //操作系统相关信息
	
	__le32 i_block[EXT2_N_BLOCKS]; //指向数据块的指针,即磁盘块号
	
	__le32 i_generation;  //文件版本,用于网络文件系统
	__le32 i_file_acl;    //文件访问控制列表
	__le32 i_dir_acl;     //目录访问控制列表
	__le32 i_faddr;       //片地址(不懂)
	union osd2;           //操作系统相关信息
}
  • i_block字段是一个有EXT2_N_BLOCKS个元素的数组,若EXT2_N_BLOCKS的默认值为15
    • [0,11]为直接寻址,即i_block[0,11]直接存放磁盘块号
    • [12,13,14]均为简介寻址,[12]指向一个存放磁盘块号的块,[13]为二级指针,[14]为三级指针
    • 若一个block的大小为4KB,直接寻址的范围为48KB,即只使用[0,11];若加上一次间接的[12],则为4.04MB;再加上二次间接的[13]则为4GB;再加上三次间接的[13]则约为4TB

Ext4中的inode

  • ext4中就出现了extent,ext4_inode 定义于/fs/ext4/ext4.h,ext4_inode的大小为256字节,一个4KB的块可以保存16个inode
    • 字段i_block[EXT4_N_BLOCKS]
/*
 * Constants relative to the data blocks
 */
#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)

/*
 * Structure of an inode on the disk
 */
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 */
	union {
		struct {
			__le32  l_i_version;
		} linux1;
		struct {
			__u32  h_i_translator;
		} hurd1;
		struct {
			__u32  m_i_reserved1;
		} masix1;
	} osd1;				/* OS dependent 1 */
	__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;
	__le32	i_obso_faddr;	/* Obsoleted fragment address */
	union {
		struct {
			__le16	l_i_blocks_high; /* were l_i_reserved1 */
			__le16	l_i_file_acl_high;
			__le16	l_i_uid_high;	/* these 2 fields */
			__le16	l_i_gid_high;	/* were reserved2[0] */
			__u32	l_i_reserved2;
		} linux2;
		struct {
			__le16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
			__u16	h_i_mode_high;
			__u16	h_i_uid_high;
			__u16	h_i_gid_high;
			__u32	h_i_author;
		} hurd2;
		struct {
			__le16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
			__le16	m_i_file_acl_high;
			__u32	m_i_reserved2[2];
		} masix2;
	} osd2;				/* OS dependent 2 */
	__le16	i_extra_isize;
	__le16	i_pad1;
	__le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
	__le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
	__le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
	__le32  i_crtime;       /* File Creation time */
	__le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
	__le32  i_version_hi;	/* high 32 bits for 64-bit version */
};
  • 可见字段i_block的大小为60个字节,即__le32 i_block[EXT4_N_BLOCKS]且EXT4_N_BLOCKS=15
    • 前12个字节为extent头,为extent的基本信息
    • 后48个字节可以保存4个extent节点,每个extent节点为12字节大小
      • extent以树的形式组织,叶节点和非页节点的大小均12字节
      • 叶节点即直接保存了文件逻辑块号、起始磁盘块号、块数
      • 非叶节点同样具有文件逻辑块号,后面内容指向了一个磁盘块号,有两个字节未使用
  • extent相关结构体定义于/fs/ext4/ext4_extents.h

/*
 * Each block (leaves and indexes), even inode-stored has 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;
};

磁盘布局

  • 这里简单的认识一下ext2的磁盘布局,ext4在ext2之上发展起来,基本概念相通

概念

  • 引导块:磁盘的第一个块,ext2对其不管理,其余的块以块组的形式管理
  • 磁盘布局如下
引导块块组0…块组n
第1个块m个块…m个块
  • 每个块组有如下内容

    • 超级块:1个块
    • 组描述符:n个块
    • 数据块bitmap:1个块
    • 索引节点bitmap:1个块
    • 索引节点表:n个块
    • 数据块:n个块
  • 其中超级块和组描述符,对于所有块组均相同,且总是缓存在内存中

  • 其余则用于描述本块组管理的inode块和数据块

Ext4中的磁盘数据结构

  • 超级块superblock实在太大,不值得搬上来,源码见此ext4_sb.h
  • 组描述符ext4_group_desc如下

/*
 * Structure of a blocks group descriptor
 */
struct ext4_group_desc
{
	__le32	bg_block_bitmap_lo;	/* Blocks bitmap block */
	__le32	bg_inode_bitmap_lo;	/* Inodes bitmap block */
	__le32	bg_inode_table_lo;	/* Inodes table block */
	__le16	bg_free_blocks_count;	/* Free blocks count */
	__le16	bg_free_inodes_count;	/* Free inodes count */
	__le16	bg_used_dirs_count;	/* Directories count */
	__le16	bg_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
	__u32	bg_reserved[2];		/* Likely block/inode bitmap checksum */
	__le16  bg_itable_unused;	/* Unused inodes count */
	__le16  bg_checksum;		/* crc16(sb_uuid+group+desc) */
	__le32	bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
	__le32	bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
	__le32	bg_inode_table_hi;	/* Inodes table block MSB */
	__le16	bg_free_blocks_count_hi;/* Free blocks count MSB */
	__le16	bg_free_inodes_count_hi;/* Free inodes count MSB */
	__le16	bg_used_dirs_count_hi;	/* Directories count MSB */
	__le16	bg_itable_unused_hi;	/* Unused inodes count MSB */
	__u32	bg_reserved2[3];
};

寻找一个文件

  • 那么接下来让我们从磁盘上寻找一个文件的内容,还记得文章开头部分新建的一个文件么,即testfile
$ pwd
/home/niugen
$ echo 'This is a test file for learning ext4' > testfile
$ cat testfile
This is a test file for learning ext4

找到文件的inode号

  • cat命令可以打印一个普通文件的内容,那么对于目录文件就是常见的ls命令,使用ls -i可以打印出相应的inode号
$ ls -i testfile
2629310 testfile

根据inode号打印出inode内容

  • 首先确认一下这个文件所在的设备
    • df命令列出挂载的设备,可知/home对应设备/dev/sda3
$ df
文件系统           1K-块     已用      可用 已用% 挂载点
udev             4010336        0   4010336    0% /dev
tmpfs             805968    17880    788088    3% /run
/dev/sda2      192115292 54064596 128268680   30% /
tmpfs            4029832    23168   4006664    1% /dev/shm
tmpfs               5120        4      5116    1% /run/lock
tmpfs            4029832        0   4029832    0% /sys/fs/cgroup
/dev/sda3       44049544  6435924  35352936   16% /home
tmpfs             805968       12    805956    1% /run/user/126
tmpfs             805968       64    805904    1% /run/user/1000
$ pwd
/home/niugen
$ ls -li testfile
2629310 -rw-rw-r-- 1 niugen niugen 38 6月  26 21:13 testfile

  • istat命令可以打印出某个设备上的某个inode信息
    • Group:320表示这个inode存在于块组320上
    • size:38表示文件的大小为38个字节
    • Direct Blocks:10622354则是这个命令根据i_block解析出来的磁盘快号
      • 那么我们不直接使用这个块号,我们自己来算一算它,这就需要直接查看inode所在的磁盘数据块才能看到完整的信息
$ sudo istat /dev/sda3 2629310 
inode: 2629310
Allocated
Group: 320
Generation Id: 2014416585
uid / gid: 1000 / 1000
mode: rrw-rw-r--
Flags: Extents, 
size: 38
num of links: 1

Inode Times:
Accessed:       2017-06-26 21:13:12.184134514 (CST)
File Modified:  2017-06-26 21:13:10.628122013 (CST)
Inode Modified: 2017-06-26 21:13:10.628122013 (CST)
File Created:   2017-06-26 10:18:07.690160310 (CST)

Direct Blocks:
10622354 

查找inode所在的磁盘块

  • 根据前一步可知这个inode位于块组320中,inode号为2629310

  • fsstat列出文件系统的信息,找到320块组的信息

    • 该块组管理的inode的inode号范围为2621441 - 2629632,可知包含了2629310这个inode
    • 该块组的inode所在的块的块号范围为10485792 - 10486303
$ sudo fsstat /dev/sda3 > dev.sda3.fsstat
$ cat dev.sda3.fsstat | grep "Group: 320" -n
4560:Group: 320:
$ cat dev.sda3.fsstat | head -n 4572 | tail -n 13
Group: 320:
  Block Group Flags: [INODE_ZEROED] 
  Inode Range: 2621441 - 2629632
  Block Range: 10485760 - 10518527
  Layout:
    Data bitmap: 10485760 - 10485760
    Inode bitmap: 10485776 - 10485776
    Inode Table: 10485792 - 10486303
    Data Blocks: 10493984 - 10518527
  Free Inodes: 8 (0%)
  Free Blocks: 23488 (71%)
  Total Directories: 534
  Stored Checksum: 0x03D2
  • 那么我们可以来算一下:一个inode大小256B,一个块4KB
    • 一个块可以容纳4KB/256B=16个inode
    • inode号范围起始为2621441,2629310号inode为第2629310-2621441=7869个inode(从0计数)
    • 7869/16=491余13,即这个inode位于该块组用来存放inode的磁盘块的第491个磁盘块(从0计数),且位于该块的16个inode中的第13+1个(从1计数)
    • inode所在块的起始块号为10485792,所以该inode位于块号为10485792+491=10486283的磁盘块

读取磁盘块内容分析inode

  • blkcat命令读出一个磁盘块的内容
$ sudo blkcat /dev/sda3 10486283 > dev.sda3.blk.10486283
  • 使用十六进制编辑器hexedit查看内容数据,其中该inode是这个块的第14个inode

这里写图片描述

  • 根据ext4_inode结构体的定义,以及小端字节序
    • 字节4-7为文件大小: 0x00000026=38
    • 字节40-51为extent头信息
      • 字节40-41为魔数:0xF30A
      • 字节42-43为extent数量:0x0001=1
      • 字节44-45为extent最大数量:0x0004=4
    • 字节52-63为第一个extent,也是唯一一个extent
      • 字节52-55为该extent对应的第一个文件逻辑块号:0x00000000=0
      • 字节56-57为该extent对应的块数量:0x0001=1
      • 字节78-59为磁盘块号的高16位:0x0000
      • 字节60-63为磁盘快号的低32位:0x00A21592
      • 故该extent对应的磁盘块号为0x000000A21592=10622354,和之前istat告诉我们的Direct Blocks一样~~~

读取文件数据所在的磁盘块

  • 终于找到头了(虽然istat的Direct Blocks已经告诉我们了)
$ sudo blkcat /dev/sda3 10622354                                                    
This is a test file for learning ext4

拓展

  • 有兴趣的可以再研究一下extent_tree,即使用extent如何实现间接的寻址
  • 其实有了结构体的定义已经很清楚了

参考内容

深入理解ext4(一)----extent区段 文件系统是操作系统的一个重要组成部分,也有着举足轻重的地位。本系列文章主要讲述了linux ext4文件系统的一些实现原理。笔者参考了2.6.32.60的内核源代码。在写这篇的文章时,最新的内核已经去到了3.7.9。 ext4是替代ext2/3的Linux文件系统。从2.6.28版本开始,被正式认定进入稳定(stable)。本文主要介绍ext4文件系统在硬盘层面上的存储结构及原理。   读者 阅读详情

相关推荐

深入Linux Ext4文件系统:格式化、inode与底层结构详解

文件系统是操作系统管理存储设备数据读写的基础设施,掌握其核心概念有助于安全地进行磁盘格式化与分区挂载。Linux下的经典ext系列(ext2、ext3、ext4)通过超级块、块组和inode结构建立底层管理规则,其中格式化实质上是为磁盘区域创建一套完整的索引与分配逻辑。日志机制的出现大幅提升了断电后的数据恢复能力,而inode与块组结构则决定了空间利用率和文件访问效率。同时对比xfs、btrfs等主流文件系统的设计取向,并结合实际运维场景,介绍分区规划、inode耗尽识别、异常恢复等日常实践,让读者在面对L

weixin_30768881的博客 183

ext4 extent详解1之示意图演示

ext4 extent用示意图演示

dongzhiyan_hjp 5093

Linux内核--文件系统(三)文件系统原理架构介绍

本节将正式开始分析Linux的文件系统。Linux一切皆文件的思想可谓众所周知,而其文件系统又是字符设备、块设备、管道、进程间通信、网络等等的必备知识,因此其重要性可想而知。本文将先介绍文件系统基础知识,然后介绍最重要的结构体inode以及构建于其上的一层层的文件系统。

文艺小少年的博客 425

Linux.ext4文件系统 .inode和extent

最近在看相关内容,不过总是不是很系统,今日看到此博客,感觉恍然大悟,作者写的非常棒:转载: https://blog.csdn.net/stringNewName/article/details/73740155 为表示对作者的尊敬,一字不动的敲击! 最近在看ext4系统的extent相关内容 对于文件系统,每个文件会对应一系列磁盘块,通过在inode中有序的存放磁盘块号,也就保存下了&lt;...

qq_22613757的博客 1412

告别手动标注!用ENVI Classic高效搞定高光谱图像语义分割标签(以农业/地物分类为例)

本文详细介绍了如何利用ENVI Classic实现高光谱图像的半自动化智能标注,特别针对农业和地物分类场景。通过光谱特征分析、智能标注技巧和MAT文件转换,显著提升标注效率和质量,助力AI模型训练。

weixin_28694169的博客 251

氮化镓GaN电机驱动实战:从器件原理到EPC驱动中心

电机驱动是工业自动化和电动交通的核心,功率器件的选择直接决定系统效率与可靠性。传统硅基IGBT和MOSFET在开关速度、损耗方面存在瓶颈,而氮化镓(GaN)作为宽禁带半导体,凭借高电子迁移率、低栅极电荷和近乎为零的反向恢复电荷,正成为电机驱动领域的热门选择。EPC建立电机驱动中心,提供完整的评估平台,覆盖从低压家电到中压伺服的应用场景。文章从GaN器件原理出发,对比传统硅器件,详解三相BLDC/PMSM驱动系统的搭建、栅极驱动与Layout设计、死区时间设置及参数计算实例,并分享测试中遇到的振铃、EMI等高

weixin_29168675的博客 322

ext4的extent解析

 ext4的extent解析 http://blog.csdn.net/kai_ding/article/details/9958031 概述         前面我们在阐述ext2文件系统实现原理的时候了解到,ext2文件系统采用了直接+多级间接映射的方式来存储逻辑块号到物理块号的映射关系。这种方式不仅实现起来较为复杂,而且在面对大文件的时候效率较为低下,且会浪费很多的间接块以存储映

lieye_leaves的专栏 5125

PCB印刷电路缺陷检测实战:从数据集准备到模型训练全流程解析

本文详细解析了PCB缺陷检测从数据集准备到模型训练的全流程。重点介绍了PKU-Market-PCB数据集的特点与下载方法,并提供了数据格式转换、模型选择(如YOLOv8)与训练配置的实战代码。针对PCB小目标检测的难点,文章给出了数据分析和模型优化的具体策略,帮助读者构建高效的缺陷检测系统。

weixin_29065791的博客 546

存储核心:EXT文件系统

哈喽,我是子牙老师,一个手写过操作系统、编程语言、Java虚拟机、docker、Ubuntu系统,玩透Windows内核、Linux内核…的硬核男人。今天写一篇文章分享下存储核心:EXT文件系统

子牙老师 1045

【Godot】【工程】中文字体与多语言(缺字/体积/打包:一次性配置到位)

本文介绍了Godot游戏开发中的中文字体配置与多语言支持方案。主要内容包括:1)中文字体的全局与局部设置;2)使用子集化技术减小字体体积;3)多语言资源管理及翻译系统实现;4)语言切换机制与控件刷新方法;5)字体回退策略优化显示效果;6)打包优化建议。文章提供了从字体导入到多语言实现的完整解决方案,帮助开发者系统性解决中文显示和多语言支持问题,同时优化资源体积和性能表现。配套案例可供学习参考。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 597

Hermes Agent 对阵 OpenClaw:自我改进的 AI 队友

但在 2026 年 2 月,Nous Research 发布了 Hermes Agent,它带来了不同的愿景:一个不仅能够运行,还能学习的代理。在完成复杂的多步骤任务后,它会分析自己的操作并创建一个可复用的技能。对于已在使用 OpenClaw 的澳大利亚企业而言,这意味着您可以试用 Hermes Agent,而无需丢失数月的配置和自定义成果。最重要的区别在于理念:OpenClaw 是一个需要配置的工具,而 Hermes Agent 则是一个会学习的队友。OpenClaw 的技能是静态的。

xiaoshun007的专栏 1571

深入理解ext4

文件系统是操作系统的一个重要组成部分,也有着举足轻重的地位。本系列文章主要讲述了linux ext4文件系统的一些实现原理。笔者参考了2.6.32.60的内核源代码。在写这篇的文章时,最新的内核已经去到了3.7.9。 ext4是替代ext2/3的Linux文件系统。从2.6.28版本开始,被正式认定进入稳定(stable)。本文主要介绍ext4文件系统在硬盘层面上的存储结构及原理。  

luominghao的专栏 4681

把 ABAP Unit 测试放进本地类:让重构更安全、让测试更好找的组织方式

ABAP测试代码组织策略:单元测试与集成测试的合理存放位置 本文针对ABAP开发中测试代码组织混乱的问题,提出了一套系统化的解决方案: 单元测试应存放在被测类的本地测试include中(...CCAU或...T99),确保测试与代码同步演进且易于发现 跨对象测试(组件/集成/系统测试)应创建单独的全局测试类,并通过FOR TESTING和ABSTRACT进行防护 使用! @testing注释建立测试关系,使测试与被测对象明确关联,提高可发现性 针对不同技术栈(RAP/CAP/OData)提供了具体落地建议,

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1729

ext4数据恢复实战及文件系统结构详解

如果你的数据被不小心误删除了,那么对文件系统结构的深入理解可以帮助你找到数据恢复的途径。我们先从一个数据恢复的例子开始,对ext4的文件系统结构做个介绍。

缘木之鱼 3649

点云焊缝提取

本文介绍了一个基于PCL库的点云处理流程,包含三个核心模块:MLS平滑处理通过多项式拟合修正点云位置;差异提取通过双向匹配定位源/目标点云的非重叠区域;统计过滤剔除离群噪声点。该流程采用"平滑-筛选-净化"的通用思路,将复杂算法封装为可配置接口,实现了工业级点云预处理。文章重点分析了各模块的原理、PCL接口调用及参数设计逻辑,同时指出参数调优、算法扩展等深入探索方向,展现了PCL在点云处理中的模块化优势与实用价值。

weixin_45196569的博客 250

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux内核文件系统10

2021SC@SDUSC inode.c(1) 今天来分析inode.c文件。有了前面对ext4_jbd2.h、acl.h等头文件的分析做基础,今天的分析将相对简单。 在看代码之前,首先要说一下inode数据结构。inode是Linux内核文件系统中最重要的数据结构之一,里面保存了文件的大小、文件块的大小、创建时间等参数,可以说,一个inode就代表了一个文件。因为软连接、硬连接的存在,指向一个文件的路径可能有多个,即一个文件可以有多个dentry,但是一个文件只能有一个inode。 ext

weixin_46243251的博客 995

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ext文件系统机制原理剖析

原文链接:http://www.cnblogs.com/f-ck-need-u/p/7016077.html 将磁盘进行分区,分区是将磁盘按柱面进行物理上的划分。划分好分区后还要进行格式化,然后再挂载才能使用(不考虑其他方法)。格式化分区的过程其实就是创建文件系统。 文件系统的类型有很多种,如CentOS 5和CentOS 6上默认使用的ext2/ext3/ext4,CentOS 7上默认使用...

神恰以泽_优快云 561

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ext4文件系统解析

写文件操作时,除了更新Data区处,还会相应更新GDT、Inode Bitmap、Block Bitmap、目录区、Inode Table区。● 针对小于480MB的文件,GDT、目录区、Inode Bitmap,更新较少。Block Bitmap会不停记录使用了的Block,更新较多,Inode Table会不停记录已经使用了的Block数,也更新较多。● 针对超过480MB的文件,尤其是更大的文件,其会启用extent子节点表。

飞鹤的程序员人生 8805

文件系统系列专题之 Ext2/3/4

一、Ext概述EXT是延伸文件系统(Extended file system,缩写为 ext或 ext1),也译为扩展文件系统,由 Remy Card 设计,并于 1992 年 4 月引入到 Linux 中。采用Unix文件系统(UFS)的元数据结构,以克服MINIX文件系统性能不佳的问题。它是在linux上,第一个利用虚拟文件系统(VFS)实现出的文件系统,在linux核心0.96c版中首次加入支持,最大可支持2GB的文件系统。

存储随笔 4014

学习笔记:EXT4文件系统特性

图:大型文件系统ext4文件系统可支持最高1 Exbibyte的分区与最大16 Tebibyte的文件。 1 EB = 1024 * 1024 TBblock size: 4 bytes向下兼容ext4向下兼容于ext3与ext2,因此可以将ext3和ext2的文件系统挂载为ext4分区。由于某些ext4的新功能可以直接运用在ext3和ext2上,直接挂载即可提升少许性能。ext3文件系统可以部分...

三生锁链 2440

VFS 与 Ext4 的深层逻辑:Linux 文件系统架构剖析与性能调优

Linux 文件系统的核心是 VFS 的统一抽象和具体文件系统的差异化实现。Ext4 通过块组布局、Extent 树和 JBD2 日志,在性能和可靠性之间取得了良好的平衡。落地路线建议:第一步,根据工作负载特征选择文件系统——数据库和通用场景选 Ext4,大文件和高并发写入选 XFS;第二步,优化挂载参数,数据库场景必须启用noatime和barrier,日志场景可适当延长commit间隔;第三步,监控空间和 inode 使用率,inode 耗尽可能比空间耗尽更早发生;第四步,对追加写入的文件使用。

jiang_style的博客 5128

DeepSeek linux-6.19/fs/ext4/ext4.h 源码分析

我来为您详细分析 Linux 内核 6.19 版本中 ext4 文件系统的核心头文件ext4.h。这个文件定义了 ext4 的所有关键数据结构和常量。

m0_37843156的博客 140

【linux文件系统】磁盘结构&文件系统详谈

本文详细介绍了Linux文件系统与磁盘结构,从物理磁盘的扇区、块等基本概念入手,逐步讲解分区表(MBR/GPT)和文件系统布局。重点剖析了ext4文件系统的核心结构,包括超级块、块组描述符、inode等重要组件,以及文件查找流程。文章还对比了主流Linux文件系统特性,完整呈现了从物理磁盘到文件名的数据访问链路。通过深入浅出的技术解析,帮助读者理解Linux存储系统的底层工作原理。

likuoelie的博客 458

Linux Ext文件系统演进与核心结构解析

文件系统是操作系统管理存储设备的核心组件,负责数据的组织、存储和检索。Linux生态中广泛使用的Ext系列文件系统,经历了从Ext1到Ext4的技术演进,逐步解决了碎片化、日志恢复和大文件支持等关键问题。其核心设计采用分层结构,包括超级块、块组描述符和inode等关键组件,通过Extent连续块分配等现代特性显著提升存储效率。在存储技术领域,Ext4凭借其稳定性和成熟度,仍是服务器和嵌入式设备的首选方案。理解其inode索引机制和日志系统原理,对于系统性能调优和故障排查具有重要工程价值。随着XFS和Btrf

weixin_26757925的博客 307
上一篇: 计算机网络.五层协议栈模型简介
下一篇: PCIe是如何工作的——How PCI Express Works
木艮氵
博客等级 码龄11年 136粉丝 51原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值