summaryrefslogtreecommitdiffstats
path: root/pnor_partition.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pnor_partition.cpp')
-rw-r--r--pnor_partition.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/pnor_partition.cpp b/pnor_partition.cpp
index 390c4d5..84aeb3f 100644
--- a/pnor_partition.cpp
+++ b/pnor_partition.cpp
@@ -10,11 +10,14 @@
#include <phosphor-logging/elog-errors.hpp>
#include <assert.h>
+#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <syslog.h>
+#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include <unistd.h>
#include "common.h"
@@ -86,7 +89,31 @@ fs::path Request::getPartitionFilePath(int flags)
return dst;
}
-ssize_t Request::fulfil(void *buf, size_t len, int flags)
+size_t Request::clamp(size_t len)
+{
+ size_t maxAccess = offset + len;
+ size_t partSize = partition.data.size << ctx->block_size_shift;
+ return std::min(maxAccess, partSize) - offset;
+}
+
+void Request::resize(const fs::path &path, size_t len)
+{
+ size_t maxAccess = offset + len;
+ size_t fileSize = fs::file_size(path);
+ if (maxAccess < fileSize)
+ {
+ return;
+ }
+ MSG_DBG("Resizing %s to %zu bytes\n", path.c_str(), maxAccess);
+ int rc = truncate(path.c_str(), maxAccess);
+ if (rc == -1)
+ {
+ MSG_ERR("Failed to resize %s: %d\n", path.c_str(), errno);
+ throw std::system_error(errno, std::system_category());
+ }
+}
+
+size_t Request::fulfil(const fs::path &path, int flags, void *buf, size_t len)
{
if (!(flags == O_RDONLY || flags == O_RDWR))
{
@@ -96,8 +123,6 @@ ssize_t Request::fulfil(void *buf, size_t len, int flags)
throw std::invalid_argument(err.str());
}
- fs::path path = getPartitionFilePath(flags);
-
int fd = ::open(path.c_str(), flags);
if (fd == -1)
{
@@ -106,45 +131,29 @@ ssize_t Request::fulfil(void *buf, size_t len, int flags)
throw std::system_error(errno, std::system_category());
}
+ size_t fileSize = fs::file_size(path);
int mprot = PROT_READ | ((flags == O_RDWR) ? PROT_WRITE : 0);
- auto map = mmap(NULL, partition.data.actual, mprot, MAP_SHARED, fd, 0);
+ auto map = mmap(NULL, fileSize, mprot, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
- MSG_ERR("Failed to map backing file '%s' for %d bytes: %d\n",
- path.c_str(), partition.data.actual, errno);
+ MSG_ERR("Failed to map backing file '%s' for %zd bytes: %d\n",
+ path.c_str(), fileSize, errno);
throw std::system_error(errno, std::system_category());
}
// copy to the reserved memory area
if (flags == O_RDONLY)
{
- len = std::min(partition.data.actual - offset, len);
- memcpy(buf, (char *)map + offset, len);
+ memset(buf, 0xff, len);
+ memcpy(buf, (char *)map + offset, std::min(len, fileSize));
}
else
{
- // if the asked offset + no of bytes to read is greater
- // then size of the partition file then throw error.
- //
- // FIXME: Don't use .actual, use (.size << ctx->block_size_shift),
- // otherwise we can't grow the size of the data to fill the partition
- if ((base + offset + len) > (base + partition.data.actual))
- {
- munmap(map, partition.data.actual);
- close(fd);
-
- /* FIXME: offset calculation */
- std::stringstream err;
- err << "Request size 0x" << std::hex << len << " from offset 0x"
- << std::hex << offset << " exceeds the partition size 0x"
- << std::hex << partition.data.actual;
- throw OutOfBoundsOffset(err.str());
- }
memcpy((char *)map + offset, buf, len);
set_flash_bytemap(ctx, base + offset, len, FLASH_DIRTY);
}
- munmap(map, partition.data.actual);
+ munmap(map, fileSize);
close(fd);
return len;
OpenPOWER on IntegriCloud