MTP: add a new parameter for cancelEvents function
Currently, cancelEvents in MTP will cancel the requests
one by one, and it will check each response to confirm
success or failure. However, if kernel usb controller
driver got the cancel request, the driver will handle
all requests in the same endpoint so that the second
io_cancel in cancelEvents will be useless. This behavior
change start from kernel 5.x.
This patch will add a parameter to check whether kernel
usb controller driver uses the new behavior so that MTP
could cancel the requests correctly.
Bug: 181729410
Test: cancel a transmitting file and then check the MTP operation
Merged-In: I4e172fa62c297ac33b0c97c67f3f7baa817fd8bf
(cherry picked from commit 305e62ec197f65ebf29d79e8d03ea3b296b4e690)
Signed-off-by: sekaiacg <sekaiacg@gmail.com>
Change-Id: I8963d69b7b7fb6d6d8fe71c293551e2ab9f13470
diff --git a/mtp/ffs/MtpFfsHandle.cpp b/mtp/ffs/MtpFfsHandle.cpp
index 5710aec..9356d4c 100644
--- a/mtp/ffs/MtpFfsHandle.cpp
+++ b/mtp/ffs/MtpFfsHandle.cpp
@@ -73,6 +73,7 @@
MtpFfsHandle::MtpFfsHandle(int controlFd) {
mControl.reset(controlFd);
+ mBatchCancel = android::base::GetBoolProperty("sys.usb.mtp.batchcancel", false);
}
MtpFfsHandle::~MtpFfsHandle() {}
@@ -370,7 +371,7 @@
}
int MtpFfsHandle::cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start,
- unsigned end) {
+ unsigned end, bool is_batch_cancel) {
// Some manpages for io_cancel are out of date and incorrect.
// io_cancel will return -EINPROGRESS on success and does
// not place the event in the given memory. We have to use
@@ -386,6 +387,10 @@
} else {
num_events++;
}
+ if (is_batch_cancel && num_events == 1) {
+ num_events = end - start;
+ break;
+ }
}
if (num_events != end - start) {
ret = -1;
@@ -495,7 +500,8 @@
num_events += this_events;
if (event_ret == -1) {
- cancelEvents(mIobuf[i].iocb.data(), ioevs, num_events, mIobuf[i].actual);
+ cancelEvents(mIobuf[i].iocb.data(), ioevs, num_events, mIobuf[i].actual,
+ mBatchCancel);
return -1;
}
ret += event_ret;
@@ -512,7 +518,7 @@
}
}
if (short_packet) {
- if (cancelEvents(mIobuf[i].iocb.data(), ioevs, short_i, mIobuf[i].actual)) {
+ if (cancelEvents(mIobuf[i].iocb.data(), ioevs, short_i, mIobuf[i].actual, false)) {
write_error = true;
}
}
@@ -613,7 +619,7 @@
&num_events) != ret) {
error = true;
cancelEvents(mIobuf[(i-1)%NUM_IO_BUFS].iocb.data(), ioevs, num_events,
- mIobuf[(i-1)%NUM_IO_BUFS].actual);
+ mIobuf[(i-1)%NUM_IO_BUFS].actual, false);
}
has_write = false;
}
diff --git a/mtp/ffs/MtpFfsHandle.h b/mtp/ffs/MtpFfsHandle.h
index 20f74fa..8c3725e 100644
--- a/mtp/ffs/MtpFfsHandle.h
+++ b/mtp/ffs/MtpFfsHandle.h
@@ -17,6 +17,7 @@
#ifndef _MTP_FFS_HANDLE_H
#define _MTP_FFS_HANDLE_H
+#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <linux/aio_abi.h>
#include <mutex>
@@ -55,6 +56,7 @@
static int getPacketSize(int ffs_fd);
bool mCanceled;
+ bool mBatchCancel;
android::base::unique_fd mControl;
// "in" from the host's perspective => sink for mtp server
@@ -74,7 +76,8 @@
int iobufSubmit(struct io_buffer *buf, int fd, unsigned length, bool read);
// Cancel submitted requests from start to end in the given array. Return 0 or -1.
- int cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start, unsigned end);
+ int cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start, unsigned end,
+ bool is_batch_cancel);
// Wait for at minimum the given number of events. Returns the amount of data in the returned
// events. Increments counter by the number of events returned.