Btrfs文件系统使用说明_scanning for btrfs filesystems failed to send flus-程序员宅基地



1 Btrfs简介

  Btrfs 被称为是下一代 Linux 文件系统。近年来 ext2/3 遇到越来越多的扩展性问题,在期待 ext4 的同时,人们发现了 btrfs,据说它采用了很多先进的文件系统设计,不仅解决了 ext2/3 的扩展性问题,还让人们看到了下一代文件系统所具有的许多其他特性。

btrfs 的主页上看到 btrfs 的特性列表。首先是扩展性 (scalability) 相关的特性,btrfs 最重要的设计目标是应对大型机器对文件系统的扩展性要求。 ExtentB-Tree 和动态 inode 创建等特性保证了 btrfs 在大型机器上仍有卓越的表现,其整体性能而不会随着系统容量的增加而降低。其次是数据一致性 (data integrity) 相关的特性。系统面临不可预料的硬件故障,Btrfs 采用 COW 事务技术来保证文件系统的一致性。 btrfs 还支持 checksum,避免了 silent corrupt 的出现。而传统文件系统则无法做到这一点。第三是和多设备管理相关的特性。 Btrfs 支持创建快照 (snapshot),和克隆 (clone) btrfs 还能够方便的管理多个物理设备,使得传统的卷管理软件变得多余。最后是其他难以归类的特性。这些特性都是比较先进的技术,能够显著提高文件系统的时间 / 空间性能,包括延迟分配,小文件的存储优化,目录索引等。

2 Btrfs使用说明

2.1. 文件系统的建立

2.1.1在虚拟机中添加一个硬盘()
2.1.2查看硬盘是否添加成功

  通过命令:# fdisk -l  查看硬盘信息,可以看到新添加的硬盘属性,这里假设新添加的硬盘名为:sdd1

  通过命令:# fdisk  /dev/sdd1(具体磁盘名称),可进入分割硬盘模式。

  Ø         输入 m 显示所有命令列示。

 

  Ø         输入 p 显示硬盘分割情形。

 

  Ø         输入 a 设定硬盘启动区。

 

  Ø         输入 n 设定新的硬盘分割区。

 

  Ø         输入 e 硬盘为[延伸]分割区(extend)

 

  Ø         输入 p 硬盘为[主要]分割区(primary)

 

  Ø         输入 t 改变硬盘分割区属性。

 

  Ø         输入 d 删除硬盘分割区属性。

 

  Ø         输入 q 结束不存入硬盘分割区属性。

 

  Ø         输入 w 结束并写入硬盘分割区属性。

 

  dmesg命令说明如下:

 

  功能说明:显示开机信息。

  语  法:dmesg [-cn][-s ]

  补充说明:kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文档里。

  参  数:

   -c  显示信息后,清除ring buffer中的内容。

   -s  预配置为8196,刚好等于ring buffer的大小。

   -n  配置记录信息的层级。

 

2.1.3 对要挂载的硬盘创建磁盘分区

 

  创建磁盘分区步骤举例如下:

 

  # fdisk /dev/sdd1

 

  进入fdisk模式:

 

  Command (m for help):m   //查看fdisk命令帮助

 

  Command (m for help):n   //创建新分区

 

  Command action

 

  e extended    //输入e为创建扩展分区

 

  p primary partition (1-4)     //输入p为创建主分区,这里我们选择p

 

  Partion number(1-4)1     //第一个扩展分区,按需求可以最多分4个主分区

 

  First Cylinder(1-1014,default 1): 1   //第一个主分区起始的磁盘块数,可以选择默认值

 

  Last cylindet or +siza or +sizeM or +sizeK: +1024MB //可以是以MB为单位的数字或者

 

  以磁盘块数,这里我们输入+1024MB表示分区大小为1G

 

  这样我们就创建完一个分区,如果要创建更多分区可以照上面的步骤继续创建。所有分区创建完后用w保存分区。

 

  Command (m for help): w

 

  The partition table has been altered!

 

  保存完成后重启服务器,可以用#fdisk -l 命令检查刚刚所建分区,可以在返回结果中确认/dev/sdb1的信息。

 

