diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index c9876fd1c..6e6d69fe2 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -213,6 +213,73 @@ static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) le32_to_cpu(es->s_r_blocks_count_lo); } +static int do_quota(char *blk_device, char *fs_type, struct fstab_rec *rec) +{ + int force_check = 0; + if (!strcmp(fs_type, "ext4")) { + /* + * Some system images do not have tune2fs for licensing reasons + * Detect these and skip reserve blocks. + */ + if (access(TUNE2FS_BIN, X_OK)) { + ERROR("Not running %s on %s (executable not in system image)\n", + TUNE2FS_BIN, blk_device); + } else { + char* arg1 = NULL; + char* arg2 = NULL; + int status = 0; + int ret = 0; + int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)); + if (fd >= 0) { + struct ext4_super_block sb; + ret = read_super_block(fd, &sb); + if (ret < 0) { + ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno)); + goto out; + } + + int has_quota = (sb.s_feature_ro_compat + & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0; + int want_quota = fs_mgr_is_quota(rec) != 0; + + if (has_quota == want_quota) { + INFO("Requested quota status is match on %s\n", blk_device); + goto out; + } else if (want_quota) { + INFO("Enabling quota on %s\n", blk_device); + arg1 = "-Oquota"; + arg2 = "-Qusrquota,grpquota"; + force_check = 1; + } else { + INFO("Disabling quota on %s\n", blk_device); + arg1 = "-Q^usrquota,^grpquota"; + arg2 = "-O^quota"; + } + } else { + ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno)); + return force_check; + } + + char *tune2fs_argv[] = { + TUNE2FS_BIN, + arg1, + arg2, + blk_device, + }; + ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv, + &status, true, LOG_KLOG | LOG_FILE, + true, NULL, NULL, 0); + if (ret < 0) { + /* No need to check for error in fork, we can't really handle it now */ + ERROR("Failed trying to run %s\n", TUNE2FS_BIN); + } + out: + close(fd); + } + } + return force_check; +} + static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec) { /* Check for the types of filesystems we know how to check */ @@ -417,7 +484,10 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ continue; } - if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { + int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type, + &fstab->recs[i]); + + if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } @@ -787,7 +857,10 @@ int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device, wait_for_file(n_blk_device, WAIT_TIMEOUT); } - if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { + int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type, + &fstab->recs[i]); + + if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c index 90c74350e..41fb746ea 100644 --- a/fs_mgr/fs_mgr_fstab.c +++ b/fs_mgr/fs_mgr_fstab.c @@ -62,29 +62,31 @@ static struct flag_list mount_flags[] = { }; static struct flag_list fs_mgr_flags[] = { - { "wait", MF_WAIT }, - { "check", MF_CHECK }, - { "encryptable=",MF_CRYPT }, - { "forceencrypt=",MF_FORCECRYPT }, - { "fileencryption=",MF_FILEENCRYPTION }, - { "forcefdeorfbe=",MF_FORCEFDEORFBE }, - { "nonremovable",MF_NONREMOVABLE }, - { "voldmanaged=",MF_VOLDMANAGED}, - { "length=", MF_LENGTH }, - { "recoveryonly",MF_RECOVERYONLY }, - { "swapprio=", MF_SWAPPRIO }, - { "zramsize=", MF_ZRAMSIZE }, - { "max_comp_streams=", MF_MAX_COMP_STREAMS }, - { "verify", MF_VERIFY }, - { "noemulatedsd", MF_NOEMULATEDSD }, - { "notrim", MF_NOTRIM }, - { "formattable", MF_FORMATTABLE }, - { "slotselect", MF_SLOTSELECT }, - { "nofail", MF_NOFAIL }, - { "latemount", MF_LATEMOUNT }, - { "reservedsize=", MF_RESERVEDSIZE }, - { "defaults", 0 }, - { 0, 0 }, + { "wait", MF_WAIT }, + { "check", MF_CHECK }, + { "encryptable=", MF_CRYPT }, + { "forceencrypt=", MF_FORCECRYPT }, + { "fileencryption=", MF_FILEENCRYPTION }, + { "forcefdeorfbe=", MF_FORCEFDEORFBE }, + { "nonremovable", MF_NONREMOVABLE }, + { "voldmanaged=", MF_VOLDMANAGED}, + { "length=", MF_LENGTH }, + { "recoveryonly", MF_RECOVERYONLY }, + { "swapprio=", MF_SWAPPRIO }, + { "zramsize=", MF_ZRAMSIZE }, + { "max_comp_streams=", MF_MAX_COMP_STREAMS }, + { "verifyatboot", MF_VERIFYATBOOT }, + { "verify", MF_VERIFY }, + { "noemulatedsd", MF_NOEMULATEDSD }, + { "notrim", MF_NOTRIM }, + { "formattable", MF_FORMATTABLE }, + { "slotselect", MF_SLOTSELECT }, + { "nofail", MF_NOFAIL }, + { "latemount", MF_LATEMOUNT }, + { "reservedsize=", MF_RESERVEDSIZE }, + { "quota", MF_QUOTA }, + { "defaults", 0 }, + { 0, 0 }, }; #define EM_SOFTWARE 1 @@ -586,3 +588,8 @@ int fs_mgr_is_latemount(struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_LATEMOUNT; } + +int fs_mgr_is_quota(struct fstab_rec *fstab) +{ + return fstab->fs_mgr_flags & MF_QUOTA; +} diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 23c97e456..db86afa85 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -65,28 +65,30 @@ __BEGIN_DECLS * */ -#define MF_WAIT 0x1 -#define MF_CHECK 0x2 -#define MF_CRYPT 0x4 -#define MF_NONREMOVABLE 0x8 -#define MF_VOLDMANAGED 0x10 -#define MF_LENGTH 0x20 -#define MF_RECOVERYONLY 0x40 -#define MF_SWAPPRIO 0x80 -#define MF_ZRAMSIZE 0x100 -#define MF_VERIFY 0x200 -#define MF_FORCECRYPT 0x400 -#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only - external storage */ -#define MF_NOTRIM 0x1000 -#define MF_FILEENCRYPTION 0x2000 -#define MF_FORMATTABLE 0x4000 -#define MF_SLOTSELECT 0x8000 -#define MF_FORCEFDEORFBE 0x10000 -#define MF_LATEMOUNT 0x20000 -#define MF_NOFAIL 0x40000 +#define MF_WAIT 0x1 +#define MF_CHECK 0x2 +#define MF_CRYPT 0x4 +#define MF_NONREMOVABLE 0x8 +#define MF_VOLDMANAGED 0x10 +#define MF_LENGTH 0x20 +#define MF_RECOVERYONLY 0x40 +#define MF_SWAPPRIO 0x80 +#define MF_ZRAMSIZE 0x100 +#define MF_VERIFY 0x200 +#define MF_FORCECRYPT 0x400 +#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only + external storage */ +#define MF_NOTRIM 0x1000 +#define MF_FILEENCRYPTION 0x2000 +#define MF_FORMATTABLE 0x4000 +#define MF_SLOTSELECT 0x8000 +#define MF_FORCEFDEORFBE 0x10000 +#define MF_LATEMOUNT 0x20000 +#define MF_NOFAIL 0x40000 +#define MF_VERIFYATBOOT 0x80000 #define MF_MAX_COMP_STREAMS 0x100000 -#define MF_RESERVEDSIZE 0x200000 +#define MF_RESERVEDSIZE 0x200000 +#define MF_QUOTA 0x400000 #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index ed22e9086..e7a0a1d74 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -123,6 +123,7 @@ int fs_mgr_is_notrim(struct fstab_rec *fstab); int fs_mgr_is_formattable(struct fstab_rec *fstab); int fs_mgr_is_nofail(struct fstab_rec *fstab); int fs_mgr_is_latemount(struct fstab_rec *fstab); +int fs_mgr_is_quota(struct fstab_rec *fstab); int fs_mgr_swapon_all(struct fstab *fstab); int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);