8
26
2014
72

linux中ext4文件系统目录项管理

Ext4文件系统目录项有两种实现方式:

方式一:线性方式

        该方式的目录项以ext4_dir_entry_2的结构一个接连一个直接存储在目录结点所指向的block块中。(缺省配置使用ext4_dir_entry_2这个结构)

 

方式二:Hash树的方式

        若目录下的文件数量很多,则若按照线性方式查找对应文件名的信息则会很低效。Hash树的方式,则可以用文件名来做hash计算,从而定位到对应文件的目录项结构所在的block,从而缩小查找范围、加快查找效率。

 

1.查看文件系统是否开启了方式二的目录管理方式

      root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg 

  输入如上指令,则可以发现文件系统的目录已经开启了hash树的管理方式。

 

2.hash树管理方式的打开和关闭

      在上述开启状态下,我们可以关闭hash树目录管理方式。关闭之后再打开。

root@f303server:~# tune2fs -O ^dir_index /dev/sde3

tune2fs 1.42.11 (09-Jul-2014)

root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index  # 查找不到了

root@f303server:~# tune2fs -O dir_index /dev/sde3

tune2fs 1.42.11 (09-Jul-2014)

root@f303server:~# tune2fs -l /dev/sde3 | grep dir_index

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize

root@f303server:~# 

 

 

3.怎么判断某目录是否以hash树的方式管理

 

    文件系统开启了hash树管理目录结点的方式并不意味着所有的目录都按树形结构组织管理。在文件系统中,系统会根据某个目录底下文件的多少来自动进行目录管理方式的选择,只有当文件数量大于某个数时,才会采用hash树管理方式。

 

    怎么判断某目录的管理方式是那种?

   

    若不是hash树的管理方式,则htree中debugfs中则会有如下提示

 

debugfs:  htree linux-2.6.34.14

 

htree: Not a hash-indexed directory

 

 

     若是hash树的管理方式,则

debugfs:  htree linux-2.6.34.14/kernel 显示如下

 

 


Root node dump:
         Reserved zero: 0
         Hash Version: 1
         Info length: 8
         Indirect levels: 0
         Flags: 0
Number of entries (count): 2
Number of entries (limit): 508
Entry #0: Hash 0x00000000, block 1
Entry #1: Hash 0x775173ee, block 2

Entry #0: Hash 0x00000000, block 1
Reading directory block 1, phys 3154297
791969 0x33788c78-7df72ede (20) rtmutex.c   
791971 0x12e2688e-f00920c3 (28) .latencytop.o.cmd   
791973 0x6d76fd8a-f7dad208 (16) futex.o   
791974 0x1f1d389c-0beb6325 (20) ns_cgroup.c   
791975 0x21f726a2-367f43fb (24) .built-in.o.cmd   
791977 0x2a43c4ba-ae0695eb (16) itimer.o   
791978 0x6139ce78-4032f3c2 (16) user.c   
791979 0x615af808-2478500b (24) test_kprobes.c   
791981 0x30feba52-ba8da1e9 (20) audit_tree.c   
791982 0x24bb2b3c-8100eb0d (20) kallsyms.o   
791987 0x71a57d4c-81410e0a (20) .uid16.o.cmd   
791989 0x3e1650ba-3d29a28e (20) freezer.c   
791991 0x0ba6a23a-978af98d (20) spinlock.o   
791992 0x1c6819e6-010b1d97 (24) sched_clock.o   
791997 0x6dc7a2ac-6b0769cb (12) gcov   792005 0x1db5303a-76fff9c7 (16) cpu.o   
792009 0x74def468-a27557c6 (20) .timer.o.cmd   
792010 0x540fdfac-e9e8121b (20) slow-work.o   
792014 0x4c0dc1c8-05179835 (24) Kconfig.preempt   
792018 0x620198da-2fb834e3 (16) cred.c   
792019 0x5973e25e-39b86f3d (32) .cgroup_freezer.o.cmd   
792021 0x1077ffa8-16896967 (16) sys.o   
792025 0x4011172e-63cbf0ec (28) .audit_tree.o.cmd   
792026 0x4c92aabc-1f86d6e5 (20) seccomp.o   
792027 0x5d7f2368-8aaa1cf9 (20) latencytop.c   
792028 0x2ff6ae9c-7b348c25 (24) pid_namespace.o   
792030 0x5f780482-e9fe78e9 (16) groups.o   
792031 0x6079e2b2-acbbff3a (24) rcutree_plugin.h   
792034 0x624e25c0-64cbfd07 (20) stacktrace.o   
792035 0x6e2d0608-09d837e7 (24) .sys_ni.o.cmd   
792036 0x7035c67c-3620d4f6 (16) uid16.o   
792038 0x5b9c06d0-57b802ad (24) .rcutree.o.cmd   
792039 0x356bc37c-95dc4cfb (16) fork.o   
792042 0x46df975e-cef87f2d (16) async.c 

