【发布时间】:2017-04-17 04:57:52
【问题描述】:
我的服务器上安装了 Red Hat Enterprise Linux Server 版本 6.6 (2.6.32-504.el6.x86_64),并且具有以下分区层次结构。
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 7.9G 1.7G 5.9G 22% /
tmpfs 5.4G 8.0K 5.4G 1% /dev/shm
/dev/sda8 53G 1.4G 49G 3% /mysql/data
/dev/sda6 7.9G 4.5G 3.1G 60% /usr/BWhttpd
/dev/sda4 32G 989M 29G 4% /var
/dev/sdb1 25T 37M 25T 1% /media1
/dev/sdc1 25T 37M 25T 1% /media2
/dev/sdd1 25T 37M 25T 1% /media3
/dev/sde1 22T 21T 1.1T 95% /media4
我对每个
发出一个statvfs 调用
/mediax
分区但系统调用失败并出现错误Value too large for defined data type。
我能够找到系统调用返回错误EOVERFLOW,但不确定struct statvfs 的哪个成员导致了此错误。
它是否与 /mediax 分区的大小有关。
注意:分区是 xfs 文件系统类型。
【问题讨论】:
-
您发布的输出看起来来自
df、which usesstatvfs()internally,因此statvfs()似乎适用于您的系统。你是如何编译你的代码的?您是编译为 32 位还是 64 位? -
@AndrewHenle 是的,输出是
df命令。我不确定 32/64 位编译是否会在这里有所作为。可以详细说明一下。 -
@Krishna_Oza:我跟踪了内核调用链(尽管只针对 ext4)。此外,您完全误解了问题的性质:本机字长,或者硬件是 32 位还是 64 位,与这里的问题无关。问题是用于
struct statfs和struct statvfs的原始结构具有无法描述为Linux 支持的大分区的字段。如果其中一个字段溢出,系统调用将返回EOVERFLOW。 所有架构上的所有 linux 内核 -- 32 和 64 位 -- 从 2.6 开始支持statfs64()等 -
@Krishna_Oza:我在水平线之后重写了答案中的部分以使其更清晰。重复一遍:这不是 32 位/64 位架构问题;只是原始结构使用的字段太小而无法保存实际的真实值。由于已有代码在使用它,内核无法更改它;它只能添加一个新的替换系统调用(用于新代码),该系统调用使用具有适当大小字段的结构。这发生在十多年前,两者仍然受到支持。在您的情况下,glibc 只是猜错了应该使用哪个,需要一些指导。
-
@Krishna_Oza:很高兴听到!我花了几次尝试以可理解的格式描述这些接口......还有许多其他与文件/文件系统相关的系统调用遇到类似问题 - 原始字段太小,或者可能没有足够的字段 - - 像
lseek64();但是#define _FILE_OFFSET_BITS 64宏应该足以告诉 glibc 使用具有普通函数 (lseek()) 和类型 (off_t,struct stat) 的 "better" 版本。跨度>
标签: c linux filesystems system-calls glibc