当前位置: 首页 > news >正文

10.Lab Nine —— file system-下

 Symbolic links

添加符号链接

1.添加有关symlink系统调用的定义声明,包括kernel/syscall.h, kernel/syscall.c, user/usys.pluser/user.h.

2.添加新的文件类型T_SYMLINK到kernel/stat.h中,添加新的文件标识位O_NOFOLLOW到kernel/fcntl.h中

3.在kenel/sysfile.c中实现sys_symlink()函数

该函数用于生成符号链接,该符号链接相当于一个特殊的独立文件,里面存储的是目标文件的路径

4.修改kernel/sysfile中的sys_open()函数

该函数可以用来打开文件,对于符号链接一般情况下需要打开的是其目标文件,因此需要额外处理

(此处需要注意避免成环问题的出现)

/* 系统调用open的实现 */
uint64
sys_open(void)
{/* 路径名缓冲区 */char path[MAXPATH];/* 文件描述符和打开模式 */int fd, omode;/* 文件结构指针 */struct file *f;/* i节点指针 */struct inode *ip;/* 临时变量,用于存储函数调用返回值 */int n;/* 获取路径名和打开模式,如果出错则返回-1 */if((n = argstr(0, path, MAXPATH)) < 0 || argint(1, &omode) < 0)return -1;/* 开始一个文件操作 */begin_op();/* 如果需要创建文件 */if(omode & O_CREATE){/* 调用create函数创建文件,如果失败则返回-1 */ip = create(path, T_FILE, 0, 0);if(ip == 0){end_op();return -1;}} else {int symlink_depth = 0;/* 查找已存在的文件,如果失败则返回-1 */while(1){if((ip = namei(path)) == 0){end_op();return -1;}/* 加锁i节点 */ilock(ip);if(ip->type == T_SYMLINK && (omode & O_NOFOLLOW) == 0){//在跟踪符号链接时需要额外考虑到符号链接的目标可能还是符号链接, 此时需要递归的去跟踪目标链接直至得到真正的文件. 而这其中需要解决两个问题: 一是符号链接可能成环, 这样会一直递归地跟踪下去, 因此需要进行成环的检测; 另一方面是需要对链接的深度进行限制, 以减轻系统负担,这里把最大深度设成10if(++symlink_depth > 10){// too many layer of symlinks, might be a loopiunlockput(ip);end_op();return -1;}if(readi(ip, 0, (uint64)path, 0, MAXPATH) < 0){iunlockput(ip);end_op();return -1;}iunlockput(ip);}else{break;}}/* 如果是目录文件且不是只读打开,返回-1 */if(ip->type == T_DIR && omode != O_RDONLY){// // 如果是目录,并且打开模式不是 O_RDONLY(只读),则不能打开iunlockput(ip);end_op();return -1;}}/* 如果是设备文件,检查设备号是否有效,否则返回-1 */if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){iunlockput(ip);end_op();return -1;}/* 分配文件结构,如果失败则返回-1 */if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){if(f)fileclose(f);iunlockput(ip);end_op();return -1;}// //处理符号链接,即软连接,如果// if(ip->type == T_SYMLINK && !(omode & O_NOFOLLOW)){ //如果不是不可追踪//   //若符号链接指向的仍旧是符号链接,则递归跟随它,直到找到真正的指向文件//   //深度不能超过MAX_SYMLINK_DEPTH//   for(int i = 0; i < MAX_SYMLINK_DEPTH; i++){//     //读出符号链接指的路径//   }// }/* 根据文件类型设置文件结构的类型和主要设备号 */if(ip->type == T_DEVICE){f->type = FD_DEVICE;f->major = ip->major;} else {f->type = FD_INODE;f->off = 0;}/* 设置文件结构的i节点指针和读写权限 */f->ip = ip;f->readable = !(omode & O_WRONLY);f->writable = (omode & O_WRONLY) || (omode & O_RDWR);/* 如果要求截断文件,且文件类型是普通文件,则截断文件 */if((omode & O_TRUNC) && ip->type == T_FILE){itrunc(ip);}/* 解锁i节点 */iunlock(ip);/* 结束文件操作 */end_op();/* 返回文件描述符 */return fd;
}

这里也可以看一下硬链接的实现方式(kernel/sysfile)

// Create the path new as a link to the same inode as old.
//xv6硬链接实现方式
uint64 sys_link(void) {char name[DIRSIZ], new[MAXPATH], old[MAXPATH];struct inode *dp, *ip;// 从用户态获取参数 old 和 new,分别表示旧路径和新路径if(argstr(0, old, MAXPATH) < 0 || argstr(1, new, MAXPATH) < 0)return -1;// 开始文件系统操作事务begin_op();// 根据旧路径名找到 inodeif((ip = namei(old)) == 0){end_op();return -1;}// 对 inode 进行加锁ilock(ip);// 检查旧路径对应的 inode 是否为目录,如果是目录则不能创建硬链接if(ip->type == T_DIR){iunlockput(ip); // 解锁 inode 并释放引用end_op();return -1;}// 增加 inode 的链接数,因为即将创建一个新的硬链接指向该 inodeip->nlink++;iupdate(ip); // 更新 inode 的磁盘信息iunlock(ip); // 解锁 inode// 解析新路径中的目录名和文件名if((dp = nameiparent(new, name)) == 0)goto bad;// 对目录的 inode 进行加锁ilock(dp);// 检查新路径所在的目录的设备号与旧路径所在的设备号是否相同// 如果不相同,或者在新路径所在的目录中无法创建新的目录项,说明创建硬链接失败if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0){iunlockput(dp); // 解锁目录的 inode 并释放引用goto bad;}// 解锁目录的 inode 并释放引用iunlockput(dp);// 释放旧路径对应的 inode 的引用iput(ip);// 结束文件系统操作事务end_op();return 0;bad:// 创建硬链接失败时,需要回滚之前对旧路径 inode 的修改,即减少链接数ilock(ip);ip->nlink--;iupdate(ip);iunlockput(ip);end_op();return -1;
}

5.最后在Makefile中添加对测试文件symlinktest.c 的编译.

测试

相关文章:

10.Lab Nine —— file system-下

Symbolic links 添加符号链接 1.添加有关symlink系统调用的定义声明&#xff0c;包括kernel/syscall.h, kernel/syscall.c, user/usys.pl 和 user/user.h. 2.添加新的文件类型T_SYMLINK到kernel/stat.h中&#xff0c;添加新的文件标识位O_NOFOLLOW到kernel/fcntl.h中 3.在ken…...

低代码中实现数据映射的必要性与方案

在数字化转型的浪潮中&#xff0c;低代码平台因其快速开发和灵活性而受到越来越多企业的青睐。然而&#xff0c;随着业务需求的复杂化&#xff0c;单纯依赖低代码工具往往难以满足企业在数据处理和业务逻辑上的要求。数据映射作为连接不同数据源和业务逻辑的桥梁&#xff0c;显…...

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…...

四元组问题

目录 问题描述 输入格式 输出格式 样例输入 样例输出 说明 评测数据规模 运行限制 原题链接 代码思路 问题描述 从小学开始&#xff0c;小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期&#xff0c;他遇到了一个非常有趣的问题&…...

如何用Prometheus监控禁用了Actuator的SpringBoot?

需求来源 prometheus监控微服务一般都是使用micrometer结合actuator来做&#xff1a; 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency> <d…...

使用TensorFlow实现一个简单的神经网络:从入门到精通

使用TensorFlow实现一个简单的神经网络:从入门到精通 在现代数据科学和机器学习领域,神经网络是一个非常重要的工具。TensorFlow 是一个开源的深度学习框架,由 Google 开发和维护,它使得构建和训练神经网络变得更加容易。本文将详细介绍如何使用 TensorFlow 实现一个简单的…...

应用DFX能力介绍

一、HarmonyOS生态DFX能力范围 围绕开发者&#xff0c;构建三方应用和设备从开发到维护全生命周期所必需、有竞争力、有特色的调试调优、定位、维护能力。 二、HarmonyOS DFX能力全集 三、DFX设计主要范围 1、HiLog 日志分类 日志常用命令 日志级别 日志规则 2、HiAppEvent 完…...

第三篇 第20章工程计价数字化与智能化

第三篇 工程计价 第20章 工程计价数字化与智能化 20.1 BIM在工程计价中的应用 20.1.1 BIM概述 1.定义 在建设工程及设施全生命周期内,对其物理特征和功能特征信息进行数字化表达,依次设计、施工、运营的过程和结果的总称。应由核心层、共享层、专业领域层、资源层四个概念层…...

成语700词(46~65组)

目录 46.熟悉、了解、知晓相关(15 个)47.很常见不奇怪(6 个)48.看法一致与否(10 个)49.从细节看全貌(10 个)50.看事情透彻(11 个)51.对事情的态度与评价(7 个)52.数量多与少(11 个)53.建筑相关(6 个)54.相同与不同(17 个)55.技艺精湛(10 个)56.与观看欣赏相…...

linux如何配置静态IP

文章目录 使用ip命令&#xff08;临时配置&#xff09;Debian/Ubuntu系统&#xff08;使用netplan&#xff09;CentOS/RHEL系统&#xff08;使用nmcli或nmtui&#xff09;使用nmcli&#xff08;命令行界面&#xff09;使用nmtui&#xff08;文本用户界面&#xff09;通过图形界…...

Dependency Check:一款针对应用程序依赖组件的安全检测工具

关于Dependency Check Dependency-Check 是一款软件组合分析 &#xff08;SCA&#xff09; 工具&#xff0c;可尝试检测项目依赖项中包含的公开披露的漏洞。它通过确定给定依赖项是否存在通用平台枚举 &#xff08;CPE&#xff09; 标识符来实现此目的。如果找到&#xff0c;它…...

Python 从入门到实战28(文件的读操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了文件的打开、创建、关闭的相关知识。今天我们将…...

[leetcode刷题]面试经典150题之7同构字符串(简单)

这个题虽然是简单题&#xff0c;但是看了半天还是没啥好思路&#xff0c;最后看了解题学到了不少知识点 1.index() 函数查找序列中首次出现的元素索引 2.zip函数&#xff1a;用于将可迭代的对象&#xff08;如列表、元组、字典等&#xff09;作为参数&#xff0c;将对象中对应…...

【Keil5教程及技巧】耗时一周精心整理万字全网最全Keil5(MDK-ARM)功能详细介绍【建议收藏-细细品尝】

&#x1f48c; 所属专栏&#xff1a;【单片机开发软件技巧】 &#x1f600; 作  者&#xff1a; 于晓超 &#x1f680; 个人简介&#xff1a;嵌入式工程师&#xff0c;专注嵌入式领域基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大家&#xff1…...

【rust】 基于rust编写wasm,实现markdown转换为html文本

文章目录 背景转换预览核心代码前置依赖rustup换源cargo换源中科大 wasm-pack安装 背景 尝试用rust编写一款markdown转html的插件&#xff0c;通过wasm给html使用&#xff0c;不得不说体积挺小&#xff0c;约200K&#xff0c; 比go的wasm起步2MB看着舒服点。 不过go的配置和换…...

Java中的反向代理与负载均衡:Nginx与Java服务的集成

Java中的反向代理与负载均衡&#xff1a;Nginx与Java服务的集成 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨一下Java应用中的反向代理与负载均衡&#xff0c;以及如何通过Ngin…...

高级java每日一道面试题-2024年9月26日-运维篇[分布式篇]-如何保证每个服务器的时间都是同步的?

如果有遗漏,评论区告诉我进行补充 面试官: 如何保证每个服务器的时间都是同步的? 我回答: 确保服务器之间的时间同步对于维护分布式系统的一致性、日志记录的准确性以及安全认证的有效性非常重要。以下是几种常见的方法来保证服务器时间同步&#xff1a; 1. 使用NTP&#…...

探索MemGPT:AI界的新宠儿

文章目录 探索MemGPT&#xff1a;AI界的新宠儿1. 背景介绍2. MemGPT是什么&#xff1f;3. 如何安装MemGPT&#xff1f;4. 简单的库函数使用方法5. 场景应用场景一&#xff1a;创建持久聊天机器人场景二&#xff1a;文档分析场景三&#xff1a;多会话聊天互动 6. 常见Bug及解决方…...

处理RabbitMQ连接和认证问题

在使用RabbitMQ进行消息队列管理时&#xff0c;我们可能会遇到各种连接和认证问题。本文将介绍如何诊断和解决这些问题&#xff0c;并通过使用RabbitMQ的管理端进行登录验证来确保配置正确。 1. 问题概述 在最近的一次部署中&#xff0c;我们遇到了两个主要问题&#xff1a; …...

FFmpeg中结构释放小函数

用于FFmpeg一些结构内存释放问题 #pragma once #include <iostream>extern "C" { #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" #include "libavutil/avutil.h" #include "libavutil/frame.h"…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...