diff options
author | Theodore Ts'o <tytso@mit.edu> | 2015-05-18 13:14:47 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2015-05-18 13:14:47 -0400 |
commit | 5b643f9ce34df945e58c7176275d406aa0db704f (patch) | |
tree | 740e471e4fa5d969d10a9f0fea50274801c1dbe1 /fs/ext4/inline.c | |
parent | e26081808edadfd257c6c9d81014e3b25e9a6118 (diff) |
ext4 crypto: optimize filename encryption
Encrypt the filename as soon it is passed in by the user. This avoids
our needing to encrypt the filename 2 or 3 times while in the process
of creating a filename.
Similarly, when looking up a directory entry, encrypt the filename
early, or if the encryption key is not available, base-64 decode the
file syystem so that the hash value and the last 16 bytes of the
encrypted filename is available in the new struct ext4_filename data
structure.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r-- | fs/ext4/inline.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 095c7a258d97..cd944a7a99cd 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -995,20 +995,18 @@ void ext4_show_inline_dir(struct inode *dir, struct buffer_head *bh, | |||
995 | * and -EEXIST if directory entry already exists. | 995 | * and -EEXIST if directory entry already exists. |
996 | */ | 996 | */ |
997 | static int ext4_add_dirent_to_inline(handle_t *handle, | 997 | static int ext4_add_dirent_to_inline(handle_t *handle, |
998 | struct ext4_filename *fname, | ||
998 | struct dentry *dentry, | 999 | struct dentry *dentry, |
999 | struct inode *inode, | 1000 | struct inode *inode, |
1000 | struct ext4_iloc *iloc, | 1001 | struct ext4_iloc *iloc, |
1001 | void *inline_start, int inline_size) | 1002 | void *inline_start, int inline_size) |
1002 | { | 1003 | { |
1003 | struct inode *dir = d_inode(dentry->d_parent); | 1004 | struct inode *dir = d_inode(dentry->d_parent); |
1004 | const char *name = dentry->d_name.name; | ||
1005 | int namelen = dentry->d_name.len; | ||
1006 | int err; | 1005 | int err; |
1007 | struct ext4_dir_entry_2 *de; | 1006 | struct ext4_dir_entry_2 *de; |
1008 | 1007 | ||
1009 | err = ext4_find_dest_de(dir, inode, iloc->bh, | 1008 | err = ext4_find_dest_de(dir, inode, iloc->bh, inline_start, |
1010 | inline_start, inline_size, | 1009 | inline_size, fname, &de); |
1011 | name, namelen, &de); | ||
1012 | if (err) | 1010 | if (err) |
1013 | return err; | 1011 | return err; |
1014 | 1012 | ||
@@ -1016,8 +1014,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, | |||
1016 | err = ext4_journal_get_write_access(handle, iloc->bh); | 1014 | err = ext4_journal_get_write_access(handle, iloc->bh); |
1017 | if (err) | 1015 | if (err) |
1018 | return err; | 1016 | return err; |
1019 | ext4_insert_dentry(dir, inode, de, inline_size, &dentry->d_name, | 1017 | ext4_insert_dentry(dir, inode, de, inline_size, fname); |
1020 | name, namelen); | ||
1021 | 1018 | ||
1022 | ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size); | 1019 | ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size); |
1023 | 1020 | ||
@@ -1248,8 +1245,8 @@ out: | |||
1248 | * If succeeds, return 0. If not, extended the inline dir and copied data to | 1245 | * If succeeds, return 0. If not, extended the inline dir and copied data to |
1249 | * the new created block. | 1246 | * the new created block. |
1250 | */ | 1247 | */ |
1251 | int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry, | 1248 | int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, |
1252 | struct inode *inode) | 1249 | struct dentry *dentry, struct inode *inode) |
1253 | { | 1250 | { |
1254 | int ret, inline_size; | 1251 | int ret, inline_size; |
1255 | void *inline_start; | 1252 | void *inline_start; |
@@ -1268,7 +1265,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry, | |||
1268 | EXT4_INLINE_DOTDOT_SIZE; | 1265 | EXT4_INLINE_DOTDOT_SIZE; |
1269 | inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; | 1266 | inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; |
1270 | 1267 | ||
1271 | ret = ext4_add_dirent_to_inline(handle, dentry, inode, &iloc, | 1268 | ret = ext4_add_dirent_to_inline(handle, fname, dentry, inode, &iloc, |
1272 | inline_start, inline_size); | 1269 | inline_start, inline_size); |
1273 | if (ret != -ENOSPC) | 1270 | if (ret != -ENOSPC) |
1274 | goto out; | 1271 | goto out; |
@@ -1289,8 +1286,9 @@ int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry, | |||
1289 | if (inline_size) { | 1286 | if (inline_size) { |
1290 | inline_start = ext4_get_inline_xattr_pos(dir, &iloc); | 1287 | inline_start = ext4_get_inline_xattr_pos(dir, &iloc); |
1291 | 1288 | ||
1292 | ret = ext4_add_dirent_to_inline(handle, dentry, inode, &iloc, | 1289 | ret = ext4_add_dirent_to_inline(handle, fname, dentry, |
1293 | inline_start, inline_size); | 1290 | inode, &iloc, inline_start, |
1291 | inline_size); | ||
1294 | 1292 | ||
1295 | if (ret != -ENOSPC) | 1293 | if (ret != -ENOSPC) |
1296 | goto out; | 1294 | goto out; |
@@ -1611,6 +1609,7 @@ out: | |||
1611 | } | 1609 | } |
1612 | 1610 | ||
1613 | struct buffer_head *ext4_find_inline_entry(struct inode *dir, | 1611 | struct buffer_head *ext4_find_inline_entry(struct inode *dir, |
1612 | struct ext4_filename *fname, | ||
1614 | const struct qstr *d_name, | 1613 | const struct qstr *d_name, |
1615 | struct ext4_dir_entry_2 **res_dir, | 1614 | struct ext4_dir_entry_2 **res_dir, |
1616 | int *has_inline_data) | 1615 | int *has_inline_data) |
@@ -1632,8 +1631,8 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir, | |||
1632 | inline_start = (void *)ext4_raw_inode(&iloc)->i_block + | 1631 | inline_start = (void *)ext4_raw_inode(&iloc)->i_block + |
1633 | EXT4_INLINE_DOTDOT_SIZE; | 1632 | EXT4_INLINE_DOTDOT_SIZE; |
1634 | inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; | 1633 | inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; |
1635 | ret = search_dir(iloc.bh, inline_start, inline_size, | 1634 | ret = ext4_search_dir(iloc.bh, inline_start, inline_size, |
1636 | dir, d_name, 0, res_dir); | 1635 | dir, fname, d_name, 0, res_dir); |
1637 | if (ret == 1) | 1636 | if (ret == 1) |
1638 | goto out_find; | 1637 | goto out_find; |
1639 | if (ret < 0) | 1638 | if (ret < 0) |
@@ -1645,8 +1644,8 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir, | |||
1645 | inline_start = ext4_get_inline_xattr_pos(dir, &iloc); | 1644 | inline_start = ext4_get_inline_xattr_pos(dir, &iloc); |
1646 | inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE; | 1645 | inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE; |
1647 | 1646 | ||
1648 | ret = search_dir(iloc.bh, inline_start, inline_size, | 1647 | ret = ext4_search_dir(iloc.bh, inline_start, inline_size, |
1649 | dir, d_name, 0, res_dir); | 1648 | dir, fname, d_name, 0, res_dir); |
1650 | if (ret == 1) | 1649 | if (ret == 1) |
1651 | goto out_find; | 1650 | goto out_find; |
1652 | 1651 | ||