注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

Linux内核中的文件描述符(三)--fd的回收  

2013-09-24 11:04:50|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
来源:Linux社区  作者:ce123

Kernel version:2.6.14

CPU architecture:ARM920T

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;
}

filp_close函数调用fput,在fput中调用release函数。

//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);
}

  评论这张
 
阅读(465)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017