EXT4檔案系統學習(15)VFS之VFS 檔案/目錄物件
無論下層具體檔案系統差異如何,VFS通過file結構向上層提供一個統一的檔案目錄物件。
VFS的檔案物件
struct file {
union {
struct llist_node fu_llist;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op; 檔案操作函式指標
/*
* Protects f_ep_links, f_flags.
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
atomic_long_t f_count; 引用計數
unsigned int f_flags;
fmode_t f_mode;
struct mutex f_pos_lock;
loff_t f_pos; 檔案的讀寫指標
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 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;
struct list_head f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
比較重要的是f_op指標,指向一個file_operations結構體,定義如下:
struct file_operations {
struct module *owner;
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 *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*mremap)(struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **, void **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
void (*show_fdinfo)(struct seq_file *m, struct file *f);
#ifndef CONFIG_MMU
unsigned (*mmap_capabilities)(struct file *);
#endif
};
read和write是同步阻塞讀寫函式,read_iter和write_iter是非同步讀寫,由於需要相容下層大多數的具體檔案系統,所有定義了所有函式指標,但是在ext4_file_operations中只對某些函式指標賦值,file物件的f_op指標型別與inode的i_fop是一致的,i_fop是在ext4_fill_super函式中inode初始化時賦值的,f_op應該是也是在file物件初始化賦值的。
VFS的目錄物件
在VFS中每個目錄項都對應一個dentry物件,dentry物件是下層具體檔案系統目錄項的抽象,定義如下:
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name; 目錄名
struct inode *d_inode; /* Where the name belongs to - NULL is 目錄對應inode
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */
struct lockref d_lockref; /* per-dentry lock and refcount */
const struct dentry_operations *d_op; 目錄操作函式指標
struct super_block *d_sb; /* The root of the dentry tree */
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
/*
* d_alias and d_rcu can share memory
*/
union {
struct hlist_node d_alias; /* inode alias list */
struct rcu_head d_rcu;
} d_u;
};
檔案路徑是通過目錄樹來組織的,如/usr/bin,首先根目錄/對應一個dentry物件,然後bin目錄對應一個dentry物件,每個目錄項的名字儲存在d_name成員中,這些目錄通過d_child連結串列組織成樹的結構,例如根目錄下所有的dentry物件都連結在根目錄中的d_child連結串列中,同時各個dentry物件的d_parent指向父目錄的dentry物件。
不只是目錄才有目錄項,檔案也有dentry物件。
根據路徑定位一個檔案過程就是一層一層找對應的dentry物件,根目錄的dentry物件是在mount時建立的,從d_child找對應的dentry物件,如果記憶體中沒有就從磁碟中讀出。
各個具體檔案系統對目錄操作d_op也不一樣,定義如下:
struct dentry_operations {
int (*d_revalidate)(struct dentry *, unsigned int);
int (*d_weak_revalidate)(struct dentry *, unsigned int);
int (*d_hash)(const struct dentry *, struct qstr *);
int (*d_compare)(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
void (*d_prune)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(struct dentry *, bool);
struct inode *(*d_select_inode)(struct dentry *, unsigned);
} ____cacheline_aligned;
d_op為NULL時表示使用預設dentry操作方式,我們的ext4是這樣使用預設的嗎?
VFS在程式中的檔案結構
各種管理結構的整體關係:
程式中fs中的root指向程式根目錄的dentry結構,而pwd指向程式當前目錄的dentry結構,遮蔽掉下層具體檔案系統的差異,程式看到的都是VFS的檔案物件。
相關文章
- EXT4檔案系統學習(14)VFS之VFS inode
- EXT4檔案系統學習(12)VFS之檔案系統物件file_system_type物件
- EXT4檔案系統學習(13)VFS之VFS超級塊super_blockBloC
- EXT4檔案系統學習(10)VFS之磁碟結構Group和superblockBloC
- EXT4檔案系統學習(9)VFS之磁碟結構inode和direntry
- EXT4檔案系統學習(11)VFS之記憶體結構sb和inode記憶體
- Linux檔案系統、目錄Linux
- linux目錄及檔案命令學習Linux
- Linux檔案系統目錄結構Linux
- 恢復ext4檔案系統被誤刪的檔案
- 關於檔案系統在建立目錄檔案和普通檔案時的區別
- Linux系統的目錄及重要檔案Linux
- 檔案系統(六):一文看懂linux ext4檔案系統工作原理Linux
- php檔案操作之提取檔案/目錄的名稱PHP
- 檔案包含之銘感目錄
- Linux VFSLinux
- Linux基礎學習——檔案與目錄管理Linux
- [Python]學習基礎篇:檔案和目錄Python
- 簡單瞭解EXT4檔案系統
- 使用SSHFS檔案系統遠端掛載目錄
- CentOS系統下/tmp目錄臨時檔案清理CentOS
- linux檔案系統的目錄結構筆記Linux筆記
- 深入理解 ext4 等 Linux 檔案系統Linux
- Python 檔案、目錄操作Python
- Linux 檔案與目錄Linux
- 列出並排序檔案系統根目錄(/)下各個目錄的大小排序
- ros學習檔案系統介紹ROS
- Macbook磁碟系統結構/檔案/目錄介紹分析Mac
- 獲取Linux系統中目錄檔案大小的方法Linux
- 如何系統學習C 語言(下)之 檔案篇
- 檔案和檔案系統
- Linux檔案和目錄管理Linux
- Linux檔案及目錄管理Linux
- Linux學習初期,怎麼給檔案或目錄命名呢?Linux
- Linux 學習筆記--目錄結構及檔案基本操作Linux筆記
- i.MX6ULL終結者Linux檔案系統的構建根檔案系統目錄介紹Linux
- 隱藏任意程式,目錄檔案,登錄檔,埠
- Linux學習之檔案操作Linux