diff --git a/include/crucible/fs.h b/include/crucible/fs.h index 2869d1e..0b34619 100644 --- a/include/crucible/fs.h +++ b/include/crucible/fs.h @@ -143,7 +143,7 @@ namespace crucible { off_t end() const; }; - struct Fiemap : public fiemap { + struct Fiemap { // because fiemap.h insists on giving FIEMAP_MAX_OFFSET // a different type from the struct fiemap members @@ -155,8 +155,14 @@ namespace crucible { void do_ioctl(int fd); vector m_extents; - uint64_t m_min_count = (4096 - sizeof(fiemap)) / sizeof(fiemap_extent); - uint64_t m_max_count = 16 * 1024 * 1024 / sizeof(fiemap_extent); + decltype(fiemap::fm_extent_count) m_min_count = (4096 - sizeof(fiemap)) / sizeof(fiemap_extent); + decltype(fiemap::fm_extent_count) m_max_count = 16 * 1024 * 1024 / sizeof(fiemap_extent); + uint64_t m_start; + uint64_t m_length; + // FIEMAP is slow and full of lies. + // This makes FIEMAP even slower, but reduces the lies a little. + decltype(fiemap::fm_flags) m_flags = FIEMAP_FLAG_SYNC; + friend ostream &operator<<(ostream &, const Fiemap &); }; ostream & operator<<(ostream &os, const fiemap_extent *info); diff --git a/lib/extentwalker.cc b/lib/extentwalker.cc index 83f430e..e1d47bc 100644 --- a/lib/extentwalker.cc +++ b/lib/extentwalker.cc @@ -640,9 +640,7 @@ namespace crucible { ExtentWalker::get_extent_map(off_t pos) { EWLOG("get_extent_map(" << to_hex(pos) << ")"); - Fiemap fm; - fm.fm_start = ranged_cast(pos); - fm.fm_length = ranged_cast(numeric_limits::max() - pos); + Fiemap fm(ranged_cast(pos), ranged_cast(numeric_limits::max() - pos)); fm.m_max_count = fm.m_min_count = sc_extent_fetch_max; fm.do_ioctl(m_fd); Vec rv; diff --git a/lib/fs.cc b/lib/fs.cc index 4f4167f..902b056 100644 --- a/lib/fs.cc +++ b/lib/fs.cc @@ -655,13 +655,10 @@ namespace crucible { operator<<(ostream &os, const Fiemap &args) { os << "Fiemap {"; - os << " .fm_start = " << to_hex(args.fm_start) << ".." << to_hex(args.fm_start + args.fm_length); - os << ", .fm_length = " << to_hex(args.fm_length); - if (args.fm_flags) os << ", .fm_flags = " << fiemap_flags_ntoa(args.fm_flags); - os << ", .fm_mapped_extents = " << args.fm_mapped_extents; - os << ", .fm_extent_count = " << args.fm_extent_count; - if (args.fm_reserved) os << ", .fm_reserved = " << args.fm_reserved; - os << ", .fm_extents[] = {"; + os << " .m_start = " << to_hex(args.m_start) << ".." << to_hex(args.m_start + args.m_length); + os << ", .m_length = " << to_hex(args.m_length); + os << ", .m_flags = " << fiemap_flags_ntoa(args.m_flags); + os << ", .fm_extents[" << args.m_extents.size() << "] = {"; size_t count = 0; for (auto i = args.m_extents.cbegin(); i != args.m_extents.cend(); ++i) { os << "\n\t[" << count++ << "] = " << &(*i) << ","; @@ -670,13 +667,8 @@ namespace crucible { } Fiemap::Fiemap(uint64_t start, uint64_t length) : - fiemap( (fiemap) { - .fm_start = start, - .fm_length = length, - // FIEMAP is slow and full of lies. - // This makes FIEMAP even slower, but reduces the lies a little. - .fm_flags = FIEMAP_FLAG_SYNC, - }) + m_start(start), + m_length(length) { } @@ -684,25 +676,25 @@ namespace crucible { Fiemap::do_ioctl(int fd) { THROW_CHECK1(out_of_range, m_min_count, m_min_count <= m_max_count); + THROW_CHECK1(out_of_range, m_min_count, m_min_count > 0); - auto extent_count = m_min_count; - ByteVector ioctl_arg(static_cast(*this), sizeof(fiemap) + extent_count * sizeof(fiemap_extent)); + const auto extent_count = m_min_count; + ByteVector ioctl_arg(sizeof(fiemap) + extent_count * sizeof(fiemap_extent)); fiemap *const ioctl_ptr = ioctl_arg.get(); - auto start = fm_start; - auto end = fm_start + fm_length; - - auto orig_start = fm_start; - auto orig_length = fm_length; + auto start = m_start; + const auto end = m_start + m_length; vector extents; while (start < end && extents.size() < m_max_count) { - ioctl_ptr->fm_start = start; - ioctl_ptr->fm_length = end - start; - ioctl_ptr->fm_extent_count = extent_count; - ioctl_ptr->fm_mapped_extents = 0; + *ioctl_ptr = (fiemap) { + .fm_start = start, + .fm_length = end - start, + .fm_flags = m_flags, + .fm_extent_count = extent_count, + }; // cerr << "Before (fd = " << fd << ") : " << ioctl_ptr << endl; DIE_IF_MINUS_ONE(ioctl(fd, FS_IOC_FIEMAP, ioctl_ptr)); @@ -728,11 +720,6 @@ namespace crucible { } } - fiemap *this_ptr = static_cast(this); - *this_ptr = *ioctl_ptr; - fm_start = orig_start; - fm_length = orig_length; - fm_extent_count = extents.size(); m_extents = extents; } diff --git a/src/fiemap.cc b/src/fiemap.cc index fb6085a..2a2c0cf 100644 --- a/src/fiemap.cc +++ b/src/fiemap.cc @@ -22,15 +22,17 @@ main(int argc, char **argv) cout << "File: " << filename << endl; Fd fd = open_or_die(filename, O_RDONLY); - Fiemap fm; - fm.fm_flags &= ~(FIEMAP_FLAG_SYNC); + uint64_t start = 0; + uint64_t length = Fiemap::s_fiemap_max_offset; + if (argc > 2) { start = stoull(argv[2], nullptr, 0); } + if (argc > 3) { length = stoull(argv[3], nullptr, 0); } + length = min(length, Fiemap::s_fiemap_max_offset - start); + Fiemap fm(start, length); + fm.m_flags &= ~(FIEMAP_FLAG_SYNC); fm.m_max_count = 100; - if (argc > 2) { fm.fm_start = stoull(argv[2], nullptr, 0); } - if (argc > 3) { fm.fm_length = stoull(argv[3], nullptr, 0); } - if (argc > 4) { fm.fm_flags = stoull(argv[4], nullptr, 0); } - fm.fm_length = min(fm.fm_length, Fiemap::s_fiemap_max_offset - fm.fm_start); - uint64_t stop_at = fm.fm_start + fm.fm_length; - uint64_t last_byte = fm.fm_start; + if (argc > 4) { fm.m_flags = stoull(argv[4], nullptr, 0); } + uint64_t stop_at = start + length; + uint64_t last_byte = start; do { fm.do_ioctl(fd); // cerr << fm; @@ -45,8 +47,8 @@ main(int argc, char **argv) last_logical = extent.fe_logical + extent.fe_length; last_byte = last_logical; } - fm.fm_start = last_logical; - } while (fm.fm_start < stop_at); + fm.m_start = last_logical; + } while (fm.m_start < stop_at); }); exit(EXIT_SUCCESS); }