virtual ssize_t pwrite()

in fs/aligned-file.cpp [86:136]


        virtual ssize_t pwrite(const void *buf, size_t count, off_t offset) override
        {
            if (count == 0) return 0;
            range_split_power2 rs(offset, count, m_alignment);
            if (rs.is_aligned() && (!m_align_memory || rs.is_aligned_ptr(buf)))
                return m_file->pwrite(buf, count, offset);

            struct stat stat;
            m_file->fstat(&stat);
            ssize_t filesize = stat.st_size;
            auto suppose_filesize = (offset + (ssize_t)count) > filesize ? offset + count: filesize;
            auto ptr = mem_alloc(rs.aligned_length());
            if (!ptr)
                LOG_ERROR_RETURN(0, -1, "Failed to allocate memory");
            DEFER(free(ptr));

            if (rs.begin_remainder > 0)
            {
                ssize_t off = rs.aligned_begin_offset();
                ssize_t ret = m_file->pread(ptr, m_alignment, off);
                if ((ret < 0) || ((off + ret < filesize) && (ret < (ssize_t)m_alignment)))
                    LOG_ERRNO_RETURN(0, -1, "failed to aligned [`]->pread(ptr=`, count=`, offset=`) and patch the first alignment block", m_file, ptr, m_alignment, off);
                if (ret < (ssize_t)m_alignment) {
                    memset((char*)ptr + ret, 0, m_alignment - ret);
                }
            }

            if (!rs.small_note && rs.end_remainder > 0)
            {
                ssize_t off = rs.aligned_end_offset() - m_alignment; // this should never be negative
                if (filesize - off > (ssize_t)(rs.end_remainder)) {
                    // that means there is still parts of data after the rear end of pwrite block
                    auto ptr_ = (char*)ptr + off - rs.aligned_begin_offset();
                    ssize_t ret = m_file->pread(ptr_, m_alignment, off);
                    if ((ret < 0) ||
                        ((ret + off < filesize) && (ret < (ssize_t)m_alignment))) // cannot fetch all data of file, and cannot fillup aligned block
                        LOG_ERRNO_RETURN(0, -1, "failed to aligned [`]->pread(ptr=`, count=`, offset=`) and patch the last alignment block", m_file, ptr_, m_alignment, off);
                }
            }

            memcpy((char*)ptr + rs.begin_remainder, buf, count);
            auto actual_write = m_file->pwrite(ptr, rs.aligned_length(), rs.aligned_begin_offset());
            auto current_tail = rs.aligned_begin_offset() + actual_write;
            if ((ssize_t)current_tail < offset)
                return -1; // failed to write
            auto count_write = current_tail - offset >= count ? count : current_tail - offset;
            if (suppose_filesize < current_tail) { // that means have written more than needs
                m_file->ftruncate(suppose_filesize);
            }
            return count_write;
        }