第三章:字符设备驱动-10:open and release--release

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 系统调用,自动关闭所有文件。

补充说明:

  1. release 与 close 的核心区别

    行为触发时机调用次数驱动关注点
    close 系统调用用户显式调用 close(fd) 或进程退出与 dup/fork 产生的副本数一致(可能多次)无需处理,由内核管理
    release 方法file 结构引用计数降至 0(最后一次关闭)与 open 调用次数严格一致(一对一)必须在此释放资源
  2. 需要实现 release 的典型场景

    基础版 scull 因无资源需要释放而简化了 release,但真实驱动通常需要在此完成:

    1. 重置设备状态(如清空硬件寄存器、释放锁资源)。

    2. 关闭硬件设备(如断开 USB 连接、关闭传感器电源);

    3. 释放 open 时分配的 private_data 内存(如动态申请的缓冲区);

  3. 示例:带资源释放的 release 实现

    1. 若 scull 驱动动态分配了 private_datarelease 应这样实现:

      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;
      }
      
  4. 进程异常退出时的资源保障

    即使进程因崩溃或信号终止而未调用 close,内核也会在进程销毁时自动触发 release 方法,确保驱动有机会释放资源,避免内存泄漏或硬件状态异常。


    技术交流,欢迎加入社区:GPUers

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeeplyMind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值