一、问题现象

1、使用ls、cp、mv、cat、rm、mkdir、echo命令操作文件未结束之前拔掉U盘,自己写的自动卸载U盘程序会出现死机现象。

二、问题原因

1、每次进行文件操作需要用到互斥锁的,流程:文件系统上锁–文件操作–文件系统解锁。但是上述命令所调用的函数是没有使用互斥锁,操作文件的时候拔掉U盘触发dfs_unmount函数卸载U盘,最终现象为两个线程同时对U盘进行文件操作发生异常。

三、解决方案

1、加上互斥锁即可,系统中已经有现成dfs的互斥锁函数dfs_lock和dfs_unlock,调用即可。在ls、cp、mv、cat、rm、mkdir、echo所调用的函数前进行dfs_lock,调用完成后dfs_unlock就可以解决问题。
2、按照上述进行解决其实使用cat时,拔掉U盘虽然不会死机,但是仍然会有异常发生,具体我会在下一篇博文讲到。
修改后的代码,我就不一一截图,直接上修改过的函数,这些函数都是在msh.c。

int cmd_ls(int argc, char **argv)
{extern void ls(const char *pathname);dfs_lock();if (argc == 1){#ifdef DFS_USING_WORKDIRls(working_directory);
#elsels("/");
#endif}else{ls(argv[1]);}dfs_unlock();return 0;
}int cmd_cp(int argc, char **argv)
{void copy(const char *src, const char *dst);dfs_lock();if (argc != 3){rt_kprintf("Usage: cp SOURCE DEST\n");rt_kprintf("Copy SOURCE to DEST.\n");}else{copy(argv[1], argv[2]);}dfs_unlock();return 0;
}int cmd_mv(int argc, char **argv)
{int res = 0;dfs_lock();if (argc != 3){rt_kprintf("Usage: mv SOURCE DEST\n");rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n");}else{int fd;char *dest = RT_NULL;rt_kprintf("%s => %s\n", argv[1], argv[2]);fd = open(argv[2], O_DIRECTORY, 0);if (fd >= 0){char *src;close(fd);/* it's a directory */dest = (char *)rt_malloc(DFS_PATH_MAX);if (dest == RT_NULL){rt_kprintf("out of memory\n");res = -RT_ENOMEM;goto end;}src = argv[1] + rt_strlen(argv[1]);while (src != argv[1]){if (*src == '/') break;src --;}rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src);}else{fd = open(argv[2], O_RDONLY, 0);if (fd >= 0){close(fd);unlink(argv[2]);}dest = argv[2];}rename(argv[1], dest);if (dest != RT_NULL && dest != argv[2]) rt_free(dest);}end:dfs_unlock();return res;
}int cmd_cat(int argc, char **argv)
{int index;extern void cat(const char *filename);dfs_lock();if (argc == 1){rt_kprintf("Usage: cat [FILE]...\n");rt_kprintf("Concatenate FILE(s)\n");goto end;}for (index = 1; index < argc; index ++){cat(argv[index]);}end:dfs_unlock();return 0;
}int cmd_rm(int argc, char **argv)
{int index, n;char f = 0, r = 0, v = 0;dfs_lock();if (argc == 1){rt_kprintf("Usage: rm option(s) FILE...\n");rt_kprintf("Remove (unlink) the FILE(s).\n");goto end;}if (argv[1][0] == '-'){for (n = 0; argv[1][n]; n++){switch (argv[1][n]){case 'f': f = 1; break;case 'r': r = 1; break;case 'v': v = 1; break;case '-': break;default:rt_kprintf("Error: Bad option: %c\n", argv[1][n]);goto end;}}argc -= 1;argv = argv + 1;}for (index = 1; index < argc; index ++){struct stat s;if (stat (argv[index], &s) == 0){if (s.st_mode & S_IFDIR){if (r == 0)rt_kprintf("cannot remove '%s': Is a directory\n", argv[index]);elsedirectory_delete_for_msh(argv[index], f, v);}else if (s.st_mode & S_IFREG){if (unlink(argv[index]) != 0){if (f == 0)rt_kprintf("cannot remove '%s'\n", argv[index]);}else if (v){rt_kprintf("removed '%s'\n", argv[index]);}}}else if (f == 0){rt_kprintf("cannot remove '%s': No such file or directory\n", argv[index]);}}end:dfs_unlock();return 0;
}int cmd_mkdir(int argc, char **argv)
{dfs_lock();if (argc == 1){rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n");rt_kprintf("Create the DIRECTORY, if they do not already exist.\n");}else{mkdir(argv[1], 0);}dfs_unlock();return 0;
}int cmd_df(int argc, char** argv)
{dfs_lock();if (argc != 2){df("/");}else{if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0)){rt_kprintf("df [path]\n");}else{df(argv[1]);}}dfs_unlock();return 0;
}int cmd_echo(int argc, char** argv)
{dfs_lock();if (argc == 2){rt_kprintf("%s\n", argv[1]);}else if (argc == 3){int fd;fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0);if (fd >= 0){write (fd, argv[1], strlen(argv[1]));close(fd);}else{rt_kprintf("open file:%s failed!\n", argv[2]);}}else{rt_kprintf("Usage: echo \"string\" [filename]\n");}dfs_unlock();return 0;
}

