linux编程出错: Value too large for defined data type

1. 背景

         有次在linux环境下,用交叉编译器编译一个简单的helloworld(C语音写的不超过10行代码),结果提示如下所示的错误信息:

cc1: error: /home/yx/test.c: Value too large for defined data type

         而奇怪的是同一个test.c文件,放在不同位置下,有的能编译通过,有的不行,对比结果如下:

#ls -lsi /root/test.c /home/test.c /home/yx/test.c

  16022526 4 -rw-r--r--. 1 root  root  149 7月  27 14:06 /home/test.c       # 编译通过

4312840465 4 -rw-r--r--. 1 root  root  149 7月  27 14:07 /home/yx/test.c    # 编译失败

 202907598 4 -rw-r--r--. 1 root  root  149 7月  27 14:02 /root/test.c        # 编译通过

         这个问题折腾我许久,最终发现跟挂载属性inode64有关系,如下是我环境的挂载属性。

#mount | grep -E '(home|root)'

/dev/mapper/centos-root on /     type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

/dev/mapper/centos-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

        

2. 理论依据

         查看文件系统xfs格式的帮助手册,里面有详细介绍inode32|inode64的注意要点。

man xfs

 

inode32|inode64

       When inode32 is specified, it indicates that XFS limits inode creation to locations which will not result in inode numbers with more than 32 bits of  signifi‐

       cance.

 

       When  inode64  is  specified,  it indicates that XFS is allowed to create inodes at any location in the filesystem, including those which will result in inode

       numbers occupying more than 32 bits of significance.

 

       inode32 is provided for backwards compatibility with older systems and applications, since 64 bits inode numbers might cause problems  for  some  applications

       that cannot handle large inode numbers.  If applications are in use which do not handle inode numbers bigger than 32 bits, the inode32 option should be speci‐

       fied.

 

       For kernel v3.7 and later, inode64 is the default.

 

3. 结合实际

         inode32最多能表达数字是4294967295,如果文件属性中的inode超过这个上限,就说明是inode64的。

         比较老的交叉编译器,只支持32位inode的文件访问,当遇到超过4294967295的文件,就会编译出错并提示:Value too large for defined data type

4.   解决方案

         如https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44116所说,在新版本的gcc中已经解决了该bug。那么解决方案就有两种:

Ø  升级交叉编译器版本,让其支持inode64的源文件。

Ø  交叉编译器版本不变,将文件系统挂载属性从inode64改为inode32。

 

5. inode32与inode64的区别

         在http://xfs.org/index.php/XFS_FAQ#Q:_What_is_the_inode64_mount_option_for.3F里面有这么一段话能诠释的5. inode32与inode64的区别:

 

By default, with 32bit inodes, XFS placesinodes only in the first 1TB of a disk. If you have a disk with 100TB, allinodes will be stuck in the first TB. This can lead to strange things like"disk full" when you still have plenty space free, but there's nomore place in the first TB to create a new inode. Also, performance sucks.

To come around this, use the inode64 mountoptions for filesystems >1TB. Inodes will then be placed in the locationwhere their data is, minimizing disk seeks.

Beware that some old programs might haveproblems reading 64bit inodes, especially over NFS. Your editor used inode64for over a year with recent (openSUSE 11.1 and higher) distributions using NFSand Samba without any corruptions, so that might be a recent enough distro.

 

         大意就是xfs文件系统会把inode存储在磁盘最开始的这1T空间里,如果这部分空间被完全填满了,那么就会出现磁盘空间不足的错误提示了。解决办法就是在挂载时,指定 inode64 选项。

6. 其他

http://blog.fmeh.org/2013/05/11/does-the-world-need-32-bit-inodes/

 

上面看到的只使用 32 位 inode 的程序占比结果 10% 还是比较令人满意的,只支持 32 位 inode 的程序现在越来越少了。

你可能感兴趣的:(linux编程出错: Value too large for defined data type)