In continuation of the previous text第三章:字符设备驱动-9:open and release--open, let's GO ahead.
The release Method
The role of the release method is the reverse of open. Sometimes you’ll find that the method implementation is called device_close instead of device_release. Either way, the device method should perform the following tasks:
• Deallocate anything that open allocated in filp->private_data
• Shut down the device on last close
The basic form of scull has no hardware to shut down, so the code required isminimal:
release 方法的作用与 open 相反。有时你会发现该方法的实现被命名为 device_close 而非 device_release,但无论名称如何,这个设备方法应完成以下任务:
-
释放
open方法在filp->private_data中分配的所有资源 -
在最后一次关闭时关闭设备
基础版 scull 没有需要关闭的硬件,因此其实现代码非常简洁:
int scull_release(struct inode *inode, struct file *filp)
{
return 0;
}
You may be wondering what happens when a device file is closed more times than it is opened. After all, the dup and fork system calls create copies of open files without calling open; each of those copies is then closed at program termination. For example, most programs don’t open their stdin file (or device), but all of them end up closing it. How does a driver know when an open device file has really been closed?
你可能会疑惑:当设备文件被关闭的次数多于打开的次数时,会发生什么?毕竟,dup 和 fork 系统调用会创建已打开文件的副本,而无需调用 open;这些副本都会在程序终止时被关闭。例如,大多数程序不会打开它们的 stdin 文件(或设备),但最终都会关闭它。驱动如何知道一个已打开的设备文件何时被真正关闭呢?
The answer is simple: not every close system call causes the release method to be invoked. Only the calls that actually release the device data structure invoke the method—hence its name. The kernel keeps a counter of how many times a file structure is being used. Neither fork nor dup creates a new file structure (only open does that); they just increment the counter in the existing structure. The close system call executes the release method only when the counter for the file structure drops to 0, which happens when the structure is destroyed. This relationship between the release method and the close system call guarantees that your driver sees only one release call for each open.
答案很简单:并非每次 close 系统调用都会触发 release 方法。只有当调用确实会释放设备数据结构时,才会调用该方法 —— 这也是它得名 “release” 的原因。内核会维护一个计数器,记录 file 结构被使用的次数:fork 和 dup 都不会创建新的 file 结构(只有 open 会),它们只会增加现有结构的计数器。只有当 file 结构的计数器降至 0(即结构被销毁)时,close 系统调用才会执行 release 方法。release 方法与 close 系统调用之间的这种关系,保证了驱动每处理一次 open,只会对应一次 release 调用。
Note that the flush method is called every time an application calls close. However, very few drivers implement flush, because usually there’s nothing to perform at close time unless release is involved.
As you may imagine, the previous discussion applies even when the application terminates without explicitly closing its open files: the kernel automatically closes any file at process exit time by internally using the close system call.
注意,flush 方法会在应用程序每次调用 close 时被调用。但很少有驱动会实现 flush,因为通常在关闭时没有什么需要执行的操作,除非涉及到 release。
可想而知,即使应用程序未显式关闭已打开的文件就终止,上述机制仍然适用:内核会在进程退出时通过内部调用 close 系统调用,自动关闭所有文件。
补充说明:
-
release与close的核心区别行为 触发时机 调用次数 驱动关注点 close系统调用用户显式调用 close(fd)或进程退出与 dup/fork产生的副本数一致(可能多次)无需处理,由内核管理 release方法file结构引用计数降至 0(最后一次关闭)与 open调用次数严格一致(一对一)必须在此释放资源 -
需要实现
release的典型场景基础版 scull 因无资源需要释放而简化了
release,但真实驱动通常需要在此完成:-
重置设备状态(如清空硬件寄存器、释放锁资源)。
-
关闭硬件设备(如断开 USB 连接、关闭传感器电源);
-
释放
open时分配的private_data内存(如动态申请的缓冲区);
-
-
示例:带资源释放的
release实现-
若 scull 驱动动态分配了
private_data,release应这样实现:int scull_release(struct inode *inode, struct file *filp) { struct scull_dev *dev = filp->private_data; // 释放 open 时为设备分配的额外资源 kfree(dev->extra_buffer); dev->extra_buffer = NULL; return 0; }
-
-
进程异常退出时的资源保障
即使进程因崩溃或信号终止而未调用
close,内核也会在进程销毁时自动触发release方法,确保驱动有机会释放资源,避免内存泄漏或硬件状态异常。
技术交流,欢迎加入社区:GPUers。

被折叠的 条评论
为什么被折叠?