2.1.4 建立文件系统

  可以用mkfs.btrfs 命令建立一个 btrfs 格式的文件系统。可以用如下命令在设备 sdd1 上建立一个 btrfs 文件系统.

#mkfs.btrfs  /dev/sdd1

[root@localhost btrfs]# mkfs.btrfs /dev/sdd1

 

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL

WARNING! - see http://btrfs.wiki.kernel.org before using

 

fs created label (null) on /dev/sdd1

    nodesize 4096 leafsize 4096 sectorsize 4096 size 7.99GB

Btrfs Btrfs v0.19

可以看到在建立btrfs系统时出现了WARNING,这是因为在我使用的linux版本中btrfs还属于一个实验性的产品,并未完全成熟,不过对我们影响不大,可以忽略。

2.1.5 挂载文件

 

  首先通过mkdir创建一个挂载文件点

  # mkdir mybtrfs

  然后通过mount命令挂载

  #mount -t btrds /dev/sdd1 mybtrfs

[root@localhost mnt]# pwd

/mnt

[root@localhost mnt]# mkdir mybtrfs

[root@localhost mnt]# mount -t btrfs /dev/sdd1 /mnt/mybtrfs

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560744   6072740  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs     8379372        56   7512812   1% /mnt/mybtrfs

[root@localhost mnt]#

通过 df –T命令可以看到文件已挂载成功。

  为了在每次系统启动时自动挂载新分区,可以修改/etc/fstab文件来进行自动挂载。在文件的末位加入如下一行:

  /dev/sdd1 /mnt/mybtrfs btrfs defaults 1 2

  这样服务器每次启动都会自动挂载此分区.

 

  至此,btrfs文件系统就OK了,可以通过# df 命令进行查看

 

2.2 Btrfs操作命令

2.2.1 修改btrfs文件系统的大小

当文件系统建立好之后,您可以修改文件系统的大小。 /dev/sda5 挂载到了 /mnt/mybtrfs下,大小为 8G 。假如您希望只使用其中的 7G,则需要减小当前文件系统的大小,这可以通过如下命令实现:

#btrfsctl -r -1024M /mnt/mybtrfs

[root@localhost mnt]# df -l

文件系统            1K-      已用      可用 已用% 挂载点

/dev/sda1             18577148  11560744   6072740  66% /

tmpfs                   510984       264    510720   1% /dev/shm

/dev/sdb1             20641404   6161100  13431780  32% /opt

/dev/sdd1              8379372        56   7512812   1% /mnt/mybtrfs

[root@localhost mnt]# btrfsctl -r -1024M /mnt/mybtrfs

operation complete

Btrfs Btrfs v0.19

[root@localhost mnt]# df -l

文件系统            1K-      已用      可用 已用% 挂载点

/dev/sda1             18577148  11560744   6072740  66% /

tmpfs                   510984       264    510720   1% /dev/shm

/dev/sdb1             20641404   6161100  13431780  32% /opt

/dev/sdd1              7330796        56   6464236   1% /mnt/mybtrfs

[root@localhost mnt]#

 

同样的,您可以使用 btrfsctl 命令增加文件系统的大小。

#btrfsctl -r +1024M /mnt/mybtrfs

2.2.2 扫描文件系统

  扫描整个btrfs文件系统:

  #btrfsctl –a

[root@localhost mnt]# btrfsctl -a

Scanning for Btrfs filesystems

failed to read /dev/fd0

failed to read /dev/sr0

[root@localhost mnt]#

 

  扫描指定btrfs文件系统:

  #btrfsctl -A /dev/sdd1

[root@localhost mnt]# btrfsctl -A /dev/sdd1

operation complete

Btrfs Btrfs v0.19

[root@localhost mnt]#

 

2.2.3 整理文件系统

  整理一个文件:

  #btrfsctl -d 文件

[root@localhost mybtrfs]# pwd

/mnt/mybtrfs

[root@localhost mybtrfs]# ls

test.txt

