diff options
| -rw-r--r-- | fs/crypto/fname.c | 1 | ||||
| -rw-r--r-- | fs/crypto/hooks.c | 11 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 62 | ||||
| -rw-r--r-- | fs/ext4/namei.c | 76 | ||||
| -rw-r--r-- | fs/f2fs/namei.c | 17 | ||||
| -rw-r--r-- | fs/ubifs/dir.c | 8 | ||||
| -rw-r--r-- | include/linux/fscrypt.h | 30 |
7 files changed, 139 insertions, 66 deletions
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 050384c79f40..eccea3d8f923 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c | |||
| @@ -356,6 +356,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, | |||
| 356 | } | 356 | } |
| 357 | if (!lookup) | 357 | if (!lookup) |
| 358 | return -ENOKEY; | 358 | return -ENOKEY; |
| 359 | fname->is_ciphertext_name = true; | ||
| 359 | 360 | ||
| 360 | /* | 361 | /* |
| 361 | * We don't have the key and we are doing a lookup; decode the | 362 | * We don't have the key and we are doing a lookup; decode the |
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index 9d8910e86ee5..042d5b44f4ed 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c | |||
| @@ -104,20 +104,21 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 104 | } | 104 | } |
| 105 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename); | 105 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename); |
| 106 | 106 | ||
| 107 | int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry) | 107 | int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, |
| 108 | struct fscrypt_name *fname) | ||
| 108 | { | 109 | { |
| 109 | int err = fscrypt_get_encryption_info(dir); | 110 | int err = fscrypt_setup_filename(dir, &dentry->d_name, 1, fname); |
| 110 | 111 | ||
| 111 | if (err) | 112 | if (err && err != -ENOENT) |
| 112 | return err; | 113 | return err; |
| 113 | 114 | ||
| 114 | if (!fscrypt_has_encryption_key(dir)) { | 115 | if (fname->is_ciphertext_name) { |
| 115 | spin_lock(&dentry->d_lock); | 116 | spin_lock(&dentry->d_lock); |
| 116 | dentry->d_flags |= DCACHE_ENCRYPTED_NAME; | 117 | dentry->d_flags |= DCACHE_ENCRYPTED_NAME; |
| 117 | spin_unlock(&dentry->d_lock); | 118 | spin_unlock(&dentry->d_lock); |
| 118 | d_set_d_op(dentry, &fscrypt_d_ops); | 119 | d_set_d_op(dentry, &fscrypt_d_ops); |
| 119 | } | 120 | } |
| 120 | return 0; | 121 | return err; |
| 121 | } | 122 | } |
| 122 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup); | 123 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup); |
| 123 | 124 | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 82ffdacdc7fa..e64a4ee96d30 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -2287,23 +2287,47 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb, | |||
| 2287 | ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); | 2287 | ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); |
| 2288 | 2288 | ||
| 2289 | #ifdef CONFIG_FS_ENCRYPTION | 2289 | #ifdef CONFIG_FS_ENCRYPTION |
| 2290 | static inline void ext4_fname_from_fscrypt_name(struct ext4_filename *dst, | ||
| 2291 | const struct fscrypt_name *src) | ||
| 2292 | { | ||
| 2293 | memset(dst, 0, sizeof(*dst)); | ||
| 2294 | |||
| 2295 | dst->usr_fname = src->usr_fname; | ||
| 2296 | dst->disk_name = src->disk_name; | ||
| 2297 | dst->hinfo.hash = src->hash; | ||
| 2298 | dst->hinfo.minor_hash = src->minor_hash; | ||
| 2299 | dst->crypto_buf = src->crypto_buf; | ||
| 2300 | } | ||
| 2301 | |||
| 2290 | static inline int ext4_fname_setup_filename(struct inode *dir, | 2302 | static inline int ext4_fname_setup_filename(struct inode *dir, |
| 2291 | const struct qstr *iname, | 2303 | const struct qstr *iname, |
| 2292 | int lookup, struct ext4_filename *fname) | 2304 | int lookup, |
| 2305 | struct ext4_filename *fname) | ||
| 2293 | { | 2306 | { |
| 2294 | struct fscrypt_name name; | 2307 | struct fscrypt_name name; |
| 2295 | int err; | 2308 | int err; |
| 2296 | 2309 | ||
| 2297 | memset(fname, 0, sizeof(struct ext4_filename)); | ||
| 2298 | |||
| 2299 | err = fscrypt_setup_filename(dir, iname, lookup, &name); | 2310 | err = fscrypt_setup_filename(dir, iname, lookup, &name); |
| 2311 | if (err) | ||
| 2312 | return err; | ||
| 2300 | 2313 | ||
| 2301 | fname->usr_fname = name.usr_fname; | 2314 | ext4_fname_from_fscrypt_name(fname, &name); |
| 2302 | fname->disk_name = name.disk_name; | 2315 | return 0; |
| 2303 | fname->hinfo.hash = name.hash; | 2316 | } |
| 2304 | fname->hinfo.minor_hash = name.minor_hash; | 2317 | |
| 2305 | fname->crypto_buf = name.crypto_buf; | 2318 | static inline int ext4_fname_prepare_lookup(struct inode *dir, |
| 2306 | return err; | 2319 | struct dentry *dentry, |
| 2320 | struct ext4_filename *fname) | ||
| 2321 | { | ||
| 2322 | struct fscrypt_name name; | ||
| 2323 | int err; | ||
| 2324 | |||
| 2325 | err = fscrypt_prepare_lookup(dir, dentry, &name); | ||
| 2326 | if (err) | ||
| 2327 | return err; | ||
| 2328 | |||
| 2329 | ext4_fname_from_fscrypt_name(fname, &name); | ||
| 2330 | return 0; | ||
| 2307 | } | 2331 | } |
| 2308 | 2332 | ||
| 2309 | static inline void ext4_fname_free_filename(struct ext4_filename *fname) | 2333 | static inline void ext4_fname_free_filename(struct ext4_filename *fname) |
| @@ -2317,19 +2341,27 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) | |||
| 2317 | fname->usr_fname = NULL; | 2341 | fname->usr_fname = NULL; |
| 2318 | fname->disk_name.name = NULL; | 2342 | fname->disk_name.name = NULL; |
| 2319 | } | 2343 | } |
| 2320 | #else | 2344 | #else /* !CONFIG_FS_ENCRYPTION */ |
| 2321 | static inline int ext4_fname_setup_filename(struct inode *dir, | 2345 | static inline int ext4_fname_setup_filename(struct inode *dir, |
| 2322 | const struct qstr *iname, | 2346 | const struct qstr *iname, |
| 2323 | int lookup, struct ext4_filename *fname) | 2347 | int lookup, |
| 2348 | struct ext4_filename *fname) | ||
| 2324 | { | 2349 | { |
| 2325 | fname->usr_fname = iname; | 2350 | fname->usr_fname = iname; |
| 2326 | fname->disk_name.name = (unsigned char *) iname->name; | 2351 | fname->disk_name.name = (unsigned char *) iname->name; |
| 2327 | fname->disk_name.len = iname->len; | 2352 | fname->disk_name.len = iname->len; |
| 2328 | return 0; | 2353 | return 0; |
| 2329 | } | 2354 | } |
| 2330 | static inline void ext4_fname_free_filename(struct ext4_filename *fname) { } | ||
| 2331 | 2355 | ||
| 2332 | #endif | 2356 | static inline int ext4_fname_prepare_lookup(struct inode *dir, |
| 2357 | struct dentry *dentry, | ||
| 2358 | struct ext4_filename *fname) | ||
| 2359 | { | ||
| 2360 | return ext4_fname_setup_filename(dir, &dentry->d_name, 1, fname); | ||
| 2361 | } | ||
| 2362 | |||
| 2363 | static inline void ext4_fname_free_filename(struct ext4_filename *fname) { } | ||
| 2364 | #endif /* !CONFIG_FS_ENCRYPTION */ | ||
| 2333 | 2365 | ||
| 2334 | /* dir.c */ | 2366 | /* dir.c */ |
| 2335 | extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, | 2367 | extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 980166a8122a..3ba6f30db8d9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -1327,7 +1327,7 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, | |||
| 1327 | } | 1327 | } |
| 1328 | 1328 | ||
| 1329 | /* | 1329 | /* |
| 1330 | * ext4_find_entry() | 1330 | * __ext4_find_entry() |
| 1331 | * | 1331 | * |
| 1332 | * finds an entry in the specified directory with the wanted name. It | 1332 | * finds an entry in the specified directory with the wanted name. It |
| 1333 | * returns the cache buffer in which the entry was found, and the entry | 1333 | * returns the cache buffer in which the entry was found, and the entry |
| @@ -1337,39 +1337,32 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, | |||
| 1337 | * The returned buffer_head has ->b_count elevated. The caller is expected | 1337 | * The returned buffer_head has ->b_count elevated. The caller is expected |
| 1338 | * to brelse() it when appropriate. | 1338 | * to brelse() it when appropriate. |
| 1339 | */ | 1339 | */ |
| 1340 | static struct buffer_head * ext4_find_entry (struct inode *dir, | 1340 | static struct buffer_head *__ext4_find_entry(struct inode *dir, |
| 1341 | const struct qstr *d_name, | 1341 | struct ext4_filename *fname, |
| 1342 | struct ext4_dir_entry_2 **res_dir, | 1342 | struct ext4_dir_entry_2 **res_dir, |
| 1343 | int *inlined) | 1343 | int *inlined) |
| 1344 | { | 1344 | { |
| 1345 | struct super_block *sb; | 1345 | struct super_block *sb; |
| 1346 | struct buffer_head *bh_use[NAMEI_RA_SIZE]; | 1346 | struct buffer_head *bh_use[NAMEI_RA_SIZE]; |
| 1347 | struct buffer_head *bh, *ret = NULL; | 1347 | struct buffer_head *bh, *ret = NULL; |
| 1348 | ext4_lblk_t start, block; | 1348 | ext4_lblk_t start, block; |
| 1349 | const u8 *name = d_name->name; | 1349 | const u8 *name = fname->usr_fname->name; |
| 1350 | size_t ra_max = 0; /* Number of bh's in the readahead | 1350 | size_t ra_max = 0; /* Number of bh's in the readahead |
| 1351 | buffer, bh_use[] */ | 1351 | buffer, bh_use[] */ |
| 1352 | size_t ra_ptr = 0; /* Current index into readahead | 1352 | size_t ra_ptr = 0; /* Current index into readahead |
| 1353 | buffer */ | 1353 | buffer */ |
| 1354 | ext4_lblk_t nblocks; | 1354 | ext4_lblk_t nblocks; |
| 1355 | int i, namelen, retval; | 1355 | int i, namelen, retval; |
| 1356 | struct ext4_filename fname; | ||
| 1357 | 1356 | ||
| 1358 | *res_dir = NULL; | 1357 | *res_dir = NULL; |
| 1359 | sb = dir->i_sb; | 1358 | sb = dir->i_sb; |
| 1360 | namelen = d_name->len; | 1359 | namelen = fname->usr_fname->len; |
| 1361 | if (namelen > EXT4_NAME_LEN) | 1360 | if (namelen > EXT4_NAME_LEN) |
| 1362 | return NULL; | 1361 | return NULL; |
| 1363 | 1362 | ||
| 1364 | retval = ext4_fname_setup_filename(dir, d_name, 1, &fname); | ||
| 1365 | if (retval == -ENOENT) | ||
| 1366 | return NULL; | ||
| 1367 | if (retval) | ||
| 1368 | return ERR_PTR(retval); | ||
| 1369 | |||
| 1370 | if (ext4_has_inline_data(dir)) { | 1363 | if (ext4_has_inline_data(dir)) { |
| 1371 | int has_inline_data = 1; | 1364 | int has_inline_data = 1; |
| 1372 | ret = ext4_find_inline_entry(dir, &fname, res_dir, | 1365 | ret = ext4_find_inline_entry(dir, fname, res_dir, |
| 1373 | &has_inline_data); | 1366 | &has_inline_data); |
| 1374 | if (has_inline_data) { | 1367 | if (has_inline_data) { |
| 1375 | if (inlined) | 1368 | if (inlined) |
| @@ -1389,7 +1382,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
| 1389 | goto restart; | 1382 | goto restart; |
| 1390 | } | 1383 | } |
| 1391 | if (is_dx(dir)) { | 1384 | if (is_dx(dir)) { |
| 1392 | ret = ext4_dx_find_entry(dir, &fname, res_dir); | 1385 | ret = ext4_dx_find_entry(dir, fname, res_dir); |
| 1393 | /* | 1386 | /* |
| 1394 | * On success, or if the error was file not found, | 1387 | * On success, or if the error was file not found, |
| 1395 | * return. Otherwise, fall back to doing a search the | 1388 | * return. Otherwise, fall back to doing a search the |
| @@ -1453,7 +1446,7 @@ restart: | |||
| 1453 | goto cleanup_and_exit; | 1446 | goto cleanup_and_exit; |
| 1454 | } | 1447 | } |
| 1455 | set_buffer_verified(bh); | 1448 | set_buffer_verified(bh); |
| 1456 | i = search_dirblock(bh, dir, &fname, | 1449 | i = search_dirblock(bh, dir, fname, |
| 1457 | block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); | 1450 | block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); |
| 1458 | if (i == 1) { | 1451 | if (i == 1) { |
| 1459 | EXT4_I(dir)->i_dir_start_lookup = block; | 1452 | EXT4_I(dir)->i_dir_start_lookup = block; |
| @@ -1484,10 +1477,50 @@ cleanup_and_exit: | |||
| 1484 | /* Clean up the read-ahead blocks */ | 1477 | /* Clean up the read-ahead blocks */ |
| 1485 | for (; ra_ptr < ra_max; ra_ptr++) | 1478 | for (; ra_ptr < ra_max; ra_ptr++) |
| 1486 | brelse(bh_use[ra_ptr]); | 1479 | brelse(bh_use[ra_ptr]); |
| 1487 | ext4_fname_free_filename(&fname); | ||
| 1488 | return ret; | 1480 | return ret; |
| 1489 | } | 1481 | } |
| 1490 | 1482 | ||
| 1483 | static struct buffer_head *ext4_find_entry(struct inode *dir, | ||
| 1484 | const struct qstr *d_name, | ||
| 1485 | struct ext4_dir_entry_2 **res_dir, | ||
| 1486 | int *inlined) | ||
| 1487 | { | ||
| 1488 | int err; | ||
| 1489 | struct ext4_filename fname; | ||
| 1490 | struct buffer_head *bh; | ||
| 1491 | |||
| 1492 | err = ext4_fname_setup_filename(dir, d_name, 1, &fname); | ||
| 1493 | if (err == -ENOENT) | ||
| 1494 | return NULL; | ||
| 1495 | if (err) | ||
| 1496 | return ERR_PTR(err); | ||
| 1497 | |||
| 1498 | bh = __ext4_find_entry(dir, &fname, res_dir, inlined); | ||
| 1499 | |||
| 1500 | ext4_fname_free_filename(&fname); | ||
| 1501 | return bh; | ||
| 1502 | } | ||
| 1503 | |||
| 1504 | static struct buffer_head *ext4_lookup_entry(struct inode *dir, | ||
| 1505 | struct dentry *dentry, | ||
| 1506 | struct ext4_dir_entry_2 **res_dir) | ||
| 1507 | { | ||
| 1508 | int err; | ||
| 1509 | struct ext4_filename fname; | ||
| 1510 | struct buffer_head *bh; | ||
| 1511 | |||
| 1512 | err = ext4_fname_prepare_lookup(dir, dentry, &fname); | ||
| 1513 | if (err == -ENOENT) | ||
| 1514 | return NULL; | ||
| 1515 | if (err) | ||
| 1516 | return ERR_PTR(err); | ||
| 1517 | |||
| 1518 | bh = __ext4_find_entry(dir, &fname, res_dir, NULL); | ||
| 1519 | |||
| 1520 | ext4_fname_free_filename(&fname); | ||
| 1521 | return bh; | ||
| 1522 | } | ||
| 1523 | |||
| 1491 | static struct buffer_head * ext4_dx_find_entry(struct inode *dir, | 1524 | static struct buffer_head * ext4_dx_find_entry(struct inode *dir, |
| 1492 | struct ext4_filename *fname, | 1525 | struct ext4_filename *fname, |
| 1493 | struct ext4_dir_entry_2 **res_dir) | 1526 | struct ext4_dir_entry_2 **res_dir) |
| @@ -1546,16 +1579,11 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi | |||
| 1546 | struct inode *inode; | 1579 | struct inode *inode; |
| 1547 | struct ext4_dir_entry_2 *de; | 1580 | struct ext4_dir_entry_2 *de; |
| 1548 | struct buffer_head *bh; | 1581 | struct buffer_head *bh; |
| 1549 | int err; | ||
| 1550 | |||
| 1551 | err = fscrypt_prepare_lookup(dir, dentry, flags); | ||
| 1552 | if (err) | ||
| 1553 | return ERR_PTR(err); | ||
| 1554 | 1582 | ||
| 1555 | if (dentry->d_name.len > EXT4_NAME_LEN) | 1583 | if (dentry->d_name.len > EXT4_NAME_LEN) |
| 1556 | return ERR_PTR(-ENAMETOOLONG); | 1584 | return ERR_PTR(-ENAMETOOLONG); |
| 1557 | 1585 | ||
| 1558 | bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); | 1586 | bh = ext4_lookup_entry(dir, dentry, &de); |
| 1559 | if (IS_ERR(bh)) | 1587 | if (IS_ERR(bh)) |
| 1560 | return ERR_CAST(bh); | 1588 | return ERR_CAST(bh); |
| 1561 | inode = NULL; | 1589 | inode = NULL; |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index f5e34e467003..c3e8a901d47a 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
| @@ -436,19 +436,23 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 436 | nid_t ino = -1; | 436 | nid_t ino = -1; |
| 437 | int err = 0; | 437 | int err = 0; |
| 438 | unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir)); | 438 | unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir)); |
| 439 | struct fscrypt_name fname; | ||
| 439 | 440 | ||
| 440 | trace_f2fs_lookup_start(dir, dentry, flags); | 441 | trace_f2fs_lookup_start(dir, dentry, flags); |
| 441 | 442 | ||
| 442 | err = fscrypt_prepare_lookup(dir, dentry, flags); | ||
| 443 | if (err) | ||
| 444 | goto out; | ||
| 445 | |||
| 446 | if (dentry->d_name.len > F2FS_NAME_LEN) { | 443 | if (dentry->d_name.len > F2FS_NAME_LEN) { |
| 447 | err = -ENAMETOOLONG; | 444 | err = -ENAMETOOLONG; |
| 448 | goto out; | 445 | goto out; |
| 449 | } | 446 | } |
| 450 | 447 | ||
| 451 | de = f2fs_find_entry(dir, &dentry->d_name, &page); | 448 | err = fscrypt_prepare_lookup(dir, dentry, &fname); |
| 449 | if (err == -ENOENT) | ||
| 450 | goto out_splice; | ||
| 451 | if (err) | ||
| 452 | goto out; | ||
| 453 | de = __f2fs_find_entry(dir, &fname, &page); | ||
| 454 | fscrypt_free_filename(&fname); | ||
| 455 | |||
| 452 | if (!de) { | 456 | if (!de) { |
| 453 | if (IS_ERR(page)) { | 457 | if (IS_ERR(page)) { |
| 454 | err = PTR_ERR(page); | 458 | err = PTR_ERR(page); |
| @@ -488,8 +492,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 488 | } | 492 | } |
| 489 | out_splice: | 493 | out_splice: |
| 490 | new = d_splice_alias(inode, dentry); | 494 | new = d_splice_alias(inode, dentry); |
| 491 | if (IS_ERR(new)) | 495 | err = PTR_ERR_OR_ZERO(new); |
| 492 | err = PTR_ERR(new); | ||
| 493 | trace_f2fs_lookup_end(dir, dentry, ino, err); | 496 | trace_f2fs_lookup_end(dir, dentry, ino, err); |
| 494 | return new; | 497 | return new; |
| 495 | out_iput: | 498 | out_iput: |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 5767b373a8ff..b73de6d04fa3 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -220,11 +220,9 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 220 | 220 | ||
| 221 | dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); | 221 | dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); |
| 222 | 222 | ||
| 223 | err = fscrypt_prepare_lookup(dir, dentry, flags); | 223 | err = fscrypt_prepare_lookup(dir, dentry, &nm); |
| 224 | if (err) | 224 | if (err == -ENOENT) |
| 225 | return ERR_PTR(err); | 225 | return d_splice_alias(NULL, dentry); |
| 226 | |||
| 227 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); | ||
| 228 | if (err) | 226 | if (err) |
| 229 | return ERR_PTR(err); | 227 | return ERR_PTR(err); |
| 230 | 228 | ||
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 76c518f1e4c7..abe7081b6b22 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h | |||
| @@ -33,6 +33,7 @@ struct fscrypt_name { | |||
| 33 | u32 hash; | 33 | u32 hash; |
| 34 | u32 minor_hash; | 34 | u32 minor_hash; |
| 35 | struct fscrypt_str crypto_buf; | 35 | struct fscrypt_str crypto_buf; |
| 36 | bool is_ciphertext_name; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | #define FSTR_INIT(n, l) { .name = n, .len = l } | 39 | #define FSTR_INIT(n, l) { .name = n, .len = l } |
| @@ -234,7 +235,8 @@ extern int __fscrypt_prepare_rename(struct inode *old_dir, | |||
| 234 | struct inode *new_dir, | 235 | struct inode *new_dir, |
| 235 | struct dentry *new_dentry, | 236 | struct dentry *new_dentry, |
| 236 | unsigned int flags); | 237 | unsigned int flags); |
| 237 | extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry); | 238 | extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, |
| 239 | struct fscrypt_name *fname); | ||
| 238 | extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, | 240 | extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, |
| 239 | unsigned int max_len, | 241 | unsigned int max_len, |
| 240 | struct fscrypt_str *disk_link); | 242 | struct fscrypt_str *disk_link); |
| @@ -347,7 +349,7 @@ static inline int fscrypt_setup_filename(struct inode *dir, | |||
| 347 | if (IS_ENCRYPTED(dir)) | 349 | if (IS_ENCRYPTED(dir)) |
| 348 | return -EOPNOTSUPP; | 350 | return -EOPNOTSUPP; |
| 349 | 351 | ||
| 350 | memset(fname, 0, sizeof(struct fscrypt_name)); | 352 | memset(fname, 0, sizeof(*fname)); |
| 351 | fname->usr_fname = iname; | 353 | fname->usr_fname = iname; |
| 352 | fname->disk_name.name = (unsigned char *)iname->name; | 354 | fname->disk_name.name = (unsigned char *)iname->name; |
| 353 | fname->disk_name.len = iname->len; | 355 | fname->disk_name.len = iname->len; |
| @@ -434,7 +436,8 @@ static inline int __fscrypt_prepare_rename(struct inode *old_dir, | |||
| 434 | } | 436 | } |
| 435 | 437 | ||
| 436 | static inline int __fscrypt_prepare_lookup(struct inode *dir, | 438 | static inline int __fscrypt_prepare_lookup(struct inode *dir, |
| 437 | struct dentry *dentry) | 439 | struct dentry *dentry, |
| 440 | struct fscrypt_name *fname) | ||
| 438 | { | 441 | { |
| 439 | return -EOPNOTSUPP; | 442 | return -EOPNOTSUPP; |
| 440 | } | 443 | } |
| @@ -555,25 +558,32 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir, | |||
| 555 | * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory | 558 | * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory |
| 556 | * @dir: directory being searched | 559 | * @dir: directory being searched |
| 557 | * @dentry: filename being looked up | 560 | * @dentry: filename being looked up |
| 558 | * @flags: lookup flags | 561 | * @fname: (output) the name to use to search the on-disk directory |
| 559 | * | 562 | * |
| 560 | * Prepare for ->lookup() in a directory which may be encrypted. Lookups can be | 563 | * Prepare for ->lookup() in a directory which may be encrypted by determining |
| 561 | * done with or without the directory's encryption key; without the key, | 564 | * the name that will actually be used to search the directory on-disk. Lookups |
| 565 | * can be done with or without the directory's encryption key; without the key, | ||
| 562 | * filenames are presented in encrypted form. Therefore, we'll try to set up | 566 | * filenames are presented in encrypted form. Therefore, we'll try to set up |
| 563 | * the directory's encryption key, but even without it the lookup can continue. | 567 | * the directory's encryption key, but even without it the lookup can continue. |
| 564 | * | 568 | * |
| 565 | * This also installs a custom ->d_revalidate() method which will invalidate the | 569 | * This also installs a custom ->d_revalidate() method which will invalidate the |
| 566 | * dentry if it was created without the key and the key is later added. | 570 | * dentry if it was created without the key and the key is later added. |
| 567 | * | 571 | * |
| 568 | * Return: 0 on success, -errno if a problem occurred while setting up the | 572 | * Return: 0 on success; -ENOENT if key is unavailable but the filename isn't a |
| 569 | * encryption key | 573 | * correctly formed encoded ciphertext name, so a negative dentry should be |
| 574 | * created; or another -errno code. | ||
| 570 | */ | 575 | */ |
| 571 | static inline int fscrypt_prepare_lookup(struct inode *dir, | 576 | static inline int fscrypt_prepare_lookup(struct inode *dir, |
| 572 | struct dentry *dentry, | 577 | struct dentry *dentry, |
| 573 | unsigned int flags) | 578 | struct fscrypt_name *fname) |
| 574 | { | 579 | { |
| 575 | if (IS_ENCRYPTED(dir)) | 580 | if (IS_ENCRYPTED(dir)) |
| 576 | return __fscrypt_prepare_lookup(dir, dentry); | 581 | return __fscrypt_prepare_lookup(dir, dentry, fname); |
| 582 | |||
| 583 | memset(fname, 0, sizeof(*fname)); | ||
| 584 | fname->usr_fname = &dentry->d_name; | ||
| 585 | fname->disk_name.name = (unsigned char *)dentry->d_name.name; | ||
| 586 | fname->disk_name.len = dentry->d_name.len; | ||
| 577 | return 0; | 587 | return 0; |
| 578 | } | 588 | } |
| 579 | 589 | ||
