首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【linux学习指南】Ext系列文件系统(四)路径&&分区&&链接

【linux学习指南】Ext系列文件系统(四)路径&&分区&&链接

作者头像
学习起来吧
发布2025-01-01 08:48:58
发布2025-01-01 08:48:58
3350
举报
文章被收录于专栏:学习C/++学习C/++

🌠⽬录与⽂件名

问题:

  • 我们访问⽂件,都是⽤的⽂件名,没⽤过inode号啊?
  • ⽬录是⽂件吗?如何理解?

答案:

  • ⽬录也是⽂件,但是磁盘上没有⽬录的概念,只有⽂件属性+⽂件内容的概念。
  • ⽬录的属性不⽤多说,内容保存的是:⽂件名和Inode号的映射关系

readdir.c文件

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    DIR *dir = opendir(argv[1]); //系统调⽤,⾃⾏查阅

    if (!dir)
    {
        perror("opendir");
        exit(EXIT_FAILURE);
    }
    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL)
    { //
        系统调⽤,⾃⾏查阅

        // Skip the "." and ".." directory entries
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
        {
            continue;
        }
        printf("Filename: %s, Inode: %lu\n", entry->d_name, (unsigned long)entry->d_ino);
    }
    closedir(dir);
    return 0;
}
  • 所以,访问文件,必须打开当前目录,根据文件名,获得对应的inode号,然后进行文件访问
  • 所以,访问文件必须要知道当前工作目录,本质是必须能打开当前工作目录文件,查看目录文件的内容!

比如:要访问test.c,就必须打开test(当前工作目录) ,然后才能获取test.c对应的inode进而对文件进行访问。

🌠路径解析

问题:打开当前⼯作⽬录⽂件,查看当前⼯作⽬录⽂件的内容?当前⼯作⽬录不也是⽂件吗?我们访问 当前⼯作⽬录不也是只知道当前⼯作⽬录的⽂件名吗?要访问它,不也得知道当前⼯作⽬录的inode 吗?

  • 答案1:所以也要打开:当前⼯作⽬录的上级⽬录,额…,上级⽬录不也是⽬录吗??不还是上⾯的问题吗?
  • 答案2:所以类似"递归",需要把路径中所有的⽬录全部解析,出⼝是"/"根⽬录。
  • 最终答案3:⽽实际上,任何⽂件,都有路径,访问⽬标⽂件,⽐如:
代码语言:javascript
复制
 /home/whb/code/test/test/test.c

都要从根⽬录开始,依次打开每⼀个⽬录,根据⽬录名,依次访问每个⽬录下指定的⽬录,直到访问 到test.c。这个过程叫做Linux路径解析。

注意:

  1. 所以,我们知道了:访问⽂件必须要有⽬录+⽂件名=路径的原因
  2. 根⽬录固定⽂件名,inode号,⽆需查找,系统开机之后就必须知道

可是路径谁提供?

  • 你访问⽂件,都是指令/⼯具访问,本质是进程访问,进程有CWD!进程提供路径。
  • 你open⽂件,提供了路径

可是最开始的路径从哪⾥来?

  • 所以Linux为什么要有根目录,根目录下为什么要有那么多缺省目录?
  • 你为什么要有家目录,你自己可以新建目录?
  • 上面所有行为:本质就是在磁盘文件系统中,新建目录文件。而你新建的任何文件,都在你或者系统指定的目录下新建,这不就是天然就有路径了嘛!
  • 系统+用户共同构建Linux路径结构.

🌠路径缓存

问题1:Linux磁盘中,存在真正的⽬录吗? 答案:不存在,只有⽂件。只保存⽂件属性+⽂件内容

问题2:访问任何⽂件,都要从/⽬录开始进⾏路径解析? 答案:原则上是,但是这样太慢,所以Linux会缓存历史路径结构

问题3:Linux⽬录的概念,怎么产⽣的? 答案:打开的⽂件是⽬录的话,由OS⾃⼰在内存中进⾏路径维护

Linux中,在内核中维护树状路径结构的内核结构体叫做:struct dentry

