Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No space left on device?

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.

like image 632
jacknad Avatar asked Nov 12 '12 22:11

jacknad


1 Answers

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 ?

like image 121
Appleman1234 Avatar answered Sep 22 '22 06:09

Appleman1234