欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
linux內核分析筆記----虛擬文件系統
虛擬文件系統,也不知道大家聽(tīng)過(guò)沒(méi)有,反正我是聽(tīng)過(guò)了!我們知道在計算機行業(yè),很多東西都不是一定有個(gè)官方說(shuō):朋友,我最大,你們做的東西,都要是這個(gè)樣子,否則是非法的。事實(shí)上,很多東西都是靠的一種實(shí)力,通過(guò)實(shí)力來(lái)慢慢在人們心中成為既定事實(shí)。這個(gè)事實(shí)同樣是沒(méi)有官方的。好了,問(wèn)題來(lái)了,沒(méi)有官方,就沒(méi)有標準,沒(méi)有標準就沒(méi)有統一,沒(méi)有統一那就是三國時(shí)代,混戰當道也!
怎么辦?特別是百花爭鳴的文件系統,這時(shí)linux的內核開(kāi)發(fā)者們想到了VFS(虛擬文件系統)。VFS使得用戶(hù)可以直接使用open(),read()和write()這樣的系統調用而不用關(guān)注具體文件系統和實(shí)際物理介質(zhì)。也許你感覺(jué)不是很新奇啊,告訴你新奇的事情:在老式操作系統上(比如DOS),任何對非本地文件系統的訪(fǎng)問(wèn)都必須依靠特殊工具才能完成。這種實(shí)現的方式是內核在它的底層文件系統接口上建立了一個(gè)抽象層。該抽象層是linux能夠支持各種文件系統,即便是它們在功能和行為上存在很大差別。為了支持文件系統,VFS提供了一個(gè)通用文件系統模型,該模型囊括了我們所能想到的文件系統的常用功能和行為。這個(gè)VFS抽象層之所以能銜接各種各樣的文件系統,是因為它定義了所有文件系統都支持的基本抽象接口和數據結構,同時(shí)實(shí)際系統也將自身的諸如“如何打開(kāi)文件”,“目錄是什么”等概念在形式上與VFS的定義保持一致。因為實(shí)際文件系統的代碼在統一的接口和數據結構隱藏了具體的實(shí)現細節,所以在VFS層和內核的其他部分看來(lái),所有文件系統都是相同的,它們都支持像文件和目錄這樣的概念,同時(shí)也支持像創(chuàng )建和刪除文件這樣的操作。
實(shí)際文件系統通過(guò)編程提供VFS所期望的抽象接口和數據結構,這樣,內核就可以毫不費力地和任何文件系統協(xié)同工作。那么接下的問(wèn)題,它們直接的關(guān)系如何呢,看下邊的例子:
1
write(f,&buf,len);
該代碼不用說(shuō),應該明白。這個(gè)用戶(hù)調用首先被一個(gè)通用系統調用sys_write()處理,sys_write()函數要找到f所在的文件系統實(shí)際給出的是哪個(gè)寫(xiě)操作,然后再執行該操作。實(shí)際文件系統的寫(xiě)方法是文件系統實(shí)現的一部分,數據最終通過(guò)該操作寫(xiě)入介質(zhì)。下圖給出流程:
下面我就先從整體上對unix(linux)文件系統做個(gè)概述,然后在具體下去。Unix使用了四種和文件系統相關(guān)的傳統抽象概念,如下:
1.文件:就是一個(gè)有序字節串。
2.目錄項:文件是放在目錄中,目錄又可以層層嵌套,形成文件路徑。路徑中的每一項就叫做目錄項。目錄是文件,這個(gè)文件列出了該目錄下的所有文件.
3.索引節點(diǎn):一個(gè)文件其實(shí)是由兩部分組成:相關(guān)信息和文件本身。這里的相關(guān)信息指的是訪(fǎng)問(wèn)控制權限,大小,擁有者,創(chuàng )建時(shí)間等。文件相關(guān)信息也叫
做元數據,被存儲在一個(gè)單獨的數據結構中,這個(gè)結構就叫做索引點(diǎn)(index node,簡(jiǎn)寫(xiě)inode)。
4.安裝點(diǎn)(掛載點(diǎn)):文件系統被安裝在一個(gè)特定的安裝點(diǎn)上,該安裝點(diǎn)在全局層次結構中被稱(chēng)為命名空間,所有的已安裝文件系統都作為根文件樹(shù)的樹(shù)葉出
現在系統中。
5.超級塊:是一種包含文件系統信息的數據結構,里邊是文件系統的控制信息。
對應于上圖,我們知道VFS是介于用戶(hù)文件和文件系統之間的一個(gè)概念,所以如果文件系統想要穿透VFS供用戶(hù)空間使用,就必須經(jīng)過(guò)封裝,提供一個(gè)符合這些概念的界面。上述每個(gè)元素都對應一個(gè)對象,該對象有屬性結構體,描述了該對象的屬性。有操作結構體,包含了自身所支持的操作,下面詳細介紹:
1.超級塊對象:代表一個(gè)已安裝的文件系統。由數據結構super_block結構體表示,定義在linux/fs.h中。如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct super_block {
struct list_head        s_list;            /* list of all superblocks */
dev_t                   s_dev;             /* identifier */
unsigned long           s_blocksize;       /* block size in bytes */
unsigned long           s_old_blocksize;   /* old block size in bytes */
unsigned char           s_blocksize_bits;  /* block size in bits */
unsigned char           s_dirt;            /* dirty flag */
unsigned long long      s_maxbytes;        /* max file size */
struct file_system_type s_type;            /* filesystem type */
struct super_operations s_op;              /* superblock methods */
struct dquot_operations *dq_op;            /* quota methods */
struct quotactl_ops     *s_qcop;           /* quota control methods */
struct export_operations *s_export_op;     /* export methods */
unsigned long            s_flags;          /* mount flags */
unsigned long            s_magic;          /* filesystem's magic number */
struct dentry            *s_root;          /* directory mount point */
struct rw_semaphore      s_umount;         /* unmount semaphore */
struct semaphore         s_lock;           /* superblock semaphore */
int                      s_count;          /* superblock ref count */
int                      s_syncing;        /* filesystem syncing flag */
int                      s_need_sync_fs;   /* not-yet-synced flag */
atomic_t                 s_active;         /* active reference count */
void                     *s_security;      /* security module */
struct list_head         s_dirty;          /* list of dirty inodes */
struct list_head         s_io;             /* list of writebacks */
struct hlist_head        s_anon;           /* anonymous dentries */
struct list_head         s_files;          /* list of assigned files */
struct block_device      *s_bdev;          /* associated block device */
struct list_head         s_instances;      /* instances of this fs */
struct quota_info        s_dquot;          /* quota-specific options */
char                     s_id[32];         /* text name */
void                     *s_fs_info;       /* filesystem-specific info */
struct semaphore         s_vfs_rename_sem; /* rename semaphore */
};
創(chuàng )建,管理和銷(xiāo)毀超級塊對象的代碼位于文件fs/super.c中,超級塊對象通過(guò)alloc_super()函數創(chuàng )建并初始化。在文件系統安裝時(shí),內核會(huì )調用該函數以便從磁盤(pán)讀取文件系統超級塊,并且將其信息填充到內存中的超級塊對象中。其中最重要的一個(gè)是s_op,指向超級塊的操作函數表,由super_operations結構體表示,定義在linux/fs.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct super_operations {
struct inode *(*alloc_inode) (struct super_block *sb);
void (*destroy_inode) (struct inode *);
void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs) (struct super_block *, int);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
int (*statfs) (struct super_block *, struct statfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options) (struct seq_file *, struct vfsmount *);
};
當文件系統需要對其超級塊執行操作時(shí),首先要在超級塊對象中尋找需要的操作方法。比如一個(gè)文件系統要寫(xiě)自己的超級塊,需要調用:sb->s_op->write_super(sb)這里的sb是指向文件系統超級塊的指針,沿著(zhù)該指針進(jìn)入超級塊操作函數表,并從表中取得希望得到的write_super()函數,該函數執行寫(xiě)入超級塊的實(shí)際操作。
2.索引節點(diǎn)對象:由inode結構體表示,定義在linux/fs.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
struct inode {
struct hlist_node       i_hash;              /* hash list */
struct list_head        i_list;              /* list of inodes */
struct list_head        i_dentry;            /* list of dentries */
unsigned long           i_ino;               /* inode number */
atomic_t                i_count;             /* reference counter */
umode_t                 i_mode;              /* access permissions */
unsigned int            i_nlink;             /* number of hard links */
uid_t                   i_uid;               /* user id of owner */
gid_t                   i_gid;               /* group id of owner */
kdev_t                  i_rdev;              /* real device node */
loff_t                  i_size;              /* file size in bytes */
struct timespec         i_atime;             /* last access time */
struct timespec         i_mtime;             /* last modify time */
struct timespec         i_ctime;             /* last change time */
unsigned int            i_blkbits;           /* block size in bits */
unsigned long           i_blksize;           /* block size in bytes */
unsigned long           i_version;           /* version number */
unsigned long           i_blocks;            /* file size in blocks */
unsigned short          i_bytes;             /* bytes consumed */
spinlock_t              i_lock;              /* spinlock */
struct rw_semaphore     i_alloc_sem;         /* nests inside of i_sem */
struct semaphore        i_sem;               /* inode semaphore */
struct inode_operations *i_op;               /* inode ops table */
struct file_operations  *i_fop;              /* default inode ops */
struct super_block      *i_sb;               /* associated superblock */
struct file_lock        *i_flock;            /* file lock list */
struct address_space    *i_mapping;          /* associated mapping */
struct address_space    i_data;              /* mapping for device */
struct dquot            *i_dquot[MAXQUOTAS]; /* disk quotas for inode */
struct list_head        i_devices;           /* list of block devices */
struct pipe_inode_info  *i_pipe;             /* pipe information */
struct block_device     *i_bdev;             /* block device driver */
unsigned long           i_dnotify_mask;      /* directory notify mask */
struct dnotify_struct   *i_dnotify;          /* dnotify */
unsigned long           i_state;             /* state flags */
unsigned long           dirtied_when;        /* first dirtying time */
unsigned int            i_flags;             /* filesystem flags */
unsigned char           i_sock;              /* is this a socket? */
atomic_t                i_writecount;        /* count of writers */
void                    *i_security;         /* security module */
__u32                   i_generation;        /* inode version number */
union {
void            *generic_ip;         /* filesystem-specific info */
} u;
};
有時(shí),某些文件系統可能并不能完整的包含索引節點(diǎn)結構體要求的所有信息。舉個(gè)例子,有的文件系統可能并不記錄文件的創(chuàng )建時(shí)間,這時(shí),該文件系統就可以在實(shí)現中選擇任意合適的辦法來(lái)解決這個(gè)問(wèn)題,它可以在i_ctime中存儲0,或者讓i_ctime等于i_mtime,甚至任何其他值。索引節點(diǎn)對象中的inode_operations項存放了操作函數列表,定義在linux/fs.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct inode_operations {
int (*create) (struct inode *, struct dentry *,int);
struct dentry * (*lookup) (struct inode *, struct dentry *);
int (*link) (struct dentry *, struct inode *, struct dentry *);
int (*unlink) (struct inode *, struct dentry *);
int (*symlink) (struct inode *, struct dentry *, const char *);
int (*mkdir) (struct inode *, struct dentry *, int);
int (*rmdir) (struct inode *, struct dentry *);
int (*mknod) (struct inode *, struct dentry *, int, dev_t);
int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char *, int);
int (*follow_link) (struct dentry *, struct nameidata *);
int (*put_link) (struct dentry *, struct nameidata *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *, size_t, int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
};
同樣,操作調用時(shí),用以下方式:i->i_op->truncate(i).
由于版面原因,我不得不分兩次說(shuō)了,下次繼續后面有關(guān)虛擬文件系統的剩余部分.
接著(zhù)上次的來(lái),我今天講虛擬文件系統剩下的一點(diǎn)知識.
3.目錄項對象.目錄項的概念上節已經(jīng)說(shuō)了,我就不多說(shuō).目錄項中也可包括安裝點(diǎn).在路徑/mnt/cdrom/foo中,/,mnt,cdrom都屬于目錄項對象。目錄項由dentry結構體表示,定義在文件linux/dcache.h中,描述如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct dentry {
atomic_t                 d_count;      /* usage count */
unsigned long            d_vfs_flags;  /* dentry cache flags */
spinlock_t               d_lock;       /* per-dentry lock */
struct inode             *d_inode;     /* associated inode */
struct list_head         d_lru;        /* unused list */
struct list_head         d_child;      /* list of dentries within */
struct list_head         d_subdirs;    /* subdirectories */
struct list_head         d_alias;      /* list of alias inodes */
unsigned long            d_time;       /* revalidate time */
struct dentry_operations *d_op;        /* dentry operations table */
struct super_block       *d_sb;        /* superblock of file */
unsigned int             d_flags;      /* dentry flags */
int                      d_mounted;    /* is this a mount point? */
void                     *d_fsdata;    /* filesystem-specific data */
struct rcu_head          d_rcu;        /* RCU locking */
struct dcookie_struct    *d_cookie;    /* cookie */
struct dentry            *d_parent;    /* dentry object of parent */
struct qstr              d_name;       /* dentry name */
struct hlist_node        d_hash;       /* list of hash table entries */
struct hlist_head        *d_bucket;    /* hash bucket */
unsigned char            d_iname[DNAME_INLINE_LEN_MIN]; /* short name */
};
由于目錄項并非真正保存在磁盤(pán)上,所有目錄項沒(méi)有對應的磁盤(pán)數據結構,VFS根據字符串形式的路徑名現場(chǎng)創(chuàng )建它,目錄項結構體也沒(méi)有是否被修改的標志。目錄項對象有三種狀態(tài):被使用,未被使用和負狀態(tài)。一個(gè)被使用的目錄項對應一個(gè)有效的索引節點(diǎn)(即d_inode指向相應的索引節點(diǎn))并且該對象存在一個(gè)或多個(gè)使用者(即d_count為正值)。一個(gè)未被使用的目錄項對應一個(gè)有效的索引節點(diǎn)(d_inode指向一個(gè)索引節點(diǎn)),但是VFS當前并未使用它(d_count為0)。該目錄項對象仍然指向一個(gè)有效對象,而且被保留在內存中以便需要時(shí)再使用它。顯然這樣要比重新創(chuàng )建要效率高些。一個(gè)負狀態(tài)的目錄項沒(méi)有對應的有效索引節點(diǎn)(d_inode為NULL).因為索引節點(diǎn)已被刪除了,或路徑不再正確了,但是目錄項仍然保留,以便快速解析以后的路徑查詢(xún)。雖然負的狀態(tài)目錄項有些用處,但如果需要的話(huà)話(huà),還是可以刪除的,可以銷(xiāo)毀它。
結構體dentry_operation指明了VFS操作目錄的所有方法,如下:
1
2
3
4
5
6
7
8
struct dentry_operations {
int (*d_revalidate) (struct dentry *, int);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
int (*d_delete) (struct dentry *);
void (*d_release) (struct dentry *);
void (*d_iput) (struct dentry *, struct inode *);
};
其實(shí),如果VFS遍歷路徑名中所有的元素并將它們逐個(gè)地解析成目錄項對象,將是一件非常耗時(shí)的事情。所以?xún)群藢⒛夸涰棇ο缶彺嬖谀夸涰椌彺?dcache)中,目錄項緩存包括三個(gè)主要部分:
1.“被使用的”目錄項鏈表,該鏈表通過(guò)索引節點(diǎn)對象中的i_dentry項連接相關(guān)的索引節點(diǎn),因為一個(gè)給定的索引節點(diǎn)可能有多個(gè)鏈接,所以就可能有多
個(gè)目錄項對象,因此用一個(gè)鏈表來(lái)連接它們。
2.“最近被使用的”雙向鏈表。該鏈表包含未被使用的和負狀態(tài)的目錄項對象。該鏈表是按時(shí)間插入的。
3.  哈希表和相應的哈希函數用來(lái)快速地將給定路徑解析為相關(guān)目錄項對象。
哈希表有數組dentry_hashtable表示,其中每一個(gè)元素都是一個(gè)指向具有相同鍵值的目錄項對象鏈表的指針。數組的大小取決于系統中物理內存的大小。實(shí)際的哈希值由d_hash()計算,它是內核提供給文件系統的唯一的一個(gè)哈希函數。查找哈希表要通過(guò)d_lookup()函數,如果該函數在dcache中發(fā)現了與其相匹配的目錄項對像,則匹配對象被返回;否則,返回NULL指針。dcache在一定意義上也提供了對索引節點(diǎn)的緩存。和目錄項對象相關(guān)的索引節點(diǎn)對象不會(huì )被釋放,因為目錄項會(huì )讓相關(guān)索引節點(diǎn)的使用計數為正,這樣就可以確保索引節點(diǎn)留在內存中。只要目錄項被緩存,其相應的索引節點(diǎn)也就被緩存了。
4.文件對象:文件對象表示進(jìn)程以打開(kāi)的文件。文件對象僅僅在進(jìn)程觀(guān)點(diǎn)上代表已打開(kāi)文件,它反過(guò)來(lái)指向目錄項對象(反過(guò)來(lái)指向索引節點(diǎn)),其實(shí)只有目錄項對象才表示已打開(kāi)的實(shí)際文件。雖然一個(gè)文件對應的文件對象不是唯一的,但對應的索引節點(diǎn)和目錄項對象無(wú)疑是唯一的。文件對象由file結構表示,定義在文件linux/fs.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct file {
struct list_head       f_list;        /* list of file objects */
struct dentry          *f_dentry;     /* associated dentry object */
struct vfsmount        *f_vfsmnt;     /* associated mounted fs */
struct file_operations *f_op;         /* file operations table */
atomic_t               f_count;       /* file object's usage count */
unsigned int           f_flags;       /* flags specified on open */
mode_t                 f_mode;        /* file access mode */
loff_t                 f_pos;         /* file offset (file pointer) */
struct fown_struct     f_owner;       /* owner data for signals */
unsigned int           f_uid;         /* user's UID */
unsigned int           f_gid;         /* user's GID */
int                    f_error;       /* error code */
struct file_ra_state   f_ra;          /* read-ahead state */
unsigned long          f_version;     /* version number */
void                   *f_security;   /* security module */
void                   *private_data; /* tty driver hook */
struct list_head       f_ep_links;    /* list of eventpoll links */
spinlock_t             f_ep_lock;     /* eventpoll lock */
struct address_space   *f_mapping;    /* page cache mapping */
};
文件對象的操作有file_operations結構表示,在linux/fs.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int);
int (*aio_fsync) (struct kiocb *, int);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *,
unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *,
unsigned long, loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t,
read_actor_t, void *);
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 flags);
int (*dir_notify) (struct file *filp, unsigned long arg);
int (*flock) (struct file *filp, int cmd, struct file_lock *fl);
};
最后,除了以上幾種VFS基礎對象外,內核還使用了另外一些數據結構來(lái)管理文件系統的其它相關(guān)數據,如下:
1.file_system_type:因為linux支持眾多的文件系統,所以?xún)群吮赜杏梢粋€(gè)特殊的結構來(lái)描述每種文件系統的功能和行為:
1
2
3
4
5
6
7
8
9
10
11
12
struct file_system_type {
const char              *name;     /* filesystem's name */
struct subsystem        subsys;    /* sysfs subsystem object */
int                     fs_flags;  /* filesystem type flags */
/* the following is used to read the superblock off the disk */
struct super_block      *(*get_sb) (struct file_system_type *, int,char *, void *);
/* the following is used to terminate access to the superblock */
void                    (*kill_sb) (struct super_block *);
struct module           *owner;    /* module owning the filesystem */
struct file_system_type *next;     /* next file_system_type in list */
struct list_head        fs_supers; /* list of superblock objects */
};
其中,get_sb()函數從磁盤(pán)上讀取超級塊,并且在文件系統被安裝時(shí),在內存中組裝超級塊對象,剩余的函數描述文件系統的屬性。每種文件系統,不管有多少個(gè)實(shí)力安裝到系統中,還是根本就沒(méi)有安裝到系統中,都只有一個(gè)file_system_type結構。更有趣的是,當文件系統被實(shí)際安裝時(shí),將有一個(gè)vfsmount結構體在安裝點(diǎn)被創(chuàng )建。該結構體被用來(lái)代表文件系統的實(shí)例----換句話(huà)說(shuō),代表一個(gè)安裝點(diǎn).
2.vfsmount結構被定義在linux/mount.h中,下面是具體結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct vfsmount {
struct list_head   mnt_hash;        /* hash table list */
struct vfsmount    *mnt_parent;     /* parent filesystem */
struct dentry      *mnt_mountpoint; /* dentry of this mount point */
struct dentry      *mnt_root;       /* dentry of root of this fs */
struct super_block *mnt_sb;         /* superblock of this filesystem */
struct list_head   mnt_mounts;      /* list of children */
struct list_head   mnt_child;       /* list of children */
atomic_t           mnt_count;       /* usage count */
int                mnt_flags;       /* mount flags */
char               *mnt_devname;    /* device file name */
struct list_head   mnt_list;        /* list of descriptors */
struct list_head   mnt_fslink;      /* fs-specific expiry list */
struct namespace   *mnt_namespace   /* associated namespace */
};
vfs中維護的各種鏈表是為了跟蹤文件系統和所有其他安裝點(diǎn)的關(guān)系,mnt_flags保存了安裝時(shí)指定的標志信息,下表給出了標準的安裝標志:
安裝那些管理不充分信任的移動(dòng)設備時(shí),這些標志很有用處。
系統中每一個(gè)進(jìn)程都有自己的一組打開(kāi)的文件,有三個(gè)數據結構將VFS層和文件的進(jìn)程緊密聯(lián)系在一起,它們分別是file_struct,fs_struct和namespace.
1.file_struct:該結構體有進(jìn)程描述符中的files域指向,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct files_struct {
atomic_t    count;              /* structure's usage count */
spinlock_t  file_lock;          /* lock protecting this structure */
int         max_fds;            /* maximum number of file objects */
int         max_fdset;          /* maximum number of file descriptors */
int         next_fd;            /* next file descriptor number */
struct file **fd;               /* array of all file objects */
fd_set      *close_on_exec;     /* file descriptors to close on exec() */
fd_set      *open_fds;           /* pointer to open file descriptors */
fd_set      close_on_exec_init; /* initial files to close on exec() */
fd_set      open_fds_init;      /* initial set of file descriptors */
struct file *fd_array[NR_OPEN_DEFAULT]; /* default array of file objects */
};
fd數組指針指向以打開(kāi)的文件對象鏈表,默認情況下,指向fd_arrar數組。NR_OPEN_DEFAULT默認是32,所以該數組可以容納32個(gè)文件對象。如果一個(gè)進(jìn)程所打開(kāi)的文件對象超過(guò)32個(gè),內核將分配一個(gè)新數組,并且將fd指針指向它。這個(gè)值也是可以調整的。
2.第二個(gè)結構體是fs_struct:由進(jìn)程描述符的fs域指向。它包含文件系統和進(jìn)程相關(guān)的信息,在linux/fs_struct.h中,如下:
1
2
3
4
5
6
7
8
9
10
11
struct fs_struct {
atomic_t        count;       /* structure usage count */
rwlock_t        lock;        /* lock protecting structure */
int             umask;       /* default file permissions*/
struct dentry   *root;       /* dentry of the root directory */
struct dentry   *pwd;        /* dentry of the current directory */
struct dentry   *altroot;    /* dentry of the alternative root */
struct vfsmount *rootmnt;    /* mount object of the root directory */
struct vfsmount *pwdmnt;     /* mount object of the current directory */
struct vfsmount *altrootmnt; /* mount object of the alternative root */
};
該結構包含了當前進(jìn)程的當前工作目錄和根目錄。
3.最后一個(gè)是namespace:由進(jìn)程描述符namespace域指向,定義在linux/namespace.h中,如下:
1
2
3
4
5
6
struct namespace {
atomic_t            count; /* structure usage count */
struct vfsmount     *root; /* mount object of root directory */
struct list_head    list;  /* list of mount points */
struct rw_semaphore sem;   /* semaphore protecting the namespace */
};
list域是連接已安裝文件系統的雙向鏈表,它包含的元素組成了全體命令空間。      上述這些數據結構都是通過(guò)進(jìn)程描述符連接起來(lái)的。對多數進(jìn)程來(lái)說(shuō),它們的描述符都指向唯一的files_struct和fs_struct結構體。但是,對于那些使用克隆標志CLONE_FILES或CLONE_FS創(chuàng )建的進(jìn)程,會(huì )共享這兩個(gè)結構體。所以多個(gè)進(jìn)程描述符可能指向同一個(gè)files_struct或fs_struct結構體。每個(gè)結構體都維護一個(gè)count域作為引用計數,它防止進(jìn)程正使用該結構時(shí),該結構被銷(xiāo)毀。而namespace卻不是這樣,默認情況下,所有的進(jìn)程共享同樣的命名空間,也就是說(shuō),它們都看到同一個(gè)文件層層結構。只有在進(jìn)行clone()操作時(shí)使用CLONE_NEWS標志,才會(huì )給進(jìn)程一個(gè)另外的命名空間結構體的拷貝。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
linux內核中的文件描述符(一)--基礎知識簡(jiǎn)介
linux內核分析筆記-------虛擬文件系統(下)
vfs 3
對 proc 文件系統的分析(一)(轉載)
內核態(tài)獲取文件詳細信息
linux的VFS詳解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久