微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

write()调用失败, errno = 28 (ENOSPC) ,设备上没有errno = 28 (ENOSPC)空间。 我试图通过以下方式处理这个错误。 当磁盘已满,我正在做lseek()将文件指针移动到文件的开头。

我相信,现在write()不应该失败,因为现在文件将从顶部覆盖(文件不会消失)。 但仍然write()调用失败,相同的错误。 请解释这种行为。

if(errno == ENOSPC) { curPos = lseek(gi4LogFd,SEEK_SET); break; }

显示哪些文件在Linux中写入的工具?

我怎样才能确定在Windows中的文件的创builddate?

即使里面的文件被python中的其他应用程序使用,如何删除目录

在Linux中添加一个文本到多个文件的末尾

两行文件间的区别

多个Java进程可以同时读取同一个文件吗?

微软编译器在Docker中

Windows文件创build时间戳可靠吗?

将特定的文件文件添加到Windows资源pipe理器视图

我如何知道在Windows下使用Java下的文件有哪些进程?

仅仅因为你写入文件的开头并不意味着文件系统将写入磁盘上的相同空间,或者文件开头的空间被分配。

你可能在文件中有一个漏洞,在这种情况下,写入将会失败。 空洞是许多文件系统做的优化,他们假装文件的一部分在那里,而实际上只有很多零,所以这些部分永远不会被写入到磁盘,只是记帐说文件一个特定部分是空的。

您可能会过度提交数据到您的文件系统(很多文件系统实际上并没有在磁盘上分配空间,直到数据从缓冲区缓存中清除,如果在写入完成之后没有几分钟,这可能是几秒钟),在这种情况下写反正会失败 你得到的ENOSPC实际上可能是因为你已经把你的文件系统填满了超过100%的容量,并且文件系统代码直到它试图刷新你之前做的写入才发现它。

你可能在一个日志记录/日志文件系统,实际的块分配不会发生,直到日志刷新,在这种情况下,写入将失败。 与缓冲区缓存情况相同的逻辑。

你可能已经用完了文件系统上的一些特定的预先分配的元数据,即使它几乎不满,它也会因为ENOSPC而失败。 今天不像过去那样普遍。

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

简而言之,我们不能保证文件系统的行为就像我们可以天真地认为它一旦满了就行。 除此之外还有其他一些原因,从来没有填补95%以上的文件系统。 几乎所有的文件系统在接近满时都是非常不确定的。

仅仅因为你正在寻找文件的开头并不意味着该文件被截断。 可以在文件上进行随机写入。

在完整的文件系统上写下一个块会导致问题。 如果你想截断文件使用truncate(2)或ftruncate调用文件之前lseek

尝试:

if(errno == ENOSPC) { ftruncate(gi4LogFd,0); lseek(gi4LogFd,SEEK_SET); break; }

好的,所以支持日志的ext3文件系统不会在完整的fs上产生问题:

建立:

创建一个图像文件

dd if=/dev/zero of=/tmp/img.dsk count=8192

创建一个4k图像文件的ext3文件系统:

mkfs.ext3 /tmp/img.dsk sudo mount /tmp/img.dsk /mnt/internal sudo chown masud.users /mnt/internal touch /mnt/internal/file.bin sudo dd if=/dev/urandom of=/mnt/internal/file.bin

这里sudo是必要的,以确保超级用户的储备已经填满。

所以现在:

df / mnt / internal /显示

/dev/loop/0 3963 3963 0 100% /mnt/internal

使用下面的代码

#include <stdio.h> #include <sys/time.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> char buf[8192]; int main(int argc,char *argv[]) { int rv; char *filename; if ( argc < 2 ) { fprintf(stderr,"provide the filenamen"); return -1; } filename = argv[1]; int rd = open("/dev/urandom",O_RDONLY); read(rd,buf,sizeof(buf)); close(rd); int fd = open(filename,O_SYNC|O_RDWR); lseek(fd,-sizeof(buf),SEEK_END); rv = write(fd,sizeof(buf)); if ( rv < 0 ) { perror(filename); goto out; } lseek(fd,SEEK_SET); rv = write(fd,"foo",3); if ( rv < 0 ) { perror(filename); } out: close(fd); return rv; }

现在:./foo /mnt/internal/file.bin

成功。

所以问题是如何不同于你的环境?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