最近由于在我们的文件系统中需要实现posix文件锁,因此研究了下linux内核和gluster的文件锁的实现的代码。主要关注posix文件锁。整理了相关的学习内容,概念方面主要摘自网络和将系统内核的两本书(《linux内核深入理解》和《内核情景分析》)。代码部分参考了书的描述,然后阅读了相关代码。
主要参考网址,请搜索《Linux 2.6 中的文件锁》
1 基本概念
1.1 锁的类型
按读写特性:共享锁(读锁)和排它锁(写锁)
按锁的工作方式:强制锁、劝告锁、共享模式锁、租借锁
1.1.1 劝告锁
内核只提供加锁以及检测文件是否已经加锁的方法,但不参与锁的控制和协调。如果有进程不遵守“游戏规则”,不检查目标文件是否已经由别的进程加了锁就往其中写入数据,那么内核是不会阻拦的。
1.1.2 强制锁
当有系统调用 open()、read() 以及write() 发生的时候,内核都要检查并确保这些系统调用不会违反在所访问文件上加的强制锁约束。Unlink不会受到强制锁的影响。
当进程对文件进行了读或写这样的系统调用时,系统则会检查该文件已经到加强制锁时,会判断文件的状态O_NONBLOCK 标识,如果设置了 O_NONBLOCK,则该进程会出错eagain返回;否则,该进程被阻塞
O_NONBLOCK 标识设置方式是通过fcntl传递参数F_SETFL。
系统支持强制锁的配置:
-
Mount –o mand设置文件系统是否支持强制锁(super_block结构中s_flags设置为0或1)
-
修改要加强制锁的文件的权限:设置 SGID 位,并清除组可执行位。
1.2 锁的释放
-
进程对某个文件拥有的各种锁会在文件对应的文件描述符被关闭时自动清除;
-
进程运行结束后,其所加的各种锁也会自动清除。
1.3 锁的继承
-
由fork产生的子进程不会继承父进程的文件锁;
-
在执行exec之后,新程序可以继承原来程序的文件锁。
2 系统调用