}
int rv = ioctl(m_fd, BTRFS_IOC_FILE_EXTENT_SAME, ioctl_ptr);
if (rv) {
- THROW_ERRNO("After FILE_EXTENT_SAME (fd = " << m_fd << " '" << name_fd(m_fd) << "') : " << ioctl_ptr);
+ // Build a self-contained description of the failed
+ // request: the src file/offset, the length, and every
+ // dst file/offset. That is exactly the set of
+ // parameters needed to replay the dedupe_file_range
+ // ioctl by hand. (name_fd() preserves errno across its
+ // readlink(), so THROW_ERRNO still reports the ioctl's.)
+ ostringstream oss;
+ oss << "FILE_EXTENT_SAME failed:"
+ << " src fd " << m_fd << " '" << name_fd(m_fd) << "'"
+ << " offset " << to_hex(m_logical_offset)
+ << " length " << to_hex(m_length);
+ for (size_t i = 0; i < m_info.size(); ++i) {
+ const auto &info = m_info[i];
+ oss << " -> dst[" << i << "] fd " << info.fd
+ << " '" << name_fd(info.fd) << "'"
+ << " offset " << to_hex(info.logical_offset);
+ }
+ THROW_ERRNO(oss.str());
}
count = 0;
for (auto i = m_info.cbegin(); i != m_info.cend(); ++i) {