diff options
author | Chao Yu <chao2.yu@samsung.com> | 2016-02-15 04:54:26 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-02-22 19:07:23 -0500 |
commit | 922ec355f86365388203672119b5bca346a45085 (patch) | |
tree | 5f8f45642a18e05c51da9053fe1f8da2c9d197c0 /fs | |
parent | ae1086686487f13130937918ca91d920c1daafcb (diff) |
f2fs crypto: avoid unneeded memory allocation when {en/de}crypting symlink
This patch adopts f2fs with codes of ext4, it removes unneeded memory
allocation in creating/accessing path of symlink.
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/crypto_fname.c | 21 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 1 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 72 |
3 files changed, 48 insertions, 46 deletions
diff --git a/fs/f2fs/crypto_fname.c b/fs/f2fs/crypto_fname.c index 73741fb65069..6dfdc978fe45 100644 --- a/fs/f2fs/crypto_fname.c +++ b/fs/f2fs/crypto_fname.c | |||
@@ -257,6 +257,18 @@ u32 f2fs_fname_crypto_round_up(u32 size, u32 blksize) | |||
257 | return ((size + blksize - 1) / blksize) * blksize; | 257 | return ((size + blksize - 1) / blksize) * blksize; |
258 | } | 258 | } |
259 | 259 | ||
260 | unsigned f2fs_fname_encrypted_size(struct inode *inode, u32 ilen) | ||
261 | { | ||
262 | struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info; | ||
263 | int padding = 32; | ||
264 | |||
265 | if (ci) | ||
266 | padding = 4 << (ci->ci_flags & F2FS_POLICY_FLAGS_PAD_MASK); | ||
267 | if (ilen < F2FS_CRYPTO_BLOCK_SIZE) | ||
268 | ilen = F2FS_CRYPTO_BLOCK_SIZE; | ||
269 | return f2fs_fname_crypto_round_up(ilen, padding); | ||
270 | } | ||
271 | |||
260 | /** | 272 | /** |
261 | * f2fs_fname_crypto_alloc_obuff() - | 273 | * f2fs_fname_crypto_alloc_obuff() - |
262 | * | 274 | * |
@@ -266,15 +278,8 @@ u32 f2fs_fname_crypto_round_up(u32 size, u32 blksize) | |||
266 | int f2fs_fname_crypto_alloc_buffer(struct inode *inode, | 278 | int f2fs_fname_crypto_alloc_buffer(struct inode *inode, |
267 | u32 ilen, struct f2fs_str *crypto_str) | 279 | u32 ilen, struct f2fs_str *crypto_str) |
268 | { | 280 | { |
269 | unsigned int olen; | 281 | unsigned int olen = f2fs_fname_encrypted_size(inode, ilen); |
270 | int padding = 32; | ||
271 | struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info; | ||
272 | 282 | ||
273 | if (ci) | ||
274 | padding = 4 << (ci->ci_flags & F2FS_POLICY_FLAGS_PAD_MASK); | ||
275 | if (ilen < F2FS_CRYPTO_BLOCK_SIZE) | ||
276 | ilen = F2FS_CRYPTO_BLOCK_SIZE; | ||
277 | olen = f2fs_fname_crypto_round_up(ilen, padding); | ||
278 | crypto_str->len = olen; | 283 | crypto_str->len = olen; |
279 | if (olen < F2FS_FNAME_CRYPTO_DIGEST_SIZE * 2) | 284 | if (olen < F2FS_FNAME_CRYPTO_DIGEST_SIZE * 2) |
280 | olen = F2FS_FNAME_CRYPTO_DIGEST_SIZE * 2; | 285 | olen = F2FS_FNAME_CRYPTO_DIGEST_SIZE * 2; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 0d2b1ba9660e..f9c294eee0f1 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -2226,6 +2226,7 @@ int _f2fs_get_encryption_info(struct inode *inode); | |||
2226 | /* crypto_fname.c */ | 2226 | /* crypto_fname.c */ |
2227 | bool f2fs_valid_filenames_enc_mode(uint32_t); | 2227 | bool f2fs_valid_filenames_enc_mode(uint32_t); |
2228 | u32 f2fs_fname_crypto_round_up(u32, u32); | 2228 | u32 f2fs_fname_crypto_round_up(u32, u32); |
2229 | unsigned f2fs_fname_encrypted_size(struct inode *, u32); | ||
2229 | int f2fs_fname_crypto_alloc_buffer(struct inode *, u32, struct f2fs_str *); | 2230 | int f2fs_fname_crypto_alloc_buffer(struct inode *, u32, struct f2fs_str *); |
2230 | int f2fs_fname_disk_to_usr(struct inode *, f2fs_hash_t *, | 2231 | int f2fs_fname_disk_to_usr(struct inode *, f2fs_hash_t *, |
2231 | const struct f2fs_str *, struct f2fs_str *); | 2232 | const struct f2fs_str *, struct f2fs_str *); |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 6f944e5eb76e..fcc8c26c0fe8 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -345,13 +345,23 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
345 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | 345 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
346 | struct inode *inode; | 346 | struct inode *inode; |
347 | size_t len = strlen(symname); | 347 | size_t len = strlen(symname); |
348 | size_t p_len; | 348 | struct f2fs_str disk_link = FSTR_INIT((char *)symname, len + 1); |
349 | char *p_str; | ||
350 | struct f2fs_str disk_link = FSTR_INIT(NULL, 0); | ||
351 | struct f2fs_encrypted_symlink_data *sd = NULL; | 349 | struct f2fs_encrypted_symlink_data *sd = NULL; |
352 | int err; | 350 | int err; |
353 | 351 | ||
354 | if (len > dir->i_sb->s_blocksize) | 352 | if (f2fs_encrypted_inode(dir)) { |
353 | err = f2fs_get_encryption_info(dir); | ||
354 | if (err) | ||
355 | return err; | ||
356 | |||
357 | if (!f2fs_encrypted_inode(dir)) | ||
358 | return -EPERM; | ||
359 | |||
360 | disk_link.len = (f2fs_fname_encrypted_size(dir, len) + | ||
361 | sizeof(struct f2fs_encrypted_symlink_data)); | ||
362 | } | ||
363 | |||
364 | if (disk_link.len > dir->i_sb->s_blocksize) | ||
355 | return -ENAMETOOLONG; | 365 | return -ENAMETOOLONG; |
356 | 366 | ||
357 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 367 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
@@ -374,42 +384,36 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
374 | f2fs_unlock_op(sbi); | 384 | f2fs_unlock_op(sbi); |
375 | alloc_nid_done(sbi, inode->i_ino); | 385 | alloc_nid_done(sbi, inode->i_ino); |
376 | 386 | ||
377 | if (f2fs_encrypted_inode(dir)) { | 387 | if (f2fs_encrypted_inode(inode)) { |
378 | struct qstr istr = QSTR_INIT(symname, len); | 388 | struct qstr istr = QSTR_INIT(symname, len); |
389 | struct f2fs_str ostr; | ||
379 | 390 | ||
380 | err = f2fs_get_encryption_info(inode); | 391 | sd = kzalloc(disk_link.len, GFP_NOFS); |
381 | if (err) | 392 | if (!sd) { |
393 | err = -ENOMEM; | ||
382 | goto err_out; | 394 | goto err_out; |
395 | } | ||
383 | 396 | ||
384 | err = f2fs_fname_crypto_alloc_buffer(inode, len, &disk_link); | 397 | err = f2fs_get_encryption_info(inode); |
385 | if (err) | 398 | if (err) |
386 | goto err_out; | 399 | goto err_out; |
387 | 400 | ||
388 | err = f2fs_fname_usr_to_disk(inode, &istr, &disk_link); | 401 | if (!f2fs_encrypted_inode(inode)) { |
389 | if (err < 0) | 402 | err = -EPERM; |
390 | goto err_out; | ||
391 | |||
392 | p_len = encrypted_symlink_data_len(disk_link.len) + 1; | ||
393 | |||
394 | if (p_len > dir->i_sb->s_blocksize) { | ||
395 | err = -ENAMETOOLONG; | ||
396 | goto err_out; | 403 | goto err_out; |
397 | } | 404 | } |
398 | 405 | ||
399 | sd = kzalloc(p_len, GFP_NOFS); | 406 | ostr.name = sd->encrypted_path; |
400 | if (!sd) { | 407 | ostr.len = disk_link.len; |
401 | err = -ENOMEM; | 408 | err = f2fs_fname_usr_to_disk(inode, &istr, &ostr); |
409 | if (err < 0) | ||
402 | goto err_out; | 410 | goto err_out; |
403 | } | 411 | |
404 | memcpy(sd->encrypted_path, disk_link.name, disk_link.len); | 412 | sd->len = cpu_to_le16(ostr.len); |
405 | sd->len = cpu_to_le16(disk_link.len); | 413 | disk_link.name = (char *)sd; |
406 | p_str = (char *)sd; | ||
407 | } else { | ||
408 | p_len = len + 1; | ||
409 | p_str = (char *)symname; | ||
410 | } | 414 | } |
411 | 415 | ||
412 | err = page_symlink(inode, p_str, p_len); | 416 | err = page_symlink(inode, disk_link.name, disk_link.len); |
413 | 417 | ||
414 | err_out: | 418 | err_out: |
415 | d_instantiate(dentry, inode); | 419 | d_instantiate(dentry, inode); |
@@ -425,7 +429,8 @@ err_out: | |||
425 | * performance regression. | 429 | * performance regression. |
426 | */ | 430 | */ |
427 | if (!err) { | 431 | if (!err) { |
428 | filemap_write_and_wait_range(inode->i_mapping, 0, p_len - 1); | 432 | filemap_write_and_wait_range(inode->i_mapping, 0, |
433 | disk_link.len - 1); | ||
429 | 434 | ||
430 | if (IS_DIRSYNC(dir)) | 435 | if (IS_DIRSYNC(dir)) |
431 | f2fs_sync_fs(sbi->sb, 1); | 436 | f2fs_sync_fs(sbi->sb, 1); |
@@ -434,7 +439,6 @@ err_out: | |||
434 | } | 439 | } |
435 | 440 | ||
436 | kfree(sd); | 441 | kfree(sd); |
437 | f2fs_fname_crypto_free_buffer(&disk_link); | ||
438 | return err; | 442 | return err; |
439 | out: | 443 | out: |
440 | handle_failed_inode(inode); | 444 | handle_failed_inode(inode); |
@@ -966,6 +970,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
966 | 970 | ||
967 | /* Symlink is encrypted */ | 971 | /* Symlink is encrypted */ |
968 | sd = (struct f2fs_encrypted_symlink_data *)caddr; | 972 | sd = (struct f2fs_encrypted_symlink_data *)caddr; |
973 | cstr.name = sd->encrypted_path; | ||
969 | cstr.len = le16_to_cpu(sd->len); | 974 | cstr.len = le16_to_cpu(sd->len); |
970 | 975 | ||
971 | /* this is broken symlink case */ | 976 | /* this is broken symlink case */ |
@@ -973,12 +978,6 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
973 | res = -ENOENT; | 978 | res = -ENOENT; |
974 | goto errout; | 979 | goto errout; |
975 | } | 980 | } |
976 | cstr.name = kmalloc(cstr.len, GFP_NOFS); | ||
977 | if (!cstr.name) { | ||
978 | res = -ENOMEM; | ||
979 | goto errout; | ||
980 | } | ||
981 | memcpy(cstr.name, sd->encrypted_path, cstr.len); | ||
982 | 981 | ||
983 | /* this is broken symlink case */ | 982 | /* this is broken symlink case */ |
984 | if (unlikely(cstr.name[0] == 0)) { | 983 | if (unlikely(cstr.name[0] == 0)) { |
@@ -1000,8 +999,6 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
1000 | if (res < 0) | 999 | if (res < 0) |
1001 | goto errout; | 1000 | goto errout; |
1002 | 1001 | ||
1003 | kfree(cstr.name); | ||
1004 | |||
1005 | paddr = pstr.name; | 1002 | paddr = pstr.name; |
1006 | 1003 | ||
1007 | /* Null-terminate the name */ | 1004 | /* Null-terminate the name */ |
@@ -1011,7 +1008,6 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, | |||
1011 | set_delayed_call(done, kfree_link, paddr); | 1008 | set_delayed_call(done, kfree_link, paddr); |
1012 | return paddr; | 1009 | return paddr; |
1013 | errout: | 1010 | errout: |
1014 | kfree(cstr.name); | ||
1015 | f2fs_fname_crypto_free_buffer(&pstr); | 1011 | f2fs_fname_crypto_free_buffer(&pstr); |
1016 | page_cache_release(cpage); | 1012 | page_cache_release(cpage); |
1017 | return ERR_PTR(res); | 1013 | return ERR_PTR(res); |