diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/data.c | 47 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 8 | ||||
-rw-r--r-- | fs/f2fs/file.c | 35 |
3 files changed, 74 insertions, 16 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3d6ae3173f98..f6cf99a311c3 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -839,13 +839,6 @@ alloc: | |||
839 | return 0; | 839 | return 0; |
840 | } | 840 | } |
841 | 841 | ||
842 | static inline bool __force_buffered_io(struct inode *inode, int rw) | ||
843 | { | ||
844 | return (f2fs_encrypted_file(inode) || | ||
845 | (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) || | ||
846 | F2FS_I_SB(inode)->s_ndevs); | ||
847 | } | ||
848 | |||
849 | int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) | 842 | int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) |
850 | { | 843 | { |
851 | struct inode *inode = file_inode(iocb->ki_filp); | 844 | struct inode *inode = file_inode(iocb->ki_filp); |
@@ -877,7 +870,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) | |||
877 | 870 | ||
878 | if (direct_io) { | 871 | if (direct_io) { |
879 | map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint); | 872 | map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint); |
880 | flag = __force_buffered_io(inode, WRITE) ? | 873 | flag = f2fs_force_buffered_io(inode, WRITE) ? |
881 | F2FS_GET_BLOCK_PRE_AIO : | 874 | F2FS_GET_BLOCK_PRE_AIO : |
882 | F2FS_GET_BLOCK_PRE_DIO; | 875 | F2FS_GET_BLOCK_PRE_DIO; |
883 | goto map_blocks; | 876 | goto map_blocks; |
@@ -1121,6 +1114,31 @@ out: | |||
1121 | return err; | 1114 | return err; |
1122 | } | 1115 | } |
1123 | 1116 | ||
1117 | bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len) | ||
1118 | { | ||
1119 | struct f2fs_map_blocks map; | ||
1120 | block_t last_lblk; | ||
1121 | int err; | ||
1122 | |||
1123 | if (pos + len > i_size_read(inode)) | ||
1124 | return false; | ||
1125 | |||
1126 | map.m_lblk = F2FS_BYTES_TO_BLK(pos); | ||
1127 | map.m_next_pgofs = NULL; | ||
1128 | map.m_next_extent = NULL; | ||
1129 | map.m_seg_type = NO_CHECK_TYPE; | ||
1130 | last_lblk = F2FS_BLK_ALIGN(pos + len); | ||
1131 | |||
1132 | while (map.m_lblk < last_lblk) { | ||
1133 | map.m_len = last_lblk - map.m_lblk; | ||
1134 | err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT); | ||
1135 | if (err || map.m_len == 0) | ||
1136 | return false; | ||
1137 | map.m_lblk += map.m_len; | ||
1138 | } | ||
1139 | return true; | ||
1140 | } | ||
1141 | |||
1124 | static int __get_data_block(struct inode *inode, sector_t iblock, | 1142 | static int __get_data_block(struct inode *inode, sector_t iblock, |
1125 | struct buffer_head *bh, int create, int flag, | 1143 | struct buffer_head *bh, int create, int flag, |
1126 | pgoff_t *next_pgofs, int seg_type) | 1144 | pgoff_t *next_pgofs, int seg_type) |
@@ -2306,7 +2324,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
2306 | if (err) | 2324 | if (err) |
2307 | return err; | 2325 | return err; |
2308 | 2326 | ||
2309 | if (__force_buffered_io(inode, rw)) | 2327 | if (f2fs_force_buffered_io(inode, rw)) |
2310 | return 0; | 2328 | return 0; |
2311 | 2329 | ||
2312 | trace_f2fs_direct_IO_enter(inode, offset, count, rw); | 2330 | trace_f2fs_direct_IO_enter(inode, offset, count, rw); |
@@ -2314,7 +2332,15 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
2314 | if (rw == WRITE && whint_mode == WHINT_MODE_OFF) | 2332 | if (rw == WRITE && whint_mode == WHINT_MODE_OFF) |
2315 | iocb->ki_hint = WRITE_LIFE_NOT_SET; | 2333 | iocb->ki_hint = WRITE_LIFE_NOT_SET; |
2316 | 2334 | ||
2317 | down_read(&F2FS_I(inode)->dio_rwsem[rw]); | 2335 | if (!down_read_trylock(&F2FS_I(inode)->dio_rwsem[rw])) { |
2336 | if (iocb->ki_flags & IOCB_NOWAIT) { | ||
2337 | iocb->ki_hint = hint; | ||
2338 | err = -EAGAIN; | ||
2339 | goto out; | ||
2340 | } | ||
2341 | down_read(&F2FS_I(inode)->dio_rwsem[rw]); | ||
2342 | } | ||
2343 | |||
2318 | err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio); | 2344 | err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio); |
2319 | up_read(&F2FS_I(inode)->dio_rwsem[rw]); | 2345 | up_read(&F2FS_I(inode)->dio_rwsem[rw]); |
2320 | 2346 | ||
@@ -2330,6 +2356,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
2330 | } | 2356 | } |
2331 | } | 2357 | } |
2332 | 2358 | ||
2359 | out: | ||
2333 | trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); | 2360 | trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); |
2334 | 2361 | ||
2335 | return err; | 2362 | return err; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 93822634870d..88f2b420de27 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -2877,6 +2877,7 @@ int f2fs_release_page(struct page *page, gfp_t wait); | |||
2877 | int f2fs_migrate_page(struct address_space *mapping, struct page *newpage, | 2877 | int f2fs_migrate_page(struct address_space *mapping, struct page *newpage, |
2878 | struct page *page, enum migrate_mode mode); | 2878 | struct page *page, enum migrate_mode mode); |
2879 | #endif | 2879 | #endif |
2880 | bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len); | ||
2880 | 2881 | ||
2881 | /* | 2882 | /* |
2882 | * gc.c | 2883 | * gc.c |
@@ -3261,4 +3262,11 @@ static inline bool f2fs_may_encrypt(struct inode *inode) | |||
3261 | #endif | 3262 | #endif |
3262 | } | 3263 | } |
3263 | 3264 | ||
3265 | static inline bool f2fs_force_buffered_io(struct inode *inode, int rw) | ||
3266 | { | ||
3267 | return (f2fs_encrypted_file(inode) || | ||
3268 | (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) || | ||
3269 | F2FS_I_SB(inode)->s_ndevs); | ||
3270 | } | ||
3271 | |||
3264 | #endif | 3272 | #endif |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3072837744b9..c4c27e63daf1 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -480,6 +480,9 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) | |||
480 | 480 | ||
481 | if (err) | 481 | if (err) |
482 | return err; | 482 | return err; |
483 | |||
484 | filp->f_mode |= FMODE_NOWAIT; | ||
485 | |||
483 | return dquot_file_open(inode, filp); | 486 | return dquot_file_open(inode, filp); |
484 | } | 487 | } |
485 | 488 | ||
@@ -2896,7 +2899,15 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
2896 | if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) | 2899 | if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) |
2897 | return -EIO; | 2900 | return -EIO; |
2898 | 2901 | ||
2899 | inode_lock(inode); | 2902 | if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) |
2903 | return -EINVAL; | ||
2904 | |||
2905 | if (!inode_trylock(inode)) { | ||
2906 | if (iocb->ki_flags & IOCB_NOWAIT) | ||
2907 | return -EAGAIN; | ||
2908 | inode_lock(inode); | ||
2909 | } | ||
2910 | |||
2900 | ret = generic_write_checks(iocb, from); | 2911 | ret = generic_write_checks(iocb, from); |
2901 | if (ret > 0) { | 2912 | if (ret > 0) { |
2902 | int err; | 2913 | int err; |
@@ -2904,11 +2915,23 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
2904 | if (iov_iter_fault_in_readable(from, iov_iter_count(from))) | 2915 | if (iov_iter_fault_in_readable(from, iov_iter_count(from))) |
2905 | set_inode_flag(inode, FI_NO_PREALLOC); | 2916 | set_inode_flag(inode, FI_NO_PREALLOC); |
2906 | 2917 | ||
2907 | err = f2fs_preallocate_blocks(iocb, from); | 2918 | if ((iocb->ki_flags & IOCB_NOWAIT) && |
2908 | if (err) { | 2919 | (iocb->ki_flags & IOCB_DIRECT)) { |
2909 | clear_inode_flag(inode, FI_NO_PREALLOC); | 2920 | if (!f2fs_overwrite_io(inode, iocb->ki_pos, |
2910 | inode_unlock(inode); | 2921 | iov_iter_count(from)) || |
2911 | return err; | 2922 | f2fs_has_inline_data(inode) || |
2923 | f2fs_force_buffered_io(inode, WRITE)) { | ||
2924 | inode_unlock(inode); | ||
2925 | return -EAGAIN; | ||
2926 | } | ||
2927 | |||
2928 | } else { | ||
2929 | err = f2fs_preallocate_blocks(iocb, from); | ||
2930 | if (err) { | ||
2931 | clear_inode_flag(inode, FI_NO_PREALLOC); | ||
2932 | inode_unlock(inode); | ||
2933 | return err; | ||
2934 | } | ||
2912 | } | 2935 | } |
2913 | blk_start_plug(&plug); | 2936 | blk_start_plug(&plug); |
2914 | ret = __generic_file_write_iter(iocb, from); | 2937 | ret = __generic_file_write_iter(iocb, from); |