aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/data.c47
-rw-r--r--fs/f2fs/f2fs.h8
-rw-r--r--fs/f2fs/file.c35
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
842static 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
849int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) 842int 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
1117bool 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
1124static int __get_data_block(struct inode *inode, sector_t iblock, 1142static 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
2359out:
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);
2877int f2fs_migrate_page(struct address_space *mapping, struct page *newpage, 2877int 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
2880bool 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
3265static 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);