mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 20:22:08 +02:00
Merge ccf7cf9237 ("f2fs: fix the f2fs_file_write_iter tracepoint") into android-mainline
Steps on the way to 5.17-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ia8000ce0417446c200e16eb42d98ed615ff464b8
This commit is contained in:
commit
e545c97646
|
|
@ -154,6 +154,7 @@ void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse)
|
|||
cc->rpages = NULL;
|
||||
cc->nr_rpages = 0;
|
||||
cc->nr_cpages = 0;
|
||||
cc->valid_nr_cpages = 0;
|
||||
if (!reuse)
|
||||
cc->cluster_idx = NULL_CLUSTER;
|
||||
}
|
||||
|
|
@ -620,7 +621,6 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
|
|||
const struct f2fs_compress_ops *cops =
|
||||
f2fs_cops[fi->i_compress_algorithm];
|
||||
unsigned int max_len, new_nr_cpages;
|
||||
struct page **new_cpages;
|
||||
u32 chksum = 0;
|
||||
int i, ret;
|
||||
|
||||
|
|
@ -635,6 +635,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
|
|||
|
||||
max_len = COMPRESS_HEADER_SIZE + cc->clen;
|
||||
cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE);
|
||||
cc->valid_nr_cpages = cc->nr_cpages;
|
||||
|
||||
cc->cpages = page_array_alloc(cc->inode, cc->nr_cpages);
|
||||
if (!cc->cpages) {
|
||||
|
|
@ -685,13 +686,6 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
|
|||
|
||||
new_nr_cpages = DIV_ROUND_UP(cc->clen + COMPRESS_HEADER_SIZE, PAGE_SIZE);
|
||||
|
||||
/* Now we're going to cut unnecessary tail pages */
|
||||
new_cpages = page_array_alloc(cc->inode, new_nr_cpages);
|
||||
if (!new_cpages) {
|
||||
ret = -ENOMEM;
|
||||
goto out_vunmap_cbuf;
|
||||
}
|
||||
|
||||
/* zero out any unused part of the last page */
|
||||
memset(&cc->cbuf->cdata[cc->clen], 0,
|
||||
(new_nr_cpages * PAGE_SIZE) -
|
||||
|
|
@ -701,10 +695,8 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
|
|||
vm_unmap_ram(cc->rbuf, cc->cluster_size);
|
||||
|
||||
for (i = 0; i < cc->nr_cpages; i++) {
|
||||
if (i < new_nr_cpages) {
|
||||
new_cpages[i] = cc->cpages[i];
|
||||
if (i < new_nr_cpages)
|
||||
continue;
|
||||
}
|
||||
f2fs_compress_free_page(cc->cpages[i]);
|
||||
cc->cpages[i] = NULL;
|
||||
}
|
||||
|
|
@ -712,9 +704,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
|
|||
if (cops->destroy_compress_ctx)
|
||||
cops->destroy_compress_ctx(cc);
|
||||
|
||||
page_array_free(cc->inode, cc->cpages, cc->nr_cpages);
|
||||
cc->cpages = new_cpages;
|
||||
cc->nr_cpages = new_nr_cpages;
|
||||
cc->valid_nr_cpages = new_nr_cpages;
|
||||
|
||||
trace_f2fs_compress_pages_end(cc->inode, cc->cluster_idx,
|
||||
cc->clen, ret);
|
||||
|
|
@ -1308,14 +1298,14 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
|
|||
|
||||
cic->magic = F2FS_COMPRESSED_PAGE_MAGIC;
|
||||
cic->inode = inode;
|
||||
atomic_set(&cic->pending_pages, cc->nr_cpages);
|
||||
atomic_set(&cic->pending_pages, cc->valid_nr_cpages);
|
||||
cic->rpages = page_array_alloc(cc->inode, cc->cluster_size);
|
||||
if (!cic->rpages)
|
||||
goto out_put_cic;
|
||||
|
||||
cic->nr_rpages = cc->cluster_size;
|
||||
|
||||
for (i = 0; i < cc->nr_cpages; i++) {
|
||||
for (i = 0; i < cc->valid_nr_cpages; i++) {
|
||||
f2fs_set_compressed_page(cc->cpages[i], inode,
|
||||
cc->rpages[i + 1]->index, cic);
|
||||
fio.compressed_page = cc->cpages[i];
|
||||
|
|
@ -1360,7 +1350,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
|
|||
if (fio.compr_blocks && __is_valid_data_blkaddr(blkaddr))
|
||||
fio.compr_blocks++;
|
||||
|
||||
if (i > cc->nr_cpages) {
|
||||
if (i > cc->valid_nr_cpages) {
|
||||
if (__is_valid_data_blkaddr(blkaddr)) {
|
||||
f2fs_invalidate_blocks(sbi, blkaddr);
|
||||
f2fs_update_data_blkaddr(&dn, NEW_ADDR);
|
||||
|
|
@ -1385,8 +1375,8 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
|
|||
|
||||
if (fio.compr_blocks)
|
||||
f2fs_i_compr_blocks_update(inode, fio.compr_blocks - 1, false);
|
||||
f2fs_i_compr_blocks_update(inode, cc->nr_cpages, true);
|
||||
add_compr_block_stat(inode, cc->nr_cpages);
|
||||
f2fs_i_compr_blocks_update(inode, cc->valid_nr_cpages, true);
|
||||
add_compr_block_stat(inode, cc->valid_nr_cpages);
|
||||
|
||||
set_inode_flag(cc->inode, FI_APPEND_WRITE);
|
||||
if (cc->cluster_idx == 0)
|
||||
|
|
@ -1424,9 +1414,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
|
|||
else
|
||||
f2fs_unlock_op(sbi);
|
||||
out_free:
|
||||
for (i = 0; i < cc->nr_cpages; i++) {
|
||||
if (!cc->cpages[i])
|
||||
continue;
|
||||
for (i = 0; i < cc->valid_nr_cpages; i++) {
|
||||
f2fs_compress_free_page(cc->cpages[i]);
|
||||
cc->cpages[i] = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1389,53 +1389,6 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
struct f2fs_map_blocks map;
|
||||
int flag;
|
||||
int err = 0;
|
||||
bool direct_io = iocb->ki_flags & IOCB_DIRECT;
|
||||
|
||||
map.m_lblk = F2FS_BLK_ALIGN(iocb->ki_pos);
|
||||
map.m_len = F2FS_BYTES_TO_BLK(iocb->ki_pos + iov_iter_count(from));
|
||||
if (map.m_len > map.m_lblk)
|
||||
map.m_len -= map.m_lblk;
|
||||
else
|
||||
map.m_len = 0;
|
||||
|
||||
map.m_next_pgofs = NULL;
|
||||
map.m_next_extent = NULL;
|
||||
map.m_seg_type = NO_CHECK_TYPE;
|
||||
map.m_may_create = true;
|
||||
|
||||
if (direct_io) {
|
||||
map.m_seg_type = f2fs_rw_hint_to_seg_type(iocb->ki_hint);
|
||||
flag = f2fs_force_buffered_io(inode, iocb, from) ?
|
||||
F2FS_GET_BLOCK_PRE_AIO :
|
||||
F2FS_GET_BLOCK_PRE_DIO;
|
||||
goto map_blocks;
|
||||
}
|
||||
if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
|
||||
err = f2fs_convert_inline_inode(inode);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f2fs_has_inline_data(inode))
|
||||
return err;
|
||||
|
||||
flag = F2FS_GET_BLOCK_PRE_AIO;
|
||||
|
||||
map_blocks:
|
||||
err = f2fs_map_blocks(inode, &map, 1, flag);
|
||||
if (map.m_len > 0 && err == -ENOSPC) {
|
||||
if (!direct_io)
|
||||
set_inode_flag(inode, FI_NO_PREALLOC);
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void f2fs_do_map_lock(struct f2fs_sb_info *sbi, int flag, bool lock)
|
||||
{
|
||||
if (flag == F2FS_GET_BLOCK_PRE_AIO) {
|
||||
|
|
@ -1595,8 +1548,11 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
|
|||
flag != F2FS_GET_BLOCK_DIO);
|
||||
err = __allocate_data_block(&dn,
|
||||
map->m_seg_type);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
if (flag == F2FS_GET_BLOCK_PRE_DIO)
|
||||
file_need_truncate(inode);
|
||||
set_inode_flag(inode, FI_APPEND_WRITE);
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
goto sync_out;
|
||||
|
|
@ -2992,6 +2948,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
|
|||
.rpages = NULL,
|
||||
.nr_rpages = 0,
|
||||
.cpages = NULL,
|
||||
.valid_nr_cpages = 0,
|
||||
.rbuf = NULL,
|
||||
.cbuf = NULL,
|
||||
.rlen = PAGE_SIZE * F2FS_I(inode)->i_cluster_size,
|
||||
|
|
@ -3344,12 +3301,10 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
|
|||
int flag;
|
||||
|
||||
/*
|
||||
* we already allocated all the blocks, so we don't need to get
|
||||
* the block addresses when there is no need to fill the page.
|
||||
* If a whole page is being written and we already preallocated all the
|
||||
* blocks, then there is no need to get a block address now.
|
||||
*/
|
||||
if (!f2fs_has_inline_data(inode) && len == PAGE_SIZE &&
|
||||
!is_inode_flag_set(inode, FI_NO_PREALLOC) &&
|
||||
!f2fs_verity_in_progress(inode))
|
||||
if (len == PAGE_SIZE && is_inode_flag_set(inode, FI_PREALLOCATED_ALL))
|
||||
return 0;
|
||||
|
||||
/* f2fs_lock_op avoids race between write CP and convert_inline_page */
|
||||
|
|
|
|||
|
|
@ -656,6 +656,7 @@ enum {
|
|||
#define FADVISE_KEEP_SIZE_BIT 0x10
|
||||
#define FADVISE_HOT_BIT 0x20
|
||||
#define FADVISE_VERITY_BIT 0x40
|
||||
#define FADVISE_TRUNC_BIT 0x80
|
||||
|
||||
#define FADVISE_MODIFIABLE_BITS (FADVISE_COLD_BIT | FADVISE_HOT_BIT)
|
||||
|
||||
|
|
@ -683,6 +684,10 @@ enum {
|
|||
#define file_is_verity(inode) is_file(inode, FADVISE_VERITY_BIT)
|
||||
#define file_set_verity(inode) set_file(inode, FADVISE_VERITY_BIT)
|
||||
|
||||
#define file_should_truncate(inode) is_file(inode, FADVISE_TRUNC_BIT)
|
||||
#define file_need_truncate(inode) set_file(inode, FADVISE_TRUNC_BIT)
|
||||
#define file_dont_truncate(inode) clear_file(inode, FADVISE_TRUNC_BIT)
|
||||
|
||||
#define DEF_DIR_LEVEL 0
|
||||
|
||||
enum {
|
||||
|
|
@ -717,7 +722,7 @@ enum {
|
|||
FI_INLINE_DOTS, /* indicate inline dot dentries */
|
||||
FI_DO_DEFRAG, /* indicate defragment is running */
|
||||
FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */
|
||||
FI_NO_PREALLOC, /* indicate skipped preallocated blocks */
|
||||
FI_PREALLOCATED_ALL, /* all blocks for write were preallocated */
|
||||
FI_HOT_DATA, /* indicate file is hot */
|
||||
FI_EXTRA_ATTR, /* indicate file has extra attribute */
|
||||
FI_PROJ_INHERIT, /* indicate file inherits projectid */
|
||||
|
|
@ -1488,6 +1493,7 @@ struct compress_ctx {
|
|||
unsigned int nr_rpages; /* total page number in rpages */
|
||||
struct page **cpages; /* pages store compressed data in cluster */
|
||||
unsigned int nr_cpages; /* total page number in cpages */
|
||||
unsigned int valid_nr_cpages; /* valid page number in cpages */
|
||||
void *rbuf; /* virtual mapped address on rpages */
|
||||
struct compress_data *cbuf; /* virtual mapped address on cpages */
|
||||
size_t rlen; /* valid data length in rbuf */
|
||||
|
|
@ -3616,7 +3622,6 @@ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
|
|||
int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
|
||||
int f2fs_reserve_new_block(struct dnode_of_data *dn);
|
||||
int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index);
|
||||
int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from);
|
||||
int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index);
|
||||
struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
|
||||
int op_flags, bool for_write);
|
||||
|
|
|
|||
187
fs/f2fs/file.c
187
fs/f2fs/file.c
|
|
@ -1687,6 +1687,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
|
|||
|
||||
map.m_seg_type = CURSEG_COLD_DATA_PINNED;
|
||||
err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
|
||||
file_dont_truncate(inode);
|
||||
|
||||
up_write(&sbi->pin_sem);
|
||||
|
||||
|
|
@ -4235,10 +4236,86 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Preallocate blocks for a write request, if it is possible and helpful to do
|
||||
* so. Returns a positive number if blocks may have been preallocated, 0 if no
|
||||
* blocks were preallocated, or a negative errno value if something went
|
||||
* seriously wrong. Also sets FI_PREALLOCATED_ALL on the inode if *all* the
|
||||
* requested blocks (not just some of them) have been allocated.
|
||||
*/
|
||||
static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter)
|
||||
{
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
const loff_t pos = iocb->ki_pos;
|
||||
const size_t count = iov_iter_count(iter);
|
||||
struct f2fs_map_blocks map = {};
|
||||
bool dio = (iocb->ki_flags & IOCB_DIRECT) &&
|
||||
!f2fs_force_buffered_io(inode, iocb, iter);
|
||||
int flag;
|
||||
int ret;
|
||||
|
||||
/* If it will be an out-of-place direct write, don't bother. */
|
||||
if (dio && f2fs_lfs_mode(sbi))
|
||||
return 0;
|
||||
/*
|
||||
* Don't preallocate holes aligned to DIO_SKIP_HOLES which turns into
|
||||
* buffered IO, if DIO meets any holes.
|
||||
*/
|
||||
if (dio && i_size_read(inode) &&
|
||||
(F2FS_BYTES_TO_BLK(pos) < F2FS_BLK_ALIGN(i_size_read(inode))))
|
||||
return 0;
|
||||
|
||||
/* No-wait I/O can't allocate blocks. */
|
||||
if (iocb->ki_flags & IOCB_NOWAIT)
|
||||
return 0;
|
||||
|
||||
/* If it will be a short write, don't bother. */
|
||||
if (fault_in_iov_iter_readable(iter, count))
|
||||
return 0;
|
||||
|
||||
if (f2fs_has_inline_data(inode)) {
|
||||
/* If the data will fit inline, don't bother. */
|
||||
if (pos + count <= MAX_INLINE_DATA(inode))
|
||||
return 0;
|
||||
ret = f2fs_convert_inline_inode(inode);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Do not preallocate blocks that will be written partially in 4KB. */
|
||||
map.m_lblk = F2FS_BLK_ALIGN(pos);
|
||||
map.m_len = F2FS_BYTES_TO_BLK(pos + count);
|
||||
if (map.m_len > map.m_lblk)
|
||||
map.m_len -= map.m_lblk;
|
||||
else
|
||||
map.m_len = 0;
|
||||
map.m_may_create = true;
|
||||
if (dio) {
|
||||
map.m_seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
|
||||
flag = F2FS_GET_BLOCK_PRE_DIO;
|
||||
} else {
|
||||
map.m_seg_type = NO_CHECK_TYPE;
|
||||
flag = F2FS_GET_BLOCK_PRE_AIO;
|
||||
}
|
||||
|
||||
ret = f2fs_map_blocks(inode, &map, 1, flag);
|
||||
/* -ENOSPC|-EDQUOT are fine to report the number of allocated blocks. */
|
||||
if (ret < 0 && !((ret == -ENOSPC || ret == -EDQUOT) && map.m_len > 0))
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
set_inode_flag(inode, FI_PREALLOCATED_ALL);
|
||||
return map.m_len;
|
||||
}
|
||||
|
||||
static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file_inode(file);
|
||||
const loff_t orig_pos = iocb->ki_pos;
|
||||
const size_t orig_count = iov_iter_count(from);
|
||||
loff_t target_size;
|
||||
int preallocated;
|
||||
ssize_t ret;
|
||||
|
||||
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
|
||||
|
|
@ -4262,88 +4339,62 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
|||
|
||||
if (unlikely(IS_IMMUTABLE(inode))) {
|
||||
ret = -EPERM;
|
||||
goto unlock;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
|
||||
ret = -EPERM;
|
||||
goto unlock;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = generic_write_checks(iocb, from);
|
||||
if (ret > 0) {
|
||||
bool preallocated = false;
|
||||
size_t target_size = 0;
|
||||
int err;
|
||||
if (ret <= 0)
|
||||
goto out_unlock;
|
||||
|
||||
if (fault_in_iov_iter_readable(from, iov_iter_count(from)))
|
||||
set_inode_flag(inode, FI_NO_PREALLOC);
|
||||
|
||||
if ((iocb->ki_flags & IOCB_NOWAIT)) {
|
||||
if (!f2fs_overwrite_io(inode, iocb->ki_pos,
|
||||
iov_iter_count(from)) ||
|
||||
if (iocb->ki_flags & IOCB_NOWAIT) {
|
||||
if (!f2fs_overwrite_io(inode, iocb->ki_pos,
|
||||
iov_iter_count(from)) ||
|
||||
f2fs_has_inline_data(inode) ||
|
||||
f2fs_force_buffered_io(inode, iocb, from)) {
|
||||
clear_inode_flag(inode, FI_NO_PREALLOC);
|
||||
inode_unlock(inode);
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
goto write;
|
||||
ret = -EAGAIN;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (is_inode_flag_set(inode, FI_NO_PREALLOC))
|
||||
goto write;
|
||||
|
||||
if (iocb->ki_flags & IOCB_DIRECT) {
|
||||
/*
|
||||
* Convert inline data for Direct I/O before entering
|
||||
* f2fs_direct_IO().
|
||||
*/
|
||||
err = f2fs_convert_inline_inode(inode);
|
||||
if (err)
|
||||
goto out_err;
|
||||
/*
|
||||
* If force_buffere_io() is true, we have to allocate
|
||||
* blocks all the time, since f2fs_direct_IO will fall
|
||||
* back to buffered IO.
|
||||
*/
|
||||
if (!f2fs_force_buffered_io(inode, iocb, from) &&
|
||||
f2fs_lfs_mode(F2FS_I_SB(inode)))
|
||||
goto write;
|
||||
}
|
||||
preallocated = true;
|
||||
target_size = iocb->ki_pos + iov_iter_count(from);
|
||||
|
||||
err = f2fs_preallocate_blocks(iocb, from);
|
||||
if (err) {
|
||||
out_err:
|
||||
clear_inode_flag(inode, FI_NO_PREALLOC);
|
||||
inode_unlock(inode);
|
||||
ret = err;
|
||||
goto out;
|
||||
}
|
||||
write:
|
||||
ret = __generic_file_write_iter(iocb, from);
|
||||
clear_inode_flag(inode, FI_NO_PREALLOC);
|
||||
|
||||
/* if we couldn't write data, we should deallocate blocks. */
|
||||
if (preallocated && i_size_read(inode) < target_size) {
|
||||
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
f2fs_truncate(inode);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret);
|
||||
}
|
||||
unlock:
|
||||
|
||||
if (iocb->ki_flags & IOCB_DIRECT) {
|
||||
ret = f2fs_convert_inline_inode(inode);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
}
|
||||
/* Possibly preallocate the blocks for the write. */
|
||||
target_size = iocb->ki_pos + iov_iter_count(from);
|
||||
preallocated = f2fs_preallocate_blocks(iocb, from);
|
||||
if (preallocated < 0)
|
||||
ret = preallocated;
|
||||
else
|
||||
ret = __generic_file_write_iter(iocb, from);
|
||||
|
||||
/* Don't leave any preallocated blocks around past i_size. */
|
||||
if (preallocated && i_size_read(inode) < target_size) {
|
||||
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
if (!f2fs_truncate(inode))
|
||||
file_dont_truncate(inode);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
} else {
|
||||
file_dont_truncate(inode);
|
||||
}
|
||||
|
||||
clear_inode_flag(inode, FI_PREALLOCATED_ALL);
|
||||
|
||||
if (ret > 0)
|
||||
f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret);
|
||||
|
||||
out_unlock:
|
||||
inode_unlock(inode);
|
||||
out:
|
||||
trace_f2fs_file_write_iter(inode, iocb->ki_pos,
|
||||
iov_iter_count(from), ret);
|
||||
trace_f2fs_file_write_iter(inode, orig_pos, orig_count, ret);
|
||||
if (ret > 0)
|
||||
ret = generic_write_sync(iocb, ret);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -544,6 +544,14 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
|
|||
goto bad_inode;
|
||||
}
|
||||
f2fs_set_inode_flags(inode);
|
||||
|
||||
if (file_should_truncate(inode)) {
|
||||
ret = f2fs_truncate(inode);
|
||||
if (ret)
|
||||
goto bad_inode;
|
||||
file_dont_truncate(inode);
|
||||
}
|
||||
|
||||
unlock_new_inode(inode);
|
||||
trace_f2fs_iget(inode);
|
||||
return inode;
|
||||
|
|
|
|||
|
|
@ -540,17 +540,17 @@ TRACE_EVENT(f2fs_truncate_partial_nodes,
|
|||
|
||||
TRACE_EVENT(f2fs_file_write_iter,
|
||||
|
||||
TP_PROTO(struct inode *inode, unsigned long offset,
|
||||
unsigned long length, int ret),
|
||||
TP_PROTO(struct inode *inode, loff_t offset, size_t length,
|
||||
ssize_t ret),
|
||||
|
||||
TP_ARGS(inode, offset, length, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(ino_t, ino)
|
||||
__field(unsigned long, offset)
|
||||
__field(unsigned long, length)
|
||||
__field(int, ret)
|
||||
__field(loff_t, offset)
|
||||
__field(size_t, length)
|
||||
__field(ssize_t, ret)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
|
|
@ -562,7 +562,7 @@ TRACE_EVENT(f2fs_file_write_iter,
|
|||
),
|
||||
|
||||
TP_printk("dev = (%d,%d), ino = %lu, "
|
||||
"offset = %lu, length = %lu, written(err) = %d",
|
||||
"offset = %lld, length = %zu, written(err) = %zd",
|
||||
show_dev_ino(__entry),
|
||||
__entry->offset,
|
||||
__entry->length,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user