close分析

大家可以使用以下函数关闭一个文件,无论是字符设备文件还是已经挂载好的文件系统中的文件:

int close(int fd);

其中close这个函数就是使用了close函数进行系统调用,其系统调用为:

SYSCALL_DEFINE1(close, unsigned int, fd)
{int retval = __close_fd(current->files, fd);/* can't restart close syscall because file table entry was cleared */if (unlikely(retval == -ERESTARTSYS ||retval == -ERESTARTNOINTR ||retval == -ERESTARTNOHAND ||retval == -ERESTART_RESTARTBLOCK))retval = -EINTR;return retval;
}

其主要使用__close_fd函数进行关闭:

int __close_fd(struct files_struct *files, unsigned fd)
{struct file *file;struct fdtable *fdt;spin_lock(&files->file_lock);//上锁//获取文件描述符位图fdt = files_fdtable(files);if (fd >= fdt->max_fds)goto out_unlock;file = fdt->fd[fd];//获取文件file结构体if (!file)goto out_unlock;//让fd指向空,就是把fd移出rcurcu_assign_pointer(fdt->fd[fd], NULL);//清理fd对应的文件位图__put_unused_fd(files, fd);spin_unlock(&files->file_lock);return filp_close(file, files);//关闭文件out_unlock:spin_unlock(&files->file_lock);return -EBADF;
}

__close_fd首先获取文件描述符位图和文件file结构体指针,然后把d移出rcu和清理fd对应的文件位图,最后通过filp_close函数关闭文件。我们现在看看filp_close:

int filp_close(struct file *filp, fl_owner_t id)
{int retval = 0;if (!file_count(filp)) {printk(KERN_ERR "VFS: Close: file count is 0\n");return 0;}//调用file的flush函数,如果是字符驱动就调用字符驱动的函数,//如果是普通文件就根据文件系统类型调用其flush函数if (filp->f_op->flush)retval = filp->f_op->flush(filp, id);if (likely(!(filp->f_mode & FMODE_PATH))) {dnotify_flush(filp, id);locks_remove_posix(filp, id);}fput(filp);//回调释放filp实例return retval;
}

filp_close首先会调用file结构体的flush函数,然后通过fput回调释放filp实例。fput会初始化一个任务,这个任务是____fput,我们会在关闭的时候回调____fput。
fput函数,文件在fs/file_table.c:

void fput(struct file *file)
{if (atomic_long_dec_and_test(&file->f_count)) {struct task_struct *task = current;if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {init_task_work(&file->f_u.fu_rcuhead, ____fput);if (!task_work_add(task, &file->f_u.fu_rcuhead, true))return;/** After this task has run exit_task_work(),* task_work_add() will fail.  Fall through to delayed* fput to avoid leaking *file.*/}if (llist_add(&file->f_u.fu_llist, &delayed_fput_list))schedule_delayed_work(&delayed_fput_work, 1);}
}static void ____fput(struct callback_head *work)
{__fput(container_of(work, struct file, f_u.fu_rcuhead));
}

fput函数会调用____fput,而最终调用的是__fput函数。

static void __fput(struct file *file)
{struct dentry *dentry = file->f_path.dentry;struct vfsmount *mnt = file->f_path.mnt;struct inode *inode = file->f_inode;if (unlikely(!(file->f_mode & FMODE_OPENED)))goto out;might_sleep();fsnotify_close(file);//通知关闭文件事件,进程可以使用inotify监视文件的事件/** The function eventpoll_release() should be the first called* in the file cleanup chain.*///如果进程使用eventpoll监听文件系统的事件,那么把文件从eventpoll中删除eventpoll_release(file);locks_remove_file(file);//如果进程持有文件锁,那么释放文件锁ima_file_free(file);if (unlikely(file->f_flags & FASYNC)) {if (file->f_op->fasync)file->f_op->fasync(-1, file, 0);}//调用具体文件系统类型的release函数if (file->f_op->release)file->f_op->release(inode, file);if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&!(file->f_mode & FMODE_PATH))) {cdev_put(inode->i_cdev);}fops_put(file->f_op);//把文件操作结合结构体引用计数减一//解除file实例和目录项,挂载描述符以及索引节点的关联put_pid(file->f_owner.pid);if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)i_readcount_dec(inode);if (file->f_mode & FMODE_WRITER) {put_write_access(inode);__mnt_drop_write(mnt);}dput(dentry);//释放目录项mntput(mnt);//释放挂载描述符
out:file_free(file);
}