[root@localhost mybtrfs]# btrfsctl -d /mnt/mybtrfs/test.txt

operation complete

Btrfs Btrfs v0.19

[root@localhost mybtrfs]#

 

  整理一个目录:

  #btrfsctl -d 目录

[root@localhost mnt]# btrfsctl -d /mnt/mybtrfs

operation complete

Btrfs Btrfs v0.19

[root@localhost mnt]#

 

 

2.2.4 创建/删除 快照(snapshot)

快照是对文件系统某一时刻的完全备份。建立快照之后,对文件系统的修改不会影响快照中的内容。这是非常有用的一种技术。比如数据库备份。假如在时间点 T1,管理员决定对数据库进行备份,那么他必须先停止数据库。备份文件是非常耗时的操作,假如在备份过程中某个应用程序修改了数据库的内容,那么将无法得到一个一致性的备份。因此在备份过程中数据库服务必须停止,对于某些关键应用这是不能允许的。

利用快照,管理员可以在时间点 T1 将数据库停止,对系统建立一个快照。这个过程一般只需要几秒钟,然后就可以立即重新恢复数据库服务。此后在任何时候,管理员都可以对快照的内容进行备份操作,而此时用户对数据库的修改不会影响快照中的内容。当备份完成,管理员便可以删除快照,释放磁盘空间。

快照一般是只读的,当系统支持可写快照,那么这种可写快照便被称为克隆。克隆技术也有很多应用。比如在一个系统中安装好基本的软件,然后为不同的用户做不同的克隆,每个用户使用自己的克隆而不会影响其他用户的磁盘空间。非常类似于虚拟机。

下面的例子中,创建快照 snap1 时系统存在 1 个文件。创建快照之后,对 test 的内容进行修改。再回到 snap1,打开 test 文件,可以看到 test1 的内容依旧是之前的内容。

  #btrfsctl -s snap1(快照名) dir

[root@localhost mybtrfs]# btrfsctl -s snap1 /mnt/mybtrfs

operation complete

Btrfs Btrfs v0.19

[root@localhost mybtrfs]# ls

snap1  test.txt

[root@localhost mybtrfs]# cat snap1/test.txt

This a test!

[root@localhost mybtrfs]# vim test.txt

[root@localhost mybtrfs]# cat snap1/test.txt

This a test!

[root@localhost mybtrfs]#

可以从上面的例子看到,快照 snap1 保存的内容不会被后续的写操作所改变。

同理,可以通过#btrfsctl –D snap(快照名) .  删除快照

[root@localhost mybtrfs]# ls

snap  text

[root@localhost mybtrfs]# btrfsctl -D snap .

operation complete

Btrfs Btrfs v0.19

[root@localhost mybtrfs]# ls

text

[root@localhost mybtrfs]#

 

 

 

2.2.5 创建子卷(subvolume)

Subvolume即是把文件系统的一部分配置为一个完整的子文件系统,称之为 subvolume

采用 subvolume,一个大的文件系统可以被划分为多个子文件系统,这些子文件系统共享底层的设备空间,在需要磁盘空间时便从底层设备中分配,类似应用程序调用 malloc() 分配内存一样。可以称之为存储池。这种模型有很多优点,比如可以充分利用 disk 的带宽,可以简化磁盘空间的管理等。

所谓充分利用 disk 的带宽,指文件系统可以并行读写底层的多个 disk,这是因为每个文件系统都可以访问所有的 disk 。传统的文件系统不能共享底层的 disk 设备,无论是物理的还是逻辑的,因此无法做到并行读写。

所谓简化管理,是相对于 LVM 等卷管理软件而言。采用存储池模型,每个文件系统的大小都可以自动调节。而使用 LVM,如果一个文件系统的空间不够了,该文件系统并不能自动使用其他磁盘设备上的空闲空间,而必须使用 LVM 的管理命令手动调节。

