【问题标题】:No space left on device?设备上没有剩余空间?
【发布时间】:2012-11-12 22:26:14
【问题描述】:

根据 df 的说法,设备上还有很多(大约 50G)空间。

/ # df db
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mmcblk0p3        61812032  11308736  50503296  18% /db

为什么这个 vala 代码可能另有说明?

try 
{
    FileUtils.set_data(bmp_path, bmp);
} 
catch (Error e)
{
    printf("Error! FileUtils.set_data %s\n%s\n", bmp_path, e.message);
}                             

代码当然会打印出来

Error! FileUtils.set_data /db/20121112/165206.0.bmp
Failed to create file '/db/20121112/165206.0.bmp.9X8PNW': No space left on device

GLib.FileUtils 在一个目录中可以处理的文件数量是否有限制? /db/20121112 包含 27220 个文件(一半 jpeg 和一半 bmp)。

mmcblk0p3 就是这样创建的

echo -e "n\np\n3\n66\n\nt\n3\nc\nw" | fdisk /dev/mmcblk0

并像这样格式化

mkfs.vfat -n DB -F 32 /dev/mmcblk0p3

这可能无关紧要,但该设备是 64G SD 卡,并且 mmcblk0p1 和 mmcblk0p2 用于引导和 rootfs。

像 Barmar 在 cmets 中建议的那样检查 inode 会导致

df: invalid option -- 'i'
BusyBox v1.18.2 (2012-11-09 13:08:26 EST) multi-call binary.

这很奇怪,因为根据BusyBox docs,df -i 是有效的

df [-Pkmhai] [-B SIZE] [FILESYSTEM...]
-i Inodes

还有其他检查 inode 的方法吗?

更新 [2012 年 11 月 15 日]:我认为问题可能是每个文件夹的文件太多,所以我修改了代码以每小时而不是每天打开一个新文件夹,但在保存 44354 后它仍然死了 使用 16.7 个 64 GB SD 卡的图像大约均匀分布在 7 个文件夹中。

【问题讨论】:

  • df -i db检查你的inode是否用完了。
  • 如果是嵌入式系统,可能是只读挂载的? /etc/fstab
  • bmp.length 有多大?
  • @AlexandreLavoie - 系统不是只读的。本期前写了27220个文件。
  • 你没有回答我的问题。我要问的是您通过让程序在某处打印值或使用调试器来验证程序中的 bmp.length == 641078 。某些返回数组的函数(例如 Gdk.Pixbuf.get_pixels)不返回长度,因此长度将设置为 -1。当您将长度转换为无符号整数时,就像 GLib.FileUtils.set_content 一样,它会变成一个非常大的正数,这可以解释您看到的错误。所以,需要明确的是,您已经验证了 bmp.length == 641078,或者这正是您所期望的?

标签: embedded-linux glib vala fileutils


【解决方案1】:

df 只有在busybox中才有-i,如果在编译时启用了FEATURE_DF_FANCY

对于 FAT32 卷,一个文件中可以存储的最大文件数 文件夹是 65,534。

一个 FAT32 目录可以有 65,536 个目录条目。

FAT32 没有 inode,而是不稳定地由内核动态生成/模拟并缓存。

按照提供的代码和错误消息。

首先,根据here,与您看到的消息相关的错误是ENOSPC No space left on device

FileUtils.set_data 调用 glib fileutils 函数g_file_set_contents(源位于here,Vala 提交消息here

在 Linux 上(Windows 具有基于 ifdef 遵循的附加逻辑)

g_file_set_contents在同一个源文件gfileutils.c中调用以下函数

  • write_to_temp_file
  • rename_file
  • g_unlink

由于您的错误消息提到db/20121112/165206.0.bmp.9X8PNW 不是/db/20121112/165206.0.bmp,因此返回ENOSPC 的函数是write_to_temp_file

从错误消息的另一部分 (Failed to create file) 我们知道导致错误的函数调用是 g_mkstemp_full,因为这是设置文件描述符 fd 的初始值的响应。

这里调用get_tmp_file,又调用wrap_g_open,也就是GTmpFileCallback,用来判断文件描述符fd的值。

wrap_g_open 调用 g_open(住在gstdio.c)名副其实。

g_open 调用 open 记录在 here 并且 ENOSPC 被描述为 pathname was to be created but the device containing pathname has no room for the new file

在 FAT 的内核源代码中,只有两个源文件返回 ENOSPC/source/fs/fat/dir.c/source/fs/fat/fatent.c

/source/fs/fat/dir.c中,通过处于某种错误状态返回ENOSPC的函数是fat_add_entries,它在目录条目数时执行此操作 大于 FAT32 评估为 2097152 的最大目录大小。

/source/fs/fat/fatent.c中直接返回ENOSPC的函数是fat_alloc_clusters,当空闲簇数 根据超级块信息,小于请求分配的簇数。

根据here,使用 FAT32 文件系统的卷上的最大可能簇数为 268,435,445。

您发布的格式命令使用 mkdosfs 默认值,即每个集群 2 个扇区。指定包括 -s 、 -R 在内的各种选项可能会改变可用集群的数量,尽管我看到它的唯一用途是与 128KB 块对齐以增加磁盘吞吐量。

我不知道你的SD卡有多少个扇区,我无法计算总簇数。

我不相信你已经超过了最大目录大小(虽然我不能确定),所以我相信它与 SD 卡上的空闲集群数量有关。

要么您的 SD 卡合法地不在集群中,要么文件系统只是认为它不在集群中。在文件系统上运行 fsck(文件系统检查)可能会有所帮助。

不同的 SD 卡的行为方式是否相同?

【讨论】:

  • 还没有机会修复这个问题,但想在它到期之前奖励赏金。
猜你喜欢
  • 2012-12-29
  • 2012-01-14
  • 2012-05-15
  • 2018-11-22
  • 2015-07-21
  • 2020-12-16
  • 2014-11-20
  • 2018-12-27
  • 2015-09-25
相关资源
最近更新 更多