linux虚拟文件系统(六)-文件关闭操作分析相关推荐

  1. 网络与IO知识扫盲(一):Linux虚拟文件系统,文件描述符,IO重定向

    系统IO原理 在 Linux 中: VFS(Virtual Filesystem Switch):虚拟文件系统,是一个目录树.树上不同的节点可以映射到物理的文件地址,可以挂载. 相当于一个解耦层,在具 ...

  2. Linux虚拟文件系统、文件描述符、管道

    在Linux中,所有内容都是以文件的形式保存和管理的,即一切皆文件,普通文件是文件,目录(Windows下称为文件夹)是文件,硬件设备(键盘.监视器.硬盘.打印机等)都是文件,就连套接字(socket ...

  3. linux 目录防篡改,一种基于Linux虚拟文件系统的防篡改方法及系统的制作方法

    一种基于Linux虚拟文件系统的防篡改方法及系统的制作方法 [技术领域] [0001]本发明涉及文件防护技术领域,特别涉及一种基于Linux虚拟文件系统的防篡改方法及系统. [背景技术] [0002] ...

  4. Linux虚拟文件系统:数据结构与文件系统注册、文件打开读写

    数据结构 超级块 - super_block 索引节点 - inode 目录项 - dentry 文件结构 - file 虚拟文件系统实现 注册文件系统 - register_filesystem 打 ...

  5. linux 文件系统 vfs,linux虚拟文件系统vfs

    <操作系统>课程设计报告课程设计题目:操作系统课程设计 设计时间:2016/1/10一. 课程设计目的与要求需要完成的内容:(1) 安装虚拟机:Vmware.Vmware palyer ( ...

  6. Linux虚拟文件系统

    从文件 I/O 看 Linux 的虚拟文件系统 1 引言 Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等.通过使用同一套文件 I/O 系统 调用即可对 Linux ...

  7. Linux 虚拟文件系统四大对象:超级块、inode、dentry、file之间关系

    一:文件系统 1. 什么是文件系统? 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统. 通常文件系统是用于存储和组织文件的一种机制,便于对文件进行方便的查找与访问. 文件系统 ...

  8. linux虚拟文件系统浅析

    linux虚拟文件系统浅析 虚拟文件系统(VFS) 在我看来, "虚拟"二字主要有两层含义: 1, 在同一个目录结构中, 可以挂载着若干种不同的文件系统. VFS隐藏了它们的实现细 ...

  9. Linux 虚拟文件系统(一)概述

    Linux 虚拟文件系统(一)概述 tags: Linux源码 Linux 虚拟文件系统一概述 文章梗概 正文 文件系统 虚拟文件系统架构 虚拟文件系统如何知道可用的文件系统有哪些的 不太喜欢的环节 ...

  10. Linux虚拟文件系统vfs与文件操作始末

    虚拟文件系统(vfs)是Linux内核的子系统,其设计目的是对用户层(系统调用)屏蔽底层(各特定文件系统)实现的复杂性,对底层提供统一的接口与数据结构,使得能衔接各个特定文件系统(如ext2.ext3 ...

最新文章

  1. python安装方法32位_Python-3.9.0 安装教程【64位/32位】
  2. 什么样的鼠标对程序员最有用,超级提高开发效率
  3. abap 函数远程启用的模块参数_SAP AMDP介绍 - ABAP托管的HANA数据库过程
  4. 作者:季统凯(1972-),男,博士,中国科学院云计算产业技术创新与育成中心研究员...
  5. Spring Cloud微服务之公共服务模块抽取(五)
  6. 【Python五篇慢慢弹】快速上手学python
  7. python之路--小数据池,再谈编码,is和 == 的区别
  8. python安装-Python安装
  9. 01-编写CMS注意事项
  10. 手机在线编程软件Anycodes
  11. c语言里除法符号,c语言整除符号(c语言switch用法举例)
  12. [RPA之家]UiPath程序设计文档
  13. 国际化地区语言码对照表(i18n)
  14. vscode任务栏图标突然不显示
  15. Loadrunner 接口测试方法
  16. JavaScript实现在HTML中的粒子文字特效
  17. 小牛的net程序开发之路
  18. 关于JDK8安装遇到1335问题
  19. Docker——Tomcat部署
  20. jmp指令流程图怎么写_应用程序里的指令可以分成向操作系统请求特定的服务和什么?-常见问题...

热门文章

  1. H3C vrrp *** ipsec 基本配置
  2. Java SE 6之GUI:让界面更加绚丽(下)
  3. C# 打开文件 保存文件
  4. Android系统--输入系统(八)Reader线程_使用EventHub读取事件
  5. 【Java】javaWeb中的三大组件与八大监听器
  6. DateTimeFormatter,时间格式化与解析日期或时间
  7. 设计模式之单例模式8种实现方式,其五:懒汉式(线程不安全,同步代码块)
  8. Tomcat的startup.bat启动闪退解决办法
  9. java中的泛型是什么_Java中泛型是什么?Java泛型的详细介绍
  10. 抽取JDBC工具类:JDBCUtils