Subvolume 可以作为根目录挂载到任意 mount 点。 subvolume 是非常有趣的一个特性,有很多应用。假如管理员只希望某些用户访问文件系统的一部分,比如希望用户只能访问 /var/test/ 下面的所有内容,而不能访问 /var/ 下面其他的内容。那么便可以将 /var/test 做成一个 subvolume /var/test 这个 subvolume 便是一个完整的文件系统,可以用 mount 命令挂载。比如挂载到 /test 目录下,给用户访问 /test 的权限,那么用户便只能访问 /var/test 下面的内容了。

使用 btrfs 命令,用户可以方便的建立 subvolume 。假设 /mnt/mybtrfs 已经挂载到了 btrfs 文件系统,则用户可以在这个文件系统内创建新的 subvolume 。比如建立一个 /sub1 subvolume,并  sub1 挂载到 /mnt/test 下:

  #mkdir /mnt/test

  #btrfsctl – S sub1 mnt/mybtrfs

  #mount – t btrfs – o subvol=sub1 /dev/sdd1 /mnt/test

[root@localhost mnt]# mkdir /mnt/test

[root@localhost mnt]# btrfsctl -S sub1 /mnt/mybtrfs

operation complete

Btrfs Btrfs v0.19

[root@localhost mnt]# mount -t btrfs -o subvol=sub1 /dev/sdd1 /mnt/test

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560792   6072692  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/mybtrfs

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/test

[root@localhost mnt]#

 

Subvolme 可以方便管理员在文件系统上创建不同用途的子文件系统,并对其进行一些特殊的配置,比如有些目录下的文件关注节约磁盘空间,因此需要打开压缩,或者配置不同的 RAID 策略等。目前 btrfs 尚处于开发阶段,创建的 subvolme snapshot 还无法删除。此外针对 subvolume 的磁盘 quota 功能也未能实现。但随着 btrfs 的不断成熟,这些功能必然将会进一步完善

 

 

2.2.6 创建 RAID

RAID 技术有很多非常吸引人的特性,比如用户可以将多个廉价的 IDE 磁盘组合为 RAID0 阵列,从而变成了一个大容量的磁盘; RAID1 和更高级的 RAID 配置还提供了数据冗余保护,从而使得存储在磁盘中的数据更加安全。Btrfs 很好的支持了软件 RAIDRAID 种类包括 RAID0,RAID1 RAID10.

mkfs 的时候,可以指定多个设备,并配置 RAID 。下面的命令演示了如何使用 mkfs.btrfs 配置 RAID1 。磁盘sde1 sdf1 可以配置为 RAID1,即 mirror 。用户可以选择将数据配置为 RAID1,也可  以选择将元数据配置为 RAID1   将数据配置为 RAID1,可以使用 mkfs.btrfs -d 参数。如下所示:

  # mkfs.btrfs -d raid1 /dev/sde1 /dev/sdf1

  # mount -t btrfs  /dev/sde1 /mnt/raid1

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560780   6072704  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/mybtrfs

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/test

[root@localhost mnt]# mkfs.btrfs -d raid1 /dev/sde1 /dev/sdf1

 

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL

WARNING! - see http://btrfs.wiki.kernel.org before using

 

adding device /dev/sdf1 id 2

fs created label (null) on /dev/sde1

    nodesize 4096 leafsize 4096 sectorsize 4096 size 15.99GB

Btrfs Btrfs v0.19

[root@localhost mnt]# mount -t btrfs  /dev/sde1 /mnt/raid1

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560780   6072704  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/mybtrfs

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/test

/dev/sde1    btrfs    16765268        56  14639444   1% /mnt/raid1

[root@localhost mnt]#

 

挂载的时候可以是sde1,也可以是sdf1,示例中用的sde1,容量是两个盘的总量,但当存储文件时,占用的存储空间同时也是文件大小2倍。

 

2.2.7添加/删除 新设备

当设备的空间快被使用完的时候,用户可以使用 btrfs-vol 命令为文件系统添加新的磁盘设备,从而增加存储空间。下面的命令向 /mnt/mybtrfs 文件系统增加一个设备 /sdg

  # btrfs-vol -a /dev/sdg  /mnt/mybtrfs

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560796   6072688  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/mybtrfs

