No space left on device?
Asked Answered
S

1

5

According to df there is plenty (about 50G) space left on the device.

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

Why might this vala code indicate otherwise?

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

The code, of course, prints out

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

Is there a limit on the number files that GLib.FileUtils can handle in one directory? /db/20121112 contains 27220 files (half jpeg and half bmp).

mmcblk0p3 was created like this

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

and formatted like this

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

This is probably a don't care but the device is a 64G SD card and mmcblk0p1 and mmcblk0p2 are used for boot and rootfs.

Checking inodes as Barmar suggested in comments like this causes

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

which is odd since according to the BusyBox docs, df -i is valid

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

Is there another way to check inodes?

Update [11-15-2012]: I thought the issue might be too many files per folder so I modified the code to open a new folder hourly rather than daily but it still died after saving 44354 images about evenly distributed in 7 folders using 16.7 of a 64 GB SD card.

Scenic answered 12/11, 2012 at 22:26 Comment(12)
Check if you've run out of inodes with df -i db.Icky
If it is an embedded system, maybe it is mounted read-only? /etc/fstabWeirick
How big is bmp.length?Augustina
@AlexandreLavoie - the system is not read only. 27220 files are written before this issue.Scenic
@Augustina - the bmps are 626.1 KB (641078 bytes)Scenic
Have you tried creating another file of the same name and approximately the same size using something like cp?Augustina
@Augustina - yes. using cp to copy a bmp to a new tmp file works fine. This may be a GLib.FileUtils issue.Scenic
To be clear, you've verified that bmp.length == 641078, or that is just what you expect it to be? Depending on the source of the data the length may not be set properly...Wonderwork
@Wonderwork - Yes. The bmp is always bmp header 1078 + 64000 (800x800).Scenic
You didn't answer my question. What I'm asking is that you verify bmp.length == 641078 in your program by either having your program print the value somewhere or using a debugger. Some functions, such as Gdk.Pixbuf.get_pixels, which return an array do not return the length so the length will be set to -1. When you cast the length to an unsigned integer, like GLib.FileUtils.set_content does, it becomes a very large positive number, which could explain the error you're seeing. So, to be clear, you've verified that bmp.length == 641078, or that is just what you expect it to be?Wonderwork
@Wonderwork - Yes. The bmp size is always 641078. During this phase of development I only have one bmp file that I keep saving with different names to test these methods while awaiting proper HW.Scenic
Did you try it with another filesystem (like ext2)?Cordalia
H
8

df only has -i in busybox, if FEATURE_DF_FANCY is enabled when compiling it.

For FAT32 volumes the maximum number of files that can be stored in a folder is 65,534.

A FAT32 directory can have 65,536 directory entries.

FAT32 doesn't have inodes instead they are unstably generated / emulated on the fly by the kernel and cached.

Following the code and the error message provided.

Firstly the error associated with the message you see is ENOSPC No space left on device as per here.

FileUtils.set_data calls glib fileutils function g_file_set_contents (source located here, Vala commit message here)

On Linux (Windows has additional logic that is followed based on ifdef)

g_file_set_contents calls the following functions in the same source file gfileutils.c

  • write_to_temp_file
  • rename_file
  • g_unlink

As your error message mentions db/20121112/165206.0.bmp.9X8PNW which is not /db/20121112/165206.0.bmp, the function that returns ENOSPC is write_to_temp_file.

From the other part of your error message (Failed to create file) we know that the function call that causes the error is g_mkstemp_full as that is what is responsing for setting the intial value of the file descriptor fd.

This calls get_tmp_file, which calls the wrap_g_open, that is the GTmpFileCallback which is used to determine the value of the file descriptor fd.

wrap_g_open calls g_open (which lives in gstdio.c) true to its name.

g_open calls open which is documented here and where ENOSPC is describled as pathname was to be created but the device containing pathname has no room for the new file .

In the kernel source code for FAT there are only two source files that return ENOSPC, /source/fs/fat/dir.c and /source/fs/fat/fatent.c.

In /source/fs/fat/dir.c the function that returns ENOSPC by being in a certain error state is fat_add_entries, it does this when the number of directory entries is greater than the maximum directory size which for FAT32 is evaluated as 2097152.

In /source/fs/fat/fatent.c the function that returns ENOSPC directly is fat_alloc_clusters, it does this when the number of free clusters according to the superblock information are less than number of clusters requested to allocate.

The maximum possible number of clusters on a volume using the FAT32 file system is 268,435,445 as per here.

The format command that you posted uses the mkdosfs default of 2 sectors per cluster. Specifying various options including -s , -R , may change the number of clusters available, though the only usage I have seen it for is alignment with 128KB blocks to increase disk throughput.

I don't know how many sectors your SD card has so, I can't calculate the number of total number of clusters.

I don't believe you have exceeded the maximum directory size (though I can't be sure), so I believe it is related to the number of free clusters on the SD card.

Either your SD card is legitimately out of clusters, or the file system just thinks it is out of clusters. Running fsck (filesystem check) on the filesystem may help.

Does a different SD card behave the same way ?

Hendecasyllable answered 29/11, 2012 at 20:43 Comment(1)
Haven't had a chance to repair this yet but wanted to award the bounty before it expired.Scenic

© 2022 - 2024 — McMap. All rights reserved.