linux挂载

在windows操作系统中, 挂载通常是指给磁盘分区(包括被虚拟出来的磁盘分区)分配一个盘符。 第三方软件,如磁盘分区管理软件、虚拟磁盘软件等,通常也附带挂载功能。

 在linux操作系统中, 挂载是指将一个设备(通常是存储设备)挂接到一个已存在的目录上。 我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上, 然后通过访问这个目录来访问存储设备。

需要理解的是,
linux 操作系统将所有的设备都看作文件,
它将整个计算机的资源都整合成一个大的 文件目录
我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上,
然后通过访问这个目录来访问 存储设备
linux中挂载命令为mount
实例:mount   /dev/hd1   /mnt
mount属于系统调用,会最终调用sys_mount://
 // 参数dev_name 是设备文件名,dir_name 是安装到的目录名,rw_flag 被安装文件的读写标志。
// 将被加载的地方必须是一个目录名,并且对应的i 节点没有被其它程序占用。
int
sys_mount (char *dev_name, char *dir_name, int rw_flag)
{
struct m_inode *dev_i, *dir_i;
struct super_block *sb;
int dev;

// 首先根据设备文件名找到对应的i 节点,并取其中的设备号。
// 对于块特殊设备文件,设备号在i 节点的i_zone[0]中。
if (!(dev_i = namei (dev_name)))
return -ENOENT;
dev = dev_i->i_zone[0];
// 如果不是块设备文件,则释放刚取得的i 节点dev_i,返回出错码。
if (!S_ISBLK (dev_i->i_mode))
{
iput (dev_i);
return -EPERM;
}
// 释放该设备文件的i 节点dev_i。
iput (dev_i);
// 根据给定的目录文件名找到对应的i 节点dir_i。
if (!(dir_i = namei (dir_name)))
return -ENOENT;
// 如果该i 节点的引用计数不为1(仅在这里引用),或者该i 节点的节点号是根文件系统的节点
// 号1,则释放该i 节点,返回出错码。
if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO)
{
iput (dir_i);
return -EBUSY;
}
// 如果该节点不是一个目录文件节点,则也释放该i 节点,返回出错码。
if (!S_ISDIR (dir_i->i_mode))
{
iput (dir_i);
return -EPERM;
}
// 读取将安装文件系统的超级块,如果失败则也释放该i 节点,返回出错码。
if (!(sb = read_super (dev)))
{
iput (dir_i);
return -EBUSY;
}
// 如果将要被安装的文件系统已经安装在其它地方,则释放该i 节点,返回出错码。
if (sb->s_imount)
{
iput (dir_i);
return -EBUSY;
}
// 如果将要安装到的i 节点已经安装了文件系统(安装标志已经置位),则释放该i 节点,返回出错码。
if (dir_i->i_mount)
{
iput (dir_i);
return -EPERM;
}
// 被安装文件系统超级块的“被安装到i 节点”字段指向安装到的目录名的i 节点。
sb->s_imount = dir_i;
// 设置安装位置i 节点的安装标志和节点已修改标志。/* 注意!这里没有iput(dir_i) */
dir_i->i_mount = 1;           /* 这将在umount 内操作 */
dir_i->i_dirt = 1;            /* NOTE! we don't iput(dir_i) */
return 0;                     /* we do that in umount */
}
总的来说,以上代码基本流程:
1)分析路径开始,准备查找hd1设备的挂节点:根据/dev/hd1线索把硬盘的超级块找到,进而找到s_imount
2)以根目录i节点为起点,得到dev目录文件的i节点
3)从dev目录文件中找到代表hd1设备文件的目录项
4)得到hd1设备文件的i节点号
5)释放dev目录文件的相关内容
6)得到hd1设备文件的i节点
7)获取hd1设备的设备号
8)释放hd1设备文件的i节点
9)获取虚拟盘上的挂节点
10)得到hd1设备文件的超级块
11)读取hd1设备文件的超级块,加载逻辑块位图和i节点位图
12)将hd1设备文件与mnt目录文件的i节点挂接
涉及到的几个关键数据结构
struct buffer_head
{
char *b_data;            /* pointer to data block (1024 bytes) *///指针。
unsigned long b_blocknr; /* block number */// 块号。
unsigned short b_dev;      /* device (0 = free) */// 数据源的设备号。
unsigned char b_uptodate;   // 更新标志:表示数据是否已更新。
unsigned char b_dirt;       /* 0-clean,1-dirty *///修改标志:0 未修改,1 已修改.
unsigned char b_count;      /* users using this block */// 使用的用户数。
unsigned char b_lock;       /* 0 - ok, 1 -locked */// 缓冲区是否被锁定。
struct task_struct *b_wait;   // 指向等待该缓冲区解锁的任务。
struct buffer_head *b_prev;   // hash 队列上前一块(这四个指针用于缓冲区的管理)。
struct buffer_head *b_next;    // hash 队列上下一块。
struct buffer_head *b_prev_free;  // 空闲表上前一块。
struct buffer_head *b_next_free;   // 空闲表上下一块。
};

// 磁盘上的索引节点(i 节点)数据结构。
struct d_inode
{
unsigned short i_mode;          // 文件类型和属性(rwx 位)。
unsigned short i_uid;           // 用户id(文件拥有者标识符)。
unsigned long i_size;           // 文件大小(字节数)。
unsigned long i_time;           // 修改时间(自1970.1.1:0 算起,秒)。
unsigned char i_gid;                    // 组id(文件拥有者所在的组)。
unsigned char i_nlinks;         // 链接数(多少个文件目录项指向该i 节点)。
unsigned short i_zone[9];               // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。
// zone 是区的意思,可译成区段,或逻辑块。
};

// 这是在内存中的i 节点结构。前7 项与d_inode 完全一样。
struct m_inode
{
unsigned short i_mode;          // 文件类型和属性(rwx 位)。
unsigned short i_uid;           // 用户id(文件拥有者标识符)。
unsigned long i_size;           // 文件大小(字节数)。
unsigned long i_mtime;          // 修改时间(自1970.1.1:0 算起,秒)。
unsigned char i_gid;                    // 组id(文件拥有者所在的组)。
unsigned char i_nlinks;         // 文件目录项链接数。
unsigned short i_zone[9];               // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。
/* these are in memory also */
struct task_struct *i_wait;     // 等待该i 节点的进程。
unsigned long i_atime;          // 最后访问时间。
unsigned long i_ctime;          // i 节点自身修改时间。
unsigned short i_dev;           // i 节点所在的设备号。
unsigned short i_num;           // i 节点号。
unsigned short i_count;         // i 节点被使用的次数,0 表示该i 节点空闲。
unsigned char i_lock;           // 锁定标志。
unsigned char i_dirt;                   // 已修改(脏)标志。
unsigned char i_pipe;           // 管道标志。
unsigned char i_mount;          // 安装标志。
unsigned char i_seek;           // 搜寻标志(lseek 时)。
unsigned char i_update;         // 更新标志。
};

// 文件结构(用于在文件句柄与i 节点之间建立关系)
struct file
{
unsigned short f_mode;          // 文件操作模式(RW 位)
unsigned short f_flags;         // 文件打开和控制的标志。
unsigned short f_count;         // 对应文件句柄(文件描述符)数。
struct m_inode *f_inode;        // 指向对应i 节点。
off_t f_pos;                            // 文件位置(读写偏移值)。
};

// 内存中磁盘超级块结构。
struct super_block
{
unsigned short s_ninodes;               // 节点数。
unsigned short s_nzones;                        // 逻辑块数。
unsigned short s_imap_blocks;   // i 节点位图所占用的数据块数。
unsigned short s_zmap_blocks;   // 逻辑块位图所占用的数据块数。
unsigned short s_firstdatazone; // 第一个数据逻辑块号。
unsigned short s_log_zone_size; // log(数据块数/逻辑块)。(以2 为底)。
unsigned long s_max_size;               // 文件最大长度。
unsigned short s_magic;                 // 文件系统魔数。
/* These are only in memory */
struct buffer_head *s_imap[8];  // i 节点位图缓冲块指针数组(占用8 块,可表示64M)。
struct buffer_head *s_zmap[8];  // 逻辑块位图缓冲块指针数组(占用8 块)。
unsigned short s_dev;                   // 超级块所在的设备号。
struct m_inode *s_isup;                 // 被安装的文件系统根目录的i 节点。(isup-super i)
struct m_inode *s_imount;               // 被安装到的i 节点。
unsigned long s_time;                   // 修改时间。
struct task_struct *s_wait;             // 等待该超级块的进程。
unsigned char s_lock;                   // 被锁定标志。
unsigned char s_rd_only;                        // 只读标志。
unsigned char s_dirt;                   // 已修改(脏)标志。
};

// 磁盘上超级块结构。上面125-132 行完全一样。
struct d_super_block
{
unsigned short s_ninodes;               // 节点数。
unsigned short s_nzones;                        // 逻辑块数。
unsigned short s_imap_blocks;   // i 节点位图所占用的数据块数。
unsigned short s_zmap_blocks;   // 逻辑块位图所占用的数据块数。
unsigned short s_firstdatazone; // 第一个数据逻辑块。
unsigned short s_log_zone_size; // log(数据块数/逻辑块)。(以2 为底)。
unsigned long s_max_size;               // 文件最大长度。
unsigned short s_magic;                 // 文件系统魔数。
};

// 文件目录项结构。
struct dir_entry
{
unsigned short inode;           // i 节点。
char name[NAME_LEN];            // 文件名。
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

failwest9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值