参考文档:
https://www.cnblogs.com/iiiiher/p/8036816.html
https://blog.csdn.net/u012077593/article/details/81874279
https://www.cnblogs.com/iiiiher/p/5328966.html
MBR引导方案的磁盘结构为:
MBR,分区1,分区2,分区3,分区4
MBR部分有64字节大小的分区表,每个分区16字节,因此MBR引导方案只支持4个分区(主分区),扩展分区与主分区的区别是,扩展分区的分区表信息存储在主分区中,分区也是主分区的一部分(不确定)。每个分区又以块为单位组织,初步理解为,ext2/3/4文件系统物理组织方式以块为单位,块大小为4K(可改变),逻辑组织方式(文件查找,访问)以节点为单位,对应数据结构定义在include/linux/fs.h文件中。
目录是一个特殊的文件,存放了目录下的文件和节点,每个文件名对应一个节点,系统中实际操作的是节点,linux可使用ls -i 命令查看当前目录下的文件名和节点号
参考文档:http://www.ruanyifeng.com/blog/2011/12/inode.html
以ext2文件系统为例:
disk | MBR | Patition1 | Patition2 | Patition3 | Patition4 |
/ \
/ \
/ \
/ \
/ \
Partition | Boot Sector | EXT2 File System |
/ \
/ \
/ \
/ \
/ \
| 块组1 | ..... | 块组n |
/ \
/ \
/ \
/ \
|超级块|组描述表|块位图|节点位图|节点表|数据块|
超级块:
每个块组有一个超级块(副本),超级块存放块组本身的信息:包括inode数、块数、保留块数、空闲块数、空闲inode数、第一个块位置、块长度、每个块组块数、每个块组inode数,以及安装时间、最后一次写时间、文件系统状态信息等
对ext2/3/4文件系统,使用dumpe2fs /dev/sda1可以查看分区中文件系统信息。
目录/run一般在引导时被清除,通常作为永久文件系统的挂载点。与此功能类似的是/run/lock、/var/run var/lock
Linux下文件系统类型:
(1) jffs2 主要用于Norflash, 基于MTD 驱动层,可读写,可压缩,因为垃圾收集的原因速度慢,不适用于Nandflash
(2) yaffs 是专门为嵌入式系统使用Nandflash 设计的日志型文件系统,不支持压缩,更适合容量大的设备
(3) cramfs 中文件,最大不能超过16MB,
特点:压缩比高,可达2:1,缺点是只能读,不能写,可作为文件系统研究的切入点
(4) Romfs 是一种只读文件系统,通常用在嵌入式设备中作为根文件系统,或者用于保存bootloader
(5) Ramdisk 和Ramfs /Tmpfs 都是基于RAM 的文件系统,区别是后者不能进行格式化。
(6) EXT2 快速、稳定的文件系统,现在很少使用
EXT3 是EXT2 的基础上加入了日志功能
EXT4 是EXT3 的扩展,支持大硬盘,速度更快。
(7) reiserfs:小文件访问能力突出。
(8) fs/fuse:应用空间的文件系统接口,支持商业版NTFS-3g, fat-
搜索Building fs with fuse
(9) AUFS:一种层叠文件系统
(10) Overlayfs:一种类似于aufs的堆叠文件系统,于2014年正式合入Linux-3.18主线内核
挂载文件系统的基本命令如下:
mount -t overlay overlay -o lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work merged
参考文档:
内核文档Documentation/filesystems/overlayfs.txt
https://blog.csdn.net/luckyapple1028/article/details/77916194
https://blog.csdn.net/luckyapple1028/article/details/78075358
格式化文件系统时可以指定节点大小和块大小
mkfs.ext4 -I 2048 -b 2048 /dev/sdb
Linux系统相关命令
0、ls -i # 显示当前目录中文件或目录的节点号
1、df # 显示系统中的文件系统
-h (human-readable)
-T # 增加显示类型
-i # 用节点数代替块(字节为单位)的结果,即节点数,节点使用率等
df Result = firstblock + superblocks + gdblocks + (2 + inode_blocks_per_group) * groups + journal_length
2、dumpe2fs /dev/sda1 # 显示块设备sda1的文件系统信息 (注:dumpe2fs,dump ext2/ext3/ext4 filesystem information)
3、stat xxx # 显示文件xxx的状态(节点号,链接数,大小,访问权限,修改时间等)
-f # 显示xxx所在文件系统的部分信息
-L # 若文件是软连接的话,显示原文件信息
4、tune2fs # 调整和查看ext2/ext3文件系统的文件系统参数
参数有:
-l 查看文件系统信息,结果与dumpe2fs的结果头差不多,tune2fs更多用于调整系统参数
-c max-mount-counts 设置强制自检的挂载次数,如果开启,每挂载一次mount conut就会加1,
超过次数就会强制自检
-i interval-between-checks[d|m|w] 设置强制自检的时间间隔[d天m月w周]
-m reserved-blocks-percentage 保留块的百分比
-j 将ext2文件系统转换为ext3类型的文件系统
-L volume-label 类似e2label的功能,可以修改文件系统的标签
-r reserved-blocks-count 调整系统保留空间
-o [^]mount-option[,...] Set or clear the indicated default mount options in the filesystem. 设置或清除默认挂载的文件系统选项
常见用法有:
tune2fs -m 1 /dev/sda1 将/dev/sda1分区的保留比调为1%
tune2fs -r 40000 /dev/sda1 调整/dev/hda1分区的保留空间为40000个磁盘块
tune2fs -c -1 /dev/hda1 关闭强制检查挂载次数限制。
tune2fs -i 10 /dev/hda1 10天后检查
tune2fs -i 1d /dev/hda1 1天后检查
tune2fs -i 3w /dev/hda1 3周后检查
tune2fs -i 6m /dev/hda1 半年后检查
tune2fs -i 0 /dev/hda1 禁用时间检查
5、mkfs指令
这里的mkfs指认不仅仅指mkfs.ext2(ext3、ext4) 三个指令,还包括mke2fs命令 。这些指令都是可以在格式化分区时指定分区类型和分区参数 ,具体参数如下:
-b <区块大小> 指定区块大小,单位为字节。
-c 检查是否有损坏的区块。
-f <不连续区段大小> 指定不连续区段的大小,单位为字节。
-F 不管指定的设备为何,强制执行mke2fs。
-i <字节> 指定"字节/inode"的比例。
-N <inode数> 指定要建立的inode数目。
-l <文件> 从指定的文件中,读取文件西中损坏区块的信息。
-L <标签> 设置文件系统的标签名称。
-m <百分比值> 指定给管理员保留区块的比例,预设为5%。
-M 记录最后一次挂入的目录。
-q 执行时不显示任何信息。
-t 指定创建文件系统类型
-r 指定要建立的ext2文件系统版本。
-R=<区块数> 设置磁盘阵列参数。
-S 仅写入superblock与group descriptors,而不更改inode able inode bitmap以及block bitmap。
6、e2label # 查看或设置卷标
用法:e2label device [newlabel]
ntfs格式的U盘使用命令ntfslabel
7、fsck:检查并修复linux文件系统
-t type:指定修复文件系统类型,不指定会自动选择当前的文件系统类型
-a:自动修复文件系统,如果不加-a每执行一步都会提示是否执行。
e2fsck:专用于修复ext2/ext3文件系统
-f:强制检测;
-p:自动修复;
二、数据结构
进程中使用数据结构struct fs_struct *fs;描述进程与文件系统的关系,其中包含进程所在的文件系统根目录及当前目录;使用数据结构struct files_struct *files;描述进程中打开的文件列表,其中有描述系统中打开文件的数据结构struct file __rcu * fd_array[NR_OPEN_DEFAULT=32];以及文件描述符,即struct file数组的下标。
include/linux/sched.h
struct task_struct {
struct fs_struct *fs; /* filesystem information */
struct files_struct *files; /* open file information */
};
struct fs_struct {
struct path root, pwd; // 进程所在文件系统的根目录和当前目录
};
struct path {
struct vfsmount *mnt; // 进程所在文件系统的挂载点
struct dentry *dentry; // 进程所在文件系统的目录项
};
struct files_struct {
struct fdtable __rcu *fdt;
struct fdtable fdtab;
struct file __rcu * fd_array[NR_OPEN_DEFAULT=32];
};
struct fdtable {
unsigned int max_fds;
struct file __rcu **fd; /* current fd array */
};
进程中的文件实体使用数据结构struct file来描述
struct file {
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
};
文件系统相关的静态数据结构:
1、超级块struct super_block; 描述一个文件系统。
定义与include/linux/fs.h
struct super_block {
struct file_system_type *s_type; /* 文件系统类型 */
const struct super_operations *s_op; /* 超级块操作集 */
struct dentry *s_root;
struct block_device *s_bdev; /* 所在的块设备 */
const struct dentry_operations *s_d_op; /* default d_op for dentries */
};
2、索引节点struct inode; 描述一个文件实体(物理属性)
struct inode {
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
struct hlist_node i_hash;
struct list_head i_io_list; /* backing dev IO list */
struct list_head i_lru; /* inode LRU list */
struct list_head i_sb_list;
atomic_t i_count;
atomic_t i_dio_count;
atomic_t i_writecount;
const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
struct file_lock_context *i_flctx;
struct address_space i_data;
struct list_head i_devices;
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
char *i_link;
};
};
描述一个挂载
struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
};
3、目录项对象描述一个文件的逻辑属性
/* include/linux/dcache.h */
struct dentry {
struct dentry *d_parent; /* parent directory */
struct inode *d_inode; /* Where the name belongs to - NULL is negative */
const struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
};
三、VFS层
1、相关数据结构定义
/* include/linux/fs.h */
struct file_system_type {
const char *name;
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
void (*kill_sb) (struct super_block *);
struct file_system_type * next;
...
};
struct file {
}
struct inode {
}
/* include/linux/dcache.h */
struct dentry{
}
2、代码层面的VFS接口
/* fs/open.c */
filp_open(const char *filename, int flags, umode_t mode)
filp_close(struct file *filp, fl_owner_t id)
/* fs/namei.c */
vfs_create(struct inode *dir, struct dentry *dentry, ...)
int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
const char *name, unsigned int flags, struct path *path)
vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
vfs_rmdir(struct inode *dir, struct dentry *dentry)
vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode)
vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode)
vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
struct inode **delegated_inode)
vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
/* fs/read_write.c */
vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
3、VFS数据结构与具体文件系统的关系
四、特殊的文件系统
sysfs
proc
devtmpfs
tmpfs是一种虚拟内存文件系统,是基于内存的文件系统。
devtmpfs 的功用是在 Linux 核心启动早期建立一个初步的 /dev,令一般启动程序不用等待 udev,缩短 GNU/Linux 的开机时间。
Devtmpfs
Linux 2.6.32–devtmpfs with or without udev/devKay Sievers, Jan Blunck, Greg Kroah-HartmanA hybrid kernel/userspace approach of a device filesystem to provide nodes before udev runs for the first time[8]
debugfs
mount -t debugfs none /sys/kernel/debug