Linux--文件结构体struct file
生活随笔
收集整理的這篇文章主要介紹了
Linux--文件结构体struct file
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼:
struct file {?
struct file *f_next,**f_pprev;?
struct dentry *f_dentry;?
struct file_operations *f_op;?
mode_t f_mode;?
loff_t f_pos;?
unsigned int f_count,f_flags;?
unsigned long f_reada,f_ramax,f_raend,f_ralen,f_rawin;?
struct fown_struct f_owner;?
unsigned long f_version;?
void *private_data;?
}; ?
[cpp]?view plain?copy struct?file?{?? ????????/*? ?????????*?fu_list?becomes?invalid?after?file_free?is?called?and?queued?via? ?????????*?fu_rcuhead?for?RCU?freeing? ?????????*/?? ????????union?{?? ????????????????struct?list_head????????fu_list;?? ????????????????struct?rcu_head?????????fu_rcuhead;?? ????????}?f_u;?? ????????struct?path?????????????f_path;?? #define?f_dentry????????f_path.dentry?? #define?f_vfsmnt????????f_path.mnt?? ????????const?struct?file_operations????*f_op;?? ????????atomic_t????????????????f_count;?? ????????unsigned?int????????????f_flags;?? ????????mode_t??????????????????f_mode;?? ????????loff_t??????????????????f_pos;?? ????????struct?fown_struct??????f_owner;?? ????????unsigned?int????????????f_uid,?f_gid;?? ????????struct?file_ra_state????f_ra;?? ????????unsigned?long???????????f_version;?? #ifdef?CONFIG_SECURITY?? ????????void????????????????????*f_security;?? #endif?? ????????/*?needed?for?tty?driver,?and?maybe?others?*/?? ????????void????????????????????*private_data;?? #ifdef?CONFIG_EPOLL?? ????????/*?Used?by?fs/eventpoll.c?to?link?all?the?hooks?to?this?file?*/?? ????????struct?list_head????????f_ep_links;?? ????????spinlock_t??????????????f_ep_lock;?? #endif?/*?#ifdef?CONFIG_EPOLL?*/?? ????????struct?address_space????*f_mapping;?? };??
文件結構體代表一個打開的文件,系統中的每個打開的文件在內核空間都有一個關聯的struct file。它由內核在打開文件時創建,并傳遞給在文件上進行操作的任何函數。在文件的所有實例都關閉后,內核釋放這個數據結構。在內核創建和驅動源碼中,struct file的指針通常被命名為file或filp。一下是對結構中的每個數據成員的解釋:
一、
union {
? ? struct list_head fu_list;
? ? struct rcu_head rcuhead;
}f_u;
其中的struct list_head定義在 linux/include/linux/list.h中,原型為:
struct list_head {
? ?? ???struct list_head *next, *prev;
};
用于通用文件對象鏈表的指針。
struct rcu_head定義在linux/include/linux/rcupdate.h中,其原型為:
[cpp]?view plain?copy /**? *?struct?rcu_head?-?callback?structure?for?use?with?RCU? *?@next:?next?update?requests?in?a?list? *?@func:?actual?update?function?to?call?after?the?grace?period.? */?? struct?rcu_head?{?? ????????struct?rcu_head?*next;?? ????????void?(*func)(struct?rcu_head?*head);?? };??
RCU(Read-Copy Update)是Linux 2.6內核中新的鎖機制,具體在這里有介紹:
http://www.ibm.com/developerworks/cn/linux/l-rcu/
二、
struct path? ?? ?? ?? ? f_path;
被定義在linux/include/linux/namei.h中,其原型為:
struct path {
? ?? ???struct vfsmount *mnt;
? ?? ???struct dentry *dentry;
};
在早些版本的內核中并沒有此結構,而是直接將path的兩個數據成員作為struct file的數據成員,
struct vfsmount *mnt的作用是指出該文件的已安裝的文件系統,
struct dentry *dentry是與文件相關的目錄項對象。
三、
const struct file_operations? ? *f_op;
被定義在linux/include/linux/fs.h中,其中包含著與文件關聯的操作,如:
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
等。當打開一個文件時,內核就創建一個與該文件相關聯的struct file結構,其中的*f_op就指向的是
具體對該文件進行操作的函數。例如用戶調用系統調用read來讀取該文件的內容時,那么系統調用read最終會陷入內核調用sys_read函數,而sys_read最終會調用于該文件關聯的struct file結構中的f_op->read函數對文件內容進行讀取。
四、
atomic_t? ?? ?? ?? ?? ? f_count;
atomic_t被定義為:
typedef struct { volatile int counter; } atomic_t;
volatile修飾字段告訴gcc不要對該類型的數據做優化處理,對它的訪問都是對內存的訪問,而不是對寄存器的訪問。?
本質是int類型,之所以這樣寫是讓編譯器對基于該類型變量的操作進行嚴格的類型檢查。此處f_count的作用是記錄對文件對象的引用計數,也即當前有多少個進程在使用該文件。
五、
unsigned int? ?? ?? ?? ?f_flags;
當打開文件時指定的標志,對應系統調用open的int flags參數。驅動程序為了支持非阻塞型操作需要檢查這個標志。
六、
mode_t? ?? ?? ?? ?? ?? ?f_mode;
對文件的讀寫模式,對應系統調用open的mod_t mode參數。如果驅動程序需要這個值,可以直接讀取這個字段。
mod_t被定義為:
typedef unsigned int __kernel_mode_t;
typedef __kernel_mode_t? ?? ?? ?mode_t;
七、
loff_t? ?? ?? ?? ?? ?? ?f_pos;
當前的文件指針位置,即文件的讀寫位置。
loff_t被定義為:
typedef long long? ?? ? __kernel_loff_t;
typedef __kernel_loff_t? ?? ?? ?loff_t;
八、 struct?fown_struct??????f_owner;?? struct?fown_struct在linux/include/linux/fs.h被定義,原型為:?? struct?fown_struct?{?? ????????rwlock_t?lock;??????????/*?protects?pid,?uid,?euid?fields?*/?? ????????struct?pid?*pid;????????/*?pid?or?-pgrp?where?SIGIO?should?be?sent?*/?? ????????enum?pid_type?pid_type;?/*?Kind?of?process?group?SIGIO?should?be?sent?to?*/?? ????????uid_t?uid,?euid;????????/*?uid/euid?of?process?setting?the?owner?*/?? ????????int?signum;?????????????/*?posix.1b?rt?signal?to?be?delivered?on?IO?*/?? };??
該結構的作用是通過信號進行I/O時間通知的數據。
九、
unsigned int? ?? ?? ?? ?f_uid, f_gid;
標識文件的所有者id,所有者所在組的id.
十、
struct file_ra_state? ? f_ra;
struct file_ra_state結構被定義在/linux/include/linux/fs.h中,原型為: [cpp]?view plain?copy struct?file_ra_state?{?? ????????pgoff_t?start;??????????????????/*?where?readahead?started?*/?? ????????unsigned?long?size;?????????????/*?#?of?readahead?pages?*/?? ????????unsigned?long?async_size;???????/*?do?asynchronous?readahead?when? ???????????????????????????????????????????there?are?only?#?of?pages?ahead?*/?? ????????????????????????????????????????????? ????????unsigned?long?ra_pages;?????????/*?Maximum?readahead?window?*/?? ????????unsigned?long?mmap_hit;?????????/*?Cache?hit?stat?for?mmap?accesses?*/?? ????????unsigned?long?mmap_miss;????????/*?Cache?miss?stat?for?mmap?accesses?*/?? ????????unsigned?long?prev_index;???????/*?Cache?last?read()?position?*/?? ????????unsigned?int?prev_offset;???????/*?Offset?where?last?read()?ended?in?a?page?*/?? };??
文件預讀狀態,文件預讀算法使用的主要數據結構,當打開一個文件時,f_ra中出了perv_page(默認為-1)和ra_apges(對該文件允許的最大預讀量)這兩個字段外,其他的所有西端都置為0。
十一、
unsigned long? ?? ?? ???f_version;
記錄文件的版本號,每次使用后都自動遞增。
十二、
#ifdef CONFIG_SECURITY
? ?? ???void? ?? ?? ?? ?? ?? ???*f_security;
#endif
此處我的理解是如果在編譯內核時配置了安全措施,那么struct file結構中就會有void *f_security數據項,用來描述安全措施或者是記錄與安全有關的信息。
十三、
void *private_data;
系統在調用驅動程序的open方法前將這個指針置為NULL。驅動程序可以將這個字段用于任意目的,也可以忽略這個字段。驅動程序可以用這個字段指向已分配的數據,但是一定要在內核釋放file結構前的release方法中清除它。
十四、
#ifdef CONFIG_EPOLL
? ?? ???/* Used by fs/eventpoll.c to link all the hooks to this file */
? ?? ???struct list_head? ?? ???f_ep_links;
? ?? ???spinlock_t? ?? ?? ?? ???f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
被用在fs/eventpoll.c來鏈接所有鉤到這個文件上。其中f_ep_links是文件的事件輪詢等待者鏈表的頭,f_ep_lock是保護f_ep_links鏈表的自旋鎖。
十五、struct address_space? ? *f_mapping;
struct address_space被定義在/linux/include/linux/fs.h中,此處是指向文件地址空間的指針。
??在驅動開發中,文件讀/寫模式mode、標志f_flags都是設備驅動關心的內容,而私有數據指針private_data在折本驅動中被廣泛使用,大多被指向設備驅動自定義用于描述設備的結構體。?
驅動程序中常用如下類似的代碼來檢測用戶打開文件的讀寫方式:
if (file->f_mode & FMODE_WRITE) //用戶要求可寫
??{
??}
??if (file->f_mode & FMODE_READ) //用戶要求可讀
??{
??}
下面的代碼可用于判斷以阻塞還是非阻塞方式打開設備文件:
??if (file->f_flags & O_NONBLOCK) //非阻塞
? ?? ?pr_debug("open:non-blocking/n");
??else //阻塞
? ?? ?pr_debug("open:blocking/n");
參考:
struct file *f_next,**f_pprev;?
struct dentry *f_dentry;?
struct file_operations *f_op;?
mode_t f_mode;?
loff_t f_pos;?
unsigned int f_count,f_flags;?
unsigned long f_reada,f_ramax,f_raend,f_ralen,f_rawin;?
struct fown_struct f_owner;?
unsigned long f_version;?
void *private_data;?
}; ?
[cpp]?view plain?copy
文件結構體代表一個打開的文件,系統中的每個打開的文件在內核空間都有一個關聯的struct file。它由內核在打開文件時創建,并傳遞給在文件上進行操作的任何函數。在文件的所有實例都關閉后,內核釋放這個數據結構。在內核創建和驅動源碼中,struct file的指針通常被命名為file或filp。一下是對結構中的每個數據成員的解釋:
一、
union {
? ? struct list_head fu_list;
? ? struct rcu_head rcuhead;
}f_u;
其中的struct list_head定義在 linux/include/linux/list.h中,原型為:
struct list_head {
? ?? ???struct list_head *next, *prev;
};
用于通用文件對象鏈表的指針。
struct rcu_head定義在linux/include/linux/rcupdate.h中,其原型為:
[cpp]?view plain?copy
RCU(Read-Copy Update)是Linux 2.6內核中新的鎖機制,具體在這里有介紹:
http://www.ibm.com/developerworks/cn/linux/l-rcu/
二、
struct path? ?? ?? ?? ? f_path;
被定義在linux/include/linux/namei.h中,其原型為:
struct path {
? ?? ???struct vfsmount *mnt;
? ?? ???struct dentry *dentry;
};
在早些版本的內核中并沒有此結構,而是直接將path的兩個數據成員作為struct file的數據成員,
struct vfsmount *mnt的作用是指出該文件的已安裝的文件系統,
struct dentry *dentry是與文件相關的目錄項對象。
三、
const struct file_operations? ? *f_op;
被定義在linux/include/linux/fs.h中,其中包含著與文件關聯的操作,如:
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
等。當打開一個文件時,內核就創建一個與該文件相關聯的struct file結構,其中的*f_op就指向的是
具體對該文件進行操作的函數。例如用戶調用系統調用read來讀取該文件的內容時,那么系統調用read最終會陷入內核調用sys_read函數,而sys_read最終會調用于該文件關聯的struct file結構中的f_op->read函數對文件內容進行讀取。
四、
atomic_t? ?? ?? ?? ?? ? f_count;
atomic_t被定義為:
typedef struct { volatile int counter; } atomic_t;
volatile修飾字段告訴gcc不要對該類型的數據做優化處理,對它的訪問都是對內存的訪問,而不是對寄存器的訪問。?
本質是int類型,之所以這樣寫是讓編譯器對基于該類型變量的操作進行嚴格的類型檢查。此處f_count的作用是記錄對文件對象的引用計數,也即當前有多少個進程在使用該文件。
五、
unsigned int? ?? ?? ?? ?f_flags;
當打開文件時指定的標志,對應系統調用open的int flags參數。驅動程序為了支持非阻塞型操作需要檢查這個標志。
六、
mode_t? ?? ?? ?? ?? ?? ?f_mode;
對文件的讀寫模式,對應系統調用open的mod_t mode參數。如果驅動程序需要這個值,可以直接讀取這個字段。
mod_t被定義為:
typedef unsigned int __kernel_mode_t;
typedef __kernel_mode_t? ?? ?? ?mode_t;
七、
loff_t? ?? ?? ?? ?? ?? ?f_pos;
當前的文件指針位置,即文件的讀寫位置。
loff_t被定義為:
typedef long long? ?? ? __kernel_loff_t;
typedef __kernel_loff_t? ?? ?? ?loff_t;
八、
?
[cpp]?view plain?copy該結構的作用是通過信號進行I/O時間通知的數據。
九、
unsigned int? ?? ?? ?? ?f_uid, f_gid;
標識文件的所有者id,所有者所在組的id.
十、
struct file_ra_state? ? f_ra;
struct file_ra_state結構被定義在/linux/include/linux/fs.h中,原型為: [cpp]?view plain?copy
文件預讀狀態,文件預讀算法使用的主要數據結構,當打開一個文件時,f_ra中出了perv_page(默認為-1)和ra_apges(對該文件允許的最大預讀量)這兩個字段外,其他的所有西端都置為0。
十一、
unsigned long? ?? ?? ???f_version;
記錄文件的版本號,每次使用后都自動遞增。
十二、
#ifdef CONFIG_SECURITY
? ?? ???void? ?? ?? ?? ?? ?? ???*f_security;
#endif
此處我的理解是如果在編譯內核時配置了安全措施,那么struct file結構中就會有void *f_security數據項,用來描述安全措施或者是記錄與安全有關的信息。
十三、
void *private_data;
系統在調用驅動程序的open方法前將這個指針置為NULL。驅動程序可以將這個字段用于任意目的,也可以忽略這個字段。驅動程序可以用這個字段指向已分配的數據,但是一定要在內核釋放file結構前的release方法中清除它。
十四、
#ifdef CONFIG_EPOLL
? ?? ???/* Used by fs/eventpoll.c to link all the hooks to this file */
? ?? ???struct list_head? ?? ???f_ep_links;
? ?? ???spinlock_t? ?? ?? ?? ???f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
被用在fs/eventpoll.c來鏈接所有鉤到這個文件上。其中f_ep_links是文件的事件輪詢等待者鏈表的頭,f_ep_lock是保護f_ep_links鏈表的自旋鎖。
十五、struct address_space? ? *f_mapping;
struct address_space被定義在/linux/include/linux/fs.h中,此處是指向文件地址空間的指針。
??在驅動開發中,文件讀/寫模式mode、標志f_flags都是設備驅動關心的內容,而私有數據指針private_data在折本驅動中被廣泛使用,大多被指向設備驅動自定義用于描述設備的結構體。?
驅動程序中常用如下類似的代碼來檢測用戶打開文件的讀寫方式:
if (file->f_mode & FMODE_WRITE) //用戶要求可寫
??{
??}
??if (file->f_mode & FMODE_READ) //用戶要求可讀
??{
??}
下面的代碼可用于判斷以阻塞還是非阻塞方式打開設備文件:
??if (file->f_flags & O_NONBLOCK) //非阻塞
? ?? ?pr_debug("open:non-blocking/n");
??else //阻塞
? ?? ?pr_debug("open:blocking/n");
參考:
總結
以上是生活随笔為你收集整理的Linux--文件结构体struct file的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于ASA防火墙的SSL ×××配置
- 下一篇: 部署Azkaban多节点分布式模式