该文如下部分探讨按照方式1组织的目录结构:

1.为了理解后文,首先了解ext4_dir_entry_2的每一个元素

Offset

Size

Name

Description

0x0

__le32

inode

Number of the inode that this directory entry points to.

0x4

__le16

rec_len

Length of this directory entry.

0x6

__u8

name_len

Length of the file name.

0x7

__u8

file_type

File type code, one of:

0x0

Unknown.

0x1

Regular file.

0x2

Directory.

0x3

Character device file.

0x4

Block device file.

0x5

FIFO.

0x6

Socket.

0x7

Symbolic link.

0x8

char

name[EXT4_NAME_LEN]

File name.

 

上表我们可以看到该结构中共5个数据项,前四项占8byte,

通过根目录为例,通过hexdump查看其二进制代码,则“目录项的长度(ren_len)= 文件名长度(name_len) + 8 ”。但是在很多情况下rec_len > = name_len + 8。原因是因为目录项每一项的起始位置必须按照后两位 00 对齐。故有时候会浪费几个字节。

 

 2.通过hexdump指令直接查看二进制内容

先通过

debugfs /dev/sde3

stat .

查找到根目录文件数据所在的块为9249,块大小为4K,故根目录数据所在的起始地址36996k。

 

root@f303server:~# hexdump -C /dev/sde3 -s 36996k -n 4096

02421000  02 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|

02421010  0c 00 02 02 2e 2e 00 00  0b 00 00 00 14 00 0a 02  |................|

02421020  6c 6f 73 74 2b 66 6f 75  6e 64 00 00 01 00 0c 00  |lost+found......|

02421030  0c 00 04 02 64 69 72 31  01 00 0e 00 0c 00 04 02  |....dir1........|

02421040  64 69 72 32 0d 00 00 00  10 00 08 01 73 64 65 33  |dir2........sde3|

02421050  2e 74 78 74 0e 00 00 00  10 00 05 01 32 2e 74 78  |.txt........2.tx|

02421060  74 74 2e 73 11 00 00 00  10 00 05 01 33 2e 74 78  |tt.s........3.tx|

02421070  74 74 2e 73 01 00 10 00  0c 00 04 02 64 69 72 33  |tt.s........dir3|

02421080  01 00 12 00 0c 00 04 02  6d 6b 66 73 0c 00 00 00  |........mkfs....|

02421090  18 00 0e 01 62 6c 6b 74  72 61 63 65 5f 73 74 75  |....blktrace_stu|

024210a0  64 79 65 33 15 00 00 00  18 00 10 01 62 6c 6b 74  |dye3........blkt|

024210b0  72 61 63 65 5f 73 74 75  64 79 2e 63 10 00 00 00  |race_study.c....|

024210c0  14 00 0b 01 67 63 63 5f  62 6c 6b 74 2e 73 68 00  |....gcc_blkt.sh.|

024210d0  0f 00 00 00 10 00 07 01  6e 65 77 2e 74 78 74 63  |........new.txtc|

024210e0  12 00 00 00 1c 00 13 01  62 6c 6b 74 72 61 63 65  |........blktrace|

024210f0  5f 73 74 75 64 79 2d 76  31 2e 63 01 01 00 02 00  |_study-v1.c.....|

02421100  10 00 06 02 4e 65 77 44  69 72 61 63 13 00 00 00  |....NewDirac....|

02421110  1c 00 13 01 62 6c 6b 74  72 61 63 65 5f 73 74 75  |....blktrace_stu|

02421120  64 79 2d 76 32 2e 63 77  14 00 00 00 18 00 0e 01  |dy-v2.cw........|

02421130  64 72 6f 70 5f 63 61 63  68 65 73 2e 73 68 79 2e  |drop_caches.shy.|

02421140  01 00 04 00 10 00 06 02  73 64 65 31 63 70 15 01  |........sde1cp..|

02421150  01 00 08 00 b0 0e 0f 02  6c 69 6e 75 78 2d 32 2e  |........linux-2.|

02421160  36 2e 33 34 2e 31 34 00  00 00 00 00 00 00 00 00  |6.34.14.........|

02421170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

*

02422000

 

上图中每个颜色表示一个dentry的记录

 

1

观察lost+found目录:

Rec_len = 0x 00 14   name_len = 0a

 

rec_len = name_len +8 +2   则在对齐时浪费了第三行的第1112个字节。

 

2

我们看到2.txt的文件名变成了2.txtt.s

 

原因是最后三个字节是无效字节,在对齐时已经去掉,对齐时三个字节的内容是随便填充的。

 

 

 

 

 

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com