diff options
Diffstat (limited to 'fs/f2fs/file.c')
| -rw-r--r-- | fs/f2fs/file.c | 101 |
1 files changed, 86 insertions, 15 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3c27e0ecb3bc..98dac27bc3f7 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "segment.h" | 26 | #include "segment.h" |
| 27 | #include "xattr.h" | 27 | #include "xattr.h" |
| 28 | #include "acl.h" | 28 | #include "acl.h" |
| 29 | #include "trace.h" | ||
| 29 | #include <trace/events/f2fs.h> | 30 | #include <trace/events/f2fs.h> |
| 30 | 31 | ||
| 31 | static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, | 32 | static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, |
| @@ -92,7 +93,6 @@ static const struct vm_operations_struct f2fs_file_vm_ops = { | |||
| 92 | .fault = filemap_fault, | 93 | .fault = filemap_fault, |
| 93 | .map_pages = filemap_map_pages, | 94 | .map_pages = filemap_map_pages, |
| 94 | .page_mkwrite = f2fs_vm_page_mkwrite, | 95 | .page_mkwrite = f2fs_vm_page_mkwrite, |
| 95 | .remap_pages = generic_file_remap_pages, | ||
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | static int get_parent_ino(struct inode *inode, nid_t *pino) | 98 | static int get_parent_ino(struct inode *inode, nid_t *pino) |
| @@ -246,6 +246,10 @@ go_write: | |||
| 246 | sync_nodes: | 246 | sync_nodes: |
| 247 | sync_node_pages(sbi, ino, &wbc); | 247 | sync_node_pages(sbi, ino, &wbc); |
| 248 | 248 | ||
| 249 | /* if cp_error was enabled, we should avoid infinite loop */ | ||
| 250 | if (unlikely(f2fs_cp_error(sbi))) | ||
| 251 | goto out; | ||
| 252 | |||
| 249 | if (need_inode_block_update(sbi, ino)) { | 253 | if (need_inode_block_update(sbi, ino)) { |
| 250 | mark_inode_dirty_sync(inode); | 254 | mark_inode_dirty_sync(inode); |
| 251 | f2fs_write_inode(inode, NULL); | 255 | f2fs_write_inode(inode, NULL); |
| @@ -265,6 +269,7 @@ flush_out: | |||
| 265 | ret = f2fs_issue_flush(sbi); | 269 | ret = f2fs_issue_flush(sbi); |
| 266 | out: | 270 | out: |
| 267 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); | 271 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); |
| 272 | f2fs_trace_ios(NULL, NULL, 1); | ||
| 268 | return ret; | 273 | return ret; |
| 269 | } | 274 | } |
| 270 | 275 | ||
| @@ -351,7 +356,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) | |||
| 351 | /* find data/hole in dnode block */ | 356 | /* find data/hole in dnode block */ |
| 352 | for (; dn.ofs_in_node < end_offset; | 357 | for (; dn.ofs_in_node < end_offset; |
| 353 | dn.ofs_in_node++, pgofs++, | 358 | dn.ofs_in_node++, pgofs++, |
| 354 | data_ofs = pgofs << PAGE_CACHE_SHIFT) { | 359 | data_ofs = (loff_t)pgofs << PAGE_CACHE_SHIFT) { |
| 355 | block_t blkaddr; | 360 | block_t blkaddr; |
| 356 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); | 361 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
| 357 | 362 | ||
| @@ -427,7 +432,8 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) | |||
| 427 | if (blkaddr == NULL_ADDR) | 432 | if (blkaddr == NULL_ADDR) |
| 428 | continue; | 433 | continue; |
| 429 | 434 | ||
| 430 | update_extent_cache(NULL_ADDR, dn); | 435 | dn->data_blkaddr = NULL_ADDR; |
| 436 | update_extent_cache(dn); | ||
| 431 | invalidate_blocks(sbi, blkaddr); | 437 | invalidate_blocks(sbi, blkaddr); |
| 432 | nr_free++; | 438 | nr_free++; |
| 433 | } | 439 | } |
| @@ -484,8 +490,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) | |||
| 484 | 490 | ||
| 485 | trace_f2fs_truncate_blocks_enter(inode, from); | 491 | trace_f2fs_truncate_blocks_enter(inode, from); |
| 486 | 492 | ||
| 487 | free_from = (pgoff_t) | 493 | free_from = (pgoff_t)F2FS_BYTES_TO_BLK(from + blocksize - 1); |
| 488 | ((from + blocksize - 1) >> (sbi->log_blocksize)); | ||
| 489 | 494 | ||
| 490 | if (lock) | 495 | if (lock) |
| 491 | f2fs_lock_op(sbi); | 496 | f2fs_lock_op(sbi); |
| @@ -836,6 +841,19 @@ static long f2fs_fallocate(struct file *file, int mode, | |||
| 836 | return ret; | 841 | return ret; |
| 837 | } | 842 | } |
| 838 | 843 | ||
| 844 | static int f2fs_release_file(struct inode *inode, struct file *filp) | ||
| 845 | { | ||
| 846 | /* some remained atomic pages should discarded */ | ||
| 847 | if (f2fs_is_atomic_file(inode)) | ||
| 848 | commit_inmem_pages(inode, true); | ||
| 849 | if (f2fs_is_volatile_file(inode)) { | ||
| 850 | set_inode_flag(F2FS_I(inode), FI_DROP_CACHE); | ||
| 851 | filemap_fdatawrite(inode->i_mapping); | ||
| 852 | clear_inode_flag(F2FS_I(inode), FI_DROP_CACHE); | ||
| 853 | } | ||
| 854 | return 0; | ||
| 855 | } | ||
| 856 | |||
| 839 | #define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) | 857 | #define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) |
| 840 | #define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) | 858 | #define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) |
| 841 | 859 | ||
| @@ -906,29 +924,30 @@ out: | |||
| 906 | return ret; | 924 | return ret; |
| 907 | } | 925 | } |
| 908 | 926 | ||
| 927 | static int f2fs_ioc_getversion(struct file *filp, unsigned long arg) | ||
| 928 | { | ||
| 929 | struct inode *inode = file_inode(filp); | ||
| 930 | |||
| 931 | return put_user(inode->i_generation, (int __user *)arg); | ||
| 932 | } | ||
| 933 | |||
| 909 | static int f2fs_ioc_start_atomic_write(struct file *filp) | 934 | static int f2fs_ioc_start_atomic_write(struct file *filp) |
| 910 | { | 935 | { |
| 911 | struct inode *inode = file_inode(filp); | 936 | struct inode *inode = file_inode(filp); |
| 912 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
| 913 | 937 | ||
| 914 | if (!inode_owner_or_capable(inode)) | 938 | if (!inode_owner_or_capable(inode)) |
| 915 | return -EACCES; | 939 | return -EACCES; |
| 916 | 940 | ||
| 917 | f2fs_balance_fs(sbi); | 941 | f2fs_balance_fs(F2FS_I_SB(inode)); |
| 942 | |||
| 943 | if (f2fs_is_atomic_file(inode)) | ||
| 944 | return 0; | ||
| 918 | 945 | ||
| 919 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | 946 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); |
| 920 | 947 | ||
| 921 | return f2fs_convert_inline_inode(inode); | 948 | return f2fs_convert_inline_inode(inode); |
| 922 | } | 949 | } |
| 923 | 950 | ||
| 924 | static int f2fs_release_file(struct inode *inode, struct file *filp) | ||
| 925 | { | ||
| 926 | /* some remained atomic pages should discarded */ | ||
| 927 | if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) | ||
| 928 | commit_inmem_pages(inode, true); | ||
| 929 | return 0; | ||
| 930 | } | ||
| 931 | |||
| 932 | static int f2fs_ioc_commit_atomic_write(struct file *filp) | 951 | static int f2fs_ioc_commit_atomic_write(struct file *filp) |
| 933 | { | 952 | { |
| 934 | struct inode *inode = file_inode(filp); | 953 | struct inode *inode = file_inode(filp); |
| @@ -949,6 +968,7 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) | |||
| 949 | 968 | ||
| 950 | ret = f2fs_sync_file(filp, 0, LONG_MAX, 0); | 969 | ret = f2fs_sync_file(filp, 0, LONG_MAX, 0); |
| 951 | mnt_drop_write_file(filp); | 970 | mnt_drop_write_file(filp); |
| 971 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | ||
| 952 | return ret; | 972 | return ret; |
| 953 | } | 973 | } |
| 954 | 974 | ||
| @@ -959,11 +979,56 @@ static int f2fs_ioc_start_volatile_write(struct file *filp) | |||
| 959 | if (!inode_owner_or_capable(inode)) | 979 | if (!inode_owner_or_capable(inode)) |
| 960 | return -EACCES; | 980 | return -EACCES; |
| 961 | 981 | ||
| 982 | if (f2fs_is_volatile_file(inode)) | ||
| 983 | return 0; | ||
| 984 | |||
| 962 | set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | 985 | set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); |
| 963 | 986 | ||
| 964 | return f2fs_convert_inline_inode(inode); | 987 | return f2fs_convert_inline_inode(inode); |
| 965 | } | 988 | } |
| 966 | 989 | ||
| 990 | static int f2fs_ioc_release_volatile_write(struct file *filp) | ||
| 991 | { | ||
| 992 | struct inode *inode = file_inode(filp); | ||
| 993 | |||
| 994 | if (!inode_owner_or_capable(inode)) | ||
| 995 | return -EACCES; | ||
| 996 | |||
| 997 | if (!f2fs_is_volatile_file(inode)) | ||
| 998 | return 0; | ||
| 999 | |||
| 1000 | punch_hole(inode, 0, F2FS_BLKSIZE); | ||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | static int f2fs_ioc_abort_volatile_write(struct file *filp) | ||
| 1005 | { | ||
| 1006 | struct inode *inode = file_inode(filp); | ||
| 1007 | int ret; | ||
| 1008 | |||
| 1009 | if (!inode_owner_or_capable(inode)) | ||
| 1010 | return -EACCES; | ||
| 1011 | |||
| 1012 | ret = mnt_want_write_file(filp); | ||
| 1013 | if (ret) | ||
| 1014 | return ret; | ||
| 1015 | |||
| 1016 | f2fs_balance_fs(F2FS_I_SB(inode)); | ||
| 1017 | |||
| 1018 | if (f2fs_is_atomic_file(inode)) { | ||
| 1019 | commit_inmem_pages(inode, false); | ||
| 1020 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | if (f2fs_is_volatile_file(inode)) { | ||
| 1024 | clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | ||
| 1025 | filemap_fdatawrite(inode->i_mapping); | ||
| 1026 | set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | ||
| 1027 | } | ||
| 1028 | mnt_drop_write_file(filp); | ||
| 1029 | return ret; | ||
| 1030 | } | ||
| 1031 | |||
| 967 | static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) | 1032 | static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) |
| 968 | { | 1033 | { |
| 969 | struct inode *inode = file_inode(filp); | 1034 | struct inode *inode = file_inode(filp); |
| @@ -1001,12 +1066,18 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 1001 | return f2fs_ioc_getflags(filp, arg); | 1066 | return f2fs_ioc_getflags(filp, arg); |
| 1002 | case F2FS_IOC_SETFLAGS: | 1067 | case F2FS_IOC_SETFLAGS: |
| 1003 | return f2fs_ioc_setflags(filp, arg); | 1068 | return f2fs_ioc_setflags(filp, arg); |
| 1069 | case F2FS_IOC_GETVERSION: | ||
| 1070 | return f2fs_ioc_getversion(filp, arg); | ||
| 1004 | case F2FS_IOC_START_ATOMIC_WRITE: | 1071 | case F2FS_IOC_START_ATOMIC_WRITE: |
| 1005 | return f2fs_ioc_start_atomic_write(filp); | 1072 | return f2fs_ioc_start_atomic_write(filp); |
| 1006 | case F2FS_IOC_COMMIT_ATOMIC_WRITE: | 1073 | case F2FS_IOC_COMMIT_ATOMIC_WRITE: |
| 1007 | return f2fs_ioc_commit_atomic_write(filp); | 1074 | return f2fs_ioc_commit_atomic_write(filp); |
| 1008 | case F2FS_IOC_START_VOLATILE_WRITE: | 1075 | case F2FS_IOC_START_VOLATILE_WRITE: |
| 1009 | return f2fs_ioc_start_volatile_write(filp); | 1076 | return f2fs_ioc_start_volatile_write(filp); |
| 1077 | case F2FS_IOC_RELEASE_VOLATILE_WRITE: | ||
| 1078 | return f2fs_ioc_release_volatile_write(filp); | ||
| 1079 | case F2FS_IOC_ABORT_VOLATILE_WRITE: | ||
| 1080 | return f2fs_ioc_abort_volatile_write(filp); | ||
| 1010 | case FITRIM: | 1081 | case FITRIM: |
| 1011 | return f2fs_ioc_fitrim(filp, arg); | 1082 | return f2fs_ioc_fitrim(filp, arg); |
| 1012 | default: | 1083 | default: |
