|
@@ -839,13 +839,6 @@ alloc:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static inline bool __force_buffered_io(struct inode *inode, int rw)
|
|
|
-{
|
|
|
- return (f2fs_encrypted_file(inode) ||
|
|
|
- (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) ||
|
|
|
- F2FS_I_SB(inode)->s_ndevs);
|
|
|
-}
|
|
|
-
|
|
|
int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
|
|
|
{
|
|
|
struct inode *inode = file_inode(iocb->ki_filp);
|
|
@@ -877,7 +870,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
|
|
|
|
|
|
if (direct_io) {
|
|
|
map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint);
|
|
|
- flag = __force_buffered_io(inode, WRITE) ?
|
|
|
+ flag = f2fs_force_buffered_io(inode, WRITE) ?
|
|
|
F2FS_GET_BLOCK_PRE_AIO :
|
|
|
F2FS_GET_BLOCK_PRE_DIO;
|
|
|
goto map_blocks;
|
|
@@ -1121,6 +1114,31 @@ out:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
|
|
|
+{
|
|
|
+ struct f2fs_map_blocks map;
|
|
|
+ block_t last_lblk;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (pos + len > i_size_read(inode))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ map.m_lblk = F2FS_BYTES_TO_BLK(pos);
|
|
|
+ map.m_next_pgofs = NULL;
|
|
|
+ map.m_next_extent = NULL;
|
|
|
+ map.m_seg_type = NO_CHECK_TYPE;
|
|
|
+ last_lblk = F2FS_BLK_ALIGN(pos + len);
|
|
|
+
|
|
|
+ while (map.m_lblk < last_lblk) {
|
|
|
+ map.m_len = last_lblk - map.m_lblk;
|
|
|
+ err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT);
|
|
|
+ if (err || map.m_len == 0)
|
|
|
+ return false;
|
|
|
+ map.m_lblk += map.m_len;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
static int __get_data_block(struct inode *inode, sector_t iblock,
|
|
|
struct buffer_head *bh, int create, int flag,
|
|
|
pgoff_t *next_pgofs, int seg_type)
|
|
@@ -2306,7 +2324,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- if (__force_buffered_io(inode, rw))
|
|
|
+ if (f2fs_force_buffered_io(inode, rw))
|
|
|
return 0;
|
|
|
|
|
|
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)
|
|
|
if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
|
|
|
iocb->ki_hint = WRITE_LIFE_NOT_SET;
|
|
|
|
|
|
- down_read(&F2FS_I(inode)->dio_rwsem[rw]);
|
|
|
+ if (!down_read_trylock(&F2FS_I(inode)->dio_rwsem[rw])) {
|
|
|
+ if (iocb->ki_flags & IOCB_NOWAIT) {
|
|
|
+ iocb->ki_hint = hint;
|
|
|
+ err = -EAGAIN;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ down_read(&F2FS_I(inode)->dio_rwsem[rw]);
|
|
|
+ }
|
|
|
+
|
|
|
err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
|
|
|
up_read(&F2FS_I(inode)->dio_rwsem[rw]);
|
|
|
|
|
@@ -2330,6 +2356,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+out:
|
|
|
trace_f2fs_direct_IO_exit(inode, offset, count, rw, err);
|
|
|
|
|
|
return err;
|