gpt4 book ai didi

c - statvfs 系统调用失败,错误值对于定义的数据类型来说太大

转载 作者:太空狗 更新时间:2023-10-29 11:03:33 40 4
gpt4 key购买 nike

我的服务器上安装了 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 分区的大小有关。

Note: Partitions are of xfs file system type.

最佳答案

man 2 statfs 中所述手册页:

The original Linux statfs() and fstatfs() system calls were not designed with extremely large file sizes in mind. Subsequently, Linux 2.6 added new statfs64() and fstatfs64() system calls that employ a new structure, statfs64. The new structure contains the same fields as the original statfs structure, but the sizes of various fields are increased, to accommodate large file sizes. The glibc statfs() and fstatfs() wrapper functions transparently deal with the kernel differences.

在您的情况下,您出于某种原因正在使用非 64 位版本的系统调用。

Linux 内核使用四种不同的系统调用(加上可选的兼容版本)实现了 fstat*fs*()stat*fs*() 库调用:fstatfs()fstatfs64()statfs()statfs64()。所有四个都在 fs/statfs.c 中定义在内核源代码中,并使用内核内部函数 vfs_statfs() 将必要的信息收集到 struct kstatfs 结构中。

statfs()fstatfs() 都使用内核内部函数 do_statfs_native()(在 fs/statfs.c 中)复制字段从内核 struct kstatfs 到用户空间 struct statfs 缓冲区。问题是,许多内核结构字段比用户空间缓冲区中的字段大。 do_statfs_native() 验证值是否合适,如果不合适,将返回 -EOVERFLOW 否则。

这是我能找到的唯一可能导致四个系统调用中的任何一个返回 -EOVERFLOW 的情况。

对于 statfs64()fstatfs64(),内核函数 do_statfs64() 用于从内核内部复制字段 struct kstatfs 到用户空间 struct statfs64 缓冲区。用户空间缓冲区字段至少与内核结构字段一样大,因此不存在溢出风险。 (该函数从不返回 -EOVERFLOW。)

解决方法是确保您使用 64 位版本的 struct statfs 和相应的系统调用。


要确保 glibc 使用结构的正确版本(可以正确描述非常大的文件系统的版本),请确保您有

#define _FILE_OFFSET_BITS 64

在任何#include之前;或者,将 -D_FILE_OFFSET_BITS=64 添加到您的编译器标志中。

所有这一切都是为了确保 glibc 知道您正在运行 Linux 2.6 或更高版本的内核(3.x、4.x 等),并且它绝对应该尝试使用结构的版本具有适当大小的字段。

或者,您可以定义_LARGEFILE64_SOURCE,以公开struct statfs64struct statvfs64 类型以及相应的statfs64()statvfs64() 包装系统调用。这避免了让 glibc 进行任何猜测,并确保您使用可以正确描述所有 Linux 文件系统大小的系统调用版本。

这两个选项都适用于所有 Linux 架构,32 位和 64 位。

关于c - statvfs 系统调用失败,错误值对于定义的数据类型来说太大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40929542/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com