linux內(nèi)核中的文件描述符(三)--fd的回收
CPU architecture:ARM920T
本文引用地址:http://m.butianyuan.cn/article/201611/319999.htmAuthor:ce123(http://blog.csdn.net/ce123)
1.close函數(shù)
上圖說(shuō)明了close(fd)的執(zhí)行過(guò)程,主要包括兩部分:釋放文件描述符fd,關(guān)閉文件file。
[plain]view plaincopyprint?
- //fs/open.c
- asmlinkagelongsys_close(unsignedintfd)
- {
- structfile*filp;
- structfiles_struct*files=current->files;//獲得當(dāng)前進(jìn)程的files結(jié)構(gòu)
- structfdtable*fdt;
- spin_lock(&files->file_lock);
- fdt=files_fdtable(files);//通過(guò)進(jìn)程的打開(kāi)文件列表獲得文件描述符位圖結(jié)構(gòu)
- if(fd>=fdt->max_fds)
- gotoout_unlock;
- filp=fdt->fd[fd];
- if(!filp)
- gotoout_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);
- returnfilp_close(filp,files);//關(guān)閉文件
- out_unlock:
- spin_unlock(&files->file_lock);
- return-EBADF;
- }
2.釋放文件描述符__put_unused_fd
[plain]view plaincopyprint?
- staticinlinevoid__put_unused_fd(structfiles_struct*files,unsignedintfd)
- {
- structfdtable*fdt=files_fdtable(files);
- __FD_CLR(fd,fdt->open_fds);//清除位圖中的相應(yīng)標(biāo)記
- if(fd
next_fd) - fdt->next_fd=fd;//如果釋放的fd小于next_fd,則next_fd=fd,下次分配從next_fd開(kāi)始。
- //因此釋放一個(gè)fd后,再打開(kāi)或創(chuàng)建一個(gè)文件放回的可能還是剛釋放的fd
- }
3.關(guān)閉文件filp_close
[plain]view plaincopyprint?
- intfilp_close(structfile*filp,fl_owner_tid)
- {
- intretval=0;
- if(!file_count(filp)){
- printk(KERN_ERR"VFS:Close:filecountis0n");
- return0;
- }
- 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);
- returnretval;
- }
[plain]view plaincopyprint?
- //fs/file_table.c
- voidfastcallfput(structfile*file)
- {
- if(rcuref_dec_and_test(&file->f_count))
- __fput(file);
- }
- voidfastcall__fput(structfile*file)
- {
- structdentry*dentry=file->f_dentry;
- structvfsmount*mnt=file->f_vfsmnt;
- structinode*inode=dentry->d_inode;
- might_sleep();
- fsnotify_close(file);
- /*
- *Thefunctioneventpoll_release()shouldbethefirstcalled
- *inthefilecleanupchain.
- */
- eventpoll_release(file);
- locks_remove_flock(file);
- if(file->f_op&&file->f_op->release)
- file->f_op->release(inode,file);//在這里調(diào)用release函數(shù)。在socket中即socket_close函數(shù)
- 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);
- }
評(píng)論