Я не мог воспроизвести эту проблему в приложении с только что урезанными 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