ftruncate64 неверный размер файла на gpfs ​​с УСПЕХОМ - PullRequest
0 голосов
/ 03 октября 2018

Я не мог воспроизвести эту проблему в приложении с только что урезанными 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 (ровно 5716 МБ).Меньшие размеры работают хорошо.Это видно по прямому выводу:

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. * Ошибка 1011 *

5716836352 5723791360, ошибка i 679 11433672704 11439124480, i 1358

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...