使用成功

时间:2018-10-03 19:18:59

标签: c++ linux operating-system filesystems

在经过以下修剪的4个调用之后,我无法在应用程序中重现此问题,但这与我在gpfs文件系统上的单线程应用程序一致。

重要的通话顺序是

const int64_t capacity = 8458240;    
ftruncate64(fd, current_size + capacity);
fstat(fd, &buf);
munmap(base, capacity);
base = mmap64(nullptr, capacity, PROT_READ|PROT_WRITE, MAP_SHARED, fd, current_size);

它可用于除gpfs之外的所有可用文件系统。 注意:current_size不会四舍五入为容量,但是会单调增加。 因此,程序及以上调用成功运行了一段时间,直到被截断5724962816。在这种情况下,文件在gpfs上调整为仅5716836352(恰好是5716MB)。较小的尺寸效果很好。 在strace输出上可见:

ftruncate(6, 5724962816)                = 0
fstat(6, {st_mode=S_IFREG|0640, st_size=5716836352, ...}) = 0

对往远处看有什么建议吗?

谢谢。

PS: 我能够产生简单的问题代码:

int main(int argc, char* argv[])
{
 auto m_fd = ::open(argv[1], O_RDWR|O_CREAT|O_TRUNC, (S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP));
long m_capacity =      8458240L;
long size = 60033856276L/8458240L;
long increment = 8417280L;
for(long i = 1; i<size; i++)
{
  if( ::ftruncate64(m_fd,  m_capacity + increment*i) < 0 )
  {
    std::cerr<<"ftruncate failed "<< errno << " "<<::strerror(errno) <<endl;
    return 1;
  }

  int8_t* base = (int8_t*)::mmap(nullptr, m_capacity, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd,  increment*i);
  if(base == MAP_FAILED)
  {
    std::cerr<<"mmap failed"<< errno << " "<<::strerror(errno) <<endl;
    return 1;
  }

  struct stat buf;
  ::fstat(m_fd, &buf);
  if(buf.st_size != m_capacity + increment*i)
    {
      std::cerr<< "size failed " << buf.st_size << " "<< (m_capacity + increment*i) <<  ", i " << i<<  endl;
      return 1;
    }

  for (int64_t i = 0; i < m_capacity; ++i)
    {
      volatile int8_t* addr = base + i;
      int8_t x              = *addr;
      *addr = x;
    }

  ::munmap(base, m_capacity);
}
return 0;
}

如果我返回,它将在“失败5716836352 5723791360,i 679”之后出现。

更新: 我通过基本调用第二次ftruncate64(如果大小不匹配)使用相同的值来创建解决方法。 值得注意的是,我遇到的第二个失败是第一个的x2,所以我可能会将其留给IBM。

大小失败5716836352 5723791360,i 679 大小失败11433672704 11439124480,i 1358

0 个答案:

没有答案