// Mount the volume specified by path at the given mount_point. int ensure_path_mounted_at(const std::string& path, const std::string& mount_point) { return android::fs_mgr::EnsurePathMounted(&fstab, path, mount_point) ? 0 : -1;
}
int ensure_path_mounted(const std::string& path) { // Mount at the default mount point. return android::fs_mgr::EnsurePathMounted(&fstab, path) ? 0 : -1;
}
static FstabEntry* LocateFormattableEntry(const std::vector<FstabEntry*>& entries) { if (entries.empty()) { return nullptr;
}
FstabEntry* f2fs_entry = nullptr; for (auto&& entry : entries) { if (getpagesize() != 4096 && entry->fs_type == "f2fs") {
f2fs_entry = entry; continue;
} if (f2fs_entry) {
LOG(INFO) << "Skipping F2FS format for block device " << entry->blk_device << " @ "
<< entry->mount_point
<< " in non-4K mode for dev option enabled devices, " "as these devices need to toggle between 4K/16K mode, and F2FS does " "not support page_size != block_size configuration.";
} return entry;
} if (f2fs_entry) {
LOG(INFO) << "Using F2FS for " << f2fs_entry->blk_device << " @ " << f2fs_entry->mount_point
<< " even though we are in non-4K mode. Device might require a data wipe after " "going back to 4K mode, as F2FS does not support page_size != block_size";
} return f2fs_entry;
}
bool WipeBlockDevice(constchar* path) {
android::base::unique_fd fd(open(path, O_RDWR)); if (fd == -1) {
PLOG(ERROR) << "WipeBlockDevice: failed to open " << path; returnfalse;
}
int64_t device_size = get_file_size(fd.get(), 0); if (device_size < 0) {
PLOG(ERROR) << "WipeBlockDevice: failed to determine size of " << device_size; returnfalse;
} if (device_size == 0) {
PLOG(ERROR) << "WipeBlockDevice: block device " << device_size << " has 0 length, skip wiping"; returnfalse;
} if (!wipe_block_device(fd.get(), device_size)) { returntrue;
}
PLOG(ERROR) << "Failed to wipe " << path; returnfalse;
}
// If the raw disk will be used as a metadata encrypted device mapper target, // next boot will do encrypt_in_place the raw disk. While fs_mgr mounts /data // as RO to avoid write file operations before encrypt_inplace, this code path // is not well tested so we would like to avoid it if possible. For safety, // let vold do the formatting on boot for metadata encrypted devices, except // when user specified a new fstype. Because init formats /data according // to fstab, it's difficult to override the fstab in init. if (!v->metadata_key_dir.empty() && length == 0 && new_fstype.empty()) {
android::base::unique_fd fd(open(v->blk_device.c_str(), O_RDWR)); if (fd == -1) {
PLOG(ERROR) << "format_volume: failed to open " << v->blk_device; return -1;
}
int64_t device_size = get_file_size(fd.get(), 0); if (device_size > 0 && !wipe_block_device(fd.get(), device_size)) {
LOG(INFO) << "format_volume: wipe metadata encrypted " << v->blk_device << " with size "
<< device_size; return0;
}
}
// Following is added for Project ID's quota as they require wider inodes. // The Quotas themselves are enabled by tune2fs on boot. if (needs_projid) {
mke2fs_args.push_back("-I");
mke2fs_args.push_back("512");
}
if (v->fs_mgr_flags.ext_meta_csum) {
mke2fs_args.push_back("-O");
mke2fs_args.push_back("metadata_csum");
mke2fs_args.push_back("-O");
mke2fs_args.push_back("64bit");
mke2fs_args.push_back("-O");
mke2fs_args.push_back("extent");
}
int raid_stride = v->logical_blk_size / kBlockSize; int raid_stripe_width = v->erase_blk_size / kBlockSize; // stride should be the max of 8KB and logical block size if (v->logical_blk_size != 0 && v->logical_blk_size < 8192) {
raid_stride = 8192 / kBlockSize;
} if (v->erase_blk_size != 0 && v->logical_blk_size != 0) {
mke2fs_args.push_back("-E");
mke2fs_args.push_back(
android::base::StringPrintf("stride=%d,stripe-width=%d", raid_stride, raid_stripe_width));
}
mke2fs_args.push_back(v->blk_device); if (length != 0) {
mke2fs_args.push_back(std::to_string(length / kBlockSize));
}
int result = exec_cmd(mke2fs_args); if (result == 0 && !directory.empty()) {
std::vector<std::string> e2fsdroid_args = { "/system/bin/e2fsdroid", "-e", "-f", directory, "-a", volume, v->blk_device,
};
result = exec_cmd(e2fsdroid_args);
}
if (result != 0) {
PLOG(ERROR) << "format_volume: Failed to make ext4 on " << v->blk_device; return -1;
} return0;
}
// Has to be f2fs because we checked earlier.
LOG(INFO) << "Formatting " << v->blk_device << " as f2fs"; static constexpr int kSectorSize = 4096;
std::vector<std::string> make_f2fs_cmd = { "/system/bin/make_f2fs", "-g", "android",
};
if (needs_casefold) {
make_f2fs_cmd.push_back("-O");
make_f2fs_cmd.push_back("casefold");
make_f2fs_cmd.push_back("-C");
make_f2fs_cmd.push_back("utf8");
} if (v->fs_mgr_flags.fs_compress) {
make_f2fs_cmd.push_back("-O");
make_f2fs_cmd.push_back("compression");
make_f2fs_cmd.push_back("-O");
make_f2fs_cmd.push_back("extra_attr");
} if (android::base::GetBoolProperty("external_storage.packedssa.enabled", false)) {
make_f2fs_cmd.push_back("-O");
make_f2fs_cmd.push_back("packed_ssa");
}
make_f2fs_cmd.push_back("-b");
make_f2fs_cmd.push_back(std::to_string(getpagesize()));
make_f2fs_cmd.push_back(v->blk_device); if (length >= kSectorSize) {
make_f2fs_cmd.push_back(std::to_string(length / kSectorSize));
}
if (exec_cmd(make_f2fs_cmd) != 0) {
PLOG(ERROR) << "format_volume: Failed to make_f2fs on " << v->blk_device
<< " wiping the block device to avoid leaving partially formatted data.";
WipeBlockDevice(v->blk_device.c_str()); return -1;
} if (!directory.empty()) {
std::vector<std::string> sload_f2fs_cmd = { "/system/bin/sload_f2fs", "-f", directory, "-t", volume, v->blk_device,
}; if (exec_cmd(sload_f2fs_cmd) != 0) {
PLOG(ERROR) << "format_volume: Failed to sload_f2fs on " << v->blk_device; return -1;
}
} return0;
}
int format_volume(const std::string& volume) { return format_volume(volume, "", "");
}
int setup_install_mounts() { if (fstab.empty()) {
LOG(ERROR) << "can't set up install mounts: no fstab loaded"; return -1;
} for (const FstabEntry& entry : fstab) { // We don't want to do anything with "/". if (entry.mount_point == "/") { continue;
}
if (entry.mount_point == "/tmp" || entry.mount_point == "/cache") { if (ensure_path_mounted(entry.mount_point) != 0) {
LOG(ERROR) << "Failed to mount " << entry.mount_point; return -1;
}
} else { if (ensure_path_unmounted(entry.mount_point) != 0) {
LOG(ERROR) << "Failed to unmount " << entry.mount_point; return -1;
}
}
} return0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.