Linux文件系统

文件系统:
提高查找效率和磁盘利用率更高,有个高效方式管理文件,按照一定方式组织格式进行 存储然后按照指定格式进行查找;
linux ext2(第二代文件系统)
1磁盘分区,交换分区(交换内存来使用)和文件系统分区(存储文件)
文件系统分区又会分很多小的文件系统分区,就是一个分区就会有一个文件系统,就是每个分区都有文件系统同一个磁盘不同分区可以拥有不同的文件系统(操作系统可以对其管理)
一个文件系统:进行了分块式存储,将磁盘分为无数个磁盘块(默认大小4096个)对目录来说每个目录创建出来至少占用一个磁盘块大小为4096
drwxrwxr-x. 2 chenyongjie chenyongjie 4096 4月 20 13:44 signal
分块存储目的:文件不需要连续存储一个文件 a.txt 分为三块,这三块在不同的位置上进行存储将自己的数据存储在三个不同的磁盘块,必须有个标记 来标记a.txt用了哪三个磁盘块并且有多大,这个文件的描述信息称为inode结点
inode包含:文件的大小,权限,用户,时间属性,磁盘块的存储位置(数据存储位置)
所以在磁盘上有一个非常大的区域叫inode区域:全部放的inode结点
一个磁盘格式化:有多少个磁盘块有多少个inode结点
由于磁盘块多inode结点也多找空闲的十分慢:标记一下哪些使用了哪些没有使用用位图:
1>数据块的位图databitmap,哪些磁盘使用和哪些没有使用,
2>inode结点位图inodebitmap:哪些inode结点使用和未使用
文件的存储方式:
在这里插入图片描述
eg:a.txt,首先在inodebitmap获取空闲的inode结点号位置,然后在inodetable中找到inode结点然后在databitmap找到空闲的数据块然后将块的位置记录到inode结点当中然后将数据写入到数据块
方式:通过inode_bitmap在inode table 中找到空闲的结点,通过data_bitmap在数据块的空闲数据块找到空闲的数据块,将数据块位置信息,记录到inode结点中,将文件数据写入数据块中,将文件的名和inode结点写到父目录文件中;
目录文件:存放了一张目录下有什么文件的表,表记录文件的名字,和inode结点号
cat ./a.txt流程:在当前目录文件中查找文件名信息,通过文件名获取inde结点号,通过inode结点号找到inode结点,进而访问数据块,读取数据进行打印
**创建文件创建不了?*1>磁盘满,但是创建空文件(没有数据区域,但是有目录项目,目录项纪录在目录文件当中,不一定占空间)有可能2>inode的结点被占完了,个数有限(解决:压缩合并,把很多的图片文件压缩成一个文件,成了一个文件,用的时候解压缩)
软连接和硬链接:
[chenyongjie@localhost wenjian]$ touch a.txt
[chenyongjie@localhost wenjian]$ ll
总用量 0
-rw-rw-r–. 1 chenyongjie chenyongjie 0 4月 21 09:34 a.txt
1为链接束,0 文件大小09:34最后一次修改时间
$ ln a.txt a.hard
[chenyongjie@localhost wenjian]$ ll
总用量 0
-rw-rw-r–. 2 chenyongjie chenyongjie 0 4月 21 09:34 a.hard
-rw-rw-r–. 2 chenyongjie chenyongjie 0 4月 21 09:34 a.txt
ln默认情况创建一个硬链接文件就是对原文件创建一个硬链接文件
作用 ls -i看inode结点号
[chenyongjie@localhost wenjian]$ ls -i
68809622 a.hard 68809622 a.txt
两个inode结点一样,刚开始创建a.txt链接束为1但是创建硬链接后链接束变为2了
inode结点一样代表用的同一个节点,在硬盘上指向了同一个数据区域,也可以说明这个文件是同一个文件(这个文件有两个名字而已)和原文没有区别相当于文件的别名
创建一个软链接文件ln -s创建一个软链接文件
$ ln -s a.txt a.soft
[chenyongjie@localhost wenjian]$ ls
a.hard a.soft a.txt
lrwxrwxrwx. 1 chenyongjie chenyongjie 5 4月 21 09:45 a.soft -> a.txt
-rw-rw-r–. 2 chenyongjie chenyongjie 0 4月 21 09:34 a.txt
符号链接文件是l第一个l代表符号链接文件以l开头
a.soft指向了a.txt相当于a.txt的快捷方式
n]$ echo “nihao…” >> a.txt
[chenyongjie@localhost wenjian]$ cat a.txt
nihao…
[chenyongjie@localhost wenjian]$ cat a.hard
nihao…
[chenyongjie@localhost wenjian]$ cat a.soft
nihao…
$ echo “hellow” >>a.soft
[chenyongjie@localhost wenjian]$ cat a.txt
nihao…
hellow
[chenyongjie@localhost wenjian]$ cat a.hard
nihao…
hellow
[chenyongjie@localhost wenjian]$ cat a.soft
nihao…
hellow
ls -i
68809622 a.hard 68809623 a.soft 68809622 a.txt
软链接文件的inode结点和原文件的inode结点不一样是一个独立的文件
所以a.soft存储的是a.txt的名字
ln -s …/wenjian/a.txt b.soft
[chenyongjie@localhost wenjian]$ ll
总用量 8
-rw-rw-ir–. 2 chenyongjie chenyongjie 15 4月 21 09:51 a.hard
lrwxrwxrwx. 1 chenyongjie chenyongjie 5 4月 21 09:45 a.soft -> a.txt
-rw-rw-r–. 2 chenyongjie chenyongjie 16 4月 21 09:51 a.txt
lrwxrwxrwx. 1 chenyongjie chenyongjie 15 4月 21 09:56 b.soft -> …/wenjian/a.txt
a.soft 5个字节 b.soft15个字节,5个字节是a.soft文件的大小
符号链接文件记录的是源文件的路径名作用,当操作b.soft,在b.soft数据区域找到a.txt的路径然后访问目录项信息,然后获取a.txt的inode结点进而获得a.txt中的数据
在这里插入图片描述
绿色线为访问,
链接数表示文件有多少个硬链接文件,在删除一个文件的时候,目录项从目录中移除将链接数减1,当链接数为0时候操作系统会认为要删除这个文件,才会删除文件,否则只是减去链接数而已
[chenyongjie@localhost wenjian]$ rm a.txt
[chenyongjie@localhost wenjian]$ ls
a.hard a.soft b.soft
[chenyongjie@localhost wenjian]$ cat a.hard
nihao…
hellow
[chenyongjie@localhost wenjian]$ cat a.soft
cat: a.soft: 没有那个文件或目录
[chenyongjie@localhost wenjian]$ touch a.txt
[chenyongjie@localhost wenjian]$ cat a.soft
[chenyongjie@localhost wenjian]$ cat a.hard
nihao…
hellow
总结:
创建硬链接文件: ln a.txt a.hard
创建软链接文件: ln -s a.txt a.soft
软链接文件是一个独立的文件,像是一个源文件的快捷方式–inode结点号不同
硬链接文件是一个文件的另一个名字,跟源文件并没有什么区别–inode结点号相同
删除源文件,软链接失效(通过文件名查找源文件);
删除源文件硬链接无影响(通过inode结点找文件只是链接数减1)
软链接文件可以跨区建立但是硬链接不可以
软链接文件恶意针对目录进行创建,硬链接不可以
**静态库和动态库:**生成与使用
库文件:将很多文件代码打包到一起生成库
1>gcc -c a.c -o a.o
在这里插入图片描述
[chenyongjie@localhost lib]$ gcc b.c a.c -o main
发现编译通过了,没有报错,a.c没有定义printf函数但是因为这个程序使用这两个函数同时生成一个程序所以并没有报错直接找到函数的实现了,在b.h头文件声明
把b.c生成一个库,在a.c链接的时候使用,而并不是拿a.c和b.c生成一个可执行程序
在这里插入图片描述
gcc -c b.c -o b.o
[chenyongjie@localhost lib]$ ls
a.c b.c b.h b.o
把b.c生成为b.o,将b.o打包成库
打包动态库
动态库:动态链接链接的是动态库生成可执行程序的时候生成一张动态函数表(函数位置符号信息表),程序运行时候将动态库加载到内存当中,使用库当中的函数,动态库可以同时被多个程序使用,也叫共享库
而–share不是生成可执行程序而是生成一个共享库
lib前缀.so是动态库的后缀中间mytest是动态库的名字
gcc -share b.o -o libmytest.so
gcc: 错误:unrecognized command line option ‘-share’
[chenyongjie@localhost lib]$ gcc --share b.o -o libmytest.so
/usr/bin/ld: b.o: relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: 最后的链结失败: 输出不可表示的节
collect2: 错误:ld 返回 1
需要重新生成-o
gcc -fPIC -c b.c -o b.o
[chenyongjie@localhost lib]$ gcc --share b.o -o libmytest.so
$ ls
a.c b.c b.h b.o libmytest.so
-fPIC编译选项,生成自己的目标源文件需要的选项,就是产生位置无关代码
如果不加fPIC
gcc -c b.c -o c.o
objdump -S libmytest.so
0000000000000665 :
665: 55 push %rbp
666: 48 89 e5
发现print有地址如果在生成一个库的时候每一个函数都有自己的地址 意味着在最终映射的时候需要把这些地址映射到虚拟地址空间的指定位置,如果没有映射到指定位置会重新计算它的位置信息而且这段代码映射到共享区一旦地址固定,第一个程序映射的位置固定,下一个程序也得映射到这个位置,程序编译的时候链接动态库的时候将这些符号信息地址信息计算完毕,动态库加载到内存中,需要映射到每个程序的指定位置如果动态库函数的位置是固定的意味着在各个程序映射到每个程序共享区是十分困难,加上-fPIC产生未知无关代码,动态库的代码位置都是相对位置,值计算了个偏移量,这样动态库映射到程序的虚拟地址空间的时候映射到任何的位置都可以,只需要根据起始位置进行偏移就能找到它们的代码
–share是链接选项
生成静态链接库
ar命令 -cr(c创建静态库r是replace模块替换) libmytset
ar -cr libmytest.a b.o
[chenyongjie@localhost lib]$ ls
a.c b.c b.h b.o libmytest.a
ib]$ objdump -S libmytest.a
在归档文件 libmytest.a 中:

b.o: 文件格式 elf64-x86-64

Disassembly of section .text:

0000000000000000 :
0: 55
只有b.o文件,只有print这个函数
总结:
a.c b.c
生成动态库:gcc -fPIC -c b.c -o b.o gcc --share b.o libmytest.so
生成静态库: gcc -c b.c -o b.o ar -cr libmytest.a b.o
gcc:
-fPIC:产生位置无关代码
–share :生成一个共享库而不是可执行程序
ar:静态库打包指令
-c创建
-r 替换
使用:
库链接的位置在指定的位置下找的,在根目录下的lib64默认查找路径
[chenyongjie@localhost lib]$ ls /lib64/
ls /usr/也有lib64
1>拷贝库
2>创建软链接文件指向就可以了
3>修改环境变量
-L指定库的查找路径
gcc a.c -o main -L ./ -lmytest
//意味着当前库在当前路径下(./);意味着在编译链接这个库的时候会默认先去指定路径下找,没有找到在当前目录下找库文件
./main 发现symool lookup error: ./main :undefined symbol print
程序运行的时候没找到动态库动态库是运行时库,所以运行时候也需要库的存在,动态库运行的时候也需要在指定路径下
$ gcc a.c -o main -L ./ -lmytest
[chenyongjie@localhost lib]$ export LD_LIBRARY_PATH=.
[chenyongjie@localhost lib]$ ./main
b.c—
nihaoshijie
LD_LIBRARY_PATH程序运行时候动态库查找的路径
库的使用:(链接) —libmytest.so libmytest.a
gcc a.c -o main -lmytest 报错找不到库(链接时候找不到库,库的查找路径)
库文件默认查找路径在/lib64或者/usr/lib64
设置环境变量**:LIBRAY_PATH=.(库的链接路径)
使用选项 -L .**
因为gcc默认动态链接–因此使用动态库生成可执行程序
./main 运行报错—找不到库(运行时找不到库,–库的加载路径)
设置环境变量:**LD_LIBRAY_PATH=.(库的运行(加载)路径)
**
静态库:很多地方使用静态库升级性程序用动态库
当前目录下有静态库和动态库会优先用动态库

