File size is updated correctly according to 

> fdatasync() is similar to fsync(), but does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled.  For example, changes to  st_atime  or  st_mtime  (respec‐
       tively,  time  of  last  access  and  time  of last modification; see inode(7)) do not require flushing because they are not necessary for a subsequent data read to be handled correctly.  On the other hand, a change to the file size
       (st_size, as made by say ftruncate(2)), would require a metadata flush.

And we don't care about modification times.
Should work alright.
{
        if (poll(&polls[0], descriptors, -1) <= 0)
            throwFromErrno("poll failed", ErrorCodes::SYSTEM_ERROR);
        for (size_t i = 0; i < descriptors; ++i)
        {
            if (!polls[i].revents)
                continue;
            if (polls[i].revents != polls[i].events)
                throw Poco::Exception("revents indicates error");
            polls[i].revents = 0;
            ++ops;
            uint64_t rand_result1 = rng();
            uint64_t rand_result2 = rng();
            uint64_t rand_result3 = rng();
            size_t rand_result = rand_result1 ^ (rand_result2 << 22) ^ (rand_result3 << 43);
            size_t offset;
            offset = min_offset + rand_result % ((max_offset - min_offset) / block_size) * block_size;
            if (mode == MODE_READ)
            {
                if (static_cast<int>(block_size) != pread(fds[i], &buf[0], block_size, offset))
                    throwFromErrno("Cannot read", ErrorCodes::CANNOT_READ_FROM_FILE_DESCRIPTOR);
            }
            else
            {
                if (static_cast<int>(block_size) != pwrite(fds[i], &buf[0], block_size, offset))
                    throwFromErrno("Cannot write", ErrorCodes::CANNOT_WRITE_TO_FILE_DESCRIPTOR);
            }
        }
    }
    for (size_t i = 0; i < descriptors; ++i)