Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50732df0 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

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: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent ca0a81b3
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -333,10 +333,12 @@ static int make_empty_dir(struct inode *inode,
static struct page *init_inode_metadata(struct inode *inode,
		struct inode *dir, const struct qstr *name)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
	struct page *page;
	int err;

	if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
	if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE) &&
			inode->i_nlink) {
		page = new_inode_page(inode, name);
		if (IS_ERR(page))
			return page;
@@ -370,6 +372,12 @@ static struct page *init_inode_metadata(struct inode *inode,
	 */
	if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
		file_lost_pino(inode);
		/*
		 * If link the tmpfile to alias through linkat path,
		 * we should remove this inode from orphan list.
		 */
		if (inode->i_nlink == 0)
			remove_orphan_inode(sbi, inode->i_ino);
		inc_nlink(inode);
	}
	return page;
+64 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/pagemap.h>
#include <linux/sched.h>
#include <linux/ctype.h>
#include <linux/dcache.h>

#include "f2fs.h"
#include "node.h"
@@ -487,6 +488,68 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
	return err;
}

static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	struct super_block *sb = dir->i_sb;
	struct f2fs_sb_info *sbi = F2FS_SB(sb);
	struct inode *inode;
	struct page *page;
	int err;

	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &f2fs_file_inode_operations;
	inode->i_fop = &f2fs_file_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;

	f2fs_lock_op(sbi);
	err = acquire_orphan_inode(sbi);
	if (err)
		goto out;
	/*
	 * add this non-linked tmpfile to orphan list, in this way we could
	 * remove all unused data of tmpfile after abnormal power-off.
	 */
	add_orphan_inode(sbi, inode->i_ino);

	page = new_inode_page(inode, NULL);
	if (IS_ERR(page)) {
		err = PTR_ERR(page);
		goto remove_out;
	}

	err = f2fs_init_acl(inode, dir, page);
	if (err)
		goto unlock_out;

	err = f2fs_init_security(inode, dir, NULL, page);
	if (err)
		goto unlock_out;

	f2fs_put_page(page, 1);
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, inode->i_ino);
	mark_inode_dirty(inode);
	d_tmpfile(dentry, inode);
	unlock_new_inode(inode);
	return 0;
unlock_out:
	f2fs_put_page(page, 1);
remove_out:
	remove_orphan_inode(sbi, inode->i_ino);
out:
	f2fs_unlock_op(sbi);
	clear_nlink(inode);
	unlock_new_inode(inode);
	make_bad_inode(inode);
	iput(inode);
	alloc_nid_failed(sbi, inode->i_ino);
	return err;
}

const struct inode_operations f2fs_dir_inode_operations = {
	.create		= f2fs_create,
	.lookup		= f2fs_lookup,
@@ -497,6 +560,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
	.rmdir		= f2fs_rmdir,
	.mknod		= f2fs_mknod,
	.rename		= f2fs_rename,
	.tmpfile	= f2fs_tmpfile,
	.getattr	= f2fs_getattr,
	.setattr	= f2fs_setattr,
	.get_acl	= f2fs_get_acl,