不要用gcc a.c -o main -L ./ -lmytest -static会让所有的库都变成静态库
所以先删除动态库然后gcc a.c -o child -L ./ -lmytest
rm libmytest.so
[chenyongjie@localhost lib]$ gcc a.c -o chlid -L ./ -lmytest
[chenyongjie@localhost lib]$ gcc --share b.o -o libmytest.so
[chenyongjie@localhost lib]$ gcc a.c -o main -L . -lmytest
[chenyongjie@localhost lib]$ ls
a.c b.c b.h b.o chlid libmytest.a libmytest.so main
ldd 查看可执行程序的链接信息
henyongjie@localhost lib]$ ldd main
linux-vdso.so.1 => (0x00007fff32dcd000)
libmytest.so => ./libmytest.so (0x00007f1762644000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1762277000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1762846000)
看到链接链接信息有libc.so.6(标准c库动态库)还链接了mytest.so(自己的动态库)
ldd chlid
linux-vdso.so.1 => (0x00007fff25730000)
libc.so.6 => /lib64/libc.so.6 (0x00007f102bb3e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f102bf0b000)
发现只链接了c库mytest没有链接
通常我们自己链接静态库生成可执行程序的时候并不是使用static静态库,而是将静态库房到指定路径下,gcc -L 选项指定库的链接路径链接静态库生成可执行程序
-static:作用是可执行程序使用静态链接生成不依赖任何动态库(不好会报错,任何库都用静态库),只是当前这个库使用静态库
libmytest.a libmytest.so main
[chenyongjie@localhost lib]$ export LD_LIBRARY_PATH=.
[chenyongjie@localhost lib]$ ./chlid
b.c—
nihaoshijie
mkdir lib
[chenyongjie@localhost lib]$ mv libmytest.* lib
[chenyongjie@localhost lib]$ mkdir inc
[chenyongjie@localhost lib]$ mv b.h inc/
[chenyongjie@localhost lib]$ ls
a.c b.c b.o chlid inc lib main
tree ./
./
|-- a.c
|-- b.c
|-- b.o
|-- chlid
|-- inc
| -- b.h |-- lib | |-- libmytest.a |libmytest.so
`-- main
通常一个目录分为src源码文件目录inc头文件目录,lib第三方库目录,etc配置文件目录
看到inc里面有b.h
gcc a.c -o main -L ./lib -lmytest
t lib]$ gcc a.c -o main -L ./lib -lmytest
a.c:2:15: 致命错误:b.h:没有那个文件或目录
#include “b.h”
^
编译中断。
[chenyongjie@localhost lib]$ gcc a.c -o main -I ./inc -L ./lib -lmytest
-I是指定头文件所在路径
gcc -L 指定库的搜索路径(链接选项)
-i指定链接库的名称(编译)
-I指定头文件搜索路径(链接选项)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值