虛擬文件系統[5]

 

    文件對象表示進程已打開的文件。進程直接處理的是文件,而不是超級塊、索引節點或目錄項。

    文件對象是已打開文件在內存的表示。該對象(不是物理文件)由相應的open()系統調用創建,由close()系統調用銷燬,所有這些文件相關的調用實際上都是文件操作表中定義的方法。

    因爲多個進程可以同時打開和操作同一個文件,所以同一個文件也可能存在多個對應的文件對象。文件對象僅僅在進程觀點上代表已打開的文件,它反過來指向目錄項對象(目錄項對象反過來指向索引節點),其實只有目錄項對象才表示已打開的實際文件。雖然一個文件對應的文件對象不是唯一的,但對應的索引節點和目錄項對象是唯一的。

   文件對象由file結構體表示:

 

  1. 在<Fs.h(include/linux)>中
  2. struct file {
  3.     /*
  4.      * fu_list becomes invalid after file_free is called and queued via
  5.      * fu_rcuhead for RCU freeing
  6.      */
  7.     union {
  8.         struct list_head    fu_list;
  9.         struct rcu_head     fu_rcuhead;
  10.     } f_u;
  11.     struct path     f_path;
  12. #define f_dentry    f_path.dentry 
  13. #define f_vfsmnt    f_path.mnt 
  14.     const struct file_operations    *f_op;
  15.     atomic_t        f_count;
  16.     unsigned int        f_flags;
  17.     mode_t          f_mode;
  18.     loff_t          f_pos;
  19.     struct fown_struct  f_owner;
  20.     unsigned int        f_uid, f_gid;
  21.     struct file_ra_state    f_ra;
  22.     unsigned long       f_version;
  23. #ifdef CONFIG_SECURITY 
  24.     void            *f_security;
  25. #endif 
  26.     /* needed for tty driver, and maybe others */
  27.     void            *private_data;
  28. #ifdef CONFIG_EPOLL 
  29.     /* Used by fs/eventpoll.c to link all the hooks to this file */
  30.     struct list_head    f_ep_links;
  31.     spinlock_t      f_ep_lock;
  32. #endif /* #ifdef CONFIG_EPOLL */ 
  33.     struct address_space    *f_mapping;
  34. };

類似於目錄項對象,文件對象實際上沒有對應的磁盤數據。所以在結構體中沒有代表其對象是否爲髒,是否需要寫回磁盤的標誌。文件對象通過f_dentry指針執行相關的目錄項對象。目錄項會執行相關的索引節點,索引節點會記錄文件是否爲髒。

  • 文件操作

  1. /*
  2.  * NOTE:
  3.  * read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
  4.  * can be called without the big kernel lock held in all filesystems.
  5.  */
  6. struct file_operations {
  7.     struct module *owner;
  8. /*該函數用於更新偏移量指針。由系統調用llseek()調用它*/
  9.     loff_t (*llseek) (struct file *, loff_t, int);
  10. /*該函數從給定文件的偏移處讀取第三個參數指定大小的字節數據到第二個參數指定的緩衝中,同時更新文件指針。由系統調用read()調用它。*/
  11.     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
  12. /*該函數從給定的緩衝區中取出指定字節的數據寫入指定文件的偏移處,同時更新文件指針。由系統調用write()調用它。*/
  13.     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
  14. /*該函數從第一個參數指定的文件中,以同步方式讀取指定字節的數據到緩衝區中。由系統調用ait_read()調用它*/
  15.     ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
  16. /*該函數以同步方式從給定的緩衝區中取出指定字節的數據,寫入第一個參數指定的文件中。由系統調用aio_write()調用它*/
  17.     ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
  18. /*該函數返回目錄列表中的下一個目錄。由系統調用readdir()調用它。*/
  19.     int (*readdir) (struct file *, void *, filldir_t);
  20. /*該函數睡眠等待給定文件的活動。由系統調用poll()調用它*/
  21.     unsigned int (*poll) (struct file *, struct poll_table_struct *);
  22. /*該函數用來給設備發送命令參數對。當文件是一個被打開的設備節點時,可以通過它進行設置操作。由系統調用ioctl()調用它。*/
  23.     int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
  24. /*該函數*/
  25.     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
  26. /**/
  27.     long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
  28. /*該函數將給定的文件映射到指定的地址空間上。由系統調用mmap()調用它*/
  29.    int (*mmap) (struct file *, struct vm_area_struct *);
  30. /*該函數創建一個新的文件對象,並將它和相應索引節點對象關聯起來。由系統調用open()調用它*/
  31.     int (*open) (struct inode *, struct file *);
  32. /*當已打開文件的引用計數減少時,該函數被VFS調用。它的作用根據具體文件系統而定*/
  33.     int (*flush) (struct file *, fl_owner_t id);
  34. /*當文件的最後一個引用被註銷時,該函數會被VFS調用。它的作用根據具體文件系統而定*/
  35.    int (*release) (struct inode *, struct file *);
  36. /*將給定文件的所有被緩存的數據寫回磁盤。該函數由fsync()調用*/
  37.    int (*fsync) (struct file *, struct dentry *, int datasync);
  38. /*將第一個參數指定的文件的所有被緩存數據寫回到磁盤。該函數由系統調用aio_fsync()調用*/
  39.     int (*aio_fsync) (struct kiocb *, int datasync);
  40. /*該函數用於打開或關閉異步I/O的通告信號*/
  41.     int (*fasync) (intstruct file *, int);
  42. /*該函數用於給指定文件上鎖*/
  43.     int (*lock) (struct file *, intstruct file_lock *);
  44. /*該函數用於從一個文件拷貝數據到另一個文件中,它執行的拷貝操作完全在內核中完成,避免了向用戶空間進行不必要的拷貝。由系統調用sendfile()調用*/
  45.     ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
  46. /*該函數用來從一個文件向另一個文件發送數據*/
  47.     ssize_t (*sendpage) (struct file *, struct page *, intsize_t, loff_t *, int);
  48. /*該函數用於獲取未使用的地址空間來映射給定的文件*/
  49.     unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
  50. /*當給出SETFL命令時,這個函數用來檢查傳遞給fcntl()系統調用的標誌的有效性。*/
  51.     int (*check_flags)(int);
  52. /**/
  53.     int (*dir_notify)(struct file *filp, unsigned long arg);
  54. /*該函數用來實現flock()系統調用,該調用提供忠告鎖*/
  55.     int (*flock) (struct file *, intstruct file_lock *);
  56. /**/
  57.     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
  58. /**/
  59.     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
  60. };

 

   具體的文件系統可以爲每一種操作做專門的實現,如果存在通用操作,也可以使用通用操作。

發佈了79 篇原創文章 · 獲贊 6 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章