【问题标题】:Working with block special files/devices to implement a filesystem使用块特殊文件/设备来实现文件系统
【发布时间】:2010-12-21 14:24:16
【问题描述】:

我已经使用 FUSE 实现了一个basic filesystem,实现了所有可预见的 POSIX 功能 [当然,我什至还没有分析过 ;)]。目前,我能够在常规文件(st_mode & S_IFREG) 上运行文件系统,但下一步的开发是将其托管在实际的块设备上。按原样运行我的代码,在设备上调用fstat 后立即读取st_size 失败。当然,我不希望问题就此止步:

  • 与常规文件相比,在块设备上操作需要哪些更改?
  • 在性能、限制、特殊功能等方面我需要特别注意哪些事项?
  • 是否有处理块特殊文件的教程和参考资料?谷歌搜索几乎没有用处。我只有背景知识(讽刺的是,在我黑暗的过去来自 MSDN)和联机帮助页中的一些信息。

更新0

  • 我已经指出了“常规文件”的含义。
  • 我不想专注于获取设备大小,我想了解常规文件和设备文件在性能和使用方面的差异的一般准则。

【问题讨论】:

  • 我想不出任何理由读取传递给 fstat 的地址的结构的 st_size 成员无论如何都会使程序崩溃,除非内核有错误并且没有检查在系统调用中正确访问该内存的权限,但在 MMU 捕获它时在应用程序中。
  • 这可能只是与块设备问题间接相关——仅仅因为它适用于常规文件并不意味着它没有细微的错误。请发布分配您的 stat 结构、调用 fstat() 并读取 st_size 的代码。

标签: c linux filesystems fuse block-device


【解决方案1】:

目前我可以运行 常规文件上的文件系统,但是 下一步的发展是 将其托管在实际的块设备上

我不完全理解您的意思-我假设您是在说“您当前将文件系统数据保存到正常安装的文件系统上的普通文件中-但现在希望使用原始块设备来存储数据” .

如果是这样 - 这样做了几次 - 我建议如下:

  • 永远不要为您的文件系统使用“实际”块设备。始终使用分区。有几种很少使用的分区类型可以用来表示这样的文件系统可能是你的文件系统类型,如果是这样的话,你的文件系统可以检查和挂载它。因此,您将永远不会在“/dev/sdb”之类的东西上运行,而是将数据存储在 /dev/sdb1 之类的东西上,并为其分配一些分区类型。这具有明显的优势,例如允许您的文件系统与另一个物理磁盘共同驻留在一个物理磁盘上,等等。
  • 如果您在文件系统中实现任何缓存(就像 Linux 使用页面缓存所做的那样),请使用 O_DIRECT 对块设备执行所有 I/O。这要求您传递页面对齐的内存来执行所有 I/O,并要求请求是扇区/块对齐的 - 但会删除数据副本,否则当数据从块设备移动到页面缓存时需要该副本,然后从页面缓存到您的用户空间 [文件系统] 阅读器。

fstat“失败”是什么意思?这是一个试图确定块设备长度的 fstat 吗?您收到错误消息吗?这是什么?

【讨论】:

  • 我会试试 O_DIRECT。谢谢。
【解决方案2】:

块设备的行为与文件非常相似 - dd 等工具无需任何特殊处理即可对其进行操作。但是,fstat 返回有关特殊文件节点的信息,而不是它所指的 blockdev。您可能想使用 BLKGETSIZE64 ioctl 来读取大小。

虽然没有特别的理由在原始设备上使用分区 - blockdev 就是 blockdev。 O_DIRECT 也很好,假设您的工作负载不会产生重复访问。不过,不要将它与确保文件系统的持久性和原子性的真正协议混淆(fsync、barriers 等)。

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 2016-03-18
    • 1970-01-01
    • 2020-10-03
    • 2017-04-18
    • 2011-06-14
    • 2013-10-10
    • 2012-11-08
    • 2011-01-12
    相关资源
    最近更新 更多