aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2014-06-19 04:23:19 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-07-09 17:04:24 -0400
commit50732df02eefb39ab414ef655979c2c9b64ad21c (patch)
treee8cb6cb0be5951f112ced0406d5bd0c6721aa60e /fs/f2fs
parentca0a81b397b5f153ac2a9880c5e85b08b0447e4e (diff)
f2fs: support ->tmpfile()
Add function f2fs_tmpfile() to support O_TMPFILE file creation, and modify logic of init_inode_metadata to enable linkat temp file. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/dir.c10
-rw-r--r--fs/f2fs/namei.c64
2 files changed, 73 insertions, 1 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index a4addd72ebbd..3677f4124541 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -333,10 +333,12 @@ static int make_empty_dir(struct inode *inode,
333static struct page *init_inode_metadata(struct inode *inode, 333static struct page *init_inode_metadata(struct inode *inode,
334 struct inode *dir, const struct qstr *name) 334 struct inode *dir, const struct qstr *name)
335{ 335{
336 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
336 struct page *page; 337 struct page *page;
337 int err; 338 int err;
338 339
339 if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 340 if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE) &&
341 inode->i_nlink) {
340 page = new_inode_page(inode, name); 342 page = new_inode_page(inode, name);
341 if (IS_ERR(page)) 343 if (IS_ERR(page))
342 return page; 344 return page;
@@ -370,6 +372,12 @@ static struct page *init_inode_metadata(struct inode *inode,
370 */ 372 */
371 if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { 373 if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
372 file_lost_pino(inode); 374 file_lost_pino(inode);
375 /*
376 * If link the tmpfile to alias through linkat path,
377 * we should remove this inode from orphan list.
378 */
379 if (inode->i_nlink == 0)
380 remove_orphan_inode(sbi, inode->i_ino);
373 inc_nlink(inode); 381 inc_nlink(inode);
374 } 382 }
375 return page; 383 return page;
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index a6bdddc33ce2..5c08c546e4c8 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -13,6 +13,7 @@
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/ctype.h> 15#include <linux/ctype.h>
16#include <linux/dcache.h>
16 17
17#include "f2fs.h" 18#include "f2fs.h"
18#include "node.h" 19#include "node.h"
@@ -487,6 +488,68 @@ out:
487 return err; 488 return err;
488} 489}
489 490
491static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
492{
493 struct super_block *sb = dir->i_sb;
494 struct f2fs_sb_info *sbi = F2FS_SB(sb);
495 struct inode *inode;
496 struct page *page;
497 int err;
498
499 inode = f2fs_new_inode(dir, mode);
500 if (IS_ERR(inode))
501 return PTR_ERR(inode);
502
503 inode->i_op = &f2fs_file_inode_operations;
504 inode->i_fop = &f2fs_file_operations;
505 inode->i_mapping->a_ops = &f2fs_dblock_aops;
506
507 f2fs_lock_op(sbi);
508 err = acquire_orphan_inode(sbi);
509 if (err)
510 goto out;
511 /*
512 * add this non-linked tmpfile to orphan list, in this way we could
513 * remove all unused data of tmpfile after abnormal power-off.
514 */
515 add_orphan_inode(sbi, inode->i_ino);
516
517 page = new_inode_page(inode, NULL);
518 if (IS_ERR(page)) {
519 err = PTR_ERR(page);
520 goto remove_out;
521 }
522
523 err = f2fs_init_acl(inode, dir, page);
524 if (err)
525 goto unlock_out;
526
527 err = f2fs_init_security(inode, dir, NULL, page);
528 if (err)
529 goto unlock_out;
530
531 f2fs_put_page(page, 1);
532 f2fs_unlock_op(sbi);
533
534 alloc_nid_done(sbi, inode->i_ino);
535 mark_inode_dirty(inode);
536 d_tmpfile(dentry, inode);
537 unlock_new_inode(inode);
538 return 0;
539unlock_out:
540 f2fs_put_page(page, 1);
541remove_out:
542 remove_orphan_inode(sbi, inode->i_ino);
543out:
544 f2fs_unlock_op(sbi);
545 clear_nlink(inode);
546 unlock_new_inode(inode);
547 make_bad_inode(inode);
548 iput(inode);
549 alloc_nid_failed(sbi, inode->i_ino);
550 return err;
551}
552
490const struct inode_operations f2fs_dir_inode_operations = { 553const struct inode_operations f2fs_dir_inode_operations = {
491 .create = f2fs_create, 554 .create = f2fs_create,
492 .lookup = f2fs_lookup, 555 .lookup = f2fs_lookup,
@@ -497,6 +560,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
497 .rmdir = f2fs_rmdir, 560 .rmdir = f2fs_rmdir,
498 .mknod = f2fs_mknod, 561 .mknod = f2fs_mknod,
499 .rename = f2fs_rename, 562 .rename = f2fs_rename,
563 .tmpfile = f2fs_tmpfile,
500 .getattr = f2fs_getattr, 564 .getattr = f2fs_getattr,
501 .setattr = f2fs_setattr, 565 .setattr = f2fs_setattr,
502 .get_acl = f2fs_get_acl, 566 .get_acl = f2fs_get_acl,