aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2016-02-15 04:54:26 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2016-02-22 19:07:23 -0500
commit922ec355f86365388203672119b5bca346a45085 (patch)
tree5f8f45642a18e05c51da9053fe1f8da2c9d197c0 /fs
parentae1086686487f13130937918ca91d920c1daafcb (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.c21
-rw-r--r--fs/f2fs/f2fs.h1
-rw-r--r--fs/f2fs/namei.c72
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
260unsigned 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)
266int f2fs_fname_crypto_alloc_buffer(struct inode *inode, 278int 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 */
2227bool f2fs_valid_filenames_enc_mode(uint32_t); 2227bool f2fs_valid_filenames_enc_mode(uint32_t);
2228u32 f2fs_fname_crypto_round_up(u32, u32); 2228u32 f2fs_fname_crypto_round_up(u32, u32);
2229unsigned f2fs_fname_encrypted_size(struct inode *, u32);
2229int f2fs_fname_crypto_alloc_buffer(struct inode *, u32, struct f2fs_str *); 2230int f2fs_fname_crypto_alloc_buffer(struct inode *, u32, struct f2fs_str *);
2230int f2fs_fname_disk_to_usr(struct inode *, f2fs_hash_t *, 2231int 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
414err_out: 418err_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;
439out: 443out:
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;
1013errout: 1010errout:
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);