/dev/sdd1    btrfs     7330796        72   6464236   1% /mnt/test

/dev/sde1    btrfs    16765268        56  14639444   1% /mnt/raid1

[root@localhost mnt]# btrfs-vol -a /dev/sdg  /mnt/mybtrfs

ioctl returns 0

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11560804   6072680  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sdd1    btrfs    15719404        72  14852844   1% /mnt/mybtrfs

/dev/sdd1    btrfs    15719404        72  14852844   1% /mnt/test

/dev/sde1    btrfs    16765268        56  14639444   1% /mnt/raid1

可以看到,通过btffs-vol命令为/mnt/mybtrfs文件系统增加了8G的容量。

为了灵活利用设备空间,Btrfs 将磁盘空间划分为多个 chunk 。每个 chunk 可以使用不同的磁盘空间分配策略。比如某些 chunk 只存放 metadata,某些 chunk 只存放数据。一些 chunk 可以配置为 mirror,而另一些 chunk 则可以配置为 stripe 。这为用户提供了非常灵活的配置可能性。

添加设备后可以通过命令平衡chunks

# btrfs-vol -b /dev/sdg  /mnt/mybtrfs

[root@localhost mnt]# btrfs-vol -b /mnt/mybtrfs

ioctl returns 0

[root@localhost mnt]#

 

 

同理,可以通过命令

# btrfs-vol -r /dev/sdg  /mnt/mybtrfs

移除添加的设备。

 

 

 

2.2.8同步文件系统

  为了提高效率,btrfs IO 操作由一些内核线程异步处理。这使得用户对文件的操作并不会立即反应到磁盘上。

  您可以做一个实验,在 btrfs 上创建一个文件后,稍等 5 10 秒将系统电源切断,再次重启后,新建的文件并没有出现。

  对于多数应用这并不是问题,但有些时候用户希望 IO 操作立即执行,此时就需要对文件系统进行同步。下面的 btrfs 命令用来同步文件系统:

  # btrfsctl -c /mnt/mybtrfs

[root@localhost mnt]# btrfsctl -c /mnt/mybtrfs

operation complete

Btrfs Btrfs v0.19

 

2.2.9文件系统转化

  可以通过如下命令将非btrfs转化为btrfs,下面的例子是将EXT3文件系统的sdd1转化为btrfs

  # btrfs-convert /dev/sdd1

[root@localhost mnt]# btrfs-convert /dev/sdd1

creating btrfs metadata.

creating ext2fs image file.

cleaning up system chunk.

conversion complete.

[root@localhost mnt]# mount /dev/sdd1 /mnt/mybtrfs

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11563724   6069760  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sde1    btrfs    16765268        56  14639444   1% /mnt/raid1

/dev/sdd1    btrfs     8379372    281344   5326336   6% /mnt/mybtrfs

[root@localhost mnt]#

 

同时,也可以通过命令将文件系统回滚到之前的状态:

# btrfs-convert -r /dev/sdd1

[root@localhost mnt]# btrfs-convert   -r /dev/sdd1

rollback complete.

[root@localhost mnt]# mount /dev/sdd1 /mnt/mybtrfs

[root@localhost mnt]# df -T

文件系统    类型         1K-      已用      可用 已用% 挂载点

/dev/sda1     ext4    18577148  11563716   6069768  66% /

tmpfs        tmpfs      510984       264    510720   1% /dev/shm

/dev/sdb1     ext4    20641404   6161100  13431780  32% /opt

/dev/sde1    btrfs    16765268        56  14639444   1% /mnt/raid1

/dev/sdd1     ext3     8247716    149624   7679124   2% /mnt/mybtrfs

[root@localhost mnt]#

 

 

  btrfs-convert命令其他用法:

  usage: btrfs-convert [-d] [-i] [-n] [-r] device

    -d disable data checksum

    -i ignore xattrs and ACLs

    -n disable packing of small files

    -r roll back to ext2fs

 

2.2.10显示所有btrfs

 

  可以通过birfs-show命令查看当前所有btrfs设备

# btrfs-show

   