代码语言:javascript
复制
struct dentry
{
    atomic_t d_count;     /* protected by d_lock */
    unsigned int d_flags; /* per dentry lock */
    spinlock_t d_lock;    /* Where the name belongs to - NULL is * negative */
    /*
     * The next three fields are touched by __d_lookup.  Place them here
     * so they all fit in a cache line.
     */
    struct hlist_node d_hash; /* lookup hash list */
    struct dentry *d_parent;  /*parent directory */
    struct qstr d_name;

    struct list_head d_lru; /* LRU list */
                            /*
                             * d_child and d_rcu can share memory
                             */
    union
    {
        struct list_head d_child; /* child of parent list */
        struct rcu_head d_rcu;
    } d_u;
    struct list_head d_subdirs; /* our children */
    struct list_head d_alias; /* inode alias list */
    unsigned long d_time; /* used by d_revalidate */
    struct dentry_operations *d_op;
    struct super_block *d_sb; /* The root of the dentry tree */
    void *d_fsdata; /* fs-specific data */
#ifdef CONFIG_PROFILING
    struct dcookie_struct *d_cookie; /* cookie, if any */
#endif
    int d_mounted;
    unsigned char d_iname[DNAME_INLINE_LEN_MIN];  /* small names */
};

注意:

  • 每个文件其实都要有对应的dentry结构,包括普通文件。这样所有被打开的文件,就可以在内存中形成整个树形结构
  • 整个树形节点也同时会隶属于LRU(Least Recently Used,最近最少使用)结构中,进行节点淘汰
  • 整个树形节点也同时会隶属于Hash,方便快速查找
  • 更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何文件,都在先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry结构,缓存新路径

🌠挂载分区

我们已经能够根据inode号在指定分区找⽂件了,也已经能根据⽬录⽂件内容,找指定的inode了,在 指定的分区内,我们可以为所欲为了。可是: 问题:inode不是不能跨分区吗?Linux不是可以有多个分区吗?我怎么知道我在哪⼀个分区???

详细挂载分区可查看【linux学习指南】磁盘分区挂载到目录,形成文件系统挂载点

🌉 ⽂件系统总结

🌠软硬连接

🌉 硬链接

我们看到,真正找到磁盘上⽂件的并不是⽂件名,⽽是inode。其实在linux中可以让多个⽂件名对应 于同⼀个inode。

代码语言:javascript
复制
[root@localhost linux]# touch abc
 [root@localhost linux]# ln abc def
 [root@localhost linux]# ls -li abc def
 263466 abc
 263466 def
  • abc和def的链接状态完全相同,他们被称为指向⽂件的硬链接。内核记录了这个连接数,inode 263466 的硬连接数为2。
  • 我们在删除⽂件时⼲了两件事情:1.在⽬录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。

🌉 软链接

硬链接是通过inode引⽤另外⼀个⽂件,软链接是通过名字引⽤另外⼀个⽂件,但实际上,新的⽂件被引⽤的⽂件的inode不同,应⽤常⻅上可以想象成⼀个快捷⽅式。在shell中的做法

代码语言:javascript
复制
[root@localhost linux]# ln -s abc.s abc
 [root@localhost linux]# ls -li
 263563 -rw-r--r--. 2 root root 0 9⽉  15 17:45 abc
 261678 lrwxrwxrwx. 1 root root 3 9⽉  15 17:53 abc.s -> abc
 263563 -rw-r--r--. 2 root root 0 9⽉  15 17:45 def

acm 下⾯解释⼀下⽂件的三个时间:

  • Access最后访问时间
  • Modify⽂件内容最后修改时间
  • Change属性最后修改时间

🌉 软硬连接对⽐

  • 软连接是独⽴⽂件
  • 硬链接只是⽂件名和⽬标⽂件inode的映射关系

🌉软硬连接的⽤途:

  • 硬链接 .和… 就是硬链接
  • ⽂件备份

软连接

  • 类似快捷⽅式
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🌠⽬录与⽂件名
  • 🌠路径解析
  • 🌠路径缓存
  • 🌠挂载分区
    • 🌉 ⽂件系统总结
  • 🌠软硬连接
    • 🌉 硬链接
    • 🌉 软链接
    • 🌉 软硬连接对⽐
    • 🌉软硬连接的⽤途:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档