aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-10-06 19:11:16 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-10-07 14:54:41 -0400
commit02a1335f25a386db9afc68f8315162f862aac93f (patch)
treeedb3b2894dfb09f42cb45b6ad0f3d40c84a4dd7b /fs
parent88b88a66797159949cec32eaab12b4968f6fae2d (diff)
f2fs: support volatile operations for transient data
This patch adds support for volatile writes which keep data pages in memory until f2fs_evict_inode is called by iput. For instance, we can use this feature for the sqlite database as follows. While supporting atomic writes for main database file, we can keep its journal data temporarily in the page cache by the following sequence. 1. open -> ioctl(F2FS_IOC_START_VOLATILE_WRITE); 2. writes : keep all the data in the page cache. 3. flush to the database file with atomic writes a. ioctl(F2FS_IOC_START_ATOMIC_WRITE); b. writes c. ioctl(F2FS_IOC_COMMIT_ATOMIC_WRITE); 4. close -> drop the cached data Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/data.c2
-rw-r--r--fs/f2fs/f2fs.h7
-rw-r--r--fs/f2fs/file.c16
-rw-r--r--fs/f2fs/inode.c2
4 files changed, 25 insertions, 2 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8bbd60633f37..8e58c4cc2cb9 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1052,7 +1052,7 @@ static int f2fs_write_end(struct file *file,
1052 1052
1053 trace_f2fs_write_end(inode, pos, len, copied); 1053 trace_f2fs_write_end(inode, pos, len, copied);
1054 1054
1055 if (f2fs_is_atomic_file(inode)) 1055 if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode))
1056 register_inmem_page(inode, page); 1056 register_inmem_page(inode, page);
1057 else 1057 else
1058 set_page_dirty(page); 1058 set_page_dirty(page);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 07fda632430b..8171e80b2ee9 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,
198#define F2FS_IOCTL_MAGIC 0xf5 198#define F2FS_IOCTL_MAGIC 0xf5
199#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) 199#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
200#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) 200#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
201#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
201 202
202#if defined(__KERNEL__) && defined(CONFIG_COMPAT) 203#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
203/* 204/*
@@ -1060,6 +1061,7 @@ enum {
1060 FI_UPDATE_WRITE, /* inode has in-place-update data */ 1061 FI_UPDATE_WRITE, /* inode has in-place-update data */
1061 FI_NEED_IPU, /* used for ipu per file */ 1062 FI_NEED_IPU, /* used for ipu per file */
1062 FI_ATOMIC_FILE, /* indicate atomic file */ 1063 FI_ATOMIC_FILE, /* indicate atomic file */
1064 FI_VOLATILE_FILE, /* indicate volatile file */
1063}; 1065};
1064 1066
1065static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) 1067static 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)
1151 return is_inode_flag_set(F2FS_I(inode), FI_ATOMIC_FILE); 1153 return is_inode_flag_set(F2FS_I(inode), FI_ATOMIC_FILE);
1152} 1154}
1153 1155
1156static inline bool f2fs_is_volatile_file(struct inode *inode)
1157{
1158 return is_inode_flag_set(F2FS_I(inode), FI_VOLATILE_FILE);
1159}
1160
1154static inline void *inline_data_addr(struct page *page) 1161static inline void *inline_data_addr(struct page *page)
1155{ 1162{
1156 struct f2fs_inode *ri = F2FS_INODE(page); 1163 struct f2fs_inode *ri = F2FS_INODE(page);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 3708b80125d0..8e68bb64f835 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)
885 if (!inode_owner_or_capable(inode)) 885 if (!inode_owner_or_capable(inode))
886 return -EACCES; 886 return -EACCES;
887 887
888 if (f2fs_is_volatile_file(inode))
889 return 0;
890
888 ret = mnt_want_write_file(filp); 891 ret = mnt_want_write_file(filp);
889 if (ret) 892 if (ret)
890 return ret; 893 return ret;
@@ -897,6 +900,17 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
897 return ret; 900 return ret;
898} 901}
899 902
903static int f2fs_ioc_start_volatile_write(struct file *filp)
904{
905 struct inode *inode = file_inode(filp);
906
907 if (!inode_owner_or_capable(inode))
908 return -EACCES;
909
910 set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE);
911 return 0;
912}
913
900static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) 914static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
901{ 915{
902 struct inode *inode = file_inode(filp); 916 struct inode *inode = file_inode(filp);
@@ -938,6 +952,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
938 return f2fs_ioc_start_atomic_write(filp); 952 return f2fs_ioc_start_atomic_write(filp);
939 case F2FS_IOC_COMMIT_ATOMIC_WRITE: 953 case F2FS_IOC_COMMIT_ATOMIC_WRITE:
940 return f2fs_ioc_commit_atomic_write(filp); 954 return f2fs_ioc_commit_atomic_write(filp);
955 case F2FS_IOC_START_VOLATILE_WRITE:
956 return f2fs_ioc_start_volatile_write(filp);
941 case FITRIM: 957 case FITRIM:
942 return f2fs_ioc_fitrim(filp, arg); 958 return f2fs_ioc_fitrim(filp, arg);
943 default: 959 default:
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 1b85f72d0071..0deead4505e7 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -270,7 +270,7 @@ void f2fs_evict_inode(struct inode *inode)
270 nid_t xnid = F2FS_I(inode)->i_xattr_nid; 270 nid_t xnid = F2FS_I(inode)->i_xattr_nid;
271 271
272 /* some remained atomic pages should discarded */ 272 /* some remained atomic pages should discarded */
273 if (f2fs_is_atomic_file(inode)) 273 if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode))
274 commit_inmem_pages(inode, true); 274 commit_inmem_pages(inode, true);
275 275
276 trace_f2fs_evict_inode(inode); 276 trace_f2fs_evict_inode(inode);