[root@localhost mnt]# btrfs-show

failed to read /dev/fd0

failed to read /dev/sr0

Label: none  uuid: fa51764c-b9cf-4ebb-b0a5-3f0a0f46c5ff

    Total devices 2 FS bytes used 36.00KB

    devid    2 size 8.00GB used 0.00 path /dev/sdg

    *** Some devices missing

 

Label: none  uuid: 4565d768-ca00-4786-aa59-3046e4e085bd

    Total devices 2 FS bytes used 28.00KB

    devid    2 size 8.00GB used 2.01GB path /dev/sdh

    *** Some devices missing

 

Label: none  uuid: de697cdb-36d5-42eb-802d-2d85c571cba6

    Total devices 2 FS bytes used 28.00KB

    devid    1 size 8.00GB used 2.03GB path /dev/sde1

    devid    2 size 7.99GB used 2.01GB path /dev/sdf1

 

Btrfs Btrfs v0.19

 

2.2.11检查btrfs文件系统

可以通过命令检查btrfs文件系统

# btrfsck /dev/sdd1

[root@localhost mnt]# btrfsck /dev/sdd1

found 288096256 bytes used err is 0

total csum bytes: 0

total tree bytes: 65536

total fs tree bytes: 32768

btree space waste bytes: 36111

file data blocks allocated: 288030720

 referenced 288030720

Btrfs Btrfs v0.19

2.2.12更新种子值

当我们需要将一个文件系统设置为只读时,我们可以通过btrfstune命令来实现。

#btrfstune -S 1 /dev/sdd1

[root@localhost mnt]# btrfstune -S 1 /dev/sdd1

[root@localhost mnt]# mount /dev/sdd1  /mnt/mybtrfs

mount: block device /dev/sdd1 is write-protected, mounting read-only

同理可以通过命令取消文件系统的只读属性

btrfstune -S 0 /dev/sdd1

2.2.13 Debug功能

Btrfs 提供了一定的 debug 功能,对于想了解 Btrfs 内部实现原理的读者,debug 将是您最喜欢的工具。这里简单介绍一下 debug 功能的命令使用。

下面的命令将设备 sda5 上的 btrfs 文件系统中的元数据打印到屏幕上。

#btrfs-debug-tree /dev/sdd1

 

#btrfs-debug-tree /dev/sdd1

leaf 33574912 items 2 free space 3773 generation 3 owner 18446744073709551607

fs uuid 1d61c350-be9a-48e5-90b6-623bf34fe27e

chunk uuid 75de6f43-0d68-43c5-9112-88d892a6d1ce

    item 0 key (FIRST_CHUNK_TREE INODE_ITEM 0) itemoff 3835 itemsize 160

       inode generation 3 size 0 block group 0 mode 40555 links 1

    item 1 key (FIRST_CHUNK_TREE INODE_REF 256) itemoff 3823 itemsize 12

       inode ref index 0 namelen 2 name: ..

total bytes 8580476928

bytes used 288096256

uuid 1d61c350-be9a-48e5-90b6-623bf34fe27e

Btrfs Btrfs v0.19

 

通过对打印信息的分析,您将能了解 btrfs 内部各个 BTree 的变化情况,从而进一步理解每一个文件系统功能的内部实现细节。

比如您可以在创建一个文件之前将 BTree 的内容打印出来,创建文件后再次打印。通过比较两次的不同来了解 btrfs 创建一个文件需要修改哪些元数据。进而理解 btrfs 内部的工作原理。

3 附录

3.1快照原理(附录)

3.1.1 COW 事务

理解 COW 事务,必须首先理解 COW 和事务这两个术语。

什么是 COW?

所谓 COW,即每次写磁盘数据时,先将更新数据写入一个新的 block,当新数据写入成功之后,再更新相关的数据结构指向新 block

什么是事务?

COW 只能保证单一数据更新的原子性。但文件系统中很多操作需要更新多个不同的元数据,比如创建文件需要修改以下这些元数据:

  1. 修改 extent tree,分配一段磁盘空间
  2. 创建一个新的 inode,并插入 FS Tree
  3. 增加一个目录项,插入到 FS Tree

