分享
 
 
 

Linux Kernel Internals(3cont.)--Virtual Filesystem

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

3.5 Superblock and Mountpoint Management

Under Linux, information about mounted filesystems is kept in two separate structures - super_block and vfsmount. The reason for this is that Linux allows to mount the same filesystem (block device) under multiple mount points, which means that the same super_block can correspond to multiple vfsmount structures.

Let us look at struct super_block first, declared in include/linux/fs.h:

--------------------------------------------------------------------------------

struct super_block {

struct list_head s_list; /* Keep this first */

kdev_t s_dev;

unsigned long s_blocksize;

unsigned char s_blocksize_bits;

unsigned char s_lock;

unsigned char s_dirt;

struct file_system_type *s_type;

struct super_operations *s_op;

struct dquot_operations *dq_op;

unsigned long s_flags;

unsigned long s_magic;

struct dentry *s_root;

wait_queue_head_t s_wait;

struct list_head s_dirty; /* dirty inodes */

struct list_head s_files;

struct block_device *s_bdev;

struct list_head s_mounts; /* vfsmount(s) of this one */

struct quota_mount_options s_dquot; /* Diskquota specific options */

union {

struct minix_sb_info minix_sb;

struct ext2_sb_info ext2_sb;

..... all filesystems that need sb-private info ...

void *generic_sbp;

} u;

/*

* The next field is for VFS *only*. No filesystems have any business

* even looking at it. You had been warned.

*/

struct semaphore s_vfs_rename_sem; /* Kludge */

/* The next field is used by knfsd when converting a (inode number based)

* file handle into a dentry. As it builds a path in the dcache tree from

* the bottom up, there may for a time be a subpath of dentrys which is not

* connected to the main tree. This semaphore ensure that there is only ever

* one such free path per filesystem. Note that unconnected files (or other

* non-directories) are allowed, but not unconnected diretories.

*/

struct semaphore s_nfsd_free_path_sem;

};

--------------------------------------------------------------------------------

The various fields in the super_block structure are:

s_list: a doubly-linked list of all active superblocks; note I don't say "of all mounted filesystems" because under Linux one can have multiple instances of a mounted filesystem corresponding to a single superblock.

s_dev: for filesystems which require a block to be mounted on, i.e. for FS_REQUIRES_DEV filesystems, this is the i_dev of the block device. For others (called anonymous filesystems) this is an integer MKDEV(UNNAMED_MAJOR, i) where i is the first unset bit in unnamed_dev_in_use array, between 1 and 255 inclusive. See fs/super.c:get_unnamed_dev()/put_unnamed_dev(). It has been suggested many times that anonymous filesystems should not use s_dev field.

s_blocksize, s_blocksize_bits: blocksize and log2(blocksize).

s_lock: indicates whether superblock is currently locked by lock_super()/unlock_super().

s_dirt: set when superblock is changed, and cleared whenever it is written back to disk.

s_type: pointer to struct file_system_type of the corresponding filesystem. Filesystem's read_super() method doesn't need to set it as VFS fs/super.c:read_super() sets it for you if fs-specific read_super() succeeds and resets to NULL if it fails.

s_op: pointer to super_operations structure which contains fs-specific methods to read/write inodes etc. It is the job of filesystem's read_super() method to initialise s_op correctly.

dq_op: disk quota operations.

s_flags: superblock flags.

s_magic: filesystem's magic number. Used by minix filesystem to differentiate between multiple flavours of itself.

s_root: dentry of the filesystem's root. It is the job of read_super() to read the root inode from the disk and pass it to d_alloc_root() to allocate the dentry and instantiate it. Some filesystems spell "root" other than "/" and so use more generic d_alloc() function to bind the dentry to a name, e.g. pipefs mounts itself on "pipe:" as its own root instead of "/".

s_wait: waitqueue of processes waiting for superblock to be unlocked.

s_dirty: a list of all dirty inodes. Recall that if inode is dirty (inode->i_state & I_DIRTY) then it is on superblock-specific dirty list linked via inode->i_list.

s_files: a list of all open files on this superblock. Useful for deciding whether filesystem can be remounted read-only, see fs/file_table.c:fs_may_remount_ro() which goes through sb->s_files list and denies remounting if there are files opened for write (file->f_mode & FMODE_WRITE) or files with pending unlink (inode->i_nlink == 0).

s_bdev: for FS_REQUIRES_DEV, this points to the block_device structure describing the device the filesystem is mounted on.

s_mounts: a list of all vfsmount structures, one for each mounted instance of this superblock.

s_dquot: more diskquota stuff.

The superblock operations are described in the super_operations structure declared in include/linux/fs.h:

--------------------------------------------------------------------------------

struct super_operations {

void (*read_inode) (struct inode *);

void (*write_inode) (struct inode *, int);

void (*put_inode) (struct inode *);

void (*delete_inode) (struct inode *);

void (*put_super) (struct super_block *);

void (*write_super) (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 *);

};

--------------------------------------------------------------------------------

read_inode: reads the inode from the filesystem. It is only called from fs/inode.c:get_new_inode() from iget4() (and therefore iget()). If a filesystem wants to use iget() then read_inode() must be implemented - otherwise get_new_inode() will panic. While inode is being read it is locked (inode->i_state = I_LOCK). When the function returns, all waiters on inode->i_wait are woken up. The job of the filesystem's read_inode() method is to locate the disk block which contains the inode to be read and use buffer cache bread() function to read it in and initialise the various fields of inode structure, for example the inode->i_op and inode->i_fop so that VFS level knows what operations can be performed on the inode or corresponding file. Filesystems that don't implement read_inode() are ramfs and pipefs. For example, ramfs has its own inode-generating function ramfs_get_inode() with all the inode operations calling it as needed.

write_inode: write inode back to disk. Similar to read_inode() in that it needs to locate the relevant block on disk and interact with buffer cache by calling mark_buffer_dirty(bh). This method is called on dirty inodes (those marked dirty with mark_inode_dirty()) when the inode needs to be sync'd either individually or as part of syncing the entire filesystem.

put_inode: called whenever the reference count is decreased.

delete_inode: called whenever both inode->i_count and inode->i_nlink reach 0. Filesystem deletes the on-disk copy of the inode and calls clear_inode() on VFS inode to "terminate it with extreme prejudice".

put_super: called at the last stages of umount(2) system call to notify the filesystem that any private information held by the filesystem about this instance should be freed. Typically this would brelse() the block containing the superblock and kfree() any bitmaps allocated for free blocks, inodes, etc.

write_super: called when superblock needs to be written back to disk. It should find the block containing the superblock (usually kept in sb-private area) and mark_buffer_dirty(bh) . It should also clear sb->s_dirt flag.

statfs: implements fstatfs(2)/statfs(2) system calls. Note that the pointer to struct statfs passed as argument is a kernel pointer, not a user pointer so we don't need to do any I/O to userspace. If not implemented then statfs(2) will fail with ENOSYS.

remount_fs: called whenever filesystem is being remounted.

clear_inode: called from VFS level clear_inode(). Filesystems that attach private data to inode structure (via generic_ip field) must free it here.

umount_begin: called during forced umount to notify the filesystem beforehand, so that it can do its best to make sure that nothing keeps the filesystem busy. Currently used only by NFS. This has nothing to do with the idea of generic VFS level forced umount support.

So, let us look at what happens when we mount a on-disk (FS_REQUIRES_DEV) filesystem. The implementation of the mount(2) system call is in fs/super.c:sys_mount() which is the just a wrapper that copies the options, filesystem type and device name for the do_mount() function which does the real work:

Filesystem driver is loaded if needed and its module's reference count is incremented. Note that during mount operation, the filesystem module's reference count is incremented twice - once by do_mount() calling get_fs_type() and once by get_sb_dev() calling get_filesystem() if read_super() was successful. The first increment is to prevent module unloading while we are inside read_super() method and the second increment is to indicate that the module is in use by this mounted instance. Obviously, do_mount() decrements the count before returning, so overall the count only grows by 1 after each mount.

Since, in our case, fs_type->fs_flags & FS_REQUIRES_DEV is true, the superblock is initialised by a call to get_sb_bdev() which obtains the referen

[1] [2] [3] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有