RT-Thread:在dfs中使用cat、cp等命令时拔掉U盘死机问题相关推荐

  1. qq无法启动此程序计算机中丢失dll,电脑打开QQ提示丢失DLL文件死机怎么处理

    QQ是我们常用的一款聊天工具,我想很多人对它并不陌生,但是有时候我们想打开使用它的时候,却发现打不开,并提示丢失DLL文件,之后死机,那么遇到这种情况我们具体该怎么解决呢?下面就由学习啦小编跟大家分享 ...

  2. 解决: cp -rf 命令中参数 -f 失效 ( 依旧要手动确认 )

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 运行  cp -rf 命令时依旧给出无数提示,要求确认,很是麻烦,如下图: 2. 可能原因:当 ...

  3. FreeRTOS+STM32F103中断中发送任务通知单片机死机问题

    最近在调试FreeRTOS系统遇到了一个比较奇怪的问题,在STM32F103最小系统上调试任务通知模拟事件标志组功能时,中断一触发,单片机就会死机.通过查询方式发送任务通知没任何问题,一旦用按键触发外 ...

  4. 问题二十三:C++中debug简单的运行死机问题

    其实,"模拟不同材料颜色"章节中,刚添加完相关code之后,运行出现过死机. 将采样次数尽可能降低,简化过程,方便分析问题. 在main()函数添几条log,为了判断死在main( ...

  5. UCOS中调用USMART死机解决办法

    最近在UCOSIII中调用USMART时,会出现死机现象. 在网上找的解决办法,大部份提供的思路不太正确.现在把自己的解决方法给大家分享一下,欢迎大家提供更好的解决方案.(以原子例程为例) 1.在us ...

  6. rt thread studio使用QBOOT和片外flash实现OTA升级

    我们这里要使用单片机外部flash作为OTA的下载分区,外部flash硬件连接关系 PB3-->SPI3_CLK PB4-->SPI3_MISO PB5-->SPI3_MOSI PE ...

  7. stm32f407单片机rt thread 片外spi flash OTA升级配置示例

    参考地址https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/ 第一步,生成Boot ...

  8. 关于RT thread系统节拍时钟的配置

    关于RT thread系统节拍时钟的配置                  -----本文基于rt-thread-3.1.3版本编写 首先,使用RTthread OS时,要配置(或者明白)它的系统节拍 ...

  9. RT Thread Free Modbus移植问题整理

    RT Thread Free Modbus移植问题整理 问题描述: 在读写寄存器中,写数据正常,只能读1个寄存器的值,多个值会异常. 在移植过程中发现串口(或RS485)数据接收长度异常. 一.环境描 ...

最新文章

  1. 遥感图像+CNN,预测区域人口收入水平
  2. 在ArcEngine下实现图层属性过滤的两种方法
  3. 金融系列4《基本指令》
  4. Excel VBA中的等价(Eqv)和蕴含(Imp)
  5. CornerEigenValsAndVecs函数
  6. QT中封装的IP地址的widget
  7. [IE技巧] 如何禁止用户关闭IE浏览器
  8. 0-pyqt5开发环境搭建
  9. 前端学习(1543):MVC的组成部分
  10. linux备份mysql怎样操作,Linux下自动备份MySQL数据库详细操作步骤(转载)
  11. chrome/firefox插件ie tab,解决无法使用网银的问题
  12. 随机抽样方法——DataFrame.sample()
  13. dwcs6 mysql站点_在Dreamweaver CS6中如何新建站点的方法
  14. 神经网络算法的关键参数,神经网络计算方法
  15. 破解Esxi服务器中Windows虚机密码(Esxi服务器Windows虚拟机忘记密码解决方案)
  16. LeetCode93—Restore IP Addresses
  17. python代码画人物_Python绘制可爱的卡通人物 | 【turtle使用】
  18. linux build文件,从源代码到可执行文件——编译全过程解析
  19. 简化版的宿舍管理系统(有细微的逻辑问题,没优化)
  20. java实现多元线性回归

热门文章

  1. Will , will be 的差別以及用法
  2. 如何注册小程序账号和下载小程序开发工具
  3. 精仿马上有号账号交易平台源码支持个人二维码收款
  4. Python数据展示 - 生成表格图片
  5. 从零开发HarmonyOS(鸿蒙)运动手表小游戏——黑白翻棋
  6. bootstrap4.3.1 导航栏鼠标悬停下拉显示
  7. 智慧船舶带来港口革命,可视化成为主力军
  8. es中的ClusterStateApplier和ClusterStateListener
  9. mysqldump和XBK备份
  10. 2021ICPC网络赛第二场The 2021 ICPC Asia Regionals Online Contest (II) 【L Euler Function】