任何一个步骤出错,文件便不能创建成功,因此可以定义为一个事务。

下面将演示一个 COW 事务。

A FS Tree 的根节点,新的 inode 的信息将被插入节点 C 。首先,btrfs inode 插入一个新分配的 block C ’中,并修改上层节点 B,使其指向新的 block C ’;修改 B 也将引发 COW,以此类推,引发一个连锁反应,直到最顶层的 Root A 。当整个过程结束后,新节点 A ’变成了 FS Tree 的根。但此时事务并未结束,superblock 依然指向 A


5. COW transaction 1

接下来,修改目录项(E 节点),同样引发这一过程,从而生成新的根节点 A ’’。


6. COW transaction 2

此时,inode 和目录项都已经写入磁盘,可以认为事务已经结束。 btrfs 修改 superblock,使其指向 A ’’,如下图所示:


7. COW transaction 3

COW 事务能够保证文件系统的一致性,并且系统 Reboot 之后不需要执行 fsck 。因为 superblock 要么指向新的 A ’’,要么指向 A,无论哪个都是一致的数据。

3.1.2 快照和克隆

快照是对文件系统某一时刻的完全备份。建立快照之后,对文件系统的修改不会影响快照中的内容。这是非常有用的一种技术。如前所述 Btrfs 采用 COW 事务技术,从图 1-10 可以看到,COW 事务结束后,如果不删除原来的节点 A,C,E,那么 A,C,E,D,F 依然完整的表示着事务开始之前的文件系统。这就是 snapshot 实现的基本原理。

Btrfs 采用引用计数决定是否在事务 commit 之后删除原有节点。对每一个节点,btrfs 维护一个引用计数。当该节点被别的节点引用时,该计数加一,当该节点不再被别的节点引用时,该计数减一。当引用计数归零时,该节点被删除。对于普通的 Tree Root, 引用计数在创建时被加一,因为 Superblock 会引用这个 Root block 。很明显,初始情况下这棵树中的所有其他节点的引用计数都为一。当 COW 事务 commit 时,superblock 被修改指向新的 Root A ’’,原来 Root block A 的引用计数被减一,变为零,因此 A 节点被删除。 A 节点的删除会引发其子孙节点的引用计数也减一,图 1-10 中的 BC 节点的引用计数因此也变成了 0,从而被删除。 D,E 节点在 COW 时,因为被 A ’’所引用,计数器加一,因此计数器这时并未归零,从而没有被删除。

创建 Snapshot 时,btrfs 将的 Root A 节点复制到 sA,并将 sA 的引用计数设置为 2 。在事务 commit 的时候,sA 节点的引用计数不会归零,从而不会被删除,因此用户可以继续通过 Root sA 访问 snapshot 中的文件。


8. Snapshot

3.2 Btrfs工具的安装(附录)

   如果当要将一个磁盘格式化为btrfs格式时发现mkfs.后并没有btrfs选项,那么可能你需要安装btrfs-tools,安装方法如下:

在下面的地址下载这个包:

ftp://ftp.li.kernel.org/pub/.3/ubuntu/pool/universe/b/btrfs-tools/

   这个包安装起来还是比较简单的,直接解压缩,然后接着执行make进行编译,之后执行make install进行安装。

如果在make install时发现有如下问题:

[root@ipshot btrfs-progs-0.19]# make install

ls btrfsck.c

btrfsck.c

gcc -Wp,-MMD,./.btrfsck.o.d,-MT,btrfsck.o -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -g -Werror -Os -c btrfsck.c

cc1: warnings being treated as errors

btrfsck.c: In function ‘maybe_free_inode_rec’:

btrfsck.c:287: error: implicit declaration of function ‘S_ISDIR’

btrfsck.c:292: error: implicit declaration of function ‘S_ISREG’

btrfsck.c:292: error: implicit declaration of function ‘S_ISLNK’

make: *** [btrfsck.o] Error 1

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tanbajiong6117/article/details/38180707

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf