linux挂载
来源:互联网 发布:java int 0xff 编辑:程序博客网 时间:2024/04/30 08:40
在windows操作系统中, 挂载通常是指给磁盘分区(包括被虚拟出来的磁盘分区)分配一个盘符。 第三方软件,如磁盘分区管理软件、虚拟磁盘软件等,通常也附带挂载功能。
在linux操作系统中, 挂载是指将一个设备(通常是存储设备)挂接到一个已存在的目录上。 我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上, 然后通过访问这个目录来访问存储设备。
需要理解的是,
linux操作系统将所有的设备都看作文件,
它将整个计算机的资源都整合成一个大的文件目录。
我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上,
然后通过访问这个目录来访问存储设备。
linux中挂载命令为mount
实例:mount /dev/hd1 /mnt
mount属于系统调用,会最终调用sys_mount://
// 参数dev_name 是设备文件名,dir_name 是安装到的目录名,rw_flag 被安装文件的读写标志。// 将被加载的地方必须是一个目录名,并且对应的i 节点没有被其它程序占用。intsys_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
- linux挂载
- linux 挂载
- linux挂载
- linux 挂载
- linux挂载
- Linux挂载
- linux挂载
- linux 挂载
- linux 挂载
- Linux挂载
- Linux挂载Linux共享文件夹
- ubuntu linux挂载/ubuntu linux mount命令
- windows/linux挂载linux网络文件系统NFS
- windows和linux挂载
- linux挂载U盘
- 让Linux挂载NTFS
- linux挂载iso文件
- linux 启动 挂载rootfs
- Unity3D流体插件FluidSim使用总结
- js实现上传图片预览,购物车加减
- Start / Stop FTP server on FreeBSD / OpenBSD
- 浅谈ASP.NET调用淘宝API之初入江湖
- /etc/fstab
- linux挂载
- Java NIO——3 非阻塞与selector
- VS2010 安装 Boost 库 1.54
- 2013整理资料-UIViewController生命周期
- jQuery-uploadify3.2带有滚动条的文件上传
- 域名解析图解教程
- 基于赛灵思(Xilinx) FPGA的DisplayPort设计与实现
- iOS 多快好省的宏
- 岁月不曾辜负谁--写于26岁生日前