diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8bbd60633f374665d877da722eb4326ee346346c..8e58c4cc2cb96519359e45d66acd34191972786f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1052,7 +1052,7 @@ static int f2fs_write_end(struct file *file, trace_f2fs_write_end(inode, pos, len, copied); - if (f2fs_is_atomic_file(inode)) + if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) register_inmem_page(inode, page); else set_page_dirty(page); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 07fda632430bfff098e0b3ee61915e5800afff45..8171e80b2ee9f9709c953b4264ea92bee01011c6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -198,6 +198,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, #define F2FS_IOCTL_MAGIC 0xf5 #define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) #define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) +#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* @@ -1060,6 +1061,7 @@ enum { FI_UPDATE_WRITE, /* inode has in-place-update data */ FI_NEED_IPU, /* used for ipu per file */ FI_ATOMIC_FILE, /* indicate atomic file */ + FI_VOLATILE_FILE, /* indicate volatile file */ }; static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) @@ -1151,6 +1153,11 @@ static inline bool f2fs_is_atomic_file(struct inode *inode) return is_inode_flag_set(F2FS_I(inode), FI_ATOMIC_FILE); } +static inline bool f2fs_is_volatile_file(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_VOLATILE_FILE); +} + static inline void *inline_data_addr(struct page *page) { struct f2fs_inode *ri = F2FS_INODE(page); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3708b80125d0133dcbc822c11b6e4a44de76a106..8e68bb64f83598360ffa8fdb31010aa1c33248f5 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -885,6 +885,9 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) if (!inode_owner_or_capable(inode)) return -EACCES; + if (f2fs_is_volatile_file(inode)) + return 0; + ret = mnt_want_write_file(filp); if (ret) return ret; @@ -897,6 +900,17 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) return ret; } +static int f2fs_ioc_start_volatile_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + return 0; +} + static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -938,6 +952,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_ioc_start_atomic_write(filp); case F2FS_IOC_COMMIT_ATOMIC_WRITE: return f2fs_ioc_commit_atomic_write(filp); + case F2FS_IOC_START_VOLATILE_WRITE: + return f2fs_ioc_start_volatile_write(filp); case FITRIM: return f2fs_ioc_fitrim(filp, arg); default: diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 1b85f72d007124d960b932de7a1fcb621ac1cc79..0deead4505e7ce1d7ec2525d8b3bf3eca9b76e00 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -270,7 +270,7 @@ void f2fs_evict_inode(struct inode *inode) nid_t xnid = F2FS_I(inode)->i_xattr_nid; /* some remained atomic pages should discarded */ - if (f2fs_is_atomic_file(inode)) + if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) commit_inmem_pages(inode, true); trace_f2fs_evict_inode(inode);