Merge changes I060f438c,I48fbca45
* changes:
fastbootd: use O_DIRECT for write partition
fastbootd: allow passage of flags to open partition
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 0a72812..4042531 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -725,7 +725,7 @@
return false;
}
- if (!OpenPartition(device_, partition_name_, &handle_, true /* read */)) {
+ if (!OpenPartition(device_, partition_name_, &handle_, O_RDONLY)) {
ret_ = device_->WriteFail(
android::base::StringPrintf("Cannot open %s", partition_name_.c_str()));
return false;
diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp
index 9b5d2cd..3f9bcdc 100644
--- a/fastboot/device/flashing.cpp
+++ b/fastboot/device/flashing.cpp
@@ -16,6 +16,7 @@
#include "flashing.h"
#include <fcntl.h>
+#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -77,9 +78,20 @@
int FlashRawDataChunk(int fd, const char* data, size_t len) {
size_t ret = 0;
+ const size_t max_write_size = 1048576;
+ void* aligned_buffer;
+
+ if (posix_memalign(&aligned_buffer, 4096, max_write_size)) {
+ PLOG(ERROR) << "Failed to allocate write buffer";
+ return -ENOMEM;
+ }
+
+ auto aligned_buffer_unique_ptr = std::unique_ptr<void, decltype(&free)>{aligned_buffer, free};
+
while (ret < len) {
- int this_len = std::min(static_cast<size_t>(1048576UL * 8), len - ret);
- int this_ret = write(fd, data, this_len);
+ int this_len = std::min(max_write_size, len - ret);
+ memcpy(aligned_buffer_unique_ptr.get(), data, this_len);
+ int this_ret = write(fd, aligned_buffer_unique_ptr.get(), this_len);
if (this_ret < 0) {
PLOG(ERROR) << "Failed to flash data of len " << len;
return -1;
@@ -147,7 +159,7 @@
int Flash(FastbootDevice* device, const std::string& partition_name) {
PartitionHandle handle;
- if (!OpenPartition(device, partition_name, &handle)) {
+ if (!OpenPartition(device, partition_name, &handle, O_WRONLY | O_DIRECT)) {
return -ENOENT;
}
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
index 07ad902..97b5ad4 100644
--- a/fastboot/device/utility.cpp
+++ b/fastboot/device/utility.cpp
@@ -78,7 +78,7 @@
} // namespace
bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle,
- bool read) {
+ int flags) {
// We prioritize logical partitions over physical ones, and do this
// consistently for other partition operations (like getvar:partition-size).
if (LogicalPartitionExists(device, name)) {
@@ -90,7 +90,6 @@
return false;
}
- int flags = (read ? O_RDONLY : O_WRONLY);
flags |= (O_EXCL | O_CLOEXEC | O_BINARY);
unique_fd fd(TEMP_FAILURE_RETRY(open(handle->path().c_str(), flags)));
if (fd < 0) {
diff --git a/fastboot/device/utility.h b/fastboot/device/utility.h
index c2646d7..1d81b7a 100644
--- a/fastboot/device/utility.h
+++ b/fastboot/device/utility.h
@@ -76,9 +76,11 @@
bool LogicalPartitionExists(FastbootDevice* device, const std::string& name,
bool* is_zero_length = nullptr);
-// If read, partition is readonly. Else it is write only.
+// Partition is O_WRONLY by default, caller should pass O_RDONLY for reading.
+// Caller may pass additional flags if needed. (O_EXCL | O_CLOEXEC | O_BINARY)
+// will be logically ORed internally.
bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle,
- bool read = false);
+ int flags = O_WRONLY);
bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number);
std::vector<std::string> ListPartitions(FastbootDevice* device);