linux内核umount源代码分析

r囧r小猫 2022-08-21 03:07 459阅读 0赞

之前我们讲过mount的内核源代码,今天我们来一起看一下umount系统调用的内核源代码实现吧。
首先看sys_umount函数,定义在fs/namespace.c,定义如下

  1. asmlinkage long sys_umount(char __user * name, int flags)
  2. {
  3. struct nameidata nd;
  4. int retval;
  5. /*之前讲过的,格局传入的路径名返回文件的inode和vfsmount结构体*/
  6. retval = __user_walk(name, LOOKUP_FOLLOW, &nd);
  7. /*如果失败了就返回错误代码*/
  8. if (retval)
  9. goto out;
  10. retval = -EINVAL;
  11. /*如果传入的umount点不是对应的挂载文件系统的根节点,也返回*/
  12. if (nd.dentry != nd.mnt->mnt_root)
  13. goto dput_and_out;
  14. /*命名空间检查*/
  15. if (!check_mnt(nd.mnt))
  16. goto dput_and_out;
  17. retval = -EPERM;
  18. /*之前讲过,权限检查*/
  19. if (!capable(CAP_SYS_ADMIN))
  20. goto dput_and_out;
  21. /*主要工作*/
  22. retval = do_umount(nd.mnt, flags);
  23. dput_and_out:
  24. path_release_on_umount(&nd);
  25. out:
  26. return retval;
  27. }

我们继续看do_umount函数,do_umount函数定义在fs/namespace.c,定义如下

  1. static int do_umount(struct vfsmount *mnt, int flags)
  2. {
  3. /*挂载点的超级块*/
  4. struct super_block *sb = mnt->mnt_sb;
  5. int retval;
  6. LIST_HEAD(umount_list);
  7. /*安全操作,可以不必管*/
  8. retval = security_sb_umount(mnt, flags);
  9. if (retval)
  10. return retval;
  11. /*如果挂载时间到了 */
  12. if (flags & MNT_EXPIRE) {
  13. /*当前进程的根节点不能umount*/
  14. if (mnt == current->fs->rootmnt ||
  15. flags & (MNT_FORCE | MNT_DETACH))
  16. return -EINVAL;
  17. /*如果有其他进程子啊用,不能umount*/
  18. if (atomic_read(&mnt->mnt_count) != 2)
  19. return -EBUSY;
  20. /*expiry位标识是否超时*/
  21. if (!xchg(&mnt->mnt_expiry_mark, 1))
  22. return -EAGAIN;
  23. }
  24. /*调用超级块的函数umount_begin做对应的初始工作,以ext2文件系统为例,ext2没有umount_begin函数,所以这个函数视不同的文件系统而不同*/
  25. lock_kernel();
  26. if (sb->s_op->umount_begin)
  27. sb->s_op->umount_begin(mnt, flags);
  28. unlock_kernel();
  29. /*如果卸载的是当前进程的根文件系统根节点,并且不是卸载,是remount,修改某些flag*/
  30. if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
  31. /*调用do_remount_sb更改flags*/
  32. down_write(&sb->s_umount);
  33. if (!(sb->s_flags & MS_RDONLY)) {
  34. lock_kernel();
  35. DQUOT_OFF(sb);
  36. retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
  37. unlock_kernel();
  38. }
  39. up_write(&sb->s_umount);
  40. return retval;
  41. }
  42. down_write(&namespace_sem);
  43. spin_lock(&vfsmount_lock);
  44. event++;
  45. retval = -EBUSY;
  46. if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
  47. if (!list_empty(&mnt->mnt_list))
  48. /*把vfsmount结构体从链表上去除*/
  49. umount_tree(mnt, 1, &umount_list);
  50. retval = 0;
  51. }
  52. spin_unlock(&vfsmount_lock);
  53. /*安全操作,可以不管*/
  54. if (retval)
  55. security_sb_umount_busy(mnt);
  56. up_write(&namespace_sem);
  57. release_mounts(&umount_list);
  58. return retval;
  59. }

发表评论

表情:
评论列表 (有 0 条评论,459人围观)

还没有评论,来说两句吧...

相关阅读

    相关 查看linux内核源代码

    这里介绍的就是通过自己的虚拟机进去查看你linux系统的内核源代码,当然也可以去网站下载,自己按需使用 1.源码路径 一般路径都是在根目录下的/usr/src下,其

    相关 linux内核capable源代码分析

    linux内核里对于进程的权限管理有一个很重要的函数capable,以前看了好多遍,今天下决心搞定他,也在此立下一个碑,以后有谁想搞明白他的话,我还可以提供一些帮助。 ca

    相关 linux内核read操作源代码分析

    read操作是任何操作系统里的基本操作,我们来看一下在linux内核里,read文件是怎样实现的。 read函数在用户空间是由read系统调用实现的,由编译器编译成软中断i