write()调用失败:设备上没有剩余空间:ENOSPC处理

Sum*_*han 3 c linux error-handling file

write()呼叫与失败errno = 28 (ENOSPC),没有留在设备上的空间.我试图通过以下方式处理此错误.当磁盘已满时,我正在lseek()将文件指针移动到文件的开头.

我相信现在不write()应该失败,因为现在文件将从顶部覆盖(文件不会扩展).但是仍然write()是因为同样的错误而失败了.请解释一下这种行为.

  if(errno == ENOSPC)
  {
      curPos = lseek(gi4LogFd, 0, SEEK_SET);
      break;
  }
Run Code Online (Sandbox Code Playgroud)

Art*_*Art 6

仅仅因为您写入文件的开头并不意味着文件系统将写入磁盘上的相同空间或者根本不分配文件开头的空间.

你可能在文件中有一个漏洞,在这种情况下写入无论如何都会失败.孔是许多文件系统做的优化,他们假装文件的一部分存在,而实际上只有很多零,所以这些部分永远不会被写入磁盘,只是簿记说文件的特定部分是空的.

您可能有过多的数据到您的文件系统(许多文件系统实际上不会在磁盘上分配空间,直到数据从缓冲区缓存中刷新,这可能是几秒钟,如果不是写入完成后几分钟),在这种情况下写入无论如何都会失败.您获得的ENOSPC实际上可能是因为您已经将文件系统填充到超过100%的容量,并且文件系统代码在尝试刷新您之前执行的写入之前没有发现它.

您可能处于日志记录/日志记录文件系统中,在刷新日志之前不会发生实际的块分配,在这种情况下写入将失败.与缓冲区缓存情况相同的逻辑.

您可能已经耗尽了文件系统上的一些特定的预分配元数据,即使它甚至几乎没有,它也会因ENOSPC而失败.这在今天并不像过去那么普遍.

你的磁盘可能已经发现它的某些部分坏了,并告诉文件系统不使用这些块并占用空间.

简而言之,不能保证文件系统的行为就像我们可以天真地认为它一旦充满就会发生.除此之外还有其他原因永远不会填满95%以上的文件系统.几乎所有的文件系统都差不多完全是不确定的.