From 62bd9e04c72f81a99a613ce00e045fa290821807 Mon Sep 17 00:00:00 2001 From: Hashcode Date: Tue, 19 Nov 2013 21:59:42 -0800 Subject: add support for fsflags= option in twrp.fstab file example userdata line (as needed by MotoX): /data f2fs /dev/block/platform/msm_sdcc.1/by-name/userdata flags=fsflags="inline_xattr" Code for parsing flags/options originally based on AOSP fs_mgr sources. Change-Id: I5fb2b5d5cdd08137e6bf71f0085a3f8aebd889a8 --- partition.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-- partitionmanager.cpp | 2 ++ partitions.hpp | 3 +++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/partition.cpp b/partition.cpp index c1e214e52..061a3e189 100644 --- a/partition.cpp +++ b/partition.cpp @@ -57,6 +57,31 @@ using namespace std; extern struct selabel_handle *selinux_handle; +struct flag_list { + const char *name; + unsigned flag; +}; + +static struct flag_list mount_flags[] = { + { "noatime", MS_NOATIME }, + { "noexec", MS_NOEXEC }, + { "nosuid", MS_NOSUID }, + { "nodev", MS_NODEV }, + { "nodiratime", MS_NODIRATIME }, + { "ro", MS_RDONLY }, + { "rw", 0 }, + { "remount", MS_REMOUNT }, + { "bind", MS_BIND }, + { "rec", MS_REC }, + { "unbindable", MS_UNBINDABLE }, + { "private", MS_PRIVATE }, + { "slave", MS_SLAVE }, + { "shared", MS_SHARED }, + { "sync", MS_SYNCHRONOUS }, + { "defaults", 0 }, + { 0, 0 }, +}; + TWPartition::TWPartition(void) { Can_Be_Mounted = false; Can_Be_Wiped = false; @@ -101,6 +126,8 @@ TWPartition::TWPartition(void) { Storage_Path = ""; Current_File_System = ""; Fstab_File_System = ""; + Mount_Flags = 0; + Mount_Options = ""; Format_Block_Size = 0; Ignore_Blkid = false; Retain_Layout_Version = false; @@ -373,6 +400,38 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) { return true; } +bool TWPartition::Process_FS_Flags(string& Options, int Flags) { + int i; + char *p; + char *savep; + char fs_options[250]; + + strlcpy(fs_options, Options.c_str(), sizeof(fs_options)); + Options = ""; + + p = strtok_r(fs_options, ",", &savep); + while (p) { + /* Look for the flag "p" in the flag list "fl" + * If not found, the loop exits with fl[i].name being null. + */ + for (i = 0; mount_flags[i].name; i++) { + if (strncmp(p, mount_flags[i].name, strlen(mount_flags[i].name)) == 0) { + Flags |= mount_flags[i].flag; + break; + } + } + + if (!mount_flags[i].name) { + if (Options.size() > 0) + Options += ","; + Options += p; + } + p = strtok_r(NULL, ",", &savep); + } + + return true; +} + bool TWPartition::Process_Flags(string Flags, bool Display_Error) { char flags[MAX_FSTAB_LINE_LENGTH]; int flags_len, index = 0, ptr_len; @@ -474,6 +533,15 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) { } else { Use_Userdata_Encryption = false; } + } else if (ptr_len > 8 && strncmp(ptr, "fsflags=", 8) == 0) { + ptr += 8; + if (*ptr == '\"') ptr++; + + Mount_Options = ptr; + if (Mount_Options.substr(Mount_Options.size() - 1, 1) == "\"") { + Mount_Options.resize(Mount_Options.size() - 1); + } + Process_FS_Flags(Mount_Options, Mount_Flags); } else { if (Display_Error) LOGERR("Unhandled flag: '%s'\n", ptr); @@ -872,7 +940,7 @@ bool TWPartition::Mount(bool Display_Error) { } return true; } - } else if (!exfat_mounted && mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) { + } else if (!exfat_mounted && mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), Mount_Flags, Mount_Options.c_str()) != 0) { #ifdef TW_NO_EXFAT_FUSE if (Current_File_System == "exfat") { LOGINFO("Mounting exfat failed, trying vfat...\n"); @@ -881,7 +949,7 @@ bool TWPartition::Mount(bool Display_Error) { LOGERR("Unable to mount '%s'\n", Mount_Point.c_str()); else LOGINFO("Unable to mount '%s'\n", Mount_Point.c_str()); - LOGINFO("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str()); + LOGINFO("Actual block device: '%s', current file system: '%s', flags: 0x%8x, options: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str(), Mount_Flags, Mount_Options.c_str()); return false; } } else { diff --git a/partitionmanager.cpp b/partitionmanager.cpp index b322932c8..7634ff047 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -235,6 +235,8 @@ void TWPartitionManager::Output_Partition(TWPartition* Part) { printf(" MTD_Name: %s\n", Part->MTD_Name.c_str()); string back_meth = Part->Backup_Method_By_Name(); printf(" Backup_Method: %s\n\n", back_meth.c_str()); + if (Part->Mount_Flags || !Part->Mount_Options.empty()) + printf(" Mount_Flags=0x%8x, Mount_Options=%s\n", Part->Mount_Flags, Part->Mount_Options.c_str()); } int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) { diff --git a/partitions.hpp b/partitions.hpp index f32f2c0c5..62f95d040 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -74,6 +74,7 @@ private: void Find_Actual_Block_Device(); // Determines the correct block device and stores it in Actual_Block_Device bool Process_Flags(string Flags, bool Display_Error); // Process custom fstab flags + bool Process_FS_Flags(string& Options, int Flags); // Process standard fstab fs flags bool Is_File_System(string File_System); // Checks to see if the file system given is considered a file system bool Is_Image(string File_System); // Checks to see if the file system given is considered an image void Setup_File_System(bool Display_Error); // Sets defaults for a file system partition @@ -144,6 +145,8 @@ private: bool Is_Settings_Storage; // Indicates that this storage partition is the location of the .twrps settings file and the location that is used for custom themes string Storage_Path; // Indicates the path to the storage -- root indicates mount point, media/ indicates e.g. /data/media string Fstab_File_System; // File system from the recovery.fstab + int Mount_Flags; // File system flags from recovery.fstab + string Mount_Options; // File system options from recovery.fstab int Format_Block_Size; // Block size for formatting bool Ignore_Blkid; // Ignore blkid results due to superblocks lying to us on certain devices / partitions bool Retain_Layout_Version; // Retains the .layout_version file during a wipe (needed on devices like Sony Xperia T where /data and /data/media are separate partitions) -- cgit v1.2.3