Linux 文件系统概念
Linux 文件包含数据,目录是文件的列表。
不同目录之间互相连接构成树状的结构,目录还可以包含在其他目录中。
pwd 显示用户在目录数中的当前位置。
路径 从树跟到所处位置所经过的目录的序列。
mkdir dirname 创建一个目录
cd dirname 转移到目标目录
pwd 打印当前工作目录。
mv oldfilename newfilename 重命名文件
rm deletefilename 删除文件名
.. 表示上一级目录,即父目录
ln filename linkfilename 连接文件。filename 和 linkfilename 都称为连接,都指向硬盘上的同一数据块。
针对目录树的命令:
ls -R 列出当前目录下的目录内容,-R 要求列出指定目录及其子目录的所有内容
chmod -R mode dirname 修改目录名下的所有文件的许可权限
du dirname 给出指定目录及其子目录下文件占用硬盘中数据块的总数
find dirname -filter filename -action 找到指定目录下符号符号筛选的文件名并执行action
文件系统的内部结构:三层抽象
1.从磁盘到分区:磁盘被划分为多个分区,在实体内创建独立的区域。
2.从磁盘到块序列:磁盘上的磁片的磁道被划分为扇区,扇区是磁盘的基本存储单位。给磁盘上的数据块进行编号。
3.块序列到三个区域的划分。将磁盘块分成3部分:超级块,i-节点表,数据区
超级块:存放文件系统本身的信息
如:每个区域的大小,未被使用的磁盘块的信息,
i-节点表:存放文件属性
存放文件的属性:大小,所有者等,存放在 i-节点 的结构中。 i-节点固定大小,i-节点表是 i-节点结构的列表
文件系统中的每个文件都在该表中有一个i-节点。
i-节点表 中的 每个 i-节点通过位置来标识。如标识为2 的位于 i-节点表 的第三个位置
数据区:存放文件内容,磁盘上的所有块的大小都是一样的,如果文件大小超过一个块的内容,则文件内容会存放在多个磁盘块中。
例:创建新目录
1. 存储属性:内核找到一个空的i-节点,如i-节点47,将文件信息记录其中
2.文件内容的存储:文件需要3个磁盘存储块,内核从自由块的列表中找出3个数据块,如块627,200,992。分别存放数据
3.记录分配情况:文件按内容存放627,200,992,内核在i-节点的磁盘分区中记录了上述的块序列。
4.添加文件名到目录。文件名是 filename ,内核将入口47添加到目录文件。
目录:一个包含i-节点和文件名的表
ls -1ia 查看目录的内容:
1054940 .
1054934 ..
1055004 demodir
左边的是文件的i-节点号,右边是文件名。当前目录是 . 跟当前目录有关的大小,文件所有者,组等信息存放其中。
文件系统的实现:
cat filename 如何进行工作的。
1.在目录中寻找文件名:文件名存储在目录文件中,内核在目录文件中寻找包含字符串filename的记录,找到编号为47的i-节点号
2.定位i-节点并读取内容:内核会预先访问缓存区,然后访问磁盘。i-节点包含数据块编号的列表。
3.访问存储文件内容的数据块:找到相应的磁盘块627,200,992.
struct inode
{
struct hlist_node i_hash;
struct list_head i_list;
struct list_head i_sb_list;
struct list_head i_dentry;
unsigned long i_ino;
atomic_t i_count;
umode_t i_mode;
unsigned int i_nlink;
uid_t i_uid;
gid_t i_gid;
dev_t i_rdev;
loff_t i_size;
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
unsigned int i_blkbits;
unsigned long i_blksize;
unsigned long i_version;
unsigned long i_blocks;
unsigned short i_bytes;
unsigned char i_sock;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
struct semaphore i_sem;
struct rw_semaphore i_alloc_sem;
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
struct super_block *i_sb;
struct file_lock *i_flock;
struct address_space *i_mapping;
struct address_space i_data;
#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS];
#endif
/* These three should probably be a union */
struct list_head i_devices;
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
int i_cindex;
__u32 i_generation;
#ifdef CONFIG_DNOTIFY
unsigned long i_dnotify_mask; /* Directory notify events */
struct dnotify_struct *i_dnotify; /* for directory notifications */
#endif
unsigned long i_state;
unsigned long dirtied_when; /* jiffies of first dirtying */
unsigned int i_flags;
atomic_t i_writecount;
void *i_security;
union {
void *generic_ip;
} u;
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount;
#endif
}
i-节点中存储有文件的读写权限,用户id,组id等信息,当获取到文件的i-节点时,会检查这些权限是否符合。
用户看到的文件系统时目录和子目录的集合,每个目录能够包含文件和子目录,每个子目录有一个父目录,
在文件系统内部,目录是一个包含文件名与i-节点对的列表的文件。
文件系统是一些相互链接的数据结构,节点被称为i-节点,指针的集合被称为目录,叶子被称为链接
创建新的目录: mkdir
#include
#include
int ret=mkdir(const char *pathname, mode_t mode);
pathname=新目录名
mode=新目录的权限位的掩码
ret:-1=错误,0=成功
mkdir :创建新的目录节点并把它链接至文件系统数,即创建了一个i-节点,分配一个磁盘块存储内容,增加 . 和 .. 两个入口,正确配置它们的i-节点号,在父目录中增加节点的链接。
删除目录:rmdir
#include
int ret=rmdir(const char *pathname);
pathname=目录名
ret:-1=错误,0=成功
rm:从目录文件中删除一个记录:接受一个或多个文件名
使用 unlink
#include
int ret=unlink(const char *pathname);
pathname=需要删除的链接名
ret:-1=失败,0=成功
ln: 创建一个文件的链接
使用 link
#include
int ret=link(const char *oldpath, const char *newpath);
oldpath=原始链接名字
newpath=新链接名字
ret: -1=失败,0=成功
link 生成一个i-节点的链接,新链接包含原始链接的 i-节点号并且具有特定的名字,如果已存在相同名字的链接,link失败。
mv:重命名,改变文件和目录的名字或目录,仅调用 rename
#include
int ret=rename(const char *oldpath, const char *newpath);
oldpath=原始链接的名字
newpath=新建链接的名字
ret:-1=错误,0=成功
cd 修改进程的但钱目录 调用 chdir
#include
int ret=chdir(const char *path);
path=要到达的目录
ret:-1=错误 0=成功
多文件系统的组合
可以通过装载的形式将文件系统嵌入到已有的系统以获得某些支持,子树的根目录被嵌入到根文件系统的一个目录中,子树所在的目录被称作第二个系统的装载点。
网络文件系统也能够被装载
多重i-节点和设备交叉链接: link 和 rename 拒绝在不同文件系统间进行i-节点的转移。
硬链接:将目录链接到数的指针,也是将文件名和文件本身链接起来的指针。
符号链接:同各国名字引用文件,而不是i-节点。