1.4 关闭文件
1.4.1 close介绍
close用于关闭文件描述符。
而文件描述符可以是普通文件,也可以是设备,还可以是socket。在关闭时,VFS会根据不同的文件类型,执行不同的操作。
下面将通过跟踪close的内核源码来了解内核如何针对不同的文件类型执行不同的操作。
文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。
SYSCALL_DEFINE1(close, unsigned int, fd)
{
**struct file *** filp;
/*
得到当前进程的文件表 */
**struct files_struct *** files = current->files;
**struct fdtable ***fdt;
int retval;
spin_lock(&files->file_lock);
/*
通过文件表,取得文件描述符表*/
fdt = files_fdtable(files);
/*
**参数fd*大于文件描述符表记录的最大描述符,那么它一定是非法的描述符/
if (fd >= fdt->max_fds)
goto out_unlock;
/*
**利用fd作为索引,得到fil*e结构指针/
filp = fdt->fd[fd];
/*
检查filp是否为NULL。正常情况下,filp一定不为NULL。*/
if (!filp)
goto out_unlock;
/* 将对应的filp置为
0*/
rcu_assign_pointer(fdt->fd[fd], NULL);
/* 清除
fd在close_on_exec位图中的位*/
FD_CLR(fd, fdt->close_on_exec);
/* 释放该
fd,或者说将其置为unused。*/
put_unused_fd(files, fd);
spin_unlock(&files->file_lock);
/* 关闭
file结构 */
retval = filp_close(filp, files);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK))
retval = -