需要一个现有目录作为挂载点。
$ ls
$ sudo mount /dev/sdb2 ./datadisk
mount: mount point ./datadisk does not exist
$ mkdir datadisk
$ sudo mount /dev/sdb2 ./datadisk
$
Run Code Online (Sandbox Code Playgroud)
我觉得它很混乱,因为它覆盖了目录的现有内容。挂载点目录有两种可能的内容可能会意外切换(对于未执行挂载的用户)。
为什么不会mount
发生在新创建的目录中?这就是图形操作系统显示可移动媒体的方式。目录是挂载(存在)还是未挂载(不存在)会很清楚。我很确定有一个很好的理由,但我还没有发现它。
pjc*_*c50 53
这是一个实现细节泄露的案例。
在 UNIX 系统中,每个目录都由映射到inode编号的名称列表组成。inode 保存元数据,它告诉系统它是文件、目录、特殊设备、命名管道等。如果它是文件或目录,它还告诉系统在磁盘上的何处找到文件或目录内容。大多数 inode 是文件或目录。将列出 inode 编号的-i
选项ls
。
挂载文件系统需要一个目录 inode 并在内核的内存副本上设置一个标志,以说明“实际上,在查找此目录的内容时,会查看其他文件系统”(请参阅本演示文稿的幻灯片 10)。这相对容易,因为它正在更改单个数据项。
为什么它不为您创建一个指向新 inode 的目录条目?有两种方法可以实现,这两种方法都有缺点。一种是将一个新目录物理写入文件系统 - 但如果文件系统是只读的,那将失败!另一种方法是向每个目录列表过程添加一个实际上并不存在的“额外”事物列表。这很繁琐,并且可能会对每个文件操作造成很小的性能影响。
如果您想要动态创建的挂载点,automount
系统可以执行此操作。特殊非磁盘文件系统也可以随意创建目录,例如proc
,sys
,devfs
等等。
编辑:另请参阅“挂载”包含内容的现有文件夹时会发生什么的答案?
Pet*_*des 20
如果mount(2)
需要创建一个新目录作为挂载点,则无法在只读文件系统下挂载任何内容。那将是愚蠢的,所以我们可以排除这种情况。
如果 mount可以选择创建一个新目录作为挂载点,那会很奇怪。这不像挂载/卸载一直发生,因此在内核中放入额外的逻辑以通过单个系统调用完成这两个步骤不会是一个重要的加速。如果需要,只需将其留给用户空间进行mkdir(2)
系统调用。德米特里的回答指出,同时mount(2)
做这两件事会使它成为非原子的。并且您需要一个额外的参数来mount(2)
使用模式标志,例如open(2)
take, for O_CREAT
,O_EXCL
等等。这纯粹是愚蠢的比较让用户空间做。
或者,也许您是在问让mount(8)
(进行mount(2)
系统调用的传统程序)这样做?这是可能的,但已经有一个非常mkdir(1)
适合这项工作的,Unix 的设计就是关于可以组合的好的小工具。如果您想要一个工具可以同时执行这两个任务,那么编写一个 shell 脚本来使用两个更简单的工具构建该工具是很容易的。(或者,正如 muru 评论的那样,udisksctl
已经这样做了,所以您不必编写它。)此外,mount(8)
来自 util-linux 的Linux 正常支持mount -o x-mount.mkdir[=mode]
将其x-
语法用于用户空间的选项,而不是传递给文件系统的选项。
就像 pjc50 的回答指出的那样(没有关系,即使他有我的首字母!),让挂载点显示在目录列表中将需要对每个readdir()
.
将挂载点作为目录存在于包含它们的目录中(在父 FS 上)是一个不错的技巧。 readdir()
根本不必注意到它是一个挂载点。仅当挂载点用作路径组件时才会发生这种情况。路径解析当然必须检查路径的每个目录组件的安装表。
Dmi*_*yev 12
挂载到现有目录mount
实际上调用了原子性:它要么成功要么失败,至少从用户的角度来看。如果mount
必须自己创建挂载点,则会出现两个故障点,从而无法保证完全回滚。想象以下场景:
mount
成功创建挂载点mount
尝试将新文件系统挂载到该目录,但失败mount
尝试删除挂载点,但失败系统最终会出现失败的副作用 mount
。
这是另一个:
umount
成功卸载文件系统umount
尝试删除挂载点,但失败现在,应该umount
返回成功还是失败?