Add fs_mgr option to enable/disable quotas.
To support upcoming disk usage calculation optimizations, this change adds a new 'quota' mount flag. As part of mounting an ext4 device, we now enable/disable the quota feature using tune2fs to match the requested value in the fstab. When changing the quota status, we force a fsck pass on the device before actually mounting it to prime the quota data structures which are stored in hidden inodes. Changing quota state and priming the data structures needs to happen before we actually mount the device, so fs_mgr is the best place to place this logic. Test: builds, boots, enables and disables quota Bug: 27948817 Change-Id: I7ccbf97cbc4a679bdd7a31a77be4b99aa9a88e66
This commit is contained in:
parent
9a0fd1d5d3
commit
6d89610d1a
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue