Enable allow_discards if dm-crypt supports it
dm-crypt version 1.11.0 and later supports the allow_discards option when setting up a crypto device. This passes discard requests from the filesytem to the underlying block device. This helps make flash based storage faster. So query the dm-crypt version, and pass the option if the version is 1.11.0 or greater. Change-Id: If30e9db5a2dbd6ea0281d91344e5b2c35e75131e
This commit is contained in:
parent
2ba45aafc2
commit
db5e026058
1 changed files with 97 additions and 27 deletions
124
cryptfs.c
124
cryptfs.c
|
@ -377,6 +377,86 @@ void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize,
|
|||
|
||||
}
|
||||
|
||||
static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
|
||||
char *real_blk_name, const char *name, int fd,
|
||||
char *extra_params)
|
||||
{
|
||||
char buffer[DM_CRYPT_BUF_SIZE];
|
||||
struct dm_ioctl *io;
|
||||
struct dm_target_spec *tgt;
|
||||
char *crypt_params;
|
||||
char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
|
||||
int i;
|
||||
|
||||
io = (struct dm_ioctl *) buffer;
|
||||
|
||||
/* Load the mapping table for this device */
|
||||
tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
|
||||
|
||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||
io->target_count = 1;
|
||||
tgt->status = 0;
|
||||
tgt->sector_start = 0;
|
||||
tgt->length = crypt_ftr->fs_size;
|
||||
strcpy(tgt->target_type, "crypt");
|
||||
|
||||
crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
|
||||
convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
|
||||
sprintf(crypt_params, "%s %s 0 %s 0 %s", crypt_ftr->crypto_type_name,
|
||||
master_key_ascii, real_blk_name, extra_params);
|
||||
crypt_params += strlen(crypt_params) + 1;
|
||||
crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
|
||||
tgt->next = crypt_params - buffer;
|
||||
|
||||
for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
|
||||
if (! ioctl(fd, DM_TABLE_LOAD, io)) {
|
||||
break;
|
||||
}
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
if (i == TABLE_LOAD_RETRIES) {
|
||||
/* We failed to load the table, return an error */
|
||||
return -1;
|
||||
} else {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int get_dm_crypt_version(int fd, const char *name, int *version)
|
||||
{
|
||||
char buffer[DM_CRYPT_BUF_SIZE];
|
||||
struct dm_ioctl *io;
|
||||
struct dm_target_versions *v;
|
||||
int i;
|
||||
|
||||
io = (struct dm_ioctl *) buffer;
|
||||
|
||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||
|
||||
if (ioctl(fd, DM_LIST_VERSIONS, io)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Iterate over the returned versions, looking for name of "crypt".
|
||||
* When found, get and return the version.
|
||||
*/
|
||||
v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)];
|
||||
while (v->next) {
|
||||
if (! strcmp(v->name, "crypt")) {
|
||||
/* We found the crypt driver, return the version, and get out */
|
||||
version[0] = v->version[0];
|
||||
version[1] = v->version[1];
|
||||
version[2] = v->version[2];
|
||||
return 0;
|
||||
}
|
||||
v = (struct dm_target_versions *)(((char *)v) + v->next);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
|
||||
char *real_blk_name, char *crypto_blk_name, const char *name)
|
||||
{
|
||||
|
@ -389,6 +469,9 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char
|
|||
int fd;
|
||||
int i;
|
||||
int retval = -1;
|
||||
int version[3];
|
||||
char *extra_params;
|
||||
int load_count;
|
||||
|
||||
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
|
||||
SLOGE("Cannot open device-mapper\n");
|
||||
|
@ -412,40 +495,27 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char
|
|||
minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
|
||||
snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
|
||||
|
||||
/* Load the mapping table for this device */
|
||||
tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
|
||||
|
||||
ioctl_init(io, 4096, name, 0);
|
||||
io->target_count = 1;
|
||||
tgt->status = 0;
|
||||
tgt->sector_start = 0;
|
||||
tgt->length = crypt_ftr->fs_size;
|
||||
strcpy(tgt->target_type, "crypt");
|
||||
|
||||
crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
|
||||
convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
|
||||
sprintf(crypt_params, "%s %s 0 %s 0", crypt_ftr->crypto_type_name,
|
||||
master_key_ascii, real_blk_name);
|
||||
crypt_params += strlen(crypt_params) + 1;
|
||||
crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
|
||||
tgt->next = crypt_params - buffer;
|
||||
|
||||
for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
|
||||
if (! ioctl(fd, DM_TABLE_LOAD, io)) {
|
||||
break;
|
||||
}
|
||||
usleep(500000);
|
||||
extra_params = "";
|
||||
if (! get_dm_crypt_version(fd, name, version)) {
|
||||
/* Support for allow_discards was added in version 1.11.0 */
|
||||
if ((version[0] >= 2) ||
|
||||
((version[0] == 1) && (version[1] >= 11))) {
|
||||
extra_params = "1 allow_discards";
|
||||
SLOGI("Enabling support for allow_discards in dmcrypt.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (i == TABLE_LOAD_RETRIES) {
|
||||
load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name,
|
||||
fd, extra_params);
|
||||
if (load_count < 0) {
|
||||
SLOGE("Cannot load dm-crypt mapping table.\n");
|
||||
goto errout;
|
||||
} else if (i) {
|
||||
SLOGI("Took %d tries to load dmcrypt table.\n", i + 1);
|
||||
} else if (load_count > 1) {
|
||||
SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
|
||||
}
|
||||
|
||||
/* Resume this device to activate it */
|
||||
ioctl_init(io, 4096, name, 0);
|
||||
ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
|
||||
|
||||
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
|
||||
SLOGE("Cannot resume the dm-crypt device\n");
|
||||
|
|
Loading…
Reference in a new issue