请教,什么情况导致superblock和inode智能客户端被破坏

&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!Linux 文件系统的 Superblock, Inode, Dentry 和 File_linux教程-织梦者
当前位置:&>&&>& > Linux 文件系统的 Superblock, Inode, Dentry 和 File
Linux 文件系统的 Superblock, Inode, Dentry 和 File
Linux 文件系统的 Superblock, Inode, Dentry 和 File
linux基础知识
133人阅读 评论(0)收藏
目录(?)[+]
参考文档:/2012/12/suerblock-inode-dentry-file-of-filesystem/
/content/12/02.shtml
http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm
http://blog.csdn.net/poechant/article/details/7214926
首先,Superblock, Inode, Dentry 和 File 都属于元数据(Metadata),根据维基百科中的解释,所谓元数据,就是描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件纪录等功能。Linux/Unix 文件系统的元数据以多级结构保存。
1、Inode 和 Block
(1)背景 由于Linux系统是多用户多的,所以文件系统类型多样化是在所难免的。从ext2开始,是将文件属性和文件内容分开存储的,分别由inode和block来负责。
(2)inode 用于存储文件的各属性,包括:
-所有者信息:文件的owner,group;
-权限信息:read、write和excite;
-时间信息:建立或改变时间(ctime)、最后读取时间(atime)、最后修改时间(mtime);
-标志信息:一些flags;
-内容信息:type,size,以及相应的block的位置信息。 注意:不记录文件名或目录名,文件名或目录名记录在文件所在目录对应的block里。
(3)block 用来存储文件的内容。
(4)创建目录或文件 当创建一个目录时,文件系统会为该目录分配一个inode和至少一个block。该inode记录该目录的属性,并指向那块block。该block记录该目录下相关联的文件或目录的关联性和名字。 当创建一个文件时,文件系统会为该文件分配至少一个inode和与该文件大小相对应的数量的block。该inode记录该文件的属性,并指向block。 如果一个目录中的文件数太多,以至于1个block容纳不下这么多文件时,Linux的文件系统会为该目录分配更多的block。 (各block之间形成链表?)
(5)读取目录或文件 当我们告知操作系统一个文件的路径后,操作系统是如何找到这个文件的呢?首先操作系统会调用文件系统的相应接口,接下来: 递归说法:当读取一个文件或目录X时,提供给文件系统的是一个路径P。文件系统会先读取X所在的目录D的inode_d(注意这里,其实是这一操作的递归过程),通过inode_d获得其对应的block_d,在block_d中通过已知的X的名称,查询到X的inode_x。 迭代说法;如果读取的是/x1/x2/x3/x4/x5这个文件,则先读取根目录的inode_root,然后找到inode_root对应的block_root,在block_root中根据x1这个名字找到x1对应的inode_x1,然后找到inode_x1对应的block_x1,在block_x1中根据x2这个名字找到inode_x2,再找到block_x2,然后根据x3找到inode_x3,再block_x3,根据x4找到inode_x4,再block_x4,再根据x5找到inode_x5,再block_x5,就读取到我们要的x5的内容了。
2、分区(1)分区结构 分区(partition)在被Linux的文件系统(比如ext2)格式化的时候,会分成inode table和block table两部分,且大小都是固定的。该分区的所有inode都在inode table里,所有block都在block table里。
(2)块大小
ext2允许的block size为1024bytes、2048bytes和4096bytes。
(3)inode大小
ext2一般默认给inode预设的大小为128bytes。
(4)预设分区 一个T bytes的分区,设定每个block为B bytes,每个inode为I bytes。如果假设平均每个文件占用两个block的话,那么inode的数量就应该设定为T/(2B+I)个,即inode table为T*I/(2B+I) bytes,block table为T*B/(2B+I) bytes。所以一个分区的文件系统所能容纳的文件数量,被限制于该分区的文件系统的inode area中的inode数。 如果一个分区大小为1GB,每个block为4KB,一个inode为128B,并假设平均每个文件占用2个block。那么inode的数量为1GB/(8KB+128B)=,即129055。那么inode table的大小为B=15.75MB。所以按照这样的规划,如果一个1GB的磁盘,那么格式化后,就已经有15.75MB被使用了。 大文件应用场景:block设置的小一些,inode设置的多一些。比如新闻组、BBS等。 小文件应用场景:block设置的大一些,inode设置的少一些。比如图片分享网站。
3、查看本机的文件系统信息 使用dumpe2fs命令可以查看分区的文件系统的相关信息。比如我在我的一台测试机上查看sda1,可以输入:dumpe2fs /dev/sda1
会得到如下内容,一些信息已经标注在注释里了。
(1)文件系统基本信息
#该分区的文件系统的名称Filesystem volumn name: MAIN
#上次的挂载点Last mounted on:&not available&
#文件系统的通用唯一标识符Filesystem UUID:&none&
#文件系统的Filesystem magic number:0xEF53
#修订版本号Filesystem revision #:1 (dynamic)
Filesystem features:has_journal needs_recoveryFilesystem flags:signed_directory_hashDefault mount options:(none)
#文件系统状态Filesystem state:clean
#发生错误后的行为Errors behavior: Continue
#操作系统Filesystem OS type: Linux
(2)结构信息
#Inode总数Inode count: 1313312
#Block总数Block count: 1313305
#保留block数Reserved block count: 65665
#空闲block数Free blocks: 979164
#空闲inode数Free inodes: 1298415
#第一个block的编号First block: 0
#block的大小Block size: 4096
#fragment的大小Fragment size:4096
#每个group的block数是32K个Blocks per group: 32768
#每个group的fragment数是32K个Fragments per group: 32768
#每个group的inode数Inodes per group:32032
#每个group的inode blocksInode blocks per group: 1001
(3)访问信息
#上次挂载时间Last mount time: Wed Jan 25 00:32:14 2012
#上次写时间Last write time: Wed Jan 24 00:32:14 2012
#挂载数Mount count:11
#最大挂在数Maximum mount count:20
#上次检查文件系统时间Last checked:Sat Oct 31 22:52:33 2009
#检查文件系统时间间隔Check intervalle:
#下一次检查文件系统的时间Next check after: Thu Apr 29 22:52:33 2010
#对保留块有权限的用户IDReserved blocks uid:0 (user root)
#对保留快有权限的组IDReserved blocks gid:0 (group root)
#第一个inodeFirst inode: 11
#每个inode大小Inode size:128
#日志inodeJournal inode: 8
#日志大小为32MJournal size: 32M
(4)group信息Group 0: (Blocks 0-32767) Primary superblock at 0,Group descriptorsat 1-1Block bitmapat 2 (+2),Inode bitmapat 3 (+3) Inode table at 4-1004 (+4) 0 free blocks, 32019 free inodes, 2 directoriesFree blocks:Free inodes: 14-32032Group 1: (Blocks )Backup superblockat 32768,Group descriptorsat Block bitmapat 32770 (+2),Inode bitmapat 32771 (+3) Inode table at
(+4) 3 free blocks, 32032 free inodes, 0 directoriesFree blocks: Free inodes: Group 2: (Blocks )Backup superblockat 65536,Group descriptorsat Block bitmapat 65538 (+2),Inode bitmapat 65539 (+3) Inode table at
(+4) 3 free blocks, 32032 free inodes, 0 directoriesFree blocks: Free inodes: Group 3: (Blocks )Backup superblockat 98304,Group descriptorsat Block bitmapat 98306 (+2),Inode bitmapat 98307 (+3) Inode table at
(+4) 3 free blocks, 32031 free inodes, 0 directoriesFree blocks: Free inodes: Group 4: (Blocks 839)Backup superblockat 131072,Group descriptorsat 073Block bitmapat 131074 (+2),Inode bitmapat 131075 (+3) Inode table at 076 (+4) 0 free blocks, 32032 free inodes, 0 directoriesFree blocks:Free inodes: 160...Group 40: (Blocks 3304)Backup superblock at1310720,Group descriptorsat 0721Block bitmapat 1310722 (+2),Inode bitmapat 1310723 (+3) Inode table at 1724 (+4) 1580 free blocks, 32032 free inodes, 0 directoriesFree blocks: 3304Free inodes: 3312
可见,各Group对应的blocks(注意每个block的大小是4096bytes)
- Group 00:
0(0x000000) -
0K = 0 * 32K
- Group 01:
32K = 1 * 32K
- Group 02:
64K = 2 * 32K
- Group 03:
000) - x01FFFF):
96K = 3 * 32K
- Group 04: x020000) - x027FFF): 128K = 4 * 32K
- Group 40: x140000) - x147FFF): 1280K = 40 * 32K
这40个group一共的大小,是40*32K*4KB = 5GB
4、文件系统结构结合上面命令的输出结果,一个分区一般含有多个block group,比如上面看到的40个。而每个block group都有superblock、group description、block bitmap、inode bitmap、inode table、data blocks,比如上面的Backup Superblock占用1个block(4KB)、Group descriptors占用1个block(4KB)、Block bitmap占用1个block(1KB)、Inode bitmap占用1个block(1KB)、Inode table占用1001个block(512.5KB)。Superblock记录整个partition的block和inode的总量,已使用和未使用的inode和block的数量,1个block和1个inode的大小,filesystem的挂载时间/最后写入时间/最后检查时间、标示该文件系统是否被挂载的valid bit(0标示未挂载,1标示已挂载)。是MBR中的Superblock的backup。
Group descriptors描述由何处开始记录数据,是MBR中的Group descriptors的backup。Block bitmap记录哪个block是空闲的。
Inode bitmap记录哪个inode是空闲的。
Inode table存放inode数据。
Data blocks存放block数据。2、Superblock
1、首先了解下block,对于ext2(ext3)文件系统而言,硬盘分区首先被划分为一个个的block,同一个ext2文件系统上的每个block大小都是一样的。但是对于不同的ext2文件系统,block的大小可以有区别。典型的block大小是1024 bytes或者4096 bytes。这个大小在创建ext2、ext3文件系统的时候被决定,mkfs –t ext2/3 –b xx就可以设定块大小了!一个硬盘分区上的block计数是从0开始的,总的来说,block这个概念好理解。2、理解了block的概念后,接着就是对block group的理解,硬盘分区上所有的block被聚在一起分成几个大的block group。其中每个block group中有多少个block是固定的。从上面的图可以看出来!每个block group都相对应一个group descriptor,每个group descriptor当中有几个重要的block指针,指向block group中的inode table、block bitmap和inode bitmap。以上三个结构记载了其所属block group的许多信息。3、下面就是对super block的理解了Super block即为超级块,它是硬盘分区开头——开头的第一个byte是byte 0,从byte 1024开始往后的一部分数据。由于block size最小是1024 bytes,所以super block可能是在block 1中(此时block的大小正好是1024 bytes)超级块中的数据其实就是文件卷的控制信息部分,也可以说它是卷资源表,有关文件卷的大部分信息都保存在这里。例如:硬盘分区中每个block的大小、硬盘分区上一共有多少个block group、以及每个block group中有多少个inode。对于super block的结构和涵义可以通过查看/usr/include/linux/ext3_fs.h文件:Superblock 是文件系统最基本的元数据,它定义了文件系统的类似、大小、状态,和其他元数据结构的信息(元数据的元数据)。Superblock 对于文件系统来说是非常关键的,因此对于每个文件系统它都冗余存储了多份。Superblock对于文件系统来说是一个非常“高等级”的元数据结构。例如,如果 /var 分区的 Superblock 损坏了,那么 /var 分区将无法挂载。在这时候,一般会执行 fsck 来自动选择一份 Superblock 备份来替换损坏的 Superblock,并尝试修复文件系统。主 Superblock 存储在分区的 block 0 或者 block 1 中,而 Superblock 的备份则分散存储在文件系统的多组 block 中。当需要手工恢复时,我们可以使用dumpe2fs/dev/sda1|grep-i superblock来查看 sda1 分区的 superblock 备份有哪一份是可用的。我们假设 dumpe2fs 输出了这样一行:Backup superblock at 163840, Group descriptors at 841,通过这条信息,我们就可以尝试使用这个 superblock 备份:/sbin/fsck.ext3-b24/dev/sda1。请注意,这里我们假设 block 的大小为 1024 字节。通过set number:386 struct ext3_super_block {386 struct ext3_super_block {387 /*00*/__le32s_inodes_
/* Inodes count */388
__le32s_blocks_
/* Blocks count */389
__le32s_r_blocks_
/* Reserved blocks count */390
__le32s_free_blocks_
/* Free blocks count */391 /*10*/__le32s_free_inodes_
/* Free inodes count */392
__le32s_first_data_ /* First Data Block */393
__le32s_log_block_
/* Block size */394
__le32s_log_frag_
/* Fragment size */395 /*20*/__le32s_blocks_per_ /* # Blocks per group */396
__le32s_frags_per_
/* # Fragments per group */397
__le32s_inodes_per_ /* # Inodes per group */398
/* Mount time */399 /*30*/__le32s_
/* Write time */400
__le16s_mnt_
/* Mount count */401
__le16s_max_mnt_
/* Maximal mount count */402
/* Magic signature */403
/* File system state */404
/* Behaviour when detecting errors */405
__le16s_minor_rev_
/* minor revision level */406 /*40*/__le32s_
/* time of last check */407
/* max. time between checks */408
__le32s_creator_
/* OS */409
__le32s_rev_
/* Revision level */410 /*50*/__le16s_def_
/* Default uid for reserved blocks */411
__le16s_def_
/* Default gid for reserved blocks */super block的几个重要成员1、Magic 签名  对于ext2和ext3文件系统来说,这个字段的值应该正好等于0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的ext2或ext3文件系统。2、s_log_block_size   从这个字段,我们可以得出真正的block的大小。我们把真正block的大小记作B,B=1 && s_log_block_size + 10),单位是bytes。举例来说,如果这个字段是0,那么block的大小就是 1024bytes,这正好就是最小的block大小;如果这个字段是2,那么block大小就是4096 bytes。从这里我们就得到了block的大小这一非常重要的数据。3、s_blocks_count和s_blocks_per_group  通过这两个成员,我们可以得到硬盘分区上一共有多少个block group,或者说一共有多少个group descriptors  s_blocks_count记录了硬盘分区上的block的总数,而 s_blocks_per_group记录了每个group中有多少个block。显然,文件系统上的block groups数量,我们把它记作G,G=(s_blocks_count-s_first_data_block- 1)/s_blocks_per_group+1。为什么要减去s_first_data_block,因为s_blocks_count是硬盘分区上全 部的block的数量,而在s_first_data_block之前的block是不归block group管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些block,这些block我们要把它划在一个相对较小的group 里面。4、s_inodes_per_group  s_inodes_per_group记载了每个block group中有多少个inode。在从已知的inode号,读取这个inode数据的过程中,s_inodes_per_group起到了至关重要的作用。  用我们得到的inode号数除以s_inodes_per_group,我们就知道了我们要的 这个inode是在哪一个block group里面,这个除法的余数也告诉我们,我们要的这个inode是这个block group里面的第几个inode;然后,我们可以先找到这个block group的group descriptor,从这个descriptor,我们找到这个group的inode table,再从inode table找到我们要的第几个 inode,再以后,我们就可以开始读取inode中的用户数据了。这个公式是这样的:  block_group = (ino - 1) / s_inodes_per_group。这里ino就是我们的inode号数  offset = (ino - 1) % s_inodes_per_group,这个offset就指出了我们要的inode是这个block group里面的第几个inode。猜你在找Linux文件系统中的inode索引结点 VFS inodelinux文件系统—inode及相关概念 inode大小的最佳设置Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解Linux操作系统文件系统基础知识详解以上就是Linux 文件系统的 Superblock, Inode, Dentry 和 File的全文介绍,希望对您学习和使用Linux有所帮助.
这些内容可能对你也有帮助
更多可查看linux教程列表页。
猜您也会喜欢这些文章博客访问: 66422
博文数量: 78
博客积分: 2850
博客等级: 少校
技术积分: 880
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
需要注意的几点如下所示:1)进程每打开一个文件,就会有一个file结构与之对应。同一个进程可以多次打开同一个文件而得到多个不同的file结构,file结构描述被打开文件的属性,如文件的当前偏移量等信息。2)两个不同的file结构可以对应同一个dentry结构。进程多次打开同一个文件时,对应的只有一个dentry结构。Dentry结构存储目录项和对应文件(inode)的信息。3)在存储介质中,每个文件对应唯一的inode结点,但是每个文件又可以有多个文件名。即可以通过不同的文件名访问同一个文件。这里多个文件名对应一个文件的关系在数据结构中表示就是dentry和inode的关系。4)Inode中不存储文件的名字,它只存储节点号;而dentry则保存有名字和与其对应的节点号,所以就可以通过不同的dentry访问同一个inode。5)不同的dentry则是同个文件链接(ln命令)来实现的。dentry
  一、dentry的定义
  dentry的中文名称是目录项,是Linux文件系统中某个索引节点(inode)的链接。这个索引节点可以是文件,也可以是目录。
  二、dentry的结构:以下是dentry的结构体
  struct dentry {
  atomic_t d_ 目录项对象使用计数器
  unsigned int d_ 目录项标志
  struct inode * d_ 与文件名关联的索引节点
  struct dentry * d_ 父目录的目录项对象
  struct list_head d_ 散列表表项的指针
  struct list_head d_ 未使用链表的指针
  struct list_head d_ 父目录中目录项对象的链表的指针
  struct list_head d_对目录而言,表示子目录目录项对象的链表
  struct list_head d_ 相关索引节点(别名)的链表
  int d_ 对于安装点而言,表示被安装文件系统根项
  struct qstr d_ 文件名
  unsigned long d_ /* used by d_revalidate */
  struct dentry_operations *d_ 目录项方法
  struct super_block * d_ 文件的超级块对象
  vunsigned long d_vfs_
  void * d_与文件系统相关的数据
  unsigned char d_iname [DNAME_INLINE_LEN]; 存放短文件名
  三、dentry与inode
  inode(可理解为ext2 inode)对应于物理磁盘上的具体对象,dentry是一个内存实体,其中的d_inode成员指向对应的inode。也就是说,一个inode可以在运行的时候链接多个dentry,而d_count记录了这个链接的数量。
  按照d_count的值,dentry分为以下三种状态:
  1、未使用(unused)状态:该dentry对象的引用计数d_count的值为0,但其d_inode指针仍然指向相关的的索引节点。该目录项仍然包含有效的信息,只是当前没有人引用他。这种dentry对象在回收内存时可能会被释放。
  2、正在使用(inuse)状态:处于该状态下的dentry对象的引用计数d_count大于0,且其d_inode指向相关的inode对象。这种dentry对象不能被释放。
  3、负(negative)状态:与目录项相关的inode对象不复存在(相应的磁盘索引节点
可能已经被删除),dentry对象的d_inode指针为NULL。但这种dentry对象仍然保存在dcache中,以便后续对同一文件名的查找能够
快速完成。这种dentry对象在回收内存时将首先被释放。
  四、dentry与dentry_cache
  dentry_cache简称dcache,中文名称是目录项高速缓存,是Linux为了提高目录项对象的处理效率而设计的。它主要由两个数据结构组成:
  1、哈希链表dentry_hashtable:dcache中的所有dentry对象都通过d_hash指针域链到相应的dentry哈希链表中。
  2、未使用的dentry对象链表dentry_unused:dcache中所有处于unused状态和negative状态的dentry对象都通过其d_lru指针域链入dentry_unused链表中。该链表也称为LRU链表。
  目录项高速缓存dcache是索引节点缓存icache的主控器(master),也即
dcache中的dentry对象控制着icache中的inode对象的生命期转换。无论何时,只要一个目录项对象存在于dcache中(非
negative状态),则相应的inode就将总是存在,因为
inode的引用计数i_count总是大于0。当dcache中的一个dentry被释放时,针对相应inode对象的iput()方法就会被调用。
  五、dentry_operations *d_op
  struct dentry_operations {
  int (*d_revalidate)(struct dentry *);
  int (*d_hash) (struct dentry *, struct qstr *);
  int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
  void (*d_delete)(struct dentry *);
  void (*d_release)(struct dentry *);
  void (*d_iput)(struct dentry *, struct inode *);
  d_revalidate:用于VFS使一个dentry重新生效。
  d_hash:用于VFS向哈希表中加入一个dentry。
  d_compare:dentry的最后一个inode被释放时(d_count等于零),此方法被调用,因为这意味这没有inode再使用此dentry;当然,此dentry仍然有效,并且仍然在dcache中。
  d_release: 用于清除一个dentry。
  d_iput:用于一个dentry释放它的inode(d_count不等于零)
  六、d_parent和d_child
  每个dentry都有一个指向其父目录的指针(d_parent),一个子dentry的哈希列表(d_child)。其中,子dentry基本上就是目录中的文件。
  七、怎样从inode值得到目录名?
  函数得到当前文件或目录的inode值后,进入dcache查找对应的dentry,然后顺着父目录指针d_parent得到父目录的dentry,这样逐级向上直到dentry= root,就得到全部目录名称。 
阅读(771) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。博客访问: 356065
博文数量: 56
博客积分: 773
博客等级: 军士长
技术积分: 2268
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
&&&&&&&&&& Linux下的文件系统中宏观上主要分为三层:一是上层的文件系统的系统调用;二是虚拟文件系统VFS(Virtual File System)层,三是挂载到VFS中的各种实际文件系统。
&&&&&&&& VFS是一种软件机制,只存在于内存中,每次系统初始化期间Linux都会先在内存中构造一棵VFS的目录树(也就是源码中的namespace)。VFS主要的作用是对上层应用屏蔽底层不同的调用方法,提供一套统一的调用接口,二是便于对不同的文件系统进行组织管理。因此,VFS其实就是文件系统组织管理中的一个抽象层。
一个典型的VFS目录组织方式如下图所示:
Superblock:超级块,是文件系统最基本的元数据,它定义了文件系统的类型、大小、状态和其他信息等。Superblock对于文件系统是非常关键的,因此一般文件系统都会冗余存储多份。
struct super_block {
&&& struct list_head&&& s_&&&&&&& /* 系统将所有文件系统的超级块组成链表*/
&&& dev_t&&&&&&&&&&& s_&&&&&&& /* _not_ kdev_t */
&&& unsigned long&&&&&&& s_
&&& unsigned char&&&&&&& s_blocksize_
&&& unsigned char&&&&&&& s_
&&& unsigned long long&&& s_&&& /* Max file size */
&&& struct file_system_type&&& *s_ //文件系统类型
&&& const struct super_operations&&& *s_ //操作函数集
&&& struct dquot_operations&&& *dq_
&&&& struct quotactl_ops&&& *s_
&&& struct export_operations *s_export_
&&& unsigned long&&&&&&& s_
&&& unsigned long&&&&&&& s_
&&& struct dentry&&&&&&& *s_ //挂载根目录
&&& struct rw_semaphore&&& s_
&&& struct mutex&&&&&&& s_
&&& int&&&&&&&&&&& s_
&&& int&&&&&&&&&&& s_
&&& int&&&&&&&&&&& s_need_sync_
&&& atomic_t&&&&&&& s_
#ifdef CONFIG_SECURITY
&&& void&&&&&&&&&&&&&&&&&&& *s_ //LSM框架的安全域
&&& struct xattr_handler&&& **s_
&&& struct list_head&&& s_&&& /* 所有的inode节点链表*/
&&& struct list_head&&& s_&&& /* dirty inodes */
&&& struct list_head&&& s_&&&&&&& /* parked for writeback */
&&& struct hlist_head&&& s_&&&&&&& /* anonymous dentries for (nfs) exporting */
&&& struct list_head&&& s_
&&& struct block_device&&& *s_
&&& struct list_head&&& s_
&&& struct quota_info&&& s_&&& /* Diskquota specific options */
&&& int&&&&&&&&&&& s_
&&& wait_queue_head_t&&& s_wait_
&&& char s_id[32];&&&&&&&&&&&&&&& /* Informational name */
&&& void&&&&&&&&&&&& *s_fs_&&& /* Filesystem private info */
&&&& * The next field is for VFS *only*. No filesystems have any business
&&&& * even looking at it. You had been warned.
&&& struct mutex s_vfs_rename_&&& /* Kludge */
&&& /* Granularity of c/m/atime in ns.
&&&&&& Cannot be worse than a second */
&&& u32&&&&&&&&&& s_time_
inode:包含了一个文件的元数据,如文件所在数据块等。这里需要注意Linux中的所有对象均为文件:实际的文件、目录、设备等等。一个inode基本包含:所有权(用户、组)、访问模式(读、写、执行)和文件类型等,但不包含文件名。
struct inode {
&&& struct hlist_node&&& i_
&&& struct list_head&&& i_
&&& struct list_head&&& i_sb_ //链入超级块中的链表
&&& struct list_head&&& i_
&&& unsigned long&&&&&&& i_ //节点号
&&& atomic_t&&&&&&& i_ //引用计数
&&& unsigned int&&&&&&& i_& //硬链接数目
&&& uid_t&&&&&&&&&&& i_ &//表示文件所有者
&&& gid_t&&&&&&&&&&& i_ &//表示文件所有者所属组
&&& dev_t&&&&&&&&&&& i_
&&& unsigned long&&&&&&& i_
&&& loff_t&&&&&&&&&&& i_
#ifdef __NEED_I_SIZE_ORDERED
&&& seqcount_t&&&&&&& i_size_
&&& struct timespec&&&&&&& i_
&&& struct timespec&&&&&&& i_
&&& struct timespec&&&&&&& i_
&&& unsigned int&&&&&&& i_
&&& blkcnt_t&&&&&&& i_
&&& unsigned short&&&&&&&&& i_
&&& umode_t&&&&&&&&&&& i_ &//inode权限
&&& spinlock_t&&&&&&& i_&&& /* i_blocks, i_bytes, maybe i_size */
&&& struct mutex&&&&&&& i_
&&& struct rw_semaphore&&& i_alloc_
&&& const struct inode_operations&&& *i_ &//inode操作函数集
&&& const struct file_operations&&& *i_&&& /* former ->i_op->default_file_ops */
&&& struct super_block&&& *i_ //指向超级块
&&& struct file_lock&&& *i_
&&& struct address_space&&& *i_
&&& struct address_space&&& i_
#ifdef CONFIG_QUOTA
&&& struct dquot&&&&&&& *i_dquot[MAXQUOTAS];
&&& struct list_head&&& i_
&&& union {
&&&&&&& struct pipe_inode_info&&& *i_
&&&&&&& struct block_device&&& *i_
&&&&&&& struct cdev&&&&&&& *i_
&&& int&&&&&&&&&&& i_
&&& __u32&&&&&&&&&&& i_
#ifdef CONFIG_DNOTIFY
&&& unsigned long&&&&&&& i_dnotify_ /* Directory notify events */
&&& struct dnotify_struct&&& *i_ /* for directory notifications */
#ifdef CONFIG_INOTIFY
&&& struct list_head&&& inotify_ /* watches on this inode */
&&& struct mutex&&&&&&& inotify_&&& /* protects the watches list */
&&& unsigned long&&&&&&& i_
&&& unsigned long&&&&&&& dirtied_&&& /* jiffies of first dirtying */
&&& unsigned int&&&&&&& i_
&&& atomic_t&&&&&&& i_
#ifdef CONFIG_SECURITY
&&& void&&&&&&&&&&& *i_ //LSM框架中的安全域
&&& void&&&&&&&&&&& *i_ /* fs or device private pointer */
inode结构中的i_ino索引节点号在同一个文件系统中是唯一的,但若是系统中挂载了多个文件系统,则inode号可能出现相同的情况。
其中这个 i_mode是16位的无符号整数表示,由9位权限方式位、3位“粘滞”标志位和4位文件类型标志位,它们的具体的定义在 include/linux/stat.h中:
#define S_IFMT&& &&&& /* 用于抽取i_mode域中类型部分的屏蔽位 */
#define S_IFSOCK 0140000&&&& /* 套接字类型码 */
#define S_IFLNK&&& 0120000&&& /* 符号连接类型码 */
#define S_IFREG&& 0100000&&& /* 普通文件类型码 */
#define S_IFBLK&& 0060000&&& /* 块特别文件类型码 */
#define S_IFDIR&& 0040000&&&& /* 目录文件类型码 */
#define S_IFCHR&& 0020000&&& /* 字符特别文件类型码 */
#define S_IFIFO&& 0010000&&&& /* 管道或FIFO类型码 */
#define S_ISUID&& 0004000&&& /* 用户粘滞位 */
#define S_ISGID&& 0002000&&& /* 用户组粘滞位 */
#define S_ISVTX&& 0001000&& /* 粘滞位 */
#define S_IRWXU 00700&&&& /* 用户读写执行 */
#define S_IRUSR 00400&&&&& /* 用户读 */
#define S_IWUSR 00200&&&& /* 用户写 */
#define S_IXUSR 00100&&&& /* 用户执行 */
#define S_IRWXG 00070&&& /* 用户组读写执行 */
#define S_IRGRP 00040&&& /* 用户组读 */
#define S_IWGRP 00020&&& /* 用户组写 */
#define S_IXGRP 00010&&& /* 用户组执行 */
#define S_IRWXO 00007&& /* 其他用户读写执行 */
#define S_IROTH 00004&&& /* 其他用户读 */
#define S_IWOTH 00002&& /* 其他用户写 */
#define S_IXOTH 00001&& /* 其他用户执行 */
#define S_IRWXUGO&&&& (S_IRWXU|S_IRWXG|S_IRWXO)&& /* 全部用户读写执行 */
#define S_IALLUGO&&&&& (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO )/* 全部用户全部权限 */
#define S_IRUGO&&&&&&&&& (S_IRUSR|S_IRGRP|S_IROTH)&&& /* 全部用户读 */
#define S_IWUGO&&&&&&&& (S_IWUSR|S_IWGRP|S_IWOTH)&& /* 全部用户写 */
#define S_IXUGO&&&&&&&&& (S_IXUSR|S_IXGRP|S_IXOTH)&&& /* 全部用户执行 */
dentry:将inode号和文件名联系起来,dentry还保存目录和其子对象的关系,用于文件系统的变量。dentry还起着缓存的作用,缓存最常使用的文件以便于更快捷的访问。
struct dentry {
&&& atomic_t d_ //引用计数
&&& unsigned int d_&&&&&&& /* protected by d_lock */
&&& spinlock_t d_&&&&&&& /* per dentry lock */
&& struct inode *d_&&&&&&& /* Where the name belongs to - NULL is
&&&&&&&&&&&&&&&&&&&& * negative */
&&&& * The next three fields are touched by __d_lookup.& Place them here
&&&& * so they all fit in a cache line.
&&& struct hlist_node d_&&& /* lookup hash list */
& & struct dentry *d_&&& /* parent directory */
&& struct qstr d_name;& //目录项名称,与inode对应起来
&&& struct list_head d_&&&&&&& /* LRU list */
&&&& * d_child and d_rcu can share memory
&&& union {
&&&&&&& struct list_head d_child;&&& /* child of parent list */ 链入父目录的子目录中
&&&&&&&& struct rcu_head d_
&&& } d_u;
&&& struct list_head d_subdirs;&&& /* our children */ 子目录链表
struct list_head d_&&& /* inode alias list */ 链入inode节点的i_dentry链表,因为一个inode可能对应多个dentry(硬链接)
&&& unsigned long d_&&&&&&& /* used by d_revalidate */
&&& struct dentry_operations *d_
&&& struct super_block *d_&&& /* The root of the dentry tree */
&&& void *d_&&&&&&&&&&& /* fs-specific data */
#ifdef CONFIG_PROFILING
&&& struct dcookie_struct *d_ /* cookie, if any */
&&& int d_
&&& unsigned char d_iname[DNAME_INLINE_LEN_MIN];&&& /* small names */
在内存中,每个文件都有一个dentry(目录项)和inode(索引节点)结构,dentry记录文件名、父目录、子目录等信息,形成文件树结构。inode结构则包含文件的宿主、创建时间和在存储介质上的位置和分布等信息。其中每个dentry都有一个唯一的inode,而每个inode则可能有多个dentry,这种情况是由ln硬链接产生的。
硬链接:其实就是同一个文件具有多个别名,具有相同inode,而dentry不同。
&&&&&&&&&&&&& 1. 文件具有相同的inode和data block;
&&&&&&&&&&&&& 2. 只能对已存在的文件进行创建;
&&&&&&&&&&&&& 3. 不同交叉文件系统进行硬链接的创建
&&&&&&&&&&&&& 4. 不能对目录进行创建,只能对文件创建硬链接
&&&&&&&&&&&&& 5. 删除一个硬链接并不影响其他具有相同inode号的文件;
软链接:软链接具有自己的inode,即具有自己的文件,只是这个文件中存放的内容是另一个文件的路径名。因此软链接具有自己的inode号以及用户数据块。
&&&&&&&&&&&&& 1. 软链接有自己的文件属性及权限等;
&&&&&&&&&&&&& 2. 软链接可以对不存在的文件或目录创建;
&&&&&&&&&&&&& 3. 软链接可以交叉文件系统;
&&&&&&&&&&&&& 4. 软链接可以对文件或目录创建;
&&&&&&&&&&&&& 5. 创建软链接时,链接计数i_nlink不会增加;
&&&&&&&&&&&&& 6. 删除软链接不会影响被指向的文件,但若指向的原文件被删除,则成死链接,但重新创建指向 的路径即可恢复为正常的软链接,只是源文件的内容可能变了。
file:每一个打开的文件都对应一个file结构,还保存文件的打开方式和偏移等。
struct file {
&&&& * fu_list becomes invalid after file_free is called and queued via
&&&& * fu_rcuhead for RCU freeing
&&& union {
&&&&&&& struct list_head&&& fu_
&&&&&&& struct rcu_head&&&& fu_
&&& } f_u;
&&& struct path&&&&&&& f_
#define f_dentry&&& f_path.dentry
#define f_vfsmnt&&& f_path.mnt
&&& const struct file_operations&&& *f_
&&& atomic_t&&&&&&& f_
&&& unsigned int&&&&&&&& f_
&&& mode_t&&&&&&&&&&& f_
loff_t&&&&&&&&&&& f_
&&& struct fown_struct&&& f_
&&& unsigned int&&&&&&& f_uid, f_
&&& struct file_ra_state&&& f_
&&& unsigned long&&&&&&& f_
#ifdef CONFIG_SECURITY
&&& void&&&&&&&&&&& *f_
&&& /* needed for tty driver, and maybe others */
&&& void&&&&&&&&&&& *private_
#ifdef CONFIG_EPOLL
&&& /* Used by fs/eventpoll.c to link all the hooks to this file */
&&& struct list_head&&& f_ep_
&&& spinlock_t&&&&&&& f_ep_
#endif /* #ifdef CONFIG_EPOLL */
&&& struct address_space&&& *f_
注意:VFS文件系统中的inode和dentry与实际文件系统的inode和dentry有一定的关系,但不能等同。真实磁盘文件的inode和dentry是存在于物理外存上的,但VFS中的inode和dentry是存在于内存中的,系统读取外存中的inode和dentry信息进行一定加工后,生成内存中的inode和dentry。虚拟的文件系统也具有inode和dentry结构,只是这是系统根据相应的规则生成的,不存在于实际外存中。
对应外存上的实际文件系统在格式化时就划分出了inode的数目和数据区块的数量,所以有可能inode用完了但数据区块还有剩余空间的情况。即虽然磁盘仍有剩余空间,但不能再创建文件和目录。
阅读(5741) | 评论(0) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 inode智能客户端 的文章

 

随机推荐