XFS文件系统

XFS文件系统


超级块:

超级块记录了整个xfs文件系统的一些重要数据,例如磁盘块(通常是以4096字节为单位的)的总数,磁盘块的大小,使用的磁盘块/未使用的磁盘块的个数等。超级块是整个文件系统最重要的部分,如果他的数据不正确,文件系统就无法使用了,所以每个分配组有一个超级块,但使用的只有第一个分配组的超级块,其他的都是备份用的。这样一来,如果超级块被损坏,可以使用其他的分配组的,有些数据可能丢失,但不致于是整个文件系统都不能用。

超级块的磁盘上的结构和linux源代码中的xfs_sb结构体是一模一样的。

typedef struct xfs_sb

{

__uint32_t           sb_magicnum;

4个字节的文件系统标示,翻译成中文暂且叫幻数吧!

对于xfs文件系统,他就是四个字母”XFSB”

__uint32_t           sb_blocksize;

一个磁盘块所占的字节数(通常是4096个字节)

xfs_drfsbno_t      sb_dblocks;

数据块的个数

xfs_drfsbno_t      sb_rblocks;

实时数据块的个数

xfs_drtbno_t        sb_rextents;        

实时区域的个数

uuid_t                  sb_uuid;

文件系统的UUID

xfs_dfsbno_t        sb_logstart;

日志区域的开始块号

xfs_ino_t              sb_rootino;

根节点的索引节点id

xfs_ino_t              sb_rbmino;

 

xfs_ino_t              sb_rsumino;

 

xfs_agblock_t      sb_rextsize;

 

xfs_agblock_t      sb_agblocks;       

一个分配组的块数

xfs_agnumber_t  sb_agcount;

分配组的个数

xfs_extlen_t         sb_rbmblocks;

 

xfs_extlen_t         sb_logblocks;

日志块的个数

__uint16_t           sb_versionnum;

 

__uint16_t           sb_sectsize;

 

__uint16_t           sb_inodesize;

一个索引节点所占的字节数

__uint16_t           sb_inopblock;

一个磁盘块有多少个索引节点

char                     sb_fname[12];

文件系统的名字

__uint8_t             sb_blocklog;

 

__uint8_t             sb_sectlog;

 

__uint8_t             sb_inodelog;

 

__uint8_t             sb_inopblog;

 

__uint8_t             sb_agblklog;

 

__uint8_t             sb_rextslog;

 

__uint8_t             sb_inprogress;

 

__uint8_t             sb_imax_pct;

 

__uint64_t           sb_icount;

已分配的索引节点的个数

__uint64_t           sb_ifree;

剩余的索引节点的个数

__uint64_t           sb_fdblocks;

空闲的数据块个数

__uint64_t           sb_frextents;

 

xfs_ino_t              sb_uquotino;

用于管理用户配额的索引节点的id

xfs_ino_t              sb_gquotino;

用于管理组配额的索引节点的id

__uint16_t           sb_qflags;

 

__uint8_t             sb_flags;

 

__uint8_t             sb_shared_vn;

 

xfs_extlen_t         sb_inoalignmt;

 

__uint32_t           sb_unit;

 

__uint32_t           sb_width;

 

__uint8_t             sb_dirblklog;

 

__uint8_t             sb_logsectlog;

 

__uint16_t           sb_logsectsize;

 

__uint32_t           sb_logsunit;

 

} xfs_sb_t;

 

 

 

文件系统的第一个索引节点----根目录的索引节点id=128,这是至最小的索引节点,它位于第64个块(512字节)的位置。用户配额文件是132,组配额文件是133。对于NECSXFS文件系统:snap文件的索引节点是131dataset文件是135

 

文件系统刚被做成,也就是刚被格式化完时,会预先分配好一部分索引节点。对于每个分配组来说,这些索引节点的组内id128-191。索引节点占256个字节,每两个节点占一个512字节的块。索引这些节点连续分布在第64-96个块之间。虽然索引节点结构体xfs_dinode_core只有128个字节,但一个索引节点却占256个字节的磁盘空间。为什么呢?主要是为了存放数据比较小的节点,比如对于一个目录节点,它下面可能有3个文件,结果这三个文件组成的3entry可以存放在128字节的空间里,这样就不必给这个目录节点分配数据块,而直接将3个文件entry存放在目录节点的256个字节的区域里就可以了。

 

