commit b7b1b26: [Minor] Allow to map files at some offset

Vsevolod Stakhov vsevolod at rspamd.com
Tue Oct 25 02:14:03 UTC 2022


Author: Vsevolod Stakhov
Date: 2022-10-24 15:29:59 +0100
URL: https://github.com/rspamd/rspamd/commit/b7b1b264b58c2b7bbe0fc1aafc623e9d609d1f63

[Minor] Allow to map files at some offset

---
 src/libserver/hyperscan_tools.cxx |  2 +-
 src/libutil/cxx/file_util.cxx     | 26 ++++++++++++++++----------
 src/libutil/cxx/file_util.hxx     | 10 ++++++----
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/libserver/hyperscan_tools.cxx b/src/libserver/hyperscan_tools.cxx
index ff566b9be..89cc4e23b 100644
--- a/src/libserver/hyperscan_tools.cxx
+++ b/src/libserver/hyperscan_tools.cxx
@@ -268,7 +268,7 @@ hs_shared_from_serialized(raii_mmaped_file &&map) -> tl::expected<hs_shared_data
 	return tl::expected<hs_shared_database, error>{tl::in_place, target};
 }
 
-auto load_cached_hs_file(const char *fname) -> tl::expected<hs_shared_database, error>
+auto load_cached_hs_file(const char *fname, std::int64_t offset = 0) -> tl::expected<hs_shared_database, error>
 {
 	auto &hs_cache = hs_known_files_cache::get();
 	const auto *log_func = RSPAMD_LOG_FUNC;
diff --git a/src/libutil/cxx/file_util.cxx b/src/libutil/cxx/file_util.cxx
index 1993ff666..f457a4cd7 100644
--- a/src/libutil/cxx/file_util.cxx
+++ b/src/libutil/cxx/file_util.cxx
@@ -181,31 +181,36 @@ auto raii_locked_file::unlock() -> raii_file {
 	return raii_file{static_cast<raii_file&&>(std::move(*this))};
 }
 
-raii_mmaped_file::raii_mmaped_file(raii_file &&_file, void *_map)
-		: file(std::move(_file)), map(_map)
+raii_mmaped_file::raii_mmaped_file(raii_file &&file, void *map, std::size_t sz)
+		: file(std::move(file)), map(map), map_size(sz)
 {
 }
 
 auto raii_mmaped_file::mmap_shared(raii_file &&file,
-								   int flags) -> tl::expected<raii_mmaped_file, error>
+								   int flags, std::int64_t offset) -> tl::expected<raii_mmaped_file, error>
 {
 	void *map;
 
+	if (file.get_stat().st_size < offset || offset < 0) {
+		return tl::make_unexpected(error {
+			fmt::format("cannot mmap file {} due to incorrect offset; offset={}, size={}",
+				file.get_name(), offset, file.get_size()), EINVAL});
+	}
 	/* Update stat on file to ensure it is up-to-date */
 	file.update_stat();
-	map = mmap(NULL, file.get_stat().st_size, flags, MAP_SHARED, file.get_fd(), 0);
+	map = mmap(nullptr, file.get_size() - offset, flags, MAP_SHARED, file.get_fd(), offset);
 
 	if (map == MAP_FAILED) {
-		return tl::make_unexpected(error { fmt::format("cannot mmap file at fd: {}: {}",
-				file.get_fd(), ::strerror(errno)), errno });
+		return tl::make_unexpected(error { fmt::format("cannot mmap file {}: {}",
+				file.get_name(), ::strerror(errno)), errno });
 
 	}
 
-	return raii_mmaped_file{std::move(file), map};
+	return raii_mmaped_file{std::move(file), map,  file.get_size() - offset};
 }
 
 auto raii_mmaped_file::mmap_shared(const char *fname, int open_flags,
-								   int mmap_flags) -> tl::expected<raii_mmaped_file, error>
+								   int mmap_flags, std::int64_t offset) -> tl::expected<raii_mmaped_file, error>
 {
 	auto file = raii_file::open(fname, open_flags);
 
@@ -213,13 +218,13 @@ auto raii_mmaped_file::mmap_shared(const char *fname, int open_flags,
 		return tl::make_unexpected(file.error());
 	}
 
-	return raii_mmaped_file::mmap_shared(std::move(file.value()), mmap_flags);
+	return raii_mmaped_file::mmap_shared(std::move(file.value()), mmap_flags, offset);
 }
 
 raii_mmaped_file::~raii_mmaped_file()
 {
 	if (map != nullptr) {
-		munmap(map, file.get_stat().st_size);
+		munmap(map, map_size);
 	}
 }
 
@@ -227,6 +232,7 @@ raii_mmaped_file::raii_mmaped_file(raii_mmaped_file &&other) noexcept
 		: file(std::move(other.file))
 {
 	std::swap(map, other.map);
+	std::swap(map_size, other.map_size);
 }
 
 auto raii_file_sink::create(const char *fname, int flags, int perms,
diff --git a/src/libutil/cxx/file_util.hxx b/src/libutil/cxx/file_util.hxx
index 9fbcda540..06073dbab 100644
--- a/src/libutil/cxx/file_util.hxx
+++ b/src/libutil/cxx/file_util.hxx
@@ -196,14 +196,14 @@ private:
  */
 struct raii_mmaped_file final {
 	~raii_mmaped_file();
-	static auto mmap_shared(raii_file &&file, int flags) -> tl::expected<raii_mmaped_file, error>;
-	static auto mmap_shared(const char *fname, int open_flags, int mmap_flags) -> tl::expected<raii_mmaped_file, error>;
+	static auto mmap_shared(raii_file &&file, int flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>;
+	static auto mmap_shared(const char *fname, int open_flags, int mmap_flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>;
 	// Returns a constant pointer to the underlying map
 	auto get_map() const -> void* {return map;}
 	auto get_file() const -> const raii_file& { return file; }
 	// Passes the ownership of the mmaped memory to the callee
 	auto steal_map() -> std::tuple<void *, std::size_t> {
-		auto ret = std::make_tuple(this->map, file.get_stat().st_size);
+		auto ret = std::make_tuple(this->map, map_size);
 		this->map = nullptr;
 		return ret;
 	}
@@ -212,6 +212,7 @@ struct raii_mmaped_file final {
 
 	raii_mmaped_file& operator=(raii_mmaped_file &&other) noexcept {
 		std::swap(map, other.map);
+		std::swap(map_size, other.map_size);
 		file = std::move(other.file);
 
 		return *this;
@@ -225,9 +226,10 @@ struct raii_mmaped_file final {
 	raii_mmaped_file(const raii_mmaped_file &other) = delete;
 private:
 	/* Is intended to be used with map_shared */
-	explicit raii_mmaped_file(raii_file &&_file, void *_map);
+	explicit raii_mmaped_file(raii_file &&_file, void *_map, std::size_t sz);
 	raii_file file;
 	void *map = nullptr;
+	std::size_t map_size;
 };
 
 /**


More information about the Commits mailing list