【问题标题】:WriteFile with Overlapped IO and ERROR_DISK_FULL?具有重叠 IO 和 ERROR_DISK_FULL 的 WriteFile?
【发布时间】:2019-07-10 05:18:48
【问题描述】:

想知道是否有人知道WriteFile()(这里是存储团队?)的内部设计,磁盘驱动器/文件系统上的文件有重叠的 IO。显然,当使用系统缓冲区和标准同步WriteFile() 时,它会检查是否已满磁盘并在返回之前分配空间,因为保存实际数据的系统缓存稍后会写入(问题会导致操作系统延迟写入错误)。

所以问题是:将OVERLAPPED 结构用于将文件扩展到可用空间之外的异步WriteFile() 时是否也是如此?例如它会在等待 IO 之前立即返回 ERROR_DISK_FULL 吗?

知道的原因是为了恢复释放磁盘空间,或插入新媒体,并恢复写入。如果以这种方式完成,则相当简单,如果在挂起 IO 之后,您可能会有一堆排队的 IO,然后必须同步这些 IO,并跟踪所有排队项目的附加信息,以防移动到新媒体以调整偏移量等.

TIA!!

【问题讨论】:

  • 看起来你可以用几行代码轻松地测试自己。填满您的可用磁盘空间,然后执行异步写入并查看它的反应。
  • 使用 OVERLAPPED 结构 不会使 I/O 异步,所以这里不相关。您的 I/O 请求是否仅以错误 ERROR_DISK_FULL 完成,或者您首先得到 ERROR_IO_PENDING,然后以 ERROR_DISK_FULL 完成,这是未定义的

标签: windows file asynchronous winapi storage


【解决方案1】:

您所说的异步文件操作(WriteFile() 等)是什么意思——这些操作仅对调用者是异步的。在内部,它们的工作方式与同步(阻塞)相同。阻塞调用的实现调用非阻塞调用并等待事件,就像您使用OVERLAPPED 结构一样。 那么,关于WriteFile 是否会在等待IO 之前返回ERROR_DISK_FULL 的问题,答案是否定的。 非阻塞调用的基本原理不是让磁盘操作返回结果更快,而是允许单个线程来并行执行多个 I/O 操作,而无需创建多个线程。

【讨论】:

  • 是的,通常处理请求的文件系统驱动程序总是异步处理它(尽管可以通过IoIsOperationSynchronous检测同步请求)。如果驱动程序返回STATUS_PENDING 并且文件对象已为同步 I/O 打开,则 IO 管理器 - 只需等待 I/O 完成,然后再返回调用方。所以这不是FS驱动等待。但是 非阻塞 I/O != 异步 I/O非阻塞 I/O 意味着请求永远不会等待,并且在返回给调用者时只是 完成异步 I/O 也只是返回给调用者,但返回时可能未完成。稍后完成
  • 与使用 OVERLAPPED 结构一样 - 并且使用 OVERLAPPED 不会使 I/O 异步。它可以用于同步 I/O。只是在异步 I/O 使用它时是强制性的,而在同步时是可选的。 I/O 是否同步取决于文件对象的打开方式(使用哪个标志)和 api(某些 api 始终同步)
  • 真的我们不知道我们是刚刚得到 STATUS_DISK_FULL 并请求完全同步错误还是首先得到 STATUS_PENDING 并且只有最终状态将是 STATUS_DISK_FULL 。可以是两种变体
  • 那么这是否意味着使用没有OVERLAP 结构的多线程与使用OVERLAP 结构的单线程性能相同?
  • @user3161924,单线程处理多个非阻塞操作(OVERLAPPED 和 WaitForMultipleObjects)性能不一样,但速度更快,因为它避免了与多线程相关的昂贵的上下文切换。
【解决方案2】:

如果没有足够的磁盘空间来完成写入操作 - 当 I/O 操作完成时,您会收到 ERROR_DISK_FULL (STATUS_DISK_FULL)。文件系统驱动程序是否只是使用STATUS_DISK_FULL 完成您的写入请求(转换为ERROR_DISK_FULL)或首先返回STATUS_PENDING(由win32 转换为ERROR_IO_PENDING)然后使用STATUS_DISK_FULL 完成I/O - 这是未定义。可以两者兼而有之。最终状态将是ERROR_DISK_FULL,但您不能假设操作将同步完成还是异步完成

【讨论】:

  • 我认为使用TAGed queued IO 是在磁盘驱动程序中的较低级别处理的,与较高级别的 API 无关?
  • @user3161924 - STATUS_DISK_FULL (ERROR_DISK_FULL) 这是文件系统错误代码。磁盘驱动程序没有什么共同点(在磁盘级别根本没有磁盘已满 - 磁盘只有大小)。 anout TAGed queued IO不明白
  • SATA/PATA queued IO 请求使用 TAG。必须是磁盘级驱动程序,该驱动程序发出的磁盘命令处理与任何WriteFile() API 调用分开。
  • @user3161924 - 但是磁盘级别与您的问题有什么关系?磁盘不能满或未满
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2016-03-16
  • 2013-01-13
  • 1970-01-01
  • 2017-12-20
相关资源
最近更新 更多