索引节点的id为什么会从128开始呢?

一个分配组是由一系列512字节的块组成的。前63个块都被用来存放系统或分配组的信息了。每2个索引节点占512个字节的块,如果从第0个块开始计算,第64个块恰好是128129所在的位置。这样如果通过id来找一个节点的话,只需将id除以2,就可以找到位置了。例如128/2=64id128的索引节点在第64个块里。另外,如果预先分配的节点用完了,系统会再开辟一段空间来继续分配,但节点号不会从上次的开始,因为节点号跟所在的块的块号有关。比如预先分配的节点是12-191,如果用完了,系统在分配的id不一定是192,这要看第96个块是否被使用,事实上第96个块是quota文件的数据块。如果节点在第200个块上,他的id就是200*2=400

 

XAGF块的结构和源代码中的xfs_agf结构体是一样的。

 

XAGI块的结构和源代码中的xfs_agi结构体是一样的。

 

inode结构

存在于磁盘的inode结构和源代码中的xfs_dinode结构体是一样的。里面含有文件大小,所占块数,父目录节点的id,时间等信息。但没有节点名字的信息,因为名字存在于父目录中。

多余的128字节是怎样处理的?

 

typedef struct xfs_dinode

{

              xfs_dinode_core_t              di_core;

              xfs_agino_t                        di_next_unlinked;/* agi unlinked list ptr */

              union {

                            xfs_bmdr_block_t di_bmbt;             /* btree root block */

                            xfs_bmbt_rec_32_t di_bmx[1];        /* extent list */

                            xfs_dir_shortform_t di_dirsf;           /* shortform directory */

                            xfs_dir2_sf_t        di_dir2sf;             /* shortform directory v2 */

                            char                     di_c[1];  /* local contents */

                            xfs_dev_t             di_dev;                 /* device for S_IFCHR/S_IFBLK */

                            uuid_t                  di_muuid;            /* mount point value */

                            char                     di_symlink[1];     /* local symbolic link */

              }                           di_u;

              union {

                            xfs_bmdr_block_t di_abmbt;           /* btree root block */

                            xfs_bmbt_rec_32_t di_abmx[1];      /* extent list */

                            xfs_attr_shortform_t di_attrsf;        /* shortform attribute list */

              }                           di_a;

} xfs_dinode_t; 


如果子节点太多,多余的128字节已经装不下了,则di_u将是di_bmbt起作用了。

 

 

user quota节点

此节点号为132,位于第66个块,根据di_u域找到第96个块为他的数据块。这个块是由entry组成的,每个entry的头两个字节为”DQ”表示是quota数据。entry的结构和xfs_disk_dquot结构体是一样的。包含quota类型,软硬限制,使用的节点数和块数等。

 

group quota节点

此节点号:133,位于第66个块的后半部,根据di_u域找到第104个块为他的数据块。快的结构也是由entry组成的,和user quota相同。

 

NECdataset节点

dataset节点号:135,位于第67个块后半部分,根据di_u域,找到第112个块为他的数据块。此块也是由entry组成的,他的每个entry头两个字节为”DD”,表示是数据集的块。entry结构和sxfs_dataset_disk结构体一样。

 

endian格式

endian格式存储变量到磁盘时,内存和磁盘上的格式是相反的。

比如 int i =0x12345678; //内存中0x12345678

              i 在磁盘上会是 0x87654321

所以许多xfs_ino_t inode=0x80;在磁盘上却是 0x80 00 00 00

endian格式以类型为单位(int ,long long, short)倒置数据。char型不会倒置,char的单位就是一个字节,不用倒置。char[8]={“abcdef”};在磁盘上还是”abcdef”

你可能感兴趣的:(linux,study)