新聞中心

        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.104case.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;//獲得當前進程的files結(jié)構(gòu)
        6. structfdtable*fdt;
        7. spin_lock(&files->file_lock);
        8. fdt=files_fdtable(files);//通過進程的打開文件列表獲得文件描述符位圖結(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)標記
        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)閉
        主站蜘蛛池模板: 同仁县| 白水县| 宜章县| 清水河县| 突泉县| 丰台区| 阜城县| 怀来县| 德阳市| 宁蒗| 华容县| 新巴尔虎左旗| 通江县| 蒙阴县| 鹤山市| 乌苏市| 维西| 英吉沙县| 咸宁市| 东安县| 绥阳县| 崇州市| 齐河县| 濉溪县| 九江县| 杭锦后旗| 大洼县| 隆化县| 鄂托克旗| 阿荣旗| 富蕴县| 平昌县| 长宁区| 通渭县| 全州县| 石河子市| 富顺县| 贵南县| 涿州市| 渝北区| 沙河市|