diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-03 21:23:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-03 21:23:53 -0400 |
commit | 8663da2c0919896788321cd8a0016af08588c656 (patch) | |
tree | 9e92edcab3fa5187f8af2b02cdc791453b21c8b8 /fs/ext4/namei.c | |
parent | 101a6fd387801bbe164eafea3950b98f8e6440bb (diff) | |
parent | 2c869b262a10ca99cb866d04087d75311587a30c (diff) |
Merge tag 'for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o:
"Some miscellaneous bug fixes and some final on-disk and ABI changes
for ext4 encryption which provide better security and performance"
* tag 'for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: fix growing of tiny filesystems
ext4: move check under lock scope to close a race.
ext4: fix data corruption caused by unwritten and delayed extents
ext4 crypto: remove duplicated encryption mode definitions
ext4 crypto: do not select from EXT4_FS_ENCRYPTION
ext4 crypto: add padding to filenames before encrypting
ext4 crypto: simplify and speed up filename encryption
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 72 |
1 files changed, 6 insertions, 66 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 7223b0b4bc38..814f3beb4369 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -640,7 +640,7 @@ static struct stats dx_show_leaf(struct inode *dir, | |||
640 | ext4_put_fname_crypto_ctx(&ctx); | 640 | ext4_put_fname_crypto_ctx(&ctx); |
641 | ctx = NULL; | 641 | ctx = NULL; |
642 | } | 642 | } |
643 | res = ext4_fname_disk_to_usr(ctx, de, | 643 | res = ext4_fname_disk_to_usr(ctx, NULL, de, |
644 | &fname_crypto_str); | 644 | &fname_crypto_str); |
645 | if (res < 0) { | 645 | if (res < 0) { |
646 | printk(KERN_WARNING "Error " | 646 | printk(KERN_WARNING "Error " |
@@ -653,15 +653,8 @@ static struct stats dx_show_leaf(struct inode *dir, | |||
653 | name = fname_crypto_str.name; | 653 | name = fname_crypto_str.name; |
654 | len = fname_crypto_str.len; | 654 | len = fname_crypto_str.len; |
655 | } | 655 | } |
656 | res = ext4_fname_disk_to_hash(ctx, de, | 656 | ext4fs_dirhash(de->name, de->name_len, |
657 | &h); | 657 | &h); |
658 | if (res < 0) { | ||
659 | printk(KERN_WARNING "Error " | ||
660 | "converting filename " | ||
661 | "from disk to htree" | ||
662 | "\n"); | ||
663 | h.hash = 0xDEADBEEF; | ||
664 | } | ||
665 | printk("%*.s:(E)%x.%u ", len, name, | 658 | printk("%*.s:(E)%x.%u ", len, name, |
666 | h.hash, (unsigned) ((char *) de | 659 | h.hash, (unsigned) ((char *) de |
667 | - base)); | 660 | - base)); |
@@ -1008,15 +1001,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
1008 | /* silently ignore the rest of the block */ | 1001 | /* silently ignore the rest of the block */ |
1009 | break; | 1002 | break; |
1010 | } | 1003 | } |
1011 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | ||
1012 | err = ext4_fname_disk_to_hash(ctx, de, hinfo); | ||
1013 | if (err < 0) { | ||
1014 | count = err; | ||
1015 | goto errout; | ||
1016 | } | ||
1017 | #else | ||
1018 | ext4fs_dirhash(de->name, de->name_len, hinfo); | 1004 | ext4fs_dirhash(de->name, de->name_len, hinfo); |
1019 | #endif | ||
1020 | if ((hinfo->hash < start_hash) || | 1005 | if ((hinfo->hash < start_hash) || |
1021 | ((hinfo->hash == start_hash) && | 1006 | ((hinfo->hash == start_hash) && |
1022 | (hinfo->minor_hash < start_minor_hash))) | 1007 | (hinfo->minor_hash < start_minor_hash))) |
@@ -1032,7 +1017,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
1032 | &tmp_str); | 1017 | &tmp_str); |
1033 | } else { | 1018 | } else { |
1034 | /* Directory is encrypted */ | 1019 | /* Directory is encrypted */ |
1035 | err = ext4_fname_disk_to_usr(ctx, de, | 1020 | err = ext4_fname_disk_to_usr(ctx, hinfo, de, |
1036 | &fname_crypto_str); | 1021 | &fname_crypto_str); |
1037 | if (err < 0) { | 1022 | if (err < 0) { |
1038 | count = err; | 1023 | count = err; |
@@ -1193,26 +1178,10 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, | |||
1193 | int count = 0; | 1178 | int count = 0; |
1194 | char *base = (char *) de; | 1179 | char *base = (char *) de; |
1195 | struct dx_hash_info h = *hinfo; | 1180 | struct dx_hash_info h = *hinfo; |
1196 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | ||
1197 | struct ext4_fname_crypto_ctx *ctx = NULL; | ||
1198 | int err; | ||
1199 | |||
1200 | ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN); | ||
1201 | if (IS_ERR(ctx)) | ||
1202 | return PTR_ERR(ctx); | ||
1203 | #endif | ||
1204 | 1181 | ||
1205 | while ((char *) de < base + blocksize) { | 1182 | while ((char *) de < base + blocksize) { |
1206 | if (de->name_len && de->inode) { | 1183 | if (de->name_len && de->inode) { |
1207 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | ||
1208 | err = ext4_fname_disk_to_hash(ctx, de, &h); | ||
1209 | if (err < 0) { | ||
1210 | ext4_put_fname_crypto_ctx(&ctx); | ||
1211 | return err; | ||
1212 | } | ||
1213 | #else | ||
1214 | ext4fs_dirhash(de->name, de->name_len, &h); | 1184 | ext4fs_dirhash(de->name, de->name_len, &h); |
1215 | #endif | ||
1216 | map_tail--; | 1185 | map_tail--; |
1217 | map_tail->hash = h.hash; | 1186 | map_tail->hash = h.hash; |
1218 | map_tail->offs = ((char *) de - base)>>2; | 1187 | map_tail->offs = ((char *) de - base)>>2; |
@@ -1223,9 +1192,6 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, | |||
1223 | /* XXX: do we need to check rec_len == 0 case? -Chris */ | 1192 | /* XXX: do we need to check rec_len == 0 case? -Chris */ |
1224 | de = ext4_next_entry(de, blocksize); | 1193 | de = ext4_next_entry(de, blocksize); |
1225 | } | 1194 | } |
1226 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | ||
1227 | ext4_put_fname_crypto_ctx(&ctx); | ||
1228 | #endif | ||
1229 | return count; | 1195 | return count; |
1230 | } | 1196 | } |
1231 | 1197 | ||
@@ -1287,16 +1253,8 @@ static inline int ext4_match(struct ext4_fname_crypto_ctx *ctx, | |||
1287 | return 0; | 1253 | return 0; |
1288 | 1254 | ||
1289 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | 1255 | #ifdef CONFIG_EXT4_FS_ENCRYPTION |
1290 | if (ctx) { | 1256 | if (ctx) |
1291 | /* Directory is encrypted */ | 1257 | return ext4_fname_match(ctx, fname_crypto_str, len, name, de); |
1292 | res = ext4_fname_disk_to_usr(ctx, de, fname_crypto_str); | ||
1293 | if (res < 0) | ||
1294 | return res; | ||
1295 | if (len != res) | ||
1296 | return 0; | ||
1297 | res = memcmp(name, fname_crypto_str->name, len); | ||
1298 | return (res == 0) ? 1 : 0; | ||
1299 | } | ||
1300 | #endif | 1258 | #endif |
1301 | if (len != de->name_len) | 1259 | if (len != de->name_len) |
1302 | return 0; | 1260 | return 0; |
@@ -1324,16 +1282,6 @@ int search_dir(struct buffer_head *bh, char *search_buf, int buf_size, | |||
1324 | if (IS_ERR(ctx)) | 1282 | if (IS_ERR(ctx)) |
1325 | return -1; | 1283 | return -1; |
1326 | 1284 | ||
1327 | if (ctx != NULL) { | ||
1328 | /* Allocate buffer to hold maximum name length */ | ||
1329 | res = ext4_fname_crypto_alloc_buffer(ctx, EXT4_NAME_LEN, | ||
1330 | &fname_crypto_str); | ||
1331 | if (res < 0) { | ||
1332 | ext4_put_fname_crypto_ctx(&ctx); | ||
1333 | return -1; | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | de = (struct ext4_dir_entry_2 *)search_buf; | 1285 | de = (struct ext4_dir_entry_2 *)search_buf; |
1338 | dlimit = search_buf + buf_size; | 1286 | dlimit = search_buf + buf_size; |
1339 | while ((char *) de < dlimit) { | 1287 | while ((char *) de < dlimit) { |
@@ -1872,14 +1820,6 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, | |||
1872 | return res; | 1820 | return res; |
1873 | } | 1821 | } |
1874 | reclen = EXT4_DIR_REC_LEN(res); | 1822 | reclen = EXT4_DIR_REC_LEN(res); |
1875 | |||
1876 | /* Allocate buffer to hold maximum name length */ | ||
1877 | res = ext4_fname_crypto_alloc_buffer(ctx, EXT4_NAME_LEN, | ||
1878 | &fname_crypto_str); | ||
1879 | if (res < 0) { | ||
1880 | ext4_put_fname_crypto_ctx(&ctx); | ||
1881 | return -1; | ||
1882 | } | ||
1883 | } | 1823 | } |
1884 | 1824 | ||
1885 | de = (struct ext4_dir_entry_2 *)buf; | 1825 | de = (struct ext4_dir_entry_2 *)buf; |