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/f2fs/namei.c | |
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/f2fs/namei.c')
-rw-r--r-- | fs/f2fs/namei.c | 72 |
1 files changed, 34 insertions, 38 deletions
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); |