Configure read ahead for fuse mounts
For fuse read ahead can be configured by writing a value to the
/sys/class/bdi/{MAJOR}:{MINOR}/read_ahead_kb file.
There are several different ways of getting {MAJOR}:{MINOR} values of
the filesystem:
* Look at st_dev of stat("/mnt/user/0/emulated").
* Parse /proc/self/mountinfo.
Stat'ing approach is used since it's easier to implement.
Bug: 157982297
Test: atest vold_tests
Test: adb shell cat /proc/self/mountinfo to get MAJOR:MINOR
Test: adb shell cat /sys/class/bdi/{MAJOR}:{MINOR}/read_ahead_kb
Test: created public volume, checked it's read_ahead_kb is also 256
Change-Id: Id0c149c4af1ceabf3afc33b4100563a512b38316
diff --git a/Utils.cpp b/Utils.cpp
index e3a419f..af0027f 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -63,6 +63,7 @@
using android::base::ReadFileToString;
using android::base::StartsWith;
using android::base::StringPrintf;
+using android::base::unique_fd;
namespace android {
namespace vold {
@@ -92,6 +93,10 @@
// other between multiple threads.
static std::mutex kSecurityLock;
+std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path) {
+ return StringPrintf("/mnt/user/%d/%s", user_id, relative_upper_path.c_str());
+}
+
status_t CreateDeviceNode(const std::string& path, dev_t dev) {
std::lock_guard<std::mutex> lock(kSecurityLock);
const char* cpath = path.c_str();
@@ -1355,6 +1360,33 @@
return OK;
}
+// Configures read ahead property of the fuse filesystem with the mount point |fuse_mount| by
+// writing |read_ahead_kb| to the /sys/class/bdi/MAJOR:MINOR/read_ahead_kb.
+void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb) {
+ LOG(INFO) << "Configuring read_ahead of " << fuse_mount << " fuse filesystem to "
+ << read_ahead_kb << "kb";
+ // First figure out MAJOR:MINOR of fuse_mount. Simplest way is to stat the path.
+ struct stat info;
+ if (stat(fuse_mount.c_str(), &info) != 0) {
+ PLOG(ERROR) << "Failed to stat " << fuse_mount;
+ return;
+ }
+ unsigned int maj = major(info.st_dev);
+ unsigned int min = minor(info.st_dev);
+ LOG(INFO) << fuse_mount << " has major:minor " << maj << ":" << min;
+ // We found major:minor of our filesystem, time to configure read ahead!
+ std::string read_ahead_file = StringPrintf("/sys/class/bdi/%u:%u/read_ahead_kb", maj, min);
+ unique_fd fd(TEMP_FAILURE_RETRY(open(read_ahead_file.c_str(), O_WRONLY | O_CLOEXEC)));
+ if (fd.get() == -1) {
+ PLOG(ERROR) << "Failed to open " << read_ahead_file;
+ return;
+ }
+ LOG(INFO) << "Writing " << read_ahead_kb << " to " << read_ahead_file;
+ if (!WriteStringToFd(std::to_string(read_ahead_kb), fd)) {
+ PLOG(ERROR) << "Failed to write to " << read_ahead_file;
+ }
+}
+
status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
const std::string& relative_upper_path, android::base::unique_fd* fuse_fd) {
std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));
diff --git a/Utils.h b/Utils.h
index c4926e7..a1d34b8 100644
--- a/Utils.h
+++ b/Utils.h
@@ -47,6 +47,8 @@
// TODO remove this with better solution, b/64143519
extern bool sSleepOnUnmount;
+std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path);
+
status_t CreateDeviceNode(const std::string& path, dev_t dev);
status_t DestroyDeviceNode(const std::string& path);
@@ -174,6 +176,8 @@
bool writeStringToFile(const std::string& payload, const std::string& filename);
+void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb);
+
status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
const std::string& relative_upper_path, android::base::unique_fd* fuse_fd);
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index bb5aa86..26d9582 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -402,6 +402,8 @@
return res;
}
+ ConfigureReadAheadForFuse(GetFuseMountPathForUser(user_id, label), 256u);
+
// All mounts where successful, disable scope guards
sdcardfs_guard.Disable();
fuse_guard.Disable();
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 6195482..64b5dfa 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -250,6 +250,8 @@
return -EIO;
}
}
+
+ ConfigureReadAheadForFuse(GetFuseMountPathForUser(user_id, stableName), 256u);
}
return OK;