产品的老大直接找到了我:他们对reiserfs的一个分区写文件数据时返回失败,返回值是28,既是No space left on device,直接到产品环境上一看,12TB的空间用了不到10GB,自己顿时头大了,我一直对“设计精妙,代码残废”的reiserfs心怀敬畏(首席设计人员中途溜号,后面全靠开发人员脑补的复杂工程真是灾难),恰好还有其他要紧任务,便把问题转给了李义处理,几天后,李义发了一个补丁给我:内核:kernel-2.6.16.60-0.83.2 for sles10sp3

 

竟然是一个低级错误,多少年了木有人发现:int型溢出了 VFS调用reiserfs_file_operations中的reiserfs_file_write写数据会预判分区剩余空间

当num_pages值为0时2×pos>filesize+blocksize(一般为4K)就会返回失败,提示空间不足。 而在reiserfs_can_fit_pages中:

目前文件系统的块号是32位(无符号),函数中int型,就最大支持0x7FFFFFFF个page,由于block和page大小皆为4KB,则当剩余空间达到0x7FFFFFFF×4KB即约8TB时,space值就会溢出,返回值为0,触发了问题。

总结:一开始以为是产品的代码问题,没有重视,内核补丁人员就要怀疑一切,(遥拜组内一位解决了intel处理器bug的大牛),像师兄说过“是人写的代码就有bug”,哪怕是如此低级的错误..

附带SUSE发布的补丁地址: http://kernel.opensuse.org/cgit/kernel/commit/?h=SLES10_SP4_BRANCH&id=5fc8d3a240af4a929e2bcb2d5baaca89536a924b


reiserfs分区空闲8TB写文件提示磁盘空间不足来自于OenHan

链接为:http://oenhan.com/reiserfs_check_can_fit_pages_for_8tb

发表评论