diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-10-06 20:39:50 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-10-06 20:39:50 -0400 |
commit | 88b88a66797159949cec32eaab12b4968f6fae2d (patch) | |
tree | da80cebeb9cc86d5f9f16718ce7921eef16ed30e /fs/f2fs/file.c | |
parent | 120c2cba1d76494a68e36a11eb630cb335ed1494 (diff) |
f2fs: support atomic writes
This patch introduces a very limited functionality for atomic write support.
In order to support atomic write, this patch adds two ioctls:
o F2FS_IOC_START_ATOMIC_WRITE
o F2FS_IOC_COMMIT_ATOMIC_WRITE
The database engine should be aware of the following sequence.
1. open
-> ioctl(F2FS_IOC_START_ATOMIC_WRITE);
2. writes
: all the written data will be treated as atomic pages.
3. commit
-> ioctl(F2FS_IOC_COMMIT_ATOMIC_WRITE);
: this flushes all the data blocks to the disk, which will be shown all or
nothing by f2fs recovery procedure.
4. repeat to #2.
The IO pattens should be:
,- START_ATOMIC_WRITE ,- COMMIT_ATOMIC_WRITE
CP | D D D D D D | FSYNC | D D D D | FSYNC ...
`- COMMIT_ATOMIC_WRITE
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/file.c')
-rw-r--r-- | fs/f2fs/file.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 735e9a20f939..3708b80125d0 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -862,6 +862,41 @@ out: | |||
862 | return ret; | 862 | return ret; |
863 | } | 863 | } |
864 | 864 | ||
865 | static int f2fs_ioc_start_atomic_write(struct file *filp) | ||
866 | { | ||
867 | struct inode *inode = file_inode(filp); | ||
868 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
869 | |||
870 | if (!inode_owner_or_capable(inode)) | ||
871 | return -EACCES; | ||
872 | |||
873 | f2fs_balance_fs(sbi); | ||
874 | |||
875 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | ||
876 | |||
877 | return f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1, NULL); | ||
878 | } | ||
879 | |||
880 | static int f2fs_ioc_commit_atomic_write(struct file *filp) | ||
881 | { | ||
882 | struct inode *inode = file_inode(filp); | ||
883 | int ret; | ||
884 | |||
885 | if (!inode_owner_or_capable(inode)) | ||
886 | return -EACCES; | ||
887 | |||
888 | ret = mnt_want_write_file(filp); | ||
889 | if (ret) | ||
890 | return ret; | ||
891 | |||
892 | if (f2fs_is_atomic_file(inode)) | ||
893 | commit_inmem_pages(inode, false); | ||
894 | |||
895 | ret = f2fs_sync_file(filp, 0, LONG_MAX, 0); | ||
896 | mnt_drop_write_file(filp); | ||
897 | return ret; | ||
898 | } | ||
899 | |||
865 | static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) | 900 | static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) |
866 | { | 901 | { |
867 | struct inode *inode = file_inode(filp); | 902 | struct inode *inode = file_inode(filp); |
@@ -899,6 +934,10 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
899 | return f2fs_ioc_getflags(filp, arg); | 934 | return f2fs_ioc_getflags(filp, arg); |
900 | case F2FS_IOC_SETFLAGS: | 935 | case F2FS_IOC_SETFLAGS: |
901 | return f2fs_ioc_setflags(filp, arg); | 936 | return f2fs_ioc_setflags(filp, arg); |
937 | case F2FS_IOC_START_ATOMIC_WRITE: | ||
938 | return f2fs_ioc_start_atomic_write(filp); | ||
939 | case F2FS_IOC_COMMIT_ATOMIC_WRITE: | ||
940 | return f2fs_ioc_commit_atomic_write(filp); | ||
902 | case FITRIM: | 941 | case FITRIM: |
903 | return f2fs_ioc_fitrim(filp, arg); | 942 | return f2fs_ioc_fitrim(filp, arg); |
904 | default: | 943 | default: |