CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
1.close函数
上图说明了close(fd)的执行过程,主要包括两部分:释放文件描述符fd,关闭文件file。
- //fs/open.c
- asmlinkage long sys_close(unsigned int fd)
- {
- struct file * filp;
- struct files_struct *files = current->files;//获得当前进程的files结构
- struct fdtable *fdt;
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);//通过进程的打开文件列表获得文件描述符位图结构
- if (fd >= fdt->max_fds)
- goto out_unlock;
- filp = fdt->fd[fd];
- if (!filp)
- goto out_unlock;
- rcu_assign_pointer(fdt->fd[fd], NULL);
- FD_CLR(fd, fdt->close_on_exec);
- __put_unused_fd(files, fd);//释放文件描述符
- spin_unlock(&files->file_lock);
- return filp_close(filp, files);//关闭文件
- out_unlock:
- spin_unlock(&files->file_lock);
- return -EBADF;
- }
2.释放文件描述符__put_unused_fd
- static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
- {
- struct fdtable *fdt = files_fdtable(files);
- __FD_CLR(fd, fdt->open_fds);//清除位图中的相应标记
- if (fd < fdt->next_fd)
- fdt->next_fd = fd;//如果释放的fd小于next_fd,则next_fd = fd,下次分配从next_fd开始。
- //因此释放一个fd后,再打开或创建一个文件放回的可能还是刚释放的fd
- }
3.关闭文件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;
- }
- if (filp->f_op && filp->f_op->flush)
- retval = filp->f_op->flush(filp);
- dnotify_flush(filp, id);
- locks_remove_posix(filp, id);
- fput(filp);
- return retval;
- }
- //fs/file_table.c
- void fastcall fput(struct file *file)
- {
- if (rcuref_dec_and_test(&file->f_count))
- __fput(file);
- }
- void fastcall __fput(struct file *file)
- {
- struct dentry *dentry = file->f_dentry;
- struct vfsmount *mnt = file->f_vfsmnt;
- struct inode *inode = dentry->d_inode;
- might_sleep();
- fsnotify_close(file);
- /*
- * The function eventpoll_release() should be the first called
- * in the file cleanup chain.
- */
- eventpoll_release(file);
- locks_remove_flock(file);
- if (file->f_op && file->f_op->release)
- file->f_op->release(inode, file);//在这里调用release函数。在socket中即socket_close函数
- security_file_free(file);
- if (unlikely(inode->i_cdev != NULL))
- cdev_put(inode->i_cdev);
- fops_put(file->f_op);
- if (file->f_mode & FMODE_WRITE)
- put_write_access(inode);
- file_kill(file);
- file->f_dentry = NULL;
- file->f_vfsmnt = NULL;
- file_free(file);
- dput(dentry);
- mntput(mnt);
- }
上一篇:linux内核中的文件描述符(四)--fd的分配--get_unused_fd
下一篇:linux内核中的文件描述符(二)--socket和文件描述符
推荐阅读最新更新时间:2024-03-16 14:45