<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux內(nèi)核中的文件描述符(三)--fd的回收

          linux內(nèi)核中的文件描述符(三)--fd的回收

          作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          Kernel version:2.6.14

          CPU architecture:ARM920T

          本文引用地址:http://www.ex-cimer.com/article/201611/319999.htm

          Author:ce123(http://blog.csdn.net/ce123)

          1.close函數(shù)

          上圖說明了close(fd)的執(zhí)行過程,主要包括兩部分:釋放文件描述符fd,關(guān)閉文件file。

          [plain]view plaincopy
          print?
          1. //fs/open.c
          2. asmlinkagelongsys_close(unsignedintfd)
          3. {
          4. structfile*filp;
          5. structfiles_struct*files=current->files;//獲得當(dāng)前進(jìn)程的files結(jié)構(gòu)
          6. structfdtable*fdt;
          7. spin_lock(&files->file_lock);
          8. fdt=files_fdtable(files);//通過進(jìn)程的打開文件列表獲得文件描述符位圖結(jié)構(gòu)
          9. if(fd>=fdt->max_fds)
          10. gotoout_unlock;
          11. filp=fdt->fd[fd];
          12. if(!filp)
          13. gotoout_unlock;
          14. rcu_assign_pointer(fdt->fd[fd],NULL);
          15. FD_CLR(fd,fdt->close_on_exec);
          16. __put_unused_fd(files,fd);//釋放文件描述符
          17. spin_unlock(&files->file_lock);
          18. returnfilp_close(filp,files);//關(guān)閉文件
          19. out_unlock:
          20. spin_unlock(&files->file_lock);
          21. return-EBADF;
          22. }

          2.釋放文件描述符__put_unused_fd

          [plain]view plaincopy
          print?
          1. staticinlinevoid__put_unused_fd(structfiles_struct*files,unsignedintfd)
          2. {
          3. structfdtable*fdt=files_fdtable(files);
          4. __FD_CLR(fd,fdt->open_fds);//清除位圖中的相應(yīng)標(biāo)記
          5. if(fdnext_fd)
          6. fdt->next_fd=fd;//如果釋放的fd小于next_fd,則next_fd=fd,下次分配從next_fd開始。
          7. //因此釋放一個fd后,再打開或創(chuàng)建一個文件放回的可能還是剛釋放的fd
          8. }

          3.關(guān)閉文件filp_close

          [plain]view plaincopy
          print?
          1. intfilp_close(structfile*filp,fl_owner_tid)
          2. {
          3. intretval=0;
          4. if(!file_count(filp)){
          5. printk(KERN_ERR"VFS:Close:filecountis0n");
          6. return0;
          7. }
          8. if(filp->f_op&&filp->f_op->flush)
          9. retval=filp->f_op->flush(filp);
          10. dnotify_flush(filp,id);
          11. locks_remove_posix(filp,id);
          12. fput(filp);
          13. returnretval;
          14. }
          filp_close函數(shù)調(diào)用fput,在fput中調(diào)用release函數(shù)。
          [plain]view plaincopy
          print?
          1. //fs/file_table.c
          2. voidfastcallfput(structfile*file)
          3. {
          4. if(rcuref_dec_and_test(&file->f_count))
          5. __fput(file);
          6. }
          7. voidfastcall__fput(structfile*file)
          8. {
          9. structdentry*dentry=file->f_dentry;
          10. structvfsmount*mnt=file->f_vfsmnt;
          11. structinode*inode=dentry->d_inode;
          12. might_sleep();
          13. fsnotify_close(file);
          14. /*
          15. *Thefunctioneventpoll_release()shouldbethefirstcalled
          16. *inthefilecleanupchain.
          17. */
          18. eventpoll_release(file);
          19. locks_remove_flock(file);
          20. if(file->f_op&&file->f_op->release)
          21. file->f_op->release(inode,file);//在這里調(diào)用release函數(shù)。在socket中即socket_close函數(shù)
          22. security_file_free(file);
          23. if(unlikely(inode->i_cdev!=NULL))
          24. cdev_put(inode->i_cdev);
          25. fops_put(file->f_op);
          26. if(file->f_mode&FMODE_WRITE)
          27. put_write_access(inode);
          28. file_kill(file);
          29. file->f_dentry=NULL;
          30. file->f_vfsmnt=NULL;
          31. file_free(file);
          32. dput(dentry);
          33. mntput(mnt);
          34. }



          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();