linux fs源代码分析,linux内核umount源代码分析

之前我们讲过mount的内核源代码,今天我们来一起看一下umount系统调用的内核源代码实现吧。

首先看sys_umount函数,定义在fs/namespace.c,定义如下

asmlinkage long sys_umount(char __user * name, int flags)

{

struct nameidata nd;

int retval;

/*之前讲过的,格局传入的路径名返回文件的inode和vfsmount结构体*/

retval = __user_walk(name, LOOKUP_FOLLOW, &nd);

/*如果失败了就返回错误代码*/

if (retval)

goto out;

retval = -EINVAL;

/*如果传入的umount点不是对应的挂载文件系统的根节点,也返回*/

if (nd.dentry != nd.mnt->mnt_root)

goto dput_and_out;

/*命名空间检查*/

if (!check_mnt(nd.mnt))

goto dput_and_out;

retval = -EPERM;

/*之前讲过,权限检查*/

if (!capable(CAP_SYS_ADMIN))

goto dput_and_out;

/*主要工作*/

retval = do_umount(nd.mnt, flags);

dput_and_out:

path_release_on_umount(&nd);

out:

return retval;

}

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

static int do_umount(struct vfsmount *mnt, int flags)

{

/*挂载点的超级块*/

struct super_block *sb = mnt->mnt_sb;

int retval;

LIST_HEAD(umount_list);

/*安全操作,可以不必管*/

retval = security_sb_umount(mnt, flags);

if (retval)

return retval;

/*如果挂载时间到了 */

if (flags & MNT_EXPIRE) {

/*当前进程的根节点不能umount*/

if (mnt == current->fs->rootmnt ||

flags & (MNT_FORCE | MNT_DETACH))

return -EINVAL;

/*如果有其他进程子啊用,不能umount*/

if (atomic_read(&mnt->mnt_count) != 2)

return -EBUSY;

/*expiry位标识是否超时*/

if (!xchg(&mnt->mnt_expiry_mark, 1))

return -EAGAIN;

}

/*调用超级块的函数umount_begin做对应的初始工作,以ext2文件系统为例,ext2没有umount_begin函数,所以这个函数视不同的文件系统而不同*/

lock_kernel();

if (sb->s_op->umount_begin)

sb->s_op->umount_begin(mnt, flags);

unlock_kernel();

/*如果卸载的是当前进程的根文件系统根节点,并且不是卸载,是remount,修改某些flag*/

if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {

/*调用do_remount_sb更改flags*/

down_write(&sb->s_umount);

if (!(sb->s_flags & MS_RDONLY)) {

lock_kernel();

DQUOT_OFF(sb);

retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);

unlock_kernel();

}

up_write(&sb->s_umount);

return retval;

}

down_write(&namespace_sem);

spin_lock(&vfsmount_lock);

event++;

retval = -EBUSY;

if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {

if (!list_empty(&mnt->mnt_list))

/*把vfsmount结构体从链表上去除*/

umount_tree(mnt, 1, &umount_list);

retval = 0;

}

spin_unlock(&vfsmount_lock);

/*安全操作,可以不管*/

if (retval)

security_sb_umount_busy(mnt);

up_write(&namespace_sem);

release_mounts(&umount_list);

return retval;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值